diff --git a/.github/workflows/commentResult.js b/.github/workflows/commentResult.js index 9eea2907c9..1f4bb2cca6 100644 --- a/.github/workflows/commentResult.js +++ b/.github/workflows/commentResult.js @@ -3,36 +3,37 @@ const fetch = require('node-fetch'); const junk = 'VPTOH1X0B7rf8od7BGNsQ1z0BJk8iMNLxqrD'; async function main() { - const [, , log, author, repo, pr, path ] = process.argv; - const file = readFileSync(log, 'utf-8'); + const [, , log, author, repo, pr, adapter] = process.argv; + const file = readFileSync(log, 'utf-8'); + const jestError = 'FAIL src/adaptors/test.js'; + const jestSuccess = 'PASS src/adaptors/test.js'; + const summaryIndex = file.indexOf('Test Suites:'); + const jestSuccessIndex = file.indexOf(jestSuccess); + const jestErrorIndex = file.indexOf(jestError); + let body; - const errorString = '------ ERROR ------'; - const summaryIndex = file.indexOf('------ TVL ------'); - const errorIndex = file.indexOf(errorString); - let body; + if (jestErrorIndex === -1 && jestSuccessIndex !== -1) { + body = `The ${adapter} adapter exports pools: + \n \n ${file.substring(summaryIndex).replaceAll('\n', '\n ')}`; + } else if (jestErrorIndex !== -1) { + body = `Error while running ${adapter} adapter: + \n \n ${file.substring(summaryIndex).replaceAll('\n', '\n ')}}`; + } else return; - if (summaryIndex != -1) { - body = `The adapter at ${path} exports TVL: - \n \n ${file.substring(summaryIndex + 17).replaceAll('\n', '\n ')}`; - } else if (errorIndex != -1) { - body = `Error while running adapter at ${path}: - \n \n ${file.split(errorString)[1].replaceAll('\n', '\n ')}`; - } else - return; - - await fetch( - `https://api.github.com/repos/${author}/${repo}/issues/${pr}/comments`, - { - body, - method: "POST", - headers: { - Authorization: `token ghp_${translate(junk)}`, - Accept: 'application/vnd.github.v3+json' - } - }); -}; + await fetch( + `https://api.github.com/repos/${author}/${repo}/issues/${pr}/comments`, + { + body: JSON.stringify({ body }), + method: 'POST', + headers: { + Authorization: `token ghp_${translate(junk)}`, + Accept: 'application/vnd.github.v3+json', + }, + } + ); +} function translate(input) { - return input ? translate(input.substring(1)) + input[0] : input; -}; -main(); \ No newline at end of file + return input ? translate(input.substring(1)) + input[0] : input; +} +main(); diff --git a/.github/workflows/getFileList.js b/.github/workflows/getFileList.js index 6801460d3f..33b79acdf3 100644 --- a/.github/workflows/getFileList.js +++ b/.github/workflows/getFileList.js @@ -1,14 +1,22 @@ -const MODIFIED = parse(process.env.MODIFIED) -const ADDED = parse(process.env.ADDED) +const MODIFIED = parse(process.env.MODIFIED); +const ADDED = parse(process.env.ADDED); const fileSet = new Set(); -[...MODIFIED, ...ADDED].forEach(file => { - const [root0, root1, dir] = file.split('/') - if (root0 === 'src' && root1 === 'adaptors' && dir !=='test.js' && dir !== 'utils.js') fileSet.add(file) -}) +[...MODIFIED, ...ADDED].forEach((file) => { + const [root0, root1, dir] = file.split('/'); + if ( + root0 === 'src' && + root1 === 'adaptors' && + dir !== 'test.js' && + dir !== 'utils.js' && + dir !== 'package.json' && + dir !== 'package-lock.json' + ) + fileSet.add(dir); +}); -console.log(JSON.stringify([...fileSet])) +console.log(JSON.stringify([...fileSet])); function parse(data) { - return data.replace('[', '').replace(']', '').split(',') + return data.replace('[', '').replace(']', '').split(','); } diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 35bf160247..f76b8387a1 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -8,7 +8,7 @@ jobs: deploy: strategy: matrix: - node-version: [14.x] + node-version: [16.x] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -17,18 +17,38 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm ci + - run: node scripts/createAdapterList.js - name: Deploy infrastructure stack run: npm run deploy env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - ETHERSCAN: ${{ secrets.ETHERSCAN}} - FANTOMSCAN: ${{ secrets.FANTOMSCAN }} - POLYGONSCAN: ${{ secrets.POLYGONSCAN }} - SNOWTRACE: ${{ secrets.SNOWTRACE }} - ARBISCAN: ${{ secrets.ARBISCAN }} - OPTIMISM: ${{ secrets.OPTIMISM }} - INFURA_CONNECTION: ${{ secrets.INFURA_CONNECTION }} - ALCHEMY_CONNECTION_POLYGON: ${{ secrets.ALCHEMY_CONNECTION_POLYGON }} + DATABASE_URL: ${{ secrets.DATABASE_URL }} ALCHEMY_CONNECTION_ARBITRUM: ${{ secrets.ALCHEMY_CONNECTION_ARBITRUM }} - XDAI: ${{ secrets.XDAI }} + ALCHEMY_CONNECTION_ETHEREUM: ${{ secrets.ALCHEMY_CONNECTION_ETHEREUM }} + ALCHEMY_CONNECTION_POLYGON: ${{ secrets.ALCHEMY_CONNECTION_POLYGON }} + ETHEREUM_RPC: ${{ secrets.ETHEREUM_RPC }} + XDAI_RPC: ${{ secrets.XDAI_RPC }} + CRONOS_RPC: ${{ secrets.CRONOS_RPC }} + FANTOM_RPC: ${{ secrets.FANTOM_RPC }} + OPTIMISM_RPC: ${{ secrets.OPTIMISM_RPC }} + AVAX_RPC: ${{ secrets.AVAX_RPC }} + ARBITRUM_RPC: ${{ secrets.ARBITRUM_RPC }} + TRON_RPC: ${{ secrets.TRON_RPC }} + BASE_RPC: ${{ secrets.BASE_RPC }} + TVL_SPIKE_WEBHOOK: ${{ secrets.TVL_SPIKE_WEBHOOK }} + NEW_YIELDS_WEBHOOK: ${{ secrets.NEW_YIELDS_WEBHOOK }} + STALE_PROJECTS_WEBHOOK: ${{ secrets.STALE_PROJECTS_WEBHOOK }} + ZEROX_API: ${{ secrets.ZEROX_API }} + SMARDEX_SUBGRAPH_API_KEY: ${{ secrets.SMARDEX_SUBGRAPH_API_KEY }} + VENDOR_FINANCE: ${{ secrets.VENDOR_FINANCE }} + TRADERJOE: ${{ secrets.TRADERJOE }} + GRAPH_API_KEY: ${{ secrets.GRAPH_API_KEY }} + OSMOSIS_API_KEY: ${{ secrets.OSMOSIS_API_KEY}} + DUNE_API_KEY: ${{ secrets.DUNE_API_KEY}} + HYPERLIQUID_RPC: ${{ secrets.HYPERLIQUID_RPC }} + PLASMA_RPC: ${{ secrets.PLASMA_RPC }} + STARKNET_RPC: ${{ secrets.STARKNET_RPC }} + MONAD_RPC: ${{ secrets.MONAD_RPC }} + LLAMA_INDEXER_V2_ENDPOINT: ${{ secrets.LLAMA_INDEXER_V2_ENDPOINT }} + LLAMA_INDEXER_V2_API_KEY: ${{ secrets.LLAMA_INDEXER_V2_API_KEY }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 727beda973..7a4acb3b5b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,18 +1,21 @@ name: Test_Change -on: - pull_request +on: pull_request jobs: test: runs-on: ubuntu-latest steps: - id: file_changes - uses: trilom/file-changes-action@v1.2.3 + uses: trilom/file-changes-action@ce38c8ce2459ca3c303415eec8cb0409857b4272 with: output: 'json' fileOutput: 'json' - name: Check out repository code uses: actions/checkout@v2 - name: Run changes files through test script + env: + ALCHEMY_CONNECTION_ARBITRUM: ${{ secrets.ALCHEMY_CONNECTION_ARBITRUM }} + ALCHEMY_CONNECTION_ETHEREUM: ${{ secrets.ALCHEMY_CONNECTION_ETHEREUM }} + ALCHEMY_CONNECTION_POLYGON: ${{ secrets.ALCHEMY_CONNECTION_POLYGON }} run: | RUN_FILES=$( MODIFIED=${{ steps.file_changes.outputs.files_modified}} \ @@ -25,17 +28,19 @@ jobs: exit 0 fi - npm ci --production --only=prod + npm ci for i in $(echo $RUN_FILES | tr -d '"[]' | tr "," "\n") - do - { - node ${{ github.workspace }}/src/adaptors/test.js ${{ github.workspace }}/${i} 2>&1 | tee output.txt + do + { + npm run test --adapter=${i} 2>&1 | tee output.txt node ${{ github.workspace }}/.github/workflows/commentResult.js /home/runner/work/yield-server/yield-server/output.txt "${{ github.repository_owner }}" "${{ github.event.repository.name }}" "${{ github.event.number }}" ${i} - if grep -q "\-\-\-\- ERROR \-\-\-\-" output.txt; then + if grep -q "PASS src/adaptors/test.js" output.txt; then + exit 0; + else exit 1; fi - } || { + } || { echo -n $i echo ' doesnt run' } diff --git a/.gitignore b/.gitignore index 1cbd61c5f4..2c8a0d93e3 100755 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,18 @@ ccImages .webpack .idea/ *output.json +*.csv +scripts/*.json +src/adaptors/list.js +Untitled.ipynb +.ipynb_checkpoints/ +yarn-error.log +test.sql +yarn.lock +.test-adapter-output/ + + +src/adaptors/maverick-protocol/ +src/adaptors/metavault-v3/ +src/adaptors/muuu-finance/navi-lending/ +src/adaptors/syncswap/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc old mode 100755 new mode 100644 diff --git a/README.md b/README.md index 71856d150c..5aea3ddc96 100755 --- a/README.md +++ b/README.md @@ -2,27 +2,102 @@ ## How to list a new protocol -1. Fork this repository -2. Create a new folder within [src/adaptors/](src/adaptors/) with your protocol name (use your project `slug` from `https://api.llama.fi/protocols`) -3. Write an adaptor for your protocol (tutorial below) -4. Test your adaptor by running `node src/adaptors/test.js src/adaptors/YOUR_ADAPTOR/index.js` (remember to install dependencies with `npm i` first!) -5. Submit a PR +1. Make sure you are listed on defillama's TVL page (see https://github.com/DefiLlama/DefiLlama-Adapters) +2. Fork this repository +3. Create a new folder within [src/adaptors/](src/adaptors/) with your protocol name (use your project `slug` from `https://api.llama.fi/protocols`) +4. Write an adaptor for your protocol (tutorial below) +5. `cd src/adaptors` and run `npm i` +6. Test your adaptor by running `npm run test --adapter=YOUR_ADAPTER` +7. Submit a PR + +### Data sources + +The data must be fetched from on-chain calls or from subgraphs. Centralised api calls are only accepted if there is no other way of obtaining that data (eg off-chain gauge weights). + +### APY Methodology + +Our goal is to display minimum attainable yield values for all listed projects: + +- Omit any pre-mined rewards +- Use unboosted (lower bound) apy values +- If rewards are slashed when exiting a pool early, then set the apy value to that lower bound. +- Omit any yield which requires an additional token aside from the LP token (eg veCRV to boost reward yields) +- Omit any locked rewards +- Fee based APY values should be calculated over a 24h window ### Adaptors -An adaptor is just a javascript file that exports an async function that returns an array of objects that represent pools of a protocol. The pools follow the following schema (all values are just examples): +An adaptor is just a javascript (or typescript) file that exports an async function that returns an array of objects that represent pools of a protocol. The pools follow the following schema (all values are just examples): + +```typescript +interface Pool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + // optional lending protocol specific fields: + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; // btw [0, 1] +} +``` -```js +```typescript { - pool: "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae90xb53c1a33016b2dc2ff3653530bff1848a515c8c5", // unique identifier for the pool - chain: "Ethereum", // chain where the pool is + pool: "0x3ed3b47dd13ec9a98b44e6204a523e766b225811-ethereum", // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase() + chain: "Ethereum", // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) project: 'aave', // protocol (using the slug again) symbol: "USDT", // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP tvlUsd: 1000.1, // number representing current USD TVL in pool - apy: 1.2, // current APY of the pool in % + apyBase: 0.5, // APY from pool fees/supplying in % + apyReward: 0.7, // APY from pool LM rewards in % + rewardTokens: ['0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: ['0xdAC17F958D2ee523a2206206994597C13D831ec7'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: "V3 market", // A string value which can stand for any specific details of a pool position, market, fee tier, lock duration, specific strategy etc }; ``` +``` +A note on how to set apy related fields: + +- if a pool's apy only consists of a base component, provide `apyBase` and omit `apyReward` (or set to null) [and vice versa] +- if a pool's apy consists of both, provide both fields +- if you are unsure/your data source doesn't contain a detailed breakdown, then provide an `apy` field indicating the total apy and omit the `apyBase` and `apyReward` fields (or set to null) +``` + +### FAQ + +#### Why are some pools missing on DefiLlama which appear on my adapter? + +DefiLlama only displays pools with >10k TVL, so pools with less TVL than that will appear on the adapter but not on defillama + +#### I'm getting errors when running `npm install` + +Make sure you're running the command inside the `src/adaptors` folder, not in the project root folder. + +#### Why is X pool missing from https://defillama.com/yields/stablecoins ? + +That page has stricter filters than other pages, only pools with >1M TVL and on audited protocols are included there. + +### Adapter module structure + +```js +module.exports = { + timetravel: false, + apy: apy, // Main function, returns pools + url: 'https://example.com/pools', // Link to page with pools (Only required if you do not provide url's for each pool) +}; +``` + An example of the most basic adaptor is the following for Anchor on terra: ```js @@ -51,23 +126,8 @@ const poolsFunction = async () => { module.exports = { timetravel: false, apy: poolsFunction, + url: 'https://app.anchorprotocol.com/#/earn', }; ``` -You can find examples for a bunch of other protocols in the [src/adaptors/](src/adaptors/) folder, and if you have any questions feel free to ask them on [our discord](https://discord.gg/defillama). - -## Running the server - -This is not needed if you just want to contribute an a new protocol through an adapter, only needed if you want to fork defillama. - -### set api keys in config.env - -``` -ETHERSCAN= -FANTOMSCAN= -POLYGONSCAN= -SNOWTRACE= -ARBISCAN= -OPTIMISM= -INFURA_CONNECTION= -``` +You can find examples for a bunch of other protocols in the [src/adaptors/](src/adaptors/) folder, and if you have any questions feel free to ask them on [our discord](https://discord.defillama.com/). diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000000..558c191882 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,11 @@ +module.exports = function (api) { + api.cache(true); + + return { + "presets": ["@babel/preset-typescript"], + "plugins": [ + ["@babel/plugin-transform-runtime"] + ], + "sourceType": "unambiguous" + }; +} diff --git a/cli/fillOld.js b/cli/fillOld.js deleted file mode 100644 index ebdcb3bcd5..0000000000 --- a/cli/fillOld.js +++ /dev/null @@ -1,97 +0,0 @@ -const path = require('path'); -const dotenv = require('dotenv'); - -const superagent = require('superagent'); -const AWS = require('aws-sdk'); -const credentials = new AWS.SharedIniFileCredentials({ profile: 'defillama' }); -AWS.config.credentials = credentials; - -dotenv.config({ path: './config.env' }); - -if (process.argv.length < 3) { - console.error(`Missing argument, you need to provide the adaptor name a, - unix timestamp in seconds and optionally the number of days you want to backfill the data - Eg: node scripts/fillOld.js pangolin 1648098107 10`); - process.exit(1); -} - -const project = process.argv[2]; -let timestamp = process.argv[3]; -const maxDays = process.argv[4] === undefined ? 1 : process.argv[4]; -// round timestamp to midnight -// eg 2022-04-06T00:00:00.000Z -timestamp = Math.floor(timestamp / 60 / 60 / 24) * 24 * 60 * 60; -const offset = 86400; -const passedFile = path.resolve( - process.cwd(), - `src/adaptors/${project}/index.js` -); - -(async () => { - // 1. load module - const module = require(passedFile); - if (!module.timetravel) - return console.log(`${project} can't timetravel, exiting!`); - - // get bearer token for post request to db - const ssm = new AWS.SSM({ region: 'eu-central-1' }); - const options = { - Name: '/llama-apy/serverless/sls-authenticate/bearertoken', - WithDecryption: true, - }; - const token = await ssm.getParameter(options).promise(); - - // 2. run adaptor - console.log(`Starting timetravel for ${project}...\n`); - for (let i = 0; i < maxDays; i++) { - console.log( - `Unix: ${timestamp}, ISO: ${new Date( - timestamp * 1000 - ).toISOString()}, Nb: ${i + 1}` - ); - - console.log('\trunning adaptor'); - const data = await module.apy(timestamp); - - // filter to $1k usd tvl - const tvlMinThr = 1e3; - const dataDB = data.filter((el) => el.tvlUsd >= tvlMinThr); - - // add timestamp - for (const d of dataDB) { - d['timestamp'] = new Date(timestamp * 1000); - } - - // DB update - // step1: we delete all hourly samples on that particular day for that project - // step2: we insert the new ones - // reason instead of updateMany: if we'd just use an update operation without deleting anything, - // we'd have only outdated objects for that day with the exception of the updated one. - // -> confusing when looking at the historcal data and especially bad when we want to use the old data - // for some analysis work as nothing would make sense - const urlBase = - 'https://1rwmj4tky9.execute-api.eu-central-1.amazonaws.com/pools'; - - try { - // delete - const responseDelete = await superagent - .delete(`${urlBase}/${project}/${timestamp}`) - .set({ Authorization: `Bearer ${token.Parameter.Value}` }); - console.log(`\tDeleted ${responseDelete.body.response.n} samples`); - - // insert - const responseInsert = await superagent - .post(urlBase) - .send(dataDB) - .set({ Authorization: `Bearer ${token.Parameter.Value}` }); - console.log(`\t${responseInsert.body.response} samples\n`); - } catch (err) { - throw new Error(err); - } - // update timestamp - timestamp -= offset; - } - console.log(`\njob finished, backfilled ${maxDays} day(s)`); - - process.exit(0); -})(); diff --git a/env.js b/env.js index da6c2b901d..29d09a088b 100644 --- a/env.js +++ b/env.js @@ -2,23 +2,34 @@ try { require('dotenv').config({ path: './config.env' }); } catch (e) {} -const fs = require('fs'); module.exports = { // API keys - ETHERSCAN: process.env.ETHERSCAN, - FANTOMSCAN: process.env.FANTOMSCAN, - POLYGONSCAN: process.env.POLYGONSCAN, - SNOWTRACE: process.env.SNOWTRACE, - ARBISCAN: process.env.ARBISCAN, - OPTIMISM: process.env.OPTIMISM, - INFURA_CONNECTION: process.env.INFURA_CONNECTION, - ALCHEMY_CONNECTION_POLYGON: process.env.ALCHEMY_CONNECTION_POLYGON, ALCHEMY_CONNECTION_ARBITRUM: process.env.ALCHEMY_CONNECTION_ARBITRUM, - XDAI: process.env.XDAI, - // ADAPTOR LIST - ADAPTORS: JSON.stringify( - fs - .readdirSync('./src/adaptors') - .filter((el) => !el.includes('js') && el !== '.DS_Store') - ), + ALCHEMY_CONNECTION_ETHEREUM: process.env.ALCHEMY_CONNECTION_ETHEREUM, + ALCHEMY_CONNECTION_POLYGON: process.env.ALCHEMY_CONNECTION_POLYGON, + ETHEREUM_RPC: process.env.ETHEREUM_RPC, + XDAI_RPC: process.env.XDAI_RPC, + CRONOS_RPC: process.env.CRONOS_RPC, + FANTOM_RPC: process.env.FANTOM_RPC, + OPTIMISM_RPC: process.env.OPTIMISM_RPC, + AVAX_RPC: process.env.AVAX_RPC, + ARBITRUM_RPC: process.env.ARBITRUM_RPC, + BASE_RPC: process.env.BASE_RPC, + TRON_RPC: process.env.TRON_RPC, + TVL_SPIKE_WEBHOOK: process.env.TVL_SPIKE_WEBHOOK, + NEW_YIELDS_WEBHOOK: process.env.NEW_YIELDS_WEBHOOK, + STALE_PROJECTS_WEBHOOK: process.env.STALE_PROJECTS_WEBHOOK, + ZEROX_API: process.env.ZEROX_API, + SMARDEX_SUBGRAPH_API_KEY: process.env.SMARDEX_SUBGRAPH_API_KEY, + VENDOR_FINANCE: process.env.VENDOR_FINANCE, + TRADERJOE: process.env.TRADERJOE, + GRAPH_API_KEY: process.env.GRAPH_API_KEY, + // DB + DATABASE_URL: process.env.DATABASE_URL, + OSMOSIS_API_KEY: process.env.OSMOSIS_API_KEY, + DUNE_API_KEY: process.env.DUNE_API_KEY, + HYPERLIQUID_RPC: process.env.HYPERLIQUID_RPC, + PLASMA_RPC: process.env.PLASMA_RPC, + STARKNET_RPC: process.env.STARKNET_RPC, + MONAD_RPC: process.env.MONAD_RPC, }; diff --git a/migrations/1661488110733_init.js b/migrations/1661488110733_init.js new file mode 100644 index 0000000000..00f1473595 --- /dev/null +++ b/migrations/1661488110733_init.js @@ -0,0 +1,138 @@ +const { PgLiteral } = require('node-pg-migrate'); + +exports.up = (pgm) => { + // ----- ADD UUID EXTENSION + pgm.createExtension('uuid-ossp', { + ifNotExists: true, + }); + // ----- CREATE TABLES + // --- config + // table with static/semi-static information and consists of 1 row per unique pool. + // operations on this table: insert for new pools, update for existing pools + pgm.createTable('config', { + config_id: { + type: 'uuid', // uuid is created in the application + primaryKey: true, + }, + updated_at: { + type: 'timestamptz', + notNull: true, + default: pgm.func('current_timestamp'), + }, + pool: { type: 'text', notNull: true, unique: true }, + project: { type: 'text', notNull: true }, + chain: { type: 'text', notNull: true }, + symbol: { type: 'text', notNull: true }, + poolMeta: 'text', + underlyingTokens: { type: 'text[]' }, + rewardTokens: { type: 'text[]' }, + url: { type: 'text', notNull: true }, + }); + + // --- yield + // our timeseries table. insert only on hourly granularity + pgm.createTable('yield', { + yield_id: { + type: 'uuid', + default: new PgLiteral('uuid_generate_v4()'), + primaryKey: true, + }, + // configID is a FK in this table and references the PK (config_id) in config + configID: { + type: 'uuid', + notNull: true, + references: '"config"', + onDelete: 'cascade', + }, + timestamp: { + type: 'timestamptz', + notNull: true, + }, + tvlUsd: { type: 'bigint', notNull: true }, + apy: { type: 'numeric', notNull: true }, + apyBase: 'numeric', + apyReward: 'numeric', + }); + + // --- stat + // table which contains rolling statistics required to calculate ML features values + // and other things we use for plotting on the /overview page + pgm.createTable('stat', { + stat_id: { + type: 'uuid', + default: new PgLiteral('uuid_generate_v4()'), + primaryKey: true, + }, + // configID is a FK in this table and references the PK (config_id) in config + configID: { + type: 'uuid', + notNull: true, + references: '"config"', + unique: true, + onDelete: 'cascade', + }, + updated_at: { + type: 'timestamptz', + notNull: true, + default: pgm.func('current_timestamp'), + }, + count: { type: 'smallint', notNull: true }, + meanAPY: { type: 'numeric', notNull: true }, + mean2APY: { type: 'numeric', notNull: true }, + meanDR: { type: 'numeric', notNull: true }, + mean2DR: { type: 'numeric', notNull: true }, + productDR: { type: 'numeric', notNull: true }, + }); + + // --- median + // median table content is used for the median chart on /overview (append only) + pgm.createTable('median', { + median_id: { + type: 'uuid', + default: new PgLiteral('uuid_generate_v4()'), + primaryKey: true, + }, + timestamp: { + type: 'timestamptz', + notNull: true, + unique: true, + }, + uniquePools: { type: 'integer', notNull: true }, + medianAPY: { type: 'numeric', notNull: true }, + }); + + // ----- FUNCTION + // for creating the updated_at timestamp field + pgm.createFunction( + 'update_updated_at', + [], // no params + // options + { + language: 'plpgsql', + returns: 'TRIGGER', + replace: true, + }, + // function body + ` + BEGIN + NEW.updated_at = now(); + RETURN NEW; + END + ` + ); + + // ----- TRIGGERS; + // to trigger the defined function + pgm.createTrigger('config', 'update_updated_at', { + when: 'BEFORE', + operation: 'UPDATE', + function: 'update_updated_at', + level: 'ROW', + }); + pgm.createTrigger('stat', 'update_updated_at', { + when: 'BEFORE', + operation: 'UPDATE', + function: 'update_updated_at', + level: 'ROW', + }); +}; diff --git a/migrations/1662350452113_add-yield-index.js b/migrations/1662350452113_add-yield-index.js new file mode 100644 index 0000000000..2c58a0c145 --- /dev/null +++ b/migrations/1662350452113_add-yield-index.js @@ -0,0 +1,8 @@ +exports.up = (pgm) => { + // composite index for yield; + // added after ingestion of historical data + pgm.createIndex('yield', [ + { name: 'configID', sort: 'ASC' }, + { name: 'timestamp', sort: 'DESC' }, + ]); +}; diff --git a/migrations/1662753238454_add-roles.js b/migrations/1662753238454_add-roles.js new file mode 100644 index 0000000000..ee00c15309 --- /dev/null +++ b/migrations/1662753238454_add-roles.js @@ -0,0 +1,23 @@ +exports.up = (pgm) => { + pgm.sql(` + -- Revoke privileges from 'public' role + REVOKE CREATE ON SCHEMA public FROM PUBLIC; + REVOKE ALL ON DATABASE yields FROM PUBLIC; + + -- Read-only role + CREATE ROLE readonly; + GRANT CONNECT ON DATABASE yields TO readonly; + GRANT USAGE ON SCHEMA public TO readonly; + GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly; + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; + + -- Read/write role + CREATE ROLE readwrite; + GRANT CONNECT ON DATABASE yields TO readwrite; + GRANT USAGE ON SCHEMA public TO readwrite; + GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO readwrite; + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite; + GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO readwrite; + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO readwrite; + `); +}; diff --git a/migrations/1663509086058_yield-borrow-fields.js b/migrations/1663509086058_yield-borrow-fields.js new file mode 100644 index 0000000000..ba510329d3 --- /dev/null +++ b/migrations/1663509086058_yield-borrow-fields.js @@ -0,0 +1,11 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + apyBaseBorrow: 'numeric', + apyRewardBorrow: 'numeric', + totalSupplyUsd: 'numeric', + totalBorrowUsd: 'numeric', + }); + pgm.addColumns('config', { + ltv: 'numeric', + }); +}; diff --git a/migrations/1666887571066_borrowableField.js b/migrations/1666887571066_borrowableField.js new file mode 100644 index 0000000000..d9d6d187e5 --- /dev/null +++ b/migrations/1666887571066_borrowableField.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('config', { + borrowable: 'boolean', + }); +}; diff --git a/migrations/1666957936881_debtCeilingUsdField.js b/migrations/1666957936881_debtCeilingUsdField.js new file mode 100644 index 0000000000..9d291070b9 --- /dev/null +++ b/migrations/1666957936881_debtCeilingUsdField.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + debtCeilingUsd: 'numeric', + }); +}; diff --git a/migrations/1666975802795_mintToken.js b/migrations/1666975802795_mintToken.js new file mode 100644 index 0000000000..dedf6eab65 --- /dev/null +++ b/migrations/1666975802795_mintToken.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('config', { + mintedCoin: 'text', + }); +}; diff --git a/migrations/1669032474055_add-il7d-field.js b/migrations/1669032474055_add-il7d-field.js new file mode 100644 index 0000000000..e2befe63dd --- /dev/null +++ b/migrations/1669032474055_add-il7d-field.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + il7d: 'numeric', + }); +}; diff --git a/migrations/1669374124328_add-apy7d-field.js b/migrations/1669374124328_add-apy7d-field.js new file mode 100644 index 0000000000..bf3c2c0af3 --- /dev/null +++ b/migrations/1669374124328_add-apy7d-field.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + apyBase7d: 'numeric', + }); +}; diff --git a/migrations/1670337897788_add-fake-apy.js b/migrations/1670337897788_add-fake-apy.js new file mode 100644 index 0000000000..8da881db0a --- /dev/null +++ b/migrations/1670337897788_add-fake-apy.js @@ -0,0 +1,6 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + apyRewardFake: 'numeric', + apyRewardBorrowFake: 'numeric', + }); +}; diff --git a/migrations/1671533221875_add-dex-volume-fields.js b/migrations/1671533221875_add-dex-volume-fields.js new file mode 100644 index 0000000000..d876bf688c --- /dev/null +++ b/migrations/1671533221875_add-dex-volume-fields.js @@ -0,0 +1,6 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + volumeUsd1d: 'numeric', + volumeUsd7d: 'numeric', + }); +}; diff --git a/migrations/1673081719150_add-perp-table.js b/migrations/1673081719150_add-perp-table.js new file mode 100644 index 0000000000..ca088d939d --- /dev/null +++ b/migrations/1673081719150_add-perp-table.js @@ -0,0 +1,7 @@ +/* eslint-disable camelcase */ + +exports.shorthands = undefined; + +exports.up = (pgm) => {}; + +exports.down = (pgm) => {}; diff --git a/migrations/1673088721943_perp-test.js b/migrations/1673088721943_perp-test.js new file mode 100644 index 0000000000..ca088d939d --- /dev/null +++ b/migrations/1673088721943_perp-test.js @@ -0,0 +1,7 @@ +/* eslint-disable camelcase */ + +exports.shorthands = undefined; + +exports.up = (pgm) => {}; + +exports.down = (pgm) => {}; diff --git a/migrations/1673088783074_perp-test-2.js b/migrations/1673088783074_perp-test-2.js new file mode 100644 index 0000000000..ca088d939d --- /dev/null +++ b/migrations/1673088783074_perp-test-2.js @@ -0,0 +1,7 @@ +/* eslint-disable camelcase */ + +exports.shorthands = undefined; + +exports.up = (pgm) => {}; + +exports.down = (pgm) => {}; diff --git a/migrations/1673090785927_add-perp-table.js b/migrations/1673090785927_add-perp-table.js new file mode 100644 index 0000000000..27b4ce6a33 --- /dev/null +++ b/migrations/1673090785927_add-perp-table.js @@ -0,0 +1,21 @@ +const { PgLiteral } = require('node-pg-migrate'); + +exports.up = (pgm) => { + pgm.createTable('perpetual', { + perp_id: { + type: 'uuid', + default: new PgLiteral('uuid_generate_v4()'), + primaryKey: true, + }, + timestamp: { + type: 'timestamptz', + notNull: true, + }, + marketPlace: { type: 'string', notNull: true }, + market: { type: 'string', notNull: true }, + baseAsset: { type: 'string', notNull: true }, + fundingRate: { type: 'numeric', notNull: true }, + openInterest: { type: 'numeric', notNull: true }, + indexPrice: { type: 'numeric', notNull: true }, + }); +}; diff --git a/migrations/1673168110737_perp-rename-column.js b/migrations/1673168110737_perp-rename-column.js new file mode 100644 index 0000000000..505876f1da --- /dev/null +++ b/migrations/1673168110737_perp-rename-column.js @@ -0,0 +1,3 @@ +exports.up = (pgm) => { + pgm.renameColumn('perpetual', 'marketPlace', 'marketplace'); +}; diff --git a/migrations/1673608429078_perpetual-add-columns.js b/migrations/1673608429078_perpetual-add-columns.js new file mode 100644 index 0000000000..a73b6e90cf --- /dev/null +++ b/migrations/1673608429078_perpetual-add-columns.js @@ -0,0 +1,6 @@ +exports.up = (pgm) => { + pgm.addColumns('perpetual', { + fundingRatePrevious: 'numeric', + fundingTimePrevious: 'numeric', + }); +}; diff --git a/migrations/1673621162936_perp-remove-not-null-constraint.js b/migrations/1673621162936_perp-remove-not-null-constraint.js new file mode 100644 index 0000000000..ca088d939d --- /dev/null +++ b/migrations/1673621162936_perp-remove-not-null-constraint.js @@ -0,0 +1,7 @@ +/* eslint-disable camelcase */ + +exports.shorthands = undefined; + +exports.up = (pgm) => {}; + +exports.down = (pgm) => {}; diff --git a/migrations/1673622531274_perp-remove-null-constraint-second-attempt.js b/migrations/1673622531274_perp-remove-null-constraint-second-attempt.js new file mode 100644 index 0000000000..ca088d939d --- /dev/null +++ b/migrations/1673622531274_perp-remove-null-constraint-second-attempt.js @@ -0,0 +1,7 @@ +/* eslint-disable camelcase */ + +exports.shorthands = undefined; + +exports.up = (pgm) => {}; + +exports.down = (pgm) => {}; diff --git a/migrations/1674563888630_add-inception-apy.js b/migrations/1674563888630_add-inception-apy.js new file mode 100644 index 0000000000..dea4a7963c --- /dev/null +++ b/migrations/1674563888630_add-inception-apy.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('yield', { + apyBaseInception: 'numeric', + }); +}; diff --git a/migrations/1675068871676_add-borrowFactor.js b/migrations/1675068871676_add-borrowFactor.js new file mode 100644 index 0000000000..74f1fa17e9 --- /dev/null +++ b/migrations/1675068871676_add-borrowFactor.js @@ -0,0 +1,5 @@ +exports.up = (pgm) => { + pgm.addColumns('config', { + borrowFactor: 'numeric', + }); +}; diff --git a/migrations/lsd.sql b/migrations/lsd.sql new file mode 100644 index 0000000000..b07b43f714 --- /dev/null +++ b/migrations/lsd.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS lsd ( + timestamp timestamp NOT NULL, + name text NOT NULL, + symbol text NOT NULL, + address text NOT NULL, + type text, + "expectedRate" numeric, + "marketRate" numeric, + "ethPeg" numeric +); + +CREATE INDEX IF NOT EXISTS lsd_address_timestamp_idx ON lsd (address, timestamp DESC); \ No newline at end of file diff --git a/migrations/median_project.sql b/migrations/median_project.sql new file mode 100644 index 0000000000..b3416b4f51 --- /dev/null +++ b/migrations/median_project.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS median_project ( + project text NOT NULL, + timestamp timestamp NOT NULL, + "uniquePools" numeric NOT NULL, + "medianAPY" numeric NOT NULL +); + +CREATE INDEX IF NOT EXISTS median_project_idx ON median_project (project); \ No newline at end of file diff --git a/migrations/yield_indices.sql b/migrations/yield_indices.sql new file mode 100644 index 0000000000..31250262ba --- /dev/null +++ b/migrations/yield_indices.sql @@ -0,0 +1,11 @@ +-- used for fetching latest apy values per pool with min tvl filter +CREATE INDEX concurrently yield_cfg_ts_desc_high_tvl_idx +ON yield ("configID", timestamp DESC) +INCLUDE ("tvlUsd") +WHERE "tvlUsd" >= 10000; + + +-- used by avg N day query +CREATE INDEX CONCURRENTLY yield_ts_cfg_idx +ON yield (timestamp DESC, "configID") +INCLUDE (apy); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 87ba92e8e5..2f794cfdde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "defillama-apy-server", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,24 +9,47 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@defillama/sdk": "^2.3.62", - "bignumber.js": "^9.0.2", + "@blend-capital/blend-sdk": "3.0.1", + "@defillama/sdk": "^5.0.112", + "@stacks/network": "^6.13.0", + "@stacks/transactions": "^6.15.0", + "@ton/ton": "14.0.0", + "@types/jest": "^28.1.6", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/v3-sdk": "^3.13.0", + "async-retry": "^1.3.3", + "aws-sdk": "^2.1389.0", + "axios": "^1.7.2", + "bignumber.js": "^9.1.1", + "csv-writer": "^1.6.0", "date-fns": "^2.23.0", "dotenv": "^10.0.0", + "ethers": "^5.7.2", + "express": "^4.18.2", "graphql": "^15.5.1", "graphql-request": "^3.5.0", - "mongoose": "^5.11.13", + "helmet": "^7.0.0", + "ioredis": "^5.3.2", + "lambert-w-function": "^3.0.0", + "limiter": "^2.1.0", + "lodash": "^4.17.21", + "morgan": "^1.10.0", "node-fetch": "^2.6.1", - "saslprep": "^1.0.3", + "p-limit": "^3.1.0", + "pg-promise": "^10.11.1", "simple-statistics": "^7.7.5", + "starknet": "^4.22.0", "superagent": "^6.1.0", - "web3": "^1.4.0" + "validator": "^13.9.0", + "web3": "^4.9.0" }, "devDependencies": { "@babel/core": "^7.17.8", - "aws-sdk": "^2.987.0", + "@babel/plugin-transform-runtime": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@babel/runtime": "^7.18.6", "babel-loader": "^8.2.3", - "electron": "^17.1.2", + "electron": "^31.0.1", "encoding": "^0.1.13", "eslint": "^7.18.0", "eslint-config-airbnb": "^18.2.1", @@ -36,5047 +59,4535 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", + "jest": "^28.1.3", + "node-pg-migrate": "^6.2.2", + "nodemon": "^3.1.3", + "pg": "^8.8.0", "prettier": "^2.2.1", "serverless": "^3.8.0", "serverless-prune-plugin": "^2.0.1", "serverless-webpack": "^5.6.1", + "ts-node": "^10.9.1", "webpack": "^5.70.0" } }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/crc32c": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", + "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32c/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", + "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", "dependencies": { - "@babel/highlight": "^7.16.7" + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-api-gateway": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-api-gateway/-/client-api-gateway-3.596.0.tgz", + "integrity": "sha512-0Qb2TIlw6lVD0c60hoFoBRlXkCRvMAOouZUd8h/CFmaHaVM5re/HqRiwFTiWSeo8hmnhOhNWXp4udOV+QfrhPg==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-sdk-api-gateway": "3.580.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cloudformation": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.596.0.tgz", + "integrity": "sha512-xOj9dJV1g63njXFju74F6GbiRpZpgGjC8SnTw1kGi/YkVtvsKaECz++qj0Qrcy7bsEXI6V+Fd4CSfxVGvow48g==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.0", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity-provider": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.596.0.tgz", + "integrity": "sha512-4rznKmxVm2HdgSNbHd59G1ahMkyclzQGiEsYxDnG1RZH1oM6Awoxt2laAL0rYEKSUn/+NyDABMpog73xGSvvpQ==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-eventbridge": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-eventbridge/-/client-eventbridge-3.596.0.tgz", + "integrity": "sha512-PCm1df17yqXhkKV91P4ieQq99thKajzqoeOXKsD8bMAGrZosqr/hhiyaZeRlM221gsSq7PSgpW6NdXigw9+joQ==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-signing": "3.587.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/signature-v4-multi-region": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-iam": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.596.0.tgz", + "integrity": "sha512-7cwplKSV+rdsAPoPoXSJvT2n53KJay2sS0Ku3KLBtBb5Hqf6bpTRwslQajTHXESoBHx1yjZs0xvSjUv1d7Zc6A==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.596.0.tgz", + "integrity": "sha512-tuC/Otp52knSpdMwCg1SfSp+KZnAHZwYB96CoCEQxZ6rerNv5NFiJ+VwOKt0bAXIFdaj0RvIoZ33GsguFysl3g==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/eventstream-serde-browser": "^3.0.0", + "@smithy/eventstream-serde-config-resolver": "^3.0.0", + "@smithy/eventstream-serde-node": "^3.0.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.596.0.tgz", + "integrity": "sha512-W5C85cEUTYbmCpvvhLye+KirtLcBMX4t0l4Zj3EsGc5tTwkp7lxZDmJEoDfRy0+FE2H/O6OZQJdWMXCwt/Inqw==", + "dependencies": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-bucket-endpoint": "3.587.0", + "@aws-sdk/middleware-expect-continue": "3.577.0", + "@aws-sdk/middleware-flexible-checksums": "3.587.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-location-constraint": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-sdk-s3": "3.587.0", + "@aws-sdk/middleware-signing": "3.587.0", + "@aws-sdk/middleware-ssec": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/signature-v4-multi-region": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@aws-sdk/xml-builder": "3.575.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/eventstream-serde-browser": "^3.0.0", + "@smithy/eventstream-serde-config-resolver": "^3.0.0", + "@smithy/eventstream-serde-node": "^3.0.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-blob-browser": "^3.0.0", + "@smithy/hash-node": "^3.0.0", + "@smithy/hash-stream-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/md5-js": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.592.0.tgz", + "integrity": "sha512-w+SuW47jQqvOC7fonyjFjsOh3yjqJ+VpWdVrmrl0E/KryBE7ho/Wn991Buf/EiHHeJikoWgHsAIPkBH29+ntdA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.596.0.tgz", + "integrity": "sha512-KnTWtKzO0N+rMdIrVwbewFp4FAvVWBV/ekCAh5w7EN+uAvBHxMoFElE2RwlcRF/gH1/F715OspPMvOxPom6bMA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.596.0.tgz", + "integrity": "sha512-37+WQDjgmqS/YXj3vPzIVIrbXaFcZ1WXk715AMGIPBZn9Y2/wr2bmSTpX7bsMyn0G8+LxmoIxFcG7n1Gu0nvLg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.592.0.tgz", + "integrity": "sha512-gLPMXR/HXDP+9gXAt58t7gaMTvRts9i6Q7NMISpkGF54wehskl5WGrbdtHJFylrlJ5BQo3XVY6i661o+EuR1wg==", + "dependencies": { + "@smithy/core": "^2.2.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.587.0.tgz", + "integrity": "sha512-Hyg/5KFECIk2k5o8wnVEiniV86yVkhn5kzITUydmNGCkXdBFHMHRx6hleQ1bqwJHbBskyu8nbYamzcwymmGwmw==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.596.0.tgz", + "integrity": "sha512-nnmvEsz1KJgRmfSZJPWuzbxPRXu8Y+/78Ifa1jY3fQKSKdEJfXMDsjPljJvMDBl4dZ8pf5Hwx+S/ONnMEDwYEA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.596.0.tgz", + "integrity": "sha512-c7PLtd7GbnOVAc5sk3sVlHxLvEsM8RF96rsBGlRo4AVpil/lXLKyNv9VarS4w/ZZZoRbJRyZ+m92PjNcLvpTDQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.587.0", + "@aws-sdk/credential-provider-http": "3.596.0", + "@aws-sdk/credential-provider-process": "3.587.0", + "@aws-sdk/credential-provider-sso": "3.592.0", + "@aws-sdk/credential-provider-web-identity": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/credential-provider-imds": "^3.1.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@aws-sdk/client-sts": "^3.596.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", - "dev": true, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.596.0.tgz", + "integrity": "sha512-F4MLyXpQyie1AnJS9n7TIRL0aF7YH8tKMIJXDsM5OXpSZi2en+yR6SzsxvHf5dwS2Ga8LUdEJyiyS2NoebaJGA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.587.0", + "@aws-sdk/credential-provider-http": "3.596.0", + "@aws-sdk/credential-provider-ini": "3.596.0", + "@aws-sdk/credential-provider-process": "3.587.0", + "@aws-sdk/credential-provider-sso": "3.592.0", + "@aws-sdk/credential-provider-web-identity": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/credential-provider-imds": "^3.1.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/core": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.10.tgz", - "integrity": "sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.10", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.9", - "@babel/parser": "^7.17.10", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.10", - "@babel/types": "^7.17.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.587.0.tgz", + "integrity": "sha512-V4xT3iCqkF8uL6QC4gqBJg/2asd/damswP1h9HCfqTllmPWzImS+8WD3VjgTLw5b0KbTy+ZdUhKc0wDnyzkzxg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=16.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.10.tgz", - "integrity": "sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==", - "dev": true, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.592.0.tgz", + "integrity": "sha512-fYFzAdDHKHvhtufPPtrLdSv8lO6GuW3em6n3erM5uFdpGytNpjXvr3XGokIsuXcNkETAY/Xihg+G9ksNE8WJxQ==", "dependencies": { - "@babel/types": "^7.17.10", - "@jridgewell/gen-mapping": "^0.1.0", - "jsesc": "^2.5.1" + "@aws-sdk/client-sso": "3.592.0", + "@aws-sdk/token-providers": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", - "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", - "dev": true, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.587.0.tgz", + "integrity": "sha512-XqIx/I2PG7kyuw3WjAP9wKlxy8IvFJwB8asOFT1xPFoVfZYKIogjG9oLP5YiRtfvDkWIztHmg5MlVv3HdJDGRw==", "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", - "semver": "^6.3.0" + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@aws-sdk/client-sts": "^3.587.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.587.0.tgz", + "integrity": "sha512-HkFXLPl8pr6BH/Q0JpOESqEKL0ZK3sk7aSZ1S6GE4RXET7H5R94THULXqQFZzD48gZcyFooO/yNKZTqrZFaWKg==", "dependencies": { - "@babel/types": "^7.16.7" + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", - "dev": true, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.577.0.tgz", + "integrity": "sha512-6dPp8Tv4F0of4un5IAyG6q++GrRrNQQ4P2NAMB1W0VO4JoEu1C8GievbbDLi88TFIFmtKpnHB0ODCzwnoe8JsA==", "dependencies": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.587.0.tgz", + "integrity": "sha512-URMwp/budDvKhIvZ4a6zIBfFTun/iDlPWXqsGKYjEtHt8jz27OSjCZtDtIeqW4WTBdKL8KZgQcl+DdaE5M1qiQ==", "dependencies": { - "@babel/types": "^7.16.7" + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", + "@aws-sdk/types": "3.577.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.577.0.tgz", + "integrity": "sha512-9ca5MJz455CODIVXs0/sWmJm7t3QO4EUa1zf8pE8grLpzf0J94bz/skDWm37Pli13T3WaAQBHCTiH2gUVfCsWg==", "dependencies": { - "@babel/types": "^7.16.7" + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", - "dev": true, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.577.0.tgz", + "integrity": "sha512-DKPTD2D2s+t2QUo/IXYtVa/6Un8GZ+phSTBkyBNx2kfZz4Kwavhl/JJzSqTV3GfCXkVdFu7CrjoX7BZ6qWeTUA==", "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", - "dev": true, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.577.0.tgz", + "integrity": "sha512-aPFGpGjTZcJYk+24bg7jT4XdIp42mFXSuPt49lw5KygefLyJM/sB0bKKqPYYivW0rcuZ9brQ58eZUNthrzYAvg==", "dependencies": { - "@babel/types": "^7.17.0" + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.577.0.tgz", + "integrity": "sha512-pn3ZVEd2iobKJlR3H+bDilHjgRnNrQ6HMmK9ZzZw89Ckn3Dcbv48xOv4RJvu0aU8SDLl/SNCxppKjeLDTPGBNA==", "dependencies": { - "@babel/types": "^7.16.7" + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "node_modules/@aws-sdk/middleware-sdk-api-gateway": { + "version": "3.580.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-api-gateway/-/middleware-sdk-api-gateway-3.580.0.tgz", + "integrity": "sha512-+6IsjfdDUK0171gQkBmVTRVMg1ZvHXNoxbhZ8MDUJbGDNsAiBJX16mj+TlOuIIrw9bnsuERunmjCBmNJ2bS/Cg==", "dev": true, + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.587.0.tgz", + "integrity": "sha512-vtXTGEiw1E9Fax4LmcU2Z208gbrC8ShrdsSLmGcRPpu5NPOGBFBSDG5sy5EDNClrFxIl/Le8coQnD0EDBtx+uQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/helpers": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", - "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", - "dev": true, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.587.0.tgz", + "integrity": "sha512-tiZaTDj4RvhXGRAlncFn7CSEfL3iNPO67WSaxAq+Ls5j1VgczPhu5262cWONNoMgth3nXR1hhLC4ITSl/a6AzA==", "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.9", - "@babel/types": "^7.17.0" + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-middleware": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/highlight": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", - "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", - "dev": true, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.577.0.tgz", + "integrity": "sha512-i2BPJR+rp8xmRVIGc0h1kDRFcM2J9GnClqqpc+NLSjmYadlcg4mPklisz9HzwFVcRPJ5XcGf3U4BYs5G8+iTyg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/parser": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", - "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.587.0.tgz", + "integrity": "sha512-SyDomN+IOrygLucziG7/nOHkjUXES5oH5T7p8AboO8oakMQJdnudNXiYWTicQWO52R51U6CR27rcMPTGeMedYA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", - "dev": true, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.587.0.tgz", + "integrity": "sha512-93I7IPZtulZQoRK+O20IJ4a1syWwYPzoO2gc3v+/GNZflZPV3QJXuVbIm0pxBsu0n/mzKGUKqSOLPIaN098HcQ==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "@aws-sdk/types": "3.577.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", - "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", - "dev": true, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.587.0.tgz", + "integrity": "sha512-TR9+ZSjdXvXUz54ayHcCihhcvxI9W7102J1OK6MrLgBlPE7uRhAx42BR9L5lLJ86Xj3LuqPWf//o9d/zR9WVIg==", "dependencies": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" + "@aws-sdk/middleware-sdk-s3": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, + "node_modules/@aws-sdk/token-providers": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.587.0.tgz", + "integrity": "sha512-ULqhbnLy1hmJNRcukANBWJmum3BbjXnurLPSFXoGdV0llXYlG55SzIla2VYqdveQEEjmsBuTZdFvXAtNpmS5Zg==", "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.587.0" } }, - "node_modules/@babel/traverse": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.10.tgz", - "integrity": "sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.10", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.10", - "@babel/types": "^7.17.10", - "debug": "^4.1.0", - "globals": "^11.1.0" + "node_modules/@aws-sdk/types": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.577.0.tgz", + "integrity": "sha512-FT2JZES3wBKN/alfmhlo+3ZOq/XJ0C7QOZcDNrpKjB0kqYoKjhVKZ/Hx6ArR0czkKfHzBBEs6y40ebIHx2nSmA==", + "dependencies": { + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@babel/types": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", - "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", - "dev": true, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", + "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=16.0.0" } }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "optional": true, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.587.0.tgz", + "integrity": "sha512-8I1HG6Em8wQWqKcRW6m358mqebRVNpL8XrrEoT4In7xqkKkmYtHRNVYP6lcmiQh5pZ/c/FXu8dSchuFIWyEtqQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "@smithy/util-endpoints": "^2.0.1", + "tslib": "^2.6.2" + }, "engines": { - "node": ">= 12" + "node": ">=16.0.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "optional": true, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", + "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=12" + "node": ">=16.0.0" } }, - "node_modules/@defillama/sdk": { - "version": "2.3.63", - "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-2.3.63.tgz", - "integrity": "sha512-vTWW0HOdwDOIaGA8racqeFKGYs9vc2aUb5NFMgNMV/LBbW46GUGEVSZ0rUaI9AhTevxF4oLwEXHOtd2mOs2Rig==", + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.577.0.tgz", + "integrity": "sha512-zEAzHgR6HWpZOH7xFgeJLc6/CzMcx4nxeQolZxVZoB5pPaJd3CjyRhZN0xXeZB0XIRCWmb4yJBgyiugXLNMkLA==", "dependencies": { - "@supercharge/promise-pool": "^2.1.0", - "ethers": "^5.4.5", - "graphql": "^15.5.0", - "graphql-request": "^3.4.0", - "node-fetch": "^2.6.1" - }, - "bin": { - "sdk": "build/cli.js" + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" } }, - "node_modules/@electron/get": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", - "integrity": "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==", - "dev": true, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.587.0.tgz", + "integrity": "sha512-Pnl+DUe/bvnbEEDHP3iVJrOtE3HbFJBPgsD6vJ+ml/+IYk1Eq49jEG+EHZdNTPz3SDG0kbp2+7u41MKYJHR/iQ==", "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^9.6.0", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" + "@aws-sdk/types": "3.577.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8.6" + "node": ">=16.0.0" }, - "optionalDependencies": { - "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1" + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.575.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.575.0.tgz", + "integrity": "sha512-cWgAwmbFYNCFzPwxL705+lWps0F3ZvOckufd2KKoEZUmtpVw9/txUXNrPySUXSmRTSRhoatIMABNfStWR043bQ==", + "dependencies": { + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "type-fest": "^0.20.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6.9.0" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@ethereumjs/common": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.4.tgz", - "integrity": "sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==", + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, "dependencies": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/abi": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.2.tgz", - "integrity": "sha512-40Ixjhy+YzFtnvzIqFU13FW9hd1gMoLa3cJfSDnfnL4o8EnEG1qLiV8sNJo3sHYi9UYMfFeRuZ7kv5+vhzU7gQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, "dependencies": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.1.tgz", - "integrity": "sha512-xhSLo6y0nGJS7NxfvOSzCaWKvWb1TLT7dQ0nnpHZrDnC67xfnWm9NXflTMFPUXXMtjr33CdV0kWDEmnbrQZ74Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/basex": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", - "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/properties": "^5.6.0" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/bignumber": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.1.tgz", - "integrity": "sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, "dependencies": { - "@ethersproject/logger": "^5.6.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.6.0" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@ethersproject/contracts": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.1.tgz", - "integrity": "sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, "dependencies": { - "@ethersproject/abi": "^5.6.0", - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "dev": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@ethersproject/hdnode": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.1.tgz", - "integrity": "sha512-6IuYDmbH5Bv/WH/A2cUd0FjNr4qTLAvyHAECiFZhNZp69pPvU7qIDwJ7CU7VAkwm4IVBzqdYy9mpMAGhQdwCDA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", - "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "js-sha3": "0.8.0" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@ethersproject/networks": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz", - "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.6.0" + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", - "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/sha2": "^5.6.0" + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, "dependencies": { - "@ethersproject/logger": "^5.6.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/providers": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.6.tgz", - "integrity": "sha512-6X6agj3NeQ4tgnvBMCjHK+CjQbz+Qmn20JTxCYZ/uymrgCEOpJtY9zeRxJIDsSi0DPw8xNAxypj95JMCsapUfA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0", - "bech32": "1.1.4", - "ws": "7.4.6" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@ethersproject/random": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", - "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/sha2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", - "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "hash.js": "1.1.7" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/signing-key": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.1.tgz", - "integrity": "sha512-XvqQ20DH0D+bS3qlrrgh+axRMth5kD1xuvqUQUTeezxUTXBOeR6hWz2/C6FBEu39FRytyybIWrYf7YLSAKr1LQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/solidity": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", - "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, "dependencies": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/units": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", - "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/wallet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.1.tgz", - "integrity": "sha512-oXWoOslEWtwZiViIMlGVjeKDQz/tI7JF9UkyzN9jaGj8z7sXt2SyFMb0Ev6vSAqjIzrCrNrJ/+MkAhtKnGOfZw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/json-wallets": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, "dependencies": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@ethersproject/wordlists": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", - "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=10.10.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=6.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", "dev": true, "dependencies": { - "debug": "^4.1.1" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", + "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "regenerator-runtime": "^0.14.0" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" } }, - "node_modules/@serverless/dashboard-plugin": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@serverless/dashboard-plugin/-/dashboard-plugin-6.2.2.tgz", - "integrity": "sha512-h3zOprpuWZCdAP7qoOKT2nboB+AaxMkGoSzOD0jIBpt9s0cXqLE2VFjR2vKn8Cvam47Qa3XYnT2/XN6tR6rZgQ==", + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "dependencies": { - "@serverless/event-mocks": "^1.1.1", - "@serverless/platform-client": "^4.3.2", - "@serverless/utils": "^6.0.3", - "child-process-ext": "^2.1.1", - "chokidar": "^3.5.3", - "flat": "^5.0.2", - "fs-extra": "^9.1.0", - "js-yaml": "^4.1.0", - "jszip": "^3.9.1", - "lodash": "^4.17.21", - "memoizee": "^0.4.15", - "ncjsm": "^4.3.0", - "node-dir": "^0.1.17", - "node-fetch": "^2.6.7", - "open": "^7.4.2", - "semver": "^7.3.7", - "simple-git": "^3.7.0", - "type": "^2.6.0", - "uuid": "^8.3.2", - "yamljs": "^0.3.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { - "node": ">=12.0" + "node": ">=6.9.0" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@serverless/dashboard-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@blend-capital/blend-sdk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@blend-capital/blend-sdk/-/blend-sdk-3.0.1.tgz", + "integrity": "sha512-jqIcvVof0MY3x9+M8FJU9xcYRDeASRGSXrrS2OrSBvmfFvJ5DJ/tkHr0o19pn9Z0aWO98WrriscRQFy2NKmSBg==", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "@stellar/stellar-sdk": "13.2.0", + "buffer": "6.0.3", + "follow-redirects": ">=1.15.6" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, + "node_modules/@blend-capital/blend-sdk/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, + "node_modules/@blend-capital/blend-sdk/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@serverless/dashboard-plugin/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/@defillama/sdk": { + "version": "5.0.188", + "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.188.tgz", + "integrity": "sha512-uSimu+IusAi9Y+fhlI+FyGv5M6nEUqVQRidMg8eRyEIZy1x8PcML934UMxWEABZQ/flTSX//3xf/4+DcKvmcLA==", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-s3": "^3.400.0", + "@elastic/elasticsearch": "^8.13.1", + "@supercharge/promise-pool": "^2.1.0", + "axios": "^1.6.5", + "ethers": "^6.0.0", + "p-limit": "^3.0.0", + "stream-json": "^1.9.1", + "tron-format-address": "^0.1.11", + "viem": "^2.38.6" + } + }, + "node_modules/@defillama/sdk/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/@defillama/sdk/node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/@defillama/sdk/node_modules/ethers": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.0.tgz", + "integrity": "sha512-+yyQQQWEntY5UVbCv++guA14RRVFm1rSnO1GoLFdrK7/XRWMoktNgyG9UjwxrQqGBfGyFKknNZ81YpUS2emCgg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@serverless/event-mocks": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@serverless/event-mocks/-/event-mocks-1.1.1.tgz", - "integrity": "sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A==", - "dev": true, + "node_modules/@defillama/sdk/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/@elastic/elasticsearch": { + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.13.1.tgz", + "integrity": "sha512-2G4Vu6OHw4+XTrp7AGIcOEezpPEoVrWg2JTK1v/exEKSLYquZkUdd+m4yOL3/UZ6bTj7hmXwrmYzW76BnLCkJQ==", "dependencies": { - "@types/lodash": "^4.14.123", - "lodash": "^4.17.11" + "@elastic/transport": "~8.4.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@serverless/platform-client": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@serverless/platform-client/-/platform-client-4.3.2.tgz", - "integrity": "sha512-DAa5Z0JAZc6UfrTZLYwqoZxgAponZpFwaqd7WzzMA+loMCkYWyJNwxrAmV6cr2UUJpkko4toPZuJ3vM9Ie+NDA==", - "dev": true, + "node_modules/@elastic/transport": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.4.1.tgz", + "integrity": "sha512-/SXVuVnuU5b4dq8OFY4izG+dmGla185PcoqgK6+AJMpmOeY1QYVNbWtCwvSvoAANN5D/wV+EBU8+x7Vf9EphbA==", "dependencies": { - "adm-zip": "^0.5.5", - "archiver": "^5.3.0", - "axios": "^0.21.1", - "fast-glob": "^3.2.7", - "https-proxy-agent": "^5.0.0", - "ignore": "^5.1.8", - "isomorphic-ws": "^4.0.1", - "js-yaml": "^3.14.1", - "jwt-decode": "^2.2.0", - "minimatch": "^3.0.4", - "querystring": "^0.2.1", - "run-parallel-limit": "^1.1.0", - "throat": "^5.0.0", - "traverse": "^0.6.6", - "ws": "^7.5.3" + "debug": "^4.3.4", + "hpagent": "^1.0.0", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0", + "tslib": "^2.4.0", + "undici": "^5.22.1" }, "engines": { - "node": ">=10.0" + "node": ">=16" } }, - "node_modules/@serverless/platform-client/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, "engines": { - "node": ">= 4" + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" } }, - "node_modules/@serverless/platform-client/node_modules/querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=0.4.x" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@serverless/platform-client/node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "engines": { - "node": ">=8.3.0" + "dependencies": { + "type-fest": "^0.20.2" }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "engines": { + "node": ">=8" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@serverless/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@serverless/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-N93Vd55docYMg2d8Gqb4/MagG4GDOStpUsWZak4QpBenkzE3Q+MK7TkeNCeBpmK+PzRiL6/4K6p81QPvZel+Pw==", - "dev": true, - "dependencies": { - "archive-type": "^4.0.0", - "chalk": "^4.1.2", - "ci-info": "^3.3.0", - "cli-progress-footer": "^2.3.1", - "content-disposition": "^0.5.4", - "d": "^1.0.1", - "decompress": "^4.2.1", - "event-emitter": "^0.3.5", - "ext": "^1.6.0", - "ext-name": "^5.0.0", - "file-type": "^16.5.3", - "filenamify": "^4.3.0", - "get-stream": "^6.0.1", - "got": "^11.8.3", - "inquirer": "^8.2.4", - "js-yaml": "^4.1.0", - "jwt-decode": "^3.1.2", - "lodash": "^4.17.21", - "log": "^6.3.1", - "log-node": "^8.0.3", - "make-dir": "^3.1.0", - "memoizee": "^0.4.15", - "ncjsm": "^4.3.0", - "node-fetch": "^2.6.7", - "open": "^7.4.2", - "p-event": "^4.2.0", - "supports-color": "^8.1.1", - "timers-ext": "^0.1.7", - "type": "^2.6.0", - "uni-global": "^1.0.0", - "uuid": "^8.3.2", - "write-file-atomic": "^4.0.1" - }, - "engines": { - "node": ">=12.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@serverless/utils/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@serverless/utils/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" }, "engines": { - "node": ">=10" + "node": ">=14" } }, - "node_modules/@serverless/utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@serverless/utils/node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@ethersproject/bytes": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } }, - "node_modules/@serverless/utils/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" } }, - "node_modules/@serverless/utils/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@serverless/utils/node_modules/got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/@serverless/utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@serverless/utils/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@serverless/utils/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/@serverless/utils/node_modules/jwt-decode": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", - "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", - "dev": true - }, - "node_modules/@serverless/utils/node_modules/keyv": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.8.tgz", - "integrity": "sha512-IZZo6krhHWPhgsP5mBkEdPopVPN/stgCnBVuqi6dda/Nm5mDTOSVTrFMkWqlJsDum+B0YSe887tNxdjDWkO7aQ==", - "dev": true, - "dependencies": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" - } - }, - "node_modules/@serverless/utils/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@serverless/utils/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@serverless/utils/node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@serverless/utils/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@serverless/utils/node_modules/responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, - "dependencies": { - "lowercase-keys": "^2.0.0" - } - }, - "node_modules/@serverless/utils/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@serverless/utils/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@supercharge/promise-pool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-2.1.0.tgz", - "integrity": "sha512-YEKOfn4xF+DQ61UY5NwHNtr8hYjwchXjGTocVJDAHLQceIRZF8VECH7gumFbp+aGTfygPbMbEtBumXJ/mcJz+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true, - "optional": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true, - "optional": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true, - "optional": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true, - "optional": true - }, - "node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/bson": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", - "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "node_modules/@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.182", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", - "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", - "dev": true - }, - "node_modules/@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", - "dependencies": { - "@types/bson": "*", - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "14.18.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", - "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==" - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/2-thenable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz", - "integrity": "sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.47" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/adm-zip": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", - "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.2.tgz", - "integrity": "sha512-cEG18jjLG0O74o/33eEfnmtXYDEY196ZjL0eQEISULF+Imi7vr25l6ntGYmqS5lIrQIEeze+CqUtPVItywE7ZQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", - "dev": true, - "dependencies": { - "file-type": "^4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/archive-type/node_modules/file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/archiver": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", - "dev": true, - "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^3.2.3", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "optional": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", - "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1135.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1135.0.tgz", - "integrity": "sha512-bl9n4QgrEh52hmQ+Jo76BgJXM/p+PwfVZvImEQHFeel/33H/PDLcTJquEw5bzxM1HRNI24iH+FNPwyWLMrttTw==", - "dev": true, - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.3.2", - "xml2js": "0.4.19" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/axe-core": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", - "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", - "dev": true - }, - "node_modules/babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", - "dev": true, - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "node_modules/bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" - }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "optional": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + ], "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" } }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" } }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } ] }, - "node_modules/browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", - "dev": true, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } ], "dependencies": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", - "escalade": "^3.1.1", - "node-releases": "^2.0.3", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" } }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "hasInstallScript": true, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "dev": true - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "engines": { - "node": ">=8" + "node": ">=8.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001341", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", - "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", - "dev": true, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } - ] - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + ], "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/child-process-ext": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz", - "integrity": "sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA==", - "dev": true, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "cross-spawn": "^6.0.5", - "es5-ext": "^0.10.53", - "log": "^6.0.0", - "split2": "^3.1.1", - "stream-promise": "^3.2.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/child-process-ext/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/child-process-ext/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/child-process-ext/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" } }, - "node_modules/child-process-ext/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/child-process-ext/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" } }, - "node_modules/child-process-ext/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", "funding": [ { "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } ], "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", - "dev": true - }, - "node_modules/cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "deprecated": "This module has been superseded by the multiformats module", + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, - "node_modules/cids/node_modules/buffer": { + "node_modules/@ethersproject/web": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" } ], "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" } }, - "node_modules/class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" - }, - "node_modules/cli-color": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.2.tgz", - "integrity": "sha512-g4JYjrTW9MGtCziFNjkqp3IMpGhnJyeB0lOtRPjQkYhXzKYr6tYnXKyEVnMzITxhpbahsEW9KsxOYIDKwcsIBw==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.59", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=0.10" + "node": ">=10.10.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "dependencies": { - "restore-cursor": "^3.1.0" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/cli-progress-footer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/cli-progress-footer/-/cli-progress-footer-2.3.1.tgz", - "integrity": "sha512-urD1hiEIQeZadVABtW5ExM8wse1phnmz15oJ4QEe46GQN87v1VBa0lZQ7gXkPELMzP6At4VY6v07baAiyztulw==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "cli-color": "^2.0.2", - "d": "^1.0.1", - "es5-ext": "^0.10.59", - "mute-stream": "0.0.8", - "process-utils": "^4.0.0", - "timers-ext": "^0.1.7", - "type": "^2.6.0" - }, "engines": { - "node": ">=10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cli-sprintf-format": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-sprintf-format/-/cli-sprintf-format-1.1.1.tgz", - "integrity": "sha512-BbEjY9BEdA6wagVwTqPvmAwGB24U93rQPBFZUT8lNCDxXzre5LFHQUTJc70czjgUomVg8u8R5kW8oY9DYRFNeg==", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { - "cli-color": "^2.0.1", - "es5-ext": "^0.10.53", - "sprintf-kit": "^2.0.1", - "supports-color": "^6.1.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=6.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-sprintf-format/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=6" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", "dependencies": { - "mimic-response": "^1.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { - "node": ">= 6" + "node": ">=6" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/compress-brotli": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", - "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 12" + "node": ">=8" } }, - "node_modules/compress-brotli/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/compress-commons/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "optional": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { - "safe-buffer": "5.2.1" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">=8" } }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" - }, - "node_modules/core-js-pure": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.5.tgz", - "integrity": "sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "engines": { + "node": ">=8" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dev": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" }, "engines": { - "node": ">= 0.10" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "bin": { - "crc32": "bin/crc32.njs" + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/crc32-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 6" + "node": ">=7.0.0" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "node_modules/@jest/core": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", "dev": true, - "optional": true - }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dependencies": { - "node-fetch": "2.6.7" + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "node_modules/@jest/core/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" } }, - "node_modules/d/node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.10" + "node": ">=7.0.0" } }, - "node_modules/date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "node": ">=8" } }, - "node_modules/dayjs": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", - "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "ms": "2.1.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8" } }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, "engines": { - "node": ">=0.10" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, "dependencies": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dependencies": { - "mimic-response": "^1.0.0" + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "node_modules/@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "dependencies": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-tar/node_modules/bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "node_modules/@jest/reporters": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/decompress-tar/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/decompress-tar/node_modules/tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" + "color-name": "~1.1.4" }, "engines": { - "node": ">=4" + "node": ">=7.0.0" } }, - "node_modules/decompress-tarbz2/node_modules/file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/decompress-targz/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "node_modules/@jest/source-map": { + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, "dependencies": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" + "@jridgewell/trace-mapping": "^0.3.13", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-unzip/node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-unzip/node_modules/get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "node_modules/@jest/test-sequencer": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, "dependencies": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress-unzip/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/decompress/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "pify": "^3.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/decompress/node_modules/make-dir/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/decompress/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, - "node_modules/deferred": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/deferred/-/deferred-0.7.11.tgz", - "integrity": "sha512-8eluCl/Blx4YOGwMapBvXRKxHXhA8ejDXYzEaK8+/gtcm8hRMhSLmXSqDmNUKNc/C8HNSmuyyp/hflhqDAvK2A==", + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.50", - "event-emitter": "^0.3.5", - "next-tick": "^1.0.0", - "timers-ext": "^0.1.7" + "engines": { + "node": ">=8" } }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=0.10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "color-name": "~1.1.4" + }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=7.0.0" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "node": ">=8" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { - "path-type": "^4.0.0" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=6.0.0" } }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true }, - "node_modules/duration": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", - "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "d": "1", - "es5-ext": "~0.10.46" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "debug": "^4.1.1" } }, - "node_modules/ee-first": { + "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true }, - "node_modules/electron": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/electron/-/electron-17.4.4.tgz", - "integrity": "sha512-/CqXJwm1VLfhF7+QhCrPEoePcpGMdRh09A+sVHX+kgT1twrmNH8S+ZeMPYxX8EU0O0Eki3UfA5zA2ADWaCDq2Q==", - "dev": true, - "hasInstallScript": true, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "peer": true, "dependencies": { - "@electron/get": "^1.13.0", - "@types/node": "^14.6.2", - "extract-zip": "^1.0.3" - }, - "bin": { - "electron": "cli.js" + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" }, "engines": { - "node": ">= 8.6" + "node": ">=12.0.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.137", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", - "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", - "dev": true + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", "engines": { - "node": ">= 4" + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "devOptional": true, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { - "iconv-lite": "^0.6.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "node_modules/enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=10.13.0" + "node": ">= 8" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, + "node_modules/@nomicfoundation/edr": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.0.tgz", + "integrity": "sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw==", + "peer": true, "dependencies": { - "ansi-colors": "^4.1.1" + "@nomicfoundation/edr-darwin-arm64": "0.4.0", + "@nomicfoundation/edr-darwin-x64": "0.4.0", + "@nomicfoundation/edr-linux-arm64-gnu": "0.4.0", + "@nomicfoundation/edr-linux-arm64-musl": "0.4.0", + "@nomicfoundation/edr-linux-x64-gnu": "0.4.0", + "@nomicfoundation/edr-linux-x64-musl": "0.4.0", + "@nomicfoundation/edr-win32-x64-msvc": "0.4.0" }, "engines": { - "node": ">=8.6" + "node": ">= 18" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz", + "integrity": "sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg==", + "peer": true, "engines": { - "node": ">=6" + "node": ">= 18" } }, - "node_modules/es-abstract": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.0.tgz", - "integrity": "sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.1", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz", + "integrity": "sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg==", + "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz", + "integrity": "sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz", + "integrity": "sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz", + "integrity": "sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz", + "integrity": "sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw==", + "peer": true, + "engines": { + "node": ">= 18" } }, - "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz", + "integrity": "sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A==", + "peer": true, + "engines": { + "node": ">= 18" + } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "peer": true, "dependencies": { - "has": "^1.0.3" + "@nomicfoundation/ethereumjs-util": "9.0.4" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "peer": true, + "bin": { + "rlp": "bin/rlp.cjs" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/es5-ext": { - "version": "0.10.61", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", - "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", - "hasInstallScript": true, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "peer": true, "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" }, "engines": { - "node": ">=0.10" + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" } }, - "node_modules/es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "peer": true, "dependencies": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } } }, - "node_modules/es6-set/node_modules/es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" } }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "peer": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" } }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } + "node_modules/@openzeppelin/contracts": { + "version": "3.4.2-solc-0.7", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz", + "integrity": "sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==" }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "optional": true, "engines": { - "node": ">=6" + "node": ">=14" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" + "node_modules/@scure/base": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", + "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, + "node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eslint-config-airbnb": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", - "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", - "dev": true, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "eslint-config-airbnb-base": "^14.2.1", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "^6.4.1", - "eslint-plugin-react": "^7.21.5", - "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" } }, - "node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "peer": true, "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" }, "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" + "node": ">=6" } }, - "node_modules/eslint-config-prettier": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "peer": true, "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "peer": true, "dependencies": { - "ms": "^2.1.1" + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" } }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "peer": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" + "node_modules/@sentry/node/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "peer": true, + "engines": { + "node": ">= 0.6" } }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "peer": true, "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" }, "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + "node": ">=6" } }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "peer": true, "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "node": ">=6" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "peer": true, "dependencies": { - "ms": "2.0.0" + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@serverless/dashboard-plugin": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@serverless/dashboard-plugin/-/dashboard-plugin-7.2.3.tgz", + "integrity": "sha512-Vu4TKJLEQ5F8ZipfCvd8A/LMIdH8kNGe448sX9mT4/Z0JVUaYmMc3BwkQ+zkNIh3QdBKAhocGn45TYjHV6uPWQ==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "@aws-sdk/client-cloudformation": "^3.410.0", + "@aws-sdk/client-sts": "^3.410.0", + "@serverless/event-mocks": "^1.1.1", + "@serverless/platform-client": "^4.5.1", + "@serverless/utils": "^6.14.0", + "child-process-ext": "^3.0.1", + "chokidar": "^3.5.3", + "flat": "^5.0.2", + "fs-extra": "^9.1.0", + "js-yaml": "^4.1.0", + "jszip": "^3.10.1", + "lodash": "^4.17.21", + "memoizee": "^0.4.15", + "ncjsm": "^4.3.2", + "node-dir": "^0.1.17", + "node-fetch": "^2.6.8", + "open": "^7.4.2", + "semver": "^7.3.8", + "simple-git": "^3.16.0", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "uuid": "^8.3.2", + "yamljs": "^0.3.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "node_modules/@serverless/dashboard-plugin/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", - "integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.3", - "aria-query": "^4.2.2", - "array-includes": "^3.1.4", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", - "language-tags": "^1.0.5", - "minimatch": "^3.0.4" + "node_modules/@serverless/dashboard-plugin/node_modules/child-process-ext": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-3.0.2.tgz", + "integrity": "sha512-oBePsLbQpTJFxzwyCvs9yWWF0OEM6vGGepHwt1stqmX7QQqOuDc8j2ywdvAs9Tvi44TT7d9ackqhR4Q10l1u8w==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "es5-ext": "^0.10.62", + "log": "^6.3.1", + "split2": "^3.2.2", + "stream-promise": "^3.2.0" }, "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "node": ">=8.0" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "node_modules/@serverless/dashboard-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" + "node": ">=10" } }, - "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "node_modules/@serverless/dashboard-plugin/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "node_modules/@serverless/dashboard-plugin/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" + "universalify": "^2.0.0" }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/eslint-plugin-react": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", - "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", + "node_modules/@serverless/dashboard-plugin/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", - "object.values": "^1.1.5", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" }, "engines": { - "node": ">=4" + "node": ">=8" }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", + "node_modules/@serverless/dashboard-plugin/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "peer": true, + "bin": { + "semver": "bin/semver.js" + }, "engines": { "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@serverless/dashboard-plugin/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" - }, + "readable-stream": "^3.0.0" + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 10.0.0" + } + }, + "node_modules/@serverless/dashboard-plugin/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "node_modules/@serverless/event-mocks": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@serverless/event-mocks/-/event-mocks-1.1.1.tgz", + "integrity": "sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A==", "dev": true, "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/lodash": "^4.14.123", + "lodash": "^4.17.11" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/@serverless/platform-client": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@serverless/platform-client/-/platform-client-4.5.1.tgz", + "integrity": "sha512-XltmO/029X76zi0LUFmhsnanhE2wnqH1xf+WBt5K8gumQA9LnrfwLgPxj+VA+mm6wQhy+PCp7H5SS0ZPu7F2Cw==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "adm-zip": "^0.5.5", + "archiver": "^5.3.0", + "axios": "^1.6.2", + "fast-glob": "^3.2.7", + "https-proxy-agent": "^5.0.0", + "ignore": "^5.1.8", + "isomorphic-ws": "^4.0.1", + "js-yaml": "^3.14.1", + "jwt-decode": "^2.2.0", + "minimatch": "^3.0.4", + "querystring": "^0.2.1", + "run-parallel-limit": "^1.1.0", + "throat": "^5.0.0", + "traverse": "^0.6.6", + "ws": "^7.5.3" }, "engines": { - "node": ">=8.0.0" + "node": ">=10.0" } }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@serverless/platform-client/node_modules/adm-zip": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.14.tgz", + "integrity": "sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=12.0" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/@serverless/platform-client/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">= 4" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/@serverless/platform-client/node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.4.x" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/@serverless/platform-client/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "dev": true, "engines": { - "node": ">=10" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "node_modules/@serverless/utils": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@serverless/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-7eDbqKv/OBd11jjdZjUwFGN8sHWkeUqLeHXHQxQ1azja2IM7WIH+z/aLgzR6LhB3/MINNwtjesDpjGqTMj2JKQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "archive-type": "^4.0.0", + "chalk": "^4.1.2", + "ci-info": "^3.8.0", + "cli-progress-footer": "^2.3.2", + "content-disposition": "^0.5.4", + "d": "^1.0.1", + "decompress": "^4.2.1", + "event-emitter": "^0.3.5", + "ext": "^1.7.0", + "ext-name": "^5.0.0", + "file-type": "^16.5.4", + "filenamify": "^4.3.0", + "get-stream": "^6.0.1", + "got": "^11.8.6", + "inquirer": "^8.2.5", + "js-yaml": "^4.1.0", + "jwt-decode": "^3.1.2", + "lodash": "^4.17.21", + "log": "^6.3.1", + "log-node": "^8.0.3", + "make-dir": "^4.0.0", + "memoizee": "^0.4.15", + "ms": "^2.1.3", + "ncjsm": "^4.3.2", + "node-fetch": "^2.6.11", + "open": "^8.4.2", + "p-event": "^4.2.0", + "supports-color": "^8.1.1", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "uni-global": "^1.0.0", + "uuid": "^8.3.2", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": ">=12.0" } }, - "node_modules/eslint/node_modules/ansi-styles": { + "node_modules/@serverless/utils/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -5091,7 +4602,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/chalk": { + "node_modules/@serverless/utils/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@serverless/utils/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -5107,7 +4624,34 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint/node_modules/color-convert": { + "node_modules/@serverless/utils/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@serverless/utils/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/@serverless/utils/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -5119,16 +4663,16 @@ "node": ">=7.0.0" } }, - "node_modules/eslint/node_modules/color-name": { + "node_modules/@serverless/utils/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/@serverless/utils/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { "node": ">=10" @@ -5137,22 +4681,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { + "node_modules/@serverless/utils/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -5161,1744 +4690,1890 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/@serverless/utils/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "argparse": "^2.0.1" }, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/esniff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.0.tgz", - "integrity": "sha1-xmhJIp+RRk3t4uDUAgHtar9l8qw=", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.12" - } + "node_modules/@serverless/utils/node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", + "dev": true }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/@serverless/utils/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "semver": "^7.5.3" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "node": ">=10" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/@serverless/utils/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "estraverse": "^5.1.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.10" + "node": ">=10" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/@serverless/utils/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/essentials": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/essentials/-/essentials-1.2.0.tgz", - "integrity": "sha512-kP/j7Iw7KeNE8b/o7+tr9uX2s1wegElGOoGZ2Xm35qBr4BbbEcH3/bxR2nfH9l9JANCq9AUrvKw+gRuHtZp0HQ==", + "node_modules/@serverless/utils/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, - "dependencies": { - "uni-global": "^1.0.0" + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "type-detect": "4.0.8" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", + "node_modules/@smithy/abort-controller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.0.1.tgz", + "integrity": "sha512-Jb7jg4E+C+uvrUQi+h9kbILY6ts6fglKZzseMCHlH9ayq+1f5QdpYf8MV/xppuiN6DAMJAmwGz53GwP3213dmA==", "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/eth-ens-namehash/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "node_modules/@smithy/chunked-blob-reader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-3.0.0.tgz", + "integrity": "sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==", "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" + "tslib": "^2.6.2" } }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.0.tgz", + "integrity": "sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==", "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "node_modules/@smithy/config-resolver": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.2.tgz", + "integrity": "sha512-wUyG6ezpp2sWAvfqmSYTROwFUmJqKV78GLf55WODrosBcT0BAMd9bOLO4HRhynWBgAobPml2cF9ZOdgCe00r+g==", "dependencies": { - "js-sha3": "^0.8.0" + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/@smithy/core": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.1.tgz", + "integrity": "sha512-R8Pzrr2v2oGUoj4CTZtKPr87lVtBsz7IUBGhSwS1kc6Cj0yPwNdYbkzhFsxhoDE9+BPl09VN/6rFsW9GJzWnBA==", "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "node_modules/@smithy/credential-provider-imds": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.1.tgz", + "integrity": "sha512-htndP0LwHdE3R3Nam9ZyVWhwPYOmD4xCL79kqvNxy8u/bv0huuy574CSiRY4cvEICgimv8jlVfLeZ7zZqbnB2g==", "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" + "@smithy/node-config-provider": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" } }, - "node_modules/ethereumjs-util/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "node_modules/@smithy/eventstream-codec": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.0.1.tgz", + "integrity": "sha512-RNl3CuWZWPy+s8sx4PcOkRvlfodR33Dj3hzUuDG/CoF6XBvm5Xvr33wRoC1RWht0NN+Q6Z6KcoAkhlQA12MBBw==", "dependencies": { - "@types/node": "*" + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^3.1.0", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" } }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/ethers": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.6.tgz", - "integrity": "sha512-2B2ZmSGvRcJpHnFMBk58mkXP50njFipUBCgLK8jUTFbomhVs501cLzyMU6+Vx8YnUDQxywC3qkZvd33xWS+2FA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.6.2", - "@ethersproject/abstract-provider": "5.6.0", - "@ethersproject/abstract-signer": "5.6.1", - "@ethersproject/address": "5.6.0", - "@ethersproject/base64": "5.6.0", - "@ethersproject/basex": "5.6.0", - "@ethersproject/bignumber": "5.6.1", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.0", - "@ethersproject/contracts": "5.6.1", - "@ethersproject/hash": "5.6.0", - "@ethersproject/hdnode": "5.6.1", - "@ethersproject/json-wallets": "5.6.0", - "@ethersproject/keccak256": "5.6.0", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.2", - "@ethersproject/pbkdf2": "5.6.0", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.6", - "@ethersproject/random": "5.6.0", - "@ethersproject/rlp": "5.6.0", - "@ethersproject/sha2": "5.6.0", - "@ethersproject/signing-key": "5.6.1", - "@ethersproject/solidity": "5.6.0", - "@ethersproject/strings": "5.6.0", - "@ethersproject/transactions": "5.6.0", - "@ethersproject/units": "5.6.0", - "@ethersproject/wallet": "5.6.1", - "@ethersproject/web": "5.6.0", - "@ethersproject/wordlists": "5.6.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "node_modules/@smithy/eventstream-serde-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.1.tgz", + "integrity": "sha512-hpjzFlsDwtircebetScjEiwQwwPy0XASsV3dpUxEhPQUnF/mQ/IeiXaDrhsOmJiscMuCwxNPoZm3x4XmnGwN1g==", "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" + "@smithy/eventstream-serde-universal": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=16.0.0" } }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.1.tgz", + "integrity": "sha512-6+B8P+5Q1mll4u7IoI7mpmYOSW3/c2r3WQoYLdqOjbIKMixJFGmN79ZjJiNMy4X2GZ4We9kQ6LfnFuczSlhcyw==", "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true, + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=0.4.x" + "node": ">=16.0.0" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/@smithy/eventstream-serde-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.1.tgz", + "integrity": "sha512-8ylxIbZ0XiQD8kSKPmrrGS/2LmcDxg1mAAURa5tjcjYeBJPg7EaFRcH/aRe2RDPaoVUAbOfjHh2bTkWvy7P4Ig==", "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "@smithy/eventstream-serde-universal": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "node_modules/@smithy/eventstream-serde-universal": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.1.tgz", + "integrity": "sha512-E6aeN0MEO1p1KVN4Z3XQlvdUPp+hKJ21eiiioWtNLNNGAZUaJPlXgrqF+6Wj/aM86//9EQp6/iAwQB6eXaulzw==", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "@smithy/eventstream-codec": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">=16.0.0" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@smithy/fetch-http-handler": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.0.2.tgz", + "integrity": "sha512-0nW6tLK0b7EqSsfKvnOmZCgJqnodBAnvqcrlC5dotKfklLedPTRGsQamSVbVDWyuU/QGg+YbZDJUQ0CUufJXZQ==", "dependencies": { - "ms": "2.0.0" + "@smithy/protocol-http": "^4.0.1", + "@smithy/querystring-builder": "^3.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "node_modules/@smithy/hash-blob-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.0.1.tgz", + "integrity": "sha512-P8xxvMm0F6vi/7+GwGhZbE532b7TzGJUfUoUNGrb+dcR+MJUisV8sEQBZ5EB/ddf1/aGr8KO7QqbO/6WhfdW/Q==", "dependencies": { - "type": "^2.5.0" + "@smithy/chunked-blob-reader": "^3.0.0", + "@smithy/chunked-blob-reader-native": "^3.0.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" } }, - "node_modules/ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, + "node_modules/@smithy/hash-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.1.tgz", + "integrity": "sha512-w2ncjgk2EYO2+WhAsSQA8owzoOSY7IL1qVytlwpnL1pFGWTjIoIh5nROkEKXY51unB63bMGZqDiVoXaFbyKDlg==", "dependencies": { - "mime-db": "^1.28.0" + "@smithy/types": "^3.1.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, + "node_modules/@smithy/hash-stream-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.0.1.tgz", + "integrity": "sha512-5Z5Oyqh9f5927HWyKK3klG09rMlVu8OcEQd4YDxYZbjdB9nHd8imTMN06tfcyrZCEzcOdeUCpJmjfVWUxUDigg==", "dependencies": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" + "@smithy/types": "^3.1.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=4" + "node": ">=16.0.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "node_modules/@smithy/invalid-dependency": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.1.tgz", + "integrity": "sha512-RSNF/32BKygXKKMyS7koyuAq1rcdW5p5c4EFa77QenBFze9As+JiRnV9OWBh2cB/ejGZalEZjvIrMLHwJl7aGA==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, + "node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.1.tgz", + "integrity": "sha512-wQa0YGsR4Zb1GQLGwOOgRAbkj22P6CFGaFzu5bKk8K4HVNIC2dBlIxqZ/baF0pLiSZySAPdDZT7CdZ7GkGXt5A==", + "dependencies": { + "@smithy/types": "^3.1.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.1.tgz", + "integrity": "sha512-6QdK/VbrCfXD5/QolE2W/ok6VqxD+SM28Ds8iSlEHXZwv4buLsvWyvoEEy0322K/g5uFgPzBmZjGqesTmPL+yQ==", + "dependencies": { + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=4" + "node": ">=16.0.0" } }, - "node_modules/external-editor/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "node_modules/@smithy/middleware-endpoint": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.2.tgz", + "integrity": "sha512-gWEaGYB3Bei17Oiy/F2IlUPpBazNXImytoOdJ1xbrUOaJKAOiUhx8/4FOnYLLJHdAwa9PlvJ2ULda2f/Dnwi9w==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@smithy/middleware-serde": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/extract-files": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", - "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", - "engines": { - "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" + "node_modules/@smithy/middleware-retry": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.4.tgz", + "integrity": "sha512-Tu+FggbLNF5G9L6Wi8o32Mg4bhlBInWlhhaFKyytGRnkfxGopxFVXJQn7sjZdFYJyTz6RZZa06tnlvavUgtoVg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/service-error-classification": "^3.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, - "funding": { - "url": "https://github.com/sponsors/jaydenseric" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, + "node_modules/@smithy/middleware-serde": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.1.tgz", + "integrity": "sha512-ak6H/ZRN05r5+SR0/IUc5zOSyh2qp3HReg1KkrnaSLXmncy9lwOjNqybX4L4x55/e5mtVDn1uf/gQ6bw5neJPw==", "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, - "bin": { - "extract-zip": "cli.js" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "node_modules/@smithy/middleware-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.1.tgz", + "integrity": "sha512-fS5uT//y1SlBdkzIvgmWQ9FufwMXrHSSbuR25ygMy1CRDIZkcBMoF4oTMYNfR9kBlVBcVzlv7joFdNrFuQirPA==", "dependencies": { - "ms": "2.0.0" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, + "node_modules/@smithy/node-config-provider": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.1.tgz", + "integrity": "sha512-z5G7+ysL4yUtMghUd2zrLkecu0mTfnYlt5dR76g/HsFqf7evFazwiZP1ag2EJenGxNBDwDM5g8nm11NPogiUVA==", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8.6.0" + "node": ">=16.0.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, + "node_modules/@smithy/node-http-handler": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.0.1.tgz", + "integrity": "sha512-hlBI6MuREA4o1wBMEt+QNhUzoDtFFvwR6ecufimlx9D79jPybE/r8kNorphXOi91PgSO9S2fxRjcKCLk7Jw8zA==", "dependencies": { - "reusify": "^1.0.4" + "@smithy/abort-controller": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/querystring-builder": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, + "node_modules/@smithy/property-provider": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.1.tgz", + "integrity": "sha512-YknOMZcQkB5on+MU0DvbToCmT2YPtTETMXW0D3+/Iln7ezT+Zm1GMHhCW1dOH/X/+LkkQD9aXEoCX/B10s4Xdw==", "dependencies": { - "pend": "~1.2.0" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, + "node_modules/@smithy/protocol-http": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.1.tgz", + "integrity": "sha512-eBhm9zwcFPEazc654c0BEWtxYAzrw+OhoSf5pkwKzfftWKXRoqEhwOE2Pvn30v0iAdo7Mfsfb6pi1NnZlGCMpg==", "dependencies": { - "escape-string-regexp": "^1.0.5" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16.0.0" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, + "node_modules/@smithy/querystring-builder": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.1.tgz", + "integrity": "sha512-vKitpnG/2KOMVlx3x1S3FkBH075EROG3wcrcDaNerQNh8yuqnSL23btCD2UyX4i4lpPzNW6VFdxbn2Z25b/g5Q==", "dependencies": { - "flat-cache": "^3.0.4" + "@smithy/types": "^3.1.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, - "node_modules/file-type": { - "version": "16.5.3", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.3.tgz", - "integrity": "sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A==", - "dev": true, + "node_modules/@smithy/querystring-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.1.tgz", + "integrity": "sha512-Qt8DMC05lVS8NcQx94lfVbZSX+2Ym7032b/JR8AlboAa/D669kPzqb35dkjkvAG6+NWmUchef3ENtrD6F+5n8Q==", "dependencies": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "node": ">=16.0.0" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true, + "node_modules/@smithy/service-error-classification": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.1.tgz", + "integrity": "sha512-ubFUvIePjDCyIzZ+pLETqNC6KXJ/fc6g+/baqel7Zf6kJI/kZKgjwkCI7zbUhoUuOZ/4eA/87YasVu40b/B4bA==", + "dependencies": { + "@smithy/types": "^3.1.0" + }, "engines": { - "node": ">=4" + "node": ">=16.0.0" } }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.1.tgz", + "integrity": "sha512-nD6tXIX2126/P9e3wqRY1bm9dTtPZwRDyjVOd18G28o+1UOG+kOVgUwujE795HslSuPlEgqzsH5sgNP1hDjj9g==", "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16.0.0" } }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "dev": true, + "node_modules/@smithy/signature-v4": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.0.1.tgz", + "integrity": "sha512-ARAmD+E7j6TIEhKLjSZxdzs7wceINTMJRN2BXPM09BiUmJhkXAF1ZZtDXH6fhlk7oehBZeh37wGiPOqtdKjLeg==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/types": "^3.1.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">= 0.4.0" + "node": ">=16.0.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, + "node_modules/@smithy/smithy-client": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.2.tgz", + "integrity": "sha512-f3eQpczBOFUtdT/ptw2WpUKu1qH1K7xrssrSiHYtd9TuLXkvFqb88l9mz9FHeUVNSUxSnkW1anJnw6rLwUKzQQ==", "dependencies": { - "to-regex-range": "^5.0.1" + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-stream": "^3.0.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/@smithy/types": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.1.0.tgz", + "integrity": "sha512-qi4SeCVOUPjhSSZrxxB/mB8DrmuSFUcJnD9KXjuP+7C3LV/KFV4kpuUSH3OHDZgQB9TEH/1sO/Fq/5HyaK9MPw==", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.8" + "node": ">=16.0.0" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@smithy/url-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.1.tgz", + "integrity": "sha512-G140IlNFlzYWVCedC4E2d6NycM1dCUbe5CnsGW1hmGt4hYKiGOw0v7lVru9WAn5T2w09QEjl4fOESWjGmCvVmg==", "dependencies": { - "ms": "2.0.0" + "@smithy/querystring-parser": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, + "node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "node": ">=16.0.0" } }, - "node_modules/find-requires": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-requires/-/find-requires-1.0.0.tgz", - "integrity": "sha512-UME7hNwBfzeISSFQcBEDemEEskpOjI/shPrpJM5PI4DSdn6hX0dmz+2dL70blZER2z8tSnTRL+2rfzlYgtbBoQ==", - "dev": true, + "node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", "dependencies": { - "es5-ext": "^0.10.49", - "esniff": "^1.1.0" + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dependencies": { + "tslib": "^2.6.2" }, - "bin": { - "find-requires": "bin/find-requires.js" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, + "node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", "dependencies": { - "locate-path": "^2.0.0" + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=4" + "node": ">=16.0.0" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" + "node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/flat-cache": { + "node_modules/@smithy/util-defaults-mode-browser": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.4.tgz", + "integrity": "sha512-sXtin3Mue3A3xo4+XkozpgPptgmRwvNPOqTvb3ANGTCzzoQgAPBNjpE+aXCINaeSMXwHmv7E2oEn2vWdID+SAQ==", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "@smithy/property-provider": "^3.1.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 10.0.0" } }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", - "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" + "node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.4.tgz", + "integrity": "sha512-CUF6TyxLh3CgBRVYgZNOPDfzHQjeQr0vyALR6/DkQkOm7rNfGEzW1BRFi88C73pndmfvoiIT7ochuT76OPz9Dw==", + "dependencies": { + "@smithy/config-resolver": "^3.0.2", + "@smithy/credential-provider-imds": "^3.1.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.2.tgz", + "integrity": "sha512-4zFOcBFQvifd2LSD4a1dKvfIWWwh4sWNtS3oZ7mpob/qPPmJseqKB148iT+hWCDsG//TmI+8vjYPgZdvnkYlTg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", "dependencies": { - "is-callable": "^1.1.3" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "node_modules/@smithy/util-middleware": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.1.tgz", + "integrity": "sha512-WRODCQtUsO7vIvfrdxS8RFPeLKcewYtaCglZsBsedIKSUGIIvMlZT5oh+pCe72I+1L+OjnZuqRNpN2LKhWA4KQ==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, "engines": { - "node": "*" + "node": ">=16.0.0" } }, - "node_modules/form-data": { + "node_modules/@smithy/util-retry": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.1.tgz", + "integrity": "sha512-5lRtYm+8fNFEUTdqZXg5M4ppVp40rMIJfR1TpbHAhKQgPIDpWT+iYMaqgnwEbtpi9U1smyUOPv5Sg+M1neOBgw==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@smithy/service-error-classification": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 6" + "node": ">=16.0.0" } }, - "node_modules/formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", - "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" + "node_modules/@smithy/util-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.2.tgz", + "integrity": "sha512-n5Obp5AnlI6qHo8sbupwrcpBe6vFp4qkl0SRNuExKPNrH3ABAMG2ZszRTIUIv2b4AsFrCO+qiy4uH1Q3z1dxTA==", + "dependencies": { + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=16.0.0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=16.0.0" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, + "node_modules/@smithy/util-waiter": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.0.1.tgz", + "integrity": "sha512-wwnrVQdjQxvWGOAiLmqlEhENGCcDIN+XJ/+usPOgSZObAslrCXgKlkX7rNVwIWW2RhPguTKthvF+4AoO0Z6KpA==", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "@smithy/abort-controller": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=16.0.0" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, + "node_modules/@stacks/common": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@stacks/common/-/common-6.16.0.tgz", + "integrity": "sha512-PnzvhrdGRMVZvxTulitlYafSK4l02gPCBBoI9QEoTqgSnv62oaOXhYAUUkTMFKxdHW1seVEwZsrahuXiZPIAwg==", + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "@types/bn.js": "^5.1.0", + "@types/node": "^18.0.4" + } + }, + "node_modules/@stacks/common/node_modules/@types/node": { + "version": "18.19.64", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", + "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@stacks/network": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/@stacks/network/-/network-6.17.0.tgz", + "integrity": "sha512-numHbfKjwco/rbkGPOEz8+FcJ2nBnS/tdJ8R422Q70h3SiA9eqk9RjSzB8p4JP8yW1SZvW+eihADHfMpBuZyfw==", + "license": "MIT", + "dependencies": { + "@stacks/common": "^6.16.0", + "cross-fetch": "^3.1.5" + } + }, + "node_modules/@stacks/transactions": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/@stacks/transactions/-/transactions-6.17.0.tgz", + "integrity": "sha512-FUah2BRgV66ApLcEXGNGhwyFTRXqX5Zco3LpiM3essw8PF0NQlHwwdPgtDko5RfrJl3LhGXXe/30nwsfNnB3+g==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.1.5", + "@noble/secp256k1": "1.7.1", + "@stacks/common": "^6.16.0", + "@stacks/network": "^6.17.0", + "c32check": "^2.0.0", + "lodash.clonedeep": "^4.5.0" + } + }, + "node_modules/@stacks/transactions/node_modules/@noble/hashes": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.5.tgz", + "integrity": "sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@stellar/js-xdr": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.1.2.tgz", + "integrity": "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==" + }, + "node_modules/@stellar/stellar-base": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-13.1.0.tgz", + "integrity": "sha512-90EArG+eCCEzDGj3OJNoCtwpWDwxjv+rs/RNPhvg4bulpjN/CSRj+Ys/SalRcfM4/WRC5/qAfjzmJBAuquWhkA==", + "dependencies": { + "@stellar/js-xdr": "^3.1.2", + "base32.js": "^0.1.0", + "bignumber.js": "^9.1.2", + "buffer": "^6.0.3", + "sha.js": "^2.3.6", + "tweetnacl": "^1.0.3" }, "engines": { - "node": ">= 8" + "node": ">=18.0.0" + }, + "optionalDependencies": { + "sodium-native": "^4.3.3" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "node_modules/@stellar/stellar-base/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } }, - "node_modules/fs2": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/fs2/-/fs2-0.3.9.tgz", - "integrity": "sha512-WsOqncODWRlkjwll+73bAxVW3JPChDgaPX3DT4iTTm73UmG4VgALa7LaFblP232/DN60itkOrPZ8kaP1feksGQ==", - "dev": true, + "node_modules/@stellar/stellar-base/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/@stellar/stellar-sdk": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-13.2.0.tgz", + "integrity": "sha512-azxeh1+mS28h96Q+vl41ffytQvWdudRl1KtjYO0TRZb/9u0/lH57oYBeJ+gvcQr+T7s02wTayFdHbKru5V5/XA==", "dependencies": { - "d": "^1.0.1", - "deferred": "^0.7.11", - "es5-ext": "^0.10.53", - "event-emitter": "^0.3.5", - "ignore": "^5.1.8", - "memoizee": "^0.4.14", - "type": "^2.1.0" + "@stellar/stellar-base": "^13.1.0", + "axios": "^1.8.4", + "bignumber.js": "^9.1.2", + "eventsource": "^2.0.2", + "feaxios": "^0.0.23", + "randombytes": "^2.1.0", + "toml": "^3.0.0", + "urijs": "^1.19.1" }, "engines": { - "node": ">=6" + "node": ">=18.0.0" } }, - "node_modules/fs2/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, + "node_modules/@supercharge/promise-pool": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-2.4.0.tgz", + "integrity": "sha512-O9CMipBlq5OObdt1uKJGIzm9cdjpPWfj+a+Zw9EgWKxaMNHKC7EU7X9taj3H0EGQNLOSq2jAcOa3EzxlfHsD6w==", "engines": { - "node": ">= 4" + "node": ">=8" } }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "defer-to-connect": "^2.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=10" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "node_modules/@ton/core": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.56.3.tgz", + "integrity": "sha512-HVkalfqw8zqLLPehtq0CNhu5KjVzc7IrbDwDHPjGoOSXmnqSobiWj8a5F+YuWnZnEbQKtrnMGNOOjVw4LG37rg==", + "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "symbol.inspect": "1.0.1" }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@ton/crypto": ">=3.2.0" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "node_modules/@ton/crypto": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ton/crypto/-/crypto-3.2.0.tgz", + "integrity": "sha512-50RkwReEuV2FkxSZ8ht/x9+n0ZGtwRKGsJ0ay4I/HFhkYVG/awIIBQeH0W4j8d5lADdO5h01UtX8PJ8AjiejjA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ton/crypto-primitives": "2.0.0", + "jssha": "3.2.0", + "tweetnacl": "1.0.3" + } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@ton/crypto-primitives": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ton/crypto-primitives/-/crypto-primitives-2.0.0.tgz", + "integrity": "sha512-wttiNClmGbI6Dfy/8oyNnsIV0b/qYkCJz4Gn4eP62lJZzMtVQ94Ko7nikDX1EfYHkLI1xpOitWpW+8ZuG6XtDg==", + "license": "MIT", + "peer": true, + "dependencies": { + "jssha": "3.2.0" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/@ton/ton": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@ton/ton/-/ton-14.0.0.tgz", + "integrity": "sha512-xb2CY6U0AlHUKc7DV7xK/K4Gqn6YoR253yUrM2E7L5WegVFsDF0CQRUIfpYACCuj1oUywQc5J2oMolYNu/uGkA==", + "license": "MIT", + "dependencies": { + "axios": "^1.6.7", + "dataloader": "^2.0.0", + "symbol.inspect": "1.0.1", + "teslabot": "^1.3.0", + "zod": "^3.21.4" + }, + "peerDependencies": { + "@ton/core": ">=0.56.0", + "@ton/crypto": ">=3.2.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "engines": { - "node": ">=6.9.0" + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/types": "^7.0.0" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "@types/node": "*" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" + "@types/istanbul-lib-report": "*" } }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "optional": true, + "node_modules/@types/jest": { + "version": "28.1.8", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.8.tgz", + "integrity": "sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "expect": "^28.0.0", + "pretty-format": "^28.0.0" } }, - "node_modules/global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, - "optional": true, "dependencies": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - }, - "engines": { - "node": ">=0.10" + "@types/node": "*" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" + "node_modules/@types/lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", + "dev": true + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "peer": true + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dependencies": { + "undici-types": "~5.26.4" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "peer": true, "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/node": "*" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/@types/pg": { + "version": "8.11.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.6.tgz", + "integrity": "sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "@types/node": "*" } }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "peer": true, + "dependencies": { + "@types/node": "*" } }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dev": true, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "dependencies": { - "lodash": "^4.17.15" + "@types/node": "*" } }, - "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", - "engines": { - "node": ">= 10.x" + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/graphql-request": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", - "integrity": "sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, "dependencies": { - "cross-fetch": "^3.0.6", - "extract-files": "^9.0.0", - "form-data": "^3.0.0" - }, - "peerDependencies": { - "graphql": "14 - 16" + "@types/node": "*" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "node_modules/@uniswap/lib": { + "version": "4.0.1-alpha", + "resolved": "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz", + "integrity": "sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==", "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", + "node_modules/@uniswap/sdk-core": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-5.3.0.tgz", + "integrity": "sha512-wbMzSY3wbByOkoirZXyeomof4a7goueT4bOa4YqoXDWqIftqrT70UuCgjk98nIBu3UqPxRNMptXusppxZVvwWA==", "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" + "@ethersproject/address": "^5.0.2", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/strings": "5.7.0", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.4", + "tiny-invariant": "^1.1.0", + "toformat": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/@uniswap/swap-router-contracts": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.1.tgz", + "integrity": "sha512-mh/YNbwKb7Mut96VuEtL+Z5bRe0xVIbjjiryn+iMMrK2sFKhR4duk/86mEz0UO5gSx4pQIw9G5276P5heY/7Rg==", "dependencies": { - "function-bind": "^1.1.1" + "@openzeppelin/contracts": "3.4.2-solc-0.7", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v3-core": "^1.0.0", + "@uniswap/v3-periphery": "^1.4.4", + "dotenv": "^14.2.0", + "hardhat-watcher": "^2.1.1" }, "engines": { - "node": ">= 0.4.0" + "node": ">=10" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@uniswap/swap-router-contracts/node_modules/dotenv": { + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.3.2.tgz", + "integrity": "sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==", + "engines": { + "node": ">=12" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, + "node_modules/@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==", "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@uniswap/v3-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz", + "integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==", + "engines": { + "node": ">=10" } }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "node_modules/@uniswap/v3-periphery": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz", + "integrity": "sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==", + "dependencies": { + "@openzeppelin/contracts": "3.4.2-solc-0.7", + "@uniswap/lib": "^4.0.1-alpha", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v3-core": "^1.0.0", + "base64-sol": "1.0.1" + }, "engines": { - "node": "*" + "node": ">=10" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" + "node_modules/@uniswap/v3-sdk": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-sdk/-/v3-sdk-3.13.0.tgz", + "integrity": "sha512-Jz8aEU7RrDK4LfFNLClXFr2hkBE08QANLEBTofmu+ueCCKoNoRd/OTR4q04HhIeMyXtzsSOzi32a5yS7OY9glg==", + "dependencies": { + "@ethersproject/abi": "^5.5.0", + "@ethersproject/solidity": "^5.0.9", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/swap-router-contracts": "^1.3.0", + "@uniswap/v3-periphery": "^1.1.1", + "@uniswap/v3-staker": "1.0.0", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "node_modules/@uniswap/v3-staker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-staker/-/v3-staker-1.0.0.tgz", + "integrity": "sha512-JV0Qc46Px5alvg6YWd+UIaGH9lDuYG/Js7ngxPit1SPaIP30AlVer1UYB7BRYeUVVxE+byUyIeN5jeQ7LLDjIw==", + "deprecated": "Please upgrade to 1.0.1", "dependencies": { - "has-symbol-support-x": "^1.4.1" + "@openzeppelin/contracts": "3.4.1-solc-0.7-2", + "@uniswap/v3-core": "1.0.0", + "@uniswap/v3-periphery": "^1.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, - "node_modules/has-tostringtag": { + "node_modules/@uniswap/v3-staker/node_modules/@openzeppelin/contracts": { + "version": "3.4.1-solc-0.7-2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz", + "integrity": "sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==" + }, + "node_modules/@uniswap/v3-staker/node_modules/@uniswap/v3-core": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz", + "integrity": "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, - "node_modules/http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/2-thenable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz", + "integrity": "sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.47" + } + }, + "node_modules/abitype": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", + "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", + "peerDependencies": { + "typescript": ">=4.9.4", + "zod": "^3 >=3.19.1" }, - "engines": { - "node": ">= 6" + "peerDependenciesMeta": { + "zod": { + "optional": true + } } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "event-target-shim": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.5" } }, - "node_modules/idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { - "punycode": "2.1.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=4.0.0" + "node": ">= 0.6" } }, - "node_modules/idna-uts46-hx/node_modules/punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=6" + "node": ">=0.4.0" } }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "devOptional": true, "engines": { - "node": ">= 4" + "node": ">=0.4.0" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "peer": true, + "engines": { + "node": ">=0.3.0" + } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "debug": "4" }, "engines": { - "node": ">=6" + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "peer": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, - "engines": { - "node": ">=0.8.19" + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "optional": true + "peerDependencies": { + "ajv": "^6.9.1" + } }, - "node_modules/inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", - "dev": true, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "peer": true, "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "engines": { - "node": ">=12.0.0" + "node": ">=6" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dependencies": { - "color-convert": "^2.0.1" + "type-fest": "^0.21.3" }, "engines": { "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=10" + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "engines": { + "node": ">= 8" } }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "file-type": "^4.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=4" } }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" }, "engines": { - "node": ">=8" + "node": ">= 10" } }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 6" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/is-arguments": { + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/archiver-utils/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "safe-buffer": "~5.1.0" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "sprintf-js": "~1.0.2" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "dependencies": { + "dequal": "^2.0.3" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -6907,22 +6582,24 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "builtin-modules": "^3.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "engines": { "node": ">= 0.4" }, @@ -6930,24 +6607,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6956,50 +6636,36 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, - "bin": { - "is-docker": "cli.js" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7008,46 +6674,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "engines": { "node": ">= 0.4" }, @@ -7055,21 +6692,48 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, "engines": { - "node": ">=0.12.0" + "node": ">= 0.4" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7078,76 +6742,69 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "node_modules/assert-options": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.0.tgz", + "integrity": "sha512-qSELrEaEz4sGwTs4Qh+swQkjiHAysC4rot21+jzXU86dJzNG+FDqBzyS3ohSoTRf4ZLA3FSwxQdiuNl5NXUtvA==", "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "retry": "0.13.1" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 4.0.0" } }, - "node_modules/is-string": { + "node_modules/available-typed-arrays": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7156,130 +6813,140 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/aws-sdk": { + "version": "2.1640.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1640.0.tgz", + "integrity": "sha512-B4ipyAKMPjTMWyVG4wx57V9Ws9anAGTCtR6jTGfIA6wSjrMNeNVohwROe4E4CZDcNiWBPhZjNus/9uupdsW8vg==", + "hasInstallScript": true, "dependencies": { - "has-symbols": "^1.0.2" + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.6.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 10.0.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/aws-sdk/node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/axios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" + "dequal": "^2.0.3" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, + "dependencies": { + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, "peerDependencies": { - "ws": "*" + "@babel/core": "^7.8.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 10.13.0" + "node": ">=7.0.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -7288,447 +6955,440 @@ "node": ">=8" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8" } }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dev": true, + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, "engines": { - "node": ">= 0.6.0" + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=8" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "node_modules/json-cycle": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/json-cycle/-/json-cycle-1.3.0.tgz", - "integrity": "sha512-FD/SedD78LCdSvJaOUQAXseT8oQBb5z6IVYaQaCrVUlu9zOAr1BDdKyVYQaSD/GDsAMrXpKcOyBD4LIl8nfjHw==", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-refs": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/json-refs/-/json-refs-3.0.15.tgz", - "integrity": "sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw==", + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, "dependencies": { - "commander": "~4.1.1", - "graphlib": "^2.1.8", - "js-yaml": "^3.13.1", - "lodash": "^4.17.15", - "native-promise-only": "^0.8.1", - "path-loader": "^1.0.10", - "slash": "^3.0.0", - "uri-js": "^4.2.2" - }, - "bin": { - "json-refs": "bin/json-refs" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" }, - "engines": { - "node": ">=0.8" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, - "bin": { - "json5": "lib/cli.js" + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" }, - "engines": { - "node": ">=0.6.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/jsx-ast-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", - "integrity": "sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==", + "node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "object.assign": "^4.1.2" + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">=4.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/jszip": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", - "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", - "dev": true, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bare-addon-resolve": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.9.4.tgz", + "integrity": "sha512-unn6Vy/Yke6F99vg/7tcrvM2KUvIhTNniaSqDbam4AWkd4NhvDVSrQiRYVlNzUV2P7SPobkCK7JFVxrJk9btCg==", + "optional": true, "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" + "bare-module-resolve": "^1.10.0", + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } } }, - "node_modules/jwt-decode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", - "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=", - "dev": true - }, - "node_modules/kareem": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", - "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "hasInstallScript": true, + "node_modules/bare-module-resolve": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.10.2.tgz", + "integrity": "sha512-C9COe/GhWfVXKytW3DElTkiBU+Gb2OXeaVkdGdRB/lp26TVLESHkTGS876iceAGdvtPgohfp9nX8vXHGvN3++Q==", + "optional": true, "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" + "bare-semver": "^1.0.0" }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "optional": true, "engines": { - "node": ">=10.0.0" + "bare": ">=1.14.0" } }, - "node_modules/keccak/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "optional": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "bare-os": "^3.0.1" } }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "node_modules/bare-semver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.1.tgz", + "integrity": "sha512-UtggzHLiTrmFOC/ogQ+Hy7VfoKoIwrP1UFcYtTxoCUdLtsIErT8+SWtOC2DH/snT9h+xDrcBEPcwKei1mzemgg==", + "optional": true + }, + "node_modules/bare-url": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.1.6.tgz", + "integrity": "sha512-FgjDeR+/yDH34By4I0qB5NxAoWv7dOTYcOXwn73kr+c93HyC2lU6tnjifqUe33LKMJcDyCYPQjEAqgOQiXkE2Q==", + "optional": true, "dependencies": { - "json-buffer": "3.0.0" + "bare-path": "^3.0.0" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", - "dev": true, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "peer": true, "dependencies": { - "language-subtag-registry": "~0.3.2" + "safe-buffer": "^5.0.1" } }, - "node_modules/lazystream": { + "node_modules/base32.js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", + "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64-sol": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, + "resolved": "https://registry.npmjs.org/base64-sol/-/base64-sol-1.0.1.tgz", + "integrity": "sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==" + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dependencies": { - "readable-stream": "^2.0.5" + "safe-buffer": "5.1.2" }, "engines": { - "node": ">= 0.6.3" + "node": ">= 0.8" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "engines": { - "node": ">= 0.8.0" + "node": "*" } }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { - "node": ">=6.11.5" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "peer": true }, - "node_modules/lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "node_modules/log": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/log/-/log-6.3.1.tgz", - "integrity": "sha512-McG47rJEWOkXTDioZzQNydAVvZNeEkSyLJ1VWkFwfW+o1knW+QSi8D1KjPn/TnctV+q99lkvJNe1f0E1IjfY2A==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "duration": "^0.2.2", - "es5-ext": "^0.10.53", - "event-emitter": "^0.3.5", - "sprintf-kit": "^2.0.1", - "type": "^2.5.0", - "uni-global": "^1.0.0" - } + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, - "node_modules/log-node": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/log-node/-/log-node-8.0.3.tgz", - "integrity": "sha512-1UBwzgYiCIDFs8A0rM2QdBFo8Wd8UQ0HrSTu/MNI+/2zN3NoHRj2fhplurAyuxTYUXu3Oohugq1jAn5s05u1MQ==", - "dev": true, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { - "ansi-regex": "^5.0.1", - "cli-color": "^2.0.1", - "cli-sprintf-format": "^1.1.1", - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "sprintf-kit": "^2.0.1", - "supports-color": "^8.1.1", - "type": "^2.5.0" + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=10.0" - }, - "peerDependencies": { - "log": "^6.0.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/log-node/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/log-node/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { - "has-flag": "^4.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", "dev": true, + "optional": true + }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "peer": true, "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=10" @@ -7737,11 +7397,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { + "node_modules/boxen/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -7752,11 +7412,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-symbols/node_modules/chalk": { + "node_modules/boxen/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7768,11 +7428,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/log-symbols/node_modules/color-convert": { + "node_modules/boxen/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -7780,26 +7440,26 @@ "node": ">=7.0.0" } }, - "node_modules/log-symbols/node_modules/color-name": { + "node_modules/boxen/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "peer": true }, - "node_modules/log-symbols/node_modules/has-flag": { + "node_modules/boxen/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "peer": true, "engines": { "node": ">=8" } }, - "node_modules/log-symbols/node_modules/supports-color": { + "node_modules/boxen/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7807,2556 +7467,2382 @@ "node": ">=8" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "peer": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dev": true, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "es5-ext": "~0.10.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "semver": "^6.0.0" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "optional": true - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, - "node_modules/matcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "peer": true }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "peer": true, "dependencies": { - "hash-base": "^3.0.0", + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" + "safe-buffer": "^5.0.1" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "peer": true, + "dependencies": { + "base-x": "^3.0.2" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "peer": true, "dependencies": { - "dom-walk": "^0.1.0" + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "node-int64": "^0.4.0" } }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, "engines": { - "node": ">= 8" + "node": "*" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true }, - "node_modules/mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", - "dependencies": { - "mkdirp": "*" - }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", "engines": { "node": ">=4" } }, - "node_modules/mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "peer": true }, - "node_modules/mongodb": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", - "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", - "dependencies": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2" - }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, "engines": { - "node": ">=4" - }, - "optionalDependencies": { - "saslprep": "^1.0.0" + "node": ">=6" }, - "peerDependenciesMeta": { - "aws4": { - "optional": true - }, - "bson-ext": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "mongodb-extjson": { - "optional": true - }, - "snappy": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mongodb/node_modules/optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "dependencies": { - "require-at": "^1.0.6" - }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/mongoose": { - "version": "5.13.14", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.14.tgz", - "integrity": "sha512-j+BlQjjxgZg0iWn42kLeZTB91OejcxWpY2Z50bsZTiKJ7HHcEtcY21Godw496GMkBqJMTzmW7G/kZ04mW+Cb7Q==", - "dependencies": { - "@types/bson": "1.x || 4.0.x", - "@types/mongodb": "^3.5.27", - "bson": "^1.1.4", - "kareem": "2.3.2", - "mongodb": "3.7.3", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.8.4", - "mquery": "3.2.5", - "ms": "2.1.2", - "optional-require": "1.0.x", - "regexp-clone": "1.0.0", - "safe-buffer": "5.2.1", - "sift": "13.5.2", - "sliced": "1.0.1" + "node_modules/c32check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/c32check/-/c32check-2.0.0.tgz", + "integrity": "sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.2", + "base-x": "^4.0.0" }, "engines": { - "node": ">=4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", - "peerDependencies": { - "mongoose": "*" + "node": ">=8" } }, - "node_modules/mongoose/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/c32check/node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==", + "license": "MIT" }, - "node_modules/mpath": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz", - "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==", + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, "engines": { - "node": ">=4.0.0" + "node": ">=10.6.0" } }, - "node_modules/mquery": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", - "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, "dependencies": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" + "node": ">=8" } }, - "node_modules/mquery/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" } }, - "node_modules/multibase/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "varint": "^5.0.0" + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" } }, - "node_modules/multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/multihashes/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/caniuse-lite": { + "version": "1.0.30001633", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", + "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", + "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/ai" } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } + ] }, - "node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "deprecated": "This module has been superseded by the multiformats module", + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "node_modules/native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "node_modules/ncjsm": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.0.tgz", - "integrity": "sha512-oah6YGwb4Ern2alojiMFcjPhE4wvQBw1Ur/kUr2P0ovKdzaF5pCIsGjs0f2y+iZeej0/5Y6OOhQ8j30cTDMEGw==", + "node_modules/child-process-ext": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz", + "integrity": "sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA==", "dev": true, "dependencies": { - "builtin-modules": "^3.2.0", - "deferred": "^0.7.11", + "cross-spawn": "^6.0.5", "es5-ext": "^0.10.53", - "es6-set": "^0.1.5", - "ext": "^1.6.0", - "find-requires": "^1.0.0", - "fs2": "^0.3.9", - "type": "^2.5.0" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" + "log": "^6.0.0", + "split2": "^3.1.1", + "stream-promise": "^3.2.0" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "node_modules/child-process-ext/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "dependencies": { - "minimatch": "^3.0.2" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": ">= 0.10.5" + "node": ">=4.8" } }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, + "node_modules/child-process-ext/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">=4" } }, - "node_modules/node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "node_modules/child-process-ext/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "semver": "bin/semver" } }, - "node_modules/node-releases": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", - "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/child-process-ext/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "node_modules/child-process-ext/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, - "optional": true, - "dependencies": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/npm-registry-utilities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-registry-utilities/-/npm-registry-utilities-1.0.0.tgz", - "integrity": "sha512-9xYfSJy2IFQw1i6462EJzjChL9e65EfSo2Cw6kl0EFeDp05VvU+anrQk3Fc0d1MbVCq7rWIxeer89O9SUQ/uOg==", + "node_modules/child-process-ext/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, "dependencies": { - "ext": "^1.6.0", - "fs2": "^0.3.9", - "memoizee": "^0.4.15", - "node-fetch": "^2.6.7", - "semver": "^7.3.5", - "type": "^2.6.0", - "validate-npm-package-name": "^3.0.0" - }, - "engines": { - "node": ">=12.0" + "readable-stream": "^3.0.0" } }, - "node_modules/npm-registry-utilities/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/child-process-ext/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "isexe": "^2.0.0" }, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "which": "bin/which" } }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, "engines": { - "node": ">= 6" + "node": ">=6.0" } }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "peer": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "peer": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10" } }, - "node_modules/object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "restore-cursor": "^3.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/object.hasown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", - "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "node_modules/cli-progress-footer": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/cli-progress-footer/-/cli-progress-footer-2.3.3.tgz", + "integrity": "sha512-p+hyTPxSZWG1c3Qy1DLBoGZhpeA3Y6AMlKrtbGpMMSKpezbSLel8gW4e5You4FNlHb3wS/M1JU594OAWe/Totg==", "dev": true, "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "cli-color": "^2.0.4", + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "mute-stream": "0.0.8", + "process-utils": "^4.0.0", + "timers-ext": "^0.1.7", + "type": "^2.7.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10.0" } }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "dependencies": { - "http-https": "^1.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/cli-sprintf-format": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cli-sprintf-format/-/cli-sprintf-format-1.1.1.tgz", + "integrity": "sha512-BbEjY9BEdA6wagVwTqPvmAwGB24U93rQPBFZUT8lNCDxXzre5LFHQUTJc70czjgUomVg8u8R5kW8oY9DYRFNeg==", + "dev": true, "dependencies": { - "ee-first": "1.1.1" + "cli-color": "^2.0.1", + "es5-ext": "^0.10.53", + "sprintf-kit": "^2.0.1", + "supports-color": "^6.1.0" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" + "node": ">=6.0" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/cli-sprintf-format/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "has-flag": "^3.0.0" }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10" } }, - "node_modules/optional-require": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", - "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.8" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" + "mimic-response": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/ora/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/ora/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "color-name": "1.1.3" } }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 0.8" } }, - "node_modules/ora/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "peer": true + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">= 6" } }, - "node_modules/ora/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" }, "engines": { - "node": ">= 6" + "node": ">= 10" } }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { - "has-flag": "^4.0.0" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "engines": { - "node": ">=6" - } + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, - "node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^3.1.0" - }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "engines": { - "node": ">=4" - } + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "browserslist": "^4.23.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" }, "engines": { - "node": ">=4" + "node": ">=0.8" } }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "dependencies": { - "p-finally": "^1.0.0" + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">= 10" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "peer": true, "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "peer": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" } }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, "engines": { - "node": ">=4" + "node": ">= 8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/csv-writer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", + "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, "engines": { - "node": ">=8" + "node": ">=0.12" } }, - "node_modules/path-loader": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/path-loader/-/path-loader-1.0.10.tgz", - "integrity": "sha512-CMP0v6S6z8PHeJ6NFVyVJm6WyJjIwFvyz2b0n2/4bKdS/0uZa/9sKUlYZzubrn3zuDRU0zIuEDX9DZYQ2ZI8TA==", - "dev": true, - "dependencies": { - "native-promise-only": "^0.8.1", - "superagent": "^3.8.3" - } + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true }, - "node_modules/path-loader/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-loader/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">= 0.12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-loader/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, - "bin": { - "mime": "cli.js" + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/path-loader/node_modules/superagent": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", - "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", - "dev": true, + "node_modules/dataloader": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", + "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dependencies": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.3.5" + "@babel/runtime": "^7.21.0" }, "engines": { - "node": ">= 4.0" + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path2": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path2/-/path2-0.1.0.tgz", - "integrity": "sha1-Y5golCzb2kSkGkWwdK6Ic0g7Tvo=", - "dev": true + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=4" } }, - "node_modules/peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, "engines": { - "node": ">=8.6" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, - "optional": true, + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, "engines": { "node": ">=4" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "node_modules/decompress-tar/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/decompress-tar/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/decompress-tar/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/decompress-tar/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/decompress-tar/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "safe-buffer": "~5.1.0" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/decompress-tar/node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/decompress-tarbz2/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "dev": true, + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, "engines": { "node": ">=4" } }, - "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "node_modules/decompress-targz/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", "dev": true, "dependencies": { - "fast-diff": "^1.1.2" + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=4" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "dev": true, "engines": { - "node": ">= 0.6.0" + "node": ">=0.10.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/process-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/process-utils/-/process-utils-4.0.0.tgz", - "integrity": "sha512-fMyMQbKCxX51YxR7YGCzPjLsU3yDzXFkP4oi1/Mt5Ixnk7GO/7uUTj8mrCHUwuvozWzI+V7QSJR9cZYnwNOZPg==", + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", "dev": true, "dependencies": { - "ext": "^1.4.0", - "fs2": "^0.3.9", - "memoizee": "^0.4.14", - "type": "^2.1.0" + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" }, "engines": { - "node": ">=10.0" + "node": ">=0.10.0" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/promise-queue": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", - "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=", + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, - "optional": true - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "clone": "^1.0.2" }, - "engines": { - "node": ">= 0.10" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "node_modules/deferred": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/deferred/-/deferred-0.7.11.tgz", + "integrity": "sha512-8eluCl/Blx4YOGwMapBvXRKxHXhA8ejDXYzEaK8+/gtcm8hRMhSLmXSqDmNUKNc/C8HNSmuyyp/hflhqDAvK2A==", + "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "d": "^1.0.1", + "es5-ext": "^0.10.50", + "event-emitter": "^0.3.5", + "next-tick": "^1.0.0", + "timers-ext": "^0.1.7" } }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=0.6" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "engines": { - "node": ">=0.4.x" + "node": ">=0.10" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/randombytes": { + "node_modules/detect-node": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "optional": true }, - "node_modules/randomfill": { + "node_modules/dezalgo": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "asap": "^2.0.0", + "wrappy": "1" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=0.3.1" } }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, + "node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "engines": { - "node": ">= 0.8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "path-type": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "node": ">=8" } }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "readable-stream": "^3.6.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node": ">=6.0.0" } }, - "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=12" } }, - "node_modules/readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "node_modules/duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", "dev": true, "dependencies": { - "minimatch": "^3.0.4" + "d": "1", + "es5-ext": "~0.10.46" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron": { + "version": "31.0.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-31.0.1.tgz", + "integrity": "sha512-2eBcp4iqLkTsml6mMq+iqrS5u3kJ/2mpOLP7Mj7lo0uNK3OyfNqRS9z1ArsHjBF2/HV250Te/O9nKrwQRTX/+g==", "dev": true, + "hasInstallScript": true, "dependencies": { - "picomatch": "^2.2.1" + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" }, "engines": { - "node": ">=8.10.0" + "node": ">= 12.20.55" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "node_modules/electron-to-chromium": { + "version": "1.4.802", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", + "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==", "dev": true }, - "node_modules/regexp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, "engines": { - "node": ">= 0.12" + "node": ">= 4" } }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { - "node": ">=0.6" + "node": ">= 0.8" } }, - "node_modules/require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "engines": { - "node": ">=4" + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "devOptional": true, + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "once": "^1.4.0" } }, - "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "dependencies": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8.6" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dependencies": { - "lowercase-keys": "^1.0.0" + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/es-module-lexer": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "dev": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">= 0.4" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hasown": "^2.0.0" } }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "dependencies": { - "bn.js": "^5.2.0" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, - "bin": { - "rlp": "bin/rlp" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/rlp/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "dev": true, - "optional": true, + "hasInstallScript": true, "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" }, "engines": { - "node": ">=8.0" + "node": ">=0.10" } }, - "node_modules/roarr/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, "optional": true }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, - "engines": { - "node": ">=0.12.0" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/es6-set": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", + "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "queue-microtask": "^1.2.2" + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "es6-iterator": "~2.0.3", + "es6-symbol": "^3.1.3", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "queue-microtask": "^1.2.2" + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, - "node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, "dependencies": { - "tslib": "^2.1.0" + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "engines": { "node": ">=6" } }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", - "dev": true + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 8.9.0" + "node": "^10.12.0 || >=12.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/eslint" } }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "hasInstallScript": true, + "node_modules/eslint-config-airbnb": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", + "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", + "dev": true, "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "eslint-config-airbnb-base": "^14.2.1", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" }, "engines": { - "node": ">=10.0.0" + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" } }, - "node_modules/seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "node_modules/eslint-config-airbnb-base": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", "dev": true, "dependencies": { - "commander": "^2.8.1" + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" }, - "bin": { - "seek-bunzip": "bin/seek-bunzip", - "seek-table": "bin/seek-bzip-table" + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1" } }, - "node_modules/seek-bzip/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/eslint-config-prettier": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", "dev": true, "bin": { - "semver": "bin/semver.js" + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "optional": true - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, - "optional": true, "dependencies": { - "type-fest": "^0.13.1" + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8.10.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" } }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "randombytes": "^2.1.0" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" + "ms": "^2.1.1" } }, - "node_modules/serverless": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/serverless/-/serverless-3.17.0.tgz", - "integrity": "sha512-M3VJc8PW/elxCAU/vQeNYPdjp3m7Ms/WyE+A+s2TTJYOVBVUuQhX2s+4u6GulTkxeBF3s83EvX26eAJ4RdXCTQ==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "hasInstallScript": true, "dependencies": { - "@serverless/dashboard-plugin": "^6.2.2", - "@serverless/platform-client": "^4.3.2", - "@serverless/utils": "^6.3.0", - "ajv": "^8.11.0", - "ajv-formats": "^2.1.1", - "archiver": "^5.3.1", - "aws-sdk": "^2.1131.0", - "bluebird": "^3.7.2", - "cachedir": "^2.3.0", - "chalk": "^4.1.2", - "child-process-ext": "^2.1.1", - "ci-info": "^3.3.0", - "cli-progress-footer": "^2.3.1", - "d": "^1.0.1", - "dayjs": "^1.11.2", - "decompress": "^4.2.1", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "essentials": "^1.2.0", - "ext": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "filesize": "^8.0.7", - "fs-extra": "^9.1.0", - "get-stdin": "^8.0.0", - "globby": "^11.1.0", - "got": "^11.8.3", - "graceful-fs": "^4.2.10", - "https-proxy-agent": "^5.0.1", - "is-docker": "^2.2.1", - "js-yaml": "^4.1.0", - "json-cycle": "^1.3.0", - "json-refs": "^3.0.15", - "lodash": "^4.17.21", - "memoizee": "^0.4.15", - "micromatch": "^4.0.5", - "node-fetch": "^2.6.7", - "npm-registry-utilities": "^1.0.0", - "object-hash": "^2.2.0", - "open": "^7.4.2", - "path2": "^0.1.0", - "process-utils": "^4.0.0", - "promise-queue": "^2.2.5", - "require-from-string": "^2.0.2", - "semver": "^7.3.7", - "signal-exit": "^3.0.7", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "tar": "^6.1.11", - "timers-ext": "^0.1.7", - "type": "^2.6.0", - "untildify": "^4.0.0", - "uuid": "^8.3.2", - "yaml-ast-parser": "0.0.43" + "esutils": "^2.0.2" }, - "bin": { - "serverless": "bin/serverless.js", - "sls": "bin/serverless.js" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" }, "engines": { - "node": ">=12.0" + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/serverless-prune-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/serverless-prune-plugin/-/serverless-prune-plugin-2.0.1.tgz", - "integrity": "sha512-fWttDV5TD3K6g9NRDJUuA/cq0AzAI0ya1FZXQKtCnWFfaGP7CzZHZWzlvnNofqvKdpY8vXtaAiswc6gdHXaTUw==", + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", "dev": true, "dependencies": { - "bluebird": "^3.7.2" + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" }, "peerDependencies": { - "serverless": "1 || 2 || 3" + "eslint": ">=5.16.0" } }, - "node_modules/serverless-prune-plugin/node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "node_modules/serverless-webpack": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/serverless-webpack/-/serverless-webpack-5.7.1.tgz", - "integrity": "sha512-uyDtyLSR81lNDRWC8yU2hB9eNdfICJ9d5OnSuXCJ+UF5A+KhMkDa0oXVtyKfa5uT+kqCgF9kUW4GUJBav8vsKA==", + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", "dev": true, "dependencies": { - "archiver": "^5.3.1", - "bluebird": "^3.7.2", - "fs-extra": "^9.1.0", - "glob": "^7.2.0", - "is-builtin-module": "^3.1.0", - "lodash": "^4.17.21", - "semver": "^7.3.7" + "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": ">= 10.12.0" - }, - "optionalDependencies": { - "ts-node": ">= 8.3.0" + "node": ">=6.0.0" }, "peerDependencies": { - "serverless": "1 || 2 || 3", - "webpack": ">= 3.0.0 < 6" + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/serverless-webpack/node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/serverless-webpack/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/eslint-plugin-react": { + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11" + }, + "engines": { + "node": ">=4" }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "peer": true, "engines": { "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/serverless-webpack/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "esutils": "^2.0.2" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/serverless-webpack/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { - "semver": "bin/semver.js" + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/serverless-webpack/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">=4.0" } }, - "node_modules/serverless/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/serverless/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, "engines": { "node": ">=10" } }, - "node_modules/serverless/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@babel/highlight": "^7.10.4" } }, - "node_modules/serverless/node_modules/ansi-styles": { + "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -10371,53 +9857,89 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/serverless/node_modules/argparse": { + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "node_modules/serverless/node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/serverless/node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serverless/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/serverless/node_modules/chalk/node_modules/supports-color": { + "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -10429,2492 +9951,2758 @@ "node": ">=8" } }, - "node_modules/serverless/node_modules/color-convert": { + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esniff": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" }, "engines": { - "node": ">=7.0.0" + "node": ">=0.10" } }, - "node_modules/serverless/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/serverless/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "dependencies": { - "mimic-response": "^3.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/serverless/node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/serverless/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/serverless/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10" } }, - "node_modules/serverless/node_modules/got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" + "node": ">=4.0" } }, - "node_modules/serverless/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/essentials": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/essentials/-/essentials-1.2.0.tgz", + "integrity": "sha512-kP/j7Iw7KeNE8b/o7+tr9uX2s1wegElGOoGZ2Xm35qBr4BbbEcH3/bxR2nfH9l9JANCq9AUrvKw+gRuHtZp0HQ==", + "dev": true, + "dependencies": { + "uni-global": "^1.0.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/serverless/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" } }, - "node_modules/serverless/node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, - "node_modules/serverless/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "peer": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } }, - "node_modules/serverless/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "peer": true + }, + "node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "peer": true, "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" } }, - "node_modules/serverless/node_modules/keyv": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.8.tgz", - "integrity": "sha512-IZZo6krhHWPhgsP5mBkEdPopVPN/stgCnBVuqi6dda/Nm5mDTOSVTrFMkWqlJsDum+B0YSe887tNxdjDWkO7aQ==", - "dev": true, + "node_modules/ethereumjs-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "peer": true, "dependencies": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" + "@types/node": "*" } }, - "node_modules/serverless/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "peer": true + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "peer": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, "engines": { - "node": ">=8" + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" } }, - "node_modules/serverless/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/serverless/node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.4.x" } }, - "node_modules/serverless/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", "engines": { - "node": ">=8" + "node": ">=12.0.0" } }, - "node_modules/serverless/node_modules/responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "peer": true, "dependencies": { - "lowercase-keys": "^2.0.0" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/serverless/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/serverless/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/execa/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serverless/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/serverless/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "node": ">= 0.8.0" } }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": ">=6" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.10.0" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" + "ms": "2.0.0" } }, - "node_modules/shebang-command": { + "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" + "type": "^2.7.2" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "mime-db": "^1.28.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sift": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/simple-git": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.7.1.tgz", - "integrity": "sha512-+Osjtsumbtew2y9to0pOYjNzSIr4NkKGBg7Po5SUtjQhaJf2QBmiTX/9E9cv9rmc7oUiSGFIB9e7ys5ibnT9+A==", + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", "dev": true, "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.3" + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/steveukx/" - } - }, - "node_modules/simple-statistics": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/simple-statistics/-/simple-statistics-7.7.5.tgz", - "integrity": "sha512-CYq683Yg2mb7M4mklQ6FtxEdsYeziGa2giaLvqXobfK1qVqZDKd7BIqLnngnKQSw9GsfNinbiScbfjc3IRWdQA==", "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, + "node_modules/extract-files": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", + "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", "engines": { - "node": ">=8" + "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/jaydenseric" } }, - "node_modules/slice-ansi/node_modules/color-convert": { + "node_modules/extract-zip": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" }, "engines": { - "node": ">=7.0.0" + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { - "is-plain-obj": "^1.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "dev": true, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fast-xml-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "dependencies": { - "sort-keys": "^1.0.0" + "strnum": "^1.0.5" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "fxparser": "src/cli/cli.js" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 4.9.1" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "reusify": "^1.0.4" } }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, "dependencies": { - "memory-pager": "^1.0.2" + "bser": "2.1.1" } }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "dependencies": { - "readable-stream": "^3.0.0" + "pend": "~1.2.0" } }, - "node_modules/split2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/feaxios": { + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/feaxios/-/feaxios-0.0.23.tgz", + "integrity": "sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g==", + "dependencies": { + "is-retry-allowed": "^3.0.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": ">= 6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sprintf-kit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.1.tgz", - "integrity": "sha512-2PNlcs3j5JflQKcg4wpdqpZ+AjhQJ2OZEo34NXDtlB0tIPG84xaaXhpA8XFacFiwjKA4m49UOYG83y3hbMn/gQ==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "es5-ext": "^0.10.53" + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" + "node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "dev": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, - "node_modules/stream-promise": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz", - "integrity": "sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA==", + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, "dependencies": { - "2-thenable": "^1.0.0", - "es5-ext": "^0.10.49", - "is-stream": "^1.1.0" + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "node_modules/filesize": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.2.tgz", + "integrity": "sha512-Dx770ai81ohflojxhU+oG+Z2QGvKdYxgEr9OSA8UVrqhwNHjfH9A8f5NKfg83fEH8ZFA5N5llJo5T3PIoZ4CRA==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 10.4.0" } }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { - "safe-buffer": "~5.1.0" + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", - "dev": true, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", - "side-channel": "^1.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "2.0.0" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "node_modules/find-requires": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-requires/-/find-requires-1.0.0.tgz", + "integrity": "sha512-UME7hNwBfzeISSFQcBEDemEEskpOjI/shPrpJM5PI4DSdn6hX0dmz+2dL70blZER2z8tSnTRL+2rfzlYgtbBoQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es5-ext": "^0.10.49", + "esniff": "^1.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "find-requires": "bin/find-requires.js" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/find-requires/node_modules/esniff": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.3.tgz", + "integrity": "sha512-SLBLpfE7xWgF/HbzhVuAwqnJDRqSCNZqcqaIMVm+f+PbTp1kFRWu6BuT83SATb4Tp+ovr+S+u7vDH7/UErAOkw==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "d": "^1.0.1", + "es5-ext": "^0.10.62" }, "engines": { - "node": ">=8" + "node": ">=0.10" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "peer": true, + "dependencies": { + "locate-path": "^2.0.0" + }, "engines": { "node": ">=4" } }, - "node_modules/strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", "dev": true, "dependencies": { - "is-natural-number": "^4.0.1" + "micromatch": "^4.0.2" } }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, "dependencies": { - "is-hex-prefixed": "1.0.0" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": ">=8" + "node": ">=4.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" + "is-callable": "^1.1.3" } }, - "node_modules/strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "node_modules/foreground-child": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.0.tgz", + "integrity": "sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==", "dev": true, "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "debug": "^4.1.0" - }, "engines": { - "node": ">= 8.0" - } - }, - "node_modules/superagent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", - "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", - "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.1", - "fast-safe-stringify": "^2.0.7", - "form-data": "^3.0.0", - "formidable": "^1.2.2", - "methods": "^1.1.2", - "mime": "^2.4.6", - "qs": "^6.9.4", - "readable-stream": "^3.6.0", - "semver": "^7.3.2" + "node": ">=14" }, - "engines": { - "node": ">= 7.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/superagent/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, - "node_modules/superagent/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { - "node": ">=10" + "node": ">= 0.6" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "peer": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/supports-preserve-symlinks-flag": { + "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, - "engines": { - "node": ">= 0.4" + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6 <7 || >=8" } }, - "node_modules/swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/swarm-js/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/swarm-js/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/swarm-js/node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "node_modules/fs2": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/fs2/-/fs2-0.3.9.tgz", + "integrity": "sha512-WsOqncODWRlkjwll+73bAxVW3JPChDgaPX3DT4iTTm73UmG4VgALa7LaFblP232/DN60itkOrPZ8kaP1feksGQ==", + "dev": true, "dependencies": { - "minipass": "^2.6.0" + "d": "^1.0.1", + "deferred": "^0.7.11", + "es5-ext": "^0.10.53", + "event-emitter": "^0.3.5", + "ignore": "^5.1.8", + "memoizee": "^0.4.14", + "type": "^2.1.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/swarm-js/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "node_modules/fs2/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, "engines": { - "node": ">=4" + "node": ">= 4" } }, - "node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/swarm-js/node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/swarm-js/node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "dependencies": { - "minipass": "^2.9.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "engines": { - "node": ">=4" + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/swarm-js/node_modules/p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dependencies": { - "p-finally": "^1.0.0" - }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "engines": { - "node": ">=0.10.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/swarm-js/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/swarm-js/node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "engines": { - "node": ">=4.5" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/swarm-js/node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dependencies": { - "prepend-http": "^1.0.1" - }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/swarm-js/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "pump": "^3.0.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">= 10" + "node": ">= 6" } }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", "dev": true, + "optional": true, "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" }, "engines": { - "node": ">=6" + "node": ">=10.0" } }, - "node_modules/tar-stream/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/global-agent/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/tar-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "engines": { + "node": ">=4" } }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz", - "integrity": "sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA==", + "node_modules/globby/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dependencies": { - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map": "~0.8.0-beta.0", - "source-map-support": "~0.5.20" + "get-intrinsic": "^1.1.3" }, - "bin": { - "terser": "bin/terser" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", "dev": true, "dependencies": { - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "lodash": "^4.17.15" + } + }, + "node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-request": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", + "integrity": "sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==", + "dependencies": { + "cross-fetch": "^3.0.6", + "extract-files": "^9.0.0", + "form-data": "^3.0.0" + }, + "peerDependencies": { + "graphql": "14 - 16" + } + }, + "node_modules/graphql-request/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 6" + } + }, + "node_modules/hardhat": { + "version": "2.22.5", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.5.tgz", + "integrity": "sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw==", + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.4.0", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "bin": { + "hardhat": "internal/cli/bootstrap.js" }, "peerDependencies": { - "webpack": "^5.1.0" + "ts-node": "*", + "typescript": "*" }, "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { + "ts-node": { "optional": true }, - "uglify-js": { + "typescript": { "optional": true } } }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, + "node_modules/hardhat-watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hardhat-watcher/-/hardhat-watcher-2.5.0.tgz", + "integrity": "sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" + "chokidar": "^3.5.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "peerDependencies": { + "hardhat": "^2.0.0" } }, - "node_modules/terser/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "node_modules/hardhat/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dev": true, + "node_modules/hardhat/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "peer": true, "dependencies": { - "whatwg-url": "^7.0.0" + "path-parse": "^1.0.6" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/terser/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "node_modules/hardhat/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/terser/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, - "node_modules/terser/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dependencies": { - "os-tmpdir": "~1.0.2" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=0.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "peer": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, "engines": { "node": ">=4" } }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "engines": { - "node": ">=6" + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "is-number": "^7.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=8.0" + "node": ">= 0.4" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "peer": true, + "bin": { + "he": "bin/he" } }, - "node_modules/token-types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz", - "integrity": "sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==", - "dev": true, - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node": ">=16.0.0" } }, - "node_modules/token-types/node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "engines": { + "node": ">=8" + } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", "engines": { - "node": ">=0.8" + "node": ">=14" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, - "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "escape-string-regexp": "^1.0.2" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, - "optional": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } + "engines": { + "node": ">=10.19.0" } }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, - "optional": true, - "bin": { - "acorn": "bin/acorn" + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.4.0" + "node": ">= 6" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "engines": { + "node": ">=10.17.0" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "devOptional": true, "dependencies": { - "minimist": "^1.2.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, - "bin": { - "json5": "lib/cli.js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "optional": true, "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + "node": ">= 4" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true }, - "node_modules/type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==" + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "peer": true }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true, + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" } }, - "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", - "dev": true, - "optional": true, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, "engines": { - "node": ">=4.2.0" + "node": ">=8" } }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", "dev": true, "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" } }, - "node_modules/unbzip2-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/uni-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz", - "integrity": "sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw==", + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "type": "^2.5.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">= 0.8" + "node": ">=7.0.0" } }, - "node_modules/untildify": { + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/inquirer/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/inquirer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "punycode": "^2.1.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, "dependencies": { - "prepend-http": "^2.0.0" + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "engines": { - "node": ">= 4" + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "peer": true, + "dependencies": { + "fp-ts": "^1.0.0" } }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - }, - "node_modules/utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "hasInstallScript": true, + "node_modules/ioredis": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", + "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", "dependencies": { - "node-gyp-build": "^4.3.0" + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">=6.14.2" + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">= 0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, - "optional": true + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { - "builtins": "^1.0.3" + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/vary": { + "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "hasown": "^2.0.0" }, - "engines": { - "node": ">=10.13.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wcwidth": { + "node_modules/is-data-view": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, "dependencies": { - "defaults": "^1.0.3" + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.3.tgz", - "integrity": "sha512-UgBvQnKIXncGYzsiGacaiHtm0xzQ/JtGqcSO/ddzQHYxnNuwI72j1Pb4gskztLYihizV9qPNQYHMSCiBlStI9A==", - "hasInstallScript": true, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "dependencies": { - "web3-bzz": "1.7.3", - "web3-core": "1.7.3", - "web3-eth": "1.7.3", - "web3-eth-personal": "1.7.3", - "web3-net": "1.7.3", - "web3-shh": "1.7.3", - "web3-utils": "1.7.3" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-bzz": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.3.tgz", - "integrity": "sha512-y2i2IW0MfSqFc1JBhBSQ59Ts9xE30hhxSmLS13jLKWzie24/An5dnoGarp2rFAy20tevJu1zJVPYrEl14jiL5w==", - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/web3-core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.3.tgz", - "integrity": "sha512-4RNxueGyevD1XSjdHE57vz/YWRHybpcd3wfQS33fgMyHZBVLFDNwhn+4dX4BeofVlK/9/cmPAokLfBUStZMLdw==", + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-requestmanager": "1.7.3", - "web3-utils": "1.7.3" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-helpers": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.3.tgz", - "integrity": "sha512-qS2t6UKLhRV/6C7OFHtMeoHphkcA+CKUr2vfpxy4hubs3+Nj28K9pgiqFuvZiXmtEEwIAE2A28GBOC3RdcSuFg==", - "dependencies": { - "web3-eth-iban": "1.7.3", - "web3-utils": "1.7.3" - }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=6" } }, - "node_modules/web3-core-method": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.3.tgz", - "integrity": "sha512-SeF8YL/NVFbj/ddwLhJeS0io8y7wXaPYA2AVT0h2C2ESYkpvOtQmyw2Bc3aXxBmBErKcbOJjE2ABOKdUmLSmMA==", + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-utils": "1.7.3" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-core-promievent": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.3.tgz", - "integrity": "sha512-+mcfNJLP8h2JqcL/UdMGdRVfTdm+bsoLzAFtLpazE4u9kU7yJUgMMAqnK59fKD3Zpke3DjaUJKwz1TyiGM5wig==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { - "eventemitter3": "4.0.4" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.3.tgz", - "integrity": "sha512-bC+jeOjPbagZi2IuL1J5d44f3zfPcgX+GWYUpE9vicNkPUxFBWRG+olhMo7L+BIcD57cTmukDlnz+1xBULAjFg==", - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.3", - "web3-providers-http": "1.7.3", - "web3-providers-ipc": "1.7.3", - "web3-providers-ws": "1.7.3" - }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "peer": true, "engines": { - "node": ">=8.0.0" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.3.tgz", - "integrity": "sha512-/i1ZCLW3SDxEs5mu7HW8KL4Vq7x4/fDXY+yf/vPoDljlpvcLEOnI8y9r7om+0kYwvuTlM6DUHHafvW0221TyRQ==", - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.3" - }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "dev": true }, - "node_modules/web3-eth": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.3.tgz", - "integrity": "sha512-BCIRMPwaMlTCbswXyGT6jj9chCh9RirbDFkPtvqozfQ73HGW7kP78TXXf9+Xdo1GjutQfxi/fQ9yPdxtDJEpDA==", - "dependencies": { - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-eth-accounts": "1.7.3", - "web3-eth-contract": "1.7.3", - "web3-eth-ens": "1.7.3", - "web3-eth-iban": "1.7.3", - "web3-eth-personal": "1.7.3", - "web3-net": "1.7.3", - "web3-utils": "1.7.3" + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { - "node": ">=8.0.0" + "node": ">=0.12.0" } }, - "node_modules/web3-eth-abi": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.3.tgz", - "integrity": "sha512-ZlD8DrJro0ocnbZViZpAoMX44x5aYAb73u2tMq557rMmpiluZNnhcCYF/NnVMy6UIkn7SF/qEA45GXA1ne6Tnw==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.3" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/web3-eth-accounts": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.3.tgz", - "integrity": "sha512-aDaWjW1oJeh0LeSGRVyEBiTe/UD2/cMY4dD6pQYa8dOhwgMtNQjxIQ7kacBBXe7ZKhjbIFZDhvXN4mjXZ82R2Q==", - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-utils": "1.7.3" + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "node_modules/is-retry-allowed": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-3.0.0.tgz", + "integrity": "sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-eth-contract": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.3.tgz", - "integrity": "sha512-7mjkLxCNMWlQrlfM/MmNnlKRHwFk5XrZcbndoMt3KejcqDP6dPHi2PZLutEcw07n/Sk8OMpSamyF3QiGfmyRxw==", - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-utils": "1.7.3" - }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-eth-ens": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.3.tgz", - "integrity": "sha512-q7+hFGHIc0mBI3LwgRVcLCQmp6GItsWgUtEZ5bjwdjOnJdbjYddm7PO9RDcTDQ6LIr7hqYaY4WTRnDHZ6BEt5Q==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-eth-contract": "1.7.3", - "web3-utils": "1.7.3" + "call-bind": "^1.0.7" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-eth-iban": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.3.tgz", - "integrity": "sha512-1GPVWgajwhh7g53mmYDD1YxcftQniIixMiRfOqlnA1w0mFGrTbCoPeVaSQ3XtSf+rYehNJIZAUeDBnONVjXXmg==", - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.3" - }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-eth-personal": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.3.tgz", - "integrity": "sha512-iTLz2OYzEsJj2qGE4iXC1Gw+KZN924fTAl0ESBFs2VmRhvVaM7GFqZz/wx7/XESl3GVxGxlRje3gNK0oGIoYYQ==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-net": "1.7.3", - "web3-utils": "1.7.3" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" - }, - "node_modules/web3-net": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.3.tgz", - "integrity": "sha512-zAByK0Qrr71k9XW0Adtn+EOuhS9bt77vhBO6epAeQ2/VKl8rCGLAwrl3GbeEl7kWa8s/su72cjI5OetG7cYR0g==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { - "web3-core": "1.7.3", - "web3-core-method": "1.7.3", - "web3-utils": "1.7.3" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-providers-http": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.3.tgz", - "integrity": "sha512-TQJfMsDQ5Uq9zGMYlu7azx1L7EvxW+Llks3MaWn3cazzr5tnrDbGh6V17x6LN4t8tFDHWx0rYKr3mDPqyTjOZw==", + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dependencies": { - "web3-core-helpers": "1.7.3", - "xhr2-cookies": "1.1.0" + "which-typed-array": "^1.1.14" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-providers-ipc": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.3.tgz", - "integrity": "sha512-Z4EGdLKzz6I1Bw+VcSyqVN4EJiT2uAro48Am1eRvxUi4vktGoZtge1ixiyfrRIVb6nPe7KnTFl30eQBtMqS0zA==", - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.3" + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-providers-ws": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.3.tgz", - "integrity": "sha512-PpykGbkkkKtxPgv7U4ny4UhnkqSZDfLgBEvFTXuXLAngbX/qdgfYkhIuz3MiGplfL7Yh93SQw3xDjImXmn2Rgw==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.3", - "websocket": "^1.0.32" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-shh": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.3.tgz", - "integrity": "sha512-bQTSKkyG7GkuULdZInJ0osHjnmkHij9tAySibpev1XjYdjLiQnd0J9YGF4HjvxoG3glNROpuCyTaRLrsLwaZuw==", - "hasInstallScript": true, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, "dependencies": { - "web3-core": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-net": "1.7.3" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">=8.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web3-utils": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", - "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, "dependencies": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "is-docker": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "node_modules/webpack": { - "version": "5.72.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", - "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", - "dev": true, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.3", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true, + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" } }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=8" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "peerDependencies": { - "acorn": "^8" + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/webpack/node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=0.8.x" + "node": ">=8" } }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "semver": "^7.5.3" }, "engines": { - "node": ">= 10.13.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dependencies": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node": ">=10" } }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "execa": "^5.0.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { + "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -12929,7 +12717,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -12941,10200 +12745,8941 @@ "node": ">=7.0.0" } }, - "node_modules/wrap-ansi/node_modules/color-name": { + "node_modules/jest-circus/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "has-flag": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">=8" } }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=8.3.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { + "node-notifier": { "optional": true } } }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "cookiejar": "^2.1.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=4.0" + "node": ">=7.0.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">=0.10.32" + "node": ">=8" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml-ast-parser": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", - "dev": true - }, - "node_modules/yamljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", - "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "glob": "^7.0.5" + "has-flag": "^4.0.0" }, - "bin": { - "json2yaml": "bin/json2yaml", - "yaml2json": "bin/yaml2json" + "engines": { + "node": ">=8" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "node_modules/jest-config": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "optional": true, + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=6" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", - "readable-stream": "^3.6.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/zip-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + }, + "node_modules/jest-config/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" } }, - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "@babel/core": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.10.tgz", - "integrity": "sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.10", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.9", - "@babel/parser": "^7.17.10", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.10", - "@babel/types": "^7.17.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.10.tgz", - "integrity": "sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==", + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "@babel/types": "^7.17.10", - "@jridgewell/gen-mapping": "^0.1.0", - "jsesc": "^2.5.1" + "engines": { + "node": ">=8" } }, - "@babel/helper-compilation-targets": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", - "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", - "semver": "^6.3.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", - "dev": true, - "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" - } + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", - "dev": true, - "requires": { - "@babel/types": "^7.17.0" + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" } }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true - }, - "@babel/helpers": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", - "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "node_modules/jest-docblock": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.9", - "@babel/types": "^7.17.0" + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@babel/highlight": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", - "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "node_modules/jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "dependencies": { + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@babel/parser": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", - "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==", - "dev": true - }, - "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@babel/runtime-corejs3": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", - "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@babel/traverse": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.10.tgz", - "integrity": "sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.10", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.10", - "@babel/types": "^7.17.10", - "debug": "^4.1.0", - "globals": "^11.1.0" - } + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "@babel/types": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", - "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" + "engines": { + "node": ">=8" } }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "optional": true + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "node_modules/jest-environment-node": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, - "optional": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@defillama/sdk": { - "version": "2.3.63", - "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-2.3.63.tgz", - "integrity": "sha512-vTWW0HOdwDOIaGA8racqeFKGYs9vc2aUb5NFMgNMV/LBbW46GUGEVSZ0rUaI9AhTevxF4oLwEXHOtd2mOs2Rig==", - "requires": { - "@supercharge/promise-pool": "^2.1.0", - "ethers": "^5.4.5", - "graphql": "^15.5.0", - "graphql-request": "^3.4.0", - "node-fetch": "^2.6.1" + "node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@electron/get": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", - "integrity": "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==", + "node_modules/jest-haste-map": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1", - "got": "^9.6.0", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" + "dependencies": { + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "node_modules/jest-leak-detector": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, "dependencies": { - "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, - "@ethereumjs/common": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.4.tgz", - "integrity": "sha512-RDJh/R/EAr+B7ZRg5LfJ0BIpf/1LydFgYdvZEuTraojCbVypO2sQ+QnpP5u2wJf9DASyooKqu8O4FJEWUV6NXw==", - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" - } - }, - "@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", - "requires": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" - } - }, - "@ethersproject/abi": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.2.tgz", - "integrity": "sha512-40Ixjhy+YzFtnvzIqFU13FW9hd1gMoLa3cJfSDnfnL4o8EnEG1qLiV8sNJo3sHYi9UYMfFeRuZ7kv5+vhzU7gQ==", - "requires": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.1.tgz", - "integrity": "sha512-xhSLo6y0nGJS7NxfvOSzCaWKvWb1TLT7dQ0nnpHZrDnC67xfnWm9NXflTMFPUXXMtjr33CdV0kWDEmnbrQZ74Q==", - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" - } - }, - "@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" - } - }, - "@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", - "requires": { - "@ethersproject/bytes": "^5.6.0" - } - }, - "@ethersproject/basex": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.0.tgz", - "integrity": "sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/properties": "^5.6.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.1.tgz", - "integrity": "sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", - "requires": { - "@ethersproject/bignumber": "^5.6.0" - } - }, - "@ethersproject/contracts": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.1.tgz", - "integrity": "sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==", - "requires": { - "@ethersproject/abi": "^5.6.0", - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0" - } - }, - "@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", - "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.1.tgz", - "integrity": "sha512-6IuYDmbH5Bv/WH/A2cUd0FjNr4qTLAvyHAECiFZhNZp69pPvU7qIDwJ7CU7VAkwm4IVBzqdYy9mpMAGhQdwCDA==", - "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz", - "integrity": "sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ==", - "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" - }, - "@ethersproject/networks": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.2.tgz", - "integrity": "sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==", - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz", - "integrity": "sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/sha2": "^5.6.0" - } - }, - "@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/providers": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.6.tgz", - "integrity": "sha512-6X6agj3NeQ4tgnvBMCjHK+CjQbz+Qmn20JTxCYZ/uymrgCEOpJtY9zeRxJIDsSi0DPw8xNAxypj95JMCsapUfA==", - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/basex": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "@ethersproject/random": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.0.tgz", - "integrity": "sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0" + "node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@ethersproject/sha2": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", - "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "hash.js": "1.1.7" + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@ethersproject/signing-key": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.1.tgz", - "integrity": "sha512-XvqQ20DH0D+bS3qlrrgh+axRMth5kD1xuvqUQUTeezxUTXBOeR6hWz2/C6FBEu39FRytyybIWrYf7YLSAKr1LQ==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@ethersproject/solidity": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.0.tgz", - "integrity": "sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", - "requires": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" - } - }, - "@ethersproject/units": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.0.tgz", - "integrity": "sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw==", - "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/wallet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.1.tgz", - "integrity": "sha512-oXWoOslEWtwZiViIMlGVjeKDQz/tI7JF9UkyzN9jaGj8z7sXt2SyFMb0Ev6vSAqjIzrCrNrJ/+MkAhtKnGOfZw==", - "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/hdnode": "^5.6.0", - "@ethersproject/json-wallets": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/wordlists": "^5.6.0" - } - }, - "@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", - "requires": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.0.tgz", - "integrity": "sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q==", - "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/hash": "^5.6.0", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" } }, - "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", - "dev": true + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, - "requires": { - "debug": "^4.1.1" + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" } }, - "@serverless/dashboard-plugin": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@serverless/dashboard-plugin/-/dashboard-plugin-6.2.2.tgz", - "integrity": "sha512-h3zOprpuWZCdAP7qoOKT2nboB+AaxMkGoSzOD0jIBpt9s0cXqLE2VFjR2vKn8Cvam47Qa3XYnT2/XN6tR6rZgQ==", - "dev": true, - "requires": { - "@serverless/event-mocks": "^1.1.1", - "@serverless/platform-client": "^4.3.2", - "@serverless/utils": "^6.0.3", - "child-process-ext": "^2.1.1", - "chokidar": "^3.5.3", - "flat": "^5.0.2", - "fs-extra": "^9.1.0", - "js-yaml": "^4.1.0", - "jszip": "^3.9.1", - "lodash": "^4.17.21", - "memoizee": "^0.4.15", - "ncjsm": "^4.3.0", - "node-dir": "^0.1.17", - "node-fetch": "^2.6.7", - "open": "^7.4.2", - "semver": "^7.3.7", - "simple-git": "^3.7.0", - "type": "^2.6.0", - "uuid": "^8.3.2", - "yamljs": "^0.3.0" - }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } - } - }, - "@serverless/event-mocks": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@serverless/event-mocks/-/event-mocks-1.1.1.tgz", - "integrity": "sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A==", - "dev": true, - "requires": { - "@types/lodash": "^4.14.123", - "lodash": "^4.17.11" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@serverless/platform-client": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@serverless/platform-client/-/platform-client-4.3.2.tgz", - "integrity": "sha512-DAa5Z0JAZc6UfrTZLYwqoZxgAponZpFwaqd7WzzMA+loMCkYWyJNwxrAmV6cr2UUJpkko4toPZuJ3vM9Ie+NDA==", + "node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, - "requires": { - "adm-zip": "^0.5.5", - "archiver": "^5.3.0", - "axios": "^0.21.1", - "fast-glob": "^3.2.7", - "https-proxy-agent": "^5.0.0", - "ignore": "^5.1.8", - "isomorphic-ws": "^4.0.1", - "js-yaml": "^3.14.1", - "jwt-decode": "^2.2.0", - "minimatch": "^3.0.4", - "querystring": "^0.2.1", - "run-parallel-limit": "^1.1.0", - "throat": "^5.0.0", - "traverse": "^0.6.6", - "ws": "^7.5.3" - }, "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "dev": true - }, - "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, - "requires": {} - } + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@serverless/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@serverless/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-N93Vd55docYMg2d8Gqb4/MagG4GDOStpUsWZak4QpBenkzE3Q+MK7TkeNCeBpmK+PzRiL6/4K6p81QPvZel+Pw==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "requires": { - "archive-type": "^4.0.0", - "chalk": "^4.1.2", - "ci-info": "^3.3.0", - "cli-progress-footer": "^2.3.1", - "content-disposition": "^0.5.4", - "d": "^1.0.1", - "decompress": "^4.2.1", - "event-emitter": "^0.3.5", - "ext": "^1.6.0", - "ext-name": "^5.0.0", - "file-type": "^16.5.3", - "filenamify": "^4.3.0", - "get-stream": "^6.0.1", - "got": "^11.8.3", - "inquirer": "^8.2.4", - "js-yaml": "^4.1.0", - "jwt-decode": "^3.1.2", - "lodash": "^4.17.21", - "log": "^6.3.1", - "log-node": "^8.0.3", - "make-dir": "^3.1.0", - "memoizee": "^0.4.15", - "ncjsm": "^4.3.0", - "node-fetch": "^2.6.7", - "open": "^7.4.2", - "p-event": "^4.2.0", - "supports-color": "^8.1.1", - "timers-ext": "^0.1.7", - "type": "^2.6.0", - "uni-global": "^1.0.0", - "uuid": "^8.3.2", - "write-file-atomic": "^4.0.1" + "engines": { + "node": ">=6" }, - "dependencies": { - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "jwt-decode": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", - "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", - "dev": true - }, - "keyv": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.8.tgz", - "integrity": "sha512-IZZo6krhHWPhgsP5mBkEdPopVPN/stgCnBVuqi6dda/Nm5mDTOSVTrFMkWqlJsDum+B0YSe887tNxdjDWkO7aQ==", - "dev": true, - "requires": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true } } }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - }, - "@supercharge/promise-pool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-2.1.0.tgz", - "integrity": "sha512-YEKOfn4xF+DQ61UY5NwHNtr8hYjwchXjGTocVJDAHLQceIRZF8VECH7gumFbp+aGTfygPbMbEtBumXJ/mcJz+w==" - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" + "node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true + "node_modules/jest-resolve": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "node_modules/jest-resolve-dependencies": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "dev": true, - "optional": true + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "optional": true + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "@types/bson": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", - "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", - "requires": { - "@types/node": "*" + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "node_modules/jest-runner": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "@types/responselike": "*" + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==", - "dev": true + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "node_modules/jest-runtime": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", "dev": true, - "requires": { - "@types/node": "*" + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@types/lodash": { - "version": "4.14.182", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", - "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", - "dev": true + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", - "requires": { - "@types/bson": "*", - "@types/node": "*" + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@types/node": { - "version": "14.18.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", - "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==" + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "@types/node": "*" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" + "node_modules/jest-snapshot": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "engines": { + "node": ">=8" } }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "@xtuc/long": "4.2.2" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" } }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } }, - "2-thenable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/2-thenable/-/2-thenable-1.0.0.tgz", - "integrity": "sha512-HqiDzaLDFCXkcCO/SwoyhRwqYtINFHF7t9BDRq4x90TOKNAJpiqUt9X5lQ08bwxYzc067HUywDjGySpebHcUpw==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.47" + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "node_modules/jest-validate": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": {} + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "adm-zip": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", - "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "debug": "4" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "ajv": "^8.0.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "ansi-colors": { + "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.2.tgz", - "integrity": "sha512-cEG18jjLG0O74o/33eEfnmtXYDEY196ZjL0eQEISULF+Imi7vr25l6ntGYmqS5lIrQIEeze+CqUtPVItywE7ZQ==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "color-convert": "^1.9.0" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "archive-type": { + "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "file-type": "^4.2.0" - }, - "dependencies": { - "file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", - "dev": true - } + "engines": { + "node": ">=8" } }, - "archiver": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^3.2.3", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "optional": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "engines": { + "node": ">=8" } }, - "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, - "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, - "array.prototype.flatmap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", - "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "requires": { - "safer-buffer": "~2.1.0" - } + "node_modules/jsbi": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", + "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" } }, - "assert-plus": { + "node_modules/json-bigint": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } }, - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + "node_modules/json-colorizer": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-2.2.2.tgz", + "integrity": "sha512-56oZtwV1piXrQnRNTtJeqRv+B9Y/dXAYLqBBaYl/COcUdoZxgLBLAO88+CnkbT6MxNs0c5E9mPBIb2sFcNz3vw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "lodash.get": "^4.4.2" + } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "node_modules/json-cycle": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/json-cycle/-/json-cycle-1.5.0.tgz", + "integrity": "sha512-GOehvd5PO2FeZ5T4c+RxobeT5a1PiGpF4u9/3+UvrMU4bhnVqzJY7hm39wg8PDCqkU91fWGH8qjWR4bn+wgq9w==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sdk": { - "version": "2.1135.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1135.0.tgz", - "integrity": "sha512-bl9n4QgrEh52hmQ+Jo76BgJXM/p+PwfVZvImEQHFeel/33H/PDLcTJquEw5bzxM1HRNI24iH+FNPwyWLMrttTw==", + "node_modules/json-refs": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/json-refs/-/json-refs-3.0.15.tgz", + "integrity": "sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw==", "dev": true, - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.3.2", - "xml2js": "0.4.19" + "dependencies": { + "commander": "~4.1.1", + "graphlib": "^2.1.8", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "native-promise-only": "^0.8.1", + "path-loader": "^1.0.10", + "slash": "^3.0.0", + "uri-js": "^4.2.2" + }, + "bin": { + "json-refs": "bin/json-refs" + }, + "engines": { + "node": ">=0.8" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "axe-core": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", - "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", - "dev": true + "optional": true }, - "babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "requires": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "requires": { - "tweetnacl": "^0.14.3" + "node_modules/jssha": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", + "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": "*" } }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "node_modules/just-performance": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", + "integrity": "sha512-L7RjvtJsL0QO8xFs5wEoDDzzJwoiowRw6Rn/GnvldlchS2JQr9wFYPiwZcDfrbbujEKqKN0tvENdbjXdYhDp5Q==" }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "node_modules/jwt-decode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", + "integrity": "sha512-86GgN2vzfUu7m9Wcj63iUkuDzFNYFVmjeDm2GzWpUk+opB0pEpMsw6ePCMrhYkumz2C1ihqtZzOMAg7FiXcNoQ==", + "dev": true }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "peer": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "optional": true + "dependencies": { + "json-buffer": "3.0.1" + } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "engines": { + "node": ">=6" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + "node_modules/lambert-w-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lambert-w-function/-/lambert-w-function-3.0.0.tgz", + "integrity": "sha512-yLAtG8+uM7FrLJR9WN37Fol9uURNW2OUR8PSbVp4kXjTmHMu7TqQgvdTceuUlVOR00qh8Skl2J2KeqCSfgzFyQ==" }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" } }, - "browserify-cipher": { + "node_modules/lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" } }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } + "safe-buffer": "~5.1.0" } }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", - "escalade": "^3.1.1", - "node-releases": "^2.0.3", - "picocolors": "^1.0.0" + "dependencies": { + "immediate": "~3.0.5" } }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "requires": { - "base-x": "^3.0.2" + "node_modules/limiter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-2.1.0.tgz", + "integrity": "sha512-361TYz6iay6n+9KvUUImqdLuFigK+K79qrUtBsXhJTLdH4rIt/r1y8r1iozwh8KbZNpujbFTSh74mJ7bwbAMOw==", + "dependencies": { + "just-performance": "4.3.0" } }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" } }, - "bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "peer": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" }, - "bufferutil": { + "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, + "node_modules/log": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/log/-/log-6.3.1.tgz", + "integrity": "sha512-McG47rJEWOkXTDioZzQNydAVvZNeEkSyLJ1VWkFwfW+o1knW+QSi8D1KjPn/TnctV+q99lkvJNe1f0E1IjfY2A==", + "dev": true, "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } + "d": "^1.0.1", + "duration": "^0.2.2", + "es5-ext": "^0.10.53", + "event-emitter": "^0.3.5", + "sprintf-kit": "^2.0.1", + "type": "^2.5.0", + "uni-global": "^1.0.0" } }, - "cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "node_modules/log-node": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/log-node/-/log-node-8.0.3.tgz", + "integrity": "sha512-1UBwzgYiCIDFs8A0rM2QdBFo8Wd8UQ0HrSTu/MNI+/2zN3NoHRj2fhplurAyuxTYUXu3Oohugq1jAn5s05u1MQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "cli-color": "^2.0.1", + "cli-sprintf-format": "^1.1.1", + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "sprintf-kit": "^2.0.1", + "supports-color": "^8.1.1", + "type": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "log": "^6.0.0" } }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001341", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", - "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "node_modules/log-node/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/log-node/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "child-process-ext": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/child-process-ext/-/child-process-ext-2.1.1.tgz", - "integrity": "sha512-0UQ55f51JBkOFa+fvR76ywRzxiPwQS3Xe8oe5bZRphpv+dIMeerW5Zn5e4cUy4COJwVtJyU0R79RMnw+aCqmGA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.5", - "es5-ext": "^0.10.53", - "log": "^6.0.0", - "split2": "^3.1.1", - "stream-promise": "^3.2.0" + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "chownr": { + "node_modules/lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", - "dev": true - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "peer": true }, - "cli-color": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.2.tgz", - "integrity": "sha512-g4JYjrTW9MGtCziFNjkqp3IMpGhnJyeB0lOtRPjQkYhXzKYr6tYnXKyEVnMzITxhpbahsEW9KsxOYIDKwcsIBw==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.59", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" + "dependencies": { + "yallist": "^3.0.2" } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "dev": true, - "requires": { - "restore-cursor": "^3.1.0" + "dependencies": { + "es5-ext": "~0.10.2" } }, - "cli-progress-footer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/cli-progress-footer/-/cli-progress-footer-2.3.1.tgz", - "integrity": "sha512-urD1hiEIQeZadVABtW5ExM8wse1phnmz15oJ4QEe46GQN87v1VBa0lZQ7gXkPELMzP6At4VY6v07baAiyztulw==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "requires": { - "cli-color": "^2.0.2", - "d": "^1.0.1", - "es5-ext": "^0.10.59", - "mute-stream": "0.0.8", - "process-utils": "^4.0.0", - "timers-ext": "^0.1.7", - "type": "^2.6.0" + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true }, - "cli-sprintf-format": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-sprintf-format/-/cli-sprintf-format-1.1.1.tgz", - "integrity": "sha512-BbEjY9BEdA6wagVwTqPvmAwGB24U93rQPBFZUT8lNCDxXzre5LFHQUTJc70czjgUomVg8u8R5kW8oY9DYRFNeg==", + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "requires": { - "cli-color": "^2.0.1", - "es5-ext": "^0.10.53", - "sprintf-kit": "^2.0.1", - "supports-color": "^6.1.0" - }, "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "tmpl": "1.0.5" } }, - "cli-width": { + "node_modules/matcher": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/matcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "requires": { - "color-name": "1.1.3" + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "peer": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" } }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dev": true, + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "peer": true, + "engines": { + "node": ">= 0.10.0" + } }, - "commondir": { + "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, - "compress-brotli": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", - "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "requires": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" - }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dependencies": { - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - } + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "engines": { + "node": ">=4" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "engines": { + "node": ">=6" } }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true, - "optional": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "engines": { + "node": ">=4" } }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "requires": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">=8" } }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" - }, - "core-js-pure": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.5.tgz", - "integrity": "sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" } }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" - }, - "crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "requires": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "peer": true, + "dependencies": { + "obliterator": "^2.0.0" } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true - }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "requires": { - "node-fetch": "2.6.7" + "node_modules/mocha": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", + "peer": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "8.1.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "peer": true, + "engines": { + "node": ">=6" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "peer": true }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "peer": true, "dependencies": { - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - } + "balanced-match": "^1.0.0" } }, - "damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==" - }, - "dayjs": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz", - "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw==", - "dev": true + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } }, - "debug": { + "node_modules/mocha/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { + "peer": true, + "dependencies": { "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "peer": true }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "dev": true, - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "peer": true, + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "peer": true, "dependencies": { - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" } }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "peer": true, "dependencies": { - "bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - } - } + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "peer": true, "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true - } + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "peer": true, "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - } + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "dev": true, - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "peer": true, "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "peer": true, + "engines": { + "node": ">=8" } }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, - "deferred": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/deferred/-/deferred-0.7.11.tgz", - "integrity": "sha512-8eluCl/Blx4YOGwMapBvXRKxHXhA8ejDXYzEaK8+/gtcm8hRMhSLmXSqDmNUKNc/C8HNSmuyyp/hflhqDAvK2A==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.50", - "event-emitter": "^0.3.5", - "next-tick": "^1.0.0", - "timers-ext": "^0.1.7" + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "peer": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } }, - "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } }, - "depd": { + "node_modules/morgan/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true + "node_modules/native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", + "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/ncjsm": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.2.tgz", + "integrity": "sha512-6d1VWA7FY31CpI4Ki97Fpm36jfURkVbpktizp8aoVViTZRQgr/0ddmlKerALSSlzfwQRBeSq1qwwVcBJK4Sk7Q==", "dev": true, - "requires": { - "path-type": "^4.0.0" + "dependencies": { + "builtin-modules": "^3.3.0", + "deferred": "^0.7.11", + "es5-ext": "^0.10.62", + "es6-set": "^0.1.6", + "ext": "^1.7.0", + "find-requires": "^1.0.0", + "fs2": "^0.3.9", + "type": "^2.7.2" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "peer": true }, - "duration": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", - "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "node_modules/node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.46" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "dependencies": { + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.10.5" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/electron/-/electron-17.4.4.tgz", - "integrity": "sha512-/CqXJwm1VLfhF7+QhCrPEoePcpGMdRh09A+sVHX+kgT1twrmNH8S+ZeMPYxX8EU0O0Eki3UfA5zA2ADWaCDq2Q==", - "dev": true, - "requires": { - "@electron/get": "^1.13.0", - "@types/node": "^14.6.2", - "extract-zip": "^1.0.3" + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "electron-to-chromium": { - "version": "1.4.137", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", - "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "devOptional": true, - "requires": { - "iconv-lite": "^0.6.2" + "node_modules/node-pg-migrate": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/node-pg-migrate/-/node-pg-migrate-6.2.2.tgz", + "integrity": "sha512-0WYLTXpWu2doeZhiwJUW/1u21OqAFU2CMQ8YZ8VBcJ0xrdqYAjtd8GGFe5A5DM4NJdIZsqJcLPDFqY0FQsmivw==", + "dev": true, + "dependencies": { + "@types/pg": "^8.0.0", + "decamelize": "^5.0.0", + "mkdirp": "~1.0.0", + "yargs": "~17.3.0" + }, + "bin": { + "node-pg-migrate": "bin/node-pg-migrate" + }, + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "pg": ">=4.3.0 <9.0.0" } }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" + "node_modules/node-pg-migrate/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "node_modules/node-pg-migrate/node_modules/yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/node-pg-migrate/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "requires": { - "ansi-colors": "^4.1.1" + "engines": { + "node": ">=12" } }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, - "es-abstract": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.0.tgz", - "integrity": "sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.1", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "node_modules/nodemon": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.3.tgz", + "integrity": "sha512-m4Vqs+APdKzDFpuaL9F9EVOF85+h070FnkHVEoU4+rmT6Vw0bmNl7s61VEkY/cJkL7RCv1p4urnUDUMrS5rk2w==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" } }, - "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "node_modules/nodemon/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "has": "^1.0.3" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" } }, - "es5-ext": { - "version": "0.10.61", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", - "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "node_modules/npm-registry-utilities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-utilities/-/npm-registry-utilities-1.0.0.tgz", + "integrity": "sha512-9xYfSJy2IFQw1i6462EJzjChL9e65EfSo2Cw6kl0EFeDp05VvU+anrQk3Fc0d1MbVCq7rWIxeer89O9SUQ/uOg==", "dev": true, - "optional": true - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "dependencies": { + "ext": "^1.6.0", + "fs2": "^0.3.9", + "memoizee": "^0.4.15", + "node-fetch": "^2.6.7", + "semver": "^7.3.5", + "type": "^2.6.0", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=12.0" } }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "node_modules/npm-registry-utilities/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - }, - "dependencies": { - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - } + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" + "engines": { + "node": ">=0.10.0" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } + "engines": { + "node": ">= 6" } }, - "eslint-config-airbnb": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", - "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^14.2.1", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" + "engines": { + "node": ">= 0.4" } }, - "eslint-config-prettier": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, - "eslint-plugin-jsx-a11y": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", - "integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==", + "node_modules/object.hasown": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, - "requires": { - "@babel/runtime": "^7.16.3", - "aria-query": "^4.2.2", - "array-includes": "^3.1.4", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", - "language-tags": "^1.0.5", - "minimatch": "^3.0.4" + "dependencies": { + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "peer": true + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" } }, - "eslint-plugin-react": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", - "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", - "object.values": "^1.1.5", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" - }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } + "wrappy": "1" } }, - "eslint-plugin-react-hooks": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", - "dev": true, - "peer": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "esniff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.0.tgz", - "integrity": "sha1-xmhJIp+RRk3t4uDUAgHtar9l8qw=", + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.12" + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" } }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "estraverse": "^5.1.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "estraverse": "^5.2.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "essentials": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/essentials/-/essentials-1.2.0.tgz", - "integrity": "sha512-kP/j7Iw7KeNE8b/o7+tr9uX2s1wegElGOoGZ2Xm35qBr4BbbEcH3/bxR2nfH9l9JANCq9AUrvKw+gRuHtZp0HQ==", + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "uni-global": "^1.0.0" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" } }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "requires": { - "js-sha3": "^0.8.0" + "node_modules/ox": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.6.tgz", + "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.0.9", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } + "node_modules/ox/node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" }, - "ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, + "node_modules/ox/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "ethers": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.6.tgz", - "integrity": "sha512-2B2ZmSGvRcJpHnFMBk58mkXP50njFipUBCgLK8jUTFbomhVs501cLzyMU6+Vx8YnUDQxywC3qkZvd33xWS+2FA==", - "requires": { - "@ethersproject/abi": "5.6.2", - "@ethersproject/abstract-provider": "5.6.0", - "@ethersproject/abstract-signer": "5.6.1", - "@ethersproject/address": "5.6.0", - "@ethersproject/base64": "5.6.0", - "@ethersproject/basex": "5.6.0", - "@ethersproject/bignumber": "5.6.1", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.0", - "@ethersproject/contracts": "5.6.1", - "@ethersproject/hash": "5.6.0", - "@ethersproject/hdnode": "5.6.1", - "@ethersproject/json-wallets": "5.6.0", - "@ethersproject/keccak256": "5.6.0", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.2", - "@ethersproject/pbkdf2": "5.6.0", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.6", - "@ethersproject/random": "5.6.0", - "@ethersproject/rlp": "5.6.0", - "@ethersproject/sha2": "5.6.0", - "@ethersproject/signing-key": "5.6.1", - "@ethersproject/solidity": "5.6.0", - "@ethersproject/strings": "5.6.0", - "@ethersproject/transactions": "5.6.0", - "@ethersproject/units": "5.6.0", - "@ethersproject/wallet": "5.6.1", - "@ethersproject/web": "5.6.0", - "@ethersproject/wordlists": "5.6.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - } + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "node_modules/ox/node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true + "node_modules/ox/node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "node_modules/ox/node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "node_modules/ox/node_modules/abitype": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.0.tgz", + "integrity": "sha512-fD3ROjckUrWsybaSor2AdWxzA0e/DSyV2dA4aYd7bd8orHsoJjl09fOgKfUkTDfk0BsDGBf4NBgu/c7JoS2Npw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "zod": { + "optional": true } } }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "requires": { - "type": "^2.5.0" + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" } }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", "dev": true, - "requires": { - "mime-db": "^1.28.0" + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, - "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" + "engines": { + "node": ">=4" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "external-editor": { + "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "extract-files": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", - "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==" - }, - "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, - "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" + "yocto-queue": "^0.1.0" }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "peer": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true + "node_modules/p-locate/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "peer": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" + "node_modules/p-locate/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "peer": true, + "engines": { + "node": ">=4" } }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "peer": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "figures": { + "node_modules/p-timeout": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "requires": { - "flat-cache": "^3.0.4" + "engines": { + "node": ">=6" } }, - "file-type": { - "version": "16.5.3", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.3.tgz", - "integrity": "sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A==", - "dev": true, - "requires": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" - } + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, - "filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "requires": { - "to-regex-range": "^5.0.1" + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" } }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "peer": true, + "engines": { + "node": ">=4" } }, - "find-requires": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-requires/-/find-requires-1.0.0.tgz", - "integrity": "sha512-UME7hNwBfzeISSFQcBEDemEEskpOjI/shPrpJM5PI4DSdn6hX0dmz+2dL70blZER2z8tSnTRL+2rfzlYgtbBoQ==", - "dev": true, - "requires": { - "es5-ext": "^0.10.49", - "esniff": "^1.1.0" + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "requires": { - "locate-path": "^2.0.0" + "engines": { + "node": ">=8" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/path-loader": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/path-loader/-/path-loader-1.0.12.tgz", + "integrity": "sha512-n7oDG8B+k/p818uweWrOixY9/Dsr89o2TkCm6tOTex3fpdo2+BFDgR+KpB37mGKBRsBAlR8CIJMFN0OEy/7hIQ==", "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "dependencies": { + "native-promise-only": "^0.8.1", + "superagent": "^7.1.6" } }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", - "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" + "node_modules/path-loader/node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dev": true, + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "node_modules/path-loader/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" } }, - "formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/path-loader/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/path-loader/node_modules/superagent": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.6.tgz", + "integrity": "sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, - "requires": { - "minipass": "^3.0.0" + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.10.3", + "readable-stream": "^3.6.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "fs2": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/fs2/-/fs2-0.3.9.tgz", - "integrity": "sha512-WsOqncODWRlkjwll+73bAxVW3JPChDgaPX3DT4iTTm73UmG4VgALa7LaFblP232/DN60itkOrPZ8kaP1feksGQ==", + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "requires": { - "d": "^1.0.1", - "deferred": "^0.7.11", - "es5-ext": "^0.10.53", - "event-emitter": "^0.3.5", - "ignore": "^5.1.8", - "memoizee": "^0.4.14", - "type": "^2.1.0" - }, "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true, - "optional": true + "engines": { + "node": "14 || >=16.14" + } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "node_modules/path2": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path2/-/path2-0.1.0.tgz", + "integrity": "sha512-TX+cz8Jk+ta7IvRy2FAej8rdlbrP0+uBIkP/5DTODez/AuL/vSb30KuAdDxGVREXzn8QfAiu5mJYJ1XjbOhEPA==", "dev": true }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "peer": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" + "node_modules/pg": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz", + "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", + "dependencies": { + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } } }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" + "node_modules/pg-connection-string": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node_modules/pg-minify": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz", + "integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==", + "engines": { + "node": ">=8.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", "dev": true, - "requires": { - "is-glob": "^4.0.1" + "engines": { + "node": ">=4" } }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" + "node_modules/pg-pool": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "peerDependencies": { + "pg": ">=8.0" } }, - "global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" + "node_modules/pg-promise": { + "version": "10.15.4", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.15.4.tgz", + "integrity": "sha512-BKlHCMCdNUmF6gagVbehRWSEiVcZzPVltEx14OJExR9Iz9/1R6KETDWLLGv2l6yRqYFnEZZy1VDjRhArzeIGrw==", + "dependencies": { + "assert-options": "0.8.0", + "pg": "8.8.0", + "pg-minify": "1.6.2", + "spex": "3.2.0" }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/pg-promise/node_modules/pg": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.2", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true } } }, - "global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" + "node_modules/pg-promise/node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "node_modules/pg-promise/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, - "requires": { - "define-properties": "^1.1.3" + "node_modules/pg-promise/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" } }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, + "node_modules/pg-promise/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pg-promise/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "node_modules/pg-protocol": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + }, + "node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", "dev": true, - "requires": { - "lodash": "^4.17.15" + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" } }, - "graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==" - }, - "graphql-request": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", - "integrity": "sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==", - "requires": { - "cross-fetch": "^3.0.6", - "extract-files": "^9.0.0", - "form-data": "^3.0.0" + "node_modules/pg/node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "har-schema": { + "node_modules/pg/node_modules/postgres-array": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" + "node_modules/pg/node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" + "node_modules/pg/node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" } }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + "node_modules/pg/node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "requires": { - "get-intrinsic": "^1.1.1" + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" } }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "http-cache-semantics": { + "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" } }, - "http-https": { + "node_modules/possible-typed-array-names": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" } }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "engines": { + "node": ">=12" } }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "requires": { - "punycode": "2.1.0" - }, "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" - } + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "engines": { + "node": ">=12" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "engines": { + "node": ">= 0.8.0" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, - "optional": true + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" } }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/process-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-utils/-/process-utils-4.0.0.tgz", + "integrity": "sha512-fMyMQbKCxX51YxR7YGCzPjLsU3yDzXFkP4oi1/Mt5Ixnk7GO/7uUTj8mrCHUwuvozWzI+V7QSJR9cZYnwNOZPg==", "dev": true, - "requires": { - "binary-extensions": "^2.0.0" + "dependencies": { + "ext": "^1.4.0", + "fs2": "^0.3.9", + "memoizee": "^0.4.14", + "type": "^2.1.0" + }, + "engines": { + "node": ">=10.0" } }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" } }, - "is-builtin-module": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", - "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "node_modules/promise-queue": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", + "integrity": "sha512-p/iXrPSVfnqPft24ZdNNLECw/UrtLTpT3jpAAMzl/o5/rDsGCPo3/CQS2611flL6LkoEJ3oQZw7C8Q80ZISXRQ==", "dev": true, - "requires": { - "builtin-modules": "^3.0.0" + "engines": { + "node": ">= 0.8.0" } }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, - "requires": { - "has": "^1.0.3" + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" } }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "requires": { - "is-extglob": "^2.1.1" + "engines": { + "node": ">=6" } }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", "dev": true }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "requires": { - "has-tostringtag": "^1.0.0" + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "requires": { - "call-bind": "^1.0.2" + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dev": true, + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "engines": { + "node": ">=4" + } }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "requires": { - "call-bind": "^1.0.2" + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, - "requires": { - "is-docker": "^2.0.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, - "requires": {} - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "engines": { + "node": ">=8" }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "dev": true + "node_modules/require-addon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.1.0.tgz", + "integrity": "sha512-KbXAD5q2+v1GJnkzd8zzbOxchTkStSyJZ9QwoCq3QwEXAaIlG3wDYRZGzVD357jmwaGY7hr5VaoEAL0BkF0Kvg==", + "optional": true, + "dependencies": { + "bare-addon-resolve": "^1.3.0", + "bare-url": "^2.1.0" + }, + "engines": { + "bare": ">=1.10.0" + } }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true }, - "json-buffer": { + "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } }, - "json-cycle": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/json-cycle/-/json-cycle-1.3.0.tgz", - "integrity": "sha512-FD/SedD78LCdSvJaOUQAXseT8oQBb5z6IVYaQaCrVUlu9zOAr1BDdKyVYQaSD/GDsAMrXpKcOyBD4LIl8nfjHw==", - "dev": true + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "json-refs": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/json-refs/-/json-refs-3.0.15.tgz", - "integrity": "sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw==", + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", "dev": true, - "requires": { - "commander": "~4.1.1", - "graphlib": "^2.1.8", - "js-yaml": "^3.13.1", - "lodash": "^4.17.15", - "native-promise-only": "^0.8.1", - "path-loader": "^1.0.10", - "slash": "^3.0.0", - "uri-js": "^4.2.2" + "engines": { + "node": ">=10" } }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "peer": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "peer": true, + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" } }, - "jsx-ast-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", - "integrity": "sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==", + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", "dev": true, - "requires": { - "array-includes": "^3.1.4", - "object.assign": "^4.1.2" + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" } }, - "jszip": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", - "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", + "node_modules/roarr/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, - "jwt-decode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", - "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=", - "dev": true - }, - "kareem": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", - "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } + "optional": true }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" } }, - "language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", - "dev": true - }, - "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { - "language-subtag-registry": "~0.3.2" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", "dev": true, - "requires": { - "readable-stream": "^2.0.5" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "dependencies": { + "tslib": "^2.1.0" } }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, - "requires": { - "immediate": "~3.0.5" + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "log": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/log/-/log-6.3.1.tgz", - "integrity": "sha512-McG47rJEWOkXTDioZzQNydAVvZNeEkSyLJ1VWkFwfW+o1knW+QSi8D1KjPn/TnctV+q99lkvJNe1f0E1IjfY2A==", - "dev": true, - "requires": { - "d": "^1.0.1", - "duration": "^0.2.2", - "es5-ext": "^0.10.53", - "event-emitter": "^0.3.5", - "sprintf-kit": "^2.0.1", - "type": "^2.5.0", - "uni-global": "^1.0.0" + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" } }, - "log-node": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/log-node/-/log-node-8.0.3.tgz", - "integrity": "sha512-1UBwzgYiCIDFs8A0rM2QdBFo8Wd8UQ0HrSTu/MNI+/2zN3NoHRj2fhplurAyuxTYUXu3Oohugq1jAn5s05u1MQ==", + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "cli-color": "^2.0.1", - "cli-sprintf-format": "^1.1.1", - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "sprintf-kit": "^2.0.1", - "supports-color": "^8.1.1", - "type": "^2.5.0" + "optional": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "ms": "2.0.0" } }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, + "optional": true, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "lru-cache": { + "node_modules/serialize-javascript": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" } }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/serverless": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/serverless/-/serverless-3.39.0.tgz", + "integrity": "sha512-FHI3fhe4TRS8+ez/KA7HmO3lt3fAynO+N1pCCzYRThMWG0J8RWCI0BI+K0mw9+sEV+QpBCpZRZbuGyUaTsaQew==", "dev": true, - "requires": { - "semver": "^6.0.0" + "hasInstallScript": true, + "dependencies": { + "@aws-sdk/client-api-gateway": "^3.588.0", + "@aws-sdk/client-cognito-identity-provider": "^3.588.0", + "@aws-sdk/client-eventbridge": "^3.588.0", + "@aws-sdk/client-iam": "^3.588.0", + "@aws-sdk/client-lambda": "^3.588.0", + "@aws-sdk/client-s3": "^3.588.0", + "@serverless/dashboard-plugin": "^7.2.0", + "@serverless/platform-client": "^4.5.1", + "@serverless/utils": "^6.13.1", + "abort-controller": "^3.0.0", + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "archiver": "^5.3.1", + "aws-sdk": "^2.1404.0", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.2", + "child-process-ext": "^2.1.1", + "ci-info": "^3.8.0", + "cli-progress-footer": "^2.3.2", + "d": "^1.0.1", + "dayjs": "^1.11.8", + "decompress": "^4.2.1", + "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", + "essentials": "^1.2.0", + "ext": "^1.7.0", + "fastest-levenshtein": "^1.0.16", + "filesize": "^10.0.7", + "fs-extra": "^10.1.0", + "get-stdin": "^8.0.0", + "globby": "^11.1.0", + "graceful-fs": "^4.2.11", + "https-proxy-agent": "^5.0.1", + "is-docker": "^2.2.1", + "js-yaml": "^4.1.0", + "json-colorizer": "^2.2.2", + "json-cycle": "^1.5.0", + "json-refs": "^3.0.15", + "lodash": "^4.17.21", + "memoizee": "^0.4.15", + "micromatch": "^4.0.5", + "node-fetch": "^2.6.11", + "npm-registry-utilities": "^1.0.0", + "object-hash": "^3.0.0", + "open": "^8.4.2", + "path2": "^0.1.0", + "process-utils": "^4.0.0", + "promise-queue": "^2.2.5", + "require-from-string": "^2.0.2", + "semver": "^7.5.3", + "signal-exit": "^3.0.7", + "stream-buffers": "^3.0.2", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "tar": "^6.1.15", + "timers-ext": "^0.1.7", + "type": "^2.7.2", + "untildify": "^4.0.0", + "uuid": "^9.0.0", + "ws": "^7.5.9", + "yaml-ast-parser": "0.0.43" + }, + "bin": { + "serverless": "bin/serverless.js", + "sls": "bin/serverless.js" + }, + "engines": { + "node": ">=12.0" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "node_modules/serverless-prune-plugin": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/serverless-prune-plugin/-/serverless-prune-plugin-2.0.2.tgz", + "integrity": "sha512-tW1Q8MAVmhW8KQN+e0AsSVsb9nmRWWj28xBjMwvVC3FbammmtUJT+5nRpmjxJZ6/K/j3OV1Rx8b32md71BwkYQ==", "dev": true, - "optional": true + "dependencies": { + "bluebird": "^3.7.2" + }, + "peerDependencies": { + "serverless": "1 || 2 || 3" + } }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "node_modules/serverless-webpack": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/serverless-webpack/-/serverless-webpack-5.14.0.tgz", + "integrity": "sha512-UmAHl1JxqBDwt4wLlRMpU6MSIK9PxhCGIt/wS4I0UIQR5SvtuXoerZOtrByJ/NErJyhhowtNpNT1cOn0AyxMvA==", "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - }, "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, + "archiver": "^7.0.1", + "bluebird": "^3.7.2", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^11.2.0", + "glob": "^8.1.0", + "is-builtin-module": "^3.2.1", + "lodash": "^4.17.21", + "semver": "^7.6.2" + }, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "ts-node": ">= 8.3.0" + }, + "peerDependencies": { + "@types/node": "*", + "serverless": "1 || 2 || 3", + "typescript": ">=2.0", + "webpack": ">= 3.0.0 < 6" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "typescript": { "optional": true } } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "node_modules/serverless-webpack/node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "node_modules/serverless-webpack/node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, - "memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "node_modules/serverless-webpack/node_modules/archiver-utils/node_modules/glob": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", + "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "node_modules/serverless-webpack/node_modules/archiver-utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/serverless-webpack/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "node_modules/serverless-webpack/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" + "node_modules/serverless-webpack/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "engines": { + "node": ">=8.0.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "node_modules/serverless-webpack/node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" + "node_modules/serverless-webpack/node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "node_modules/serverless-webpack/node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "node_modules/serverless-webpack/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/serverless-webpack/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { - "brace-expansion": "^1.1.7" + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "node_modules/serverless-webpack/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "node_modules/serverless-webpack/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "requires": { - "yallist": "^4.0.0" + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "node_modules/serverless-webpack/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" + "node_modules/serverless-webpack/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" - }, - "mongodb": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", - "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", - "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - }, + "node_modules/serverless-webpack/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, "dependencies": { - "optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "requires": { - "require-at": "^1.0.6" - } - } + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "mongoose": { - "version": "5.13.14", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.14.tgz", - "integrity": "sha512-j+BlQjjxgZg0iWn42kLeZTB91OejcxWpY2Z50bsZTiKJ7HHcEtcY21Godw496GMkBqJMTzmW7G/kZ04mW+Cb7Q==", - "requires": { - "@types/bson": "1.x || 4.0.x", - "@types/mongodb": "^3.5.27", - "bson": "^1.1.4", - "kareem": "2.3.2", - "mongodb": "3.7.3", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.8.4", - "mquery": "3.2.5", - "ms": "2.1.2", - "optional-require": "1.0.x", - "regexp-clone": "1.0.0", - "safe-buffer": "5.2.1", - "sift": "13.5.2", - "sliced": "1.0.1" + "node_modules/serverless-webpack/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serverless-webpack/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, - "mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==", - "requires": {} + "node_modules/serverless-webpack/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, - "mpath": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz", - "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==" + "node_modules/serverless-webpack/node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } }, - "mquery": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", - "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", - "requires": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" + "node_modules/serverless/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/serverless/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/serverless/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } + "node_modules/serverless/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "requires": { - "varint": "^5.0.0" + "node_modules/serverless/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } + "node_modules/serverless/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" } + ], + "engines": { + "node": ">=8" } }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true + "node_modules/serverless/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "node_modules/serverless/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "ncjsm": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.0.tgz", - "integrity": "sha512-oah6YGwb4Ern2alojiMFcjPhE4wvQBw1Ur/kUr2P0ovKdzaF5pCIsGjs0f2y+iZeej0/5Y6OOhQ8j30cTDMEGw==", + "node_modules/serverless/node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, - "requires": { - "builtin-modules": "^3.2.0", - "deferred": "^0.7.11", - "es5-ext": "^0.10.53", - "es6-set": "^0.1.5", - "ext": "^1.6.0", - "find-requires": "^1.0.0", - "fs2": "^0.3.9", - "type": "^2.5.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + "node_modules/serverless/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "node_modules/serverless/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + "node_modules/serverless/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "node_modules/serverless/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "node_modules/serverless/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "requires": { - "minimatch": "^3.0.2" + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" + "node_modules/serverless/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" - }, - "node-releases": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", - "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + "node_modules/serverless/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "node_modules/serverless/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "optional": true, - "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" + "engines": { + "node": ">= 10.0.0" } }, - "npm-registry-utilities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-registry-utilities/-/npm-registry-utilities-1.0.0.tgz", - "integrity": "sha512-9xYfSJy2IFQw1i6462EJzjChL9e65EfSo2Cw6kl0EFeDp05VvU+anrQk3Fc0d1MbVCq7rWIxeer89O9SUQ/uOg==", + "node_modules/serverless/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "dev": true, - "requires": { - "ext": "^1.6.0", - "fs2": "^0.3.9", - "memoizee": "^0.4.15", - "node-fetch": "^2.6.7", - "semver": "^7.3.5", - "type": "^2.6.0", - "validate-npm-package-name": "^3.0.0" + "engines": { + "node": ">=8.3.0" }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true } } }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - } + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "dev": true + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" } }, - "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "engines": { + "node": ">=8" } }, - "object.hasown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", - "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", - "dev": true, - "requires": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-git": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.25.0.tgz", + "integrity": "sha512-KIY5sBnzc4yEcJXW7Tdv4viEz8KyG+nU0hay+DWZasvdFOYKeUZ6Xc25LUHHjw0tinPT7O1eY6pzX7pRT1K8rw==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" } }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "requires": { - "http-https": "^1.0.0" + "node_modules/simple-statistics": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/simple-statistics/-/simple-statistics-7.8.3.tgz", + "integrity": "sha512-JFvMY00t6SBGtwMuJ+nqgsx9ylkMiJ5JlK9bkj8AdvniIe5615wWQYkKHXe84XtSuc40G/tlrPu0A5/NlJvv8A==", + "engines": { + "node": "*" } }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" } }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "optional-require": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", - "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + "node_modules/sodium-native": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.3.tgz", + "integrity": "sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==", + "optional": true, + "dependencies": { + "require-addon": "^1.1.0" + } }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "peer": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" } }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "node_modules/solc/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "peer": true }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "peer": true, + "bin": { + "semver": "bin/semver" + } }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "parent-module": { + "node_modules/sort-keys-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", "dev": true, - "requires": { - "callsites": "^3.0.0" + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" } }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "node_modules/spex": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz", + "integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==", + "engines": { + "node": ">=4.5" + } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "path-loader": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/path-loader/-/path-loader-1.0.10.tgz", - "integrity": "sha512-CMP0v6S6z8PHeJ6NFVyVJm6WyJjIwFvyz2b0n2/4bKdS/0uZa/9sKUlYZzubrn3zuDRU0zIuEDX9DZYQ2ZI8TA==", + "node_modules/sprintf-kit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.2.tgz", + "integrity": "sha512-lnapdj6W4LflHZGKvl9eVkz5YF0xaTrqpRWVA4cNVOTedwqifIP8ooGImldzT/4IAN5KXFQAyXTdLidYVQdyag==", "dev": true, - "requires": { - "native-promise-only": "^0.8.1", - "superagent": "^3.8.3" - }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "superagent": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", - "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "dev": true, - "requires": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.3.5" - } - } + "es5-ext": "^0.10.64" + }, + "engines": { + "node": ">=0.12" } }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } }, - "path2": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path2/-/path2-0.1.0.tgz", - "integrity": "sha1-Y5golCzb2kSkGkWwdK6Ic0g7Tvo=", - "dev": true + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" } }, - "peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "peer": true, + "engines": { + "node": ">=8" + } }, - "performance-now": { + "node_modules/standard-as-callback": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/starknet": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/starknet/-/starknet-4.22.0.tgz", + "integrity": "sha512-jC9Taxb6a/ht9zmS1LU/DSLfwJKpgCJnE9AktVksc5SE/+jQMpqxsq6fm7PRiqupjiqRC1DOS8N47cj+KaGv4Q==", + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "bn.js": "^5.2.1", + "elliptic": "^6.5.4", + "ethereum-cryptography": "^1.0.3", + "hash.js": "^1.1.7", + "isomorphic-fetch": "^3.0.0", + "json-bigint": "^1.0.0", + "minimalistic-assert": "^1.0.1", + "pako": "^2.0.4", + "ts-custom-error": "^3.3.1", + "url-join": "^4.0.1" + } }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "node_modules/starknet/node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", "dev": true, - "optional": true + "engines": { + "node": ">= 0.10.0" + } }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", + "license": "BSD-3-Clause" }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" + "node_modules/stream-json": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", + "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", + "license": "BSD-3-Clause", + "dependencies": { + "stream-chain": "^2.2.5" } }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/stream-promise": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz", + "integrity": "sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA==", "dev": true, - "requires": { - "find-up": "^4.0.0" - }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } + "2-thenable": "^1.0.0", + "es5-ext": "^0.10.49", + "is-stream": "^1.1.0" } }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "node_modules/stream-promise/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } }, - "prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", - "dev": true + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { - "fast-diff": "^1.1.2" + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "process-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/process-utils/-/process-utils-4.0.0.tgz", - "integrity": "sha512-fMyMQbKCxX51YxR7YGCzPjLsU3yDzXFkP4oi1/Mt5Ixnk7GO/7uUTj8mrCHUwuvozWzI+V7QSJR9cZYnwNOZPg==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { - "ext": "^1.4.0", - "fs2": "^0.3.9", - "memoizee": "^0.4.14", - "type": "^2.1.0" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "promise-queue": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", - "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=", - "dev": true + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, - "optional": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "randombytes": { + "node_modules/strip-dirs": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "dependencies": { + "is-natural-number": "^4.0.1" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "peer": true, "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" } }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", "dev": true, - "requires": { - "readable-stream": "^3.6.0" - }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "dev": true, - "requires": { - "minimatch": "^3.0.4" + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", "dev": true, - "requires": { - "picomatch": "^2.2.1" + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" } }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "regexp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", - "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "node_modules/superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 7.0.0" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "node_modules/superagent/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - } + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" } }, - "require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==" + "node_modules/superagent/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" } }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "resolve-from": { + "node_modules/supports-hyperlinks/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "requires": { - "glob": "^7.1.3" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } + "node_modules/symbol.inspect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol.inspect/-/symbol.inspect-1.0.1.tgz", + "integrity": "sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==", + "license": "ISC" }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" } }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "node_modules/table/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, "dependencies": { - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "optional": true - } + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "engines": { + "node": ">=6" } }, - "run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "requires": { - "sparse-bitfield": "^3.0.3" + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" } }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "node_modules/terser": { + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", "dev": true, - "requires": { - "commander": "^2.8.1" - }, "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, - "optional": true - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "esbuild": { + "optional": true }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "uglify-js": { + "optional": true } } }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "node_modules/terser-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" + "engines": { + "node": ">=8" } }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "serverless": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/serverless/-/serverless-3.17.0.tgz", - "integrity": "sha512-M3VJc8PW/elxCAU/vQeNYPdjp3m7Ms/WyE+A+s2TTJYOVBVUuQhX2s+4u6GulTkxeBF3s83EvX26eAJ4RdXCTQ==", - "dev": true, - "requires": { - "@serverless/dashboard-plugin": "^6.2.2", - "@serverless/platform-client": "^4.3.2", - "@serverless/utils": "^6.3.0", - "ajv": "^8.11.0", - "ajv-formats": "^2.1.1", - "archiver": "^5.3.1", - "aws-sdk": "^2.1131.0", - "bluebird": "^3.7.2", - "cachedir": "^2.3.0", - "chalk": "^4.1.2", - "child-process-ext": "^2.1.1", - "ci-info": "^3.3.0", - "cli-progress-footer": "^2.3.1", - "d": "^1.0.1", - "dayjs": "^1.11.2", - "decompress": "^4.2.1", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "essentials": "^1.2.0", - "ext": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "filesize": "^8.0.7", - "fs-extra": "^9.1.0", - "get-stdin": "^8.0.0", - "globby": "^11.1.0", - "got": "^11.8.3", - "graceful-fs": "^4.2.10", - "https-proxy-agent": "^5.0.1", - "is-docker": "^2.2.1", - "js-yaml": "^4.1.0", - "json-cycle": "^1.3.0", - "json-refs": "^3.0.15", - "lodash": "^4.17.21", - "memoizee": "^0.4.15", - "micromatch": "^4.0.5", - "node-fetch": "^2.6.7", - "npm-registry-utilities": "^1.0.0", - "object-hash": "^2.2.0", - "open": "^7.4.2", - "path2": "^0.1.0", - "process-utils": "^4.0.0", - "promise-queue": "^2.2.5", - "require-from-string": "^2.0.2", - "semver": "^7.3.7", - "signal-exit": "^3.0.7", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "tar": "^6.1.11", - "timers-ext": "^0.1.7", - "type": "^2.6.0", - "untildify": "^4.0.0", - "uuid": "^8.3.2", - "yaml-ast-parser": "0.0.43" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "keyv": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.8.tgz", - "integrity": "sha512-IZZo6krhHWPhgsP5mBkEdPopVPN/stgCnBVuqi6dda/Nm5mDTOSVTrFMkWqlJsDum+B0YSe887tNxdjDWkO7aQ==", - "dev": true, - "requires": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "serverless-prune-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/serverless-prune-plugin/-/serverless-prune-plugin-2.0.1.tgz", - "integrity": "sha512-fWttDV5TD3K6g9NRDJUuA/cq0AzAI0ya1FZXQKtCnWFfaGP7CzZHZWzlvnNofqvKdpY8vXtaAiswc6gdHXaTUw==", + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "requires": { - "bluebird": "^3.7.2" - }, "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - } + "randombytes": "^2.1.0" } }, - "serverless-webpack": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/serverless-webpack/-/serverless-webpack-5.7.1.tgz", - "integrity": "sha512-uyDtyLSR81lNDRWC8yU2hB9eNdfICJ9d5OnSuXCJ+UF5A+KhMkDa0oXVtyKfa5uT+kqCgF9kUW4GUJBav8vsKA==", + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "requires": { - "archiver": "^5.3.1", - "bluebird": "^3.7.2", - "fs-extra": "^9.1.0", - "glob": "^7.2.0", - "is-builtin-module": "^3.1.0", - "lodash": "^4.17.21", - "semver": "^7.3.7", - "ts-node": ">= 8.3.0" - }, "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" + "node_modules/terser/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "node_modules/teslabot": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/teslabot/-/teslabot-1.5.0.tgz", + "integrity": "sha512-e2MmELhCgrgZEGo7PQu/6bmYG36IDH+YrBI1iGm6jovXkeDIGa3pZ2WSqRjzkuw2vt1EqfkZoV5GpXgqL8QJVg==", + "license": "MIT" }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", "dev": true, - "requires": { - "shebang-regex": "^3.0.0" + "dependencies": { + "b4a": "^1.6.4" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" } }, - "sift": { - "version": "13.5.2", - "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", - "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" }, - "simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" } }, - "simple-git": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.7.1.tgz", - "integrity": "sha512-+Osjtsumbtew2y9to0pOYjNzSIr4NkKGBg7Po5SUtjQhaJf2QBmiTX/9E9cv9rmc7oUiSGFIB9e7ys5ibnT9+A==", + "node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "dev": true, - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.3" + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "simple-statistics": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/simple-statistics/-/simple-statistics-7.7.5.tgz", - "integrity": "sha512-CYq683Yg2mb7M4mklQ6FtxEdsYeziGa2giaLvqXobfK1qVqZDKd7BIqLnngnKQSw9GsfNinbiScbfjc3IRWdQA==" + "node_modules/token-types/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "slash": { + "node_modules/toml": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/traverse": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz", + "integrity": "sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==", + "dev": true, + "dependencies": { + "gopd": "^1.0.1", + "typedarray.prototype.slice": "^1.0.3", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tron-format-address": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/tron-format-address/-/tron-format-address-0.1.11.tgz", + "integrity": "sha512-Jx2i3R1yXrEMQsfc2jueAI71ivnySzdeva6SiSM/pddwj8TK7PVABSP6s/iYcTRI63GxJEgGMmOJXNNKoBmbQw==" + }, + "node_modules/ts-custom-error": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", + "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } + "peerDependenciesMeta": { + "@swc/core": { + "optional": true }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "@swc/wasm": { + "optional": true } } }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" + "node_modules/ts-node/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "dev": true, - "requires": { - "sort-keys": "^1.0.0" + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", - "requires": { - "memory-pager": "^1.0.2" + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "requires": { - "readable-stream": "^3.0.0" - }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sprintf-kit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sprintf-kit/-/sprintf-kit-2.0.1.tgz", - "integrity": "sha512-2PNlcs3j5JflQKcg4wpdqpZ+AjhQJ2OZEo34NXDtlB0tIPG84xaaXhpA8XFacFiwjKA4m49UOYG83y3hbMn/gQ==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "requires": { - "es5-ext": "^0.10.53" + "engines": { + "node": ">=4" } }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, - "stream-promise": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-promise/-/stream-promise-3.2.0.tgz", - "integrity": "sha512-P+7muTGs2C8yRcgJw/PPt61q7O517tDHiwYEzMWo1GSBCcZedUMT/clz7vUNsSxFphIlJ6QUL4GexQKlfJoVtA==", - "dev": true, - "requires": { - "2-thenable": "^1.0.0", - "es5-ext": "^0.10.49", - "is-stream": "^1.1.0" - } + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "peer": true }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "peer": true }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", - "side-channel": "^1.0.4" + "engines": { + "node": ">=4" } }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, - "requires": { - "ansi-regex": "^5.0.1" + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, - "requires": { - "is-natural-number": "^4.0.1" + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "node_modules/typedarray.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz", + "integrity": "sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==", "dev": true, - "requires": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-errors": "^1.3.0", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-offset": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "superagent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", - "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", - "requires": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.1", - "fast-safe-stringify": "^2.0.7", - "form-data": "^3.0.0", - "formidable": "^1.2.2", - "methods": "^1.1.2", - "mime": "^2.4.6", - "qs": "^6.9.4", - "readable-stream": "^3.6.0", - "semver": "^7.3.2" + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "requires": { - "lru-cache": "^6.0.0" - } - } + "buffer": "^5.2.1", + "through": "^2.3.8" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "requires": { - "has-flag": "^3.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, - "swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" } }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/uni-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz", + "integrity": "sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw==", "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } + "type": "^2.5.0" } }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "terser": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz", - "integrity": "sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map": "~0.8.0-beta.0", - "source-map-support": "~0.5.20" - }, "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dev": true, - "requires": { - "whatwg-url": "^7.0.0" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } + "punycode": "^2.1.0" } }, - "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", - "dev": true, - "requires": { - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" + }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, - "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "dev": true }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" + "dependencies": { + "builtins": "^1.0.3" } }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "engines": { + "node": ">= 0.10" + } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + "node_modules/viem": { + "version": "2.40.2", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.40.2.tgz", + "integrity": "sha512-iZXVl5Uip1BUQv0PI9yOq+vHGRTnJ0a8azC5IAAJMSrvdkGrvghIwGskp3+g243fpzFlO/iqAFrWIG15SDoiTQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.1.0", + "isows": "1.0.7", + "ox": "0.9.6", + "ws": "8.18.3" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "token-types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz", - "integrity": "sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==", - "dev": true, - "requires": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" }, - "dependencies": { - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - } + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "node_modules/viem/node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", - "dev": true + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", - "dev": true, - "optional": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" + "node_modules/viem/node_modules/abitype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.1.0.tgz", + "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { "optional": true } } }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "node_modules/viem/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true } } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "optional": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" + "dependencies": { + "makeerror": "1.0.12" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, - "requires": { - "prelude-ls": "^1.2.1" + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" } }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, - "optional": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "dependencies": { + "defaults": "^1.0.3" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" + "node_modules/web3": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-4.9.0.tgz", + "integrity": "sha512-O0R90ijjyqUlG1Wk3SXqfYMU1ZGJvLCAF/WfSg/isDz/0Fkpqxoj893wauZ+ieRvTXITlbQHVXGfpp8qrhWZ1g==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-abi": "^4.2.2", + "web3-eth-accounts": "^4.1.2", + "web3-eth-contract": "^4.5.0", + "web3-eth-ens": "^4.3.0", + "web3-eth-iban": "^4.0.7", + "web3-eth-personal": "^4.0.8", + "web3-net": "^4.1.0", + "web3-providers-http": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.12.0" } }, - "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", - "dev": true, - "optional": true, - "peer": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "node_modules/web3-core": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.5.0.tgz", + "integrity": "sha512-Q8LIAqmF7vkRydBPiU+OC7wI44nEU6JEExolFaOakqrjMtQ1CWFHRUQMNJRDsk5bRirjyShuAsuqLeYByvvXhg==", + "dependencies": { + "web3-errors": "^1.2.0", + "web3-eth-accounts": "^4.1.2", + "web3-eth-iban": "^4.0.7", + "web3-providers-http": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + }, + "optionalDependencies": { + "web3-providers-ipc": "^4.0.7" } }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - }, + "node_modules/web3-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.2.0.tgz", + "integrity": "sha512-58Kczou5zyjcm9LuSs5Hrm6VrG8t9p2J8X0yGArZrhKNPZL66gMGkOUpPx+EopE944Sk4yE+Q25hKv4H5BH+kA==", "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } + "web3-types": "^1.6.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "uni-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uni-global/-/uni-global-1.0.0.tgz", - "integrity": "sha512-WWM3HP+siTxzIWPNUg7hZ4XO8clKi6NoCAJJWnuRL+BAqyFXF8gC03WNyTefGoUXYc47uYgXxpKLIEvo65PEHw==", - "dev": true, - "requires": { - "type": "^2.5.0" + "node_modules/web3-eth": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.7.0.tgz", + "integrity": "sha512-gqlWq4Xjz+yKL2MdxQ+BgR3F4CRo4AXWDXzftb3LDzvauEfjk/yRyoxkMSK4S9RIG96ylRImS172cV6cYzcukw==", + "dependencies": { + "setimmediate": "^1.0.5", + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth-abi": "^4.2.2", + "web3-eth-accounts": "^4.1.2", + "web3-net": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "node_modules/web3-eth-abi": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.2.2.tgz", + "integrity": "sha512-akbGi642UtKG3k3JuLbhl9KuG7LM/cXo/by2WfdwfOptGZrzRsWJNWje1d2xfw1n9kkVG9SAMvPJl1uSyR3dfw==", + "dependencies": { + "abitype": "0.7.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true + "node_modules/web3-eth-accounts": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.1.2.tgz", + "integrity": "sha512-y0JynDeTDnclyuE9mShXLeEj+BCrPHxPHOyPCgTchUBQsALF9+0OhP7WiS3IqUuu0Hle5bjG2f5ddeiPtNEuLg==", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "crc-32": "^1.2.2", + "ethereum-cryptography": "^2.0.0", + "web3-errors": "^1.1.4", + "web3-types": "^1.6.0", + "web3-utils": "^4.2.3", + "web3-validator": "^2.0.5" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" + "node_modules/web3-eth-accounts/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "node_modules/web3-eth-accounts/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" + "node_modules/web3-eth-accounts/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" + "node_modules/web3-eth-accounts/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" + "node_modules/web3-eth-accounts/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "dependencies": { + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } }, - "utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "requires": { - "node-gyp-build": "^4.3.0" + "node_modules/web3-eth-contract": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.5.0.tgz", + "integrity": "sha512-AX6OiDrIryz/T28k9Xz0gXpUrlOUjcooEgGluu2s5dFDWCPM/zlN5RsUZlXZiXpQyj52VCUy5+bkvu3yDPA4fg==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-abi": "^4.2.2", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" + "node_modules/web3-eth-ens": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.3.0.tgz", + "integrity": "sha512-QpiKT9GqJouH5kEI/pRFprh88YPCtbht2Ym6rrklZ+VoWl9D+wLfbwvW7Aox349FS7k0UX2qVins5tVNLJ5GCQ==", + "dependencies": { + "@adraffy/ens-normalize": "^1.8.8", + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-contract": "^4.5.0", + "web3-net": "^4.1.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "node_modules/web3-eth-iban": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz", + "integrity": "sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==", + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "node_modules/web3-eth-personal": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.8.tgz", + "integrity": "sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw==", + "dependencies": { + "web3-core": "^4.3.0", + "web3-eth": "^4.3.1", + "web3-rpc-methods": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "node_modules/web3-net": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.1.0.tgz", + "integrity": "sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "node_modules/web3-providers-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.1.0.tgz", + "integrity": "sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg==", + "dependencies": { + "cross-fetch": "^4.0.0", + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true + "node_modules/web3-providers-http/node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "requires": { - "builtins": "^1.0.3" + "node_modules/web3-providers-ipc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz", + "integrity": "sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==", + "optional": true, + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" + "node_modules/web3-providers-ws": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.7.tgz", + "integrity": "sha512-n4Dal9/rQWjS7d6LjyEPM2R458V8blRm0eLJupDEJOOIBhGYlxw5/4FthZZ/cqB7y/sLVi7K09DdYx2MeRtU5w==", + "dependencies": { + "@types/ws": "8.5.3", + "isomorphic-ws": "^5.0.0", + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "ws": "^8.8.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "node_modules/web3-providers-ws/node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "node_modules/web3-providers-ws/node_modules/ws": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true } } }, - "watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "node_modules/web3-rpc-methods": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz", + "integrity": "sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" + "node_modules/web3-types": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.7.0.tgz", + "integrity": "sha512-nhXxDJ7a5FesRw9UG5SZdP/C/3Q2EzHGnB39hkAV+YGXDMgwxBXFWebQLfEzZzuArfHnvC0sQqkIHNwSKcVjdA==", + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.0.tgz", + "integrity": "sha512-fGG2IZr0XB1vEoWZiyJzoy28HpsIfZgz4mgPeQA9aj5rIx8z0o80qUPtIyrCYX/Bo2gYALlV5SWIJWxJNUQn9Q==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "eventemitter3": "^5.0.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "web3": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.3.tgz", - "integrity": "sha512-UgBvQnKIXncGYzsiGacaiHtm0xzQ/JtGqcSO/ddzQHYxnNuwI72j1Pb4gskztLYihizV9qPNQYHMSCiBlStI9A==", - "requires": { - "web3-bzz": "1.7.3", - "web3-core": "1.7.3", - "web3-eth": "1.7.3", - "web3-eth-personal": "1.7.3", - "web3-net": "1.7.3", - "web3-shh": "1.7.3", - "web3-utils": "1.7.3" + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "web3-bzz": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.3.tgz", - "integrity": "sha512-y2i2IW0MfSqFc1JBhBSQ59Ts9xE30hhxSmLS13jLKWzie24/An5dnoGarp2rFAy20tevJu1zJVPYrEl14jiL5w==", - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dependencies": { - "@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" - } + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "web3-core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.3.tgz", - "integrity": "sha512-4RNxueGyevD1XSjdHE57vz/YWRHybpcd3wfQS33fgMyHZBVLFDNwhn+4dX4BeofVlK/9/cmPAokLfBUStZMLdw==", - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-requestmanager": "1.7.3", - "web3-utils": "1.7.3" + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", "dependencies": { - "@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" - } + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "web3-core-helpers": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.3.tgz", - "integrity": "sha512-qS2t6UKLhRV/6C7OFHtMeoHphkcA+CKUr2vfpxy4hubs3+Nj28K9pgiqFuvZiXmtEEwIAE2A28GBOC3RdcSuFg==", - "requires": { - "web3-eth-iban": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-core-method": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.3.tgz", - "integrity": "sha512-SeF8YL/NVFbj/ddwLhJeS0io8y7wXaPYA2AVT0h2C2ESYkpvOtQmyw2Bc3aXxBmBErKcbOJjE2ABOKdUmLSmMA==", - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-core-promievent": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.3.tgz", - "integrity": "sha512-+mcfNJLP8h2JqcL/UdMGdRVfTdm+bsoLzAFtLpazE4u9kU7yJUgMMAqnK59fKD3Zpke3DjaUJKwz1TyiGM5wig==", - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.3.tgz", - "integrity": "sha512-bC+jeOjPbagZi2IuL1J5d44f3zfPcgX+GWYUpE9vicNkPUxFBWRG+olhMo7L+BIcD57cTmukDlnz+1xBULAjFg==", - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.3", - "web3-providers-http": "1.7.3", - "web3-providers-ipc": "1.7.3", - "web3-providers-ws": "1.7.3" - } - }, - "web3-core-subscriptions": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.3.tgz", - "integrity": "sha512-/i1ZCLW3SDxEs5mu7HW8KL4Vq7x4/fDXY+yf/vPoDljlpvcLEOnI8y9r7om+0kYwvuTlM6DUHHafvW0221TyRQ==", - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.3" - } - }, - "web3-eth": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.3.tgz", - "integrity": "sha512-BCIRMPwaMlTCbswXyGT6jj9chCh9RirbDFkPtvqozfQ73HGW7kP78TXXf9+Xdo1GjutQfxi/fQ9yPdxtDJEpDA==", - "requires": { - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-eth-accounts": "1.7.3", - "web3-eth-contract": "1.7.3", - "web3-eth-ens": "1.7.3", - "web3-eth-iban": "1.7.3", - "web3-eth-personal": "1.7.3", - "web3-net": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-eth-abi": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.3.tgz", - "integrity": "sha512-ZlD8DrJro0ocnbZViZpAoMX44x5aYAb73u2tMq557rMmpiluZNnhcCYF/NnVMy6UIkn7SF/qEA45GXA1ne6Tnw==", - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.3" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - } + "node_modules/web3-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", + "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "util": "^0.12.5", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "zod": "^3.21.4" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" } }, - "web3-eth-accounts": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.3.tgz", - "integrity": "sha512-aDaWjW1oJeh0LeSGRVyEBiTe/UD2/cMY4dD6pQYa8dOhwgMtNQjxIQ7kacBBXe7ZKhjbIFZDhvXN4mjXZ82R2Q==", - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-utils": "1.7.3" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - } + "node_modules/web3-validator/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "web3-eth-contract": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.3.tgz", - "integrity": "sha512-7mjkLxCNMWlQrlfM/MmNnlKRHwFk5XrZcbndoMt3KejcqDP6dPHi2PZLutEcw07n/Sk8OMpSamyF3QiGfmyRxw==", - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-eth-ens": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.3.tgz", - "integrity": "sha512-q7+hFGHIc0mBI3LwgRVcLCQmp6GItsWgUtEZ5bjwdjOnJdbjYddm7PO9RDcTDQ6LIr7hqYaY4WTRnDHZ6BEt5Q==", - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-promievent": "1.7.3", - "web3-eth-abi": "1.7.3", - "web3-eth-contract": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-eth-iban": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.3.tgz", - "integrity": "sha512-1GPVWgajwhh7g53mmYDD1YxcftQniIixMiRfOqlnA1w0mFGrTbCoPeVaSQ3XtSf+rYehNJIZAUeDBnONVjXXmg==", - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.3" + "node_modules/web3-validator/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "web3-eth-personal": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.3.tgz", - "integrity": "sha512-iTLz2OYzEsJj2qGE4iXC1Gw+KZN924fTAl0ESBFs2VmRhvVaM7GFqZz/wx7/XESl3GVxGxlRje3gNK0oGIoYYQ==", - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.3", - "web3-core-helpers": "1.7.3", - "web3-core-method": "1.7.3", - "web3-net": "1.7.3", - "web3-utils": "1.7.3" + "node_modules/web3-validator/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-validator/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dependencies": { - "@types/node": { - "version": "12.20.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", - "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==" - } + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "web3-net": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.3.tgz", - "integrity": "sha512-zAByK0Qrr71k9XW0Adtn+EOuhS9bt77vhBO6epAeQ2/VKl8rCGLAwrl3GbeEl7kWa8s/su72cjI5OetG7cYR0g==", - "requires": { - "web3-core": "1.7.3", - "web3-core-method": "1.7.3", - "web3-utils": "1.7.3" - } - }, - "web3-providers-http": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.3.tgz", - "integrity": "sha512-TQJfMsDQ5Uq9zGMYlu7azx1L7EvxW+Llks3MaWn3cazzr5tnrDbGh6V17x6LN4t8tFDHWx0rYKr3mDPqyTjOZw==", - "requires": { - "web3-core-helpers": "1.7.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.3.tgz", - "integrity": "sha512-Z4EGdLKzz6I1Bw+VcSyqVN4EJiT2uAro48Am1eRvxUi4vktGoZtge1ixiyfrRIVb6nPe7KnTFl30eQBtMqS0zA==", - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.3" - } - }, - "web3-providers-ws": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.3.tgz", - "integrity": "sha512-PpykGbkkkKtxPgv7U4ny4UhnkqSZDfLgBEvFTXuXLAngbX/qdgfYkhIuz3MiGplfL7Yh93SQw3xDjImXmn2Rgw==", - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.3.tgz", - "integrity": "sha512-bQTSKkyG7GkuULdZInJ0osHjnmkHij9tAySibpev1XjYdjLiQnd0J9YGF4HjvxoG3glNROpuCyTaRLrsLwaZuw==", - "requires": { - "web3-core": "1.7.3", - "web3-core-method": "1.7.3", - "web3-core-subscriptions": "1.7.3", - "web3-net": "1.7.3" - } - }, - "web3-utils": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz", - "integrity": "sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg==", - "requires": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "node_modules/web3-validator/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "dependencies": { + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "webidl-conversions": { + "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "webpack": { - "version": "5.72.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.72.1.tgz", - "integrity": "sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung==", + "node_modules/webpack": { + "version": "5.92.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.0.tgz", + "integrity": "sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==", "dev": true, - "requires": { + "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.9.3", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.3.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true } } }, - "webpack-sources": { + "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true + "dev": true, + "engines": { + "node": ">=10.13.0" + } }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "requires": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" + "node_modules/webpack/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/webpack/node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "whatwg-url": { + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-boxed-primitive": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { + "dev": true, + "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "peer": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "peer": true }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "requires": { - "xhr-request": "^1.1.0" + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "^2.1.1" + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "dev": true, - "requires": { + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dependencies": { "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, - "yaml-ast-parser": { + "node_modules/yaml-ast-parser": { "version": "0.0.43", "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", "dev": true }, - "yamljs": { + "node_modules/yamljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "peer": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" } }, - "yauzl": { + "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, - "requires": { + "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, - "optional": true + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } }, - "zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" } } } diff --git a/package.json b/package.json index 7d9ae2c8d4..176daa63bd 100644 --- a/package.json +++ b/package.json @@ -4,30 +4,57 @@ "scripts": { "deploy:env": "sls deploy --stage $NODE_ENV", "deploy:prod": "export AWS_PROFILE='defillama' && export NODE_ENV=prod && npm run deploy:env", - "deploy:dev": "export AWS_PROFILE='default' && export NODE_ENV=dev && npm run deploy:env", - "deploy": "export NODE_ENV=prod && npm run deploy:env" + "deploy:dev": "export AWS_PROFILE='defillama' && export NODE_ENV=dev && npm run deploy:env", + "deploy": "export NODE_ENV=prod && npm run deploy:env", + "build": "sls package", + "test": "jest", + "migrate": "node-pg-migrate", + "start:api": "node src/api/server" }, "author": "", "license": "ISC", "dependencies": { - "@defillama/sdk": "^2.3.62", - "bignumber.js": "^9.0.2", + "@blend-capital/blend-sdk": "3.0.1", + "@defillama/sdk": "^5.0.112", + "@stacks/network": "^6.13.0", + "@stacks/transactions": "^6.15.0", + "@ton/ton": "14.0.0", + "@types/jest": "^28.1.6", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/v3-sdk": "^3.13.0", + "async-retry": "^1.3.3", + "aws-sdk": "^2.1389.0", + "axios": "^1.7.2", + "p-limit": "^3.1.0", + "bignumber.js": "^9.1.1", + "csv-writer": "^1.6.0", "date-fns": "^2.23.0", "dotenv": "^10.0.0", + "ethers": "^5.7.2", + "express": "^4.18.2", "graphql": "^15.5.1", "graphql-request": "^3.5.0", - "mongoose": "^5.11.13", + "helmet": "^7.0.0", + "ioredis": "^5.3.2", + "lambert-w-function": "^3.0.0", + "limiter": "^2.1.0", + "lodash": "^4.17.21", + "morgan": "^1.10.0", "node-fetch": "^2.6.1", - "saslprep": "^1.0.3", + "pg-promise": "^10.11.1", "simple-statistics": "^7.7.5", + "starknet": "^4.22.0", "superagent": "^6.1.0", - "web3": "^1.4.0" + "validator": "^13.9.0", + "web3": "^4.9.0" }, "devDependencies": { "@babel/core": "^7.17.8", - "aws-sdk": "^2.987.0", + "@babel/plugin-transform-runtime": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@babel/runtime": "^7.18.6", "babel-loader": "^8.2.3", - "electron": "^17.1.2", + "electron": "^31.0.1", "encoding": "^0.1.13", "eslint": "^7.18.0", "eslint-config-airbnb": "^18.2.1", @@ -37,10 +64,19 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", + "jest": "^28.1.3", + "node-pg-migrate": "^6.2.2", + "nodemon": "^3.1.3", + "pg": "^8.8.0", "prettier": "^2.2.1", "serverless": "^3.8.0", "serverless-prune-plugin": "^2.0.1", "serverless-webpack": "^5.6.1", + "ts-node": "^10.9.1", "webpack": "^5.70.0" + }, + "jest": { + "globalSetup": "./src/adaptors/beforeTests.js", + "globalTeardown": "./src/adaptors/afterTests.js" } } diff --git a/scripts/bootstrapStdTable.js b/scripts/bootstrapStdTable.js deleted file mode 100644 index b6bdfba96f..0000000000 --- a/scripts/bootstrapStdTable.js +++ /dev/null @@ -1,81 +0,0 @@ -const fs = require('fs'); - -const ss = require('simple-statistics'); -const superagent = require('superagent'); -const AWS = require('aws-sdk'); -const credentials = new AWS.SharedIniFileCredentials({ profile: 'defillama' }); -AWS.config.credentials = credentials; - -// script for boostrapping std and quantile tables (running locally) -// when calculating the expanding stds, i want to include all data -// i've collected so far, hence why i need this step to create the fields -// required by welford's algorithm -const main = async () => { - const dataStd = []; - // path to latest db snapshot (full history!) - const p = './pools.json'; - const data = JSON.parse(fs.readFileSync(p)); - - for (const [i, pool] of [...new Set(data.map((el) => el.pool))].entries()) { - console.log(i); - - // filter to pool and add day and time fields - let X = data - .filter((el) => el.pool === pool) - .map((el) => ({ - ...el, - day: el.timestamp['$date'].split('T')[0], - time: Number(el.timestamp['$date'].split('T')[1].slice(0, 2)), - })); - - // find latest data point per day - const latestDaily = []; - for (const d of [...new Set(X.map((el) => el.day))]) { - let x = X.filter((el) => el.day === d); - const maxTime = Math.max.apply( - Math, - x.map((t) => t.time) - ); - // append to array - latestDaily.push(x.find((el) => el.time === maxTime)); - } - - // i remove extreme values (eg there is 'bifi-maxi-56' with apy values of >1e100...) - X = latestDaily - .map((el) => el.apy) - .filter((el) => el !== null && el >= 0 && el <= 1e6); - - const count = X.length; - if (count === 0) { - continue; - } - const mean = X.reduce((a, b) => a + b, 0) / count; - const mean2 = count < 2 ? null : ss.variance(X) * (count - 1); - - dataStd.push({ - pool, - count, - mean, - mean2, - }); - } - - // save to tables - const ssm = new AWS.SSM({ region: 'eu-central-1' }); - const options = { - Name: '/llama-apy/serverless/sls-authenticate/bearertoken', - WithDecryption: true, - }; - const token = await ssm.getParameter(options).promise(); - - const urlBase = 'https://1rwmj4tky9.execute-api.eu-central-1.amazonaws.com'; - const responseStd = await superagent - .post(`${urlBase}/stds`) - .send(dataStd) - .set({ Authorization: `Bearer ${token.Parameter.Value}` }); - console.log(responseStd.body); -}; - -(async () => { - await main(); -})(); diff --git a/scripts/confirm.js b/scripts/confirm.js new file mode 100644 index 0000000000..83723e2bba --- /dev/null +++ b/scripts/confirm.js @@ -0,0 +1,22 @@ +const readline = require('readline'); + +module.exports.confirm = (query) => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false, + }); + + return new Promise((resolve) => + rl.question(query, (ans) => { + if (ans !== 'yes') { + rl.close(); + console.log('Exiting'); + process.exit(1); + } else { + rl.close(); + resolve(ans); + } + }) + ); +}; diff --git a/scripts/createAdapterList.js b/scripts/createAdapterList.js new file mode 100644 index 0000000000..573b6f48e4 --- /dev/null +++ b/scripts/createAdapterList.js @@ -0,0 +1,10 @@ +const fs = require('fs'); + +function main(){ + const adapters = fs + .readdirSync('./src/adaptors') + .filter((el) => !el.includes('js') && el !== '.DS_Store' && !el.includes('package')).map(t=>`"${t}"`).join(",") + fs.writeFileSync("./src/adaptors/list.js", "module.exports = [" + adapters + "]") +} + +main() \ No newline at end of file diff --git a/scripts/createConfig.js b/scripts/createConfig.js new file mode 100644 index 0000000000..48fe830baf --- /dev/null +++ b/scripts/createConfig.js @@ -0,0 +1,40 @@ +const fs = require('fs'); + +const superagent = require('superagent'); + +const { confirm } = require('./confirm'); +const { connect } = require('../src/utils/dbConnection'); +const { buildInsertConfigQuery } = require('../src/queries/config'); + +(async () => { + await confirm( + `Confirm with 'yes' if you want to start the ${process.argv[1] + .split('/') + .slice(-1)} script: ` + ); + + const uuids = JSON.parse(fs.readFileSync('./created_uuids.json')); + const urls = (await superagent.get('https://yields.llama.fi/url')).body; + let data = JSON.parse(fs.readFileSync('./yield_snapshot_last.json')); + + data = data.map((p) => ({ + config_id: uuids[p.pool], + pool: p.pool, + project: p.project, + chain: p.chain, + symbol: p.symbol, + poolMeta: p.poolMeta, + underlyingTokens: + p?.underlyingTokens?.length > 0 ? p?.underlyingTokens : null, + rewardTokens: p?.rewardTokens?.length > 0 ? p?.rewardTokens : null, + url: urls[p.project], + })); + + // build multi row insert query + const insertConfigQ = buildInsertConfigQuery(data); + + const conn = await connect(); + const response = await conn.result(insertConfigQ); + console.log(response); + process.exit(0); +})(); diff --git a/scripts/createMedian.js b/scripts/createMedian.js new file mode 100644 index 0000000000..0ece2e07b3 --- /dev/null +++ b/scripts/createMedian.js @@ -0,0 +1,45 @@ +const fs = require('fs'); + +const ss = require('simple-statistics'); + +const { confirm } = require('./confirm'); +const exclude = require('../src/utils/exclude'); +const { insertMedian } = require('../src/queries/median'); + +(async () => { + await confirm( + `Confirm with 'yes' if you want to start the ${process.argv[1] + .split('/') + .slice(-1)} script: ` + ); + // load yield table snapshot of daily values only + let data = JSON.parse(fs.readFileSync('./yield_snapshot_daily.json')); + // we filter further on tvl (10k) cause this is what we do on retrieval from db for frontend + data = data.filter( + (p) => + p.tvlUsd >= 1e4 && + !exclude.excludePools.includes(p.pool) && + !exclude.excludeAdaptors.includes(p.project) + ); + + let payload = []; + for (const [i, timestamp] of [ + ...new Set(data.map((el) => el.timestamp)), + ].entries()) { + console.log(i, timestamp); + + // filter to day + let X = data.filter((el) => el.timestamp === timestamp); + + payload.push({ + timestamp: new Date(timestamp), + medianAPY: parseFloat(ss.median(X.map((p) => p.apy)).toFixed(5)), + uniquePools: new Set(X.map((p) => p.pool)).size, + }); + } + payload = payload.sort((a, b) => b.timestamp - a.timestamp); + + const response = await insertMedian(payload); + console.log(response); + process.exit(0); +})(); diff --git a/scripts/createMedianProtocol.js b/scripts/createMedianProtocol.js new file mode 100644 index 0000000000..514b67fbb8 --- /dev/null +++ b/scripts/createMedianProtocol.js @@ -0,0 +1,52 @@ +const fs = require('fs'); +const path = require('path'); + +require('dotenv').config({ path: path.resolve(__dirname, '../config.env') }); + +const pgp = require('pg-promise')({ + capSQL: true, +}); +pgp.pg.types.setTypeParser(20, parseInt); +pgp.pg.types.setTypeParser(1700, parseFloat); + +const query = ` +INSERT INTO +median_project (timestamp, project, "medianAPY", "uniquePools") +WITH daily_data AS ( + SELECT + "configID", + DATE(timestamp) AS timestamp, + apy + FROM yield + WHERE "configID" IN (SELECT config_id FROM config WHERE project = $) + AND timestamp < current_date + AND apy > 0 + AND "tvlUsd" > 10000 +) +SELECT + timestamp, + $ AS project, + PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY apy) AS "medianAPY", + count(distinct "configID") AS "uniquePools" +FROM daily_data +GROUP BY timestamp +ORDER BY timestamp; + `; + +(async () => { + const projects = fs + .readdirSync('../src/adaptors') + .filter((f) => !f.endsWith('.js') && !f.endsWith('.json')) + .slice(204); + + const conn = pgp({ + connectionString: process.env.DATABASE_URL, + idleTimeoutMillis: 5000, + max: 1, + }); + + for (const project of projects) { + const response = await conn.result(query, { project }); + console.log(projects.indexOf(project), project, response.rowCount); + } +})(); diff --git a/scripts/createStat.js b/scripts/createStat.js new file mode 100644 index 0000000000..36b4181167 --- /dev/null +++ b/scripts/createStat.js @@ -0,0 +1,54 @@ +const fs = require('fs'); + +const ss = require('simple-statistics'); + +const { confirm } = require('./confirm'); +const { insertStat } = require('../src/queries/stat'); + +(async () => { + await confirm( + `Confirm with 'yes' if you want to start the ${process.argv[1] + .split('/') + .slice(-1)} script: ` + ); + // load yield table snapshot of daily values only + let data = JSON.parse(fs.readFileSync('./yield_snapshot_daily.json')); + + // load the uuids + const uuids = JSON.parse(fs.readFileSync('./created_uuids.json')); + + // create return field + const T = 365; + // transform raw apy to return field (required for geometric mean below) + data = data.map((p) => ({ + pool: p.pool, + apy: p.apy, + return: (1 + p.apy / 100) ** (1 / T) - 1, + })); + + const payload = []; + for (const [i, pool] of [...new Set(data.map((p) => p.pool))].entries()) { + console.log(i); + + // filter to config id + let X = data.filter((p) => p.pool === pool); + if (X.length === 0) continue; + + const count = X.length; + const seriesAPY = X.map((p) => p.apy); + const seriesReturn = X.map((p) => p.return); + + payload.push({ + configID: uuids[pool], + count, + meanAPY: seriesAPY.reduce((a, b) => a + b, 0) / count, + mean2APY: count < 2 ? 0 : ss.variance(seriesAPY) * (count - 1), + meanDR: seriesReturn.reduce((a, b) => a + b, 0) / count, + mean2DR: count < 2 ? 0 : ss.variance(seriesReturn) * (count - 1), + productDR: seriesReturn.map((a) => 1 + a).reduce((a, b) => a * b), + }); + } + const response = await insertStat(payload); + console.log(response); + process.exit(0); +})(); diff --git a/scripts/createUUID.js b/scripts/createUUID.js new file mode 100644 index 0000000000..48ef4d2be9 --- /dev/null +++ b/scripts/createUUID.js @@ -0,0 +1,21 @@ +const fs = require('fs'); +const crypto = require('crypto'); + +const data = JSON.parse(fs.readFileSync('./yield_snapshot_last.json')); +const uniquePools = new Set(data.map((p) => p.pool)); +console.log('nb of unique pools: ', uniquePools.size); + +const uuidMapping = {}; +for (const pool of uniquePools) { + uuidMapping[pool] = crypto.randomUUID(); +} +console.log( + 'nb of unique pools in mapping: ', + new Set(Object.keys(uuidMapping)).size +); +console.log( + 'nb of unique uuids in mapping: ', + new Set(Object.values(uuidMapping)).size +); + +fs.writeFileSync('./created_uuids.json', JSON.stringify(uuidMapping)); diff --git a/scripts/createYield.js b/scripts/createYield.js new file mode 100644 index 0000000000..0057410cd1 --- /dev/null +++ b/scripts/createYield.js @@ -0,0 +1,34 @@ +const fs = require('fs'); + +const { confirm } = require('./confirm'); +const { connect } = require('../src/utils/dbConnection'); +const { buildInsertYieldQuery } = require('../src/queries/yield'); + +(async () => { + await confirm( + `Confirm with 'yes' if you want to start the ${process.argv[1] + .split('/') + .slice(-1)} script: ` + ); + + const uuids = JSON.parse(fs.readFileSync('./created_uuids.json')); + + let data = JSON.parse(fs.readFileSync('./yield_snapshot_daily.json')); + + data = data.map((p) => ({ + configID: uuids[p.pool], + timestamp: new Date(p.timestamp), + tvlUsd: p.tvlUsd, + apy: p.apy, + apyBase: p.apyBase, + apyReward: p.apyReward, + })); + + // build multi row insert query + const insertYieldQ = buildInsertYieldQuery(data); + + const conn = await connect(); + const response = await conn.result(insertYieldQ); + console.log(response); + process.exit(0); +})(); diff --git a/scripts/prepareSnapshot.py b/scripts/prepareSnapshot.py new file mode 100644 index 0000000000..eac7cacd22 --- /dev/null +++ b/scripts/prepareSnapshot.py @@ -0,0 +1,101 @@ +import sys +import ast + +import pandas as pd + +# the way i ran this: +# Step 1) DOWNLOAD FULL HISTORY from mongodb + +# Step 2) PREPARE DATA +# run this python script, which does: + # filter apy >= 0, tvlUsd >= 1000 + # cast dtype: tvlUsd to integer + # round apy columns to 5 decimals + # ... + # stores 3 outputs: the full hourly history (for yield), last value for each day (for stat), last value (for config) + +# Step 3) CREATE UUIDS +# based on output from Step 2) run the bootstrapUUID.js file which creates a unique uuid for each unique pool and stores that locally + +# Step 4) CREATE THE POSTGRES TABLES +# run the create scripts starting with config, then the others (order doesn't matter for the rest) + +def replaceFunc(x: str) -> str: + if x == "[null]": + return "[]" + elif x == "[null,null]": + return "[]" + elif "null," in x: + return x.replace("null,", "") + elif ",null" in x: + return x.replace(",null", "") + else: + return x + + +def prepare_snapshot(filename: str) -> None: + df = pd.read_csv(f"{filename}") + + # correct none, null values in array + df.loc[df["underlyingTokens"].notnull(), "underlyingTokens"] = df.loc[ + df["underlyingTokens"].notnull(), "underlyingTokens" + ].apply(lambda x: replaceFunc(x) if "null" in x else x) + + # remove rows where all 3 apy fields are null + df = df[ + ~((df["apy"].isnull()) & (df["apyReward"].isnull()) & (df["apyBase"].isnull())) + ] + + # keep positive apy sum values only + df = df[(df["apy"] >= 0) & (df["apy"] <= 1e6)] + # tvl btw boundary values + df = df[(df["tvlUsd"] >= 1000) & (df["tvlUsd"] <= 2e10)] + + # remove pools and project from exclusion list + exclude_pools = [ + "0xf4bfe9b4ef01f27920e490cea87fe2642a8da18d", + "DWmAv5wMun4AHxigbwuJygfmXBBe9WofXAtrMCRJExfb", + "ripae-seth-weth-42161", + "ripae-peth-weth-42161", + "0x3eed430cd45c5e2b45aa1adc609cc77c6728d45b", + "0x3c42B0f384D2912661C940d46cfFE1CD10F1c66F-ethereum", + "0x165ab553871b1a6b3c706e15b6a7bb29a244b2f3", + ] + df = df[~df["pool"].isin(exclude_pools)] + df = df[df["project"] != "koyo-finance"] + + # cast dtypes and round + df["tvlUsd"] = df["tvlUsd"].astype(int) + apy_columns = ["apy", "apyBase", "apyReward"] + df[apy_columns] = df[apy_columns].round(5) + + # 1. hourly (for yield table) + df["timestamp"] = pd.to_datetime(df["timestamp"]) + df = df.sort_values(["pool", "timestamp"], ascending=True).reset_index(drop=True) + f = "yield_snapshot" + df.to_csv(f"{f}_hourly.csv", index=False) + + # 2. prepare daily (for stat) + df_daily = ( + df.groupby(["pool", pd.Grouper(key="timestamp", freq="1D")]) + .last() + .reset_index() + ) + df_daily.to_json(f"{f}_daily.json", orient="records") + + # 3. prepare last (for config) + df_last = ( + df_daily.sort_values(["pool", "timestamp"], ascending=True) + .groupby("pool") + .last() + .reset_index() + ) + # cast string to arrays + func = lambda x: ast.literal_eval(x) if type(x) == str else x + df_last["underlyingTokens"] = df_last["underlyingTokens"].apply(func) + df_last["rewardTokens"] = df_last["rewardTokens"].apply(func) + df_last.to_json(f"{f}_last.json", orient="records") + + +if __name__ == "__main__": + prepare_snapshot(sys.argv[1]) diff --git a/scripts/updatePool.js b/scripts/updatePool.js new file mode 100644 index 0000000000..6b53adb69f --- /dev/null +++ b/scripts/updatePool.js @@ -0,0 +1,28 @@ +const fs = require('fs'); + +const { confirm } = require('./confirm'); +const { pgp, connect } = require('../src/utils/dbConnection'); +const { tableName: configTableName } = require('../src/queries/config'); + +(async () => { + await confirm( + `Confirm with 'yes' if you want to start the ${process.argv[1] + .split('/') + .slice(-1)} script: ` + ); + + const payload = JSON.parse(fs.readFileSync('./old_new_mapping.json')); + const X = payload.map((p) => ({ poolOld: p.pool, pool: p.poolNew })); + + // ? -> only used in where clause + const cs = new pgp.helpers.ColumnSet(['?poolOld', 'pool'], { + table: configTableName, + }); + const query = pgp.helpers.update(X, cs) + ' WHERE v."poolOld" = t.pool'; + + const conn = await connect(); + const response = await conn.result(query); + + console.log(response); + process.exit(0); +})(); diff --git a/serverless.yml b/serverless.yml index 166e049a54..2cae295eb3 100644 --- a/serverless.yml +++ b/serverless.yml @@ -7,13 +7,13 @@ frameworkVersion: '3' provider: name: aws - runtime: nodejs14.x + runtime: nodejs22.x stage: dev region: eu-central-1 tracing: apiGateway: true lambda: true - memorySize: 256 + memorySize: 1024 iam: role: statements: @@ -28,57 +28,15 @@ provider: - s3:*Object* - sqs:SendMessage Resource: '*' - - Effect: Allow - Action: - - ssm:PutParameter - - ssm:GetParameter - - ssm:DescribeParameters - - kms:Decrypt - Resource: '*' environment: - # for entrypoint and enrichment - ADAPTORS: ${file(./env.js):ADAPTORS} - # for api handlers - APIG_URL: - { - 'Fn::Join': - [ - '', - [ - 'https://', - { Ref: 'HttpApi' }, - '.execute-api.', - { Ref: 'AWS::Region' }, - '.', - { Ref: 'AWS::URLSuffix' }, - ], - ], - } - SSM_PATH: ${self:custom.ssmPath} BUCKET_DATA: { Ref: BucketData } - - httpApi: - metrics: true - cors: - allowedMethods: - - GET - authorizers: - JwtAuthorizer: - type: jwt - identitySource: $request.header.Authorization - issuerUrl: ${ssm:${self:custom.ssmPath}/issuer} - audience: ${ssm:${self:custom.ssmPath}/audience} + DATABASE_URL: ${file(./env.js):DATABASE_URL} + ZEROX_API: ${file(./env.js):ZEROX_API} + GRAPH_API_KEY: ${file(./env.js):GRAPH_API_KEY} functions: - triggerAuthenticate: - handler: src/handlers/triggerAuthenticate.handler - description: Lambda to create bearer token which stores to ssm - timeout: 30 - events: - # every 12hours - - schedule: rate(12 hours) - + # ---------- TRIGGER HANDLERS # --- top-lvl-entrypoint triggerEntrypoint: handler: src/handlers/triggerEntrypoint.handler @@ -94,114 +52,126 @@ functions: triggerAdaptor: handler: src/handlers/triggerAdaptor.handler description: Lambda which runs adaptors - timeout: 600 + timeout: 900 events: - sqs: arn: Fn::GetAtt: - AdapterQueue - Arn - batchSize: 2 + batchSize: 4 functionResponseType: ReportBatchItemFailures environment: - ETHERSCAN: ${file(./env.js):ETHERSCAN} - FANTOMSCAN: ${file(./env.js):FANTOMSCAN} - POLYGONSCAN: ${file(./env.js):POLYGONSCAN} - SNOWTRACE: ${file(./env.js):SNOWTRACE} - ARBISCAN: ${file(./env.js):ARBISCAN} - OPTIMISM: ${file(./env.js):OPTIMISM} - INFURA_CONNECTION: ${file(./env.js):INFURA_CONNECTION} - ALCHEMY_CONNECTION_POLYGON: ${file(./env.js):ALCHEMY_CONNECTION_POLYGON} ALCHEMY_CONNECTION_ARBITRUM: ${file(./env.js):ALCHEMY_CONNECTION_ARBITRUM} - XDAI: ${file(./env.js):XDAI} - - # --- data enrichment (pct-changes) + ALCHEMY_CONNECTION_ETHEREUM: ${file(./env.js):ALCHEMY_CONNECTION_ETHEREUM} + ALCHEMY_CONNECTION_POLYGON: ${file(./env.js):ALCHEMY_CONNECTION_POLYGON} + ETHEREUM_RPC: ${file(./env.js):ETHEREUM_RPC} + XDAI_RPC: ${file(./env.js):XDAI_RPC} + CRONOS_RPC: ${file(./env.js):CRONOS_RPC} + FANTOM_RPC: ${file(./env.js):FANTOM_RPC} + OPTIMISM_RPC: ${file(./env.js):OPTIMISM_RPC} + AVAX_RPC: ${file(./env.js):AVAX_RPC} + ARBITRUM_RPC: ${file(./env.js):ARBITRUM_RPC} + BASE_RPC: ${file(./env.js):BASE_RPC} + TRON_RPC: ${file(./env.js):TRON_RPC} + TVL_SPIKE_WEBHOOK: ${file(./env.js):TVL_SPIKE_WEBHOOK} + NEW_YIELDS_WEBHOOK: ${file(./env.js):NEW_YIELDS_WEBHOOK} + SMARDEX_SUBGRAPH_API_KEY: ${file(./env.js):SMARDEX_SUBGRAPH_API_KEY} + VENDOR_FINANCE: ${file(./env.js):VENDOR_FINANCE} + TRADERJOE: ${file(./env.js):TRADERJOE} + OSMOSIS_API_KEY: ${file(./env.js):OSMOSIS_API_KEY} + DUNE_API_KEY: ${file(./env.js):DUNE_API_KEY} + HYPERLIQUID_RPC: ${file(./env.js):HYPERLIQUID_RPC} + PLASMA_RPC: ${file(./env.js):PLASMA_RPC} + STARKNET_RPC: ${file(./env.js):STARKNET_RPC} + MONAD_RPC: ${file(./env.js):MONAD_RPC} + LLAMA_INDEXER_V2_ENDPOINT: ${env:LLAMA_INDEXER_V2_ENDPOINT} + LLAMA_INDEXER_V2_API_KEY: ${env:LLAMA_INDEXER_V2_API_KEY} + + # --- data enrichment triggerEnrichment: handler: src/handlers/triggerEnrichment.handler description: Lambda which runs enrichment process - timeout: 300 + timeout: 900 + memorySize: 1024 events: - # every hour at 20 past - - schedule: cron(20 * * * ? *) + # every hour at 16 past + - schedule: cron(16 * * * ? *) - # --- DB Crud operations - getPools: - handler: src/handlers/getPools.handler - description: Lambda for retrieving the latest data for each unique pool - timeout: 20 + # --- stats update + triggerStat: + handler: src/handlers/triggerStat.handler + description: Lambda which updates the stat table + timeout: 600 events: - - httpApi: - method: get - path: /pools + # 30min prior midnight + - schedule: cron(30 23 * * ? *) - storePools: - handler: src/handlers/storePools.handler - description: Lambda for db bulkwrite - timeout: 20 + # --- median insert + triggerMedian: + handler: src/handlers/triggerMedian.handler + description: Lambda which inserts latest value into the median table + timeout: 600 events: - - httpApi: - method: post - path: /pools - authorizer: - name: JwtAuthorizer + # 30min prior midnight + - schedule: cron(30 23 * * ? *) - deletePools: - handler: src/handlers/deletePools.handler - description: Lambda for deleteMany operation of pool data - timeout: 20 + # --- save poolsEnriched as CSV + triggerCsv: + handler: src/handlers/triggerCsv.handler + description: Lambda which saves poolsEnriched as csv to s3 bucket + timeout: 300 events: - - httpApi: - method: delete - path: /pools/{project}/{timestamp} - authorizer: - name: JwtAuthorizer + # every hour at 25 past + - schedule: cron(25 * * * ? *) - getPoolsEnriched: - handler: src/handlers/getPoolsEnriched.handler - description: Lambda for retrieving the latest enriched data for each unique pool - timeout: 20 + # --- trigger monitor + triggerMonitor: + handler: src/handlers/triggerMonitor.handler + description: Lambda which triggers the monitor query for logging stale adapters + timeout: 300 events: - - httpApi: - method: get - path: /poolsEnriched + # every hour at 30 past + - schedule: cron(30 * * * ? *) + environment: + STALE_PROJECTS_WEBHOOK: ${file(./env.js):STALE_PROJECTS_WEBHOOK} - getChart: - handler: src/handlers/getChart.handler - description: Lambda for retrieving chart data for a particular pool - timeout: 20 + # --- trigger perpetuals + triggerPerpertuals: + handler: src/handlers/triggerPerpetuals.handler + description: Lambda which triggers perp files + timeout: 300 events: - - httpApi: - method: get - path: /chart/{pool} + # every new hour + - schedule: cron(0 * * * ? *) - getOffsets: - handler: src/handlers/getOffsets.handler - description: Lambda for getting 1/7/30 day offset data of apy values - timeout: 20 + triggerMedianProject: + handler: src/handlers/triggerMedianProject.handler + description: Lambda which triggers daily median calculation for each project + timeout: 300 events: - - httpApi: - method: get - path: /offsets/{project}/{days} + # 30min prior midnight + - schedule: cron(30 23 * * ? *) - getStds: - handler: src/handlers/getStds.handler - description: Lambda for retrieving std data - timeout: 20 + triggerLSDRates: + handler: src/handlers/triggerLSDRates.handler + description: Lambda which triggers lsd market rate and expected rate + timeout: 300 events: - - httpApi: - method: get - path: /stds + # every new hour + - schedule: cron(0 * * * ? *) + environment: + ETHEREUM_RPC: ${file(./env.js):ETHEREUM_RPC} - storeStds: - handler: src/handlers/storeStds.handler - description: Lambda for db bulkupdate of std data - timeout: 20 + triggerProtocolNameChange: + handler: src/handlers/triggerProtocolNameChange.handler + description: Lambda which checks for protocol renames + timeout: 300 events: - - httpApi: - method: post - path: /stds - authorizer: - name: JwtAuthorizer + # every hour 40min past + - schedule: cron(40 * * * ? *) + environment: + STALE_PROJECTS_WEBHOOK: ${file(./env.js):STALE_PROJECTS_WEBHOOK} resources: Resources: @@ -211,7 +181,7 @@ resources: Type: AWS::SQS::Queue Properties: QueueName: ${self:service}-${self:custom.stage}-AdapterQueue - VisibilityTimeout: 660 + VisibilityTimeout: 960 # setting this to 9hours MessageRetentionPeriod: 32400 RedrivePolicy: @@ -266,7 +236,6 @@ resources: custom: stage: ${opt:stage, self:provider.stage} - ssmPath: /${self:service}/serverless/sls-authenticate webpack: webpackConfig: 'webpack.config.js' includeModules: true diff --git a/src/adaptors/1inch/index.js b/src/adaptors/1inch/index.js new file mode 100644 index 0000000000..8196384dae --- /dev/null +++ b/src/adaptors/1inch/index.js @@ -0,0 +1,45 @@ +const utils = require('../utils'); +// test3 + +const ADDRESSES = { + ethereum: { + '1INCH': '0x111111111117dc0aa78b770fa6a738034120c302', + dst1INCH: '0x9a0c8ff858d273f57072d714bca7411d717501d7', + }, + base: { + '1INCH': '0xc5fecc3a29fb57b5024eec8a2239d4621e111cbe', + }, +}; + +const main = async () => { + const data = await utils.getData( + 'https://data-distributor.1inch.io/resolversMetrics' + ); + const result = Object.values(data)[0].map((pool) => { + const apyReward = Number(pool.apyBase); + + return { + pool: `1INCH-${pool.resolver_address}-${pool.chain}`.toLowerCase(), + chain: utils.formatChain(pool.chain), + project: '1inch', + symbol: '1INCH', + poolMeta: pool.pool, + tvlUsd: Number(pool.tvlUsd), + apyReward, + url: `https://app.1inch.io/#/1/earn/delegate/${pool.resolver_address}`, + rewardTokens: + apyReward > 0 ? [ADDRESSES[pool.chain.toLowerCase()]['1INCH']] : [], + underlyingTokens: [ + ADDRESSES[pool.chain.toLowerCase()]['1INCH'], + ADDRESSES[pool.chain.toLowerCase()]['dst1INCH'], + ], + }; + }); + return result; +}; + +module.exports = { + timetravel: false, + apy: main, + // url: "https://app.1inch.io/#/1/dao/staking", +}; diff --git a/src/adaptors/3jane-options/index.ts b/src/adaptors/3jane-options/index.ts new file mode 100644 index 0000000000..691d57ff2c --- /dev/null +++ b/src/adaptors/3jane-options/index.ts @@ -0,0 +1,86 @@ +const { gql, request } = require('graphql-request'); +const { mean } = require('lodash'); +const utils = require('../utils'); + +const SUBGRAPH_URL = + 'https://api.goldsky.com/api/public/project_clvvvr5shxt6301t7b2zn04ii/subgraphs/3jane/1.4.2/gn'; + +const annualizedWeeklyYield = (yieldPercent: number) => { + return (yieldPercent + 1) ** 52 - 1; +}; + +const VaultsQuery = gql` + query VaultsQuery { + vaults { + id + name + underlyingSymbol + underlyingName + underlyingDecimals + underlyingAsset + totalBalance + symbol + } + } +`; + +const PremiumsQuery = gql` + query PremiumsQuery($id: ID = "") { + vaultOptionTrades( + first: 4 + orderBy: timestamp + orderDirection: desc + where: { vault_: { id: $id } } + ) { + premium + vault { + totalBalance + } + } + } +`; + +const poolsFunction = async () => { + const { vaults } = await request(SUBGRAPH_URL, VaultsQuery); + + const { pricesByAddress: prices } = await utils.getPrices( + vaults.map(({ underlyingAsset }) => underlyingAsset), + 'ethereum' + ); + + const pools = vaults.map(async (vault) => { + const { vaultOptionTrades } = await request(SUBGRAPH_URL, PremiumsQuery, { + id: vault.id, + }); + const avgWeeklyRet = mean( + vaultOptionTrades.map( + (trade) => Number(trade.premium) / Number(trade.vault.totalBalance) + ) + ); + const apyBase = annualizedWeeklyYield(avgWeeklyRet); + + const price = prices[vault.underlyingAsset]; + + let symbol = vault.symbol.replace('-THETA', '').slice(1); + symbol = symbol.includes('yvUSDC') ? 'USDC' : symbol; + + return { + pool: vault.id, + project: '3jane-options', + chain: 'Ethereum', + symbol, + tvlUsd: price * (vault.totalBalance / 10 ** vault.underlyingDecimals), + apy: apyBase * 100, + underlyingTokens: [vault.underlyingAsset], + poolMeta: vault.name.includes('Put') ? 'Put-Selling' : 'Covered-Call', + }; + }); + + return await Promise.all(pools); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.3jane.xyz/supply', +}; diff --git a/src/adaptors/3xcalibur/abi.json b/src/adaptors/3xcalibur/abi.json new file mode 100644 index 0000000000..540249de9b --- /dev/null +++ b/src/adaptors/3xcalibur/abi.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/3xcalibur/apy.ts b/src/adaptors/3xcalibur/apy.ts new file mode 100644 index 0000000000..de078fe45d --- /dev/null +++ b/src/adaptors/3xcalibur/apy.ts @@ -0,0 +1,141 @@ +const sdk = require('@defillama/sdk'); +const BN = require('bignumber.js'); +const utils = require('../utils'); + +const { getXCALPrice, getSwapPairs } = require('./subgraph'); +const GAUGE_ABI = require('./abi.json'); + +const STABLE_FEE_PERCENTAGE = 0.00369; +const VARIABLE_FEE_PERCENTAGE = 0.27; + +const CHAIN = 'arbitrum'; + +const XCAL_ADRESS = '0xd2568acCD10A4C98e87c44E9920360031ad89fCB'; + +const getApy = async () => { + try { + const [xcalPrice, pairs] = await Promise.all([ + getXCALPrice(), + getSwapPairs(), + ]); + let gaugePairs: any = []; + let nonGaugePairs: any = []; + const multicalls: any[] = []; + + _uniquePairs(pairs).forEach((pair: any) => { + if (pair.gaugeAddress) { + gaugePairs.push(pair); + + // construct rewardRate multicall + multicalls.push({ params: XCAL_ADRESS, target: pair.gaugeAddress }); + } else { + nonGaugePairs.push(pair); + } + }); + + const gaugesRewardRates = ( + await sdk.api.abi.multiCall({ + calls: multicalls, + + abi: GAUGE_ABI.find(({ name }) => name === 'rewardRate'), + chain: CHAIN, + }) + ).output.map(({ output }) => output); + + // gauge pairs apr/apy + gaugePairs = gaugePairs.map((pair: any, index: number) => { + const rewardRate = gaugesRewardRates[index].toString(); + const apr = _calculateGaugeAPR(pair.reserveUSD, xcalPrice, rewardRate); + const apy = _toApy(apr); + // apy might have 20+ decimals for low liq pool, just show apr instead + pair.apy = new BN(apy).gt(1_000_000) + ? Number(apr) + : new BN(apy).times(100).toNumber(); + return pair; + }); + // none-gauge pairs apr/apy + nonGaugePairs = nonGaugePairs.map((pair: any) => { + const apr = _calculateSwapFeeAPR( + pair.volumeUSD, + pair.reserveUSD, + pair.stable + ); + const apy = _toApy(apr); + // apy might have 20+ decimals for low liq pool, just show apr instead + pair.apy = new BN(apy).gt(1_000_000) + ? Number(apr) + : new BN(apy).times(100).toNumber(); + return pair; + }); + + return [...gaugePairs, ...nonGaugePairs] + .sort((a: any, b: any) => Number(b.reserveUSD) - Number(a.reserveUSD)) + .map(({ address, token0, token1, reserveUSD, apy, stable }: any) => ({ + pool: address, + chain: utils.formatChain('arbitrum'), + project: '3xcalibur', + symbol: `${token0.symbol}-${token1.symbol}`, + tvlUsd: Number(reserveUSD), + apyReward: apy, + underlyingTokens: [token0.address, token1.address], + rewardTokens: [XCAL_ADRESS], + url: `https://app.3xcalibur.com/swap/liquidity/add?asset0=${token0.address}&asset1=${token1.address}&stable=${stable}`, + })); + } catch (error) { + console.error('error@getApy', error); + return []; + } +}; + +const _uniquePairs = (pairs: any[]) => { + const existingPairs = new Set(); + return pairs + .sort((a: any, b: any) => Number(b.reserveUSD) - Number(a.reserveUSD)) // keep the highest tvl pairs + .filter((pair: any) => { + const symbol = `${pair.token0.symbol}_${pair.token1.symbol}`; + if (!existingPairs.has(symbol)) { + existingPairs.add(symbol); + return true; + } + return false; + }); +}; + +const _calculateSwapFeeAPR = ( + volumeUSD: string, + reserveUSD: string, + stable: boolean +) => { + const feeShare = new BN(volumeUSD) + .times(stable ? STABLE_FEE_PERCENTAGE : VARIABLE_FEE_PERCENTAGE) + .div(100); + const projectedYearlyFees = feeShare.times(365); + const feeAPR = projectedYearlyFees.div(reserveUSD).times(100).toFixed(); + + return feeAPR; +}; + +const _calculateGaugeAPR = ( + reserveUSD: string, + rewardRate: string, + xcalPrice: string +) => { + const gaugeAPR = new BN(rewardRate) + .div(1e18) + .times(3600 * 24 * 365) + .times(xcalPrice) + .div(reserveUSD) + .toFixed(18); + + return gaugeAPR; +}; + +const _toApy = (apr: string) => { + const anualCompounds = 365; // assume 1 compound per day + const leftSide = new BN(1).plus(new BN(apr).div(anualCompounds)); + return new BN(leftSide).pow(anualCompounds).minus(1).toFixed(18); +}; + +module.exports = { + getApy, +}; diff --git a/src/adaptors/3xcalibur/index.ts b/src/adaptors/3xcalibur/index.ts new file mode 100644 index 0000000000..a2350ef106 --- /dev/null +++ b/src/adaptors/3xcalibur/index.ts @@ -0,0 +1,7 @@ +const { getApy } = require('./apy'); + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.3xcalibur.com/swap/liquidity/add', +}; diff --git a/src/adaptors/3xcalibur/subgraph.ts b/src/adaptors/3xcalibur/subgraph.ts new file mode 100644 index 0000000000..91056703e5 --- /dev/null +++ b/src/adaptors/3xcalibur/subgraph.ts @@ -0,0 +1,55 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const XCAL_USDC_PAIR_ADRESS = '0x2Cc6AC1454490AfA83333Fabc84345FaD751285B'; +const SUBGRAPH_URL = sdk.graph.modifyEndpoint('J9xPBr2XdBxWvLi2HSiz8hW76HUU91WQ9ztkicCRccDS'); + +const swapPairsQuery = gql` + query PairsQuery { + pairs: swapPairs( + first: 1000 + orderBy: reserveUSD + orderDirection: desc + where: { reserve0_gt: 0.01, reserve1_gt: 0.01, reserveUSD_gt: 1000 } + ) { + address: id + token0 { + address: id + symbol + } + token1 { + address: id + symbol + } + stable + reserveUSD + volumeUSD + gaugeAddress + } + } +`; + +const swapPairQuery = gql` + query pairQuery($id: String!) { + pair: swapPair(id: $id) { + token1Price + } + } +`; + +const getSwapPairs = async () => { + const { pairs } = await request(SUBGRAPH_URL, swapPairsQuery, {}); + return pairs; +}; + +const getXCALPrice = async () => { + const { pair } = await request(SUBGRAPH_URL, swapPairQuery, { + id: XCAL_USDC_PAIR_ADRESS.toLowerCase(), + }); + return pair.token1Price; +}; + +module.exports = { + getSwapPairs, + getXCALPrice, +}; diff --git a/src/adaptors/40-acres/index.js b/src/adaptors/40-acres/index.js new file mode 100644 index 0000000000..8f00398998 --- /dev/null +++ b/src/adaptors/40-acres/index.js @@ -0,0 +1,57 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +async function getVault(timestamp, address, network, symbol, underlyingToken) { + const vaultInfo = await utils.getERC4626Info(address, network, timestamp); + const { tvl, ...rest } = vaultInfo; + return { + ...rest, + project: '40-acres', + symbol, + tvlUsd: tvl / 1e6, + underlyingTokens: [underlyingToken], + }; +}; + +const apy = async (timestamp) => { + const fortyAcresBasevault = await getVault( + timestamp, + '0xB99B6dF96d4d5448cC0a5B3e0ef7896df9507Cf5', + 'base', + '40base-USDC-Vault', + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913' + ); + + const fortyAcresOpvault = await getVault( + timestamp, + '0x08dCDBf7baDe91Ccd42CB2a4EA8e5D199d285957', + 'optimism', + '40op-USDC-Vault', + '0x0b2c639c533813f4aa9d7837caf62653d097ff85' + ); + + const fortyAcresAvaxVault = await getVault( + timestamp, + '0x124D00b1ce4453Ffc5a5F65cE83aF13A7709baC7', + 'avax', + '40avax-USDC-Vault', + '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' + ); + + const fortyAcresAvaxBlackholeVault = await getVault( + timestamp, + '0xC0485C4bafB594Ae1457820fb6e5B67e8A04BCFD', + 'avax', + '40avax-blackhole-USDC-Vault', + '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E' + ); + + return [fortyAcresBasevault, fortyAcresOpvault, fortyAcresAvaxVault, fortyAcresAvaxBlackholeVault]; +}; + +module.exports = { + timetravel: true, + apy, + url: 'https://www.40acres.finance/', +}; \ No newline at end of file diff --git a/src/adaptors/aave-v2/abiLendingPool.js b/src/adaptors/aave-v2/abiLendingPool.js new file mode 100644 index 0000000000..7c343d3410 --- /dev/null +++ b/src/adaptors/aave-v2/abiLendingPool.js @@ -0,0 +1,691 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/aave-v2/abiProtocolDataProvider.js b/src/adaptors/aave-v2/abiProtocolDataProvider.js new file mode 100644 index 0000000000..e7a171f8c1 --- /dev/null +++ b/src/adaptors/aave-v2/abiProtocolDataProvider.js @@ -0,0 +1,147 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/aave-v2/index.js b/src/adaptors/aave-v2/index.js new file mode 100644 index 0000000000..028663642e --- /dev/null +++ b/src/adaptors/aave-v2/index.js @@ -0,0 +1,149 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); + +const utils = require('../utils'); + +const chains = { + ethereum: { + LendingPool: '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9', + ProtocolDataProvider: '0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d', + url: 'mainnet', + }, + polygon: { + LendingPool: '0x8dff5e27ea6b7ac08ebfdf9eb090f32ee9a30fcf', + ProtocolDataProvider: '0x7551b5D2763519d4e37e8B81929D336De671d46d', + url: 'polygon', + }, + avalanche: { + LendingPool: '0x4F01AeD16D97E3aB5ab2B501154DC9bb0F1A5A2C', + ProtocolDataProvider: '0x65285E9dfab318f57051ab2b139ccCf232945451', + url: 'avalanche', + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain === 'avalanche' ? 'avax' : chain; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + permitFailure: true, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + const url = `https://app.aave.com/reserve-overview/?underlyingAsset=${t.toLowerCase()}&marketName=proto_${ + chains[chain].url + }`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'aave-v2', + chain, + tvlUsd, + apyBase, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/aave-v3/abi.js b/src/adaptors/aave-v3/abi.js new file mode 100644 index 0000000000..42fd722b87 --- /dev/null +++ b/src/adaptors/aave-v3/abi.js @@ -0,0 +1,4 @@ +module.exports = { + aTokenAbi: [{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"BalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlyingAsset","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"address","name":"incentivesController","type":"address"},{"indexed":false,"internalType":"uint8","name":"aTokenDecimals","type":"uint8"},{"indexed":false,"internalType":"string","name":"aTokenName","type":"string"},{"indexed":false,"internalType":"string","name":"aTokenSymbol","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ATOKEN_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_REVISION","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVE_TREASURY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_ASSET_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"receiverOfUnderlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getIncentivesController","outputs":[{"internalType":"contract IAaveIncentivesController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPreviousIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getScaledUserBalanceAndSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"handleRepayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"initializingPool","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"contract IAaveIncentivesController","name":"incentivesController","type":"address"},{"internalType":"uint8","name":"aTokenDecimals","type":"uint8"},{"internalType":"string","name":"aTokenName","type":"string"},{"internalType":"string","name":"aTokenSymbol","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mintToTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"scaledBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scaledTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAaveIncentivesController","name":"controller","type":"address"}],"name":"setIncentivesController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferOnLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferUnderlyingTo","outputs":[],"stateMutability":"nonpayable","type":"function"}], + aaveStakedTokenDataProviderAbi: [{"inputs":[{"internalType":"address","name":"stkAave","type":"address"},{"internalType":"address","name":"ethUsdPriceFeed","type":"address"},{"internalType":"address","name":"aaveUsdPriceFeed","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AAVE_USD_PRICE_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_PRICE_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKED_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakedAsset","type":"address"},{"internalType":"address","name":"oracle","type":"address"}],"name":"getStakedAssetData","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"stakedAssets","type":"address[]"},{"internalType":"address[]","name":"oracles","type":"address[]"}],"name":"getStakedAssetDataBatch","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakedAsset","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getStakedUserData","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"stakedTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"stakedTokenRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"underlyingTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"rewardsToClaim","type":"uint256"},{"internalType":"uint40","name":"userCooldownTimestamp","type":"uint40"},{"internalType":"uint216","name":"userCooldownAmount","type":"uint216"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenUserData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"stakedAssets","type":"address[]"},{"internalType":"address[]","name":"oracles","type":"address[]"},{"internalType":"address","name":"user","type":"address"}],"name":"getStakedUserDataBatch","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData[]","name":"","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"stakedTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"stakedTokenRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"underlyingTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"rewardsToClaim","type":"uint256"},{"internalType":"uint40","name":"userCooldownTimestamp","type":"uint40"},{"internalType":"uint216","name":"userCooldownAmount","type":"uint216"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenUserData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}] +} \ No newline at end of file diff --git a/src/adaptors/aave-v3/index.js b/src/adaptors/aave-v3/index.js new file mode 100755 index 0000000000..95f4b32f9f --- /dev/null +++ b/src/adaptors/aave-v3/index.js @@ -0,0 +1,256 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); +const { aaveStakedTokenDataProviderAbi } = require('./abi'); + +const GHO = '0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f'; + +const protocolDataProviders = { + ethereum: '0x497a1994c46d4f6C864904A9f1fac6328Cb7C8a6', + optimism: '0x14496b405D62c24F91f04Cda1c69Dc526D56fDE5', + arbitrum: '0x14496b405D62c24F91f04Cda1c69Dc526D56fDE5', + polygon: '0x14496b405D62c24F91f04Cda1c69Dc526D56fDE5', + avax: '0x14496b405D62c24F91f04Cda1c69Dc526D56fDE5', + metis: '0xbb4a3B6781be3650B252552dFF6332EfB1162152', + base: '0xC4Fcf9893072d61Cc2899C0054877Cb752587981', + xdai: '0xA2d323DBc43F445aD2d8974F17Be5dab32aAD474', + bsc: '0x1e26247502e90b4fab9D0d17e4775e90085D2A35', + scroll: '0xDC3c96ef82F861B4a3f10C81d4340c75460209ca', + era: '0xf79473ea6ef2C9537027bAe2f6E07d67dD9999E0', + lido: '0x66FeAe868EBEd74A34A7043e88742AAE00D2bC53', // on ethereum + etherfi: '0xECdA3F25B73261d1FdFa1E158967660AA29f00cC', // on ethereum + linea: '0x9eEBf28397D8bECC999472fC8838CBbeF54aebf6', + sonic: '0x306c124fFba5f2Bc0BcAf40D249cf19D492440b9', + celo: '0x33b7d355613110b4E842f5f7057Ccd36fb4cee28', + plasma: '0xf2D6E38B407e31E7E7e4a16E6769728b76c7419F', +}; + +const getApy = async (market) => { + const chain = ['lido', 'etherfi'].includes(market) ? 'ethereum' : market; + + const protocolDataProvider = protocolDataProviders[market]; + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .concat(`${chain}:${GHO}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const ghoSupply = + ( + await sdk.api.abi.call({ + target: GHO, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + if (pool.symbol === 'GHO') { + tvlUsd = 0; + totalSupplyUsd = tvlUsd; + totalBorrowUsd = ghoSupply * prices[`${chain}:${GHO}`]?.price; + } else { + totalBorrowUsd = totalSupplyUsd - tvlUsd; + } + + const marketUrlParam = + market === 'ethereum' + ? 'mainnet' + : market === 'avax' + ? 'avalanche' + : market === 'xdai' + ? 'gnosis' + : market === 'bsc' + ? 'bnb' + : market; + + const url = `https://app.aave.com/reserve-overview/?underlyingAsset=${pool.tokenAddress.toLowerCase()}&marketName=proto_${marketUrlParam}_v3`; + + return { + pool: `${aTokens[i].tokenAddress}-${ + market === 'avax' ? 'avalanche' : market + }`.toLowerCase(), + chain, + project: 'aave-v3', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd: pool.symbol === 'GHO' ? 1e8 : null, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + url, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + mintedCoin: pool.symbol === 'GHO' ? 'GHO' : null, + poolMeta: ['lido', 'etherfi'].includes(market) + ? `${market}-market` + : null, + }; + }) + .filter((i) => Boolean(i)); +}; + +const stkGho = async () => { + const convertStakedTokenApy = (rawApy) => { + const rawApyStringified = rawApy.toString(); + const lastTwoDigits = rawApyStringified.slice(-2); + const remainingDigits = rawApyStringified.slice(0, -2); + const result = `${remainingDigits}.${lastTwoDigits}`; + return Number(result); + }; + + const STKGHO = '0x1a88Df1cFe15Af22B3c4c783D4e6F7F9e0C1885d'; + const stkGhoTokenOracle = '0x3f12643d3f6f874d39c2a4c9f2cd6f2dbac877fc'; + const aaveStakedTokenDataProviderAddress = + '0xb12e82DF057BF16ecFa89D7D089dc7E5C1Dc057B'; + + const stkghoData = ( + await sdk.api.abi.call({ + target: aaveStakedTokenDataProviderAddress, + abi: aaveStakedTokenDataProviderAbi.find( + (m) => m.name === 'getStakedAssetData' + ), + params: [STKGHO, stkGhoTokenOracle], + chain: 'ethereum', + }) + ).output; + + const stkghoNativeApyRaw = stkghoData[6]; // 6th index of the tuple is the APY + const stkghoNativeApy = convertStakedTokenApy(stkghoNativeApyRaw); + + const stkghoMeritApy = ( + await axios.get('https://apps.aavechan.com/api/merit/aprs') + ).data.currentAPR.actionsAPR['ethereum-stkgho']; + + const stkghoApy = stkghoNativeApy + stkghoMeritApy; + + const stkghoSupply = + ( + await sdk.api.abi.call({ + target: STKGHO, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const ghoPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:${GHO}`) + ).data.coins[`ethereum:${GHO}`].price; + + const pool = { + pool: `${STKGHO}-ethereum`.toLowerCase(), + chain: 'Ethereum', + project: 'aave-v3', + symbol: 'sGHO', + tvlUsd: stkghoSupply * ghoPrice, + apy: stkghoApy, + url: 'https://app.aave.com/staking', + }; + + return pool; +}; + +const apy = async () => { + const pools = await Promise.allSettled( + Object.keys(protocolDataProviders).map(async (market) => getApy(market)) + ); + + const stkghoPool = await stkGho(); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .concat([stkghoPool]) + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/aave-v3/poolAbi.js b/src/adaptors/aave-v3/poolAbi.js new file mode 100644 index 0000000000..bba1c9dc38 --- /dev/null +++ b/src/adaptors/aave-v3/poolAbi.js @@ -0,0 +1,242 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/aave/index.js b/src/adaptors/aave/index.js deleted file mode 100755 index fc0cfd1cf5..0000000000 --- a/src/adaptors/aave/index.js +++ /dev/null @@ -1,129 +0,0 @@ -const { request, gql } = require('graphql-request'); - -const utils = require('../utils'); - -const baseUrl = 'https://api.thegraph.com/subgraphs/name/aave'; -const urlV2 = `${baseUrl}/protocol-v2`; -const urlPolygon = `${baseUrl}/aave-v2-matic`; -const urlAvalanche = 'https://aave-api-v2.aave.com/data/markets-data'; - -const query = gql` - { - reserves { - id - name - symbol - decimals - liquidityRate - aEmissionPerSecond - totalATokenSupply - price { - priceInEth - } - } - } -`; - -const tvl = (entry, ethPriceUSD) => { - entry = { ...entry }; - const totalATokenSupply = Number(entry.totalATokenSupply); - const totalATokenSupplyNormalised = totalATokenSupply / 10 ** entry.decimals; - - entry.totalLiquidityUSD = - totalATokenSupplyNormalised * - (Number(entry.price.priceInEth) / 1e18) * - ethPriceUSD; - - return entry; -}; - -const apy = (entry, rewardTokenPriceInEth) => { - entry = { ...entry }; - - entry.incentive_apy = 0; - if (entry.aEmissionPerSecond !== '0') { - const SECONDS_PER_YEAR = 3.154e7; - const REWARD_TOKEN_DECIMALS = 18; - - const tokenDecimals = entry.decimals; - const aEmissionPerSecond = Number(entry.aEmissionPerSecond); - const tokenPriceInEth = Number(entry.price.priceInEth); - - const num = - aEmissionPerSecond * - SECONDS_PER_YEAR * - rewardTokenPriceInEth * - 10 ** tokenDecimals; - const denom = - entry.totalATokenSupply * tokenPriceInEth * 10 ** REWARD_TOKEN_DECIMALS; - - entry.incentive_apy = 100 * (num / denom); - } - return entry; -}; - -const buildPool = (entry, chainString) => { - let apy; - if (chainString === 'avalanche') { - apy = (Number(entry.liquidityRate) + Number(entry.aIncentivesAPY)) * 100; - } else { - apy = Number(entry.liquidityRate) / 1e25 + entry.incentive_apy; - } - - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'aave', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.totalLiquidityUSD, - apy, - }; - - return newObj; -}; - -const topLvl = async (chainString, url, rewardTokenString = null) => { - let data = []; - if (chainString === 'avalanche') { - data = await utils.getData(url); - - // filter to specific id only - data = data.reserves.filter((el) => el.id.endsWith('ce3ede02a318f')); - } else { - // get asset price in usd - let price = await utils.getCGpriceData('ethereum', true); - - // pull data - data = await request(url, query); - - // calculate tvl in usd - data = data.reserves.map((el) => tvl(el, price['ethereum'].usd)); - - // calculate apy - // get rewardToken price in eth (for incentivsed rewards) - const priceInEthRewardToken = Number( - data.find((el) => el.symbol === rewardTokenString.toUpperCase()).price - .priceInEth - ); - data = data.map((el) => apy(el, priceInEthRewardToken)); - } - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async () => { - const data = await Promise.all([ - topLvl('ethereum', urlV2, 'aave'), - topLvl('polygon', urlPolygon, 'wmatic'), - topLvl('avalanche', urlAvalanche), - ]); - - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/abracadabra-spell/abis/BaseStargateLPStrategy.json b/src/adaptors/abracadabra-spell/abis/BaseStargateLPStrategy.json new file mode 100644 index 0000000000..5f54a38828 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/BaseStargateLPStrategy.json @@ -0,0 +1,440 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_strategyToken", + "type": "address" + }, + { "internalType": "address", "name": "_bentoBox", "type": "address" }, + { + "internalType": "contract IStargateRouter", + "name": "_router", + "type": "address" + }, + { "internalType": "uint256", "name": "_poolId", "type": "uint256" }, + { + "internalType": "contract ILPStaking", + "name": "_staking", + "type": "address" + }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeCollector", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "FeeParametersChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "server", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "LogConvert", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "name": "LogSetStrategyExecutor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "total", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "strategyAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "LpMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "STGPOOL", + "outputs": [ + { "internalType": "contract ICurvePool", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "THREEPOOL", + "outputs": [ + { + "internalType": "contract ICurveThreePool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDC", + "outputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDT", + "outputs": [ + { "internalType": "contract Tether", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "afterExit", + "outputs": [{ "internalType": "bool", "name": "success", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bentoBox", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridgeToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "balance", "type": "uint256" } + ], + "name": "exit", + "outputs": [ + { "internalType": "int256", "name": "amountAdded", "type": "int256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exited", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeCollector", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feePercent", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "balance", "type": "uint256" }, + { "internalType": "address", "name": "sender", "type": "address" } + ], + "name": "harvest", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxBentoBoxBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "router", + "outputs": [ + { + "internalType": "contract IStargateRouter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "maxBalance", "type": "uint256" }, + { "internalType": "bool", "name": "rebalance", "type": "bool" }, + { + "internalType": "uint256", + "name": "maxChangeAmount", + "type": "uint256" + }, + { "internalType": "bool", "name": "harvestRewards", "type": "bool" } + ], + "name": "safeHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeCollector", "type": "address" }, + { "internalType": "uint8", "name": "_feePercent", "type": "uint8" } + ], + "name": "setFeeParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "executor", "type": "address" }, + { "internalType": "bool", "name": "value", "type": "bool" } + ], + "name": "setStrategyExecutor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { "internalType": "contract ILPStaking", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stargateToken", + "outputs": [ + { + "internalType": "contract IStargateToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "strategyExecutors", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "strategyToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" }, + { "internalType": "address", "name": "inputToken", "type": "address" } + ], + "name": "swapExactTokensForUnderlying", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" } + ], + "name": "swapToLP", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "actualAmount", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/BentoBoxV1.json b/src/adaptors/abracadabra-spell/abis/BentoBoxV1.json new file mode 100644 index 0000000000..66ffd477d7 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/BentoBoxV1.json @@ -0,0 +1,1154 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "wethToken_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": true, + "internalType": "address", + "name": "cloneAddress", + "type": "address" + } + ], + "name": "LogDeploy", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "LogDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "LogFlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protocol", + "type": "address" + } + ], + "name": "LogRegisterProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "LogSetMasterContractApproval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LogStrategyDivest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LogStrategyInvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LogStrategyLoss", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LogStrategyProfit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IStrategy", + "name": "strategy", + "type": "address" + } + ], + "name": "LogStrategyQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IStrategy", + "name": "strategy", + "type": "address" + } + ], + "name": "LogStrategySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "targetPercentage", + "type": "uint256" + } + ], + "name": "LogStrategyTargetPercentage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "LogTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "LogWhiteListMasterContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "LogWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "calls", + "type": "bytes[]" + }, + { + "internalType": "bool", + "name": "revertOnFail", + "type": "bool" + } + ], + "name": "batch", + "outputs": [ + { + "internalType": "bool[]", + "name": "successes", + "type": "bool[]" + }, + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBatchFlashBorrower", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address[]", + "name": "receivers", + "type": "address[]" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "batchFlashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "useCreate2", + "type": "bool" + } + ], + "name": "deploy", + "outputs": [ + { + "internalType": "address", + "name": "cloneAddress", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token_", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shareOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFlashBorrower", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "bool", + "name": "balance", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "maxChangeAmount", + "type": "uint256" + } + ], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "masterContractApproved", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "masterContractOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "pendingStrategy", + "outputs": [ + { + "internalType": "contract IStrategy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registerProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "setMasterContractApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "contract IStrategy", + "name": "newStrategy", + "type": "address" + } + ], + "name": "setStrategy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint64", + "name": "targetPercentage_", + "type": "uint64" + } + ], + "name": "setStrategyTargetPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "strategy", + "outputs": [ + { + "internalType": "contract IStrategy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "strategyData", + "outputs": [ + { + "internalType": "uint64", + "name": "strategyStartDate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "targetPercentage", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "balance", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "toAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "toShare", + "outputs": [ + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "totals", + "outputs": [ + { + "internalType": "uint128", + "name": "elastic", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "base", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tos", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "shares", + "type": "uint256[]" + } + ], + "name": "transferMultiple", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "direct", + "type": "bool" + }, + { + "internalType": "bool", + "name": "renounce", + "type": "bool" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "masterContract", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "whitelistMasterContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedMasterContracts", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token_", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shareOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/CauldronV2.json b/src/adaptors/abracadabra-spell/abis/CauldronV2.json new file mode 100644 index 0000000000..f22f716562 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/CauldronV2.json @@ -0,0 +1,730 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBentoBoxV1", + "name": "bentoBox_", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "magicInternetMoney_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint128", + "name": "accruedAmount", + "type": "uint128" + } + ], + "name": "LogAccrue", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "LogAddCollateral", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "part", + "type": "uint256" + } + ], + "name": "LogBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "LogExchangeRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newFeeTo", + "type": "address" + } + ], + "name": "LogFeeTo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "LogRemoveCollateral", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "part", + "type": "uint256" + } + ], + "name": "LogRepay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeTo", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesEarnedFraction", + "type": "uint256" + } + ], + "name": "LogWithdrawFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "BORROW_OPENING_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "COLLATERIZATION_RATE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LIQUIDATION_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInfo", + "outputs": [ + { + "internalType": "uint64", + "name": "lastAccrued", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "feesEarned", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "INTEREST_PER_SECOND", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bool", + "name": "skim", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "addCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bentoBox", + "outputs": [ + { + "internalType": "contract IBentoBoxV1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "part", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "collateral", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8[]", + "name": "actions", + "type": "uint8[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes[]", + "name": "datas", + "type": "bytes[]" + } + ], + "name": "cook", + "outputs": [ + { + "internalType": "uint256", + "name": "value1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value2", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "users", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "maxBorrowParts", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "contract ISwapper", + "name": "swapper", + "type": "address" + } + ], + "name": "liquidate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "magicInternetMoney", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterContract", + "outputs": [ + { + "internalType": "contract CauldronV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracleData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "reduceSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "name": "removeCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bool", + "name": "skim", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "part", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newFeeTo", + "type": "address" + } + ], + "name": "setFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrow", + "outputs": [ + { + "internalType": "uint128", + "name": "elastic", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "base", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalCollateralShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "direct", + "type": "bool" + }, + { + "internalType": "bool", + "name": "renounce", + "type": "bool" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateExchangeRate", + "outputs": [ + { + "internalType": "bool", + "name": "updated", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userBorrowPart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userCollateralShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/ERC4626.json b/src/adaptors/abracadabra-spell/abis/ERC4626.json new file mode 100644 index 0000000000..733c6acf3d --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/ERC4626.json @@ -0,0 +1,460 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [{ "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "name": "balance", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "owner", "type": "address" }, + { "indexed": true, "name": "spender", "type": "address" }, + { "indexed": false, "name": "value", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "from", "type": "address" }, + { "indexed": true, "name": "to", "type": "address" }, + { "indexed": false, "name": "value", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "name": "asset", + "type": "function", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "name": "assetTokenAddress", + "type": "address" + } + ] + }, + { + "name": "totalAssets", + "type": "function", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "name": "totalManagedAssets", + "type": "uint256" + } + ] + }, + { + "name": "convertToShares", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "convertToAssets", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "maxDeposit", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxAssets", + "type": "uint256" + } + ] + }, + { + "name": "previewDeposit", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "deposit", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "assets", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "maxMint", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxShares", + "type": "uint256" + } + ] + }, + { + "name": "previewMint", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "mint", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "shares", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "maxWithdraw", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxAssets", + "type": "uint256" + } + ] + }, + { + "name": "previewWithdraw", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "withdraw", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "assets", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + }, + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "maxRedeem", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxShares", + "type": "uint256" + } + ] + }, + { + "name": "previewRedeem", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "redeem", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "shares", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + }, + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "Deposit", + "type": "event", + "inputs": [ + { + "name": "_caller", + "indexed": true, + "type": "address" + }, + { + "name": "owner", + "indexed": true, + "type": "address" + }, + { + "name": "assets", + "indexed": false, + "type": "uint256" + }, + { + "name": "shares", + "indexed": false, + "type": "uint256" + } + ] + }, + { + "name": "Withdraw", + "type": "event", + "inputs": [ + { + "name": "_caller", + "indexed": true, + "type": "address" + }, + { + "name": "receiver", + "indexed": true, + "type": "address" + }, + { + "name": "owner", + "indexed": true, + "type": "address" + }, + { + "name": "assets", + "indexed": false, + "type": "uint256" + }, + { + "name": "shares", + "indexed": false, + "type": "uint256" + } + ] + } +] diff --git a/src/adaptors/abracadabra-spell/abis/FeeCollectable.json b/src/adaptors/abracadabra-spell/abis/FeeCollectable.json new file mode 100644 index 0000000000..d4a7cb5f37 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/FeeCollectable.json @@ -0,0 +1,112 @@ +[ + { + "inputs": [], + "name": "ErrInvalidFeeBips", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "ErrInvalidFeeOperator", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousFeeCollector", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "previousFeeAmount", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "feeCollector", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "feeAmount", + "type": "uint16" + } + ], + "name": "LogFeeParametersChanged", + "type": "event" + }, + { + "inputs": [], + "name": "feeBips", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeCollector", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isFeeOperator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeCollector", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_feeBips", + "type": "uint16" + } + ], + "name": "setFeeParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/GlpManager.json b/src/adaptors/abracadabra-spell/abis/GlpManager.json new file mode 100644 index 0000000000..fbf987211b --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/GlpManager.json @@ -0,0 +1,431 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_vault", "type": "address" }, + { "internalType": "address", "name": "_usdg", "type": "address" }, + { "internalType": "address", "name": "_glp", "type": "address" }, + { + "internalType": "address", + "name": "_shortsTracker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_cooldownDuration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aumInUsdg", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "glpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "usdgAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "AddLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "glpAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aumInUsdg", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "glpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "usdgAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "RemoveLiquidity", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GLP_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_COOLDOWN_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDG_DECIMALS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_minUsdg", "type": "uint256" }, + { "internalType": "uint256", "name": "_minGlp", "type": "uint256" } + ], + "name": "addLiquidity", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fundingAccount", + "type": "address" + }, + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_minUsdg", "type": "uint256" }, + { "internalType": "uint256", "name": "_minGlp", "type": "uint256" } + ], + "name": "addLiquidityForAccount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "aumAddition", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aumDeduction", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cooldownDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "maximise", "type": "bool" }], + "name": "getAum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "maximise", "type": "bool" }], + "name": "getAumInUsdg", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAums", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "getGlobalShortAveragePrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_price", "type": "uint256" }, + { "internalType": "uint256", "name": "_size", "type": "uint256" } + ], + "name": "getGlobalShortDelta", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_maximise", "type": "bool" }], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "glp", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateMode", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isHandler", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "lastAddedAt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tokenOut", "type": "address" }, + { "internalType": "uint256", "name": "_glpAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_minOut", "type": "uint256" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "removeLiquidity", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_tokenOut", "type": "address" }, + { "internalType": "uint256", "name": "_glpAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_minOut", "type": "uint256" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "removeLiquidityForAccount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_aumAddition", "type": "uint256" }, + { "internalType": "uint256", "name": "_aumDeduction", "type": "uint256" } + ], + "name": "setAumAdjustment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_cooldownDuration", + "type": "uint256" + } + ], + "name": "setCooldownDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gov", "type": "address" } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_handler", "type": "address" }, + { "internalType": "bool", "name": "_isActive", "type": "bool" } + ], + "name": "setHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_inPrivateMode", "type": "bool" } + ], + "name": "setInPrivateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IShortsTracker", + "name": "_shortsTracker", + "type": "address" + } + ], + "name": "setShortsTracker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_shortsTrackerAveragePriceWeight", + "type": "uint256" + } + ], + "name": "setShortsTrackerAveragePriceWeight", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortsTracker", + "outputs": [ + { + "internalType": "contract IShortsTracker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "shortsTrackerAveragePriceWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usdg", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { "internalType": "contract IVault", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/InterestStrategy.json b/src/adaptors/abracadabra-spell/abis/InterestStrategy.json new file mode 100644 index 0000000000..796326530a --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/InterestStrategy.json @@ -0,0 +1,868 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_strategyToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_mim", + "type": "address" + }, + { + "internalType": "contract IBentoBoxV1", + "name": "_bentoBox", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeTo", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InsufficientAmountOut", + "type": "error" + }, + { + "inputs": [], + "name": "InsupportedToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFeeTo", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInterestRate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLerpParameters", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMaxInterestPerSecond", + "type": "error" + }, + { + "inputs": [], + "name": "SwapFailed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "EmergencyExitEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previous", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "current", + "type": "address" + } + ], + "name": "FeeToChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "accruedAmount", + "type": "uint256" + } + ], + "name": "LogAccrue", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "interestPerSecond", + "type": "uint64" + } + ], + "name": "LogInterestChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "startInterestPerSecond", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "targetInterestPerSecond", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "duration", + "type": "uint64" + } + ], + "name": "LogInterestWithLerpChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "name": "LogSetStrategyExecutor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + } + ], + "name": "SwapAndWithdrawFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "SwapTokenOutEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previous", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "current", + "type": "address" + } + ], + "name": "SwapperChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawFee", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "afterExit", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "availableAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bentoBox", + "outputs": [ + { + "internalType": "contract IBentoBoxV1", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyExitEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "exit", + "outputs": [ + { + "internalType": "int256", + "name": "amountAdded", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exited", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getYearlyInterestBips", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "harvest", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interestLerp", + "outputs": [ + { + "internalType": "uint64", + "name": "startTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "startInterestPerSecond", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "targetInterestPerSecond", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "duration", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestPerSecond", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastAccrued", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxBentoBoxBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeEarned", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeEarnedAdjustement", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "principal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxBalance", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "rebalance", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "maxChangeAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "harvestRewards", + "type": "bool" + } + ], + "name": "safeHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_emergencyExitEnabled", + "type": "bool" + } + ], + "name": "setEmergencyExitEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeTo", + "type": "address" + } + ], + "name": "setFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_interestPerSecond", + "type": "uint64" + } + ], + "name": "setInterestPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "startInterestPerSecond", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "targetInterestPerSecond", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "duration", + "type": "uint64" + } + ], + "name": "setInterestPerSecondWithLerp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "internalType": "bool", + "name": "value", + "type": "bool" + } + ], + "name": "setStrategyExecutor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "setSwapTokenOutEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_swapper", + "type": "address" + } + ], + "name": "setSwapper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "strategyExecutors", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "strategyToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swapAndwithdrawFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "swapTokenOutEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "swapper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "direct", + "type": "bool" + }, + { + "internalType": "bool", + "name": "renounce", + "type": "bool" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "actualAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/MagicGlpHarvestor.json b/src/adaptors/abracadabra-spell/abis/MagicGlpHarvestor.json new file mode 100644 index 0000000000..b994d85725 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/MagicGlpHarvestor.json @@ -0,0 +1,321 @@ +[ + { + "inputs": [ + { + "internalType": "contract IWETHAlike", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "contract IGmxRewardRouterV2", + "name": "_rewardRouterV2", + "type": "address" + }, + { + "internalType": "contract IGmxGlpRewardRouter", + "name": "_glpRewardRouter", + "type": "address" + }, + { + "internalType": "contract IMagicGlpRewardHandler", + "name": "_vault", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useDistributeRewardsFeature", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "ErrInvalidFeePercent", "type": "error" }, + { "inputs": [], "name": "ErrNotRewardToken", "type": "error" }, + { "inputs": [], "name": "NotAllowedOperator", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeCollector", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "feeAmount", + "type": "uint16" + } + ], + "name": "LogFeeParametersChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "total", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "LogHarvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IGmxRewardRouterV2", + "name": "", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IGmxRewardRouterV2", + "name": "", + "type": "address" + } + ], + "name": "LogRewardRouterV2Changed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "", + "type": "address" + }, + { "indexed": false, "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "OperatorChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "BIPS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeCollector", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feePercentBips", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "glpRewardRouter", + "outputs": [ + { + "internalType": "contract IGmxGlpRewardRouter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastExecution", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "operators", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRouterV2", + "outputs": [ + { + "internalType": "contract IGmxRewardRouterV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IWETHAlike", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "minGlp", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardAmount", "type": "uint256" } + ], + "name": "run", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeCollector", "type": "address" }, + { "internalType": "uint16", "name": "_feePercentBips", "type": "uint16" } + ], + "name": "setFeeParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "status", "type": "bool" } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IGmxRewardRouterV2", + "name": "_rewardRouterV2", + "type": "address" + } + ], + "name": "setRewardRouterV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalRewardsBalanceAfterClaiming", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" }, + { "internalType": "bool", "name": "direct", "type": "bool" }, + { "internalType": "bool", "name": "renounce", "type": "bool" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "useDistributeRewardsFeature", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract IMagicGlpRewardHandler", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/abracadabra-spell/abis/MarketLens.json b/src/adaptors/abracadabra-spell/abis/MarketLens.json new file mode 100644 index 0000000000..1008bad3cb --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/MarketLens.json @@ -0,0 +1,754 @@ +[ + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getBorrowFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getCollateralPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getHealthFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getInterestPerYear", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getLiquidationFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMarketInfoCauldronV2", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumCollateralRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketMaxBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "userMaxBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oracleExchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralPrice", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "totalCollateral", + "type": "tuple" + } + ], + "internalType": "struct MarketLens.MarketInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV3", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMarketInfoCauldronV3", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumCollateralRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketMaxBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "userMaxBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oracleExchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralPrice", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "totalCollateral", + "type": "tuple" + } + ], + "internalType": "struct MarketLens.MarketInfo", + "name": "marketInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMaxMarketBorrowForCauldronV2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV3", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMaxMarketBorrowForCauldronV3", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMaxUserBorrowForCauldronV2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV3", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMaxUserBorrowForCauldronV3", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getMaximumCollateralRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getOracleExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBentoBoxV1", + "name": "bentoBox", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getTokenInBentoBox", + "outputs": [ + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getTotalBorrowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + } + ], + "name": "getTotalCollateral", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserCollateral", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserLiquidationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidationPrice", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserLtv", + "outputs": [ + { + "internalType": "uint256", + "name": "ltvBps", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserMaxBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getUserPosition", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "ltvBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowValue", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "collateral", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "liquidationPrice", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.UserPosition", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICauldronV2", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + } + ], + "name": "getUserPositions", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "cauldron", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "ltvBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowValue", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.AmountValue", + "name": "collateral", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "liquidationPrice", + "type": "uint256" + } + ], + "internalType": "struct MarketLens.UserPosition[]", + "name": "positions", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/MultiRewardsStaking.json b/src/adaptors/abracadabra-spell/abis/MultiRewardsStaking.json new file mode 100644 index 0000000000..ba5132e563 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/MultiRewardsStaking.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrInvalidTokenAddress","type":"error"},{"inputs":[],"name":"ErrRewardAlreadyAdded","type":"error"},{"inputs":[],"name":"ErrRewardPeriodStillActive","type":"error"},{"inputs":[],"name":"ErrZeroAmount","type":"error"},{"inputs":[],"name":"ErrZeroDuration","type":"error"},{"inputs":[],"name":"NotAllowedOperator","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"LogRewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"LogRewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"LogRewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"},{"indexed":false,"internalType":"bool","name":"","type":"bool"}],"name":"OperatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"rewardToken","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"}],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokenLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"}],"name":"isSupportedReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rewardData","outputs":[{"components":[{"internalType":"uint256","name":"rewardsDuration","type":"uint256"},{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"}],"internalType":"struct MultiRewards.Reward","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/adaptors/abracadabra-spell/abis/RewardTracker.json b/src/adaptors/abracadabra-spell/abis/RewardTracker.json new file mode 100644 index 0000000000..ecc499f3c8 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/RewardTracker.json @@ -0,0 +1,493 @@ +[ + { + "inputs": [ + { "internalType": "string", "name": "_name", "type": "string" }, + { "internalType": "string", "name": "_symbol", "type": "string" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BASIS_POINTS_DIVISOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "address", "name": "_spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_spender", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "averageStakedAmounts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "claim", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "claimForAccount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimableReward", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cumulativeRewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "cumulativeRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "depositBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateClaimingMode", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateStakingMode", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateTransferMode", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_depositTokens", + "type": "address[]" + }, + { "internalType": "address", "name": "_distributor", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isDepositToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isHandler", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "previousCumulatedRewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_depositToken", "type": "address" }, + { "internalType": "bool", "name": "_isDepositToken", "type": "bool" } + ], + "name": "setDepositToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gov", "type": "address" } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_handler", "type": "address" }, + { "internalType": "bool", "name": "_isActive", "type": "bool" } + ], + "name": "setHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateClaimingMode", + "type": "bool" + } + ], + "name": "setInPrivateClaimingMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateStakingMode", + "type": "bool" + } + ], + "name": "setInPrivateStakingMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateTransferMode", + "type": "bool" + } + ], + "name": "setInPrivateTransferMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_depositToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fundingAccount", + "type": "address" + }, + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_depositToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "stakeForAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "stakedAmounts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "totalDepositSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_recipient", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_sender", "type": "address" }, + { "internalType": "address", "name": "_recipient", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_depositToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_depositToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "unstakeForAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/Sorbettiere.json b/src/adaptors/abracadabra-spell/abis/Sorbettiere.json new file mode 100644 index 0000000000..7980bda3c2 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/Sorbettiere.json @@ -0,0 +1,518 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_ice", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_icePerSecond", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_startTime", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_allocPoint", + "type": "uint16" + }, + { + "internalType": "contract IERC20", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "addSeconds", + "type": "uint32" + } + ], + "name": "changeEndTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "endTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ice", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "icePerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingIce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakingTokenTotalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accIcePerShare", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "lastRewardTime", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "allocPoint", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_allocPoint", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_icePerSecond", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "setIcePerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "direct", + "type": "bool" + }, + { + "internalType": "bool", + "name": "renounce", + "type": "bool" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "remainingIceTokenReward", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/abis/UniswapV2Pair.json b/src/adaptors/abracadabra-spell/abis/UniswapV2Pair.json new file mode 100644 index 0000000000..97ce5ca158 --- /dev/null +++ b/src/adaptors/abracadabra-spell/abis/UniswapV2Pair.json @@ -0,0 +1,658 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/abracadabra-spell/cauldrons.js b/src/adaptors/abracadabra-spell/cauldrons.js new file mode 100644 index 0000000000..cd4d0a14c3 --- /dev/null +++ b/src/adaptors/abracadabra-spell/cauldrons.js @@ -0,0 +1,749 @@ +const { + utils: { formatEther, formatUnits }, +} = require('ethers'); +const _ = require('lodash'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const utils = require('../utils'); +const MARKET_LENS_ABI = require('./abis/MarketLens.json'); +const CAULDRON_V2_ABI = require('./abis/CauldronV2.json'); +const BENTOBOX_V1_ABI = require('./abis/BentoBoxV1.json'); +const INTEREST_STRATEGY = require('./abis/InterestStrategy.json'); +const BASE_STARGATE_LP_STRATEGY = require('./abis/BaseStargateLPStrategy.json'); +const FEE_COLLECTABLE_STRATEGY = require('./abis/FeeCollectable.json'); + +const MIM_COINGECKO_ID = 'magic-internet-money'; + +const POOLS = { + arbitrum: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { version: 2, address: '0xc89958b03a55b5de2221acb25b58b89a000215e6' }, // wETH + { version: 4, address: '0x5698135ca439f21a57bddbe8b582c62f090406d5' }, // GLP + { + version: 4, + address: '0x726413d7402ff180609d0ebc79506df8633701b1', + collateralPoolId: 'a4bcffaa-3b75-436c-b6c2-7b1c3840d041' + }, // magicGLP + { + version: 4, + address: '0x7962acfcfc2ccebc810045391d60040f635404fb', + collateralPoolId: '906b233c-8478-4b94-94e5-2d77e6c7c9e5', + symbol: "SOL-USDC", + }, // gmSOLUSDC + { + version: 4, + address: '0x2b02bBeAb8eCAb792d3F4DDA7a76f63Aa21934FA', + collateralPoolId: '61b4c35c-97f6-4c05-a5ff-aeb4426adf5b', + symbol: "ETH-USDC", + }, // gmETHUSDC + { + version: 4, + address: '0xD7659D913430945600dfe875434B6d80646d552A', + collateralPoolId: '5b8c0691-b9ff-4d82-97e4-19a1247e6dbf', + symbol: "WBTC.B-USDC", + }, // gmBTCUSDC + { + version: 4, + address: '0x4F9737E994da9811B8830775Fd73E2F1C8e40741', + collateralPoolId: 'f3fa942f-1867-4028-95ff-4eb76816cd07', + symbol: "ARB-USDC", + }, // gmARBUSDC + { + version: 4, + address: '0x66805F6e719d7e67D46e8b2501C1237980996C6a', + collateralPoolId: 'dffb3514-d667-4f2f-8df3-f716ebe09c93', + symbol: "LINK-USDC", + }, // gmLINKUSDC + { + version: 4, + address: '0x9fF8b4C842e4a95dAB5089781427c836DAE94831', + collateralPoolId: 'ffb4e407-6507-4615-b776-a0d99cfc1bbb', + symbol: "WBTC.B-WBTC.B", + }, // gmBTC + { + version: 4, + address: '0x625Fe79547828b1B54467E5Ed822a9A8a074bD61', + collateralPoolId: '5e2aac09-71c8-4092-ba4f-00f1ac0d04fd', + symbol: "ETH-ETH", + }, // gmETH + { version: 4, address: '0x49De724D7125641F56312EBBcbf48Ef107c8FA57' }, // WBTC + { version: 4, address: '0x780db9770dDc236fd659A39430A8a7cC07D0C320' }, // WETHV2 + ], + }, + avax: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { version: 2, address: '0x3cfed0439ab822530b1ffbd19536d897ef30d2a2' }, // AVAX + { version: 2, address: '0x56984f04d2d04b2f63403f0ebedd3487716ba49d' }, // wMEMO (deprecated) + { version: 2, address: '0x3b63f81ad1fc724e44330b4cf5b5b6e355ad964b' }, // xJOE + { version: 2, address: '0x35fa7a723b3b39f15623ff1eb26d8701e7d6bb21' }, // wMEMO + { version: 2, address: '0x95cce62c3ecd9a33090bbf8a9eac50b699b54210' }, // USDC/AVAX JLP + { version: 2, address: '0x0a1e6a80e93e62bd0d3d3bfcf4c362c40fb1cf3d' }, // USDT/AVAX JLP + { version: 2, address: '0x2450bf8e625e98e14884355205af6f97e3e68d07' }, // MIM/AVAX JLP + { version: 2, address: '0xacc6821d0f368b02d223158f8ada4824da9f28e3' }, // MIM/AVAX SLP + ], + }, + bsc: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { version: 2, address: '0x692cf15f80415d83e8c0e139cabcda67fcc12c90' }, // wBNB + { version: 2, address: '0xf8049467f3a9d50176f4816b20cddd9bb8a93319' }, // CAKE + ], + }, + ethereum: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { + version: 1, + address: '0xbb02a884621fb8f5bfd263a67f58b65df5b090f3', + interestPerYear: 150, + maximumCollateralRatio: 7500, + }, // xSUSHI (deprecated) + { + version: 1, + address: '0x6ff9061bb8f97d948942cef376d98b51fa38b91f', + interestPerYear: 150, + maximumCollateralRatio: 7500, + }, // yvWETH (deprecated) + { + version: 1, + address: '0xffbf4892822e0d552cff317f65e1ee7b5d3d9ae6', + interestPerYear: 150, + maximumCollateralRatio: 7500, + }, // yvYFI (deprecated) + { version: 2, address: '0xc1879bf24917ebe531fbaa20b0d05da027b592ce' }, // AGLD + { version: 2, address: '0x7b7473a76d6ae86ce19f7352a1e89f6c9dc39020' }, // ALCX + { version: 2, address: '0x05500e2ee779329698df35760bedcaac046e7c27' }, // FTM + { version: 2, address: '0x98a84eff6e008c5ed0289655ccdca899bcb6b99f' }, // xSUSHI v3 + { version: 2, address: '0x0bf90b3b5cad7dfcf70de198c498b61b3ba35cff' }, // xSUSHI v2 + { version: 2, address: '0x0bca8ebcb26502b013493bf8fe53aa2b1ed401c1' }, // yvstETH (deprecated) + { version: 2, address: '0x5db0ebf9feeecfd0ee82a4f27078dbce7b4cd1dc' }, // sSPELL + { version: 2, address: '0xc319eea1e792577c319723b5e60a15da3857e7da' }, // sSPELL v2 (deprecated) + { version: 2, address: '0x252dcf1b621cc53bc22c256255d2be5c8c32eae4' }, // SHIB + { version: 2, address: '0x9617b633ef905860d919b88e1d9d9a6191795341' }, // FTT + { version: 2, address: '0xcfc571f3203756319c231d3bc643cee807e74636' }, // SPELL (DegenBox) + { version: 2, address: '0xbc36fde44a7fd8f545d459452ef9539d7a14dd63' }, // UST V1 (deprecated) + // { version: 2, address: '0x59e9082e068ddb27fc5ef1690f9a9f22b32e573f' }, // UST V2 (deprecated + { version: 2, address: '0x390db10e65b5ab920c19149c919d970ad9d18a41' }, // WETH + { version: 2, address: '0x5ec47ee69bede0b6c2a2fc0d9d094df16c192498' }, // WBTC + { version: 2, address: '0xf179fe36a36b32a4644587b8cdee7a23af98ed37' }, // yvCVXETH + { version: 2, address: '0x6371efe5cd6e3d2d7c477935b7669401143b7985' }, // cvx3pool (deprecated) + { + version: 3, + address: '0x7ce7d9ed62b9a6c5ace1c6ec9aeb115fa3064757', + collateralPoolId: '7be3388a-0591-4281-a6f3-eff3217693fa', + }, // yvDAI + { + version: 3, + address: '0x53375add9d2dfe19398ed65baaeffe622760a9a6', + cauldronMeta: 'Whitelisted', + }, // yvstETH Concentrated (deprecated) + { version: 3, address: '0xd31e19a0574dbf09310c3b06f3416661b4dc7324' }, // Stargate USDC + { + version: 3, + address: '0xc6b2b3fe7c3d7a6f823d9106e22e66660709001e', + collateralPoolId: '07d379c9-2c9d-4abd-9b23-18c379f1ff5b', + }, // Stargate USDT + { version: 3, address: '0x8227965a7f42956549afaec319f4e444aa438df5' }, // LUSD + { + version: 4, + address: '0x1062eb452f8c7a94276437ec1f4aaca9b1495b72', + cauldronMeta: 'Whitelisted', + collateralPoolId: '07d379c9-2c9d-4abd-9b23-18c379f1ff5b', + }, // Stargate USDT (POF) + { version: 4, address: '0x207763511da879a900973a5e092382117c3c1588' }, // CRV + { version: 4, address: '0x85f60d3ea4e86af43c9d4e9cc9095281fc25c405' }, // Migrated WBTC + { version: 4, address: '0x7d8df3e4d06b0e19960c19ee673c0823beb90815' }, // CRV V2 + { + version: 4, + address: '0x289424add4a1a503870eb475fd8bf1d586b134ed', + collateralPoolId: '7394f1bc-840a-4ff0-9e87-5e0ef932943a', + }, // cvx3pool + { version: 4, address: '0xc6d3b82f9774db8f92095b5e4352a8bb8b0dc20d' }, // sSPELL v3 + { + version: 4, + address: '0x46f54d434063e5f1a2b2cc6d9aaa657b1b9ff82c', + collateralPoolId: 'ad3d7253-fb8f-402f-a6f8-821bc0a055cb', + }, // cvxTricrypto2 + { + version: 4, + address: '0x40d95c4b34127cf43438a963e7c066156c5b87a3', + }, // yvUSDT (deprecated) + { + version: 4, + address: '0x6bcd99d6009ac1666b58cb68fb4a50385945cda2', + }, // yvUSDC (deprecated) + { version: 4, address: '0x289424add4a1a503870eb475fd8bf1d586b134ed' }, // cvx3Pool (deprecated) + { + version: 4, + address: '0xed510639e1b07c9145cd570f8dd0ca885f760e09', + collateralPoolId: 'acb09b67-8509-4e2a-adb4-4ce520084714', + }, // yvWETH + { version: 4, address: '0xce450a23378859fb5157f4c4cccaf48faa30865b' }, // yvcrvIB + ], + }, + fantom: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { version: 2, address: '0x8e45af6743422e488afacdad842ce75a09eaed34' }, // wFTM + { version: 2, address: '0xd4357d43545f793101b592bacab89943dc89d11b' }, // wFTM + { version: 2, address: '0xed745b045f9495b8bfc7b58eea8e0d0597884e12' }, // yvFTM + { version: 2, address: '0xa3fc1b4b7f06c2391f7ad7d4795c1cd28a59917e' }, // xBOO + { version: 2, address: '0x7208d9f9398d7b02c5c22c334c2a7a3a98c0a45d' }, // FTM/MIM SpiritLP + { version: 2, address: '0x4fdffa59bf8dda3f4d5b38f260eab8bfac6d7bc1' }, // FTM/MIM SpookyLP + ], + }, + optimism: { + marketLensAddress: '0x73f52bd9e59edbdf5cf0dd59126cef00ecc31528', + cauldrons: [ + { version: 3, address: '0x68f498c230015254aff0e1eb6f85da558dff2362' }, + ], + }, + kava: { + marketLensAddress: '0x2d50927A6E87E517946591A137b765fAba018E70', + cauldrons: [ + { version: 4, address: '0x3CFf6F628Ebc88e167640966E67314Cf6466E6A8' }, // MIM/USDT Curve LP + { + version: 4, + address: '0x895731a0C3836a5534561268F15EBA377218651D', + collateralPoolId: '246ee0b2-434e-44dd-90a7-a728deaf1597', + }, // Stargate USDT + ] + }, +}; + +const NEGATIVE_INTEREST_STRATEGIES = { + ethereum: [ + '0x186d76147a226a51a112bb1958e8b755ab9fd1af', + '0xcc0d7af1f809dd3a589756bba36be04d19e9c6c5', + ], +}; + +const BASE_STARGATE_LP_STRATEGIES = { + ethereum: [ + '0x86130Dac04869a8201c7077270C10f3AFaba1c82', + '0x8439Ac976aC597C71C0512D8a53697a39E8F9773', + ], +}; + +const FEE_COLLECTABLE_STRATEGIES = { + arbitrum: [ + '0x39c54bd10261d42ee1838d5fc71dd307dcb39001', + '0xb4fc7be1fc0a6d7b6d5d509c622f56d719cd1373', + '0xf53a003e863ba83424048d729460fba056c06b80', + '0x25ac30195f5b7653ddd7eb93cae6ff5d924cdaf4', + '0x9f026f9edc92150076bb8a0ac44c14a8412c1639', + ], + kava: [ + '0x30d525cbb79d2baae7637ea748631a6360ce7c16', + ], +} + +const STRATEGY_CONFIGURATIONS = { + arbitrum: { + '0x39c54bd10261d42ee1838d5fc71dd307dcb39001': { ignoreTargetPercentage: true }, // All rewards will be yielded regardless of targetPercentage + '0xb4fc7be1fc0a6d7b6d5d509c622f56d719cd1373': { ignoreTargetPercentage: true }, // All rewards will be yielded regardless of targetPercentage + '0xf53a003e863ba83424048d729460fba056c06b80': { ignoreTargetPercentage: true }, // All rewards will be yielded regardless of targetPercentage + '0x25ac30195f5b7653ddd7eb93cae6ff5d924cdaf4': { ignoreTargetPercentage: true }, // All rewards will be yielded regardless of targetPercentage + '0x9f026f9edc92150076bb8a0ac44c14a8412c1639': { ignoreTargetPercentage: true }, // All rewards will be yielded regardless of targetPercentage + } +} + +const getMarketLensDetailsForCauldrons = ( + chain, + marketLensAddress, + abiName, + cauldrons +) => + sdk.api.abi + .multiCall({ + abi: MARKET_LENS_ABI.find((abi) => abi.name == abiName), + calls: cauldrons.map((cauldron) => ({ + target: marketLensAddress, + params: [cauldron.address], + })), + chain, + requery: true, + permitFailure: true + }) + .then((call) => call.output.map((x) => x.output)); + +const enrichMarketInfos = (cauldrons, marketInfos) => + marketInfos + .map((marketInfo, i) => ({ + ...cauldrons[i], + ...marketInfo, + })) + .map((enrichedMarketInfo) => _.omitBy(enrichedMarketInfo, _.isUndefined)); + +const getApyV1Cauldrons = async (chain, marketLensAddress, cauldrons) => { + const [ + marketMaxBorrowCauldrons, + totalBorrowedCauldrons, + oracleExchangeRateCauldrons, + totalCollateralCauldrons, + ] = await Promise.all([ + getMarketLensDetailsForCauldrons( + chain, + marketLensAddress, + 'getMaxMarketBorrowForCauldronV2', + cauldrons + ), + sdk.api.abi + .multiCall({ + abi: CAULDRON_V2_ABI.find((abi) => abi.name == 'totalBorrow'), + calls: cauldrons.map((cauldron) => ({ + target: cauldron.address, + })), + chain, + requery: true, + permitFailure: true + }) + .then((call) => call.output.map((x) => x.output.elastic)), + getMarketLensDetailsForCauldrons( + chain, + marketLensAddress, + 'getOracleExchangeRate', + cauldrons + ), + getMarketLensDetailsForCauldrons( + chain, + marketLensAddress, + 'getTotalCollateral', + cauldrons + ), + ]); + + const marketInfos = cauldrons.map((_, i) => ({ + marketMaxBorrow: marketMaxBorrowCauldrons[i], + totalBorrowed: totalBorrowedCauldrons[i], + oracleExchangeRate: oracleExchangeRateCauldrons[i], + totalCollateral: totalCollateralCauldrons[i], + })); + + return enrichMarketInfos(cauldrons, marketInfos); +}; + +const getApyV2Cauldrons = (chain, marketLensAddress, cauldrons) => + getMarketLensDetailsForCauldrons( + chain, + marketLensAddress, + 'getMarketInfoCauldronV2', + cauldrons + ).then((marketInfos) => enrichMarketInfos(cauldrons, marketInfos)); + +const getApyV3PlusCauldrons = (chain, marketLensAddress, cauldrons) => + getMarketLensDetailsForCauldrons( + chain, + marketLensAddress, + 'getMarketInfoCauldronV3', + cauldrons + ).then((marketInfos) => enrichMarketInfos(cauldrons, marketInfos)); + +const getMarketInfos = (pools) => + Promise.all( + Object.entries(pools).map(async ([chain, chainPoolData]) => { + const v1Cauldrons = chainPoolData.cauldrons.filter( + (cauldron) => cauldron.version === 1 + ); + const v2Cauldrons = chainPoolData.cauldrons.filter( + (cauldron) => cauldron.version === 2 + ); + const v3plusCauldrons = chainPoolData.cauldrons.filter( + (cauldron) => cauldron.version >= 3 + ); + + const marketInfos = await Promise.all([ + getApyV1Cauldrons(chain, chainPoolData.marketLensAddress, v1Cauldrons), + getApyV2Cauldrons(chain, chainPoolData.marketLensAddress, v2Cauldrons), + getApyV3PlusCauldrons( + chain, + chainPoolData.marketLensAddress, + v3plusCauldrons + ), + ]).then((x) => x.flat()); + + return [chain, marketInfos]; + }) + ).then((x) => Object.fromEntries(x)); + +const getCauldronDetails = (pools, abiName) => + Promise.all( + Object.entries(pools).map(async ([chain, { cauldrons }]) => [ + chain, + await sdk.api.abi + .multiCall({ + abi: CAULDRON_V2_ABI.find((abi) => abi.name == abiName), + calls: cauldrons.map((cauldron) => ({ + target: cauldron.address, + })), + chain, + requery: true, + permitFailure: true + }) + .then((call) => + Object.fromEntries( + call.output.map((x, i) => [ + cauldrons[i].address.toLowerCase(), + x.output, + ]) + ) + ), + ]) + ).then(Object.fromEntries); + +const getStrategies = (collaterals, bentoboxes) => + Promise.all( + Object.entries(collaterals).map(async ([chain, chainCollaterals]) => { + const zippedCollateralBentoboxes = Object.keys(chainCollaterals).map( + (cauldronAddress) => [ + collaterals[chain][cauldronAddress].toLowerCase(), + bentoboxes[chain][cauldronAddress].toLowerCase(), + ] + ); + + const uniqueZippedCollateralBentoboxes = _.uniqWith( + zippedCollateralBentoboxes, + _.isEqual + ); + + const [strategies, strategyDataArray] = await Promise.all([ + sdk.api.abi + .multiCall({ + abi: BENTOBOX_V1_ABI.find((abi) => abi.name === 'strategy'), + calls: uniqueZippedCollateralBentoboxes.map( + ([collateral, bentobox]) => ({ + target: bentobox, + params: [collateral], + }) + ), + chain, + requery: true, + permitFailure: true + }) + .then((call) => call.output.map((x) => x.output)), + sdk.api.abi + .multiCall({ + abi: BENTOBOX_V1_ABI.find((abi) => abi.name === 'strategyData'), + calls: uniqueZippedCollateralBentoboxes.map( + ([collateral, bentobox]) => ({ + target: bentobox, + params: [collateral], + }) + ), + chain, + requery: true, + permitFailure: true + }) + .then((call) => call.output.map((x) => x.output)), + ]); + + // Build result like {collateralAddress: {bentoboxAddress: {address: strategyAddress, strategyData: strategyData}}} + const zippedResults = _.zip( + uniqueZippedCollateralBentoboxes, + strategies, + strategyDataArray + ).filter( + ([_, strategy, strategyData]) => + // Ignore empty strategies and disabled strategies + strategy !== '0x0000000000000000000000000000000000000000' && + strategyData.targetPercentage != 0 + ); + const resultObject = _.zipObjectDeep( + zippedResults.map(([collateralBentobox, _]) => collateralBentobox), + zippedResults.map(([_, strategy, strategyData]) => ({ + address: strategy.toLowerCase(), + strategyData: strategyData, + })) + ); + + return [chain, resultObject]; + }) + ).then(Object.fromEntries); + +const getNegativeInterestStrategyApy = (negativeInterestStrategies) => + Promise.all( + Object.entries(negativeInterestStrategies).map( + async ([chain, chainNegativeInterestStrategies]) => [ + chain, + await sdk.api.abi + .multiCall({ + abi: INTEREST_STRATEGY.find( + (abi) => abi.name === 'getYearlyInterestBips' + ), + calls: chainNegativeInterestStrategies.map( + (negativeInterestStrategy) => ({ + target: negativeInterestStrategy, + }) + ), + chain, + requery: true, + permitFailure: true + }) + .then((call) => + Object.fromEntries( + call.output.map((x, i) => [ + chainNegativeInterestStrategies[i].toLowerCase(), + x.output / 100, + ]) + ) + ), + ] + ) + ).then(Object.fromEntries); + +const getBaseStargateLpStrategyFees = (baseStargateLpStrategies) => + Promise.all( + Object.entries(baseStargateLpStrategies).map( + async ([chain, chainBaseStargateLpStrategies]) => [ + chain, + await sdk.api.abi + .multiCall({ + abi: BASE_STARGATE_LP_STRATEGY.find( + (abi) => abi.name === 'feePercent' + ), + calls: chainBaseStargateLpStrategies.map( + (baseStargateLpStrategy) => ({ + target: baseStargateLpStrategy, + }) + ), + chain, + requery: true, + permitFailure: true + }) + .then((call) => + Object.fromEntries( + call.output.map((x, i) => [ + chainBaseStargateLpStrategies[i].toLowerCase(), + x.output / 100, + ]) + ) + ), + ] + ) + ).then(Object.fromEntries); + +const getFeeCollectableStrategyFees = (feeCollectableStrategies) => + Promise.all( + Object.entries(feeCollectableStrategies).map( + async ([chain, chainFeeCollectableStrategies]) => [ + chain, + await sdk.api.abi + .multiCall({ + abi: FEE_COLLECTABLE_STRATEGY.find( + ({ name }) => name === 'feeBips' + ), + calls: chainFeeCollectableStrategies.map( + (feeCollectableStrategy) => ({ + target: feeCollectableStrategy, + }) + ), + chain, + requery: true, + permitFailure: true + }) + .then((call) => + Object.fromEntries( + call.output.map((x, i) => [ + chainFeeCollectableStrategies[i].toLowerCase(), + x.output / 10000, + ]) + ) + ), + ] + ) + ).then(Object.fromEntries); + + +const getDetailsFromCollaterals = (collaterals, abi) => + Promise.all( + Object.entries(collaterals).map(async ([chain, chainCollaterals]) => { + const chainCollateralEntries = Object.entries(chainCollaterals); + + return [ + chain, + await sdk.api.abi + .multiCall({ + abi, + calls: chainCollateralEntries.map(([_, collateral]) => ({ + target: collateral, + })), + chain, + requery: true, + permitFailure: true + }) + .then((call) => + Object.fromEntries( + call.output.map((x, i) => [ + chainCollateralEntries[i][0].toLowerCase(), + x.output, + ]) + ) + ), + ]; + }) + ).then(Object.fromEntries); + +const marketInfoToPool = (chain, marketInfo, collateral, pricesObj) => { + // Use price from pricesObj, but fallback to cauldron oracle price + const collateralPrice = pricesObj.pricesByAddress[ + collateral.address.toLowerCase() + ] + ? pricesObj.pricesByAddress[collateral.address.toLowerCase()] + : 1 / formatUnits(marketInfo.oracleExchangeRate, collateral.decimals); + const mimPrice = pricesObj.pricesByAddress[MIM_COINGECKO_ID]; + + const totalSupplyUsd = + formatUnits(marketInfo.totalCollateral.amount, collateral.decimals) * + collateralPrice; + const totalBorrowUsd = formatEther(marketInfo.totalBorrowed) * mimPrice; + const availableToBorrowUsd = + formatEther(marketInfo.marketMaxBorrow) * mimPrice; + const debtCeilingUsd = totalBorrowUsd + availableToBorrowUsd; + + const apyBaseBorrow = marketInfo.interestPerYear / 100; + const ltv = marketInfo.maximumCollateralRatio / 10000; + + const pool = { + pool: `${marketInfo.address}-${chain}`, + chain: utils.formatChain(chain), + symbol: marketInfo.symbol ?? utils.formatSymbol(collateral.symbol), + tvlUsd: totalSupplyUsd, + apyBaseBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + debtCeilingUsd, + mintedCoin: 'MIM', + }; + + if (collateral.apyBase !== undefined) { + pool.apyBase = collateral.apyBase; + } else { + pool.apy = 0; + } + + if (marketInfo.cauldronMeta !== undefined) { + pool.poolMeta = marketInfo.cauldronMeta; + } + + return pool; +}; + +const poolsApy = async () => + (await superagent.get('https://yields.llama.fi/pools')).body.data; + +const getApy = async () => { + const collateralsPromise = getCauldronDetails(POOLS, 'collateral'); + const bentoboxesPromise = getCauldronDetails(POOLS, 'bentoBox'); + const [ + marketInfos, + collaterals, + bentoboxes, + strategies, + negativeInterestStrategyApys, + strategyFees, + symbols, + decimals, + pricesObj, + apyObj, + ] = await Promise.all([ + getMarketInfos(POOLS), + collateralsPromise, + bentoboxesPromise, + Promise.all([collateralsPromise, bentoboxesPromise]).then( + ([collaterals, bentoboxes]) => getStrategies(collaterals, bentoboxes) + ), + getNegativeInterestStrategyApy(NEGATIVE_INTEREST_STRATEGIES), + Promise.all([ + getBaseStargateLpStrategyFees(BASE_STARGATE_LP_STRATEGIES), + getFeeCollectableStrategyFees(FEE_COLLECTABLE_STRATEGIES), + ]).then((strategyFeesArr) => _.merge({}, ...strategyFeesArr)), + collateralsPromise.then((collaterals) => + getDetailsFromCollaterals(collaterals, 'erc20:symbol') + ), + collateralsPromise.then((collaterals) => + getDetailsFromCollaterals(collaterals, 'erc20:decimals') + ), + collateralsPromise.then((collaterals) => { + const coins = Object.entries(collaterals).flatMap( + ([chain, chainCollaterals]) => + Object.values(chainCollaterals).map( + (collateral) => `${chain}:${collateral}` + ) + ); + + return utils.getPrices([`coingecko:${MIM_COINGECKO_ID}`, ...coins]); + }), + poolsApy(), + ]); + + return Object.entries(marketInfos).flatMap(([chain, chainMarketInfos]) => + chainMarketInfos.map((marketInfo) => { + const collateralAddress = + collaterals[chain][marketInfo.address.toLowerCase()].toLowerCase(); + const bentobox = + bentoboxes[chain][marketInfo.address.toLowerCase()].toLowerCase(); + const collateral = { + address: collateralAddress, + symbol: symbols[chain][marketInfo.address.toLowerCase()], + decimals: decimals[chain][marketInfo.address.toLowerCase()], + }; + + // Add negative strategy APY to collateral if there's one for the cauldron + const strategyDetails = _.get(strategies, [ + chain, + collateralAddress, + bentobox, + ]); + const collateralApy = + marketInfo.collateralPoolId !== undefined + ? _.find(apyObj, { pool: marketInfo.collateralPoolId }) + : undefined; + if (collateralApy !== undefined) { + collateral.apyBase = collateralApy.apyBase; + } else { + collateral.apyBase = 0; + } + if (strategyDetails !== undefined) { + const strategy = strategyDetails.address.toLowerCase(); + const strategyConfiguration = _.get( + STRATEGY_CONFIGURATIONS, + [chain, strategy] + ); + const ignoreTargetPercentage = strategyConfiguration?.ignoreTargetPercentage === true; + const targetPercentage = ignoreTargetPercentage ? 100 : strategyDetails.strategyData.targetPercentage; + const negativeInterestStrategyApy = _.get( + negativeInterestStrategyApys, + [chain, strategy] + ); + const strategyFee = _.get(strategyFees, [ + chain, + strategy, + ]); + if (negativeInterestStrategyApy !== undefined) { + collateral.apyBase += + (targetPercentage / 100) * -negativeInterestStrategyApy; + } else if ( + strategyFee !== undefined && + collateralApy !== undefined + ) { + collateral.apyBase += + ((collateralApy.apyReward * targetPercentage) / 100) * + (1 - strategyFee); + } + } + if (collateral.apyBase === 0) { + collateral.apyBase = undefined; + } + + return { + ...marketInfoToPool(chain, marketInfo, collateral, pricesObj), + project: 'abracadabra-spell', + }; + }) + ); +}; + +module.exports = getApy; diff --git a/src/adaptors/abracadabra-spell/common.ts b/src/adaptors/abracadabra-spell/common.ts new file mode 100644 index 0000000000..2a074eebc9 --- /dev/null +++ b/src/adaptors/abracadabra-spell/common.ts @@ -0,0 +1,238 @@ +import type Axios from 'axios'; +const axios = require('axios') as typeof Axios; +import type Sdk from '@defillama/sdk'; +const sdk = require('@defillama/sdk') as typeof Sdk; +import type Ethers from 'ethers'; +const { utils: { formatUnits }, BigNumber } = require('ethers') as typeof Ethers; +import type Utils from '../utils'; +const utils = require('../utils') as typeof Utils; +const MULTI_REWARDS_STAKING = require('./abis/MultiRewardsStaking.json'); + +const SECONDS_PER_YEAR = 31536000; + +export type MultiRewardFarm = { + stakingTokenPool?: string; + pool: { + pool?: string; + project: string; + symbol?: string; + rewardTokens?: string[]; + underlyingTokens?: string[]; + poolMeta?: string; + url?: string; + }; +}; + +export type MultiRewardFarms = { + [chain: string]: { + [address: string]: MultiRewardFarm + }; +} + +async function getRewardTokens(chain: string, farms: MultiRewardFarms[string]): Promise<{ [farm: string]: string[] }> { + const farmEntries = Object.entries(farms); + + const rewardTokens = farmEntries.map(([address, { pool }]) => + [address, pool.rewardTokens ?? []] as const + ); + + const rewardTokenLengthCalls = farmEntries.map(([target, { pool }], farmIndex) => { + if (pool.rewardTokens !== undefined) { + return undefined; + } + return { farmIndex, target }; + }).filter((x) => x !== undefined); + + const rewardTokenLengthResults = await sdk.api.abi.multiCall({ + abi: MULTI_REWARDS_STAKING.find(({ name }) => name === "getRewardTokenLength"), + calls: rewardTokenLengthCalls.map(({ target }) => ({ target })), + chain, + }).then((call => call.output.map((x, callIndex) => ({ + ...rewardTokenLengthCalls[callIndex], + rewardLength: x.output, + })))); + + const rewardTokenCalls = rewardTokenLengthResults.flatMap((result) => + Array.from({ length: result.rewardLength }).map((_, rewardTokenIndex) => ({ + ...result, + params: [rewardTokenIndex], + })) + ); + + const rewardTokenResults = await sdk.api.abi.multiCall({ + abi: MULTI_REWARDS_STAKING.find(({ name }) => name === "rewardTokens"), + calls: rewardTokenCalls.map(({ target, params }) => ({ target, params })), + chain, + }).then((call => call.output.map((x, callIndex) => ({ + ...rewardTokenCalls[callIndex], + rewardToken: x.output, + })))); + + for (const { farmIndex, rewardToken } of rewardTokenResults) { + rewardTokens[farmIndex][1].push(rewardToken); + } + + return Object.fromEntries(rewardTokens); +} + +function getStakingTokens(chain: string, farms: MultiRewardFarms[string]): Promise<{ [farm: string]: string }> { + const farmAddresses = Object.keys(farms); + return sdk.api.abi.multiCall({ + abi: MULTI_REWARDS_STAKING.find(({ name }) => name === "stakingToken"), + calls: farmAddresses.map((target) => ({ target })), + chain, + }).then((call => call.output.map((x, callIndex) => + [farmAddresses[callIndex], x.output] + ))).then((results) => Object.fromEntries(results)); +} + +async function multiRewardFarmsApy(farms: MultiRewardFarms) { + const pools = await Promise.all(Object.entries(farms).map(async ([chain, chainFarms]) => { + const rewardTokensPromise = getRewardTokens(chain, chainFarms); + const stakingTokensPromise = getStakingTokens(chain, chainFarms); + const [stakingTokens, stakingTokensDecimals, rewardDataResults, totalSupplyResults, prices, symbols, yieldPools] = await Promise.all([ + stakingTokensPromise, + stakingTokensPromise.then((stakingTokens) => sdk.api.abi.multiCall({ + abi: "erc20:decimals", + calls: Array.from(new Set(Object.values(stakingTokens))).map((target) => ({ target })), + chain, + })).then((call) => call.output.map((x) => [x.input.target, x.output])) + .then(Object.fromEntries), + rewardTokensPromise.then((rewardTokens) => + sdk.api.abi.multiCall({ + abi: MULTI_REWARDS_STAKING.find(({ name }) => name === "rewardData"), + calls: Object.entries(rewardTokens).flatMap(([target, farmRewardTokens]) => + farmRewardTokens.map((rewardToken) => ({ target, params: [rewardToken] })) + ), + chain, + }).then((call => call.output))), + sdk.api.abi.multiCall({ + abi: MULTI_REWARDS_STAKING.find(({ name }) => name === "totalSupply"), + calls: Object.keys(chainFarms).map((target) => ({ target })), + chain, + }).then((call => call.output.map((x) => [x.input.target, x]))) + .then(Object.fromEntries), + Promise.all([rewardTokensPromise, stakingTokensPromise]).then(([rewardTokens, stakingTokens]) => + utils.getPrices([ + ...Object.values(rewardTokens).flat(), + ...Object.values(stakingTokens).flat(), + ], chain) + ), + stakingTokensPromise.then((stakingTokens) => sdk.api.abi.multiCall({ + abi: "erc20:symbol", + calls: Object.keys(chainFarms).map((farmAddress) => ({ + target: stakingTokens[farmAddress], + })), + chain, + })).then((call => call.output.map((x) => [x.input.target, x]))) + .then(Object.fromEntries), + axios.get('https://yields.llama.fi/pools').then((result) => result.data.data), + ]); + + const tvlUsdChainFarms = Object.fromEntries( + await Promise.all( + Object.entries(chainFarms).map(async ([farmAddress, { stakingTokenPool, pool }]) => { + const stakingTokenDecimals = stakingTokensDecimals[farmAddress]; + const totalSupply = Number(formatUnits(totalSupplyResults[farmAddress].output, stakingTokenDecimals)); + let stakingTokenPrice = prices.pricesByAddress[stakingTokens[farmAddress].toLowerCase()]; + + // If the staking token price is not available, try to calculate it from the underlying tokens + if (stakingTokenPrice === undefined) { + const underlyingTokens = pool.underlyingTokens ?? yieldPools.find(({ pool }) => pool === stakingTokenPool)?.underlyingTokens; + + if (underlyingTokens === undefined) { + return [farmAddress, undefined]; + } + + const [stakingTokenTotalSupply, underlyingTokenPrices, underlyingTokenBalances, underlyingTokenDecimals] = await Promise.all([ + sdk.api.abi.call({ + abi: "erc20:totalSupply", + target: stakingTokens[farmAddress], + chain, + }).then((call) => call.output), + utils.getPrices(underlyingTokens, chain), + sdk.api.abi.multiCall({ + abi: "erc20:balanceOf", + calls: underlyingTokens.map((underlyingToken) => ({ target: underlyingToken, params: [stakingTokens[farmAddress]] })), + chain, + }).then((call) => call.output.map((x) => x.output)), + sdk.api.abi.multiCall({ + abi: "erc20:decimals", + calls: underlyingTokens.map((underlyingToken) => ({ target: underlyingToken })), + chain, + }).then((call) => call.output.map((x) => x.output)), + ]); + + let underlyingTokensTvlUsd = 0; + for (const [index, underlyingToken] of underlyingTokens.entries()) { + const underlyingTokenPrice = underlyingTokenPrices.pricesByAddress[underlyingToken.toLowerCase()]; + + if (underlyingTokenPrice === undefined) { + return [farmAddress, undefined]; + } + + const underlyingTokenBalance = Number(formatUnits(underlyingTokenBalances[index], underlyingTokenDecimals[index])); + underlyingTokensTvlUsd += underlyingTokenBalance * underlyingTokenPrice; + } + stakingTokenPrice = underlyingTokensTvlUsd / Number(formatUnits(stakingTokenTotalSupply, stakingTokenDecimals)); + } + + const totalSupplyUsd = totalSupply * stakingTokenPrice; + return [farmAddress, totalSupplyUsd]; + }) + ) + ); + + const aprs: Record> = Object.fromEntries( + Object.keys(chainFarms).map((address) => [address, []]) + ); + + for (const { input: { target: farm, params: [rewardToken] }, output: { rewardRate, periodFinish } } of rewardDataResults) { + if (periodFinish <= Math.floor(Date.now() / 1000)) { + continue; + } + + const rewardPrice = prices.pricesByAddress[rewardToken.toLowerCase()]; + if (rewardPrice === undefined) { + continue; + } + + const rewardsPerYearRaw = BigNumber.from(rewardRate).mul(SECONDS_PER_YEAR); + if (rewardsPerYearRaw.eq(0)) { + continue; + } + + const rewardsPerYear = Number(formatUnits(rewardsPerYearRaw, 18)); + const rewardsPerYearUsd = rewardsPerYear * rewardPrice; + const rewardApr = rewardsPerYearUsd / tvlUsdChainFarms[farm] * 100; + + aprs[farm].push({ token: rewardToken, apr: rewardApr }); + } + + return Object.entries(chainFarms).map(([farmAddress, { stakingTokenPool, pool }]) => { + const tvlUsd = tvlUsdChainFarms[farmAddress]; + if (tvlUsd === undefined) { + return undefined; + } + const stakingTokenYieldPool = yieldPools.find(({ pool }) => pool === stakingTokenPool); + return { + pool: `${farmAddress}-${chain}`, + chain: utils.formatChain(chain), + tvlUsd, + symbol: utils.formatSymbol(symbols[stakingTokens[farmAddress]].output), + apyBase: stakingTokenYieldPool?.apyBase ?? 0, + apyReward: aprs[farmAddress].reduce((acc, { apr }) => acc + apr, 0), + underlyingTokens: stakingTokenYieldPool?.underlyingTokens, + ...pool, + rewardTokens: aprs[farmAddress].map(({ token }) => token), + } + }).filter((x) => x !== undefined); + })); + return pools.flat(); +} + +export type MultiRewardFarmsApy = typeof multiRewardFarmsApy; + +module.exports = { + multiRewardFarmsApy +}; diff --git a/src/adaptors/abracadabra-spell/farms.js b/src/adaptors/abracadabra-spell/farms.js new file mode 100644 index 0000000000..7ca49c57e9 --- /dev/null +++ b/src/adaptors/abracadabra-spell/farms.js @@ -0,0 +1,266 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const utils = require('../utils'); +const SORBETTIERE_ABI = require('./abis/Sorbettiere.json'); +const UNISWAP_V2_PAIR_ABI = require('./abis/UniswapV2Pair.json'); + +const makeCall = async (targets, abi) => { + return ( + await sdk.api.abi.multiCall({ + abi, + calls: targets.map((target) => ({ target })), + chain: 'aurora', + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const SPELL_ADDRESS = '0x090185f2135308bad17527004364ebcc2d37e5f6'; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const POOLS = { + fantom: { + pool: '0x37Cf490255082ee50845EA4Ff783Eb9b6D1622ce', + name: 'MIM-fUSDT-USDC', + }, + arbitrum: { + pool: '0x839De324a1ab773F76a53900D70Ac1B913d2B387', + name: 'MIM-3CRV', + }, + ethereum: { + pool: '0xF43480afE9863da4AcBD4419A47D9Cc7d25A647F', + name: 'SPELL-ETH', + }, +}; + +const getApy = async () => { + const spellPerSec = await Promise.all( + Object.keys(POOLS).map( + async (chain) => + ( + await sdk.api.abi.call({ + target: POOLS[chain].pool, + abi: SORBETTIERE_ABI.find(({ name }) => name === 'icePerSecond'), + chain, + permitFailure: true, + }) + ).output + ) + ); + + const poolsLength = await Promise.all( + Object.keys(POOLS).map( + async (chain) => + ( + await sdk.api.abi.call({ + target: POOLS[chain].pool, + abi: SORBETTIERE_ABI.find(({ name }) => name === 'poolLength'), + chain, + permitFailure: true, + }) + ).output + ) + ); + + const poolsInfo = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLength[i])).keys()].map((idx) => ({ + params: idx, + target: POOLS[chain].pool, + })), + abi: SORBETTIERE_ABI.find(({ name }) => name === 'poolInfo'), + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const lpSupply = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: poolsInfo[i].map((pool) => ({ + target: pool.stakingToken, + })), + abi: 'erc20:totalSupply', + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const lpSymbol = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: poolsInfo[i].map((pool) => ({ + target: pool.stakingToken, + })), + abi: 'erc20:symbol', + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const underlying0 = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: poolsInfo[i].map((pool) => ({ + target: pool.stakingToken, + })), + abi: UNISWAP_V2_PAIR_ABI.find(({ name }) => name === 'token0'), + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + const underlying1 = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: poolsInfo[i].map((pool) => ({ + target: pool.stakingToken, + })), + abi: UNISWAP_V2_PAIR_ABI.find(({ name }) => name === 'token1'), + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const underlying0Symbol = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: underlying0[i].map((pool) => ({ + target: pool, + })), + abi: 'erc20:symbol', + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + const underlying1Symbol = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: underlying1[i].map((pool) => ({ + target: pool, + })), + abi: 'erc20:symbol', + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const lpReserves = await Promise.all( + Object.keys(POOLS).map(async (chain, i) => + ( + await sdk.api.abi.multiCall({ + calls: poolsInfo[i].map((pool) => ({ + target: pool.stakingToken, + })), + abi: UNISWAP_V2_PAIR_ABI.find(({ name }) => name === 'getReserves'), + chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const tokens0WithChain = Object.keys(POOLS).map((chain, i) => + underlying0[i].map((token) => `${chain}:${token}`) + ); + const tokens1WithChain = Object.keys(POOLS).map((chain, i) => + underlying1[i].map((token) => `${chain}:${token}`) + ); + + const prices = await getPrices( + tokens0WithChain.concat(tokens1WithChain).flat() + ); + + const spellPrice = prices[SPELL_ADDRESS]; + + const pools = Object.keys(POOLS).map((chain, i) => { + const totalAllocPoint = poolsInfo[i].reduce( + (acc, val) => +val.allocPoint + acc, + 0 + ); + const rewardPerYear = + ((spellPerSec[i] * 60 * 60 * 24 * 365) / 1e18) * spellPrice; + + return poolsInfo[i].map((pool, idx) => { + const token0 = underlying0[i][idx]; + const token1 = underlying1[i][idx]; + + let tvlUsd = 0; + const isCryptoPool = token0 && token1; + + if (isCryptoPool) { + const poolShare = pool.stakingTokenTotalAmount / lpSupply[i][idx]; + const token0Price = prices[token0.toLowerCase()]; + const token1Price = prices[token1.toLowerCase()]; + + const lpTvl = + (token0Price * Number(lpReserves[i][idx]._reserve0)) / 1e18 + + (token1Price * Number(lpReserves[i][idx]._reserve1)) / 1e18; + tvlUsd = lpTvl * poolShare; + } else { + tvlUsd = Number(pool.stakingTokenTotalAmount) / 1e18; + } + const apyReward = + ((rewardPerYear * (pool.allocPoint / totalAllocPoint)) / tvlUsd) * 100; + + const symbol = isCryptoPool + ? `${underlying0Symbol[i][idx]}-${underlying1Symbol[i][idx]}` + : lpSymbol[i][idx]; + + return { + pool: `${pool.stakingToken}-abracadabra`, + chain: utils.formatChain(chain), + project: 'abracadabra-spell', + tvlUsd, + symbol, + apyReward, + rewardTokens: [SPELL_ADDRESS], + underlyingTokens: [token0, token1].filter(Boolean), + }; + }); + }); + + return pools.flat(); +}; + +module.exports = getApy; diff --git a/src/adaptors/abracadabra-spell/index.js b/src/adaptors/abracadabra-spell/index.js new file mode 100644 index 0000000000..7ae9bc5e73 --- /dev/null +++ b/src/adaptors/abracadabra-spell/index.js @@ -0,0 +1,22 @@ +const cauldrons = require('./cauldrons'); +const multiRewardFarms = require('./multi-reward-farms'); +const farms = require('./farms'); +const magicGlp = require('./magic-glp'); +const utils = require('../utils'); + +const getApy = async () => { + const pools = [ + ...(await cauldrons()), + ...(await farms()), + ...(await magicGlp()), + ...(await multiRewardFarms()), + ].map((i) => ({ ...i, pool: i.pool.toLowerCase() })); + + return utils.removeDuplicates(pools); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.abracadabra.money', +}; diff --git a/src/adaptors/abracadabra-spell/magic-glp.js b/src/adaptors/abracadabra-spell/magic-glp.js new file mode 100644 index 0000000000..b157cec8c8 --- /dev/null +++ b/src/adaptors/abracadabra-spell/magic-glp.js @@ -0,0 +1,233 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const ERC4626 = require('./abis/ERC4626.json'); +const GLP_MANAGER = require('./abis/GlpManager.json'); +const MAGIC_GLP_HARVESTOR = require('./abis/MagicGlpHarvestor.json'); +const REWARD_TRACKER = require('./abis/RewardTracker.json'); + +const HOURS_PER_YEAR = 8760; +const SECONDS_PER_YEAR = 31536000; +const HARVESTS_PER_YEAR = HOURS_PER_YEAR; +const MAGIC_GLP_POOLS = { + arbitrum: { + magicGlpAddress: '0x85667409a723684fe1e57dd1abde8d88c2f54214', + glp: { + address: '0x4277f8f2c384827b5273592ff7cebd9f2c1ac258', + decimals: 18, + }, + glpManagerAddress: '0x3963ffc9dff443c2a94f21b129d429891e32ec18', + harvestorAddress: '0xc99a4863173ef52ccb7ea05440da0e37ba39c139', + glpRewardTrackerAddresses: [ + '0x4e971a87900b931ff39d1aad67697f49835400b6', + '0x1addd80e6039594ee970e5872d247bf0414c8903', + ], + }, + avax: { + magicGlpAddress: '0x5efc10c353fa30c5758037fdf0a233e971ecc2e0', + glp: { + address: '0x01234181085565ed162a948b6a5e88758cd7c7b8', + decimals: 18, + }, + glpManagerAddress: '0xd152c7f25db7f4b95b7658323c5f33d176818ee4', + harvestorAddress: '0x05b3b96df07b4630373ae7506e51777b547335b0', + glpRewardTrackerAddresses: [ + '0xd2d1162512f927a7e282ef43a362659e4f2a728f', + '0x9e295b5b976a184b14ad8cd72413ad846c299660', + ], + }, +}; + +const getChainDetails = (pools, abi) => + Promise.all( + Object.entries(pools).map(async ([chain, chainPools]) => { + const responses = await utils.makeMulticall(abi, chainPools, chain); + const associatedResponses = Object.fromEntries( + responses.map((response, index) => [chainPools[index], response]) + ); + return [chain, associatedResponses]; + }) + ).then(Object.fromEntries); + +const getChainDetail = (pools, abi) => + Promise.all( + Object.entries(pools).map(async ([chain, target]) => { + const response = await sdk.api.abi + .call({ + target, + abi, + chain, + }) + .then(({ output }) => output); + return [chain, response]; + }) + ).then(Object.fromEntries); + +const getHarvestFees = (magicGlpPools) => + Promise.all( + Object.entries(magicGlpPools).map(async ([chain, { harvestorAddress }]) => { + const fee = await sdk.api.abi + .call({ + target: harvestorAddress, + abi: MAGIC_GLP_HARVESTOR.find((abi) => abi.name === 'feePercentBips'), + chain, + }) + .then(({ output }) => output / 10000); + return [chain, fee]; + }) + ).then(Object.fromEntries); + +const getGlpAum = (magicGlpPools) => + Promise.all( + Object.entries(magicGlpPools).map( + async ([chain, { glpManagerAddress }]) => { + const [price, pricePrecision] = await Promise.all([ + sdk.api.abi + .call({ + target: glpManagerAddress, + abi: GLP_MANAGER.find((abi) => abi.name === 'getAum'), + params: [false], + chain, + }) + .then(({ output }) => output), + sdk.api.abi + .call({ + target: glpManagerAddress, + abi: GLP_MANAGER.find((abi) => abi.name === 'PRICE_PRECISION'), + chain, + }) + .then(({ output }) => output), + ]); + return [chain, price / pricePrecision]; + } + ) + ).then(Object.fromEntries); + +const getGlpPrice = (magicGlpPools) => + Promise.all( + Object.entries(magicGlpPools).map( + async ([chain, { glpManagerAddress }]) => { + const [price, pricePrecision] = await Promise.all([ + sdk.api.abi + .call({ + target: glpManagerAddress, + abi: GLP_MANAGER.find((abi) => abi.name === 'getPrice'), + params: [false], + chain, + }) + .then(({ output }) => output), + sdk.api.abi + .call({ + target: glpManagerAddress, + abi: GLP_MANAGER.find((abi) => abi.name === 'PRICE_PRECISION'), + chain, + }) + .then(({ output }) => output), + ]); + return [chain, price / pricePrecision]; + } + ) + ).then(Object.fromEntries); + +const getGlpRewards = (magicGlpPools) => + Promise.all( + Object.entries(magicGlpPools).map( + async ([chain, { glpRewardTrackerAddresses }]) => { + const [rewardTokens, tokensPerInterval] = await Promise.all([ + utils.makeMulticall( + REWARD_TRACKER.find((abi) => abi.name === 'rewardToken'), + glpRewardTrackerAddresses, + chain + ), + utils.makeMulticall( + REWARD_TRACKER.find((abi) => abi.name === 'tokensPerInterval'), + glpRewardTrackerAddresses, + chain + ), + ]); + const rewards = rewardTokens.map((rewardToken, index) => ({ + rewardToken: rewardToken.toLowerCase(), + tokensPerInterval: tokensPerInterval[index], + })); + return [chain, rewards]; + } + ) + ).then(Object.fromEntries); + +const getApy = async () => { + const glpRewardsPromise = getGlpRewards(MAGIC_GLP_POOLS); + const [ + magicGlpTotalAssets, + harvestFees, + glpAum, + glpPrice, + glpRewards, + glpRewardTokenDecimals, + pricesObj, + ] = await Promise.all([ + getChainDetail( + Object.fromEntries( + Object.entries(MAGIC_GLP_POOLS).map(([chain, { magicGlpAddress }]) => [ + chain, + magicGlpAddress, + ]) + ), + ERC4626.find((abi) => abi.name === 'totalAssets') + ), + getHarvestFees(MAGIC_GLP_POOLS), + getGlpAum(MAGIC_GLP_POOLS), + getGlpPrice(MAGIC_GLP_POOLS), + glpRewardsPromise, + glpRewardsPromise.then((glpRewards) => + getChainDetails( + Object.fromEntries( + Object.entries(glpRewards).map(([chain, chainGlpRewards]) => [ + chain, + chainGlpRewards.map(({ rewardToken }) => rewardToken), + ]) + ), + 'erc20:decimals' + ) + ), + glpRewardsPromise.then(async (glpRewards) => { + const coins = Object.entries(glpRewards).flatMap( + ([chain, chainGlpRewards]) => + chainGlpRewards.map(({ rewardToken }) => `${chain}:${rewardToken}`) + ); + return utils.getPrices(coins); + }), + ]); + + return Object.entries(MAGIC_GLP_POOLS).map( + ([chain, { magicGlpAddress, glp }]) => { + const usdRewardsPerInterval = glpRewards[chain] + .map(({ rewardToken, tokensPerInterval }) => { + const rewardTokenPrice = pricesObj.pricesByAddress[rewardToken] ?? 0; + return ( + (tokensPerInterval * rewardTokenPrice) / + 10 ** glpRewardTokenDecimals[chain][rewardToken] + ); + }) + .reduce((a, b) => a + b, 0); + const usdRewardsPerYear = usdRewardsPerInterval * SECONDS_PER_YEAR; + const glpApr = usdRewardsPerYear / glpAum[chain]; + const magicGlpApy = + (1 + (glpApr * (1 - harvestFees[chain])) / HARVESTS_PER_YEAR) ** + HARVESTS_PER_YEAR - + 1; + + return { + pool: `${magicGlpAddress}-magicglp-${chain}`, + chain: utils.formatChain(chain), + project: 'abracadabra-spell', + symbol: utils.formatSymbol('magicGLP'), + tvlUsd: + (magicGlpTotalAssets[chain] / 10 ** glp.decimals) * glpPrice[chain], + apyBase: magicGlpApy * 100, + underlyingTokens: [glp.address], + }; + } + ); +}; + +module.exports = getApy; diff --git a/src/adaptors/abracadabra-spell/multi-reward-farms.js b/src/adaptors/abracadabra-spell/multi-reward-farms.js new file mode 100644 index 0000000000..72e9ace069 --- /dev/null +++ b/src/adaptors/abracadabra-spell/multi-reward-farms.js @@ -0,0 +1,23 @@ +const { multiRewardFarmsApy } = require('./common'); + +module.exports = () => multiRewardFarmsApy({ + arbitrum: { + "0x6d2070b13929Df15B13D96cFC509C574168988Cd": { + stakingTokenPool: "0bf3cb38-1908-4d85-87c3-af62651d5a03", + pool: { + project: 'abracadabra-spell', + underlyingTokens: [ + "0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A", // MIM + "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", // USDC.e + "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", // USDT + ], + rewardTokens: [ + "0x912CE59144191C1204E64559FE8253a0e49E6548", // ARB + "0x3E6648C5a70A150A88bCE65F4aD4d506Fe15d2AF" // SPELL + ], + symbol: "MIM-USDC.e-USDT", + url: "https://app.abracadabra.money/#/farm/4", + }, + }, + }, +}); diff --git a/src/adaptors/accountable/index.js b/src/adaptors/accountable/index.js new file mode 100644 index 0000000000..f9d1b1a0bc --- /dev/null +++ b/src/adaptors/accountable/index.js @@ -0,0 +1,181 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const API_URL = 'https://yield.accountable.capital/api/loan'; +const chainIdToName = { 143: 'monad' }; +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +const abis = { + asset: 'function asset() view returns (address)', + convertToAssets: 'function convertToAssets(uint256 shares) view returns (uint256)', +}; + +const basisPointsToPercent = (value) => Number(value) / 1e4; +const formatAmount = (value, decimals = 18) => (value == null ? null : Number(value) / 10 ** decimals); + +const fetchVaultsByLoanIds = async(loanIds) => { + const results = await Promise.allSettled( + loanIds.map((id) => utils.getData(`${API_URL}/${id}`)) + ); + + return results.reduce((acc, res, idx) => { + if (res.status !== 'fulfilled') return acc; + const vault = res.value.on_chain_loan.loan.vault; + if (vault && vault !== ZERO_ADDRESS) + acc[loanIds[idx]] = vault.toLowerCase(); + return acc; + }, {}); +}; + +const getVaultAddressesFromApi = async() => { + const { items } = await utils.getData(API_URL); + const vaults = items + .map((item) => item.on_chain_loan.loan.vault) + .filter((addr) => addr && addr !== ZERO_ADDRESS) + .map((addr) => addr.toLowerCase()); + return Array.from(new Set(vaults)); +}; + +const getVaultStats = async(vaults, chain = 'monad') => { + if (!vaults.length) return {}; + + const [suppliesRes, underlyingsRes] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: vaults.map((vault) => ({ target: vault })), + permitFailure: true, + }), + sdk.api.abi.multiCall({ + chain, + abi: abis.asset, + calls: vaults.map((vault) => ({ target: vault })), + permitFailure: true, + }), + ]); + + const supplies = suppliesRes.output.map((o) => o.output); + const underlyings = underlyingsRes.output.map((o) => o.output); + + const [totalAssetsRes, liquidityRes] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + abi: abis.convertToAssets, + calls: vaults.map((vault, i) => ({ + target: vault, + params: [supplies[i]], + })), + permitFailure: true, + }), + sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: vaults.map((vault, i) => ({ + target: underlyings[i], + params: vault, + })), + permitFailure: true, + }), + ]); + + const totalAssets = totalAssetsRes.output.map((o) => o.output); + const liquidity = liquidityRes.output.map((o) => o.output); + return vaults.reduce((acc, address, i) => { + acc[address] = { + totalSupplied: supplies[i], + totalBorrowed: Number(totalAssets[i]) - Number(liquidity[i] || 0), + tvl: liquidity[i], + }; + return acc; + }, {}); +}; + +const fetchBreakdowns = async(loanIds) => { + const results = await Promise.allSettled( + loanIds.map((id) => utils.getData(`${API_URL}/${id}/apy/breakdown`)) + ); + + return results.reduce((acc, res, idx) => { + if (res.status !== 'fulfilled') return acc; + acc[loanIds[idx]] = res.value || {}; + return acc; + }, {}); +}; + +const apy = async() => { + const { items } = await utils.getData(API_URL); + const activeLoans = items.filter((item) => item.loan_state === 3); + const loanIds = activeLoans.map((item) => item.id); + + const loanVaultMap = await fetchVaultsByLoanIds(loanIds); + const vaultAddresses = Object.values(loanVaultMap); + const vaultStats = await getVaultStats(vaultAddresses); + const breakdowns = await fetchBreakdowns(loanIds); + + return Promise.all( + activeLoans.map(async(item) => { + const chainName = chainIdToName[item.chain_id] || 'unknown'; + const vaultAddress = loanVaultMap[item.id]; + const stats = vaultAddress ? vaultStats[vaultAddress] || {} : {}; + const pointBoosts = item?.all_points_apy_boost?.boosts_by_points || []; + + const breakdown = breakdowns[item.id]?.main || {}; + + const interestRate = Number(breakdown?.interest_rate); + const perfFeePctRaw = Number(breakdown?.performance_fee_percentage); + const perfFeePct = + !Number.isNaN(perfFeePctRaw) && perfFeePctRaw > 1 ? perfFeePctRaw / 100 : perfFeePctRaw; + const perfFeePoints = Number(breakdown?.performance_fee_points); + const netInterest = breakdown?.net_interest_rate; + const baseApy = + netInterest != null + ? Number(netInterest) + : !Number.isNaN(interestRate) && !Number.isNaN(perfFeePct) + ? interestRate * (1 - perfFeePct) + : !Number.isNaN(interestRate) && !Number.isNaN(perfFeePoints) + ? interestRate - perfFeePoints + : basisPointsToPercent(item.apy); + + const merklApy = Number(breakdown?.merkl_apy_boost?.total_apr ?? breakdown?.merkle_apy ?? 0); + const pointBoostsFromBreakdown = breakdown?.points_apy_boost?.boosts_by_points || pointBoosts; + const pointRewardApyFromBreakdown = + breakdown?.points_apy_boost?.total_apy_boost_percent ?? + pointBoostsFromBreakdown.reduce((sum, b) => sum + Number(b?.apy_boost_percent || 0), 0); + const pointRewardTokens = pointBoostsFromBreakdown.map((b) => b?.point_name).filter(Boolean); + + const merklTokens = + breakdown?.merkl_apy_boost?.tokens?.map((t) => t?.address?.toLowerCase()).filter(Boolean) || []; + + const rewardsBoost = Number(breakdown?.rewards_apy_boost?.total_apy_boost_percent ?? 0); + const rewardBoostTokens = + breakdown?.rewards_apy_boost?.boosts_by_token + ?.map((b) => b?.token?.address || b?.address || b?.token_address) + .filter(Boolean) + .map((addr) => addr.toLowerCase()) || []; + + const totalApyReward = merklApy + pointRewardApyFromBreakdown + rewardsBoost || null; + const combinedRewardTokens = Array.from( + new Set([...(merklTokens || []), ...rewardBoostTokens, ...pointRewardTokens]) + ); + + return { + pool: `${item.loan_address}-${chainName}`.toLowerCase(), + chain: utils.formatChain(chainName), + project: 'accountable', + symbol: utils.formatSymbol(item.asset_symbol), + tvlUsd: formatAmount(stats.tvl, 6), + apyBase: baseApy, + apyReward: totalApyReward, + rewardTokens: combinedRewardTokens, + url: `https://yield.accountable.capital/vaults/${item.loan_address}`, + totalSupplyUsd: formatAmount(stats.totalSupplied, 6), + totalBorrowUsd: formatAmount(stats.totalBorrowed, 6), + }; + }) + ); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/across/abi/AcceleratingDistributor.json b/src/adaptors/across/abi/AcceleratingDistributor.json new file mode 100644 index 0000000000..08314ba153 --- /dev/null +++ b/src/adaptors/across/abi/AcceleratingDistributor.json @@ -0,0 +1,503 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_rewardToken", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenCumulativeStaked", + "type": "uint256" + } + ], + "name": "Exit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "RecoverErc20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsToSend", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenLastUpdateTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenRewardPerTokenStored", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "userRewardsOutstanding", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "userRewardsPaidPerToken", + "type": "uint256" + } + ], + "name": "RewardsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "averageDepositTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cumulativeBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenCumulativeStaked", + "type": "uint256" + } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "baseEmissionRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxMultiplier", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "secondsToMaxMultiplier", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + } + ], + "name": "TokenConfiguredForStaking", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingCumulativeBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenCumulativeStaked", + "type": "uint256" + } + ], + "name": "Unstake", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" } + ], + "name": "baseRewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "bool", "name": "enabled", "type": "bool" }, + { + "internalType": "uint256", + "name": "baseEmissionRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "maxMultiplier", "type": "uint256" }, + { + "internalType": "uint256", + "name": "secondsToMaxMultiplier", + "type": "uint256" + } + ], + "name": "configureStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" } + ], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getAverageDepositTimePostDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" } + ], + "name": "getCumulativeStaked", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getOutstandingRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getTimeSinceAverageDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getUserRewardMultiplier", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getUserStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "cumulativeBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageDepositTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardsAccumulatedPerToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardsOutstanding", + "type": "uint256" + } + ], + "internalType": "struct AcceleratingDistributor.UserDeposit", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenAddress", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "recoverErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "stakingTokens", + "outputs": [ + { "internalType": "bool", "name": "enabled", "type": "bool" }, + { + "internalType": "uint256", + "name": "baseEmissionRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "maxMultiplier", "type": "uint256" }, + { + "internalType": "uint256", + "name": "secondsToMaxMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "cumulativeStaked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { "internalType": "uint256", "name": "lastUpdateTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "stakedToken", "type": "address" } + ], + "name": "withdrawReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/across/constants.js b/src/adaptors/across/constants.js new file mode 100644 index 0000000000..6e54bfa579 --- /dev/null +++ b/src/adaptors/across/constants.js @@ -0,0 +1,59 @@ +const ADContractAbi = require('./abi/AcceleratingDistributor.json'); + +const SECONDS_PER_YEAR = 31557600; // 365.25 days per year + +const contracts = { + AcceleratedDistributor: { + address: '0x9040e41ef5e8b281535a96d9a48acb8cfabd9a48', + abi: ADContractAbi, + }, +}; + +const tokens = { + WETH: { + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + lpAddress: '0x28f77208728b0a45cab24c4868334581fe86f95b', + }, + USDC: { + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + lpAddress: '0xc9b09405959f63f72725828b5d449488b02be1ca', + }, + USDT: { + address: '0xdac17f958d2ee523a2206206994597c13d831ec7', + lpAddress: '0xc2fab88f215f62244d2e32c8a65e8f58da8415a5', + }, + WBTC: { + address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + lpAddress: '0x59c1427c658e97a7d568541dac780b2e5c8affb4', + }, + DAI: { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + lpAddress: '0x4fabacac8c41466117d6a38f46d08ddd4948a0cb', + }, + ACX: { + address: '0x44108f0223a3c3028f5fe7aec7f9bb2e66bef82f', + lpAddress: '0xb0c8fef534223b891d4a430e49537143829c4817', + }, + UMA: { + address: '0x04fa0d235c4abf4bcf4787af4cf447de572ef828', + lpAddress: '0xb9921d28466304103a233fcd071833e498f12853', + }, + BAL: { + address: '0xba100000625a3754423978a60c9317c58a424e3d', + lpAddress: '0xfacd2ec4647df2cb758f684c2aaab56a93288f9e', + }, + SNX: { + address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f', + lpAddress: '0xe480f5a42e263ac0352d0c9c6e75c4a612ee52a7', + }, + POOL: { + address: '0x0cec1a9154ff802e7934fc916ed7ca50bde6844e', + lpAddress: '0xc3f35d90ebce372ded12029b72b22a23a2f637fd', + } +}; + +module.exports = { + SECONDS_PER_YEAR, + contracts, + tokens, +}; diff --git a/src/adaptors/across/index.js b/src/adaptors/across/index.js new file mode 100644 index 0000000000..7e271cb45d --- /dev/null +++ b/src/adaptors/across/index.js @@ -0,0 +1,139 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { ethers } = require('ethers'); + +const utils = require('../utils'); +const { SECONDS_PER_YEAR, contracts, tokens } = require('./constants'); + +const fixedPoint = ethers.utils.parseUnits('1'); + +const rewardApr = (underlyingToken, stakingPool, rewardToken) => { + const { enabled, baseEmissionRate, cumulativeStaked } = stakingPool; + + if (!enabled) return 0.0; + + const underlyingTokenPrice = ethers.utils.parseUnits( + underlyingToken.price.toString() + ); + const rewardTokenPrice = ethers.utils.parseUnits( + rewardToken.price.toString() + ); + + // Normalise to 18 decimals and convert LP token => underlying token. + const cumulativeStakedUsd = ethers.utils + .parseUnits(cumulativeStaked) + .mul(ethers.utils.parseUnits('1', 18 - underlyingToken.decimals).toString()) + .mul(underlyingToken.exchangeRateCurrent) + .div(fixedPoint) + .mul(underlyingTokenPrice) + .div(fixedPoint); + + const rewardsPerYearUsd = ethers.utils + .parseUnits(baseEmissionRate) + .mul(ethers.utils.parseUnits('1', 18 - rewardToken.decimals).toString()) + .mul(SECONDS_PER_YEAR.toString()) + .mul(rewardTokenPrice) + .div(fixedPoint); + + const apr = ethers.utils.formatUnits( + rewardsPerYearUsd.mul('100').mul(fixedPoint).div(cumulativeStakedUsd) + ); + + return Number(apr); +}; + +const queryLiquidityPool = async (l1TokenAddr) => { + return (await axios.get(`https://across.to/api/pools?token=${l1TokenAddr}`)) + .data; +}; + +const queryLiquidityPools = async (l1TokenAddrs) => { + const pools = await Promise.all( + l1TokenAddrs.map((l1TokenAddr) => queryLiquidityPool(l1TokenAddr)) + ); + + return Object.fromEntries( + pools.map((pool, i) => { + return [l1TokenAddrs[i].toLowerCase(), pool]; + }) + ); +}; + +const apy = async () => { + // Note lpTokenAddrs is included in the Across API /pools response. These + // LP token addresses are however hardcoded in constants so that the staking + // pool lookups can occur in parallel with all other external lookups. + const tokenAddrs = Object.values(tokens).map((token) => token.address); + const lpTokenAddrs = Object.values(tokens).map((token) => token.lpAddress); + + const [totalSupplyRes, decimalsRes] = await Promise.all( + ['erc20:totalSupply', 'erc20:decimals'].map( + async (m) => + await sdk.api.abi.multiCall({ + calls: lpTokenAddrs.map((i) => ({ target: i })), + abi: m, + }) + ) + ); + const totalSupply = totalSupplyRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + + const keys = tokenAddrs.map((addr) => `ethereum:${addr}`).join(); + const tokenPrices = ( + await axios.get(`https://coins.llama.fi/prices/current/${keys}`) + ).data.coins; + + const liquidityPools = await queryLiquidityPools(tokenAddrs); + + const { address, abi } = contracts.AcceleratedDistributor; + const rewardToken = ( + await sdk.api.abi.call({ + target: address, + abi: abi.find((m) => m.name === 'rewardToken'), + }) + ).output.toLowerCase(); + + const stakingTokens = ( + await sdk.api.abi.multiCall({ + calls: lpTokenAddrs.map((i) => ({ target: address, params: i })), + abi: abi.find((m) => m.name === 'stakingTokens'), + }) + ).output.map((o, i) => o.output); + + return Object.entries(tokens).map((token, i) => { + const underlying = token[1].address; + + const underlyingPrice = tokenPrices[`ethereum:${underlying}`]?.price; + + const tvlUsd = (underlyingPrice * totalSupply[i]) / 10 ** decimals[i]; + + const apyReward = rewardApr( + { + ...token, + price: underlyingPrice, + exchangeRateCurrent: liquidityPools[underlying].exchangeRateCurrent, + decimals: decimals[i], + }, + stakingTokens[i], + tokenPrices[`ethereum:${rewardToken}`] + ); + + return { + pool: underlying, // should be changed to lp token + chain: 'Ethereum', + project: 'across', + symbol: utils.formatSymbol(token[0]), + tvlUsd, + underlyingTokens: [underlying], + apyBase: Number(liquidityPools[underlying].estimatedApy) * 100, + apyReward: apyReward > 0 ? apyReward : 0, + rewardTokens: apyReward > 0 ? [rewardToken] : null, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://across.to/pool', +}; diff --git a/src/adaptors/acryptos/index.js b/src/adaptors/acryptos/index.js new file mode 100644 index 0000000000..1d8978a90b --- /dev/null +++ b/src/adaptors/acryptos/index.js @@ -0,0 +1,81 @@ +const utils = require('../utils'); + +const urlApi = 'https://api.unrekt.net/api/v2/acryptos-asset.json'; + +const chainMapping = { + 1: 'ethereum', + 10: 'optimism', + 56: 'binance', + 25: 'cronos', + 100: 'xdai', + 137: 'polygon', + 250: 'fantom', + 592: 'astar', + 1284: 'moonbeam', + 1285: 'moonriver', + 2222: 'kava', + 7700: 'canto', + 8453: 'base', + 42161: 'arbitrum', + 43114: 'avalanche', + 59144: 'linea', + 1666600000: 'harmony', +}; + +const fetch = (dataTvl, chainMapping) => { + const data = []; + + for (const chain of Object.keys(chainMapping)) { + poolData = dataTvl[chain]; + + if (poolData === undefined) continue; + + for (const [addr, details] of Object.entries(poolData)) { + if (details.status === 'deprecated') { + continue; + } + data.push({ + id: `acryptos-${chain}${addr}`, + network: chain, + symbol: details.tokensymbol, + tvl: details.tvl_usd, + apy: details.apytotal, + platform: details.platform, + }); + } + } + return data; +}; + +const buildObject = (entry) => { + const platform = entry.platform; + const payload = { + pool: entry.id, + chain: utils.formatChain(chainMapping[entry.network]), + project: 'acryptos', + symbol: utils.formatSymbol(entry.symbol), + poolMeta: platform.charAt(0).toUpperCase() + platform.slice(1), + tvlUsd: Number(entry.tvl), + apy: Number(entry.apy), + }; + + return payload; +}; + +const main = async () => { + // pull data + const dataApi = await utils.getData(urlApi); + + let data = fetch(dataApi.assets, chainMapping); + + // build pool objects + data = data.map((el) => buildObject(el)); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.acryptos.com/', +}; diff --git a/src/adaptors/aegis/index.js b/src/adaptors/aegis/index.js new file mode 100644 index 0000000000..4706fa8c01 --- /dev/null +++ b/src/adaptors/aegis/index.js @@ -0,0 +1,50 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +async function getTvl(token, chain) { + const tvl = await sdk.api.abi.call({ + target: token, + abi: 'uint256:totalSupply', + chain: chain + }); + return tvl.output / 1e18; +} + +const apy = async () => { + const aegisFetch = await superagent + .get('https://api.aegis.im/api/project-stats') + .set('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36') + + const aegisData = aegisFetch.body.data; + const aegisEth = '0x4274cD7277C7bb0806Bd5FE84b9aDAE466a8DA0a'; + const aegisBsc = '0xAB3dBcD9B096C3fF76275038bf58eAC10D22C61f'; + + const aegisEthTvl = await getTvl(aegisEth, 'ethereum'); + const aegisBscTvl = await getTvl(aegisBsc, 'bsc'); + const yusdPools = [ + { + pool: '0x4274cD7277C7bb0806Bd5FE84b9aDAE466a8DA0a-ethereum'.toLowerCase(), + chain: 'Ethereum', + project: 'aegis', + symbol: 'YUSD', + tvlUsd: aegisEthTvl, + apy: aegisData.efficient_apr, + }, + { + pool: '0xAB3dBcD9B096C3fF76275038bf58eAC10D22C61f-binance'.toLowerCase(), + chain: 'Binance', + project: 'aegis', + symbol: 'YUSD', + tvlUsd: aegisBscTvl, + apy: aegisData.efficient_apr, + }, + ]; + + return yusdPools; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.aegis.im/', +}; diff --git a/src/adaptors/aerodrome-slipstream/abiSugar.json b/src/adaptors/aerodrome-slipstream/abiSugar.json new file mode 100644 index 0000000000..cadc9f7834 --- /dev/null +++ b/src/adaptors/aerodrome-slipstream/abiSugar.json @@ -0,0 +1,931 @@ +[ + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_voter", + "type": "address" + }, + { + "name": "_registry", + "type": "address" + }, + { + "name": "_convertor", + "type": "address" + }, + { + "name": "_slipstream_helper", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "forSwaps", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokens", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + }, + { + "name": "_addresses", + "type": "address[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "token_address", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "account_balance", + "type": "uint256" + }, + { + "name": "listed", + "type": "bool" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "all", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "tick", + "type": "int24" + }, + { + "name": "sqrt_ratio", + "type": "uint160" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "reserve0", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "reserve1", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "gauge", + "type": "address" + }, + { + "name": "gauge_liquidity", + "type": "uint256" + }, + { + "name": "gauge_alive", + "type": "bool" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "emissions_token", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + }, + { + "name": "unstaked_fee", + "type": "uint256" + }, + { + "name": "token0_fees", + "type": "uint256" + }, + { + "name": "token1_fees", + "type": "uint256" + }, + { + "name": "nfpm", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "byIndex", + "inputs": [ + { + "name": "_index", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "tick", + "type": "int24" + }, + { + "name": "sqrt_ratio", + "type": "uint160" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "reserve0", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "reserve1", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "gauge", + "type": "address" + }, + { + "name": "gauge_liquidity", + "type": "uint256" + }, + { + "name": "gauge_alive", + "type": "bool" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "emissions_token", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + }, + { + "name": "unstaked_fee", + "type": "uint256" + }, + { + "name": "token0_fees", + "type": "uint256" + }, + { + "name": "token1_fees", + "type": "uint256" + }, + { + "name": "nfpm", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "positions", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "staked", + "type": "uint256" + }, + { + "name": "amount0", + "type": "uint256" + }, + { + "name": "amount1", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "unstaked_earned0", + "type": "uint256" + }, + { + "name": "unstaked_earned1", + "type": "uint256" + }, + { + "name": "emissions_earned", + "type": "uint256" + }, + { + "name": "tick_lower", + "type": "int24" + }, + { + "name": "tick_upper", + "type": "int24" + }, + { + "name": "sqrt_ratio_lower", + "type": "uint160" + }, + { + "name": "sqrt_ratio_upper", + "type": "uint160" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "positionsByFactory", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + }, + { + "name": "_factory", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "staked", + "type": "uint256" + }, + { + "name": "amount0", + "type": "uint256" + }, + { + "name": "amount1", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "unstaked_earned0", + "type": "uint256" + }, + { + "name": "unstaked_earned1", + "type": "uint256" + }, + { + "name": "emissions_earned", + "type": "uint256" + }, + { + "name": "tick_lower", + "type": "int24" + }, + { + "name": "tick_upper", + "type": "int24" + }, + { + "name": "sqrt_ratio_lower", + "type": "uint160" + }, + { + "name": "sqrt_ratio_upper", + "type": "uint160" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "epochsLatest", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "ts", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "votes", + "type": "uint256" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "bribes", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + }, + { + "name": "fees", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "epochsByAddress", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_address", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "ts", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "votes", + "type": "uint256" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "bribes", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + }, + { + "name": "fees", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_venft_id", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "venft_id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + }, + { + "name": "token", + "type": "address" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewardsByAddress", + "inputs": [ + { + "name": "_venft_id", + "type": "uint256" + }, + { + "name": "_pool", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "venft_id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + }, + { + "name": "token", + "type": "address" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_FACTORIES", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_POOLS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_TOKENS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_LPS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_EPOCHS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_REWARDS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "MAX_POSITIONS", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "WEEK", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "registry", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voter", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "convertor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "cl_helper", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/aerodrome-slipstream/abiSugarHelper.json b/src/adaptors/aerodrome-slipstream/abiSugarHelper.json new file mode 100644 index 0000000000..ac33b3b751 --- /dev/null +++ b/src/adaptors/aerodrome-slipstream/abiSugarHelper.json @@ -0,0 +1,475 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tickLow", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickHigh", + "type": "int24" + } + ], + "name": "estimateAmount0", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tickLow", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickHigh", + "type": "int24" + } + ], + "name": "estimateAmount1", + "outputs": [ + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "positionManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "fees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "getAmount0Delta", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidity", + "type": "int128" + } + ], + "name": "getAmount0Delta", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidity", + "type": "int128" + } + ], + "name": "getAmount1Delta", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "getAmount1Delta", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "getAmountsForLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + } + ], + "name": "getLiquidityForAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "startTick", + "type": "int24" + } + ], + "name": "getPopulatedTicks", + "outputs": [ + { + "components": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + } + ], + "internalType": "struct ISugarHelper.PopulatedTick[]", + "name": "populatedTicks", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "getSqrtRatioAtTick", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "getTickAtSqrtRatio", + "outputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "int24", + "name": "tickCurrent", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "poolFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "positionManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + } + ], + "name": "principal", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/aerodrome-slipstream/index.js b/src/adaptors/aerodrome-slipstream/index.js new file mode 100644 index 0000000000..7fd64972dc --- /dev/null +++ b/src/adaptors/aerodrome-slipstream/index.js @@ -0,0 +1,290 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const abiSugar = require('./abiSugar.json'); +const abiSugarHelper = require('./abiSugarHelper.json'); +const { pool } = require('../rocifi-v2/abi'); + +const AERO = '0x940181a94A35A4569E4529A3CDfB74e38FD98631'; +const sugar = '0x92294D631E995f1dd9CeE4097426e6a71aB87Bcf'; +const sugarHelper = '0x6d2D739bf37dFd93D804523c2dfA948EAf32f8E1'; +const nullAddress = '0x0000000000000000000000000000000000000000'; +const PROJECT = 'aerodrome-slipstream'; +const CHAIN = 'base'; +const SUBGRAPH = sdk.graph.modifyEndpoint('GENunSHWLBXm59mBSgPzQ8metBEp9YDfdqwFr91Av1UM'); + +const tickWidthMappings = {1: 5, 50: 5, 100: 15, 200: 10, 2000: 2}; + +const query = gql` +{ + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, block: {number: }) { + id + reserve0: totalValueLockedToken0 + reserve1: totalValueLockedToken1 + volumeUSD + volumeToken0 + feeTier + token0 { + symbol + id + } + token1 { + symbol + id + } + } +} +`; + +const queryPrior = gql` +{ + pools(first: 1000 orderBy: totalValueLockedUSD orderDirection: desc, block: {number: }) { + id + volumeUSD + volumeToken0 + } +} +`; + +async function getPoolVolumes(timestamp = null) { + const [block, blockPrior] = await utils.getBlocks(CHAIN, timestamp, [ + SUBGRAPH, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + CHAIN, + timestamp, + [SUBGRAPH], + 604800 + ); + + // pull data + let dataNow = await request(SUBGRAPH, query.replace('', block)); + dataNow = dataNow.pools; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + SUBGRAPH, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // 7d offset + const dataPrior7d = ( + await request(SUBGRAPH, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, CHAIN); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + const pools = {} + for (const p of dataNow.filter(p => p.volumeUSD1d >= 0 && (!isNaN(p.apy1d) || !isNaN(p.apy7d)))) { + const url = 'https://aerodrome.finance/deposit?token0=' + p.token0.id + '&token1=' + p.token1.id + '&factory=' + p.factory; + const poolMeta = 'CL' + ' - ' + (Number(p.feeTier) / 10000).toString() + '%'; + const underlyingTokens = [p.token0.id, p.token1.id]; + + const poolAddress = utils.formatAddress(p.id); + pools[poolAddress] = { + pool: poolAddress, + chain: utils.formatChain('base'), + project: PROJECT, + poolMeta, + symbol: `${p.token0.symbol}-${p.token1.symbol}`, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + } + } + + return pools; +} + +const getGaugeApy = async () => { + const chunkSize = 400; + let currentOffset = 1650; // Ignore older non-Slipstream pools + let unfinished = true; + let allPoolsData = []; + + while (unfinished) { + const poolsChunkUnfiltered = ( + await sdk.api.abi.call({ + target: sugar, + params: [chunkSize, currentOffset], + abi: abiSugar.find((m) => m.name === 'all'), + chain: 'base', + }) + ).output; + + const poolsChunk = poolsChunkUnfiltered.filter(t => Number(t.type) > 0 && t.gauge != nullAddress); + + unfinished = poolsChunkUnfiltered.length !== 0; + currentOffset += chunkSize; + allPoolsData.push(...poolsChunk); + } + + unfinished = true; + currentOffset = 0; + let allTokenData = []; + + while (unfinished) { + const tokensChunk = ( + await sdk.api.abi.call({ + target: sugar, + params: [chunkSize, currentOffset, sugar, []], + abi: abiSugar.find((m) => m.name === 'tokens'), + chain: 'base', + }) + ).output; + + unfinished = tokensChunk.length !== 0; + currentOffset += chunkSize; + allTokenData.push(...tokensChunk); + } + + const tokens = [ + ...new Set( + allPoolsData + .map((m) => [m.token0, m.token1]) + .flat() + .concat(AERO) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `base:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA.flat()) { + prices = { ...prices, ...p }; + } + + let allStakedData = []; + for (let pool of allPoolsData) { + // don't waste RPC calls if gauge has no staked liquidity + if (Number(pool.gauge_liquidity) == 0) { + allStakedData.push({'amount0': 0, 'amount1': 0}); + continue; + } + + const wideTickAmount = tickWidthMappings[Number(pool.type)] !== undefined ? tickWidthMappings[Number(pool.type)] : 5; + const lowTick = Number(pool.tick) - (wideTickAmount * Number(pool.type)); + const highTick = Number(pool.tick) + ((wideTickAmount - 1) * Number(pool.type)); + + const ratioA = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [lowTick], + abi: abiSugarHelper.find((m) => m.name === 'getSqrtRatioAtTick'), + chain: 'base', + }) + ).output; + + const ratioB = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [highTick], + abi: abiSugarHelper.find((m) => m.name === 'getSqrtRatioAtTick'), + chain: 'base', + }) + ).output; + + // fetch staked liquidity around wide set of ticks + const stakedAmounts = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [pool.sqrt_ratio, ratioA, ratioB, pool.gauge_liquidity], + abi: abiSugarHelper.find((m) => m.name === 'getAmountsForLiquidity'), + chain: 'base', + }) + ).output; + + allStakedData.push(stakedAmounts); + } + + const pools = allPoolsData.map((p, i) => { + const token0Data = allTokenData.find(({token_address}) => token_address == p.token0); + const token1Data = allTokenData.find(({token_address}) => token_address == p.token1); + + const p0 = prices[`base:${p.token0}`]?.price; + const p1 = prices[`base:${p.token1}`]?.price; + + const tvlUsd = ((p.reserve0 / (10**token0Data.decimals)) * p0) + ((p.reserve1 / (10**token1Data.decimals)) * p1); + + // use wider staked TVL across many ticks + const stakedTvlUsd = ((allStakedData[i]['amount0'] / (10**token0Data.decimals)) * p0) + ((allStakedData[i]['amount1'] / (10**token1Data.decimals)) * p1); + + const s = token0Data.symbol + '-' + token1Data.symbol; + + const apyReward = + (((p.emissions / 1e18) * 86400 * 365 * prices[`base:${AERO}`]?.price) / + stakedTvlUsd) * + 100; + + const url = 'https://aerodrome.finance/deposit?token0=' + p.token0 + '&token1=' + p.token1 + '&type=' + p.type.toString() + '&factory=' + p.factory; + const poolMeta = 'CL' + p.type.toString() + ' - ' + (p.pool_fee / 10000).toString() + '%'; + + return { + pool: utils.formatAddress(p.lp), + chain: utils.formatChain('base'), + project: PROJECT, + symbol: s, + tvlUsd, + apyReward, + rewardTokens: apyReward ? [AERO] : [], + underlyingTokens: [p.token0, p.token1], + poolMeta, + url, + }; + }); + + const poolsApy = {}; + for (const pool of pools.filter((p) => utils.keepFinite(p))) { + poolsApy[pool.pool] = pool; + } + + return poolsApy; +}; + +async function main(timestamp = null) { + const poolsApy = await getGaugeApy(); + const poolsVolumes = await getPoolVolumes(timestamp); + + // left-join volumes onto APY output to avoid filtering out pools + return Object.values(poolsApy).map((pool) => { + const v = poolsVolumes[pool.pool]; + return { + ...pool, + apyBase: v?.apyBase, + apyBase7d: v?.apyBase7d, + volumeUsd1d: v?.volumeUsd1d, + volumeUsd7d: v?.volumeUsd7d, + }; + }); +} + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/aerodrome-v1/abiGauge.json b/src/adaptors/aerodrome-v1/abiGauge.json new file mode 100644 index 0000000000..33e60ad34b --- /dev/null +++ b/src/adaptors/aerodrome-v1/abiGauge.json @@ -0,0 +1,345 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_forwarder", "type": "address" }, + { "internalType": "address", "name": "_stakingToken", "type": "address" }, + { + "internalType": "address", + "name": "_feesVotingReward", + "type": "address" + }, + { "internalType": "address", "name": "_rewardToken", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "bool", "name": "_isPool", "type": "bool" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "NotAlive", "type": "error" }, + { "inputs": [], "name": "NotAuthorized", "type": "error" }, + { "inputs": [], "name": "NotTeam", "type": "error" }, + { "inputs": [], "name": "NotVoter", "type": "error" }, + { "inputs": [], "name": "RewardRateTooHigh", "type": "error" }, + { "inputs": [], "name": "ZeroAmount", "type": "error" }, + { "inputs": [], "name": "ZeroRewardRate", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_recipient", "type": "address" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feesVotingReward", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "forwarder", "type": "address" } + ], + "name": "isTrustedForwarder", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "notifyRewardWithoutClaim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardRateByEpoch", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/aerodrome-v1/abiPool.json b/src/adaptors/aerodrome-v1/abiPool.json new file mode 100644 index 0000000000..27b3ac4ad2 --- /dev/null +++ b/src/adaptors/aerodrome-v1/abiPool.json @@ -0,0 +1,773 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "BelowMinimumK", "type": "error" }, + { "inputs": [], "name": "DepositsNotEqual", "type": "error" }, + { "inputs": [], "name": "FactoryAlreadySet", "type": "error" }, + { "inputs": [], "name": "InsufficientInputAmount", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidity", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidityBurned", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidityMinted", "type": "error" }, + { "inputs": [], "name": "InsufficientOutputAmount", "type": "error" }, + { "inputs": [], "name": "InvalidTo", "type": "error" }, + { "inputs": [], "name": "IsPaused", "type": "error" }, + { "inputs": [], "name": "K", "type": "error" }, + { "inputs": [], "name": "NotEmergencyCouncil", "type": "error" }, + { + "inputs": [{ "internalType": "string", "name": "str", "type": "string" }], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "version", "type": "string" }, + { "internalType": "uint256", "name": "chainId", "type": "uint256" }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, + { "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getK", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" }, + { "internalType": "bool", "name": "_stable", "type": "bool" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct IPool.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodSize", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolFees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "__name", "type": "string" } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "__symbol", "type": "string" } + ], + "name": "setSymbol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/aerodrome-v1/abiPoolsFactory.json b/src/adaptors/aerodrome-v1/abiPoolsFactory.json new file mode 100644 index 0000000000..fb73de847b --- /dev/null +++ b/src/adaptors/aerodrome-v1/abiPoolsFactory.json @@ -0,0 +1,336 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "FeeInvalid", "type": "error" }, + { "inputs": [], "name": "FeeTooHigh", "type": "error" }, + { "inputs": [], "name": "InvalidPool", "type": "error" }, + { "inputs": [], "name": "NotFeeManager", "type": "error" }, + { "inputs": [], "name": "NotPauser", "type": "error" }, + { "inputs": [], "name": "NotVoter", "type": "error" }, + { "inputs": [], "name": "PoolAlreadyExists", "type": "error" }, + { "inputs": [], "name": "SameAddress", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { "inputs": [], "name": "ZeroFee", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "SetCustomFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeManager", + "type": "address" + } + ], + "name": "SetFeeManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "SetPauseState", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pauser", + "type": "address" + } + ], + "name": "SetPauser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "voter", + "type": "address" + } + ], + "name": "SetVoter", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ZERO_FEE_INDICATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPoolsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "customFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "bool", "name": "_stable", "type": "bool" } + ], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "name": "isPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "uint256", "name": "fee", "type": "uint256" } + ], + "name": "setCustomFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_stable", "type": "bool" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPauseState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pauser", "type": "address" } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voter", "type": "address" } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/aerodrome-v1/abiVoter.json b/src/adaptors/aerodrome-v1/abiVoter.json new file mode 100644 index 0000000000..652ba68367 --- /dev/null +++ b/src/adaptors/aerodrome-v1/abiVoter.json @@ -0,0 +1,781 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_forwarder", "type": "address" }, + { "internalType": "address", "name": "_ve", "type": "address" }, + { + "internalType": "address", + "name": "_factoryRegistry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AlreadyVotedOrDeposited", "type": "error" }, + { "inputs": [], "name": "DistributeWindow", "type": "error" }, + { "inputs": [], "name": "FactoryPathNotApproved", "type": "error" }, + { "inputs": [], "name": "GaugeAlreadyKilled", "type": "error" }, + { "inputs": [], "name": "GaugeAlreadyRevived", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "GaugeDoesNotExist", + "type": "error" + }, + { "inputs": [], "name": "GaugeExists", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "GaugeNotAlive", + "type": "error" + }, + { "inputs": [], "name": "InactiveManagedNFT", "type": "error" }, + { "inputs": [], "name": "MaximumVotingNumberTooLow", "type": "error" }, + { "inputs": [], "name": "NonZeroVotes", "type": "error" }, + { "inputs": [], "name": "NotAPool", "type": "error" }, + { "inputs": [], "name": "NotApprovedOrOwner", "type": "error" }, + { "inputs": [], "name": "NotEmergencyCouncil", "type": "error" }, + { "inputs": [], "name": "NotGovernor", "type": "error" }, + { "inputs": [], "name": "NotMinter", "type": "error" }, + { "inputs": [], "name": "NotWhitelistedNFT", "type": "error" }, + { "inputs": [], "name": "NotWhitelistedToken", "type": "error" }, + { "inputs": [], "name": "SameValue", "type": "error" }, + { "inputs": [], "name": "SpecialVotingWindow", "type": "error" }, + { "inputs": [], "name": "TooManyPools", "type": "error" }, + { "inputs": [], "name": "UnequalLengths", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { "inputs": [], "name": "ZeroBalance", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolFactory", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "votingRewardsFactory", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gaugeFactory", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bribeVotingReward", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeVotingReward", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_bool", + "type": "bool" + } + ], + "name": "WhitelistNFT", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_bool", + "type": "bool" + } + ], + "name": "WhitelistToken", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_fees", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolFactory", "type": "address" }, + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_mTokenId", "type": "uint256" } + ], + "name": "depositManaged", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_start", "type": "uint256" }, + { "internalType": "uint256", "name": "_finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epochGovernor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochNext", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochVoteEnd", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochVoteStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "factoryRegistry", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forwarder", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugeToBribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugeToFees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "forwarder", "type": "address" } + ], + "name": "isTrustedForwarder", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "isWhitelistedNFT", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelistedToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxVotingNum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_epochGovernor", "type": "address" } + ], + "name": "setEpochGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_maxVotingNum", "type": "uint256" } + ], + "name": "setMaxVotingNum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "bool", "name": "_bool", "type": "bool" } + ], + "name": "whitelistNFT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "bool", "name": "_bool", "type": "bool" } + ], + "name": "whitelistToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "withdrawManaged", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/aerodrome-v1/index.js b/src/adaptors/aerodrome-v1/index.js new file mode 100644 index 0000000000..495b400b7f --- /dev/null +++ b/src/adaptors/aerodrome-v1/index.js @@ -0,0 +1,285 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const abiPool = require('./abiPool.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); +const abiPoolsFactory = require('./abiPoolsFactory.json'); + +const poolsFactory = '0x420DD381b31aEf6683db6B902084cB0FFECe40Da'; +const voter = '0x16613524e02ad97eDfeF371bC883F2F5d6C480A5'; +const AERO = '0x940181a94A35A4569E4529A3CDfB74e38FD98631'; + +const PROJECT = 'aerodrome-v1'; +const CHAIN = 'base'; +const SUBGRAPH = sdk.graph.modifyEndpoint('7uEwiKmfbRQqV8Ec9nvdKrMFVFQv5qaM271gdBvHtywj'); + +const query = gql` + { + pairs(first: 1000, orderBy: reserveUSD, orderDirection: desc, block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + feeTier: token0Fee + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: reserveUSD orderDirection: desc, block: {number: }) { + id + volumeUSD + } + } +`; + +async function getPoolVolumes(timestamp = null) { + const [block, blockPrior] = await utils.getBlocks(CHAIN, timestamp, [ + SUBGRAPH, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + CHAIN, + timestamp, + [SUBGRAPH], + 604800 + ); + + // pull data + let dataNow = await request(SUBGRAPH, query.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + SUBGRAPH, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(SUBGRAPH, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, CHAIN); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + const pools = {} + for (const p of dataNow.filter(p => p.volumeUSD1d >= 0 && (!isNaN(p.apy1d) || !isNaN(p.apy7d)))) { + const url = 'https://aerodrome.finance/deposit?token0=' + p.token0.id + '&token1=' + p.token1.id + '&factory=0x420DD381b31aEf6683db6B902084cB0FFECe40Da'; + const underlyingTokens = [p.token0.id, p.token1.id]; + + const poolAddress = utils.formatAddress(p.id); + pools[poolAddress] = { + pool: poolAddress, + chain: utils.formatChain('base'), + project: PROJECT, + symbol: `${p.token0.symbol}-${p.token1.symbol}`, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + } + } + + return pools; +} + +const getGaugeApy = async () => { + const allPoolsLength = ( + await sdk.api.abi.call({ + target: poolsFactory, + abi: abiPoolsFactory.find((m) => m.name === 'allPoolsLength'), + chain: CHAIN, + }) + ).output; + + const allPools = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPoolsLength)).keys()].map((i) => ({ + target: poolsFactory, + params: [i], + })), + abi: abiPoolsFactory.find((m) => m.name === 'allPools'), + chain: CHAIN, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: i, + })), + abi: abiPool.find((m) => m.name === 'metadata'), + chain: CHAIN, + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: i, + })), + abi: abiPool.find((m) => m.name === 'symbol'), + chain: CHAIN, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: CHAIN, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: CHAIN, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const poolSupply = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ target: i })), + chain: CHAIN, + abi: 'erc20:totalSupply', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'totalSupply'), + chain: CHAIN, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(AERO) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `${CHAIN}:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA.flat()) { + prices = { ...prices, ...p }; + } + + const pools = allPools.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`${CHAIN}:${poolMeta.t0}`]?.price; + const p1 = prices[`${CHAIN}:${poolMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const pairPrice = (tvlUsd * 1e18) / totalSupply[i]; + + // Only staked supply is eligible for the rewardRate's emissions + let stakedSupplyRatio = 1; + if (totalSupply[i] !== 0) { + stakedSupplyRatio = poolSupply[i] / totalSupply[i]; + } + + const apyReward = + (((rewardRate[i] / 1e18) * 86400 * 365 * prices[`${CHAIN}:${AERO}`]?.price) / + tvlUsd) * stakedSupplyRatio * + 100; + + return { + pool: utils.formatAddress(p), + chain: utils.formatChain(CHAIN), + project: PROJECT, + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [AERO] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + url: `https://aerodrome.finance/deposit?token0=${poolMeta.t0}&token1=${poolMeta.t1}&type=-1&chain0=8453&chain1=8453&factory=0x420DD381b31aEf6683db6B902084cB0FFECe40Da`, + }; + }); + + const poolsApy = {}; + for (const pool of pools.filter((p) => utils.keepFinite(p))) { + poolsApy[pool.pool] = pool; + } + + return poolsApy; +}; + +async function main(timestamp = null) { + const poolsApy = await getGaugeApy(); + const poolsVolumes = await getPoolVolumes(timestamp); + + // left-join volumes onto APY output to avoid filtering out pools + return Object.values(poolsApy).map((pool) => { + const v = poolsVolumes[pool.pool]; + return { + ...pool, + apyBase: v?.apyBase, + apyBase7d: v?.apyBase7d, + volumeUsd1d: v?.volumeUsd1d, + volumeUsd7d: v?.volumeUsd7d, + }; + }); +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://aerodrome.finance/liquidity', +}; diff --git a/src/adaptors/affine-defi-earn/abi.json b/src/adaptors/affine-defi-earn/abi.json new file mode 100644 index 0000000000..b118be60a6 --- /dev/null +++ b/src/adaptors/affine-defi-earn/abi.json @@ -0,0 +1,52 @@ +[ + { + "inputs": [], + "name": "detailedTVL", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "num", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct DetailedShare.Number", + "name": "tvl", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "detailedPrice", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "num", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct DetailedShare.Number", + "name": "price", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/affine-defi-earn/index.js b/src/adaptors/affine-defi-earn/index.js new file mode 100644 index 0000000000..8e0014f3a9 --- /dev/null +++ b/src/adaptors/affine-defi-earn/index.js @@ -0,0 +1,219 @@ +const { api } = require('@defillama/sdk'); +const axios = require('axios'); +const ABI = require('./abi.json'); + +const API_URL = 'https://api.affinedefi.com'; + +const SUPPORTED_CHAINS = { + 1: 'ethereum', + 137: 'polygon', +}; + +const SECONDS_IN_DAY = 86400; + +const getLatestBlock = async (chainId) => { + return await api.util.getLatestBlock(SUPPORTED_CHAINS[chainId]); +}; + +/** + * This will convert the output of the contract to a number + */ +const formatOutputToNumber = (output) => { + const number = Number(output.num); + const decimals = Number(output.decimals); + + return number / 10 ** decimals; +}; + +const getBasketsByChainId = async (chainId) => { + const { data } = await axios.get( + `${API_URL}/v2/getBasketMetadata?chainId=${chainId}` + ); + return data; +}; + +const getTVLInUsdByBasketDenomination = async ( + ticker, + basketDenomination, + tvl, + chainId +) => { + if (basketDenomination === '$') { + // case - the denomination is already in USD, we don't need to convert it + return { + ticker, + tvlUsd: tvl ?? 0, + }; + } + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/coingecko:${SUPPORTED_CHAINS[chainId]}` + ); + + if ( + data && + data.coins && + data.coins[`coingecko:${SUPPORTED_CHAINS[chainId]}`] && + data.coins[`coingecko:${SUPPORTED_CHAINS[chainId]}`].price + ) { + return { + ticker, + tvlUsd: + tvl * + Number(data.coins[`coingecko:${SUPPORTED_CHAINS[chainId]}`].price), + }; + } + + return { + ticker, + tvlUsd: tvl ?? 0, + }; +}; + +const getTVLFromChain = async (baskets, chainId) => { + // we are going to find the address in the addressbook + + const latestBlock = await getLatestBlock(chainId); + const abi = ABI.find((abi) => abi.name === 'detailedTVL'); + + const value = await api.abi.multiCall({ + abi, + calls: baskets.map((basket) => ({ + target: basket.basketAddress, + })), + chain: SUPPORTED_CHAINS[chainId], + block: latestBlock.number, + }); + + const TVLsInUSDPromises = value.output.map((output, index) => + getTVLInUsdByBasketDenomination( + baskets[index].basketTicker, + baskets[index].denomination, + formatOutputToNumber(output.output), + chainId + ) + ); + + return await Promise.all(TVLsInUSDPromises); +}; + +const getAPYFromChainByBasket = async ( + baskets, + chainId, + isSevenDay = false +) => { + const latestBlock = await getLatestBlock(chainId); + const oneDayOldBlock = await api.util.lookupBlock( + latestBlock.timestamp - SECONDS_IN_DAY, + { + chain: SUPPORTED_CHAINS[chainId], + } + ); + const sevenDayOldBlock = await api.util.lookupBlock( + latestBlock.timestamp - SECONDS_IN_DAY * 7, + { + chain: SUPPORTED_CHAINS[chainId], + } + ); + + const abi = ABI.find((abi) => abi.name === 'detailedPrice'); + + const currentPrice = await api.abi.multiCall({ + abi, + calls: baskets.map((basket) => ({ + target: basket.basketAddress, + })), + chain: SUPPORTED_CHAINS[chainId], + block: latestBlock.block, + }); + const oldPrice = await api.abi.multiCall({ + abi, + calls: baskets.map((basket) => ({ + target: basket.basketAddress, + })), + chain: SUPPORTED_CHAINS[chainId], + block: isSevenDay ? sevenDayOldBlock.block : oneDayOldBlock.block, + }); + let APYs = []; + const multiplyr = isSevenDay ? 36500 / 7 : 36500; + + currentPrice.output.forEach((price, index) => { + let apy = 0; + if (oldPrice.output[index].output != null) { + apy = + (formatOutputToNumber(price.output) / + formatOutputToNumber(oldPrice.output[index].output) - + 1) * + multiplyr; + } + APYs.push({ + ticker: baskets[index].basketTicker, + apy, + }); + }); + + return APYs; +}; + +const assetAbi = { + inputs: [], + name: 'asset', + outputs: [ + { internalType: 'address', name: 'assetTokenAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getAllBasketApyByChain = async (chainId) => { + const baskets = await getBasketsByChainId(chainId); // we will get objects as a response + + // filtering out the BtcEthVault vault due to no yield + delete baskets['BtcEthVault']; + const basketsArr = Object.keys(baskets).map((key) => baskets[key]); + const apys = await getAPYFromChainByBasket(basketsArr, chainId); + const sevenDayAPYs = await getAPYFromChainByBasket(basketsArr, chainId, true); + const tvls = await getTVLFromChain(basketsArr, chainId); + + const pools = await Promise.all( + Object.keys(baskets).map(async (key, index) => { + const { output: underlying } = await api.abi.call({ + target: baskets[key].basketAddress, + chain: SUPPORTED_CHAINS[chainId], + abi: assetAbi, + }); + + return { + pool: `${baskets[key].basketAddress}-${SUPPORTED_CHAINS[chainId]}`, + chain: SUPPORTED_CHAINS[chainId], + project: 'affine-defi-earn', + symbol: + baskets[key].denomination === '$' + ? 'USDC' + : baskets[key].denomination, + tvlUsd: tvls.find((tvl) => tvl.ticker === key).tvlUsd, + apyBase: apys.find((apy) => apy.ticker === key).apy, + apyBase7d: sevenDayAPYs.find((apy) => apy.ticker === key).apy, + poolMeta: baskets[key].basketName, + underlyingTokens: [underlying], + }; + }) + ); + return pools.flat(); +}; + +const main = async () => { + // we will fetch the APY for all baskets based on 'SUPPORTED_CHAINS' + const data = await Promise.all( + Object.keys(SUPPORTED_CHAINS).map((chainId) => + getAllBasketApyByChain(chainId) + ) + ); + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.affinedefi.com/', +}; diff --git a/src/adaptors/affluent/index.js b/src/adaptors/affluent/index.js new file mode 100644 index 0000000000..4e63dad460 --- /dev/null +++ b/src/adaptors/affluent/index.js @@ -0,0 +1,163 @@ +const utils = require("../utils"); + +const AFFLUENT_MULTIPLY_VAULT_API_URL = "https://api.affluent.org/v2/api/strategyvaults"; +const AFFLUENT_LENDING_VAULT_API_URL = "https://api.affluent.org/v2/api/sharevaults"; +const AFFLUENT_ASSETS_API_URL = "https://api.affluent.org/v2/api/assets"; + +const nowSec = () => Math.floor(Date.now() / 1000); + +const getAPY = async () => { + try { + const assetMap = await getAssetMap(); + + const [strategy, share] = await Promise.all([ + getStrategyVaultsMapped(assetMap), + getShareVaultsMapped(assetMap), + ]); + + const merged = [...strategy, ...share]; + return merged; + } catch (err) { + console.error("getAPY failed:", err); + return []; + } +}; + +async function getStrategyVaultsMapped(assetMap) { + const res = await fetch(AFFLUENT_MULTIPLY_VAULT_API_URL); + if (!res.ok) { + throw new Error(`Strategy API error: HTTP ${res.status} ${res.statusText}`); + } + + const data = await res.json(); + if (!Array.isArray(data)) { + throw new Error("Strategy: Unexpected response shape (not an array)"); + } + + return data.map((v) => { + const assetKeys = Object.keys(v.assets || {}); + const assetSymbols = assetKeys + .map((addr) => assetMap[addr] || addr) + .sort((a, b) => a.localeCompare(b)); + const assetSymbolString = assetSymbols.join("-"); + + return mapToOutput({ + address: v.address, + symbol: assetSymbolString, + tvl: v.tvl, + netApy: v.netApy, + }); + }); +} + +async function getShareVaultList() { + const res = await fetch(AFFLUENT_LENDING_VAULT_API_URL); + if (!res.ok) { + throw new Error(`Share list API error: HTTP ${res.status} ${res.statusText}`); + } + + const data = await res.json(); + if (!Array.isArray(data)) { + throw new Error("Share list: Unexpected response shape (not an array)"); + } + return data; +} + +async function getShareVaultPoint(address, ts = nowSec()) { + const url = `${AFFLUENT_LENDING_VAULT_API_URL}/${address}?from=${ts}&to=${ts}&unit=3600`; + const res = await fetch(url); + if (!res.ok) { + throw new Error(`Share point API error(${address}): HTTP ${res.status} ${res.statusText}`); + } + + const arr = await res.json(); + return Array.isArray(arr) && arr[0] ? arr[0] : null; +} + +async function getShareVaultsMapped(assetMap) { + const list = await getShareVaultList(); + const ts = nowSec(); + + const results = await Promise.allSettled( + list.map(async (v) => { + const p = await getShareVaultPoint(v.address, ts); + const netApy = typeof p?.apy === "number" ? p.apy : undefined; + const tvl = p?.tvl; + + const underlyingSymbol = v?.underlying ? (assetMap[v.underlying] || v.underlying) : undefined; + + return mapToOutput({ + address: v.address, + symbol: underlyingSymbol, + tvl, + netApy, + }); + }) + ); + + return results.map((r, i) => { + if (r.status === "fulfilled") return r.value; + const sv = list[i]; + return mapToOutput({ + address: sv.address, + symbol: sv?.symbol, + tvl: 0, + netApy: undefined, + }); + }); +} + +async function getAssetMap() { + const res = await fetch(AFFLUENT_ASSETS_API_URL); + if (!res.ok) { + throw new Error(`Asset API error: HTTP ${res.status} ${res.statusText}`); + } + + const data = await res.json(); + if (!Array.isArray(data)) { + throw new Error("Asset: Unexpected response shape (not an array)"); + } + + const map = {}; + for (const item of data) { + let symbol = item.symbol; + + if (symbol === "FactorialTON") { + symbol = "TON"; + } + + map[item.address] = symbol; + } + + return map; +} + +module.exports = { + apy: getAPY, + timetravel: false, + url: "https://affluent.org", +}; + +function toNumberOr0(v) { + if (typeof v === "number") return v; + if (typeof v === "string") { + const n = Number(v); + return Number.isFinite(n) ? n : 0; + } + return 0; +} + +function mapToOutput({ address, symbol, tvl, netApy }) { + const pool = `${address}-TON`; + const project = "affluent"; + const apyBase = netApy; + + return { + pool, + chain: "TON", + project, + symbol: String(symbol ?? ""), + tvlUsd: toNumberOr0(tvl), + ...(apyBase !== undefined ? { apyBase } : {}), + }; +} \ No newline at end of file diff --git a/src/adaptors/afterTests.js b/src/adaptors/afterTests.js new file mode 100644 index 0000000000..cdc3c3edf8 --- /dev/null +++ b/src/adaptors/afterTests.js @@ -0,0 +1,15 @@ +module.exports = function () { + console.log(`\nNb of pools: ${global.apy.length}\n `); + if (process.env.CI !== undefined) { + console.log('\nSample pools:'); + console.table(global.apy.slice(0, 10)); + } else { + console.log('\nSample pools:', global.apy.slice(0, 10)); + } + if (global.apy.some((p) => p.tvlUsd < 10e3)) { + console.log( + "This adapter contains some pools with <10k TVL, these pools won't be shown in DefiLlama" + ); + } + process.exit(0); +}; diff --git a/src/adaptors/agave/abiIncentivesController.js b/src/adaptors/agave/abiIncentivesController.js new file mode 100644 index 0000000000..2d8958eb98 --- /dev/null +++ b/src/adaptors/agave/abiIncentivesController.js @@ -0,0 +1 @@ +module.exports = [{ "inputs": [{ "internalType": "contract IERC20", "name": "rewardToken", "type": "address" }, { "internalType": "address", "name": "emissionManager", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint8", "name": "decimals", "type": "uint8" }, { "indexed": false, "internalType": "uint256", "name": "emission", "type": "uint256" }], "name": "AssetConfigUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "index", "type": "uint256" }], "name": "AssetIndexUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "newBulkClaimer", "type": "address" }], "name": "BulkClaimerUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "user", "type": "address" }, { "indexed": true, "internalType": "address", "name": "claimer", "type": "address" }], "name": "ClaimerSet", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint256", "name": "newDistributionEnd", "type": "uint256" }], "name": "DistributionEndUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "token", "type": "address" }], "name": "RewardTokenUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "user", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "RewardsAccrued", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "user", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": true, "internalType": "address", "name": "claimer", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }], "name": "RewardsClaimed", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "vault", "type": "address" }], "name": "RewardsVaultUpdated", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "user", "type": "address" }, { "indexed": true, "internalType": "address", "name": "asset", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "index", "type": "uint256" }], "name": "UserIndexUpdated", "type": "event" }, { "inputs": [], "name": "BULK_CLAIMER", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "DISTRIBUTION_END", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "EMISSION_MANAGER", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "PRECISION", "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "PROXY_ADMIN", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "REVISION", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "REWARD_TOKEN", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "assets", "outputs": [{ "internalType": "uint104", "name": "emissionPerSecond", "type": "uint104" }, { "internalType": "uint104", "name": "index", "type": "uint104" }, { "internalType": "uint40", "name": "lastUpdateTimestamp", "type": "uint40" }, { "internalType": "uint8", "name": "decimals", "type": "uint8" }, { "internalType": "bool", "name": "disabled", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "address", "name": "user", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }], "name": "bulkClaimRewardsOnBehalf", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "address", "name": "to", "type": "address" }], "name": "claimRewards", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "address", "name": "user", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }], "name": "claimRewardsOnBehalf", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }, { "internalType": "uint256[]", "name": "emissionsPerSecond", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "assetDecimals", "type": "uint256[]" }], "name": "configureAssets", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }], "name": "disableAssets", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "asset", "type": "address" }], "name": "getAssetData", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }, { "internalType": "uint256", "name": "", "type": "uint256" }, { "internalType": "uint8", "name": "", "type": "uint8" }, { "internalType": "uint256", "name": "", "type": "uint256" }, { "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "user", "type": "address" }], "name": "getClaimer", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getDistributionEnd", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address[]", "name": "assets", "type": "address[]" }, { "internalType": "address", "name": "user", "type": "address" }], "name": "getRewardsBalance", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getRewardsVault", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "user", "type": "address" }, { "internalType": "address", "name": "asset", "type": "address" }], "name": "getUserAssetData", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_user", "type": "address" }], "name": "getUserUnclaimedRewards", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "user", "type": "address" }, { "internalType": "uint256", "name": "totalSupply", "type": "uint256" }, { "internalType": "uint256", "name": "userBalance", "type": "uint256" }], "name": "handleAction", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "rewardsVault", "type": "address" }], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "newRewardTokenAdjustmentAmount", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "newRewardTokenAdjustmentMultiplier", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "bulkClaimer", "type": "address" }], "name": "setBulkClaimer", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "user", "type": "address" }, { "internalType": "address", "name": "caller", "type": "address" }], "name": "setClaimer", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "distributionEnd", "type": "uint256" }], "name": "setDistributionEnd", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "rewardToken", "type": "address" }], "name": "setRewardToken", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "bool", "name": "RewardTokenAdjustmentMultiplier", "type": "bool" }, { "internalType": "uint256", "name": "RewardTokenAdjustmentAmount", "type": "uint256" }], "name": "setRewardTokenAdjustment", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "rewardsVault", "type": "address" }], "name": "setRewardsVault", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]; diff --git a/src/adaptors/agave/abiLendingPool.js b/src/adaptors/agave/abiLendingPool.js new file mode 100644 index 0000000000..ed108cf9ab --- /dev/null +++ b/src/adaptors/agave/abiLendingPool.js @@ -0,0 +1 @@ +module.exports = [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowRateMode","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowRate","type":"uint256"},{"indexed":true,"internalType":"uint16","name":"referral","type":"uint16"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint16","name":"referral","type":"uint16"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"premium","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"referralCode","type":"uint16"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collateralAsset","type":"address"},{"indexed":true,"internalType":"address","name":"debtAsset","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtToCover","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidatedCollateralAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"bool","name":"receiveAToken","type":"bool"},{"indexed":false,"internalType":"bool","name":"useAToken","type":"bool"}],"name":"LiquidationCall","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"RebalanceStableBorrowRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"repayer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"useAToken","type":"bool"}],"name":"Repay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"variableBorrowRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"}],"name":"ReserveDataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ReserveUsedAsCollateralDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ReserveUsedAsCollateralEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"depositLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralUsageLimit","type":"uint256"}],"name":"SetReserveLimits","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"rateMode","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"reserve","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"FLASHLOAN_PREMIUM_TOTAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LENDINGPOOL_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NUMBER_RESERVES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STABLE_RATE_BORROW_SIZE_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"interestRateMode","type":"uint256"},{"internalType":"uint16","name":"referralCode","type":"uint16"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint16","name":"referralCode","type":"uint16"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"balanceFromBefore","type":"uint256"},{"internalType":"uint256","name":"balanceToBefore","type":"uint256"}],"name":"finalizeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"modes","type":"uint256[]"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint16","name":"referralCode","type":"uint16"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAddressesProvider","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getConfiguration","outputs":[{"components":[{"internalType":"uint256","name":"data","type":"uint256"}],"internalType":"struct DataTypes.ReserveConfigurationMap","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveData","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"data","type":"uint256"}],"internalType":"struct DataTypes.ReserveConfigurationMap","name":"configuration","type":"tuple"},{"internalType":"uint128","name":"liquidityIndex","type":"uint128"},{"internalType":"uint128","name":"variableBorrowIndex","type":"uint128"},{"internalType":"uint128","name":"currentLiquidityRate","type":"uint128"},{"internalType":"uint128","name":"currentVariableBorrowRate","type":"uint128"},{"internalType":"uint128","name":"currentStableBorrowRate","type":"uint128"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"address","name":"stableDebtTokenAddress","type":"address"},{"internalType":"address","name":"variableDebtTokenAddress","type":"address"},{"internalType":"address","name":"interestRateStrategyAddress","type":"address"},{"internalType":"uint8","name":"id","type":"uint8"}],"internalType":"struct DataTypes.ReserveData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveLimits","outputs":[{"components":[{"internalType":"uint256","name":"depositLimit","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"collateralUsageLimit","type":"uint256"}],"internalType":"struct DataTypes.ReserveLimits","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveNormalizedIncome","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveNormalizedVariableDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReservesList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserAccountData","outputs":[{"internalType":"uint256","name":"totalCollateralETH","type":"uint256"},{"internalType":"uint256","name":"totalDebtETH","type":"uint256"},{"internalType":"uint256","name":"availableBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserConfiguration","outputs":[{"components":[{"internalType":"uint256","name":"data","type":"uint256"}],"internalType":"struct DataTypes.UserConfigurationMap","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"address","name":"stableDebtAddress","type":"address"},{"internalType":"address","name":"variableDebtAddress","type":"address"},{"internalType":"address","name":"interestRateStrategyAddress","type":"address"}],"name":"initReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"provider","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"debtAsset","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"debtToCover","type":"uint256"},{"internalType":"bool","name":"receiveAToken","type":"bool"}],"name":"liquidationCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"debtAsset","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"debtToCover","type":"uint256"},{"internalType":"bool","name":"receiveAToken","type":"bool"}],"name":"liquidationCallUsingAgToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"rebalanceStableBorrowRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rateMode","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"repay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rateMode","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"repayUsingAgToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"configuration","type":"uint256"}],"name":"setConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"val","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"rateStrategyAddress","type":"address"}],"name":"setReserveInterestRateStrategyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"depositLimit","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"collateralUsageLimit","type":"uint256"}],"name":"setReserveLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"bool","name":"useAsCollateral","type":"bool"}],"name":"setUserUseReserveAsCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"rateMode","type":"uint256"}],"name":"swapBorrowRateMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/adaptors/agave/abiProtocolDataProvider.js b/src/adaptors/agave/abiProtocolDataProvider.js new file mode 100644 index 0000000000..fe810e449b --- /dev/null +++ b/src/adaptors/agave/abiProtocolDataProvider.js @@ -0,0 +1 @@ +module.exports = [{"inputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"addressesProvider","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ADDRESSES_PROVIDER","outputs":[{"internalType":"contract ILendingPoolAddressesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllATokens","outputs":[{"components":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"tokenAddress","type":"address"}],"internalType":"struct AgaveProtocolDataProvider.TokenData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllReservesTokens","outputs":[{"components":[{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"tokenAddress","type":"address"}],"internalType":"struct AgaveProtocolDataProvider.TokenData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveConfigurationData","outputs":[{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"liquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"liquidationBonus","type":"uint256"},{"internalType":"uint256","name":"reserveFactor","type":"uint256"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"},{"internalType":"bool","name":"borrowingEnabled","type":"bool"},{"internalType":"bool","name":"stableBorrowRateEnabled","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isFrozen","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveData","outputs":[{"internalType":"uint256","name":"availableLiquidity","type":"uint256"},{"internalType":"uint256","name":"totalStableDebt","type":"uint256"},{"internalType":"uint256","name":"totalVariableDebt","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint256","name":"variableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"averageStableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveLimits","outputs":[{"components":[{"internalType":"uint256","name":"depositLimit","type":"uint256"},{"internalType":"uint256","name":"borrowLimit","type":"uint256"},{"internalType":"uint256","name":"collateralUsageLimit","type":"uint256"}],"internalType":"struct DataTypes.ReserveLimits","name":"limits","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveTokensAddresses","outputs":[{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"address","name":"stableDebtTokenAddress","type":"address"},{"internalType":"address","name":"variableDebtTokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserReserveData","outputs":[{"internalType":"uint256","name":"currentATokenBalance","type":"uint256"},{"internalType":"uint256","name":"currentStableDebt","type":"uint256"},{"internalType":"uint256","name":"currentVariableDebt","type":"uint256"},{"internalType":"uint256","name":"principalStableDebt","type":"uint256"},{"internalType":"uint256","name":"scaledVariableDebt","type":"uint256"},{"internalType":"uint256","name":"stableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"liquidityRate","type":"uint256"},{"internalType":"uint40","name":"stableRateLastUpdated","type":"uint40"},{"internalType":"bool","name":"usageAsCollateralEnabled","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/agave/index.js b/src/adaptors/agave/index.js new file mode 100644 index 0000000000..8a4af09ace --- /dev/null +++ b/src/adaptors/agave/index.js @@ -0,0 +1,192 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiIncentivesController = require('./abiIncentivesController'); + +const utils = require('../utils'); + +const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; + +const chains = { + xdai: { + LendingPool: '0x5E15d5E33d318dCEd84Bfe3F4EACe07909bE6d9c', + ProtocolDataProvider: '0xE6729389DEa76D47b5BcB0bA5c080821c3B51329', + IncentivesController: '0xfa255f5104f129b78f477e9a6d050a02f31a5d86', + reward_subgraph: sdk.graph.modifyEndpoint('EJezH1Cp31QkKPaBDerhVPRWsKVZLrDfzjrLqpmv6cGg'), + }, +}; + +const query = gql` + query BalancerV2Pool { + pool( + id: "0x388cae2f7d3704c937313d990298ba67d70a3709000200000000000000000026" + ) { + totalLiquidity + totalShares + } + } +`; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const incentivesVariableDebtTokenData = ( + await sdk.api.abi.multiCall({ + calls: reserveData.map((t) => ({ + target: addresses.IncentivesController, + params: t.variableDebtTokenAddress, + })), + chain: sdkChain, + abi: abiIncentivesController.find((n) => n.name === 'getAssetData'), + }) + ).output.map((o) => o.output); + + const incentivesAgTokenData = ( + await sdk.api.abi.multiCall({ + calls: reserveData.map((t) => ({ + target: addresses.IncentivesController, + params: t.aTokenAddress, + })), + chain: sdkChain, + abi: abiIncentivesController.find((n) => n.name === 'getAssetData'), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const rewardTokenData = await request(addresses.reward_subgraph, query); + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + const rewardTokenPrice = + rewardTokenData.pool.totalLiquidity / + rewardTokenData.pool.totalShares; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const apyReward = + incentivesAgTokenData[i] && totalSupplyUsd + ? (incentivesAgTokenData[i][1] * + rewardTokenPrice * + SECONDS_PER_YEAR) / + (totalSupplyUsd * 10e18) + : 0; + const apyRewardBorrow = + incentivesVariableDebtTokenData[i] && totalBorrowUsd + ? (incentivesVariableDebtTokenData[i][1] * + SECONDS_PER_YEAR * + rewardTokenPrice) / + (totalBorrowUsd * 10e18) + : 0; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const url = `https://agave.finance/markets/${symbols[i]}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'agave', + chain, + tvlUsd, + apyBase, + apyReward, + rewardTokens: ['0x388Cae2f7d3704C937313d990298Ba67D70a3709'], // Geist + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/aimstrong/index.js b/src/adaptors/aimstrong/index.js new file mode 100644 index 0000000000..063b846156 --- /dev/null +++ b/src/adaptors/aimstrong/index.js @@ -0,0 +1,201 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abi = { + getReservesList: 'function getReservesList() view returns (address[])', + getReserveData: + 'function getReserveData(address asset) external view returns (tuple(tuple(uint256 data) configuration, uint128 liquidityIndex, uint128 variableBorrowIndex, uint128 currentLiquidityRate, uint128 currentVariableBorrowRate, uint40 lastUpdateTimestamp, address tTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id))', + totalSupply: 'function totalSupply() external view returns (uint256)', + symbol: 'function symbol() external view returns (string)', + decimals: 'function decimals() external view returns (uint8)', + getVault: 'function getVault(address token) external view returns (address)', + ratePerSecond: 'function ratePerSecond() external view returns (uint256)', + tokenStaked: 'function tokenStaked() external view returns (address)', + tokenRewards: 'function tokenRewards() external view returns (address)', +}; + +const config = { + base: { + pool: '0x7c94606f2240E61E242D14Ed984Aa38FA4C79c0C', + factory: '0xb28ee1F4Ae2C8082a6c06c446C79aD8173d988e4', + rewardToken: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2', + }, + arbitrum: { + pool: '0x7c94606f2240E61E242D14Ed984Aa38FA4C79c0C', + factory: '0x2659e4a192D4f9541267578BD4ae41D391774A06', + rewardToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + }, +}; + +const SECONDS_IN_YEAR = 365 * 24 * 60 * 60; +const TEN_POW_27 = 10 ** 27; +const PRECISION_FACTOR = 10000; + +const apy = async () => { + const chains = ['base', 'arbitrum']; + const pools = []; + + for (const chain of chains) { + const reservesList = await sdk.api.abi.call({ + abi: abi.getReservesList, + target: config[chain].pool, + chain, + }); + + for (const reserveAddress of reservesList.output) { + const reserveData = await sdk.api.abi.call({ + abi: abi.getReserveData, + target: config[chain].pool, + params: [reserveAddress], + chain, + }); + + const [symbol, decimals] = await Promise.all([ + sdk.api.abi.call({ + abi: abi.symbol, + target: reserveAddress, + chain, + }), + sdk.api.abi.call({ + abi: abi.decimals, + target: reserveAddress, + chain, + }), + ]); + + const currentLiquidityRate = + reserveData.output.currentLiquidityRate / TEN_POW_27; + const currentVariableBorrowRate = + reserveData.output.currentVariableBorrowRate / TEN_POW_27; + + const apyBase = currentLiquidityRate * 100; + const apyBaseBorrow = currentVariableBorrowRate * 100; + + let apyReward = 0; + const incentivesControllerAddr = await getIncentivesController( + reserveAddress, + chain + ); + if ( + incentivesControllerAddr && + incentivesControllerAddr !== + '0x0000000000000000000000000000000000000000' + ) { + apyReward = await getRewardApy(incentivesControllerAddr, chain); + } + + const [tTokenTotalSupply, variableDebtTotalSupply] = await Promise.all([ + sdk.api.abi.call({ + abi: abi.totalSupply, + target: reserveData.output.tTokenAddress, + chain, + }), + sdk.api.abi.call({ + abi: abi.totalSupply, + target: reserveData.output.variableDebtTokenAddress, + chain, + }), + ]); + + const priceInUsd = await getPrice(reserveAddress, chain); + + const totalSupplyUsd = + (tTokenTotalSupply.output / 10 ** decimals.output) * priceInUsd; + const totalBorrowUsd = + (variableDebtTotalSupply.output / 10 ** decimals.output) * priceInUsd; + + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const poolData = { + pool: `${reserveData.output.tTokenAddress}-${chain}`.toLowerCase(), + chain: chain.charAt(0).toUpperCase() + chain.slice(1), + project: 'aimstrong', + symbol: symbol.output, + tvlUsd: tvlUsd, + apyBase: apyBase > 0 ? apyBase : null, + apyReward: apyReward > 0 ? apyReward : null, + rewardTokens: apyReward > 0 ? [config[chain].rewardToken] : undefined, + underlyingTokens: [reserveAddress], + apyBaseBorrow: apyBaseBorrow > 0 ? apyBaseBorrow : null, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + }; + + if (apyBase > 0 || apyReward > 0) { + pools.push(poolData); + } + } + } + + return pools; +}; + +async function getIncentivesController(token, chain) { + const controllerAddress = await sdk.api.abi.call({ + abi: abi.getVault, + target: config[chain].factory, + params: [token], + chain, + }); + return controllerAddress.output; +} + +async function getRewardApy(icAddr, chain) { + const [rps, stakeTokenAddr, rewardTokenAddr] = await Promise.all([ + sdk.api.abi.call({ + abi: abi.ratePerSecond, + target: icAddr, + chain, + }), + sdk.api.abi.call({ + abi: abi.tokenStaked, + target: icAddr, + chain, + }), + sdk.api.abi.call({ + abi: abi.tokenRewards, + target: icAddr, + chain, + }), + ]); + + const [stakeDecimals, rewardDecimals] = await Promise.all([ + sdk.api.abi.call({ + abi: abi.decimals, + target: stakeTokenAddr.output, + chain, + }), + sdk.api.abi.call({ + abi: abi.decimals, + target: rewardTokenAddr.output, + chain, + }), + ]); + + const stakeUnitPrice = await getPrice(stakeTokenAddr.output, chain); + const rewardUnitPrice = await getPrice(rewardTokenAddr.output, chain); + + const numerator = + (rps.output * SECONDS_IN_YEAR * rewardUnitPrice) / + 10 ** rewardDecimals.output; + const denominator = + (stakeUnitPrice * TEN_POW_27) / 10 ** stakeDecimals.output; + const apyWithPrecision = (numerator * PRECISION_FACTOR) / denominator; + + return apyWithPrecision / 100; +} + +async function getPrice(tokenAddress, chain) { + const priceKey = `${chain}:${tokenAddress.toLowerCase()}`; + const response = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const price = response.data.coins[priceKey]?.price || 1; + return price; +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.aimstrong.ai/lending', +}; diff --git a/src/adaptors/alien-base-v2/index.js b/src/adaptors/alien-base-v2/index.js new file mode 100644 index 0000000000..0c6925b961 --- /dev/null +++ b/src/adaptors/alien-base-v2/index.js @@ -0,0 +1,302 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js'); +const axios = require('axios'); +const utils = require('../utils'); +const masterchefAbi = require('./masterchef.js'); +const SUBGRAPH_URL = sdk.graph.modifyEndpoint( + sdk.graph.modifyEndpoint('6bg5PGSbcbiXVj6iTNNYz7CaJE8zdVZhZNNCYu8oYmPc') +); +const masterchef = '0x52eaecac2402633d98b95213d0b473e069d86590'; +const ALB = '0x1dd2d631c92b1aCdFCDd51A0F7145A50130050C4'; +const WETH = '0x4200000000000000000000000000000000000006'; +const SECONDS_PER_YEAR = 31536000; + +const excludedPools = [ + '0x1dd2d631c92b1aCdFCDd51A0F7145A50130050C4', + '0x840dCB7b4d3cEb906EfD00c8b5F5c5Dd61d7f8a6', + '0xfA52C8902519e4Da95C3C520039C676d5bD4d9a2', + '0xcdEF05048602aA758fCa3E33B964397f904b87a9', + '0x9D309C52abb61655610eCaE04624b81Ab1f2aEd7', + '0xA787D1177afdEc8E03D72fFCA14Dcb1126A74887', + '0xe95255C018c1662a20A652ec881F32bf3515017a', + '0x7042064c6556Edbe8188C03020B21402eEdCBF0a', + '0xDe16407Aeb41253bAC9163Fa230ceB630Be46534', + '0x053D11735F501199EC64A125498f29eD453d27a4', + '0x8F472e07886f03C6385072f7DE60399455a243E6', + '0x91BE3DD3c16EE370bc26b4c6FFE2de25aBa4AB3C', + '0x9D309C52abb61655610eCaE04624b81Ab1f2aEd7', + '0xcdEF05048602aA758fCa3E33B964397f904b87a9', + '0xfA52C8902519e4Da95C3C520039C676d5bD4d9a2', + '0x6e00F103616dc8e8973920a3588b853Ce4ef011C', + '0x8fC786FdA48A24C9EcDbf6409F9709Aa8a62d1Af', + '0x67979Dcc55e01d799C3FbA8198f9B39E6f42Da33', + '0x22584e946e51e41D8A0002111b1bd9d5d8406cE9', + '0xBC33B469Fd0292B2e2B6FC037bdF27617263e91E', + '0x7bFA42A4331aC8901c68390aA72a2e29f25A47d0', +].map((a) => a.toLowerCase()); + +const pairQuery = gql` + query getPairs($first: Int!, $skip: Int!) { + pairs( + first: $first + skip: $skip + orderBy: reserveUSD + orderDirection: desc + ) { + id + token0 { + id + symbol + decimals + } + token1 { + id + symbol + decimals + } + reserveUSD + volumeUSD + reserve0 + reserve1 + totalSupply + } + } +`; + +const pairDayDataQuery = gql` + query getPairDayData($pairAddresses: [String!], $startTime: Int!) { + pairDayDatas( + first: 7 + orderBy: date + orderDirection: desc + where: { pairAddress_in: $pairAddresses, date_gt: $startTime } + ) { + pairAddress + dailyVolumeUSD + } + } +`; + +const getPairs = async () => { + const pairs = []; + let skip = 0; + const first = 100; + + while (true) { + const result = await request(SUBGRAPH_URL, pairQuery, { first, skip }); + pairs.push(...result.pairs); + if (result.pairs.length < first) break; + skip += first; + } + + return pairs.filter((pair) => !excludedPools.includes(pair.id.toLowerCase())); +}; + +const getWeeklyVolumes = async (pairs) => { + const pairAddresses = pairs.map((pair) => pair.id.toLowerCase()); + const startTime = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60; + + const result = await request(SUBGRAPH_URL, pairDayDataQuery, { + pairAddresses, + startTime, + }); + + const weeklyVolumes = {}; + const lastDayVolumes = {}; + result.pairDayDatas.forEach((dayData) => { + if (!weeklyVolumes[dayData.pairAddress]) { + weeklyVolumes[dayData.pairAddress] = 0; + } + weeklyVolumes[dayData.pairAddress] += parseFloat(dayData.dailyVolumeUSD); + lastDayVolumes[dayData.pairAddress] = parseFloat(dayData.dailyVolumeUSD); + }); + + return { weeklyVolumes, lastDayVolumes }; +}; + +const getMasterChefData = async () => { + const chain = 'base'; + const totalAllocPointAbi = { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + const albPerSecAbi = { + inputs: [], + name: 'albPerSec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const [totalAllocPoint, albPerSec] = await Promise.all([ + sdk.api.abi.call({ + target: masterchef, + abi: totalAllocPointAbi, + chain: chain, + }), + sdk.api.abi.call({ + target: masterchef, + abi: albPerSecAbi, + chain: chain, + }), + ]); + + return { + totalAllocPoint: totalAllocPoint.output, + albPerSec: albPerSec.output / 1e18, + }; +}; + +const getPoolInfo = async (pairAddresses) => { + const chain = 'base'; + const poolLengthAbi = { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + const poolInfoAbi = { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accAlbPerShare', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }; + + const poolLength = await sdk.api.abi.call({ + target: masterchef, + abi: poolLengthAbi, + chain: chain, + }); + + const poolInfoCalls = [...Array(Number(poolLength.output)).keys()].map( + (i) => ({ + target: masterchef, + params: i, + }) + ); + + const poolInfos = await sdk.api.abi.multiCall({ + calls: poolInfoCalls, + abi: poolInfoAbi, + chain: chain, + }); + + return poolInfos.output + .map(({ output }, i) => ({ + id: i, + pair: { id: output.lpToken.toLowerCase() }, + allocPoint: output.allocPoint, + lastRewardTime: output.lastRewardTime, + accAlbPerShare: output.accAlbPerShare, + })) + .filter((pool) => pairAddresses.includes(pool.pair.id)); +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + albPerSec, + albPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + const albPerYear = albPerSec * SECONDS_PER_YEAR; + return ((poolWeight * albPerYear * albPrice) / reserveUSD) * 100; +}; + +const main = async (timestamp = Date.now() / 1000) => { + const chainString = 'base'; + const pairs = await getPairs(); + const { weeklyVolumes, lastDayVolumes } = await getWeeklyVolumes(pairs); + console.log(weeklyVolumes, lastDayVolumes); + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolLength'), + chain: chainString, + }) + ).output; + const masterChefData = await getMasterChefData(); + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'poolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + console.log(poolInfo); + const wethPriceKey = `base:${WETH}`; + const wethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${wethPriceKey}`) + ).data.coins[wethPriceKey]?.price; + + const albPrice = ( + await axios.get(`https://api.dexscreener.com/latest/dex/tokens/${ALB}`) + ).data.pairs[0]?.priceUsd; + const apyData = pairs + .map((pair) => { + const pairPoolInfo = poolInfo.find( + (info) => info.lpToken?.toLowerCase() === pair.id.toLowerCase() + ); + if (!pairPoolInfo || pairPoolInfo.allocPoint === '0' || !pair.id) + return null; + + const reserveUSD = parseFloat(pair.reserveUSD); + const apyReward = calculateApy( + pairPoolInfo, + masterChefData.totalAllocPoint, + masterChefData.albPerSec, + albPrice, + reserveUSD + ); + + const weeklyVolumeUSD = weeklyVolumes[pair.id] || 0; + const lastDayVolumeUSD = lastDayVolumes[pair.id] || 0; + const feeRate = 0.0016; + const apyBase = ((weeklyVolumeUSD * feeRate * 52) / reserveUSD) * 100; + + const isAlbStake = pair.id.toLowerCase() === ALB.toLowerCase(); + const symbol = isAlbStake + ? pair.token0.symbol + : `${pair.token0.symbol}-${pair.token1.symbol}`; + + const url = isAlbStake + ? `https://app.alienbase.xyz/swap` + : `https://app.alienbase.xyz/add/${pair.token0.id}/${pair.token1.id}`; + + return { + pool: pair.id, + chain: utils.formatChain('base'), + project: 'alien-base-v2', + symbol, + tvlUsd: reserveUSD, + apyBase: isAlbStake ? 0 : apyBase, + apyReward: apyReward * 0.85, + rewardTokens: apyReward > 0 ? [ALB] : [], + underlyingTokens: [pair.token0.id, pair.token1.id], + url, + }; + }) + .filter(Boolean); + + return apyData.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/alien-base-v2/masterchef.js b/src/adaptors/alien-base-v2/masterchef.js new file mode 100644 index 0000000000..c02fb4ef25 --- /dev/null +++ b/src/adaptors/alien-base-v2/masterchef.js @@ -0,0 +1,820 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IBoringERC20', + name: '_alb', + type: 'address', + }, + { internalType: 'uint256', name: '_albPerSec', type: 'uint256' }, + { internalType: 'address', name: '_teamAddress', type: 'address' }, + { internalType: 'address', name: '_treasuryAddress', type: 'address' }, + { internalType: 'address', name: '_investorAddress', type: 'address' }, + { internalType: 'uint256', name: '_teamPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_treasuryPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_investorPercent', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IComplexRewarder[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Add', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newAmount', + type: 'uint256', + }, + ], + name: 'AllocPointsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newValue', + type: 'uint256', + }, + ], + name: 'EmissionRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountLockedUp', + type: 'uint256', + }, + ], + name: 'RewardLockedUp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IComplexRewarder[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Set', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetInvestorAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetInvestorPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetTeamAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetTeamPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetTreasuryAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetTreasuryPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accAlbPerShare', + type: 'uint256', + }, + ], + name: 'UpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'MAXIMUM_DEPOSIT_FEE_RATE', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAXIMUM_HARVEST_INTERVAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IBoringERC20', + name: '_lpToken', + type: 'address', + }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IComplexRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'alb', + outputs: [ + { internalType: 'contract IBoringERC20', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'albPerSec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'canHarvest', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: '_pids', type: 'uint256[]' }], + name: 'harvestMany', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'investorAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'investorPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { internalType: 'uint256', name: 'accAlbPerShare', type: 'uint256' }, + { internalType: 'uint16', name: 'depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: 'harvestInterval', type: 'uint256' }, + { internalType: 'uint256', name: 'totalLp', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewarders', + outputs: [ + { internalType: 'address[]', name: 'rewarders', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewardsPerSec', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'rewardsPerSec', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'poolTotalLp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IComplexRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_investorAddress', type: 'address' }, + ], + name: 'setInvestorAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newInvestorPercent', + type: 'uint256', + }, + ], + name: 'setInvestorPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_teamAddress', type: 'address' }, + ], + name: 'setTeamAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newTeamPercent', type: 'uint256' }, + ], + name: 'setTeamPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_treasuryAddress', type: 'address' }, + ], + name: 'setTreasuryAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newTreasuryPercent', + type: 'uint256', + }, + ], + name: 'setTreasuryPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAlbInPools', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLockedUpRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'treasuryAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'treasuryPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'updateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_albPerSec', type: 'uint256' }], + name: 'updateEmissionRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardLockedUp', type: 'uint256' }, + { internalType: 'uint256', name: 'nextHarvestUntil', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/alien-base-v2/poolAbi.js b/src/adaptors/alien-base-v2/poolAbi.js new file mode 100644 index 0000000000..5ae876fe3d --- /dev/null +++ b/src/adaptors/alien-base-v2/poolAbi.js @@ -0,0 +1,441 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/albReward.js b/src/adaptors/alien-base-v3/albReward.js new file mode 100644 index 0000000000..db256605c5 --- /dev/null +++ b/src/adaptors/alien-base-v3/albReward.js @@ -0,0 +1,302 @@ +const abiMcV3 = require('./masterchefv3.json'); +const { getBunniVaultsForPool, getPricePerFullShare, getProtocolFee, getPoolData, getTokensForPool, getTotalSupply, getReservesForBunniVault } = require('./calls'); + +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const bn = require('bignumber.js'); +const fetch = require('node-fetch'); +const { fetchPoolAvgInfo, fetchPoolsFromSubgraph, fetchTokenPricesFromSubgraph } = require('./subgraphCalls'); + +const ALB = { + base: '0x1dd2d631c92b1acdfcdd51a0f7145a50130050c4', +}; + +const chainIds = { + base: { + id: 8453, + mchef: '0x52eaeCAC2402633d98b95213d0b473E069D86590', + abi: abiMcV3, + }, +}; + +const getFarmApyReward = (pid, tvlUsd, chain, prices, subgraphPrices, rewards) => { + const { addresses, symbols, decimals, rewardsPerSec } = rewards; + + let apyReward = 0; + const SECONDS_IN_YEAR = 31536000; + + for (let i = 0; i < addresses.length; i++) { + const tokenAddress = addresses[i]; + const rewardPerSec = rewardsPerSec[i]; + const tokenDecimals = decimals[i]; + + const tokenPrice = prices[`${chain}:${tokenAddress.toLowerCase()}`]?.price || subgraphPrices[tokenAddress.toLowerCase()]?.derivedUSD || 0; + + const yearlyRewardUsd = (rewardPerSec / Math.pow(10, tokenDecimals)) * SECONDS_IN_YEAR * tokenPrice; + + apyReward += (yearlyRewardUsd / tvlUsd) * 100; + } + + return { apyReward, rewardTokens: addresses }; +}; + +const calculateApyBase = (avgVolume, liquidity, totalSupply, poolLiquidity, fee, protocolFee, totalUsd) => { + // console.log('We are calculating APY with the following parameters: ', { + // avgVolume, + // liquidity, + // totalSupply, + // poolLiquidity, + // fee, + // protocolFee, + // }); + const liqRatio = (liquidity * totalSupply) / poolLiquidity / 1e18; + return ( + ((avgVolume * + 365 * + (Number(fee) / 1e6) * + liqRatio * + (1 - protocolFee)) / + totalUsd) * + 100 + ); +}; + +const processPoolInfos = async (poolInfos) => { + const pools = await fetchPoolsFromSubgraph(); + const {protocolFee, newProtocolFee} = await getProtocolFee(); + + const allTokens = [ + ...new Set(pools.map((p) => [p.token0, p.token1]).flat()), + ]; + + const { albPrice, prices } = await getBaseTokensPrice(allTokens, 'base'); + const subgraphPrices = await fetchTokenPricesFromSubgraph(); + + const results = []; + + for (const pool of pools) { + const bunniVaults = await getBunniVaultsForPool(pool.id); + const avgInfo = await fetchPoolAvgInfo(pool.id); + + for (const bunniVault of bunniVaults) { + const tokens = await getTokensForPool(bunniVault.poolAddress, 'base'); + if (!tokens) { + console.log(`Could not find tokens for pool ${bunniVault.poolAddress}`); + continue; + }; + + const matchingPoolInfo = poolInfos.find((info) => info.lpToken === bunniVault.bunniToken); + + const poolData = await getPoolData(bunniVault.poolAddress, 'base'); + if (!poolData) { + console.log(`Could not find pool data for pool ${bunniVault.poolAddress}`); + continue + } + + const { slot0, fee, liquidity } = poolData; + + const pricePerShare = await getPricePerFullShare(bunniVault); + if (!pricePerShare) { + console.log(`Could not find price per share for pool ${bunniVault.poolAddress}`); + continue; + } + + const totalSupply = await getTotalSupply(bunniVault.bunniToken, 'base'); + const reserves = await getReservesForBunniVault(bunniVault, tokens.token0.decimals, tokens.token1.decimals); + + const currentTick = slot0.tick; + const isInRange = (Number(currentTick) >= Number(bunniVault.tickLower)) && (Number(currentTick) <= Number(bunniVault.tickUpper)); + + const token0Price = prices[`base:${tokens.token0.address?.toLowerCase()}`]?.price || subgraphPrices[tokens.token0.address?.toLowerCase()]?.derivedUSD || 0; + const token1Price = prices[`base:${tokens.token1.address?.toLowerCase()}`]?.price || subgraphPrices[tokens.token1.address?.toLowerCase()]?.derivedUSD || 0; + + const token0USDValue = reserves.reserve0 * token0Price; + const token1USDValue = reserves.reserve1 * token1Price; + const totalUSDValue = token0USDValue + token1USDValue; + + const apyBase = isInRange + ? calculateApyBase( + avgInfo.volumeUSD, + Number(pricePerShare.liquidity), + Number(totalSupply), + Number(liquidity), + Number(fee), + protocolFee, + totalUSDValue + ) + : 0; + + let extraApy = 0; + + if (matchingPoolInfo && matchingPoolInfo?.rewards) { + const { apyReward, rewardTokens } = getFarmApyReward( + matchingPoolInfo.pid, + totalUSDValue, + 'base', + prices, + subgraphPrices, + matchingPoolInfo.rewards + ); + extraApy = apyReward; + } + const tickRange = Number(bunniVault.tickUpper) - Number(bunniVault.tickLower); + let poolMeta = ''; + if ( + Math.abs(Number(bunniVault.tickLower) + 887272) <= 1000 && + Math.abs(Number(bunniVault.tickUpper) - 887272) <= 1000 + ) { + poolMeta = 'Infinite'; + } else if (tickRange > 10000) { + poolMeta = 'Wide'; + } else if ((tickRange >= 3000 && tickRange <= 10000)) { + poolMeta = 'Narrow'; + } else if (tickRange < 3000) { + poolMeta = 'Ultra Narrow'; + } + + if (totalUSDValue > 0) results.push({ + pool: bunniVault.poolAddress, + bunniToken: bunniVault.bunniToken, + chain: 'base', + symbol: prices[`base:${tokens.token0.address?.toLowerCase()}`]?.symbol + '-' + prices[`base:${tokens.token1.address?.toLowerCase()}`]?.symbol, + project: 'alien-base-v3', + apyBase, + apyReward: extraApy, + rewardTokens: matchingPoolInfo?.rewards?.addresses || [], + underlyingTokens: [tokens.token0.address, tokens.token1.address], + url: `https://app.alienbase.xyz/add/${tokens.token0.address}/${tokens.token1.address}`, + tvlUsd: totalUSDValue, + poolMeta, + }); + // console.log(`For the bunni token ${bunniVault.bunniToken}, APY: ${apyBase.toFixed(2)}%`); + // if (matchingPoolInfo?.rewards) { + // console.log(`For the bunni token ${bunniVault.bunniToken}, EXTRA APY Reward: ${extraApy?.toFixed(2)}%`); + // } + } + } + + return results; +}; + + +const getAlbAprs = async (chain) => { + if (chainIds[chain] === undefined) return []; + + const masterChef = chainIds[chain].mchef; + const abi = chainIds[chain].abi; + + const poolLength = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'poolLength'), + target: masterChef, + chain, + }) + .then((o) => o.output); + const totalAllocPoint = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'totalAllocPoint'), + target: masterChef, + chain, + }) + .then((o) => o.output); + const latestPeriodAlbPerSecond = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'albPerSec'), + target: masterChef, + chain, + }) + .then((o) => o.output); + + const albPerSecond = new bn(latestPeriodAlbPerSecond.toString()) + .div(1e18) + // .div(1e12) + .toString(); + + const poolInfoCalls = Array.from({ length: +poolLength }) + .map((_, i) => i) + .filter((i) => i !== 0) + .map((i) => { + return { + target: masterChef, + params: i, + }; + }); + + const poolInfos = await sdk.api.abi + .multiCall({ + abi: abi.find((m) => m.name === 'poolInfo'), + calls: poolInfoCalls, + chain, + }) + .then((o) => + o.output + .map((r, index) => ({ + ...r.output, + pid: index + 1, + })) + .filter((r) => r.allocPoint !== '0' && r.totalLiquidity !== '0') + ); + + const validPIDs = poolInfos.map((info) => info.pid); + + const poolRewardsCalls = validPIDs.map((pid) => ({ + target: masterChef, + params: pid, + })); + + const poolRewards = await sdk.api.abi.multiCall({ + abi: abi.find((m) => m.name === 'poolRewardsPerSec'), + calls: poolRewardsCalls, + chain, + }); + + const mergedPools = poolInfos.map((info, index) => { + const rewards = poolRewards.output[index].output; + + return { + ...info, + rewards: { + addresses: rewards.addresses, + symbols: rewards.symbols, + decimals: rewards.decimals, + rewardsPerSec: rewards.rewardsPerSec, + }, + }; + }); + + const processedInfo = await processPoolInfos(mergedPools); + + return processedInfo; +}; + +const getBaseTokensPrice = async (allTokens, chain) => { + let priceKeys = { + alb: '0x1dd2d631c92b1acdfcdd51a0f7145a50130050c4', + }; + + let prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${Object.values(priceKeys) + .map((t) => `base:${t}`) + .concat(allTokens.map((t) => `${chain}:${t.id}`)) + .join(',')}` + ) + ).coins; + + const albriceData = prices[`base:${priceKeys.alb}`]; + + const albId = `${chain}:${ALB[chain]}`; + + if (ALB[chain] && !prices[albId]) { + prices[albId] = albriceData; + } + + return { albPrice: albriceData.price, prices }; +}; + +module.exports = { + getAlbAprs, + ALB, + chainIds, + getBaseTokensPrice, +}; diff --git a/src/adaptors/alien-base-v3/bunniHub.json b/src/adaptors/alien-base-v3/bunniHub.json new file mode 100644 index 0000000000..2a78cb62b1 --- /dev/null +++ b/src/adaptors/alien-base-v3/bunniHub.json @@ -0,0 +1,907 @@ +[ + { + "inputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "factory_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "protocolFee_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Compound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Pool", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Pool", + "type": "uint256" + } + ], + "name": "CompoundSkim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "NewBunni", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "PayProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolFee", + "type": "uint256" + } + ], + "name": "SetProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "compound", + "outputs": [ + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "compoundSkim", + "outputs": [ + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "deployBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IBunniHub.DepositParams", + "name": "params", + "type": "tuple" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "setProtocolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokenList", + "type": "address[]" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct IBunniHub.WithdrawParams", + "name": "params", + "type": "tuple" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint128", + "name": "removedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/bunniLens.json b/src/adaptors/alien-base-v3/bunniLens.json new file mode 100644 index 0000000000..792f0861c9 --- /dev/null +++ b/src/adaptors/alien-base-v3/bunniLens.json @@ -0,0 +1,288 @@ +[ + { + "inputs": [ + { "internalType": "contract IBunniHub", "name": "hub_", "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "T", "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { "internalType": "address", "name": "pair", "type": "address" + }, + { "internalType": "address", "name": "token", "type": "address" + } + ], + "name": "addKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" + } + ], + "name": "getBunniKeyForToken", + "outputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" + }, + { "internalType": "uint256", "name": "index", "type": "uint256" + } + ], + "name": "getBunniVault", + "outputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { "internalType": "contract IBunniToken", "name": "token", "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" + } + ], + "name": "getBunniVaults", + "outputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey[]", + "name": "keys", + "type": "tuple[]" + }, + { + "internalType": "contract IBunniToken[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getReserves", + "outputs": [ + { "internalType": "uint112", "name": "reserve0", "type": "uint112" + }, + { "internalType": "uint112", "name": "reserve1", "type": "uint112" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getTokenForBunniKey", + "outputs": [ + { "internalType": "address", "name": "token", "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { "internalType": "contract IBunniHub", "name": "", "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" + }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "pricePerFullShare", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" + }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" + }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" + }, + { "internalType": "address", "name": "pair", "type": "address" + }, + { "internalType": "address", "name": "token", "type": "address" + } + ], + "name": "removeKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] + \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/calls.js b/src/adaptors/alien-base-v3/calls.js new file mode 100644 index 0000000000..3bacefec2d --- /dev/null +++ b/src/adaptors/alien-base-v3/calls.js @@ -0,0 +1,254 @@ +const sdk = require('@defillama/sdk'); +const bn = require('bignumber.js'); +const fetch = require('node-fetch'); + +const bunniLensAbi = require('./bunniLens.json'); +const v3PoolAbi = require('./v3PoolAbi.json'); +const bunniHubAbi = require('./bunniHub.json'); +const abiMcV3 = require('./masterchefv3.json'); + +const bunniLens = '0x3ceb26bb6ad94f2dfdd98f10cb4d6caf02bec9dc'; +const newBunniLens = '0xf71e5E59f762B1D13e3797D24Bf0C8986A05b621'; +const bunniHub = '0xdc53487e2a6ef468260bc938f645f84caaccac6f'; +const newBunniHub = '0xd1Fac4F51457E4a6D35BdC7311718e5D6de92BB9'; + +const tokenCache = {}; + +const getTokenDecimals = async (tokenAddress, chain) => { + if (tokenCache[tokenAddress]) { + return tokenCache[tokenAddress].decimals; + } + + const erc20Abi = [ + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ]; + + try { + const decimals = await sdk.api.abi.call({ + abi: erc20Abi.find((m) => m.name === 'decimals'), + target: tokenAddress, + chain, + }); + + tokenCache[tokenAddress] = { decimals: decimals.output }; + + return decimals.output; + } catch (err) { + console.log(`Error fetching decimals for token ${tokenAddress}:`, err); + return 18; + } +}; + +const getTokensForPool = async (poolAddress, chain) => { + try { + const [token0Address, token1Address] = await Promise.all([ + sdk.api.abi.call({ + abi: v3PoolAbi.find((m) => m.name === 'token0'), + target: poolAddress, + chain, + }), + sdk.api.abi.call({ + abi: v3PoolAbi.find((m) => m.name === 'token1'), + target: poolAddress, + chain, + }), + ]); + + const [token0Decimals, token1Decimals] = await Promise.all([ + getTokenDecimals(token0Address.output, chain), + getTokenDecimals(token1Address.output, chain), + ]); + + return { + token0: { address: token0Address.output, decimals: token0Decimals }, + token1: { address: token1Address.output, decimals: token1Decimals }, + }; + } catch (err) { + console.log(`Error fetching tokens for pool ${poolAddress}:`, err); + return null; + } +}; + +const getBunniVaultsForPool = async (poolAddress) => { + const getBunniVaults = async (poolAddress) => { + return sdk.api.abi.call({ + abi: bunniLensAbi.find((m) => m.name === 'getBunniVaults'), + target: bunniLens, + params: [poolAddress], + chain: 'base', + }); + }; + + const getNewBunniVaults = async (poolAddress) => { + return sdk.api.abi.call({ + abi: bunniLensAbi.find((m) => m.name === 'getBunniVaults'), + target: newBunniLens, + params: [poolAddress], + chain: 'base', + }); + }; + + try { + const result = await getBunniVaults(poolAddress); + const newResult = await getNewBunniVaults(poolAddress); + + return [ + ...result.output.keys.map((vault, i) => ({ + poolAddress, + bunniToken: result.output.tokens[i], + tickLower: vault[1], + tickUpper: vault[2], + isNew: false, + })), + ...newResult.output.keys.map((vault, i) => ({ + poolAddress, + bunniToken: newResult.output.tokens[i], + tickLower: vault[1], + tickUpper: vault[2], + isNew: true, + })), + ]; + } catch (err) { + console.log(`Error fetching bunniVaults for pool ${poolAddress}:`, err); + return []; + } +}; + +const getPricePerFullShare = async (bunniVault) => { + try { + const result = await sdk.api.abi.call({ + abi: bunniLensAbi.find((m) => m.name === 'pricePerFullShare'), + target: bunniVault?.isNew ? newBunniLens : bunniLens, + params: [ + { + pool: bunniVault.poolAddress, + tickLower: bunniVault.tickLower, + tickUpper: bunniVault.tickUpper, + }, + ], + chain: 'base', + }); + + const liquidity = result.output.liquidity; + const amount0 = result.output.amount0; + const amount1 = result.output.amount1; + + return { liquidity, amount0, amount1 }; + } catch (err) { + console.log(`Error fetching price per full share for bunniVault ${bunniVault.poolAddress}:`, err); + return null; + } +}; + +const getProtocolFee = async () => { + try { + const protocolFee = await sdk.api.abi.call({ + abi: bunniHubAbi.find((m) => m.name === 'protocolFee'), + target: bunniHub, + chain: 'base', + }); + const newPprotocolFee = await sdk.api.abi.call({ + abi: bunniHubAbi.find((m) => m.name === 'protocolFee'), + target: newBunniHub, + chain: 'base', + }); + return { protocolFee: protocolFee.output / 1e18, newProtocolFee: newPprotocolFee.output / 1e18 }; + } catch (err) { + console.log('Error fetching protocol fee:', err); + return 0; + } +}; + +const getPoolData = async (poolAddress, chain) => { + try { + const slot0Call = sdk.api.abi.call({ + target: poolAddress, + abi: v3PoolAbi.find((m) => m.name === 'slot0'), + chain, + }); + + const feeCall = sdk.api.abi.call({ + target: poolAddress, + abi: v3PoolAbi.find((m) => m.name === 'fee'), + chain, + }); + + const liquidityCall = sdk.api.abi.call({ + target: poolAddress, + abi: v3PoolAbi.find((m) => m.name === 'liquidity'), + chain, + }); + + const [slot0Result, feeResult, liquidityResult] = await Promise.all([slot0Call, feeCall, liquidityCall]); + + const slot0 = slot0Result?.output || null; + const fee = feeResult?.output || null; + const liquidity = liquidityResult?.output || null; + + return { + slot0, + fee, + liquidity, + }; + } catch (err) { + console.log(`Error fetching pool data for ${poolAddress}:`, err); + return null; + } +}; + +const getTotalSupply = async (bunniToken, chain) => { + try { + const totalSupply = await sdk.api.abi.call({ + abi: 'erc20:totalSupply', + target: bunniToken, + chain, + }); + + return totalSupply.output; + } catch (err) { + console.log(`Error fetching total supply for bunniToken ${bunniToken}:`, err); + return 0; + } +}; + +const getReservesForBunniVault = async (bunniVault, token0Decimals, token1Decimals) => { + + const getReserves = async (pool, tickLower, tickUpper) => { + return sdk.api.abi.call({ + abi: bunniLensAbi.find((m) => m.name === 'getReserves'), + target: bunniVault?.isNew ? newBunniLens : bunniLens, + params: [{ pool, tickLower, tickUpper }], + chain: 'base' + }); + }; + + try { + const result = await getReserves(bunniVault.poolAddress, bunniVault.tickLower, bunniVault.tickUpper); + const reserve0 = result.output.reserve0 / Math.pow(10, token0Decimals); + const reserve1 = result.output.reserve1 / Math.pow(10, token1Decimals); + + return { reserve0, reserve1 }; + } catch (err) { + console.log(`Error fetching reserves for bunniVault ${bunniVault.poolAddress}`, err); + return null; + } + }; + +module.exports = { + getTokenDecimals, + getTokensForPool, + getBunniVaultsForPool, + getPricePerFullShare, + getReservesForBunniVault, + getProtocolFee, + getPoolData, + getTotalSupply, +}; \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/estimateFee.ts b/src/adaptors/alien-base-v3/estimateFee.ts new file mode 100644 index 0000000000..77b45998c2 --- /dev/null +++ b/src/adaptors/alien-base-v3/estimateFee.ts @@ -0,0 +1,250 @@ +// forked from see https://github.com/chunza2542/uniswap.fish +// @ts-nocheck +const bn = require('bignumber.js'); + +interface Tick { + tickIdx: string; + liquidityNet: string; + price0: string; + price1: string; +} + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = ( + price: number, + token0Decimal: string, + token1Decimal: string +): number => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 1) +interface TokensAmount { + amount0: number; + amount1: number; +} +const getTokensAmountFromDepositAmountUSD = ( + P: number, + Pl: number, + Pu: number, + priceUSDX: number, + priceUSDY: number, + depositAmountUSD: number +): TokensAmount => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount0: bn +): bn => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount1: bn +): bn => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = ( + price: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P: number, + lowerP: number, + upperP: number, + amount0: number, + amount1: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity: bn; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +const estimateFee = ( + liquidityDelta: bn, + liquidity: bn, + volume24H: number, + feeTier: string +): number => { + const feeTierPercentage = getFeeTierPercentage(feeTier); + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + + return feeTierPercentage * volume24H * liquidityPercentage; +}; + +const getLiquidityFromTick = (poolTicks: Tick[], tick: number): bn => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity: bn = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price: number | string | bn): bn => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n: number | string | bn, exp: number): bn => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a: bn, b: bn, multiplier: bn) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getFeeTierPercentage = (tier: string): number => { + if (tier === '100') return 0.01 / 100; + if (tier === '300') return 0.03 / 100; + if (tier === '500') return 0.05 / 100; + if (tier === '750') return 0.075 / 100; + if (tier === '2500') return 0.25 / 100; + if (tier === '10000') return 1 / 100; + return 0; +}; + +const FEE_BASE = 10_000; + +function parseProtocolFees(feeProtocol) { + const packed = Number(feeProtocol); + if (Number.isNaN(packed)) { + throw new Error(`Invalid fee protocol ${feeProtocol}`); + } + + const token0ProtocolFee = packed % 2 ** 16; + const token1ProtocolFee = packed >> 16; + return [token0ProtocolFee / FEE_BASE, token1ProtocolFee / FEE_BASE]; +} + +module.exports.EstimatedFees = ( + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + feeTier, + volume, + feeProtocol, + poolTicks +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + // For now the protocol fee is the same on both tokens so here we just use the fee on token0 + const [protocolFee] = parseProtocolFees(feeProtocol); + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const estimatedFee = + P >= Pl && P <= Pu ? estimateFee(deltaL, L, volume, feeTier) : 0; + + const estimatedFeeAfterProtocolFee = estimatedFee * (1 - protocolFee); + + return estimatedFeeAfterProtocolFee; +}; diff --git a/src/adaptors/alien-base-v3/index.js b/src/adaptors/alien-base-v3/index.js new file mode 100644 index 0000000000..b390fc152a --- /dev/null +++ b/src/adaptors/alien-base-v3/index.js @@ -0,0 +1,325 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('./estimateFee'); +const { getAlbAprs, ALB, chainIds } = require('./albReward'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); +const { queryPrior, query, SUBGRAPH_URL } = require('./subgraphCalls'); + +const chain = 'base'; + +const fetchAndCombineAPR = async (chain, url, query, queryPrior, timestamp, stablecoins) => { + const albPools = await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins); + const bunniAPRResults = await getAlbAprs(chain); + + const combinedResults = []; + + albPools.forEach((albPool) => { + const bunniAPR = bunniAPRResults.find((bunni) => bunni.pool === albPool.pool); + + combinedResults.push({ + ...albPool, + apyBase: albPool.apyBase, + apyReward: albPool.apyReward || 0, + rewardTokens: albPool.rewardTokens || [], + underlyingTokens: albPool.underlyingTokens, + }); + + if (bunniAPR) { + combinedResults.push({ + ...albPool, + pool: bunniAPR.bunniToken, + apyBase: bunniAPR.apyBase, + tvlUsd: bunniAPR.tvlUsd, + apyReward: bunniAPR.apyReward, + rewardTokens: bunniAPR.rewardTokens || [], + poolMeta: bunniAPR.poolMeta, + underlyingTokens: albPool.underlyingTokens, + }); + } + }); + + bunniAPRResults.forEach((bunniAPR) => { + if (!combinedResults.find((r) => r.pool === bunniAPR.bunniToken)) { + combinedResults.push({ + pool: bunniAPR.bunniToken, + chain: bunniAPR.chain, + symbol: bunniAPR.symbol, + project: bunniAPR.project, + apyBase: bunniAPR.apyBase, + apyReward: bunniAPR.apyReward, + rewardTokens: bunniAPR.rewardTokens, + underlyingTokens: bunniAPR.underlyingTokens, + url: bunniAPR.url, + tvlUsd: bunniAPR.tvlUsd, + poolMeta: bunniAPR.poolMeta, + }); + }}) + + return combinedResults; +}; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + // console.log('dataNow', dataNow); + + dataNow = dataNow.map((p) => { + return { + ...p, + reserve0: p.totalValueLockedToken0, + reserve1: p.totalValueLockedToken1, + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = true; + if (enableV3Apy) { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // batching the tick query into 3 chunks to prevent it from breaking + const nbBatches = 3; + const chunkSize = Math.ceil(dataNow.length / nbBatches); + const chunks = [ + dataNow.slice(0, chunkSize).map((i) => i.id), + dataNow.slice(chunkSize, chunkSize * 2).map((i) => i.id), + dataNow.slice(chunkSize * 2, dataNow.length).map((i) => i.id), + ]; + + const tickData = {}; + // we fetch 3 pages for each pool + for (const page of [0, 1, 2]) { + console.log(`page nb: ${page}`); + let pageResults = {}; + for (const chunk of chunks) { + console.log(chunk.length); + const tickQuery = ` + query { + ${chunk + .map( + (poolAddress, index) => ` + pool_${poolAddress}: ticks( + first: 1000, + skip: ${page * 1000}, + where: { poolAddress: "${poolAddress}" }, + orderBy: tickIdx + ) { + tickIdx + liquidityNet + price0 + price1 + } + ` + ) + .join('\n')} + } + `; + + try { + const response = await request(url, tickQuery); + pageResults = { ...pageResults, ...response }; + } catch (err) { + console.log(err); + } + } + tickData[`page_${page}`] = pageResults; + } + + // reformat tickData + const ticks = {}; + Object.values(tickData).forEach((page) => { + Object.entries(page).forEach(([pool, values]) => { + if (!ticks[pool]) { + ticks[pool] = []; + } + ticks[pool] = ticks[pool].concat(values); + }); + }); + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + dataNow = dataNow.map((p) => { + const poolTicks = ticks[`pool_${p.id}`] ?? []; + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${p.id}`); + return { ...p, estimatedFee: null, apy7d: null }; + } + + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + const estimatedFee = EstimatedFees( + priceAssumption, + [p.token1_in_token0 * (1 - delta), p.token1_in_token0 * (1 + delta)], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + p.volumeUSD7d, + p.feeProtocol, + poolTicks + ); + + const apy7d = ((estimatedFee * 52) / investmentAmount) * 100; + + return { ...p, estimatedFee, apy7d }; + }); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + + const chainId = chainIds[chainString].id; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://app.alienbase.xyz/add/${token0}/${token1}/${feeTier}?chainId=${chainId}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'alien-base-v3', + poolMeta: poolMeta, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + if (!timestamp) { + timestamp = Math.floor(Date.now() / 1000); + } + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + try { + data.push( + await topLvl( + chain, + SUBGRAPH_URL, + query, + queryPrior, + 'v3', + timestamp, + stablecoins + ) + ); + } catch (err) { + console.log(err); + } + + const combinedResults = await fetchAndCombineAPR( + chain, + SUBGRAPH_URL, + query, + queryPrior, + timestamp, + stablecoins + ); + + // console.log('Returning:', combinedResults.flat().filter((p) => utils.keepFinite(p))); + + return combinedResults + .flat() + .filter((p) => utils.keepFinite(p)); + }; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/alien-base-v3/masterchefv3.json b/src/adaptors/alien-base-v3/masterchefv3.json new file mode 100644 index 0000000000..53f664e731 --- /dev/null +++ b/src/adaptors/alien-base-v3/masterchefv3.json @@ -0,0 +1,1195 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBoringERC20", + "name": "_alb", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_albPerSec", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_teamAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasuryAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_investorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_teamPercent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_treasuryPercent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_investorPercent", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IBoringERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IComplexRewarder[]", + "name": "rewarders", + "type": "address[]" + } + ], + "name": "Add", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "AllocPointsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "EmissionRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountLockedUp", + "type": "uint256" + } + ], + "name": "RewardLockedUp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IComplexRewarder[]", + "name": "rewarders", + "type": "address[]" + } + ], + "name": "Set", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetInvestorAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercent", + "type": "uint256" + } + ], + "name": "SetInvestorPercent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetTeamAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercent", + "type": "uint256" + } + ], + "name": "SetTeamPercent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetTreasuryAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercent", + "type": "uint256" + } + ], + "name": "SetTreasuryPercent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accAlbPerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAXIMUM_DEPOSIT_FEE_RATE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAXIMUM_HARVEST_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBoringERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_harvestInterval", + "type": "uint256" + }, + { + "internalType": "contract IComplexRewarder[]", + "name": "_rewarders", + "type": "address[]" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "alb", + "outputs": [ + { + "internalType": "contract IBoringERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "albPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "canHarvest", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "depositWithPermit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + } + ], + "name": "harvestMany", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "investorAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "investorPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "symbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "decimals", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBoringERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accAlbPerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalLp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "poolRewarders", + "outputs": [ + { + "internalType": "address[]", + "name": "rewarders", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "poolRewardsPerSec", + "outputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "symbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "decimals", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsPerSec", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "poolTotalLp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_harvestInterval", + "type": "uint256" + }, + { + "internalType": "contract IComplexRewarder[]", + "name": "_rewarders", + "type": "address[]" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_investorAddress", + "type": "address" + } + ], + "name": "setInvestorAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newInvestorPercent", + "type": "uint256" + } + ], + "name": "setInvestorPercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_teamAddress", + "type": "address" + } + ], + "name": "setTeamAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newTeamPercent", + "type": "uint256" + } + ], + "name": "setTeamPercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasuryAddress", + "type": "address" + } + ], + "name": "setTreasuryAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newTreasuryPercent", + "type": "uint256" + } + ], + "name": "setTreasuryPercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startFarming", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAlbInPools", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalLockedUpRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + } + ], + "name": "updateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_albPerSec", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardLockedUp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nextHarvestUntil", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/subgraphCalls.js b/src/adaptors/alien-base-v3/subgraphCalls.js new file mode 100644 index 0000000000..964a1b80ec --- /dev/null +++ b/src/adaptors/alien-base-v3/subgraphCalls.js @@ -0,0 +1,138 @@ +const sdk = require("@defillama/sdk"); +const { request, gql } = require("graphql-request"); + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint("378iBSg3LF7U4Gby57EsgACtTjjhD55fm7324H58sMeo"); + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const query = gql` + { + pools(first: 100, where: {totalValueLockedUSD_gt: 1000}, orderBy:totalValueLockedUSD, orderDirection: desc) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + feeProtocol + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const fetchPoolsFromSubgraph = async () => { + const poolQuery = gql` + query { + pools(first: 100, where: {totalValueLockedUSD_gt: 1000}) { + id + token0 { + id + } + token1 { + id + } + liquidity + totalValueLockedUSD + volumeUSD + } + } + `; + + try { + const data = await request(SUBGRAPH_URL, poolQuery); + return data.pools; + } catch (err) { + console.log('Error fetching pools:', err); + return []; + } +}; + +const averageArray = (dataToCalculate) => { + let data = [...dataToCalculate]; + if (data.length > 3) { + data = data.sort((a, b) => a - b).slice(1, data.length - 1); + } + return data.reduce((result, val) => result + val, 0) / data.length; +}; + +const fetchPoolAvgInfo = async (address) => { + const volumeQuery = gql` + query getVolume($days: Int!, $address: String!) { + poolDayDatas(first: $days, orderBy: date, orderDirection: desc, where: { pool: $address }) { + volumeUSD + tvlUSD + feesUSD + protocolFeesUSD + } + } + `; + + try { + const data = await request(SUBGRAPH_URL, volumeQuery, { + days: 7, + address: address.toLowerCase() + }); + + const poolDayDatas = data.poolDayDatas; + const volumes = poolDayDatas.map((d) => Number(d.volumeUSD)); + return { + volumeUSD: averageArray(volumes), + }; + } catch (err) { + console.log('Error fetching pool volume info:', err); + return { volumeUSD: 0 }; + } +}; + +const fetchTokenPricesFromSubgraph = async () => { + const tokenQuery = gql` + query { + tokens(first: 100) { + id + name + symbol + derivedUSD + } + } + `; + + try { + const data = await request(SUBGRAPH_URL, tokenQuery); + + const tokenPrices = {}; + data.tokens.forEach((token) => { + tokenPrices[token.id?.toLowerCase()] = { + symbol: token.symbol, + derivedUSD: parseFloat(token.derivedUSD) + }; + }); + return tokenPrices; + } catch (err) { + console.log('Error fetching token prices:', err); + return {}; + } +}; + +module.exports = { + fetchPoolsFromSubgraph, + fetchTokenPricesFromSubgraph, + fetchPoolAvgInfo, + queryPrior, + query, + SUBGRAPH_URL, +}; \ No newline at end of file diff --git a/src/adaptors/alien-base-v3/v3PoolAbi.json b/src/adaptors/alien-base-v3/v3PoolAbi.json new file mode 100644 index 0000000000..49cc338ed3 --- /dev/null +++ b/src/adaptors/alien-base-v3/v3PoolAbi.json @@ -0,0 +1,988 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/alien-finance/alien-finance.json b/src/adaptors/alien-finance/alien-finance.json new file mode 100644 index 0000000000..f059be2323 --- /dev/null +++ b/src/adaptors/alien-finance/alien-finance.json @@ -0,0 +1,3096 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrow", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "credit", + "type": "uint256" + } + ], + "name": "CreditLimitChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "CreditLimitManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "extension", + "type": "address" + } + ], + "name": "ExtensionAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "extension", + "type": "address" + } + ], + "name": "ExtensionRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "timestamp", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRatePerSecond", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + } + ], + "name": "InterestAccrued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "marketBorrow", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "marketCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedAmount", + "type": "uint256" + } + ], + "name": "Liquidate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct DataTypes.MarketConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "MarketConfigurationChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "configurator", + "type": "address" + } + ], + "name": "MarketConfiguratorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "MarketDelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "timestamp", + "type": "uint40" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct DataTypes.MarketConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "priceOracle", + "type": "address" + } + ], + "name": "PriceOracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aTokenAmount", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrow", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "ReserveManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReservesDecreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReservesIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aTokenAmount", + "type": "uint256" + } + ], + "name": "Supply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenSeized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "absorbToReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "accrueInterest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allAllowedExtensions", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allCreditMarkets", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allEnteredMarkets", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowedExtensions", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "marketBorrow", + "type": "address" + }, + { + "internalType": "address", + "name": "marketCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "calculateLiquidationOpportunity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "checkAccountLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "configureYield", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "creditLimitManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "creditLimits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "deferLiquidityCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "delistMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "enteredMarkets", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getATokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getBorrowBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getCreditLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getMarketConfiguration", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.MarketConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getSupplyBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getTotalBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getTotalCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getTotalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserAllowedExtensions", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserCreditMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_gasStation", + "type": "address" + }, + { + "internalType": "address", + "name": "_pointsOperator", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "extension", + "type": "address" + } + ], + "name": "isAllowedExtension", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "isCreditAccount", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "isMarketListed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "isUserLiquidatable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address", + "name": "marketBorrow", + "type": "address" + }, + { + "internalType": "address", + "name": "marketCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "liquidityCheckStatus", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.MarketConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "listMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "marketConfigurator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.MarketConfig", + "name": "config", + "type": "tuple" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceOracle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "aTokenAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "reduceReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "seize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "credit", + "type": "uint256" + } + ], + "name": "setCreditLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setCreditLimitManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "pauseFlags", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRate", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.MarketConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "setMarketConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "configurator", + "type": "address" + } + ], + "name": "setMarketConfigurator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + } + ], + "name": "setPriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setReserveManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "extension", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "name": "setUserExtension", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "supply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferAToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + } + ], + "name": "getAllCurrentMarketsStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketStatus[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + } + ], + "name": "getAllMarketsMetadata", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "string", + "name": "marketName", + "type": "string" + }, + { + "internalType": "string", + "name": "marketSymbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "marketDecimals", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supplyPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isSoftDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketMetadata[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + } + ], + "name": "getAllMarketsStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketStatus[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getCurrentMarketStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketStatus", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getCurrentUserMarketStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allowanceToAlien", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aTokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.UserMarketStatus", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getMarketMetadata", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "string", + "name": "marketName", + "type": "string" + }, + { + "internalType": "string", + "name": "marketSymbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "marketDecimals", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "liquidationBonus", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "isPToken", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supplyPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isSoftDelisted", + "type": "bool" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModelAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketMetadata", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getMarketStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrow", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "marketPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.MarketStatus", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserAllCurrentMarketsStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allowanceToAlien", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aTokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.UserMarketStatus[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserAllMarketsStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allowanceToAlien", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aTokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.UserMarketStatus[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AlienFinance", + "name": "alien", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "getUserMarketStatus", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allowanceToAlien", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aTokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + } + ], + "internalType": "struct AlienFinanceLens.UserMarketStatus", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/alien-finance/index.js b/src/adaptors/alien-finance/index.js new file mode 100644 index 0000000000..caa94954c2 --- /dev/null +++ b/src/adaptors/alien-finance/index.js @@ -0,0 +1,76 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abis = require('./alien-finance.json'); + +const alien = '0x50454acC07bf8fC78100619a1b68e9E8d28cE022'; +const lens = '0xF090b119b10FE4aF048B3EAEB9c0d4821CaBcD30'; +const chain = utils.formatChain('blast'); +const project = 'alien-finance'; + +const calculateApy = (ratesPerSec) => { + const secondsPerDay = 86400; + const daysPerYear = 365; + + return ( + (Math.pow((ratesPerSec / 10 ** 18) * secondsPerDay + 1, daysPerYear) - 1) * + 100 + ); +}; + +const apy = async () => { + const allMarketsMetadata = ( + await sdk.api.abi.call({ + target: lens, + abi: abis.find((m) => m.name === 'getAllMarketsMetadata'), + params: [alien], + chain: 'blast', + }) + ).output; + + const allMarketsStatus = ( + await sdk.api.abi.call({ + target: lens, + abi: abis.find((m) => m.name === 'getAllMarketsStatus'), + params: [alien], + chain: 'blast', + }) + ).output; + + const pools = allMarketsMetadata.map((marketMetadata, i) => { + const marketStatus = allMarketsStatus[i]; + + const pool = `${marketMetadata.aTokenAddress}-${chain}`.toLowerCase(); + const symbol = marketMetadata.marketSymbol; + const decimals = marketMetadata.marketDecimals; + const price = marketStatus.marketPrice / 10 ** 18; + const tvlUsd = (marketStatus.totalCash / 10 ** decimals) * price; + const apyBase = calculateApy(marketStatus.supplyRate); + const underlyingTokens = [marketStatus.market]; + const apyBaseBorrow = calculateApy(marketStatus.borrowRate); + const totalSupplyUsd = (marketStatus.totalSupply / 10 ** decimals) * price; + const totalBorrowUsd = (marketStatus.totalBorrow / 10 ** decimals) * price; + const ltv = marketMetadata.collateralFactor / 10 ** 4; + + return { + pool, + chain, + project, + symbol, + tvlUsd, + apyBase, + underlyingTokens, + apyBaseBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.alien.finance/', +}; diff --git a/src/adaptors/allbridge-classic/index.js b/src/adaptors/allbridge-classic/index.js new file mode 100644 index 0000000000..418e28c166 --- /dev/null +++ b/src/adaptors/allbridge-classic/index.js @@ -0,0 +1,37 @@ +const axios = require('axios'); + +const api = 'https://core.api.allbridgecoreapi.net/token-info'; + +const chainMapping = { + BSC: 'BSC', + ETH: 'Ethereum', + POL: 'Polygon', + TRX: 'Tron', + SOL: 'Solana', + ARB: 'Arbitrum', +}; + +const getApy = async () => { + const pools = (await axios.get(api)).data; + + return Object.keys(pools) + .map((chain) => { + return pools[chain].tokens.map((t) => { + return { + chain: chainMapping[chain], + project: 'allbridge-classic', + pool: t.poolAddress, + symbol: t.symbol, + apyBase: Number(t.apr), + tvlUsd: Number(t.poolInfo.totalLpAmount) / 1e3, + }; + }); + }) + .flat() + .filter((i) => i.chain); +}; + +module.exports = { + apy: getApy, + url: 'https://stake.allbridge.io/?chain=SOL', +}; diff --git a/src/adaptors/aloe/index.js b/src/adaptors/aloe/index.js new file mode 100644 index 0000000000..cf30953d49 --- /dev/null +++ b/src/adaptors/aloe/index.js @@ -0,0 +1,195 @@ +const sdk = require('@defillama/sdk'); +const { secondsInYear } = require('date-fns'); +const ethers = require('ethers'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const superagent = require('superagent'); +const { rewardTokens } = require('../sommelier/config'); + +const config = { + ethereum: { fromBlock: 18782116 }, + optimism: { fromBlock: 113464669 }, + base: { fromBlock: 7869252 }, + arbitrum: { fromBlock: 159919891 }, + linea: { + factory: '0x00000000333288eBA83426245D144B966Fd7e82E', + volatilityOracle: '0x00000000570385b76719a95Fdf27B9c7fB5Ff299', + lenderLens: '0xFc39498Edd3E18d5296E6584847f2580ad0e770B', + fromBlock: 3982456, + }, +}; + +const ALOE_II_MAX_LEVERAGE = 1 / 200; +const ALOE_II_LIQUIDATION_INCENTIVE = 1 / 20; + +function computeLTV(iv, nSigma) { + const ltv = + 1 / + ((1 + ALOE_II_MAX_LEVERAGE + ALOE_II_LIQUIDATION_INCENTIVE) * + Math.exp(iv * nSigma)); + return Math.max(0.1, Math.min(ltv, 0.9)); +} + +async function getLTVs(chain, factory, volatilityOracle, uniswapPools) { + const parameters = await sdk.api2.abi.multiCall({ + calls: uniswapPools.map((uniswapPool) => ({ + target: factory, + params: [uniswapPool], + })), + abi: 'function getParameters(address uniswapPool) view returns (uint208 ante,uint8 nSigma,uint8 manipulationThresholdDivisor,uint32 pausedUntilTime)', + chain, + }); + + const consults = await sdk.api2.abi.multiCall({ + calls: uniswapPools.map((uniswapPool) => ({ + target: volatilityOracle, + params: [uniswapPool, '0x100000000'], + })), + abi: 'function consult(address pool,uint40 seed) view returns (uint56 metric,uint160 sqrtMeanPriceX96,uint256 iv)', + chain, + }); + + return parameters.map((p, i) => + computeLTV(Number(consults[i].iv) / 1e12, Number(p.nSigma) / 10) + ); +} + +async function getPrices(chain, addresses) { + const priceKeys = [...new Set(addresses)].map( + (address) => `${chain}:${address}` + ); + return ( + await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys + .join(',') + .toLowerCase()}` + ) + ).body.coins; +} + +async function getPoolsFor(chain) { + const { + factory = '0x000000009efdB26b970bCc0085E126C9dfc16ee8', + volatilityOracle = '0x0000000030d51e39a2dDDb5Db50F9d74a289DFc3', + lenderLens = '0x1f36838Ac6e3922dD26f1222d75af86185f2b798', + fromBlock, + } = config[chain]; + + const currentBlock = await sdk.api.util.getLatestBlock(chain); + + const iface = new ethers.utils.Interface([ + 'event CreateMarket(address indexed pool, address lender0, address lender1)', + ]); + const createMarketEvents = ( + await sdk.api2.util.getLogs({ + target: factory, + topic: '', + fromBlock, + toBlock: currentBlock.number, + keys: [], + topics: [iface.getEventTopic('CreateMarket')], + chain, + }) + ).output + .filter((ev) => !ev.removed) + .map((ev) => iface.parseLog(ev).args); + + const lenders = createMarketEvents.flatMap((ev, idx) => [ + { address: ev.lender0, peer: ev.lender1, peerIdx: idx * 2 + 1 }, + { address: ev.lender1, peer: ev.lender0, peerIdx: idx * 2 }, + ]); + + const uniswapPools = createMarketEvents.map((ev) => ev.pool); + const ltvs = await getLTVs(chain, factory, volatilityOracle, uniswapPools); + + const basics = await sdk.api2.abi.multiCall({ + calls: lenders.map((lender) => ({ + target: lenderLens, + params: [lender.address], + })), + abi: 'function readBasics(address lender) view returns (address asset,uint256 interestRate,uint256 utilization,uint256 inventory,uint256 totalBorrows,uint256 totalSupply,uint8 reserveFactor,uint64 rewardsRate)', + chain, + }); + + const prices = await getPrices( + chain, + basics.map((info) => info.asset) + ); + + return basics + .map((info, i) => { + const reserveFraction = 1 / info.reserveFactor; + const userFraction = 1 - reserveFraction; + + const aprBaseBorrow = new BigNumber(info.interestRate).times( + secondsInYear + ); + const aprBaseLend = aprBaseBorrow + .times(info.utilization) + .times(userFraction) + .div('1e18'); + + const apyBaseBorrow = + utils.aprToApy( + aprBaseBorrow.div('1e7').toNumber() / 1e3, + secondsInYear + ) / 100; + const apyBaseLend = + utils.aprToApy(aprBaseLend.div('1e7').toNumber() / 1e3, secondsInYear) / + 100; + + const priceKey = `${chain}:${info.asset}`.toLowerCase(); + if (!(priceKey in prices)) { + return undefined; + } + const { decimals = 18, symbol, price } = prices[priceKey]; + + const totalSupply = + new BigNumber(info.inventory) + .times('1e8') + .div(`1e${decimals}`) + .toNumber() / 1e8; + const totalBorrow = + new BigNumber(info.totalBorrows) + .times('1e8') + .div(`1e${decimals}`) + .toNumber() / 1e8; + const tvl = totalSupply - totalBorrow; + + const lender = lenders[i]; + const peerAssetAddress = basics[lender.peerIdx].asset; + const peerPriceKey = `${chain}:${peerAssetAddress}`.toLowerCase(); + const { symbol: peerSymbol } = + peerPriceKey in prices + ? prices[peerPriceKey] + : { symbol: peerAssetAddress }; + + return { + pool: `${lender.address}-${chain}`.toLowerCase(), + chain, + project: 'aloe', + symbol: symbol.toUpperCase(), + tvlUsd: tvl * price, + apyBase: apyBaseLend * 100, + underlyingTokens: [info.asset], + poolMeta: `${peerSymbol.toUpperCase()}-pool`, + apyBaseBorrow: apyBaseBorrow * 100, + totalSupplyUsd: totalSupply * price, + totalBorrowUsd: totalBorrow * price, + ltv: ltvs[Math.floor(i / 2)], + }; + }) + .filter((pool) => pool !== undefined); +} + +async function apy() { + return ( + await Promise.all(Object.keys(config).map((chain) => getPoolsFor(chain))) + ).flat(); +} + +module.exports = { + apy, + timetravel: false, + url: 'https://app.aloe.capital/markets', +}; diff --git a/src/adaptors/alpaca-finance-2.0/abiDebtToken.json b/src/adaptors/alpaca-finance-2.0/abiDebtToken.json new file mode 100644 index 0000000000..21289623ee --- /dev/null +++ b/src/adaptors/alpaca-finance-2.0/abiDebtToken.json @@ -0,0 +1,270 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "DebtToken_NoSelfTransfer", "type": "error" }, + { "inputs": [], "name": "DebtToken_UnApprovedHolder", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset_", "type": "address" }, + { "internalType": "address", "name": "moneyMarket_", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "moneyMarket", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "okHolders", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_okHolders", + "type": "address[]" + }, + { "internalType": "bool", "name": "_isOk", "type": "bool" } + ], + "name": "setOkHolders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/alpaca-finance-2.0/abiIBToken.json b/src/adaptors/alpaca-finance-2.0/abiIBToken.json new file mode 100644 index 0000000000..96ec37bd61 --- /dev/null +++ b/src/adaptors/alpaca-finance-2.0/abiIBToken.json @@ -0,0 +1,505 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "InterestBearingToken_InvalidDestination", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "assetTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "convertToAssets", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "convertToShares", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset_", "type": "address" }, + { "internalType": "address", "name": "moneyMarket_", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDeposit", + "outputs": [ + { "internalType": "uint256", "name": "maxAssets", "type": "uint256" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxMint", + "outputs": [ + { "internalType": "uint256", "name": "maxShares", "type": "uint256" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxRedeem", + "outputs": [ + { "internalType": "uint256", "name": "maxShares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxWithdraw", + "outputs": [ + { "internalType": "uint256", "name": "maxAssets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "moneyMarket", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "onDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "onWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewDeposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewMint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewRedeem", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewWithdraw", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "redeem", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "totalManagedAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/alpaca-finance-2.0/abiMiniFL.json b/src/adaptors/alpaca-finance-2.0/abiMiniFL.json new file mode 100644 index 0000000000..7040bd9b67 --- /dev/null +++ b/src/adaptors/alpaca-finance-2.0/abiMiniFL.json @@ -0,0 +1,696 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "MiniFL_BadRewarder", "type": "error" }, + { "inputs": [], "name": "MiniFL_DuplicatePool", "type": "error" }, + { "inputs": [], "name": "MiniFL_InsufficientFundedAmount", "type": "error" }, + { "inputs": [], "name": "MiniFL_InvalidArguments", "type": "error" }, + { "inputs": [], "name": "MiniFL_Unauthorized", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + } + ], + "name": "LogAddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_newAlpacaPerSecond", + "type": "uint256" + } + ], + "name": "LogAlpacaPerSecond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_allow", + "type": "bool" + } + ], + "name": "LogApproveStakeDebtToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LogDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LogEmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LogHarvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_maxAlpacaPerSecond", + "type": "uint256" + } + ], + "name": "LogSetMaxAlpacaPerSecond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newAllocPoint", + "type": "uint256" + } + ], + "name": "LogSetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_rewarder", + "type": "address" + } + ], + "name": "LogSetPoolRewarder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_allow", + "type": "bool" + } + ], + "name": "LogSetWhitelistedCaller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_lastRewardTime", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_stakedBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_accAlpacaPerShare", + "type": "uint256" + } + ], + "name": "LogUpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "LogWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "ALPACA", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { "internalType": "address", "name": "_stakingToken", "type": "address" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "addPool", + "outputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "alpacaPerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_for", "type": "address" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_amountToDeposit", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getPoolAllocPoint", + "outputs": [ + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getStakingReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserveAmount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_funder", "type": "address" }, + { "internalType": "address", "name": "_for", "type": "address" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getUserAmountFundedBy", + "outputs": [ + { "internalType": "uint256", "name": "_stakingAmount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "getUserRewardDebtOf", + "outputs": [ + { "internalType": "int256", "name": "_rewardDebt", "type": "int256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "getUserTotalAmountOf", + "outputs": [ + { "internalType": "uint256", "name": "_totalAmount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_pids", "type": "uint256[]" } + ], + "name": "harvestMany", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_alpaca", "type": "address" }, + { + "internalType": "uint256", + "name": "_maxAlpacaPerSecond", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isStakingToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxAlpacaPerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "pendingAlpaca", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "accAlpacaPerShare", + "type": "uint128" + }, + { "internalType": "uint64", "name": "lastRewardTime", "type": "uint64" }, + { "internalType": "uint64", "name": "allocPoint", "type": "uint64" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { "internalType": "uint256", "name": "_poolLength", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "rewarders", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newAlpacaPerSecond", + "type": "uint256" + }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "setAlpacaPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxAlpacaPerSecond", + "type": "uint256" + } + ], + "name": "setMaxAlpacaPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_newAllocPoint", + "type": "uint256" + }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "setPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { + "internalType": "address[]", + "name": "_newRewarders", + "type": "address[]" + } + ], + "name": "setPoolRewarders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_callers", "type": "address[]" }, + { "internalType": "bool", "name": "_allow", "type": "bool" } + ], + "name": "setWhitelistedCallers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "stakingReserves", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "stakingTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "updatePool", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "accAlpacaPerShare", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { "internalType": "uint64", "name": "allocPoint", "type": "uint64" } + ], + "internalType": "struct MiniFL.PoolInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_pids", "type": "uint256[]" } + ], + "name": "updatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userInfo", + "outputs": [ + { "internalType": "uint256", "name": "totalAmount", "type": "uint256" }, + { "internalType": "int256", "name": "rewardDebt", "type": "int256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "whitelistedCallers", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_amountToWithdraw", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/alpaca-finance-2.0/abiMoneyMarketReader.json b/src/adaptors/alpaca-finance-2.0/abiMoneyMarketReader.json new file mode 100644 index 0000000000..f6eba4f930 --- /dev/null +++ b/src/adaptors/alpaca-finance-2.0/abiMoneyMarketReader.json @@ -0,0 +1,584 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "moneyMarket_", "type": "address" }, + { + "internalType": "address", + "name": "moneyMarketAccountManager_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_underlyingTokens", + "type": "address[]" + } + ], + "name": "getAlpacaGuardStatuses", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { "internalType": "bool", "name": "isGuardActivated", "type": "bool" } + ], + "internalType": "struct IMoneyMarketReader.AlpacaGuardStatus[]", + "name": "_alpacaGuardStatuses", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "getInterestRateModelConfig", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "ceilSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ceilSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ceilSlope3", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxInterestSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxInterestSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxInterestSlope3", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.TripleSlopeModelConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { + "internalType": "address[]", + "name": "_underlyingTokenAddresses", + "type": "address[]" + } + ], + "name": "getMainAccountSummary", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "ibTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "supplyIbAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ibTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingTokenPrice", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.SupplyAccountDetail[]", + "name": "supplyAccountDetails", + "type": "tuple[]" + } + ], + "internalType": "struct IMoneyMarketReader.MainAccountSummary", + "name": "_mainAccountSummary", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "getMarketMetadata", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ibTokenAddress", + "type": "address" + }, + { + "components": [ + { "internalType": "uint8", "name": "tier", "type": "uint8" }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "borrowingFactor", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "maxCollateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrow", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.TokenConfig", + "name": "underlyingTokenConfig", + "type": "tuple" + }, + { + "components": [ + { "internalType": "uint8", "name": "tier", "type": "uint8" }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "borrowingFactor", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "maxCollateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrow", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.TokenConfig", + "name": "ibTokenConfig", + "type": "tuple" + } + ], + "internalType": "struct IMoneyMarketReader.MarketMetadata", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "getMarketPriceInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "underlyingTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ibTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingToIbRate", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.MarketPriceInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + }, + { "internalType": "address[]", "name": "_rewarders", "type": "address[]" } + ], + "name": "getMarketRewardInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "totalDebtTokenInPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalUnderlyingTokenInPool", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "uint256", "name": "pId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "rewardPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.RewarderInfo[]", + "name": "ibRewarderInfos", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "uint256", "name": "pId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "rewardPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.RewarderInfo[]", + "name": "debtRewarderInfos", + "type": "tuple[]" + } + ], + "internalType": "struct IMoneyMarketReader.MarketRewardInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "getMarketStats", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "ibTotalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ibTotalAsset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "globalDebtValue", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserve", "type": "uint256" }, + { + "internalType": "uint256", + "name": "totalToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pendingInterest", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastAccruedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.MarketStats", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" } + ], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "getPriceUSD", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pId", "type": "uint256" }, + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address[]", "name": "_rewarders", "type": "address[]" } + ], + "name": "getRewardSummary", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "uint256", "name": "pId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "pendingReward", + "type": "uint256" + } + ], + "internalType": "struct IMoneyMarketReader.RewardSummary[]", + "name": "_rewardSummary", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "_subAccountId", "type": "uint256" } + ], + "name": "getSubAccountSummary", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "subAccountId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowedValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCollateralValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowingPower", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalUsedBorrowingPower", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "ibToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ibTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "collateralFactor", + "type": "uint16" + } + ], + "internalType": "struct IMoneyMarketReader.CollateralPosition[]", + "name": "collaterals", + "type": "tuple[]" + }, + { + "components": [ + { "internalType": "address", "name": "token", "type": "address" }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "price", "type": "uint256" }, + { + "internalType": "uint16", + "name": "borrowingFactor", + "type": "uint16" + } + ], + "internalType": "struct IMoneyMarketReader.DebtPosition[]", + "name": "debts", + "type": "tuple[]" + } + ], + "internalType": "struct IMoneyMarketReader.SubAccountSummary", + "name": "summary", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "moneyMarket", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/alpaca-finance-2.0/index.js b/src/adaptors/alpaca-finance-2.0/index.js new file mode 100644 index 0000000000..7db881ad86 --- /dev/null +++ b/src/adaptors/alpaca-finance-2.0/index.js @@ -0,0 +1,211 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abiIBToken = require('./abiIBToken.json'); +const abiDebtToken = require('./abiDebtToken.json'); +const abiMoneyMarketReader = require('./abiMoneyMarketReader.json'); +const abiMiniFL = require('./abiMiniFL.json'); + +const moneyMarketReader = '0x4913DEC75cC0e061Ba78ebbDb2584905760be4C6'; +const miniFL = '0x4579587AE043131999cE3d9C66199726972E3Fb7'; +const ALPACA = '0x8F0528cE5eF7B51152A59745bEfDD91D97091d2F'; + +const markets = [ + { + name: 'WBNB', + tier: 'COLLATERAL', + token: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + ibToken: '0x2928623eFF453Fb8C9BC744041637a4D2D5Fc56b', + debtToken: '0x855894fe37CFaeE188A1acCc5dd4b38d504F09E9', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'USDC', + tier: 'COLLATERAL', + token: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + ibToken: '0x547593f6aFa897bb05828FBb8D587Ca31D9fF519', + debtToken: '0x049C15F84850FC0d76eFe3b0940a44fC3edD6e2E', + interestModel: '0x4132392C57B9D2DE1BA393A03f23Fcb880Bf8EE1', + }, + { + name: 'USDT', + tier: 'COLLATERAL', + token: '0x55d398326f99059fF775485246999027B3197955', + ibToken: '0x90476BFEF61F190b54a439E2E98f8E43Fb9b4a45', + debtToken: '0xd9D0a0B8B9dc0f845797B678F00c6d7FAD577B56', + interestModel: '0x4132392C57B9D2DE1BA393A03f23Fcb880Bf8EE1', + }, + { + name: 'BUSD', + tier: 'COLLATERAL', + token: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + ibToken: '0x3f38BA29AcC107E6F0b059a17c9bAb0598d0f249', + debtToken: '0x7ffbcda33cD2F7812f9Da4c1189E745379F95B79', + interestModel: '0x4132392C57B9D2DE1BA393A03f23Fcb880Bf8EE1', + }, + { + name: 'BTCB', + tier: 'COLLATERAL', + token: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + ibToken: '0x6C9Cb3739d6B390A4BAcc4D5F0a2629cF5c383B3', + debtToken: '0x457a325E5c63aE73F684d9477826e07F56da749B', + interestModel: '0x89c53B34b5E6A1D0b2922941749e9Ee05ce58b42', + }, + { + name: 'ETH', + tier: 'COLLATERAL', + token: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + ibToken: '0x0A4FE32De91bE99a3EFAC80F6576976293B95369', + debtToken: '0x57496afdB38A0da228046c93695778c757075dEa', + interestModel: '0x89c53B34b5E6A1D0b2922941749e9Ee05ce58b42', + }, + { + name: 'HIGH', + tier: 'CROSS', + token: '0x5f4Bde007Dc06b867f86EBFE4802e34A1fFEEd63', + ibToken: '0x0c9E2653B17b60E9aD9465D1cF478bD6d76a03F0', + debtToken: '0xeB27c21EBA6765608681ec96B0d9F697726884DA', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'Cake', + tier: 'COLLATERAL', + token: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + ibToken: '0x848204278E491f5f15B3F2dce593e6af9552b372', + debtToken: '0xE0ECA72bEe09695C82d9DD5422267270495eA0c2', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'XRP', + tier: 'COLLATERAL', + token: '0x1D2F0da169ceB9fC7B3144628dB156f3F6c60dBE', + ibToken: '0xACb41b8bddF67727F07bf375b01edC40Ed51c4ff', + debtToken: '0x9c04F5D68fc754D79fBCAc8fC56469C0264F85DC', + interestModel: '0x89c53B34b5E6A1D0b2922941749e9Ee05ce58b42', + }, + { + name: 'DOGE', + tier: 'COLLATERAL', + token: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43', + ibToken: '0x72Ad41ecf9C6C1171F19FaCCBA2b347D64AFe57f', + debtToken: '0xBda539AFD66fEE61499B22769E4e413dc158f271', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'LTC', + tier: 'COLLATERAL', + token: '0x4338665CBB7B2485A8855A139b75D5e34AB0DB94', + ibToken: '0x42b2D846785636CfB393b5EC48C6581f47c37EC3', + debtToken: '0x22c583069619eA08F260758E34Bc525B5833d11b', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'THE', + tier: 'ISOLATE', + token: '0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11', + ibToken: '0x91E3A9B3f5a2c02Dd5cd40733fe4d52a87A213d9', + debtToken: '0x2C8A7592828007eF33D87B49732F174D9A0b6759', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, + { + name: 'ADA', + tier: 'COLLATERAL', + token: '0x3EE2200Efb3400fAbB9AacF31297cBdD1d435D47', + ibToken: '0x674d38092D177A9b074e5CAA5D45315eaAcEc790', + debtToken: '0xA57Ce447a14Ec8822105bF2c8f8456fcC0ba4dF4', + interestModel: '0xe44bDd3f0b69f2c294A0250825BCF31eE3af4314', + }, +]; + +const apy = async () => { + const marketStats = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ + target: moneyMarketReader, + params: [m.token], + })), + abi: abiMoneyMarketReader.find((m) => m.name === 'getMarketStats'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const getMarketMetadata = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ + target: moneyMarketReader, + params: [m.token], + })), + abi: abiMoneyMarketReader.find((m) => m.name === 'getMarketMetadata'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const decimals = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m.ibToken })), + abi: abiIBToken.find((m) => m.name === 'decimals'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const decimalsDebtToken = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m.debtToken })), + abi: 'erc20:decimals', + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const priceKeys = markets.map((m) => `bsc:${m.token}`).join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const pools = markets.map((m, i) => { + const underlyingPrice = prices[`bsc:${m.token}`].price; + + const totalSupplyUsd = + (marketStats[i].ibTotalAsset / 10 ** decimals[i]) * underlyingPrice; + + const totalBorrowUsd = + (marketStats[i].globalDebtValue / 10 ** decimalsDebtToken[i]) * + underlyingPrice; + + const utilization = totalBorrowUsd / totalSupplyUsd; + + const apyBaseBorrow = + (marketStats[i].interestRate / 1e18) * 60 * 60 * 24 * 365 * 100; + const apyBase = apyBaseBorrow * utilization * (1 - 0.18); + + const ltv = getMarketMetadata[i].ibTokenConfig.collateralFactor / 1e4; + const borrowFactor = + getMarketMetadata[i].underlyingTokenConfig.borrowingFactor / 1e4; + const debtCeilingUsd = + (getMarketMetadata[i].underlyingTokenConfig.maxBorrow / 1e18) * + underlyingPrice; + + const url = `https://app-v2.alpacafinance.org/market/${m.token}`; + + return { + pool: m.ibToken, + symbol: m.name, + chain: 'bsc', + project: 'alpaca-finance-2.0', + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase, + + apyBaseBorrow, + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd, + ltv, + borrowFactor, + url, + }; + }); + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/alpaca-finance/index.js b/src/adaptors/alpaca-finance/index.js deleted file mode 100644 index 0856695089..0000000000 --- a/src/adaptors/alpaca-finance/index.js +++ /dev/null @@ -1,91 +0,0 @@ -const axios = require('axios'); -const utils = require('../utils'); - -function formatSymbol(sourceName) { - const space = sourceName.indexOf(' '); - return `${sourceName.substring(space + 1)} (${sourceName.substring( - 0, - space - )})`; -} - -async function apy(chain) { - const response = ( - await axios.get( - `https://alpaca-static-api.alpacafinance.org/${chain}/v1/landing/summary.json` - ) - ).data.data; - - const filteredStakingPools = response.fairLaunchStakingPools.filter( - (p) => !p.key.includes('debt') - ); - const fairLaunchStakingPools = filteredStakingPools.map((p) => ({ - pool: `${p.stakingToken.address}-staking`, - chain: utils.formatChain(chainMapping[chain]), - project: 'alpaca-finance', - symbol: utils.formatSymbol(p.symbol), - tvlUsd: Number(p.tvl), - apy: Number(p.apy), - })); - - const strategyPools = response.strategyPools.map((p) => ({ - pool: `${p.key}-strategy-pool`, - chain: utils.formatChain(chainMapping[chain]), - project: 'alpaca-finance', - symbol: utils.formatSymbol(p.iuToken.symbol), - tvlUsd: Number(p.tvl), - apy: Number(p.apy), - })); - - const farmingPools = response.farmingPools.map((p) => ({ - pool: `${p.key}-farming-pool`, - chain: utils.formatChain(chainMapping[chain]), - project: 'alpaca-finance', - symbol: formatSymbol(p.sourceName), - tvlUsd: Number(p.tvl), - apy: utils.aprToApy( - (Number(p.farmRewardApr) + Number(p.tradingFeeApr)) / p.leverage - ), - })); - - const ausdPools = response.ausdPools.map((p) => ({ - pool: `${p.key}-aUSD-pool`, - chain: utils.formatChain(chainMapping[chain]), - project: 'alpaca-finance', - symbol: utils.formatSymbol(p.sourceName), - tvlUsd: Number(p.tvl), - apy: Number(p.totalApy), - })); - - const lendingPools = response.lendingPools.map((p) => ({ - pool: `${p.ibToken.address}-lending`, - chain: utils.formatChain(chainMapping[chain]), - project: 'alpaca-finance', - symbol: utils.formatSymbol(p.symbol), - tvlUsd: Number(p.tvl), - apy: Number(p.totalApy), - })); - - return [ - ...fairLaunchStakingPools, - ...strategyPools, - ...farmingPools, - ...ausdPools, - ...lendingPools, - ]; -} - -const chainMapping = { - bsc: 'binance', - ftm: 'fantom', -}; - -const main = async () => { - const [bsc, ftm] = await Promise.all([apy('bsc'), apy('ftm')]); - return [...bsc, ...ftm]; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/alpaca-leveraged-yield-farming/index.js b/src/adaptors/alpaca-leveraged-yield-farming/index.js new file mode 100644 index 0000000000..4ed086bc7d --- /dev/null +++ b/src/adaptors/alpaca-leveraged-yield-farming/index.js @@ -0,0 +1,140 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const project = 'alpaca-leveraged-yield-farming'; + +const tokenAbi = { + inputs: [], + name: 'token', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', +}; + +async function apy(chain) { + const response = ( + await axios.get( + `https://alpaca-static-api.alpacafinance.org/${chain}/v1/landing/summary.json` + ) + ).data.data; + + const filteredStakingPools = response.fairLaunchStakingPools.filter( + (p) => !p.key.includes('debt') + ); + + const chainString = utils.formatChain(chainMapping[chain]); + + const fairLaunchStakingPools = await Promise.all( + filteredStakingPools.map(async (p) => { + let underlying; + if (chain === 'ftm') { + underlying = ( + await sdk.api.abi.call({ + target: p.stakingToken.address, + abi: tokenAbi, + chain: 'fantom', + }) + ).output; + } + + return { + pool: `${p.stakingToken.address}-staking-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol: utils.formatSymbol(p.symbol.split(' ')[0]), + tvlUsd: Number(p.tvl), + apy: Number(p.apy), + underlyingTokens: chain === 'ftm' ? [underlying] : [], + }; + }) + ); + + const strategyPools = response.strategyPools.map((p) => ({ + pool: `${p.address}-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol: p.workingToken.symbol.split(' ')[0], + poolMeta: p.name, + tvlUsd: Number(p.tvl), + apy: Number(p.apy), + underlyingTokens: [ + p.workingToken?.tokenA?.address, + p.workingToken?.tokenB?.address, + ].filter((i) => i !== undefined), + })); + + const farmingPools = response.farmingPools.map((p) => ({ + pool: `${p.workingToken.address}-farming-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol: p.sourceName.split(' ')[1], + poolMeta: p.sourceName.split(' ')[0], + tvlUsd: Number(p.tvl), + apy: utils.aprToApy( + (Number(p.farmRewardApr) + Number(p.tradingFeeApr)) / p.leverage + ), + underlyingTokens: [ + p.workingToken?.tokenA?.address, + p.workingToken?.tokenB?.address, + ].filter((i) => i !== undefined), + })); + + const ausdPools = response.ausdPools.map((p) => ({ + pool: `${p.key}-aUSD-pool`, + chain: chainString, + project, + symbol: utils.formatSymbol(p.sourceName), + tvlUsd: Number(p.tvl), + apy: Number(p.totalApy), + })); + + return [ + ...fairLaunchStakingPools, + ...strategyPools, + ...farmingPools, + ...ausdPools, + ]; +} + +const chainMapping = { + bsc: 'binance', + ftm: 'fantom', +}; + +async function apyLending(chain) { + const response = ( + await axios.get( + `https://alpaca-static-api.alpacafinance.org/${chain}/v1/landing/summary.json` + ) + ).data.data; + + const chainString = utils.formatChain(chainMapping[chain]); + + return response.lendingPools.map((p) => ({ + pool: `${p.ibToken.address}-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol: utils.formatSymbol(p.symbol), + tvlUsd: Number(p.tvl), + apy: Number(p.totalApy), + underlyingTokens: [p.baseToken.address], + })); +} + +const main = async () => { + const [bsc, ftm, bscLending, ftmLending] = await Promise.all([ + apy('bsc'), + apy('ftm'), + apyLending('bsc'), + apyLending('ftm'), + ]); + + return [...bsc, ...ftm, ...bscLending, ...ftmLending]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.alpacafinance.org/farm', +}; diff --git a/src/adaptors/amnis-finance/index.js b/src/adaptors/amnis-finance/index.js new file mode 100644 index 0000000000..d205f9f022 --- /dev/null +++ b/src/adaptors/amnis-finance/index.js @@ -0,0 +1,46 @@ +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const AMNIS_RESOURCE_ACCOUNT ='0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a'; +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; +const DECIMALS = 1e8; +const axios = require('axios'); + + +const aptosCoinName = 'coingecko:aptos'; + +async function main() { + //calculate apy + const { data: { rewards_rate, rewards_rate_denominator } } = await utils.getData(`${NODE_URL}/accounts/0x1/resource/0x1::staking_config::StakingConfig`) + const amStakedData = await utils.getData(`${NODE_URL}/view`, {"function": `${AMNIS_RESOURCE_ACCOUNT}::stapt_token::total_amapt_staked`,"type_arguments": [],"arguments": []}) + const amStaked = amStakedData[0] + const amTotalSupplyData = await utils.getData(`${NODE_URL}/view`, {"function": `${AMNIS_RESOURCE_ACCOUNT}::amapt_token::total_supply`,"type_arguments": [],"arguments": []}) + const amTotalSupply = amTotalSupplyData[0] + const apy = (Math.pow(1 + rewards_rate * amTotalSupply / amStaked / rewards_rate_denominator, 12 * 365) - 1) * 100; + + //calculate tvlUsd + let tvlUsd = 0 + const aptPrice = await utils.getData(`${COINS_LLAMA_PRICE_URL}${aptosCoinName}`) + const { data: { supply } } = await utils.getData(`${NODE_URL}/accounts/${AMNIS_RESOURCE_ACCOUNT}/resource/0x1::coin::CoinInfo%3C${AMNIS_RESOURCE_ACCOUNT}::amapt_token::AmnisApt%3E`) + tvlUsd = supply.vec[0].integer.vec[0].value/1e8 * aptPrice.coins[aptosCoinName].price + + return [ + { + pool: `${AMNIS_RESOURCE_ACCOUNT}-amnis-finance`, + chain: utils.formatChain('aptos'), + project: 'amnis-finance', + symbol: utils.formatSymbol('apt'), + tvlUsd: tvlUsd, + apy: apy, + apyBase: apy, + }, + ]; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://amnis.finance', +}; \ No newline at end of file diff --git a/src/adaptors/amphor/index.js b/src/adaptors/amphor/index.js new file mode 100644 index 0000000000..bee83f56fb --- /dev/null +++ b/src/adaptors/amphor/index.js @@ -0,0 +1,93 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const poolsFunction = async () => { + + const wbtc = "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"; + const wsteth = "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0"; + const prices = (await utils.getPrices([wsteth, wbtc], 'ethereum')) + .pricesByAddress; + const usdcVaultAddress = '0x3b022EdECD65b63288704a6fa33A8B9185b5096b'; + const wstethVaultAddress = '0x2791EB5807D69Fe10C02eED6B4DC12baC0701744'; + const wbtcVaultAddress = '0xC4A324fDF8a2495776B4d6cA46599B5a52f96489'; + + const ERC4626TotalAssets = + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }; + const wstethAprData = await utils.getData( + 'https://app.amphor.io/api/apr?vault=wstethVault' + ); + const wstethApy = ((1 + Number(JSON.stringify(wstethAprData.wstethVault.strategyNetAPR))/2600) ** (26) - 1) * 100; + + const usdcAprData = await utils.getData( + 'https://app.amphor.io/api/apr?vault=usdcVault' + ); + const usdcApy = ((1 + Number(JSON.stringify(usdcAprData.usdcVault.strategyNetAPR))/2600) ** (26) - 1) * 100; + + const wbtcAprData = await utils.getData( + 'https://app.amphor.io/api/apr?vault=wbtcVault' + ); + const wbtcApy = ((1 + Number(JSON.stringify(wbtcAprData.wbtcVault.strategyNetAPR))/2600) ** (26) - 1) * 100; + + const usdcTotalAsset = await sdk.api.abi.call({ + abi: ERC4626TotalAssets, + chain: 'ethereum', + target: usdcVaultAddress, + }); + const wstethTotalAsset = await sdk.api.abi.call({ + abi: ERC4626TotalAssets, + chain: 'ethereum', + target: wstethVaultAddress, + }); + const wbtcTotalAsset = await sdk.api.abi.call({ + abi: ERC4626TotalAssets, + chain: 'ethereum', + target: wbtcVaultAddress, + }); + + const usdcPool = { + pool: usdcVaultAddress, + chain: 'ethereum', + project: 'amphor', + symbol: utils.formatSymbol('USDC'), + tvlUsd: Number(usdcTotalAsset.output)/1e6, + apy: usdcApy, + }; + + const wstethPool = { + pool: wstethVaultAddress, + chain: 'ethereum', + project: 'amphor', + symbol: utils.formatSymbol('WSTETH'), + tvlUsd: (Number(wstethTotalAsset.output)/1e18) * prices[wsteth.toLowerCase()], + apy: wstethApy, + }; + + const wbtcPool = { + pool: wbtcVaultAddress, + chain: 'ethereum', + project: 'amphor', + symbol: utils.formatSymbol('WBTC'), + tvlUsd: (Number(wbtcTotalAsset.output)/1e8) * prices[wbtc.toLowerCase()], + apy: wbtcApy, + }; + + return [usdcPool, wstethPool, wbtcPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.amphor.io/earn', +}; diff --git a/src/adaptors/amply-finance/abi.js b/src/adaptors/amply-finance/abi.js new file mode 100644 index 0000000000..42fd722b87 --- /dev/null +++ b/src/adaptors/amply-finance/abi.js @@ -0,0 +1,4 @@ +module.exports = { + aTokenAbi: [{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"BalanceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlyingAsset","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"address","name":"incentivesController","type":"address"},{"indexed":false,"internalType":"uint8","name":"aTokenDecimals","type":"uint8"},{"indexed":false,"internalType":"string","name":"aTokenName","type":"string"},{"indexed":false,"internalType":"string","name":"aTokenSymbol","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balanceIncrease","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ATOKEN_REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_REVISION","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESERVE_TREASURY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING_ASSET_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"receiverOfUnderlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getIncentivesController","outputs":[{"internalType":"contract IAaveIncentivesController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPreviousIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getScaledUserBalanceAndSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"handleRepayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"initializingPool","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"contract IAaveIncentivesController","name":"incentivesController","type":"address"},{"internalType":"uint8","name":"aTokenDecimals","type":"uint8"},{"internalType":"string","name":"aTokenName","type":"string"},{"internalType":"string","name":"aTokenSymbol","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mintToTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"scaledBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scaledTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAaveIncentivesController","name":"controller","type":"address"}],"name":"setIncentivesController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferOnLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferUnderlyingTo","outputs":[],"stateMutability":"nonpayable","type":"function"}], + aaveStakedTokenDataProviderAbi: [{"inputs":[{"internalType":"address","name":"stkAave","type":"address"},{"internalType":"address","name":"ethUsdPriceFeed","type":"address"},{"internalType":"address","name":"aaveUsdPriceFeed","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AAVE_USD_PRICE_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_PRICE_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKED_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakedAsset","type":"address"},{"internalType":"address","name":"oracle","type":"address"}],"name":"getStakedAssetData","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"stakedAssets","type":"address[]"},{"internalType":"address[]","name":"oracles","type":"address[]"}],"name":"getStakedAssetDataBatch","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakedAsset","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getStakedUserData","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"stakedTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"stakedTokenRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"underlyingTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"rewardsToClaim","type":"uint256"},{"internalType":"uint40","name":"userCooldownTimestamp","type":"uint40"},{"internalType":"uint216","name":"userCooldownAmount","type":"uint216"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenUserData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"stakedAssets","type":"address[]"},{"internalType":"address[]","name":"oracles","type":"address[]"},{"internalType":"address","name":"user","type":"address"}],"name":"getStakedUserDataBatch","outputs":[{"components":[{"internalType":"uint256","name":"stakedTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stakedTokenTotalRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"stakeCooldownSeconds","type":"uint256"},{"internalType":"uint256","name":"stakeUnstakeWindow","type":"uint256"},{"internalType":"uint256","name":"stakedTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"rewardTokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"stakeApy","type":"uint256"},{"internalType":"uint128","name":"distributionPerSecond","type":"uint128"},{"internalType":"bool","name":"inPostSlashingPeriod","type":"bool"},{"internalType":"uint256","name":"distributionEnd","type":"uint256"},{"internalType":"uint256","name":"maxSlashablePercentage","type":"uint256"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenData[]","name":"","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"stakedTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"stakedTokenRedeemableAmount","type":"uint256"},{"internalType":"uint256","name":"underlyingTokenUserBalance","type":"uint256"},{"internalType":"uint256","name":"rewardsToClaim","type":"uint256"},{"internalType":"uint40","name":"userCooldownTimestamp","type":"uint40"},{"internalType":"uint216","name":"userCooldownAmount","type":"uint216"}],"internalType":"struct IStakedTokenDataProvider.StakedTokenUserData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}] +} \ No newline at end of file diff --git a/src/adaptors/amply-finance/index.js b/src/adaptors/amply-finance/index.js new file mode 100644 index 0000000000..6bc62ddebd --- /dev/null +++ b/src/adaptors/amply-finance/index.js @@ -0,0 +1,131 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); +const { aaveStakedTokenDataProviderAbi } = require('./abi'); + +const protocolDataProviders = { + cronos_zkevm: '0x47656eb2A31094b348EBF458Eccb942d471324eD', +}; + +const getApy = async (chain) => { + const protocolDataProvider = protocolDataProviders[chain]; + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens.map((pool, i) => { + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + totalBorrowUsd = totalSupplyUsd - tvlUsd; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + chain, + project: 'amply-finance', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + }; + }); +}; + +const apy = async () => { + const pools = await Promise.all( + Object.keys(protocolDataProviders).map(async (chain) => getApy(chain)) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://amply.finance/', +}; diff --git a/src/adaptors/amply-finance/poolAbi.js b/src/adaptors/amply-finance/poolAbi.js new file mode 100644 index 0000000000..a0c13ecfb4 --- /dev/null +++ b/src/adaptors/amply-finance/poolAbi.js @@ -0,0 +1,489 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getATokenTotalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getDebtCeiling', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getFlashLoanEnabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getInterestRateStrategyAddress', + outputs: [ + { + internalType: 'address', + name: 'irStrategyAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getLiquidationProtocolFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getPaused', + outputs: [ + { + internalType: 'bool', + name: 'isPaused', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveCaps', + outputs: [ + { + internalType: 'uint256', + name: 'borrowCap', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyCap', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveConfigurationData', + outputs: [ + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ltv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowingEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'unbacked', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalAToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveEModeCategory', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveTokensAddresses', + outputs: [ + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getSiloedBorrowing', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getTotalDebt', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getUnbackedMintCap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'scaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/anchor/index.js b/src/adaptors/anchor/index.js deleted file mode 100644 index 8bbd75bd00..0000000000 --- a/src/adaptors/anchor/index.js +++ /dev/null @@ -1,38 +0,0 @@ -const utils = require('../utils'); - -const buildPool = (entry, chainString) => { - const newObj = { - pool: 'terra1hzh9vpxhsk8253se0vv5jj6etdvxu3nv8z07zu', - chain: utils.formatChain(chainString), - project: 'anchor', - symbol: utils.formatSymbol('UST'), - tvlUsd: Number(entry.tvl) / 1e6, - apy: entry.deposit_apy * 100, - }; - - return newObj; -}; - -const topLvl = async (chainString) => { - let data = await utils.getData( - 'https://api.anchorprotocol.com/api/v1/market/ust' - ); - const dataTvl = await utils.getData( - 'https://api.anchorprotocol.com/api/v1/deposit' - ); - data.tvl = dataTvl.total_ust_deposits; - - data = [data].map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async () => { - const data = await topLvl('terra'); - return data; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/angle/index.js b/src/adaptors/angle/index.js index 0a0be436dc..0545189b90 100644 --- a/src/adaptors/angle/index.js +++ b/src/adaptors/angle/index.js @@ -3,6 +3,17 @@ const utils = require('../utils'); const networks = { 1: 'Ethereum', 137: 'Polygon', + 501404: 'Solana', + 122: 'Fuse', + 250: 'Fantom', +}; + +const CDP_URL = 'https://api.angle.money/v1/vaultManagers'; +const cdpNetworksSupport = { + 1: 'ethereum', + 137: 'polygon', + 42161: 'arbitrum', + 10: 'optimism', }; let symbol; @@ -31,16 +42,79 @@ const getPoolsData = async () => { chain: networks[apyData[staking]?.network] || 'Other', project: 'angle', symbol: symbol, - tvlUsd: apyData[staking]?.tvl, - apy: apyData[staking]['apr']?.value, + tvlUsd: apyData[staking]?.tvl || 0, + apyBase: + apyData[staking]['apr']?.value || + apyData[staking]['apr']?.details?.['ANGLE'] || + 0, }; result.push(pool); } - return result; + return result.filter((p) => p.chain !== 'Other'); +}; + +const AGEUR = 'ageur'; + +const cdpData = async () => { + const queryChainId = (chainId) => `?chainId=${chainId}`; + + const vaultCall = ( + await Promise.all( + Object.keys(cdpNetworksSupport).map((id) => + utils.getData(`${CDP_URL}${queryChainId(id)}`) + ) + ) + ).map((pool) => Object.keys(pool).map((key) => pool[key])); + const result = []; + const mintedCoinPrice = (await utils.getPrices([`coingecko:${AGEUR}`])) + .pricesBySymbol[AGEUR.toLowerCase()]; + + for (const [index, vault] of vaultCall.entries()) { + const stableAdress = vault.map((e) => e.stablecoin); + const collateralAdrees = vault.map((e) => e.collateral); + const chain = Object.values(cdpNetworksSupport)[index]; + const coins = collateralAdrees.map((address) => `${chain}:${address}`); + const prices = ( + await utils.getPrices([...coins, `${chain}:${stableAdress[0]}`]) + ).pricesByAddress; + + const _result = vault.map((_vault) => { + const totalSupplyUsd = + Number(_vault.totalCollateral) * + prices[_vault.collateral.toLowerCase()]; + const totalBorrowUsd = Number(_vault.totalDebt) * mintedCoinPrice; + + return { + pool: `${_vault.address}-${chain}`, + project: 'angle', + chain: chain, + symbol: _vault.symbol.split('-')[0], + apy: 0, + tvlUsd: totalSupplyUsd, + apyBaseBorrow: ((_vault.stabilityFee - 1) / 1) * 100, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + ltv: Number(_vault.maxLTV), + mintedCoin: 'agEUR', + debtCeilingUsd: + (Number(_vault.debtCeiling) / 10 ** 18) * mintedCoinPrice, + }; + }); + + result.push(_result); + } + return result.flat(); +}; + +const main = async () => { + const apy = await getPoolsData(); + const cdp = await cdpData(); + return [...apy, ...cdp].filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: false, - apy: getPoolsData, + apy: main, + url: 'https://app.angle.money/earn', }; diff --git a/src/adaptors/animeswap/index.js b/src/adaptors/animeswap/index.js new file mode 100644 index 0000000000..cd510f1c01 --- /dev/null +++ b/src/adaptors/animeswap/index.js @@ -0,0 +1,186 @@ +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const DEPLOYER_ADDRESS = '0x16fe2df00ea7dde4a63409201f7f4e536bde7bb7335526a35d05111e68aa322c'; +const STAKING_ADDRESS = '0x8615f5671592532631e56c76ca09d332fae1cd03d463bc379eec1007973966ef'; +const POOL_ADDRESS = '0x796900ebe1a1a54ff9e932f19c548f5c1af5c6e7d34965857ac2f7b1d1ab2cbf'; +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; +const DECIMALS = 1e8; + +const aptosCoinName = 'coingecko:aptos'; +const aptCoinName = '0x1::aptos_coin::AptosCoin'; +const aniCoinName = `${DEPLOYER_ADDRESS}::AnimeCoin::ANI`; +const zusdcCoinName = '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC'; + +async function getPricePerLPCoin(coinX, coinY, ledgerVersion) { + const [lp, lpCoinInfo] = await Promise.all([ + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeSwapPoolV1::LiquidityPool<${coinX},${coinY}>?ledger_version=${ledgerVersion}`), + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/0x1::coin::CoinInfo<${POOL_ADDRESS}::LPCoinV1::LPCoin<${coinX},${coinY}>>?ledger_version=${ledgerVersion}`), + ]) + + const lpSupply = lpCoinInfo.data.supply.vec[0].integer.vec[0].value // lp total supply + return BigNumber(lp.data.coin_x_reserve.value) + .multipliedBy(lp.data.coin_y_reserve.value) + .sqrt() + .div(lpSupply) +} + +async function main() { + const [aptPrice, coinInfo, coinInfoAPTzUDSC, swapPool, swapPoolAPTzUDSC, aniPoolInfo, lpPoolInfo, lpPoolInfoAPTzUDSC, mcData, ledgerInfo] = await Promise.all([ + utils.getData(`${COINS_LLAMA_PRICE_URL}${aptosCoinName}`), + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/0x1::coin::CoinInfo<${POOL_ADDRESS}::LPCoinV1::LPCoin<${aptCoinName},${aniCoinName}>>`), + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/0x1::coin::CoinInfo<${POOL_ADDRESS}::LPCoinV1::LPCoin<${aptCoinName},${zusdcCoinName}>>`), + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeSwapPoolV1::LiquidityPool<${aptCoinName},${aniCoinName}>`), + utils.getData(`${NODE_URL}/accounts/${POOL_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeSwapPoolV1::LiquidityPool<${aptCoinName},${zusdcCoinName}>`), + utils.getData(`${NODE_URL}/accounts/${STAKING_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeMasterChefV1::PoolInfo<${aniCoinName}>`), + utils.getData(`${NODE_URL}/accounts/${STAKING_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeMasterChefV1::PoolInfo<${POOL_ADDRESS}::LPCoinV1::LPCoin<${aptCoinName},${aniCoinName}>>`), + utils.getData(`${NODE_URL}/accounts/${STAKING_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeMasterChefV1::PoolInfo<${POOL_ADDRESS}::LPCoinV1::LPCoin<${aptCoinName},${zusdcCoinName}>>`), + utils.getData(`${NODE_URL}/accounts/${STAKING_ADDRESS}/resource/${DEPLOYER_ADDRESS}::AnimeMasterChefV1::MasterChefData`), + utils.getData(`${NODE_URL}/`), + ]); + + const YEAR_S = 365 * 86400; + + // calculate ANI staking + // ANI + const stakedANI = aniPoolInfo.data.coin_reserve.value; + const interestANI = BigNumber(mcData.data.per_second_ANI) + .multipliedBy(aniPoolInfo.data.alloc_point) + .div(mcData.data.total_alloc_point) + .multipliedBy(BigNumber(100).minus(mcData.data.dao_percent)) + .div(100) + .multipliedBy(YEAR_S); + const aprANIReward = interestANI + .div(stakedANI) + .multipliedBy(100) + .toNumber(); + + const tvlUsdStakeAni = BigNumber(stakedANI) + .multipliedBy(swapPool.data.coin_x_reserve.value) + .div(swapPool.data.coin_y_reserve.value) + .multipliedBy(aptPrice.coins[aptosCoinName].price) + .div(DECIMALS) + .toNumber(); + + // APT-ANI + const lpSupply = coinInfo.data.supply.vec[0].integer.vec[0].value; + const stakedLP = lpPoolInfo.data.coin_reserve.value; + const interestANI2 = BigNumber(mcData.data.per_second_ANI) + .multipliedBy(lpPoolInfo.data.alloc_point) + .div(mcData.data.total_alloc_point) + .multipliedBy(BigNumber(100).minus(mcData.data.dao_percent)) + .div(100) + .multipliedBy(YEAR_S); + const lpCoinValue2ANI = BigNumber(stakedLP) + .div(lpSupply) + .multipliedBy(swapPool.data.coin_y_reserve.value) + .multipliedBy(2); + const aprLPCoinReward = interestANI2 + .div(lpCoinValue2ANI) + .multipliedBy(100) + .toNumber(); + + const tvlUsdLPCoin = lpCoinValue2ANI + .multipliedBy(swapPool.data.coin_x_reserve.value) + .div(swapPool.data.coin_y_reserve.value) + .multipliedBy(aptPrice.coins[aptosCoinName].price) + .div(DECIMALS) + .toNumber(); + + // APT-zUSDC + const lpSupplyAPTzUDSC = coinInfoAPTzUDSC.data.supply.vec[0].integer.vec[0].value; + const stakedLPAPTzUDSC = lpPoolInfoAPTzUDSC.data.coin_reserve.value; + const interestANI3 = BigNumber(mcData.data.per_second_ANI) + .multipliedBy(lpPoolInfoAPTzUDSC.data.alloc_point) + .div(mcData.data.total_alloc_point) + .multipliedBy(BigNumber(100).minus(mcData.data.dao_percent)) + .div(100) + .multipliedBy(YEAR_S); + const lpCoinAPTzUDSCValue2ANI = BigNumber(stakedLPAPTzUDSC) + .div(lpSupplyAPTzUDSC) + .multipliedBy(swapPoolAPTzUDSC.data.coin_x_reserve.value) + .multipliedBy(swapPool.data.coin_y_reserve.value) + .div(swapPool.data.coin_x_reserve.value) + .multipliedBy(2); + const aprLPCoinAPTzUDSCReward = interestANI3 + .div(lpCoinAPTzUDSCValue2ANI) + .multipliedBy(100) + .toNumber(); + + const tvlAPTzUDSCUsdLPCoin = lpCoinAPTzUDSCValue2ANI + .multipliedBy(swapPool.data.coin_x_reserve.value) + .div(swapPool.data.coin_y_reserve.value) + .multipliedBy(aptPrice.coins[aptosCoinName].price) + .div(DECIMALS) + .toNumber(); + + // calculate pool apy base + const currentLedgerVersion = BigNumber(ledgerInfo.ledger_version); + const queryLedgerVersion = currentLedgerVersion.minus(1e6); + const currentTimestamp = ledgerInfo.ledger_timestamp; + const [currentPricePerLPCoin, queryPricePerLPCoin, currentPricePerLPCoinAPTzUDSC, queryPricePerLPCoinAPTzUDSC, queryTx] = await Promise.all([ + getPricePerLPCoin(aptCoinName, aniCoinName, currentLedgerVersion), + getPricePerLPCoin(aptCoinName, aniCoinName, queryLedgerVersion), + getPricePerLPCoin(aptCoinName, zusdcCoinName, currentLedgerVersion), + getPricePerLPCoin(aptCoinName, zusdcCoinName, queryLedgerVersion), + utils.getData(`${NODE_URL}/transactions/by_version/${queryLedgerVersion}`), + ]); + const deltaTimestamp = BigNumber(currentTimestamp) + .minus(queryTx.timestamp) + .div(1e6); + const apyLPCoinBase = currentPricePerLPCoin + .minus(queryPricePerLPCoin) + .div(queryPricePerLPCoin) + .multipliedBy(YEAR_S) + .div(deltaTimestamp) + .multipliedBy(100) + .toNumber(); + const apyLPCoinAPTzUDSCBase = currentPricePerLPCoinAPTzUDSC + .minus(queryPricePerLPCoinAPTzUDSC) + .div(queryPricePerLPCoinAPTzUDSC) + .multipliedBy(YEAR_S) + .div(deltaTimestamp) + .multipliedBy(100) + .toNumber(); + + return [ + { + pool: `${STAKING_ADDRESS}-StakeANI-aptos`, + chain: utils.formatChain('Aptos'), + project: 'animeswap', + symbol: utils.formatSymbol('ANI'), + tvlUsd: tvlUsdStakeAni, + apyReward: aprANIReward, + rewardTokens: [aniCoinName], + poolMeta: 'Stake ANI', + }, + { + pool: `${STAKING_ADDRESS}-APT-ANI-aptos`, + chain: utils.formatChain('Aptos'), + project: 'animeswap', + symbol: utils.formatSymbol('APT-ANI'), + tvlUsd: tvlUsdLPCoin, + apyBase: apyLPCoinBase, + apyReward: aprLPCoinReward, + rewardTokens: [aniCoinName], + }, + { + pool: `${STAKING_ADDRESS}-APT-zUSDC-aptos`, + chain: utils.formatChain('Aptos'), + project: 'animeswap', + symbol: utils.formatSymbol('APT-zUSDC'), + tvlUsd: tvlAPTzUDSCUsdLPCoin, + apyBase: apyLPCoinAPTzUDSCBase, + apyReward: aprLPCoinAPTzUDSCReward, + rewardTokens: [aniCoinName], + }, + ]; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.animeswap.org/#/pool?chain=aptos', +}; diff --git a/src/adaptors/ankr/index.js b/src/adaptors/ankr/index.js index f1e6ba2138..d229b86371 100644 --- a/src/adaptors/ankr/index.js +++ b/src/adaptors/ankr/index.js @@ -1,6 +1,22 @@ const utils = require('../utils'); -const buildObject = (entry, tokenString, chainString) => { +const serviceToUrl = { + eth: 'ethereum', + ftm: 'fantom', + avax: 'avax', + polygon: 'matic', + bnb: 'bnb', +}; + +const underlying = { + eth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + ftm: '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', + avax: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', + polygon: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', + bnb: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', +}; + +const buildObject = (entry, tokenString, chainString, serviceName) => { const payload = { pool: `ankr-${tokenString}`, chain: utils.formatChain(chainString), @@ -8,20 +24,27 @@ const buildObject = (entry, tokenString, chainString) => { symbol: utils.formatSymbol(tokenString), tvlUsd: Number(entry.totalStakedUsd), apy: Number(entry.apy), + url: `https://www.ankr.com/staking/stake/${serviceToUrl[serviceName]}`, + underlyingTokens: [underlying[serviceName]], }; return payload; }; const fetch = async (serviceName, tokenString, chainString) => { - data = await utils.getData('https://api.stkr.io/v1alpha/metrics'); + data = await utils.getData('https://api.staking.ankr.com/v1alpha/metrics'); const idx = data.services.findIndex( (service) => service.serviceName === serviceName ); if (idx > -1) { - data = buildObject(data.services[idx], tokenString, chainString); + data = buildObject( + data.services[idx], + tokenString, + chainString, + serviceName + ); } else { data = {}; } @@ -31,11 +54,11 @@ const fetch = async (serviceName, tokenString, chainString) => { const main = async () => { const data = await Promise.all([ - fetch('eth', 'aETHc', 'ethereum'), - fetch('bnb', 'aBNBc', 'binance'), - fetch('ftm', 'aFTMc', 'fantom'), - fetch('polygon', 'aMATICc', 'polygon'), - fetch('avax', 'aAVAXc', 'avalanche'), + fetch('eth', 'ankrETH', 'ethereum'), + fetch('bnb', 'ankrBNB', 'binance'), + fetch('ftm', 'ankrFTM', 'fantom'), + fetch('polygon', 'ankrMATIC', 'polygon'), + fetch('avax', 'ankrAVAX', 'avalanche'), ]); return data.flat(); }; diff --git a/src/adaptors/anzen-v2/index.js b/src/adaptors/anzen-v2/index.js new file mode 100644 index 0000000000..9018a50658 --- /dev/null +++ b/src/adaptors/anzen-v2/index.js @@ -0,0 +1,62 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); + +const USDz = '0xA469B7Ee9ee773642b3e93E842e5D9b5BaA10067'; +const sUSDz = '0x547213367cfb08ab418e7b54d7883b2c2aa27fd7'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: sUSDz, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const priceKey = `ethereum:${USDz}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const tvlUsd = totalSupply * price; + + const currentBlock = await sdk.api.util.getLatestBlock('ethereum'); + const toBlock = currentBlock.number; + const topic = + '0xd0e841f234010ad7f57b7c09faffb2245cd240429c6e8fa3cd934a0a8bf58eb0'; + const logs = ( + await sdk.api.util.getLogs({ + target: '0x547213367cfb08ab418e7b54d7883b2c2aa27fd7', + topic: '', + toBlock, + fromBlock: 19881601, + keys: [], + topics: [topic], + chain: 'ethereum', + }) + ).output.sort((a, b) => b.blockNumber - a.blockNumber); + + console.log(logs[0]); + // rewards are now beeing streamed every week, which we scale up to a year + const rewardsReceived = parseInt(logs[0].topics[1] / 1e18); + const aprBase = ((rewardsReceived * 365 / 7) / tvlUsd) * 100; + // weekly compoounding + const apyBase = utils.aprToApy(aprBase, 52); + return [ + { + pool: sUSDz, + symbol: 'sUSDz', + project: 'anzen-v2', + chain: 'Ethereum', + tvlUsd, + apyBase, + poolMeta: '7 days unstaking', + }, + ]; +}; + +module.exports = { + apy, + url: 'https://anzen.finance/', +}; \ No newline at end of file diff --git a/src/adaptors/apertureswap/index.js b/src/adaptors/apertureswap/index.js new file mode 100644 index 0000000000..a65037a5e0 --- /dev/null +++ b/src/adaptors/apertureswap/index.js @@ -0,0 +1,257 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('../uniswap-v3/estimateFee.ts'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); + +const chains = { + manta: + 'https://api.goldsky.com/api/public/project_clnz7akg41cv72ntv0uhyd3ai/subgraphs/aperture-manta-pacific/uniswap-v3/gn', +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + }); + + dataNow = dataNow.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = false; + if (enableV3Apy) { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // split up subgraph tick calls into n-batches + // (tick response can be in the thousands per pool) + const skip = 20; + let start = 0; + let stop = skip; + const pages = Math.floor(dataNow.length / skip); + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + let X = []; + for (let i = 0; i <= pages; i++) { + console.log(i); + let promises = dataNow.slice(start, stop).map((p) => { + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + return EstimatedFees( + p.id, + priceAssumption, + [ + p.token1_in_token0 * (1 - delta), + p.token1_in_token0 * (1 + delta), + ], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + url, + p.volumeUSD7d + ); + }); + X.push(await Promise.all(promises)); + start += skip; + stop += skip; + } + const d = {}; + X.flat().forEach((p) => { + d[p.poolAddress] = p.estimatedFee; + }); + + dataNow = dataNow.map((p) => ({ + ...p, + apy7d: ((d[p.id] * 52) / investmentAmount) * 100, + })); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://app.aperture.finance/new-position?tokenA=${token0}-false&tokenB=${token1}-false&feeTier=${feeTier}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'apertureswap', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + console.log(chainString, e); + return []; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/apeswap-amm/abis/abi-ape-price-getter.json b/src/adaptors/apeswap-amm/abis/abi-ape-price-getter.json new file mode 100644 index 0000000000..7bb12c3ed2 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-ape-price-getter.json @@ -0,0 +1,85 @@ +[ + { + "inputs": [], + "name": "DECIMALS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FACTORY", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITCODEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBNBPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "_decimals", "type": "uint256" } + ], + "name": "getLPPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "tokens", "type": "address[]" }, + { "internalType": "uint256", "name": "_decimals", "type": "uint256" } + ], + "name": "getLPPrices", + "outputs": [{ "internalType": "uint256[]", "name": "prices", "type": "uint256[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "_decimals", "type": "uint256" } + ], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "tokens", "type": "address[]" }, + { "internalType": "uint256", "name": "_decimals", "type": "uint256" } + ], + "name": "getPrices", + "outputs": [{ "internalType": "uint256[]", "name": "prices", "type": "uint256[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "token", "type": "address" }], + "name": "getRawPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address[]", "name": "tokens", "type": "address[]" }], + "name": "getRawPrices", + "outputs": [{ "internalType": "uint256[]", "name": "prices", "type": "uint256[]" }], + "stateMutability": "view", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-erc20.json b/src/adaptors/apeswap-amm/abis/abi-erc20.json new file mode 100644 index 0000000000..0efe3d7813 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-erc20.json @@ -0,0 +1,223 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } + ] + \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-jungle-farms.json b/src/adaptors/apeswap-amm/abis/abi-jungle-farms.json new file mode 100644 index 0000000000..f8f13cb9c2 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-jungle-farms.json @@ -0,0 +1,41 @@ +[ + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bonusEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-lp-token.json b/src/adaptors/apeswap-amm/abis/abi-lp-token.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-lp-token.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-master-chef-polygon.json b/src/adaptors/apeswap-amm/abis/abi-master-chef-polygon.json new file mode 100644 index 0000000000..0f198370d4 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-master-chef-polygon.json @@ -0,0 +1,89 @@ +[ + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "pools", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bananaPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "accBananaPerShare", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "allocPoint", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-master-chef-v2.json b/src/adaptors/apeswap-amm/abis/abi-master-chef-v2.json new file mode 100644 index 0000000000..f5d10e0b32 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-master-chef-v2.json @@ -0,0 +1,1149 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "banana_", + "type": "address" + }, + { + "internalType": "contract IMasterApe", + "name": "masterApe_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "masterPid_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bananaPerSecond_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositBananaRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "stakeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFee", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "contract IRewarderV2", + "name": "rewarder", + "type": "address" + } + ], + "name": "LogPoolAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFee", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "contract IRewarderV2", + "name": "rewarder", + "type": "address" + } + ], + "name": "LogSetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakeSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accBananaPerShare", + "type": "uint256" + } + ], + "name": "LogUpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetFeeAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pendingMasterApeOwner", + "type": "address" + } + ], + "name": "SetPendingMasterApeV1Owner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelistAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "whitelistEnabled", + "type": "bool" + } + ], + "name": "UpdateContractWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bananaPerSecond", + "type": "uint256" + } + ], + "name": "UpdateEmissionRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "hardCap", + "type": "uint256" + } + ], + "name": "UpdateHardCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "whitelistEnabled", + "type": "bool" + } + ], + "name": "UpdateWhitelistStatus", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MASTER_APE_BANANA_PER_BLOCK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MASTER_APE_BANANA_PER_SECOND_ESTIMATE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DEPOSIT_FEE_BP", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptMasterApeV1Ownership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_stakeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "contract IRewarderV2", + "name": "_rewarder", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "availableBananaRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "banana", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bananaPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositBananaRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "depositTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IRewarderV2", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accBananaPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStaked", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getWhitelistAtIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hardCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvestFromMasterApe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "masterApe", + "outputs": [ + { + "internalType": "contract IMasterApe", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterPid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingBanana", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingMasterApeV1Owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "poolExistence", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "stakeToken", + "type": "address" + }, + { + "internalType": "contract IRewarderV2", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStaked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accBananaPerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "contract IRewarderV2", + "name": "_rewarder", + "type": "address" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_addresses", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_enabled", + "type": "bool[]" + } + ], + "name": "setBatchContractWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + } + ], + "name": "setContractWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeAddress", + "type": "address" + } + ], + "name": "setFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pendingMasterApeV1Owner", + "type": "address" + } + ], + "name": "setPendingMasterApeV1Owner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + } + ], + "name": "setWhitelistEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unallocatedBanana", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bananaPerSecond", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_hardCap", + "type": "uint256" + } + ], + "name": "updateHardCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/abis/abi-master-chef.json b/src/adaptors/apeswap-amm/abis/abi-master-chef.json new file mode 100644 index 0000000000..9fcb101151 --- /dev/null +++ b/src/adaptors/apeswap-amm/abis/abi-master-chef.json @@ -0,0 +1,594 @@ +[ + { + "inputs": [ + { + "internalType": "contract BananaToken", + "name": "_banana", + "type": "address" + }, + { + "internalType": "contract BananaSplitBar", + "name": "_bananaSplit", + "type": "address" + }, + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_bananaPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_multiplier", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cake", + "outputs": [ + { + "internalType": "contract BananaToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cakePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "checkPoolDuplicate", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + } + ], + "name": "dev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devaddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "enterStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accCakePerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "leaveStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingCake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accCakePerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "syrup", + "outputs": [ + { + "internalType": "contract BananaSplitBar", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "multiplierNumber", + "type": "uint256" + } + ], + "name": "updateMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/apeswap-amm/config.js b/src/adaptors/apeswap-amm/config.js new file mode 100644 index 0000000000..cfba1db8b2 --- /dev/null +++ b/src/adaptors/apeswap-amm/config.js @@ -0,0 +1,49 @@ +const sdk = require('@defillama/sdk'); +const masterChefV2ABIBNB = require('./abis/abi-master-chef-v2.json'); +const masterChefABIPolygon = require('./abis/abi-master-chef-polygon.json'); +exports.CHAINS = { + bsc: { + banana: '0x603c7f932ED1fc6575303D8Fb018fDCBb0f39a95', + masterchef: '0x71354AC3c695dfB1d3f595AfA5D4364e9e06339B', + feeRate: 0.0005, + // apiUrl: 'https://bnb.apeswapgraphs.com/subgraphs/name/ape-swap/apeswap-subgraph', + apiUrl: sdk.graph.modifyEndpoint('GH4Zt29mCApHwMfavNFw5ZdQDH3owc2Wq8DdU4hGPXYe'), + callsName: { + length: 'poolLength', + alloc: 'totalAllocPoint', + bananaPerSecond: 'bananaPerSecond', + poolInfo: 'poolInfo', + }, + abi: masterChefV2ABIBNB, + lpToken: 'stakeToken', + exclude: [ + '0x344a9C3a0961DA3Cd78A8f5A62Bd04A0358178be', + '0x603c7f932ED1fc6575303D8Fb018fDCBb0f39a95', + '0xA5818a82016cb07D0D9892736A2Abd1B47E78ea4', + '0xeCabfEd917852D5951CAE753985aE23bd0489d3D', + '0x8A49764C91718eF2b6264E54e1b6497CcC945D49', + '0x703b40842eF1A81777e7696e37c335d32D094a80', + '0x1e8732890dB1d070FC7D6befE0008e39C7953814', + ], + }, + polygon: { + banana: '0x5d47baba0d66083c52009271faf3f50dcc01023c', + masterchef: '0x54aff400858Dcac39797a81894D9920f16972D1D', + feeRate: 0.0005, + apiUrl: sdk.graph.modifyEndpoint('32BWziYZT6en9rVM9L3sDonnjHGtKvfsiJyMDv3T7Dx1'), + callsName: { + length: 'poolLength', + alloc: 'totalAllocPoint', + bananaPerSecond: 'bananaPerSecond', + poolInfo: 'poolInfo', + }, + abi: masterChefABIPolygon, + lpToken: 'lpToken', + exclude: ['0xe9699f65a4981035589727f448c3a642F0E19209'], + }, + telos: { + farmsUrl: + 'https://raw.githubusercontent.com/ApeSwapFinance/apeswap-lists/main/config/jungleFarms.json', + apePriceGetterAddress: '0x29392EFEd565c13a0901Aeb88e32bf58EEb8a067', + }, +}; diff --git a/src/adaptors/apeswap-amm/index.js b/src/adaptors/apeswap-amm/index.js new file mode 100644 index 0000000000..2d466fbf25 --- /dev/null +++ b/src/adaptors/apeswap-amm/index.js @@ -0,0 +1,435 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); + +const lpTokenABI = require('./abis/abi-lp-token.json'); +const erc20ABI = require('./abis/abi-erc20.json'); +const apePriceABI = require('./abis/abi-ape-price-getter.json'); +const jungleFarmsABI = require('./abis/abi-jungle-farms.json'); +const utils = require('../utils'); +const { chunk } = require('lodash'); +const { request, gql, batchRequests } = require('graphql-request'); +const { CHAINS } = require('./config'); + +const WEEKS_PER_YEAR = 52; +const SECONDS_PER_YEAR = new BigNumber(31536000); + +const pairQuery = gql` + query pairQuery($id_in: [ID!]) { + pairs(where: { id_in: $id_in }) { + id + token0 { + symbol + decimals + id + } + token1 { + symbol + decimals + id + } + } + } +`; + +const getPairInfo = async (pairs, apiUrl) => { + const pairInfo = await Promise.all( + chunk(pairs, 7).map((tokens) => + request(apiUrl, pairQuery, { + id_in: tokens.map((pair) => pair.toLowerCase()), + }) + ) + ); + + return pairInfo + .map(({ pairs }) => pairs) + .flat() + .reduce((acc, pair) => ({ ...acc, [pair.id.toLowerCase()]: pair }), {}); +}; + +const getPrices = async (addresses, chain) => { + const addy = addresses.map((address) => `${chain}:${address}`).join(','); + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addy.toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + bananaPerSecond, + bananaPrice, + reserveUSD, + chain +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const bananaPerYear = bananaPerSecond * SECONDS_PER_YEAR; + return ((poolWeight * bananaPerYear * bananaPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, id: token0Address } = token0; + const { decimals: token1Decimals, id: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const apy = async (chain) => { + const masterchef = CHAINS[chain].masterchef; + const masterChefABI = CHAINS[chain].abi; + const poolLength = await sdk.api.abi.call({ + target: masterchef, + chain, + abi: masterChefABI.find((e) => e.name === CHAINS[chain].callsName.length), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: masterchef, + chain, + abi: masterChefABI.find((e) => e.name === CHAINS[chain].callsName.alloc), + }); + const bananaPerSecond = await sdk.api.abi.call({ + target: masterchef, + chain, + abi: masterChefABI.find( + (e) => e.name === CHAINS[chain].callsName.bananaPerSecond + ), + }); + const normalizedbananaPerBlock = bananaPerSecond.output / 1e18; + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter( + ({ name }) => name === CHAINS[chain].callsName.poolInfo + )[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: masterchef, + params: i, + })), + chain, + requery: true, + }); + const filterLpTokenAbi = masterChefABI.filter( + ({ name }) => name === 'lpToken' + )[0]; + const lpTokensAddress = filterLpTokenAbi + ? await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'lpToken')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: masterchef, + params: i, + })), + chain, + requery: true, + }) + : []; + const pools = poolsRes.output + .map(({ output }, i) => ({ + ...output, + ...{ + lpToken: + output[CHAINS[chain].lpToken] ?? lpTokensAddress.output[i].output, + }, + i, + })) + .filter((e) => e.allocPoint !== '0') + .filter((e) => !CHAINS[chain].exclude.includes(e[CHAINS[chain].lpToken])); + const lpTokens = pools.map(({ lpToken }) => lpToken); + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [masterchef] : null, + })), + chain, + requery: true, + }) + ) + ); + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain, + requery: true, + }) + ) + ); + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1], chain); + const pairsInfo = await getPairInfo(lpTokens, CHAINS[chain].apiUrl); + const lpChunks = chunk(lpTokens, 10); + const pairVolumes = await Promise.all( + lpChunks.map((lpsChunk) => + request( + CHAINS[chain].apiUrl, + gql` + query volumesQuery { + ${lpsChunk + .slice(0, 10) + .map( + (token, i) => `token_${token.toLowerCase()}:pairDayDatas( + orderBy: date + orderDirection: desc + first: 7 + where: { pairAddress: "${token.toLowerCase()}" } + ) { + dailyVolumeUSD + }` + ) + .join('\n')} + + } + ` + ) + ) + ); + const volumesMap = pairVolumes.flat().reduce( + (acc, curChunk) => ({ + ...acc, + ...Object.entries(curChunk).reduce((innerAcc, [key, val]) => ({ + ...innerAcc, + [key.split('_')[1]]: val, + })), + }), + {} + ); + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairsInfo[pool.lpToken.toLowerCase()]; + if (!pairInfo) return null; + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const lpReservesUsd = calculateReservesUSD( + reserves, + 1, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + const lpFees7D = + (volumesMap[pool.lpToken.toLowerCase()] || []).reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * CHAINS[chain].feeRate; + const apyBase = ((lpFees7D * WEEKS_PER_YEAR) / lpReservesUsd) * 100; + const banana = CHAINS[chain].banana; + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizedbananaPerBlock, + tokensPrices[banana.toLowerCase()], + masterChefReservesUsd, + chain + ); + + return { + pool: pool.lpToken, + chain: utils.formatChain(chain), + project: 'apeswap-amm', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyBase, + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [banana], + }; + }); + + return res; +}; +const fetchPrices = async (tokens, chain) => { + const tokenDecimals = await sdk.api.abi.multiCall({ + abi: erc20ABI.filter(({ name }) => name === 'decimals')[0], + calls: tokens.map(({ address }) => ({ + target: address, + })), + chain, + requery: true, + }); + const tokenPrices = await Promise.all( + tokens.map((token, i) => { + const method = token.isLp ? 'getLPPrice' : 'getPrice'; + return sdk.api.abi.multiCall({ + abi: apePriceABI.filter(({ name }) => name === method)[0], + calls: [ + { + target: CHAINS[chain].apePriceGetterAddress, + params: [token.address, tokenDecimals.output[i].output], + }, + ], + chain, + requery: true, + }); + }) + ); + const mappedTokenPrices = tokenPrices.map((prices, i) => { + const displayBalance = new BigNumber(prices.output[0].output).dividedBy( + new BigNumber(10).pow(tokenDecimals.output[i].output) + ); + return { + address: tokens[i].address, + price: displayBalance.toNumber(), + }; + }); + + return mappedTokenPrices; +}; + +const getAprAndStakedUsd = async (farm, tokenPrices, chain) => { + const totalStakedCall = await sdk.api.abi.multiCall({ + abi: jungleFarmsABI.filter(({ name }) => name === 'totalStaked')[0], + calls: [ + { + target: farm.contractAddress[40], + }, + ], + chain, + requery: true, + }); + const totalStaked = totalStakedCall.output[0].output / 1e18; + const rewardsPerSecond = farm.rewardsPerSecond; + + const rewardToken = tokenPrices + ? tokenPrices.find( + (token) => + farm?.rewardToken && + token?.address.toLowerCase() === + farm?.rewardToken.address[40].toLowerCase() + ) + : farm.rewardToken; + const stakingToken = tokenPrices + ? tokenPrices.find( + (token) => + token?.address.toLowerCase() === + farm?.stakingToken.address[40].toLowerCase() + ) + : farm.stakingToken; + + const stakingTokenPrice = stakingToken?.price; + const rewardTokenPrice = rewardToken?.price; + const totalStakedUsd = totalStaked * stakingTokenPrice; + const totalRewardPricePerYear = new BigNumber(rewardTokenPrice) + .times(+rewardsPerSecond) + .times(SECONDS_PER_YEAR); + const totalStakingTokenInPool = new BigNumber(stakingTokenPrice).times( + totalStaked + ); + const apr = totalRewardPricePerYear.div(totalStakingTokenInPool).times(100); + return { + rewardToken: rewardToken.address, + apr: apr.isNaN() || !apr.isFinite() ? null : apr.toNumber(), + totalStakedUsd, + }; +}; +const apyTelos = async (chain) => { + const farmsUrl = CHAINS[chain].farmsUrl; + const farmsList = (await axios.get(farmsUrl)).data; + const farmsTlos = farmsList.filter(({ network }) => network === 40); + const priceList = []; + farmsTlos.map(async (farm) => { + const tokens0 = farm.lpTokens.token.address[40]; + const tokens1 = farm.lpTokens.quoteToken.address[40]; + const lpToken = farm.stakingToken.address[40]; + priceList.push( + fetchPrices( + [ + { address: tokens0 }, + { address: tokens1 }, + { address: lpToken, isLp: true }, + ], + chain + ) + ); + }); + const prices = await Promise.all(priceList); + const data = await Promise.all( + farmsTlos.map(async (farm) => { + const tokens0 = farm.lpTokens.token.address[40]; + const tokens1 = farm.lpTokens.quoteToken.address[40]; + const lpToken = farm.stakingToken.address[40]; + const { apr, totalStakedUsd, rewardToken } = await getAprAndStakedUsd( + farm, + prices.flat(), + chain + ); + return { + pool: lpToken, + chain: utils.formatChain(chain), + project: 'apeswap-amm', + symbol: `${farm.lpTokens.token.symbol}-${farm.lpTokens.quoteToken.symbol}`, + tvlUsd: Number(totalStakedUsd), + apyReward: apr, + underlyingTokens: [tokens0, tokens1], + rewardTokens: [rewardToken], + }; + }) + ); + return data; +}; +const main = async () => { + const data = await Promise.all( + Object.keys(CHAINS).map((chain) => + chain !== 'telos' ? apy(chain) : apyTelos(chain) + ) + ); + return data + .flat() + .filter(Boolean) + .filter((p) => utils.keepFinite(p)); +}; +module.exports = { + timetravel: false, + apy: main, + url: 'https://apeswap.finance/farms', +}; diff --git a/src/adaptors/apeswap-lending/abi.js b/src/adaptors/apeswap-lending/abi.js new file mode 100644 index 0000000000..ce7e244c56 --- /dev/null +++ b/src/adaptors/apeswap-lending/abi.js @@ -0,0 +1,2988 @@ +module.exports = { + ercDelegator: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'adminPart', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'olaBank', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'olaPart', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'blocksBased', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'contractNameHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAccrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract CTokenInterface', + name: 'cTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'nativeCoinUnderlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'olaReserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + distributorAbi: [ + { + inputs: [ + { internalType: 'address', name: '_comptroller', type: 'address' }, + { internalType: 'address', name: '_admin', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'lnIncentiveToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'blockNumber', + type: 'uint256', + }, + ], + name: 'LnIncentiveTokenUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'SingleAssetDynamicRainMakerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'uint256', name: 'compSupplySpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'compBorrowSpeed', type: 'uint256' }, + ], + name: '_setDynamicCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: '_cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '_compSupplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_compBorrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setDynamicCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'incentiveTokenAddress', + type: 'address', + }, + ], + name: '_setLnIncentiveToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPendingAdmin', type: 'address' }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: '_supportMarket', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'baseUnits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'market', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'connect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'contractNameHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'distributeBorrowerComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'supplier', type: 'address' }, + ], + name: 'distributeSupplierComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getLnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'isListed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRetired', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'lnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'retire', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'retireRainMaker', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'updateCompBorrowIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: 'updateCompSupplyIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralUsage', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralUsage', + type: 'uint256', + }, + ], + name: 'ActiveCollateralUsageChange', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, + ], + name: 'LimitBorrowingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, + ], + name: 'LimitMintingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newActiveCollateralCap', + type: 'uint256', + }, + ], + name: 'NewActiveCollateralCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdminBankAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdminBankAddress', + type: 'address', + }, + ], + name: 'NewAdminBankAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBouncer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBouncer', + type: 'address', + }, + ], + name: 'NewBouncer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'ctoken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldMinBorrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMinBorrowAmount', + type: 'uint256', + }, + ], + name: 'NewMinBorrowAmount', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldRainMaker', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newRainMaker', + type: 'address', + }, + ], + name: 'NewRainMaker', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_afterNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_beforeNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_latestVersionSynced', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newActiveCollateralCaps', + type: 'uint256[]', + }, + ], + name: '_setActiveCollateralCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newAdminBankAddress', + type: 'address', + }, + ], + name: '_setAdminBankAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setBouncer', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitBorrowing', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitMinting', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'minBorrowAmountUsd_', + type: 'uint256', + }, + ], + name: '_setMinBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setRainMaker', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'address', name: 'interestRateModel', type: 'address' }, + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: '_supportNewMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'adminBankAddress', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'bouncer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'bytes32', name: '', type: 'bytes32' }, + ], + name: 'existingMarketTypes', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getRegistry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasBouncer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'initializeNewComptroller', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isAccountApproved', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitMinting', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationFactorMantissa', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationIncentiveMantissa', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'activeCollateralUSDCap', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'activeCollateralCTokenUsage', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'minBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rainMaker', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'registry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unitrollerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: 'updateDelegatedImplementations', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/apeswap-lending/index.js b/src/adaptors/apeswap-lending/index.js new file mode 100644 index 0000000000..4b13de2c90 --- /dev/null +++ b/src/adaptors/apeswap-lending/index.js @@ -0,0 +1,237 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator, distributorAbi } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0xAD48B2C9DC6709a560018c678e918253a65df86e'; +const REWARD_DISTRIBUTOR = '0x5CB93C0AdE6B7F2760Ec4389833B0cCcb5e4efDa'; +const CHAIN = 'bsc'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const REWARD_SPEEDS = 'compSupplySpeeds'; +const BORROW_SPEEDS = 'compBorrowSpeeds'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const SECONDS_PER_DAY = 86400; +const BLOCKS_PER_DAY = SECONDS_PER_DAY; + +const PROJECT_NAME = 'apeswap-lending'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'BNB', + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'BANANA', + address: '0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95'.toLowerCase(), +}; + +const getRewards = async (markets, isBorrow) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: REWARD_DISTRIBUTOR, + params: [market], + })), + abi: distributorAbi.find( + ({ name }) => name === (isBorrow ? BORROW_SPEEDS : REWARD_SPEEDS) + ), + }) + ).output.map(({ output }) => output); +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const lendingApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const marketsInfo = ( + await sdk.api.abi.multiCall({ + chain: 'bsc', + calls: allMarkets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: market, + })), + abi: comptrollerAbi.find(({ name }) => name === 'markets'), + }) + ).output.map(({ output }) => output); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const distributeRewards = await getRewards(allMarkets); + const distributeBorrowRewards = await getRewards(allMarkets, true); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + const token = symbol === 'BNB' ? NATIVE_TOKEN.address : underlyingTokens[i]; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const apyReward = + (((((distributeRewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY) / + 3) * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((((distributeBorrowRewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY) / + 3) * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalBorrowUsd) * + 100; + + return { + pool: market, + chain: utils.formatChain('binance'), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward > 0 ? PROTOCOL_TOKEN.address : null].filter( + Boolean + ), + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: marketsInfo[i].collateralFactorMantissa / 10 ** 18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: lendingApy, + url: 'https://lending.apeswap.finance/', +}; diff --git a/src/adaptors/apollodao/index.js b/src/adaptors/apollodao/index.js new file mode 100755 index 0000000000..066e40d401 --- /dev/null +++ b/src/adaptors/apollodao/index.js @@ -0,0 +1,70 @@ +const utils = require('../utils'); + +const chains = { osmosis: 'osmosis-1' }; + +const getApy = async () => { + const data = await Promise.all( + Object.entries(chains).map(async (chain) => { + const vaults = await utils.getData( + `https://api.apollo.farm/api/vault_infos/v2/${chain[1]}` + ); + + const tokens = await utils.getData( + `https://api.apollo.farm/api/tokens/v2/network/${chain[1]}` + ); + + return vaults.map((v) => { + const vault_token = tokens.find( + (t) => JSON.stringify(t.asset) === JSON.stringify(v.vault_token) + ); + const lp_token = tokens.find( + (t) => JSON.stringify(t.asset) === JSON.stringify(v.tvl.info) + ); + return { + pool: `${vault_token.asset.native}-${chain[0]}`, + chain: utils.formatChain(chain[0]), + project: 'apollodao', + symbol: utils.formatSymbol(`${v.label.split(' ')[0]}-VT`), + tvlUsd: + (v.tvl.amount / Math.pow(10, lp_token.decimals)) * lp_token.price, + apy: formatApyBreakdown(v.apr) * 100, + rewardTokens: [ + ...new Set( + v.apr.aprs + .filter((a) => a.type !== 'Swap Fee') + .map( + (a) => tokens.find((t) => t.symbol === a.type).asset.native + ) + ), + ], + underlyingTokens: [v.tvl.info.native], + poolMeta: '14days lockup', + url: 'https://apollo.farm', + }; + }); + }) + ); + + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +const formatApyBreakdown = (apr) => { + const baseApr = apr.aprs.reduce((acc, apr) => { + return acc + apr.value; + }, 0); + const fees = apr.fees.reduce((acc, fee) => { + return acc + fee.value; + }, 0); + const totalApr = baseApr - fees; + const apy = aprToApy(totalApr); + return apy; +}; + +const aprToApy = (apr) => { + return apr <= 0 ? 0 : Math.pow(1 + apr / 365, 365) - 1; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/aptin-finance-v2/index.js b/src/adaptors/aptin-finance-v2/index.js new file mode 100644 index 0000000000..cfac4891dc --- /dev/null +++ b/src/adaptors/aptin-finance-v2/index.js @@ -0,0 +1,15 @@ +const utils = require('../utils'); + +async function main() { + const apyData = await utils.getData( + 'https://data.aptin.io/api/data' + ); + return apyData +} + + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.aptin.io', +}; diff --git a/src/adaptors/aqua-patina/abi.json b/src/adaptors/aqua-patina/abi.json new file mode 100644 index 0000000000..e85509e948 --- /dev/null +++ b/src/adaptors/aqua-patina/abi.json @@ -0,0 +1,28 @@ +{ + "totalSupply": { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "ethPerAPEth": { + "inputs": [], + "name": "ethPerAPEth", + "outputs": [ + { + "internalType": "uint256", + "name": "ethPerAPEth", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/aqua-patina/index.js b/src/adaptors/aqua-patina/index.js new file mode 100644 index 0000000000..8bd7492eaf --- /dev/null +++ b/src/adaptors/aqua-patina/index.js @@ -0,0 +1,54 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const axios = require('axios'); + +const APETH = '0xAaAaAAaBC6CBc3A1FD3a0fe0FDec43251C6562F5'; +const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' + + +const getApy = async () => { + const apy = await utils.getData('https://wallet.aquapatina.com/api/apy_current'); + + tvl = await tvlUsd(); + + return [ + { + pool: APETH, + chain: utils.formatChain('ethereum'), + project: 'aqua-patina', + symbol: utils.formatSymbol('APETH'), + tvlUsd: tvl, + apy: apy.data.apy, + }, + ]; +}; + +async function tvlUsd() { + + const supply = await sdk.api.abi.call({ + target: APETH, + abi: abi['totalSupply'], + chain: 'ethereum' + }); + + const multiplier = await sdk.api.abi.call({ + target: APETH, + abi: abi['ethPerAPEth'], + chain: 'ethereum' + }); + + const ethPrice = ( + await axios.get('https://coins.llama.fi/prices/current/coingecko:ethereum') + ).data.coins['coingecko:ethereum'].price; + + let tvl = BigInt(supply.output) * BigInt(multiplier.output) / BigInt(1e18) / BigInt(1e18); + + return Number(tvl) * ethPrice; +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://aquapatina.eth/', +}; \ No newline at end of file diff --git a/src/adaptors/arbitrove/abi/abi.json b/src/adaptors/arbitrove/abi/abi.json new file mode 100644 index 0000000000..78a9b66956 --- /dev/null +++ b/src/adaptors/arbitrove/abi/abi.json @@ -0,0 +1,51 @@ +{ + "totalSupply": { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getTargets": { + "inputs": [], + "name": "getTargets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "coin", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct CoinWeight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAmountAcrossStrategies": { + "inputs": [ + { "internalType": "address", "name": "coin", "type": "address" } + ], + "name": "getAmountAcrossStrategies", + "outputs": [ + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/arbitrove/index.js b/src/adaptors/arbitrove/index.js new file mode 100644 index 0000000000..e817eab7ac --- /dev/null +++ b/src/adaptors/arbitrove/index.js @@ -0,0 +1,102 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi/abi.json'); + +const chains = { arbitrum: 'arbitrum' }; + +const getApy = async () => { + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/coingecko:nitro-cartel,coingecko:arbitrove-alp` + ); + + const { alpData } = await utils.getData( + 'https://nitrocartel.finance/api/alpData?chainId=42161&trove=alp' + ); + + const stakingAddress = '0x9d4903f755fc12cded3012686c2064e98b84e6b7'; + const troveAddress = '0x982239D38Af50B0168dA33346d85Fb12929c4c07'; + const alpAddress = '0xb49B6A3Fd1F4bB510Ef776de7A88A9e65904478A'; + const feeOracleAddress = '0x013B8efb8531fd08e47e41f53D633c249D3D73Cf'; + const nullAddress = '0x0000000000000000000000000000000000000000'; + const alpPrice = priceData['coingecko:arbitrove-alp'].price; + const trovePrice = priceData['coingecko:nitro-cartel'].price; + + const { output: alpStakedAmount } = await sdk.api.abi.call({ + target: alpAddress, + abi: 'erc20:balanceOf', + chain: chains['arbitrum'], + params: [stakingAddress], + }); + const { output: alpTotalSupply } = await sdk.api.abi.call({ + target: alpAddress, + abi: abi['totalSupply'], + chain: chains['arbitrum'], + }); + + const { output: targets } = await sdk.api.abi.call({ + target: feeOracleAddress, + abi: abi['getTargets'], + chain: chains['arbitrum'], + }); + + let tvl = 0; + + for (const target of targets) { + const coin = target.coin; + if (coin === nullAddress) { + const { output: balance } = await sdk.api.eth.getBalance({ + target: alpAddress, + chain: chains['arbitrum'], + }); + tvl = + tvl + + (balance / 1e18) * + alpData.find( + (alp) => alp.address.toLowerCase() === coin.toLowerCase() + ).price; + } else { + const { output: tokenBalance } = await sdk.api.abi.call({ + target: alpAddress, + abi: abi['getAmountAcrossStrategies'], + chain: chains['arbitrum'], + params: [coin], + }); + const { output: decimals } = await sdk.api.abi.call({ + target: coin, + abi: 'erc20:decimals', + chain: chains['arbitrum'], + }); + tvl = + tvl + + (tokenBalance / 10 ** decimals) * + alpData.find( + (alp) => alp.address.toLowerCase() === coin.toLowerCase() + ).price; + } + } + + const troveRewardPerYear = + (42900 * 365 * trovePrice * 1e18) / alpStakedAmount / alpPrice; + const alpTotalSupplyUsd = (alpTotalSupply / 1e18) * alpPrice; + + return [ + { + pool: stakingAddress, + chain: utils.formatChain(chains['arbitrum']), + project: 'arbitrove', + symbol: 'ALP', + tvlUsd: tvl, + apyReward: troveRewardPerYear * 100, + totalSupplyUsd: alpTotalSupplyUsd, + poolMeta: 'ALP', + rewardTokens: [troveAddress], + underlyingTokens: [alpAddress], // ALP + url: 'https://nitrocartel.finance/', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/arbitrum-exchange-v2/index.js b/src/adaptors/arbitrum-exchange-v2/index.js new file mode 100755 index 0000000000..46812bdabf --- /dev/null +++ b/src/adaptors/arbitrum-exchange-v2/index.js @@ -0,0 +1,214 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const masterchefAbi = require('./masterchef'); +const axios = require('axios'); + +const masterchef = '0xd2bcFd6b84E778D2DE5Bb6A167EcBBef5D053A06'; +const ARX = '0xD5954c3084a1cCd70B4dA011E67760B8e78aeE84'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint( + sdk.graph.modifyEndpoint('6Bjqi1HiqNphwqzaa3h3ojTgQwtFJ817QuE8vsyWBiCw') +); + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolLength'), + chain: chainString, + }) + ).output; + + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'poolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const arxTotalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'arxTotalAllocPoint'), + chain: chainString, + }) + ).output; + + const wethTotalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'WETHTotalAllocPoint'), + chain: chainString, + }) + ).output; + + const arxPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'arxPerSec'), + chain: chainString, + }) + ).output / 1e18; + + const wethPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'WETHPerSec'), + chain: chainString, + }) + ).output / 1e18; + + const arxPriceKey = `arbitrum:${ARX}`; + const arxPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${arxPriceKey}`) + ).data.coins[arxPriceKey]?.price; + + const wethPriceKey = `ethereum:${WETH}`; + const wethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${wethPriceKey}`) + ).data.coins[wethPriceKey]?.price; + + const arxPerYearUsd = arxPerSec * 86400 * 365 * arxPrice; + const wethPerYearUsd = wethPerSec * 86400 * 365 * wethPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString; + const url = `https://arbidex.fi/add/${token0}/${token1}/`; + + const arxAllocPoint = poolInfo.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.arxAllocPoint; + + const wethAllocPoint = poolInfo.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.WETHAllocPoint; + + const arxApyReward = + (((arxAllocPoint / arxTotalAllocPoint) * arxPerYearUsd) / + p.totalValueLockedUSD) * + 100; + + const wethApyReward = + (((wethAllocPoint / wethTotalAllocPoint) * wethPerYearUsd) / + p.totalValueLockedUSD) * + 100; + + const apyReward = arxApyReward + wethApyReward; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'arbitrum-exchange-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward, + rewardTokens: apyReward > 0 ? [WETH, ARX] : [], + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +}; + +const main = async (timestamp = null) => { + let data = await topLvl( + 'arbitrum', + url, + query, + queryPrior, + 'arbidex', + timestamp + ); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/arbitrum-exchange-v2/masterchef.js b/src/adaptors/arbitrum-exchange-v2/masterchef.js new file mode 100644 index 0000000000..1a40cc8116 --- /dev/null +++ b/src/adaptors/arbitrum-exchange-v2/masterchef.js @@ -0,0 +1,713 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "contract ArxToken", + "name": "_arx", + "type": "address" + }, + { + "internalType": "contract BEP20", + "name": "_WETH", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_arxPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHPerSec", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "contract BEP20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHTotalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "arx", + "outputs": [ + { + "internalType": "contract ArxToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arxPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arxTotalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTeamRewardBlockTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingArx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingWETH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accArxPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accWETHPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsStarted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + } + ], + "name": "setStartTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamRewardPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamTimeInbetweenRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamTotalReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllowedTeamReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_arxPerSec", + "type": "uint256" + } + ], + "name": "updateArxPerSec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "multiplierNumber", + "type": "uint256" + } + ], + "name": "updateMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_WETHPerSec", + "type": "uint256" + } + ], + "name": "updateWETHPerSec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "arxRewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "WETHRewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]; diff --git a/src/adaptors/arbitrum-exchange-v3/deshare.js b/src/adaptors/arbitrum-exchange-v3/deshare.js new file mode 100644 index 0000000000..fdc0e01c65 --- /dev/null +++ b/src/adaptors/arbitrum-exchange-v3/deshare.js @@ -0,0 +1,1059 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract IStrategyFactory", + "name": "_factory", + "type": "address" + }, + { + "internalType": "contract IUniswapV3Pool", + "name": "_pool", + "type": "address" + }, + { + "internalType": "contract IOneInchRouter", + "name": "_oneInchRouter", + "type": "address" + }, + { + "internalType": "contract FeedRegistryInterface", + "name": "_chainlinkRegistry", + "type": "address" + }, + { + "internalType": "contract IStrategyManager", + "name": "_manager", + "type": "address" + }, + { + "internalType": "bool[2]", + "name": "_usdAsBase", + "type": "bool[2]" + }, + { + "components": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct IStrategyBase.Tick[]", + "name": "_ticks", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "managerFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFee", + "type": "uint256" + } + ], + "name": "ClaimFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "FeesClaim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Hold", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "share", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "burn", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct DefiEdgeStrategy.PartialTick[]", + "name": "ticks", + "type": "tuple[]" + } + ], + "name": "PartialRebalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct DefiEdgeStrategy.NewTick[]", + "name": "ticks", + "type": "tuple[]" + } + ], + "name": "Rebalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_zeroForOne", + "type": "bool" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TICK_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accManagementFeeShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accPerformanceFeeShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accProtocolPerformanceFeeShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1Min", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "collect0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collect1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tickIndex", + "type": "uint256" + } + ], + "name": "burnLiquiditySingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "internalType": "struct DefiEdgeStrategy.NewTick[]", + "name": "_newTicks", + "type": "tuple[]" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract IStrategyFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_includeFee", + "type": "bool" + } + ], + "name": "getAUMWithFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalFee0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalFee1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getTicks", + "outputs": [ + { + "components": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct IStrategyBase.Tick[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "contract IStrategyManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minShare", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "share", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "onHold", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oneInchRouter", + "outputs": [ + { + "internalType": "contract IOneInchRouter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_swapData", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "burn", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "internalType": "struct DefiEdgeStrategy.PartialTick[]", + "name": "_existingTicks", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "internalType": "struct DefiEdgeStrategy.NewTick[]", + "name": "_newTicks", + "type": "tuple[]" + }, + { + "internalType": "bool", + "name": "_burnAll", + "type": "bool" + } + ], + "name": "rebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usdAsBase", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/arbitrum-exchange-v3/index.js b/src/adaptors/arbitrum-exchange-v3/index.js new file mode 100644 index 0000000000..cf71c67402 --- /dev/null +++ b/src/adaptors/arbitrum-exchange-v3/index.js @@ -0,0 +1,308 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); +const masterchefAbi = require('./masterchef'); +const deshareAbi = require('./deshare'); +const axios = require('axios'); +const pools = require('../concentrator/pools'); + +const masterchef = '0xd2bcFd6b84E778D2DE5Bb6A167EcBBef5D053A06'; +const ARX = '0xD5954c3084a1cCd70B4dA011E67760B8e78aeE84'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const url = sdk.graph.modifyEndpoint('AQPMJVpukYUo96WvuKqn7aPZn3m8BHckYs82ZLSMKyeu'); +const chain = 'arbitrum'; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolLength'), + chain: chainString, + }) + ).output; + + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'poolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + // find only v3 pools + const pools = []; + for (const pool of poolInfo) { + try { + const lpId = ( + await sdk.api.abi.call({ + target: pool.lpToken, + abi: deshareAbi.find((m) => m.name === 'pool'), + chain: chainString, + }) + ).output; + pool.lpId = lpId; + pools.push(pool); + } catch (error) {} + } + + const arxTotalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'arxTotalAllocPoint'), + chain: chainString, + }) + ).output; + + const wethTotalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'WETHTotalAllocPoint'), + chain: chainString, + }) + ).output; + + const arxPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'arxPerSec'), + chain: chainString, + }) + ).output / 1e18; + + const wethPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'WETHPerSec'), + chain: chainString, + }) + ).output / 1e18; + + const arxPriceKey = `arbitrum:${ARX}`; + const arxPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${arxPriceKey}`) + ).data.coins[arxPriceKey]?.price; + + const wethPriceKey = `ethereum:${WETH}`; + const wethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${wethPriceKey}`) + ).data.coins[wethPriceKey]?.price; + + const arxPerYearUsd = arxPerSec * 86400 * 365 * arxPrice; + const wethPerYearUsd = wethPerSec * 86400 * 365 * wethPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // uni v3 subgraph reserves values are wrong! + // instead of relying on subgraph values, gonna pull reserve data from contracts + // new tvl calc + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + }); + + dataNow = dataNow.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://arbidex.fi/quantumliquidity/`; + + const arxAllocPoint = pools.find( + (pid) => pid.lpId.toLowerCase() === p.id?.toLowerCase() + )?.arxAllocPoint; + + const wethAllocPoint = pools.find( + (pid) => pid.lpId.toLowerCase() === p.id?.toLowerCase() + )?.WETHAllocPoint; + + const arxApyReward = + (((arxAllocPoint / arxTotalAllocPoint) * arxPerYearUsd) / + p.totalValueLockedUSD) * + 100; + + const wethApyReward = + (((wethAllocPoint / wethTotalAllocPoint) * wethPerYearUsd) / + p.totalValueLockedUSD) * + 100; + + const apyReward = arxApyReward + wethApyReward; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'arbitrum-exchange-v3', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyReward, + rewardTokens: apyReward > 0 ? [WETH, ARX] : [], + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = await topLvl( + chain, + url, + query, + queryPrior, + 'v3', + timestamp, + stablecoins + ); + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/arbitrum-exchange-v3/masterchef.js b/src/adaptors/arbitrum-exchange-v3/masterchef.js new file mode 100644 index 0000000000..1a40cc8116 --- /dev/null +++ b/src/adaptors/arbitrum-exchange-v3/masterchef.js @@ -0,0 +1,713 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "contract ArxToken", + "name": "_arx", + "type": "address" + }, + { + "internalType": "contract BEP20", + "name": "_WETH", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_arxPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHPerSec", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "contract BEP20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHTotalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "arx", + "outputs": [ + { + "internalType": "contract ArxToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arxPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "arxTotalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTeamRewardBlockTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingArx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingWETH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accArxPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accWETHPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsStarted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_arxAllocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_WETHAllocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + } + ], + "name": "setStartTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamRewardPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamTimeInbetweenRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "teamTotalReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllowedTeamReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_arxPerSec", + "type": "uint256" + } + ], + "name": "updateArxPerSec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "multiplierNumber", + "type": "uint256" + } + ], + "name": "updateMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_WETHPerSec", + "type": "uint256" + } + ], + "name": "updateWETHPerSec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "arxRewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "WETHRewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]; diff --git a/src/adaptors/arbor-finance/index.js b/src/adaptors/arbor-finance/index.js new file mode 100644 index 0000000000..c6a4daade0 --- /dev/null +++ b/src/adaptors/arbor-finance/index.js @@ -0,0 +1,83 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); +const dayjs = require('dayjs'); + +const graphQuery = () => gql` + { + bonds(where: { state: active }) { + id + createdAt + collateralTokenAmount + collateralToken { + id + decimals + } + clearingPrice + paymentToken { + id + symbol + } + maturityDate + symbol + auctions { + id + minimumBondPrice + } + } + } +`; + +const graphUrl = sdk.graph.modifyEndpoint('9MKTb9g59rBG1CNUTrriA6tDdSR8neruGJCP6FjD7SSo'); + +const defiUrl = 'https://coins.llama.fi/prices/current/'; + +const poolsFunction = async () => { + const { bonds } = await request(graphUrl, graphQuery(), {}); + + const bondPools = bonds.map(async (bond) => { + const coinUrl = `ethereum:${bond.collateralToken.id}`; + const fullUrl = defiUrl + coinUrl; + const { coins } = await utils.getData(fullUrl); + const tokenPrice = await coins[coinUrl].price; + const tokenAmount = + bond.collateralTokenAmount / 10 ** bond.collateralToken.decimals; + + const tvl = tokenPrice * tokenAmount; + + const date = dayjs.unix(bond.maturityDate); + const issuanceDate = dayjs.unix(bond.createdAt); + const yearsUntilMaturity = date.diff(issuanceDate, 'year', true); + + const price = () => { + if (!bond.clearingPrice) { + return (bondPrice = bond.auctions[0]?.minimumBondPrice); + } else { + return (bondPrice = bond.clearingPrice); + } + }; + + price(); + + return { + pool: `${bond.id}-ethereum`.toLowerCase(), + chain: utils.formatChain('ethereum'), + project: 'arbor-finance', + symbol: utils.formatSymbol(bond.paymentToken.symbol), + tvlUsd: tvl, + apy: ((1 / bondPrice) ** (1 / yearsUntilMaturity) - 1) * 100, + poolMeta: bond.symbol, + underlyingTokens: [bond.collateralToken.id], + }; + }); + + return (await Promise.all(bondPools)).filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.arbor.finance/offerings', +}; + +//npm run test --adapter=arbor-finance diff --git a/src/adaptors/arcadia-v2/abi.js b/src/adaptors/arcadia-v2/abi.js new file mode 100644 index 0000000000..80bb7de52a --- /dev/null +++ b/src/adaptors/arcadia-v2/abi.js @@ -0,0 +1,1243 @@ +module.exports = { + poolABI: [ + { + inputs: [ + { internalType: 'address', name: 'riskManager_', type: 'address' }, + { internalType: 'contract ERC20', name: 'asset_', type: 'address' }, + { internalType: 'address', name: 'treasury_', type: 'address' }, + { internalType: 'address', name: 'accountFactory', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AmountExceedsBalance', type: 'error' }, + { inputs: [], name: 'AuctionOngoing', type: 'error' }, + { inputs: [], name: 'CoolDownPeriodNotPassed', type: 'error' }, + { inputs: [], name: 'FunctionIsPaused', type: 'error' }, + { inputs: [], name: 'FunctionNotImplemented', type: 'error' }, + { inputs: [], name: 'InvalidVersion', type: 'error' }, + { inputs: [], name: 'IsNotAnAccount', type: 'error' }, + { inputs: [], name: 'IsNotAnAccountWithDebt', type: 'error' }, + { inputs: [], name: 'LiquidationWeightsTooHigh', type: 'error' }, + { inputs: [], name: 'NonExistingTranche', type: 'error' }, + { inputs: [], name: 'OnlyGuardian', type: 'error' }, + { inputs: [], name: 'OpenPositionNonZero', type: 'error' }, + { inputs: [], name: 'TrancheAlreadyExists', type: 'error' }, + { inputs: [], name: 'Unauthorized', type: 'error' }, + { inputs: [], name: 'Unauthorized', type: 'error' }, + { inputs: [], name: 'ZeroAmount', type: 'error' }, + { inputs: [], name: 'ZeroShares', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'creditor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'startDebt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'initiationReward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'terminationReward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'penalty', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'badDebt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'surplus', + type: 'uint256', + }, + ], + name: 'AuctionFinished', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'creditor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint128', + name: 'openDebt', + type: 'uint128', + }, + ], + name: 'AuctionStarted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'by', type: 'address' }, + { + indexed: false, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'fee', + type: 'uint256', + }, + { + indexed: true, + internalType: 'bytes3', + name: 'referrer', + type: 'bytes3', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'beneficiary', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CreditApproval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newGuardian', + type: 'address', + }, + ], + name: 'GuardianChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'interest', + type: 'uint256', + }, + ], + name: 'InterestSynced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'tranche', + type: 'address', + }, + { + indexed: true, + internalType: 'uint8', + name: 'trancheIndex', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint16', + name: 'interestWeight', + type: 'uint16', + }, + ], + name: 'InterestWeightTrancheUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'liquidationWeight', + type: 'uint16', + }, + ], + name: 'LiquidationWeightTrancheUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'repayPauseFlagsUpdated', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'withdrawPauseFlagsUpdated', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'borrowPauseFlagsUpdated', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'depositPauseFlagsUpdated', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'liquidationPauseFlagsUpdated', + type: 'bool', + }, + ], + name: 'PauseFlagsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'totalDebt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalLiquidity', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint80', + name: 'interestRate', + type: 'uint80', + }, + ], + name: 'PoolStateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'riskManager', + type: 'address', + }, + ], + name: 'RiskManagerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'tranche', + type: 'address', + }, + ], + name: 'TranchePopped', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'interestWeight', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'liquidationWeight', + type: 'uint16', + }, + ], + name: 'TreasuryWeightsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'accountVersion', + type: 'uint256', + }, + { indexed: false, internalType: 'bool', name: 'valid', type: 'bool' }, + ], + name: 'ValidAccountVersionsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tranche', type: 'address' }, + { internalType: 'uint16', name: 'interestWeight_', type: 'uint16' }, + ], + name: 'addTranche', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'beneficiary', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'approveBeneficiary', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'contract ERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'startDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'minimumMargin_', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'bidder', type: 'address' }, + ], + name: 'auctionRepay', + outputs: [{ internalType: 'bool', name: 'earlyTerminate', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes3', name: 'referrer', type: 'bytes3' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'borrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'calcUnrealisedDebt', + outputs: [ + { internalType: 'uint256', name: 'unrealisedDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'guardian_', type: 'address' }], + name: 'changeGuardian', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'closeMarginAccount', + outputs: [], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'creditAllowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'from', type: 'address' }, + ], + name: 'depositInLendingPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'trancheIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + ], + name: 'donateToTranche', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amountBorrowed', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'actionTarget', type: 'address' }, + { internalType: 'bytes', name: 'actionData', type: 'bytes' }, + { internalType: 'bytes3', name: 'referrer', type: 'bytes3' }, + ], + name: 'flashAction', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'callbackData', type: 'bytes' }], + name: 'flashActionCallback', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getInterestRateConfig', + outputs: [ + { internalType: 'uint72', name: '', type: 'uint72' }, + { internalType: 'uint72', name: '', type: 'uint72' }, + { internalType: 'uint72', name: '', type: 'uint72' }, + { internalType: 'uint16', name: '', type: 'uint16' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getLiquidationParameters', + outputs: [ + { internalType: 'uint16', name: '', type: 'uint16' }, + { internalType: 'uint16', name: '', type: 'uint16' }, + { internalType: 'uint16', name: '', type: 'uint16' }, + { internalType: 'uint16', name: '', type: 'uint16' }, + { internalType: 'uint80', name: '', type: 'uint80' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getOpenPosition', + outputs: [ + { internalType: 'uint256', name: 'openPosition', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'guardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'interestRate', + outputs: [{ internalType: 'uint80', name: '', type: 'uint80' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'isValidVersion', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidationPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner_', type: 'address' }], + name: 'liquidityOf', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner_', type: 'address' }], + name: 'liquidityOfAndSync', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'accountVersion', type: 'uint256' }, + ], + name: 'openMarginAccount', + outputs: [ + { internalType: 'bool', name: 'success', type: 'bool' }, + { internalType: 'address', name: 'numeraire', type: 'address' }, + { internalType: 'address', name: 'liquidator_', type: 'address' }, + { internalType: 'uint256', name: 'minimumMargin_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'originationFee', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseTimestamp', + outputs: [{ internalType: 'uint96', name: '', type: 'uint96' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'repay', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'repayPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'riskManager', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'accountVersion', type: 'uint256' }, + { internalType: 'bool', name: 'valid', type: 'bool' }, + ], + name: 'setAccountVersion', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint72', name: 'baseRatePerYear_', type: 'uint72' }, + { internalType: 'uint72', name: 'lowSlopePerYear_', type: 'uint72' }, + { internalType: 'uint72', name: 'highSlopePerYear_', type: 'uint72' }, + { + internalType: 'uint16', + name: 'utilisationThreshold_', + type: 'uint16', + }, + ], + name: 'setInterestParameters', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'index', type: 'uint256' }, + { internalType: 'uint16', name: 'interestWeight_', type: 'uint16' }, + ], + name: 'setInterestWeightTranche', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: 'initiationWeight_', type: 'uint16' }, + { internalType: 'uint16', name: 'penaltyWeight_', type: 'uint16' }, + { internalType: 'uint16', name: 'terminationWeight_', type: 'uint16' }, + { internalType: 'uint16', name: 'minRewardWeight_', type: 'uint16' }, + { internalType: 'uint80', name: 'maxReward_', type: 'uint80' }, + ], + name: 'setLiquidationParameters', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: 'liquidationWeight', type: 'uint16' }, + ], + name: 'setLiquidationWeightTranche', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint96', name: 'minimumMargin_', type: 'uint96' }, + ], + name: 'setMinimumMargin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'originationFee_', type: 'uint8' }, + ], + name: 'setOriginationFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'riskManager_', type: 'address' }, + ], + name: 'setRiskManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'treasury_', type: 'address' }], + name: 'setTreasury', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: 'interestWeight_', type: 'uint16' }, + { internalType: 'uint16', name: 'liquidationWeight', type: 'uint16' }, + ], + name: 'setTreasuryWeights', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'startDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'minimumMargin_', type: 'uint256' }, + { internalType: 'address', name: 'terminator', type: 'address' }, + ], + name: 'settleLiquidationHappyFlow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'startDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'minimumMargin_', type: 'uint256' }, + { internalType: 'address', name: 'terminator', type: 'address' }, + ], + name: 'settleLiquidationUnhappyFlow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'initiator', type: 'address' }, + { internalType: 'uint256', name: 'minimumMargin_', type: 'uint256' }, + ], + name: 'startLiquidation', + outputs: [ + { internalType: 'uint256', name: 'startDebt', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { internalType: 'uint256', name: 'totalDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLiquidity', + outputs: [ + { internalType: 'uint256', name: 'totalLiquidity_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bool', name: 'repayPaused_', type: 'bool' }, + { internalType: 'bool', name: 'withdrawPaused_', type: 'bool' }, + { internalType: 'bool', name: 'borrowPaused_', type: 'bool' }, + { internalType: 'bool', name: 'depositPaused_', type: 'bool' }, + { internalType: 'bool', name: 'liquidationPaused_', type: 'bool' }, + ], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'updateInterestRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'withdrawFromLendingPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/arcadia-v2/index.js b/src/adaptors/arcadia-v2/index.js new file mode 100644 index 0000000000..e8fe2338bc --- /dev/null +++ b/src/adaptors/arcadia-v2/index.js @@ -0,0 +1,202 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { poolABI } = require('./abi'); + +const assets = { + USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + wETH: '0x4200000000000000000000000000000000000006', + DAI: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb', + cbETH: '0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22', + USDbC: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', + wstETH: '0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452', + cbBTC: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', +}; + +const pools = { + USDC: '0x3ec4a293Fb906DD2Cd440c20dECB250DeF141dF1', + wETH: '0x803ea69c7e87D1d6C86adeB40CB636cC0E6B98E2', + cbBTC: '0xa37E9b4369dc20940009030BfbC2088F09645e3B', +}; + +const getCollfactors = async () => { + const erc20AssetModule = '0xfBecEaFC96ed6fc800753d3eE6782b6F9a60Eed7'; + + const callsWeth = Object.values(assets).map((assetAddress) => ({ + target: erc20AssetModule, + params: [pools.wETH, assetAddress, 0], //[creditor, asset, assetId=0 for erc20] + })); + + const callsUsdc = Object.values(assets).map((assetAddress) => ({ + target: erc20AssetModule, + params: [pools.USDC, assetAddress, 0], //[creditor, asset, assetId=0 for erc20] + })); + + const callsCbbtc = Object.values(assets).map((assetAddress) => ({ + target: erc20AssetModule, + params: [pools.cbBTC, assetAddress, 0], //[creditor, asset, assetId=0 for erc20] + })); + + const collFactorsWeth = await sdk.api.abi.multiCall({ + abi: 'function getRiskFactors(address creditor, address asset, uint256 assetId) external view returns (uint16 collateralFactor, uint16 liquidationFactor)', + calls: callsWeth, + chain: 'base', + }); + const collFactorsUsdc = await sdk.api.abi.multiCall({ + abi: 'function getRiskFactors(address creditor, address asset, uint256 assetId) external view returns (uint16 collateralFactor, uint16 liquidationFactor)', + calls: callsUsdc, + chain: 'base', + }); + const collFactorCbbtc = await sdk.api.abi.multiCall({ + abi: 'function getRiskFactors(address creditor, address asset, uint256 assetId) external view returns (uint16 collateralFactor, uint16 liquidationFactor)', + calls: callsCbbtc, + chain: 'base', + }); + + const extractCollateralFactor = (factors) => + factors.map((factor) => parseInt(factor.output.collateralFactor)); + + const wethFactors = extractCollateralFactor(collFactorsWeth.output); + const usdcFactors = extractCollateralFactor(collFactorsUsdc.output); + const cbbtcFactors = extractCollateralFactor(collFactorCbbtc.output); + + const maxWethFactor = Math.max(...wethFactors); + const maxUsdcFactor = Math.max(...usdcFactors); + const maxCbbtcFactor = Math.max(...cbbtcFactors); + + return { maxWethFactor, maxUsdcFactor, maxCbbtcFactor }; +}; + +const getApy = async () => { + const coinPrices = await utils.getData( + 'https://coins.llama.fi/prices/current/base:0x4200000000000000000000000000000000000006,base:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913,base:0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf' + ); + + const wethPrice = + coinPrices['coins']['base:0x4200000000000000000000000000000000000006'] + .price; + const usdcPrice = + coinPrices['coins']['base:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'] + .price; + const cbbtcPrice = + coinPrices['coins']['base:0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf'] + .price + + const totalDebtWeth = await sdk.api.abi.call({ + target: pools.wETH, + abi: poolABI.filter(({ name }) => name === 'totalAssets')[0], + chain: 'base', + }); + const totalLiquidityWeth = await sdk.api.abi.call({ + target: pools.wETH, + abi: poolABI.filter(({ name }) => name === 'totalLiquidity')[0], + chain: 'base', + }); + const interestRateWeth = await sdk.api.abi.call({ + target: pools.wETH, + abi: poolABI.filter(({ name }) => name === 'interestRate')[0], + chain: 'base', + }); + const apyWeth = (totalDebtWeth.output * interestRateWeth.output) / totalLiquidityWeth.output / 1e18; + const tvlUsdWeth = ((totalLiquidityWeth.output - totalDebtWeth.output) * wethPrice) / 1e18; + const totalSupplyUsdWeth = (totalLiquidityWeth.output * wethPrice) / 1e18; + const totalBorrowUsdWeth = (totalDebtWeth.output * wethPrice) / 1e18; + const borrowApyWeth = (interestRateWeth.output * 100) / 1e18; //interestRateWeth is in 18 decimals, times 100 for pct + + const totalDebtUsdc = await sdk.api.abi.call({ + target: pools.USDC, + abi: poolABI.filter(({ name }) => name === 'totalAssets')[0], + chain: 'base', + }); + const totalLiquidityUsdc = await sdk.api.abi.call({ + target: pools.USDC, + abi: poolABI.filter(({ name }) => name === 'totalLiquidity')[0], + chain: 'base', + }); + const interestRateUsdc = await sdk.api.abi.call({ + target: pools.USDC, + abi: poolABI.filter(({ name }) => name === 'interestRate')[0], + chain: 'base', + }); + const apyUsdc = (totalDebtUsdc.output * interestRateUsdc.output) / totalLiquidityUsdc.output / 1e18; + const tvlUsdUsdc = ((totalLiquidityUsdc.output - totalDebtUsdc.output) * usdcPrice) / 1e6; + const totalSupplyUsdUsdc = (totalLiquidityUsdc.output * usdcPrice) / 1e6; + const totalBorrowUsdUsdc = (totalDebtUsdc.output * usdcPrice) / 1e6; + const borrowApyUsdc = (interestRateUsdc.output * 100) / 1e18; //interestRateUsdc is in 18 decimals, times 100 for pct + + const totalDebtCbbtc = await sdk.api.abi.call({ + target: pools.cbBTC, + abi: poolABI.filter(({ name }) => name === 'totalAssets')[0], + chain: 'base', + }); + const totalLiquidityCbbtc = await sdk.api.abi.call({ + target: pools.cbBTC, + abi: poolABI.filter(({ name }) => name === 'totalLiquidity')[0], + chain: 'base', + }); + const interestRateCbbtc = await sdk.api.abi.call({ + target: pools.cbBTC, + abi: poolABI.filter(({ name }) => name === 'interestRate')[0], + chain: 'base', + }); + const apyCbbtc = (totalDebtCbbtc.output * interestRateCbbtc.output) / totalLiquidityCbbtc.output / 1e18; + const tvlUsdCbbtc = ((totalLiquidityCbbtc.output - totalDebtCbbtc.output) * cbbtcPrice) / 1e8; + const totalSupplyUsdCbbtc = (totalLiquidityCbbtc.output * cbbtcPrice) / 1e8; + const totalBorrowUsdCbbtc = (totalDebtCbbtc.output * cbbtcPrice) / 1e8; + const borrowApyCbbtc = (interestRateCbbtc.output * 100) / 1e18; //interestRateCbbtc is in 18 decimals, times 100 for pct + + const maxCollFactors = await getCollfactors(); + + return [ + { + pool: pools.wETH, + chain: utils.formatChain('base'), + project: 'arcadia-v2', + symbol: 'wETH', + tvlUsd: tvlUsdWeth, + apyBase: apyWeth * 100, + totalSupplyUsd: totalSupplyUsdWeth, + totalBorrowUsd: totalBorrowUsdWeth, + apyBaseBorrow: borrowApyWeth, + ltv: maxCollFactors.maxWethFactor / 10_000, // 4 decimal precision + poolMeta: 'Arcadia V2 WETH Pool', + underlyingTokens: ['0x4200000000000000000000000000000000000006'], // WETH + url: 'https://arcadia.finance/pool/8453/0x803ea69c7e87D1d6C86adeB40CB636cC0E6B98E2', + }, + { + pool: pools.USDC, + chain: utils.formatChain('base'), + project: 'arcadia-v2', + symbol: 'USDC', + tvlUsd: tvlUsdUsdc, + apyBase: apyUsdc * 100, + totalSupplyUsd: totalSupplyUsdUsdc, + totalBorrowUsd: totalBorrowUsdUsdc, + apyBaseBorrow: borrowApyUsdc, + ltv: maxCollFactors.maxUsdcFactor / 10_000, // 4 decimal precision + poolMeta: 'Arcadia V2 USDC Pool', + underlyingTokens: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'], // USDC + url: 'https://arcadia.finance/pool/8453/0x3ec4a293Fb906DD2Cd440c20dECB250DeF141dF1', + }, + { + pool: pools.cbBTC, + chain: utils.formatChain('base'), + project: 'arcadia-v2', + symbol: 'cbBTC', + tvlUsd: tvlUsdCbbtc, + apyBase: apyCbbtc * 100, + totalSupplyUsd: totalSupplyUsdCbbtc, + totalBorrowUsd: totalBorrowUsdCbbtc, + apyBaseBorrow: borrowApyCbbtc, + ltv: maxCollFactors.maxCbbtcFactor / 10_000, // 4 decimal precision + poolMeta: 'Arcadia V2 cbBTC Pool', + underlyingTokens: ['0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf'], // cbBTC + url: 'https://arcadia.finance/pool/8453/0xa37E9b4369dc20940009030BfbC2088F09645e3B', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://arcadia.finance/earn', +}; diff --git a/src/adaptors/archimedes-finance/index.js b/src/adaptors/archimedes-finance/index.js new file mode 100644 index 0000000000..45cce2bdf6 --- /dev/null +++ b/src/adaptors/archimedes-finance/index.js @@ -0,0 +1,88 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +// Curve +const POOL_CONTRACT_LVUSD_3CRV = '0xe9123cbc5d1ea65301d417193c40a72ac8d53501'; +const POOL_INDEX_LVUSD = 0; +const POOL_INDEX_3CRV = 1; +// Coingecko +// const COINGECKO_ID_LVUSD = "lvusd"; // Not yet supported by Coingecko +const COINGECKO_ID_3CRV = 'lp-3pool-curve'; +const COINGECKO_ID_ARCH = 'archimedes'; + +// Get USD value from token amount +const getUsdValue = async (tokenId, tokenAmount) => { + const priceKey = `coingecko:${tokenId}`; + const usdPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + return tokenAmount * usdPrice; +}; + +// Get token balance of token in curve pool +const getTokenLiquidity = async (tokenIndex) => { + const liquidity = ( + await sdk.api.abi.call({ + target: POOL_CONTRACT_LVUSD_3CRV, + abi: { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'balances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + chain: 'ethereum', + params: tokenIndex, + }) + ).output; + return liquidity / 1e18; +}; + +const getTvlUsd = async () => { + const poolLiquidityLVUSD = await getTokenLiquidity(POOL_INDEX_LVUSD); + // const poolLiquidityLVUSDInUSD = await getUsdValue(COINGECKO_ID_LVUSD, poolLiquidityLVUSD); // Update once Coingecko supports + const poolLiquidity3CRV = await getTokenLiquidity(POOL_INDEX_3CRV); + const poolLiquidity3CRVInUSD = await getUsdValue( + COINGECKO_ID_3CRV, + poolLiquidity3CRV + ); + return poolLiquidityLVUSD + poolLiquidity3CRVInUSD; +}; + +const getApy = async (tvl) => { + const weeklyArchEmissions = ( + await axios.get( + 'https://o18rvfj4v9.execute-api.us-east-2.amazonaws.com/default/get-weekly-arch-emissions' + ) + ).data; + const weeklyArchEmissionsInUSD = await getUsdValue( + COINGECKO_ID_ARCH, + weeklyArchEmissions + ); + const weeklyYieldUSD = weeklyArchEmissionsInUSD / tvl; + const dailyYieldUSD = weeklyYieldUSD / 7; + const yearlyYieldUSD = dailyYieldUSD * 365; + return yearlyYieldUSD * 100; +}; + +const main = async () => { + const tvl = await getTvlUsd(); + + const pool = { + pool: POOL_CONTRACT_LVUSD_3CRV, + chain: utils.formatChain('Ethereum'), + project: 'archimedes-finance', + symbol: utils.formatSymbol('LvUSD'), + tvlUsd: tvl, + apy: await getApy(tvl), + }; + + return [pool]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://curve.finance/#/ethereum/pools/factory-v2-268/deposit', +}; diff --git a/src/adaptors/archly-v1/apy.ts b/src/adaptors/archly-v1/apy.ts new file mode 100644 index 0000000000..1e3544468d --- /dev/null +++ b/src/adaptors/archly-v1/apy.ts @@ -0,0 +1,131 @@ +const sdk = require('@defillama/sdk'); +const BN = require('bignumber.js'); +const utils = require('../utils'); + +const { getArcPrice, getPairs } = require('./subgraph'); +const GAUGE_ABI = require('./gauge_abi.json'); + +const STABLE_FEE_PERCENTAGE = 0.005; +const VARIABLE_FEE_PERCENTAGE = 0.005; + +const CHAIN = 'telos'; + +const ARC_ADDRESS = '0xa84df7afbcbcc1106834a5fed9453bd1219b1fb5'; + +const getApy = async () => { + try { + const [arcPrice, pairs] = await Promise.all([getArcPrice(), getPairs()]); + let gaugePairs = []; + let nonGaugePairs = []; + const multicalls = []; + + _uniquePairs(pairs).forEach((pair) => { + if (pair.gaugeAddress) { + gaugePairs.push(pair); + + // construct rewardRate multicall + multicalls.push({ params: ARC_ADDRESS, target: pair.gaugeAddress }); + } else { + nonGaugePairs.push(pair); + } + }); + + const gaugesRewardRates = ( + await sdk.api.abi.multiCall({ + calls: multicalls, + + abi: GAUGE_ABI.find(({ name }) => name === 'rewardRate'), + chain: CHAIN, + }) + ).output.map(({ output }) => output); + + // gauge pairs apr/apy + gaugePairs = gaugePairs.map((pair, index) => { + const rewardRate = gaugesRewardRates[index]?.toString(); + const aprReward = _calculateGaugeAPR( + pair.reserveUSD, + rewardRate, + arcPrice + ); + const aprFee = _calculateSwapFeeAPR( + pair.volumeUSD, + pair.reserveUSD, + pair.stable + ); + + pair.apyBase = Number(aprFee); + pair.apyReward = Number(aprReward); + return pair; + }); + // none-gauge pairs apr/apy + nonGaugePairs = nonGaugePairs.map((pair) => { + const aprFee = _calculateSwapFeeAPR( + pair.volumeUSD, + pair.reserveUSD, + pair.stable + ); + + pair.apyBase = Number(aprFee); + pair.apyReward = Number(0); + return pair; + }); + + return [...gaugePairs, ...nonGaugePairs] + .sort((a, b) => Number(b.reserveUSD) - Number(a.reserveUSD)) + .map(({ address, token0, token1, reserveUSD, apyReward }) => ({ + pool: address, + chain: utils.formatChain('telos'), + project: 'archly-v1', + symbol: `${token0.symbol}-${token1.symbol}`.toUpperCase(), + tvlUsd: Number(reserveUSD), + apyReward: apyReward, + underlyingTokens: [token0.address, token1.address], + rewardTokens: [ARC_ADDRESS], + url: `https://archly.fi/liquidity/${address}`, + })) + .filter((i) => utils.keepFinite(i)); + } catch (error) { + console.error('error@getApy', error); + return []; + } +}; + +const _uniquePairs = (pairs) => { + const existingPairs = new Set(); + return pairs + .sort((a, b) => Number(b.reserveUSD) - Number(a.reserveUSD)) // keep the highest tvl pairs + .filter((pair) => { + const symbol = `${pair.token0.symbol}_${pair.token1.symbol}`; + if (!existingPairs.has(symbol)) { + existingPairs.add(symbol); + return true; + } + return false; + }); +}; + +const _calculateSwapFeeAPR = (volumeUSD, reserveUSD, stable) => { + const feeShare = new BN(volumeUSD) + .times(stable ? STABLE_FEE_PERCENTAGE : VARIABLE_FEE_PERCENTAGE) + .div(100); + const projectedYearlyFees = feeShare.times(365); + const feeAPR = projectedYearlyFees.div(reserveUSD).times(100).toFixed(); + + return feeAPR; +}; + +const _calculateGaugeAPR = (reserveUSD, rewardRate, arcPrice) => { + const gaugeAPR = new BN(rewardRate) + .div(1e18) + .times(3600 * 24 * 365) + .times(arcPrice) + .div(reserveUSD) + .times(100) + .toFixed(18); + + return gaugeAPR; +}; + +module.exports = { + getApy, +}; diff --git a/src/adaptors/archly-v1/gauge_abi.json b/src/adaptors/archly-v1/gauge_abi.json new file mode 100644 index 0000000000..540249de9b --- /dev/null +++ b/src/adaptors/archly-v1/gauge_abi.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/archly-v1/index.ts b/src/adaptors/archly-v1/index.ts new file mode 100644 index 0000000000..d044e6672b --- /dev/null +++ b/src/adaptors/archly-v1/index.ts @@ -0,0 +1,7 @@ +const { getApy } = require('./apy'); + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://archly.fi/liquidity', +}; diff --git a/src/adaptors/archly-v1/subgraph.ts b/src/adaptors/archly-v1/subgraph.ts new file mode 100644 index 0000000000..5158d3acf2 --- /dev/null +++ b/src/adaptors/archly-v1/subgraph.ts @@ -0,0 +1,74 @@ +const { request, gql } = require('graphql-request'); +const BN = require('bignumber.js'); + +const ARC_USDC_PAIR_ADDRESS = '0xeab0f20cb5536f07135f9d32c93fc77911317ab6'; +const ARC_USDT_PAIR_ADDRESS = '0x309c5c0285d8051f7d4921b108526c173ef43507'; +const AMM_SUBGRAPH_URL = 'https://api.archly.fi/subgraphs/name/archly/amm'; + +const pairsQuery = gql` + query PairsQuery { + pairs: pairs( + first: 1000 + orderBy: reserveUSD + orderDirection: desc + where: { reserve0_gt: 0.01, reserve1_gt: 0.01, reserveUSD_gt: 100 } + ) { + address: id + token0 { + address: id + symbol + } + token1 { + address: id + symbol + } + isStable + reserveUSD + volumeUSD + gaugeAddress + } + } +`; + +const pairQuery = gql` + query pairQuery($id: String!) { + pair: pair(id: $id) { + token0Price + token1Price + } + } +`; + +const getPairs = async () => { + const { pairs } = await request(AMM_SUBGRAPH_URL, pairsQuery, {}); + return pairs; +}; + + +const getArcUsdcPrice = async () => { + const { pair } = await request(AMM_SUBGRAPH_URL, pairQuery, { + id: ARC_USDC_PAIR_ADDRESS.toLowerCase(), + }); + + return pair != null ? pair.token0Price : 0 +} + +const getArcUsdtPrice = async () => { + const { pair } = await request(AMM_SUBGRAPH_URL, pairQuery, { + id: ARC_USDT_PAIR_ADDRESS.toLowerCase(), + }); + + return pair != null ? pair.token1Price : 0 +} + +const getArcPrice = async () => { + let usdcPrice = await getArcUsdcPrice() + let usdtPrice = await getArcUsdtPrice() + + return new BN(usdcPrice).plus(usdtPrice).div(2); +}; + +module.exports = { + getPairs, + getArcPrice, +}; diff --git a/src/adaptors/aries-markets/index.js b/src/adaptors/aries-markets/index.js new file mode 100644 index 0000000000..0b6e9f66b2 --- /dev/null +++ b/src/adaptors/aries-markets/index.js @@ -0,0 +1,92 @@ +const utils = require('../utils'); + +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; + +const FARMING_TYPE = "0x9770fa9c725cbd97eb50b2be5f7416efdfd1f1554beb0750d4dae4c64e860da3::reserve_config::DepositFarming"; +const APT_ADDR = "0x1::aptos_coin::AptosCoin"; +const APT_PRICE_ID = 'coingecko:aptos'; + +const SUPPORTED_COINS = [ + ["usdc", "coingecko:usd-coin", 6, "0x5e156f1207d0ebfa19a9eeff00d62a282278fb8719f4fab3a586a0a2c0fffbea::coin::T"], + ["zusdc", "coingecko:usd-coin", 6, "0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC"], + ["zusdt", "coingecko:tether", 6, "0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT"], + ["zweth", "coingecko:ethereum", 6, "0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WETH"], + ["stApt", "coingecko:amnis-staked-aptos-coin", 8, "0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a::stapt_token::StakedApt"], + ["cake", "coingecko:pancakeswap-token", 8, "0x159df6b7689437016108a019fd5bef736bac692b6d4a1f10c941f6fbb9a74ca6::oft::CakeOFT"], + ["apt", APT_PRICE_ID, 8, APT_ADDR], +] + +async function main() { + const aptRes = await utils.getData(`${COINS_LLAMA_PRICE_URL}${APT_PRICE_ID}`) + const aptPrice = aptRes['coins'][APT_PRICE_ID]['price'] + const {result: res } = await utils.getData(`https://api-v2.ariesmarkets.xyz/reserve.current`) + const reserveStats = res['data']['stats'] + const reserveStatsMap = new Map(reserveStats.map(({ key, value }) => [key, value])); + + return await Promise.all(SUPPORTED_COINS.map(async (coin) => await calculateRewardApy(coin, reserveStatsMap, aptPrice))); +} + +async function calculateRewardApy(coin, reserveStatsMap, aptPrice) { + const [coinSymbol, priceId, coinDecimal, coinAddr] = coin; + const reserveStat = reserveStatsMap.get(coinAddr); + const priceRes = await utils.getData(`${COINS_LLAMA_PRICE_URL}${priceId}`) + const coinPrice = priceRes['coins'][priceId]['price'] + + const [_1, _2, remainingReward, rewardPerDay] = await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, { + "type_arguments": [ + coinAddr, + FARMING_TYPE, + APT_ADDR + ], + "function": "0x9770fa9c725cbd97eb50b2be5f7416efdfd1f1554beb0750d4dae4c64e860da3::reserve::reserve_farm_coin", + "arguments": [] + }); + const [netTvl, tvlWithBorrow] = calcTvlUSD(reserveStat, coinDecimal, coinPrice); + const interestApy = calcInterestApy(reserveStat); + const res = { + pool: `aries-markets-${coinSymbol}`, + chain: utils.formatChain('aptos'), + project: 'aries-markets', + symbol: utils.formatSymbol(coinSymbol), + tvlUsd: netTvl, + apyBase: interestApy, + } + + if (remainingReward > 0) { + const rewardApy = calcAptRewardApy(rewardPerDay / 1e8, aptPrice, tvlWithBorrow); + res['apyReward'] = rewardApy; + res['rewardTokens'] = [APT_ADDR]; + } + + return res; +} + +function calcInterestApy(data) { + const interestRateConfig = data["interest_rate_config"]; + const totalLiquidity = data['total_borrowed'] + data['total_cash_available'] + data['reserve_amount']; + const utilizationPct = data['total_borrowed'] / totalLiquidity * 100 + let borrowApy = 0 + if (utilizationPct <= interestRateConfig['optimal_utilization']) { + borrowApy = interestRateConfig['min_borrow_rate'] + utilizationPct / interestRateConfig['optimal_utilization'] * (interestRateConfig['optimal_borrow_rate'] - interestRateConfig['min_borrow_rate'] ) + } else { + borrowApy = interestRateConfig['optimal_borrow_rate'] + (utilizationPct - interestRateConfig['optimal_utilization']) / interestRateConfig['optimal_utilization'] * (interestRateConfig['max_borrow_rate'] - interestRateConfig['optimal_borrow_rate'] ) + } + return borrowApy * utilizationPct * (100 - data['reserve_config']['reserve_ratio']) / 10000; +} + +function calcTvlUSD(data, decimals, price) { + const netTvl = (data['total_cash_available'] + data['reserve_amount']) * price / (10 ** decimals); + const tvlwithBorrow = data['total_borrowed'] * price / (10 ** decimals) + netTvl; + return [netTvl, tvlwithBorrow] +} + +function calcAptRewardApy(rewardPerDay, aptPrice, tvlWithBorrow) { + return rewardPerDay * 365 * aptPrice / tvlWithBorrow * 100 +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.ariesmarkets.xyz', +}; \ No newline at end of file diff --git a/src/adaptors/armor/index.ts b/src/adaptors/armor/index.ts new file mode 100644 index 0000000000..f77aaa03c6 --- /dev/null +++ b/src/adaptors/armor/index.ts @@ -0,0 +1,43 @@ +const utils = require('../utils'); + +const API_URL: string = 'https://armorfi.info/api/apy'; + +const ARMOR_TOKEN = '0x1337def16f9b486faed0293eb623dc8395dfe46a'; + +interface Pool { + contract_address: string; + asset_symbol: string; + quote_symbol: string; + protocol: string; + liquidity_usd: string; + apy: { yearly: string }; +} + +interface Response { + dailyapys: Array; +} + +const getApy = async () => { + const { dailyapys: poolsRes }: Response = await utils.getData(API_URL); + + const pools = poolsRes.map((pool) => { + return { + pool: pool.contract_address, + chain: utils.formatChain('ethereum'), + project: 'armor', + symbol: `${pool.asset_symbol}-${pool.quote_symbol}`, + poolMeta: pool.protocol, + tvlUsd: Number(pool.liquidity_usd), + apyReward: Number(pool.apy.yearly), + rewardTokens: [ARMOR_TOKEN], + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://armor.ease.org/rewards', +}; diff --git a/src/adaptors/arpa-staking/index.js b/src/adaptors/arpa-staking/index.js new file mode 100644 index 0000000000..f7a181a9a9 --- /dev/null +++ b/src/adaptors/arpa-staking/index.js @@ -0,0 +1,72 @@ +const sdk = require('@defillama/sdk'); +const ARPA = '0xBA50933C268F567BDC86E1aC131BE072C6B0b71a'; +const STAKING_CONTRACT = '0xee710f79aa85099e200be4d40cdf1bfb2b467a01'; +const { ethers } = require('ethers'); +const { getPrices } = require('../utils'); + +const calApy = (rewardRate, totalCommunityStakingAmount) => + (rewardRate / totalCommunityStakingAmount) * + 3600 * + 24 * + 365 * + (1 - 0.05) * + 100; + +const getApyReward = async () => { + const [amount, rate] = await Promise.all([ + sdk.api.abi.call({ + chain: 'ethereum', + target: STAKING_CONTRACT, + abi: 'uint256:getTotalCommunityStakedAmount', + }), + sdk.api.abi.call({ + chain: 'ethereum', + target: STAKING_CONTRACT, + abi: 'uint256:getRewardRate', + }), + ]).then((values) => + values.some((ret) => !ret || !ret.output) + ? null + : values.map(({ output }) => ethers.utils.formatEther(output)) + ); + + let apy = 0; + + if (rate && amount) { + apy = calApy(rate, amount); + } + + const floored = Math.floor(apy * 10e1) / 10e1; + + return { apyReward: floored, stakedAmount: amount || 0 }; +}; + +const getApy = async () => { + const [{ pricesBySymbol }, { apyReward, stakedAmount }] = await Promise.all([ + getPrices([ARPA], 'ethereum'), + getApyReward(), + ]); + + const apyBase = 0; + const tvl = (pricesBySymbol['arpa'] || 0) * stakedAmount; + + return [ + { + pool: `${STAKING_CONTRACT}-ethereum`, + project: 'arpa-staking', + symbol: 'ARPA', + rewardTokens: [ARPA], + underlyingTokens: [ARPA], + tvlUsd: tvl, + apyBase, + apyReward, + chain: 'Ethereum', + url: 'https://staking.arpanetwork.io/en-US/stake?action=Stake', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/arrakis-v1/abi.js b/src/adaptors/arrakis-v1/abi.js new file mode 100644 index 0000000000..634aa86261 --- /dev/null +++ b/src/adaptors/arrakis-v1/abi.js @@ -0,0 +1,80 @@ +module.exports = { + arrakisABI: { + getDeployers: { + inputs: [], + name: 'getDeployers', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getPools: { + inputs: [ + { + internalType: 'address', + name: 'deployer', + type: 'address', + }, + ], + name: 'getPools', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + token0: { + inputs: [], + name: 'token0', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + token1: { + inputs: [], + name: 'token1', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getUnderlyingBalances: { + inputs: [], + name: 'getUnderlyingBalances', + outputs: [ + { + internalType: 'uint256', + name: 'amount0Current', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount1Current', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; diff --git a/src/adaptors/arrakis-v1/index.js b/src/adaptors/arrakis-v1/index.js new file mode 100644 index 0000000000..14209ed37f --- /dev/null +++ b/src/adaptors/arrakis-v1/index.js @@ -0,0 +1,138 @@ +const axios = require('axios'); + +const { gql, request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { arrakisABI } = require('./abi'); + +const CHAINS = { + ethereum: sdk.graph.modifyEndpoint( + '2jrpKNFuyHgD6rKf5UUMHkmn1LmkCZG4RsGW4DtqU2i' + ), + polygon: sdk.graph.modifyEndpoint( + '3mgJQXKpkggZUKbt8v5pDy9jvkvKV7EEYGi4rogNmLbZ' + ), + optimism: sdk.graph.modifyEndpoint( + 'H7KF8RUHTk5PrtQCZ5iFCqB5Xrp66gq1aJhXbJXkW9xB' + ), +}; + +const CHAIN_IDS = { + ethereum: 1, + optimism: 10, + polygon: 137, +}; + +const vaultsQuery = gql` + { + vaults { + id + apr { + averageApr + } + snapshots(orderBy: startTimestamp, orderDirection: desc, first: 1) { + apr + } + token0 { + symbol + address + decimals + } + token1 { + symbol + address + decimals + } + uniswapPool + } + } +`; + +const pairsToObj = (pairs) => + pairs.reduce((acc, [el1, el2]) => ({ ...acc, [el1]: el2 }), {}); + +const getApy = async () => { + const vaultData = pairsToObj( + await Promise.all( + Object.keys(CHAINS).map(async (chain) => [ + chain, + await request(CHAINS[chain], vaultsQuery), + ]) + ) + ); + + const underlyingBalances = pairsToObj( + await Promise.all( + Object.keys(CHAINS).map(async (chain) => + ( + await sdk.api.abi.multiCall({ + abi: arrakisABI.getUnderlyingBalances, + calls: vaultData[chain].vaults.map((v) => ({ + target: v.id, + })), + chain: chain, + }) + ).output.map(({ output, input }) => [input.target, output]) + ) + ).then((val) => val.flat()) + ); + const tokens = Object.entries(vaultData).reduce( + (acc, [chain, { vaults }]) => ({ + ...acc, + [chain]: [ + ...new Set( + vaults + .map((vault) => [vault.token0.address, vault.token1.address]) + .flat() + ), + ], + }), + {} + ); + + const keys = []; + for (const key of Object.keys(tokens)) { + keys.push(tokens[key].map((t) => `${key}:${t}`)); + } + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${keys + .flat() + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pools = Object.keys(CHAINS).map((chain) => { + const { vaults: chainVaults } = vaultData[chain]; + const chainAprs = chainVaults.map((vault) => { + const { amount0Current, amount1Current } = underlyingBalances[vault.id]; + const token0Supply = Number(amount0Current) / 10 ** vault.token0.decimals; + const token1Supply = Number(amount1Current) / 10 ** vault.token1.decimals; + const tvl = + token0Supply * prices[`${chain}:${vault.token0.address}`]?.price + + token1Supply * prices[`${chain}:${vault.token1.address}`]?.price; + + return { + pool: vault.id, + chain: utils.formatChain(chain), + project: 'arrakis-v1', + symbol: `${vault.token0.symbol}-${vault.token1.symbol}`, + tvlUsd: tvl || 0, + apyBase: vault.snapshots[0] + ? Number(vault.snapshots[0].apr) + : Number(vault.apr.averageApr), + url: `https://beta.arrakis.finance/vaults/${CHAIN_IDS[chain]}/${vault.id}`, + underlyingTokens: [vault.token0.address, vault.token1.address], + }; + }); + return chainAprs; + }); + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/ashswap/index.js b/src/adaptors/ashswap/index.js new file mode 100644 index 0000000000..fc223e0586 --- /dev/null +++ b/src/adaptors/ashswap/index.js @@ -0,0 +1,65 @@ +const { request } = require('graphql-request'); +const { removeDuplicates } = require('../utils'); + +const API_URL = 'https://api-v2.ashswap.io/graphql'; + +const YieldQuery = ` +{ + defillama { + pools { + address + tokens + tvlUsd + apyBase + apyReward + } + } +} +`; + +const getSymbol = (tokens) => { + let result = ''; + for (const token of tokens) { + if (token != null) { + result += token.split('-')[0] + '-'; + } + } + return result.slice(0, -1); +}; + +const getTokens = (tokens) => { + let result = []; + for (const token of tokens) { + if (token != null) { + result.push(token); + } + } + return result; +}; + +const apy = async () => { + const pools = []; + let results = await request(API_URL, YieldQuery); + + for (const pool of results.defillama.pools) { + pools.push({ + pool: pool.address, + project: 'ashswap', + chain: 'MultiversX', + symbol: getSymbol(pool.tokens), + tvlUsd: pool.tvlUsd, + apyBase: pool.apyBase, + apyReward: pool.apyReward, + rewardTokens: ['ASH-a642d1'], + underlyingTokens: getTokens(pool.tokens), + }); + } + + return removeDuplicates(pools); +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.ashswap.io/pool/', +}; diff --git a/src/adaptors/astroport/index.js b/src/adaptors/astroport/index.js new file mode 100644 index 0000000000..708d0c9d48 --- /dev/null +++ b/src/adaptors/astroport/index.js @@ -0,0 +1,76 @@ +const axios = require('axios'); +const num = require('bignumber.js'); + +const chainIdToNames = { + 'phoenix-1': 'Terra2', + 'injective-1': 'Injective', + 'neutron-1': 'Neutron', + 'pacific-1': 'Sei', +}; + +const astroDenoms = { + 'phoenix-1': + 'terra1nsuqsk6kh58ulczatwev87ttq2z6r3pusulg9r24mfj2fvtzd4uq3exn26', + 'injective-1': + 'ibc/EBD5A24C554198EBAF44979C5B4D2C2D312E6EBAB71962C92F735499C7575839', + 'neutron-1': + 'ibc/5751B8BCDA688FD0A8EC0B292EEF1CDEAB4B766B63EC632778B196D317C40C3A', + 'pacific-1': + 'ibc/0EC78B75D318EA0AAB6160A12AEE8F3C7FEA3CFEAD001A3B103E11914709F4CE', +}; + +const getRewardTokens = (pool) => { + const rewardTokens = []; + if (pool?.protocolRewards?.apr > 0) { + rewardTokens.push(pool?.rewardTokenSymbol); + } + if (pool?.astroRewards?.apr > 0) { + rewardTokens.push(astroDenoms[pool.chainId]); + } + return rewardTokens.length > 0 ? rewardTokens : undefined; +}; + +const apy = async () => { + let results = ( + await axios.get( + 'https://app.astroport.fi/api/trpc/pools.getAll?input=%7B%22json%22%3A%7B%22chainId%22%3A%22neutron-1%22%7D%7D' + ) + ).data.result.data.json; + + const apy = results + ?.filter((pool) => pool?.poolLiquidityUsd && pool?.poolLiquidityUsd > 10000) + .map((pool) => { + const apyBase = pool?.tradingFees?.apy + ? new num(pool?.tradingFees?.apy).times(100).dp(6).toNumber() + : 0; + const chain = chainIdToNames[pool.chainId]; + const astroRewards = pool?.astroRewards?.apr || 0; + const protocolRewards = pool?.protocolRewards?.apr || 0; + const apyReward = new num(astroRewards) + .plus(protocolRewards) + .times(100) + .dp(6) + .toNumber(); + + return { + pool: `${pool.poolAddress}-${chain}`.toLowerCase(), + project: 'astroport', + chain, + symbol: `${pool.assets[0].symbol}-${pool.assets[1].symbol}`, + tvlUsd: pool.poolLiquidityUsd || 0, + apyBase, + apyReward, + rewardTokens: getRewardTokens(pool) ?? null, + underlyingTokens: [pool.assets[0].address, pool.assets[1].address], + url: `https://app.astroport.fi/pools/${pool.poolAddress}/provide`, + }; + }); + + return apy; +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.astroport.fi/pools/', +}; diff --git a/src/adaptors/asymetrix-protocol/abi/ERC20.json b/src/adaptors/asymetrix-protocol/abi/ERC20.json new file mode 100644 index 0000000000..5e361ebffa --- /dev/null +++ b/src/adaptors/asymetrix-protocol/abi/ERC20.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/asymetrix-protocol/abi/StakePrizePool.json b/src/adaptors/asymetrix-protocol/abi/StakePrizePool.json new file mode 100644 index 0000000000..26c3e7d48d --- /dev/null +++ b/src/adaptors/asymetrix-protocol/abi/StakePrizePool.json @@ -0,0 +1,1636 @@ +[ + { + "inputs": [], + "name": "AwardNotAvailable", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidArrayLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidBalanceCap", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidExternalToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLidoAPR", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLiquidationAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLiquidationThreshold", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLiquidityCap", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSlippageTolerance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTimestamp", + "type": "error" + }, + { + "inputs": [], + "name": "NotContract", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughETH", + "type": "error" + }, + { + "inputs": [], + "name": "NothingToLiquidate", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPrizeFlush", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyTicket", + "type": "error" + }, + { + "inputs": [], + "name": "TicketAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "TooSmallLiquidationAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "asxRewardPerSecond", + "type": "uint256" + } + ], + "name": "AsxRewardPerSecondSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AwardCaptured", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ITicket", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Awarded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AwardedExternalERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + } + ], + "name": "AwardedExternalERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "balanceCap", + "type": "uint256" + } + ], + "name": "BalanceCapSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ITicket", + "name": "token", + "type": "address" + } + ], + "name": "ControlledTokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ITicket", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IDrawBeacon", + "name": "drawBeacond", + "type": "address" + } + ], + "name": "DrawBeaconSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "error", + "type": "bytes" + } + ], + "name": "ErrorAwardingExternalERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "esAsxRewardPerSecond", + "type": "uint256" + } + ], + "name": "EsAsxRewardPerSecondSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "firstLidoRebaseTimestamp", + "type": "uint32" + } + ], + "name": "FirstLidoRebaseTimestampSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "freeExitDuration", + "type": "uint32" + } + ], + "name": "FreeExitDurationSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "lidoAPR", + "type": "uint16" + } + ], + "name": "LidoAPRSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "liquidationThreshold", + "type": "uint16" + } + ], + "name": "LiquidationThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityCap", + "type": "uint256" + } + ], + "name": "LiquidityCapSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pendingOwner", + "type": "address" + } + ], + "name": "OwnershipOffered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "prizeFlush", + "type": "address" + } + ], + "name": "PrizeFlushSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken", + "type": "address" + } + ], + "name": "RewardTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "lastUpdated", + "type": "uint64" + } + ], + "name": "RewardUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ITicket", + "name": "ticket", + "type": "address" + } + ], + "name": "TicketSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredExternalERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ITicket", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_DISTRIBUTION_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DRAW_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_EPOCH_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TIMESTAMPS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKEN_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_HUNDRED_PERCENTS", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "asxOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "availableForLiquidationEsAsx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "award", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "awardBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "address", + "name": "_externalToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "awardExternalERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "address", + "name": "_externalToken", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_tokenIds", + "type": "uint256[]" + } + ], + "name": "awardExternalERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_externalToken", + "type": "address" + } + ], + "name": "canAwardExternal", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "captureAwardBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICompLike", + "name": "_compLike", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "compLikeDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_delegate", + "type": "address" + } + ], + "name": "depositToAndDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "esAsx", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "esAsxRewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "esAsxRewardPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "esAsxVesting", + "outputs": [ + { + "internalType": "contract IESASXVesting", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAccountedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAsxRewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAsxRewardPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalanceCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "_asxReward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_esAsxReward", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeploymentTimestamp", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDistributionEnd", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDrawBeacon", + "outputs": [ + { + "internalType": "contract IDrawBeacon", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFirstLidoRebaseTimestamp", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFreeExitDuration", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastUpdated", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLidoAPR", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLiquidityCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrizeFlush", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTicket", + "outputs": [ + { + "internalType": "contract ITicket", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getUserStakeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "former", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "lastClaimed", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "esAsxLastClaimed", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "esAsxBoostableReward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "esAsxBoostlessReward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "esAsxFormer", + "type": "uint256" + } + ], + "internalType": "struct IPrizePoolV2.UserStakeInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITicket", + "name": "_controlledToken", + "type": "address" + } + ], + "name": "isControlled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_users", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_amounts", + "type": "uint256[]" + } + ], + "name": "liquidate", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationThreshold", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsBooster", + "outputs": [ + { + "internalType": "contract IRewardsBooster", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newAsxOracle", + "type": "address" + } + ], + "name": "setAsxOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_asxRewardPerSecond", + "type": "uint256" + } + ], + "name": "setAsxRewardPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_balanceCap", + "type": "uint256" + } + ], + "name": "setBalanceCap", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_newDistributionEnd", + "type": "uint32" + } + ], + "name": "setDistributionEnd", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IDrawBeacon", + "name": "_drawBeacon", + "type": "address" + } + ], + "name": "setDrawBeacon", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_esAsxRewardPerSecond", + "type": "uint256" + } + ], + "name": "setEsAsxRewardPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_freeExitDuration", + "type": "uint32" + } + ], + "name": "setFreeExitDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_lidoAPR", + "type": "uint16" + } + ], + "name": "setLidoAPR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_liquidationThreshold", + "type": "uint16" + } + ], + "name": "setLiquidationThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidityCap", + "type": "uint256" + } + ], + "name": "setLiquidityCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_prizeFlush", + "type": "address" + } + ], + "name": "setPrizeFlush", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newRewardsBooster", + "type": "address" + } + ], + "name": "setRewardsBooster", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_newSlippageTolerance", + "type": "uint16" + } + ], + "name": "setSlippageTolerance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITicket", + "name": "_ticket", + "type": "address" + } + ], + "name": "setTicket", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newUniswapWrapper", + "type": "address" + } + ], + "name": "setUniswapWrapper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slippageTolerance", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "address", + "name": "_externalToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferExternalERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapWrapper", + "outputs": [ + { + "internalType": "contract UniswapWrapper", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_beforeBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_afterBalance", + "type": "uint256" + } + ], + "name": "updateUserRewardAndFormer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFrom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] diff --git a/src/adaptors/asymetrix-protocol/abi/Ticket.json b/src/adaptors/asymetrix-protocol/abi/Ticket.json new file mode 100644 index 0000000000..e2d1642824 --- /dev/null +++ b/src/adaptors/asymetrix-protocol/abi/Ticket.json @@ -0,0 +1,995 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + } + ], + "name": "Delegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "Deployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint224", + "name": "amount", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "timestamp", + "type": "uint32" + } + ], + "indexed": false, + "internalType": "struct ObservationLib.Observation", + "name": "newTotalSupplyTwab", + "type": "tuple" + } + ], + "name": "NewTotalSupplyTwab", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint224", + "name": "amount", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "timestamp", + "type": "uint32" + } + ], + "indexed": false, + "internalType": "struct ObservationLib.Observation", + "name": "newTwab", + "type": "tuple" + } + ], + "name": "NewUserTwab", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "TicketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DISTRIBUTION_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DRAW_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_EPOCH_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TIMESTAMPS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKEN_IDS_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "controllerBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "controllerBurnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "controllerDelegateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "controllerMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "delegateOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_newDelegate", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "_v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "_r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "delegateWithSignature", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getAccountDetails", + "outputs": [ + { + "components": [ + { + "internalType": "uint208", + "name": "balance", + "type": "uint208" + }, + { + "internalType": "uint24", + "name": "nextTwabIndex", + "type": "uint24" + }, + { + "internalType": "uint24", + "name": "cardinality", + "type": "uint24" + } + ], + "internalType": "struct TwabLib.AccountDetails", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_startTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "_endTime", + "type": "uint64" + } + ], + "name": "getAverageBalanceBetween", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint64[]", + "name": "_startTimes", + "type": "uint64[]" + }, + { + "internalType": "uint64[]", + "name": "_endTimes", + "type": "uint64[]" + } + ], + "name": "getAverageBalancesBetween", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64[]", + "name": "_startTimes", + "type": "uint64[]" + }, + { + "internalType": "uint64[]", + "name": "_endTimes", + "type": "uint64[]" + } + ], + "name": "getAverageTotalSuppliesBetween", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_target", + "type": "uint64" + } + ], + "name": "getBalanceAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint64[]", + "name": "_targets", + "type": "uint64[]" + } + ], + "name": "getBalancesAt", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64[]", + "name": "_targets", + "type": "uint64[]" + } + ], + "name": "getTotalSuppliesAt", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_target", + "type": "uint64" + } + ], + "name": "getTotalSupplyAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_index", + "type": "uint16" + } + ], + "name": "getTwab", + "outputs": [ + { + "components": [ + { + "internalType": "uint224", + "name": "amount", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "timestamp", + "type": "uint32" + } + ], + "internalType": "struct ObservationLib.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/asymetrix-protocol/abi/UniswapV3Factory.json b/src/adaptors/asymetrix-protocol/abi/UniswapV3Factory.json new file mode 100644 index 0000000000..efbd50a530 --- /dev/null +++ b/src/adaptors/asymetrix-protocol/abi/UniswapV3Factory.json @@ -0,0 +1,236 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "createPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "feeAmountTickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "parameters", + "outputs": [ + { + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/asymetrix-protocol/abi/UniswapV3Pool.json b/src/adaptors/asymetrix-protocol/abi/UniswapV3Pool.json new file mode 100644 index 0000000000..905e300b7e --- /dev/null +++ b/src/adaptors/asymetrix-protocol/abi/UniswapV3Pool.json @@ -0,0 +1,988 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/asymetrix-protocol/index.js b/src/adaptors/asymetrix-protocol/index.js new file mode 100644 index 0000000000..3297dc10e1 --- /dev/null +++ b/src/adaptors/asymetrix-protocol/index.js @@ -0,0 +1,154 @@ +const uniswapV3FactoryAbi = require('./abi/UniswapV3Factory.json'); +const stakePrizePoolAbi = require('./abi/StakePrizePool.json'); +const uniswapV3PoolAbi = require('./abi/UniswapV3Pool.json'); +const ticketAbi = require('./abi/Ticket.json'); +const erc20Abi = require('./abi/ERC20.json'); + +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); + +const { Web3 } = require('web3'); + +let uniswapV3FactoryContract; +let stakePrizePoolContract; +let ticketContract; +let wethContract; +let usdcContract; +let asxContract; + +let web3; + +const UNISWAP_V3_FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; +const STAKE_PRIZE_POOL_ADDRESS = '0x82D24dD5041A3Eb942ccA68B319F1fDa9EB0c604'; +const TICKET_ADDRESS = '0xd1c88b7Cc2F9B3A23d1CB537d53A818cef5E5E32'; +const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const USDC_ADDRESS = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; +const ASX_ADDRESS = '0x67d85A291fcDC862A78812a3C26d55e28FFB2701'; + +async function init() { + web3 = new Web3( + new Web3.providers.HttpProvider('https://ethereum.publicnode.com') + ); + + stakePrizePoolContract = new web3.eth.Contract( + stakePrizePoolAbi, + STAKE_PRIZE_POOL_ADDRESS + ); + wethContract = new web3.eth.Contract(erc20Abi, WETH_ADDRESS); + usdcContract = new web3.eth.Contract(erc20Abi, USDC_ADDRESS); + asxContract = new web3.eth.Contract(erc20Abi, ASX_ADDRESS); + ticketContract = new web3.eth.Contract(ticketAbi, TICKET_ADDRESS); + uniswapV3FactoryContract = new web3.eth.Contract( + uniswapV3FactoryAbi, + UNISWAP_V3_FACTORY_ADDRESS + ); +} + +async function getTokenPriceInWeth(tokenContract) { + const uniswapV3TokenWethPoolAddress = await uniswapV3FactoryContract.methods + .getPool(tokenContract.options.address, WETH_ADDRESS, 3000) + .call(); + const uniswapV3TokenWethPoolContract = new web3.eth.Contract( + uniswapV3PoolAbi, + uniswapV3TokenWethPoolAddress + ); + + const { tick } = await uniswapV3TokenWethPoolContract.methods.slot0().call(); + + const tokenDecimals = await tokenContract.methods.decimals().call(); + const wethDecimals = await wethContract.methods.decimals().call(); + + const oneTokenInWeth = + 1 / + ((1.0001 ** Number(tick) * 10 ** Number(wethDecimals)) / + 10 ** Number(tokenDecimals)); + + return oneTokenInWeth; +} + +async function getTokenPriceInUsdc(tokenContract) { + const uniswapV3TokenUsdcPoolAddress = await uniswapV3FactoryContract.methods + .getPool(tokenContract.options.address, USDC_ADDRESS, 3000) + .call(); + const uniswapV3TokenUsdcPoolContract = new web3.eth.Contract( + uniswapV3PoolAbi, + uniswapV3TokenUsdcPoolAddress + ); + + const { tick } = await uniswapV3TokenUsdcPoolContract.methods.slot0().call(); + + const tokenDecimals = await tokenContract.methods.decimals().call(); + const usdcDecimals = await usdcContract.methods.decimals().call(); + + const oneTokenInUsdc = + 1 / + ((1.0001 ** Number(tick) * 10 ** Number(usdcDecimals)) / + 10 ** Number(tokenDecimals)); + + return oneTokenInUsdc; +} + +async function getApy() { + // 1. Retrieve reward per year amount (in ASX tokens). + let rewardPerSecondInEsAsxTokens = await stakePrizePoolContract.methods + .esAsxRewardPerSecond() + .call(); + + const rewardPerYearInEsAsxTokens = + +new BigNumber(rewardPerSecondInEsAsxTokens.toString()) * + 60 * + 60 * + 24 * + 365; + + // 2. Calculate price of 1 ASX token in WETH. + const oneAsxInWeth = await getTokenPriceInWeth(asxContract); + + // 3. Calculate price of 1 WETH token in USDC. + const oneWethPriceUsdc = await getTokenPriceInUsdc(wethContract); + + // 4. Calculate price of 1 ASX token in USDC. + const oneAsxInUsdc = oneAsxInWeth * oneWethPriceUsdc; + + // 5. Calculate reward per year (in esASX tokens, in USDC). + const rewardPerYearInEsAsxTokensInUsdc = + rewardPerYearInEsAsxTokens * +new BigNumber(oneAsxInUsdc.toString()); + + // 6. Calculate APR. + const totalInProtocol = +new BigNumber( + (await ticketContract.methods.totalSupply().call()).toString() + ); + + const lockedEthPriceInUsdc = totalInProtocol * oneWethPriceUsdc; + const apy = (rewardPerYearInEsAsxTokensInUsdc / lockedEthPriceInUsdc) * 100; + + if (apy === Infinity) { + return 0; + } + + return apy; +} + +async function getApyData() { + await init(); + + const stakePrizePoolData = { + pool: stakePrizePoolContract.options.address, + chain: utils.formatChain('ethereum'), + project: 'asymetrix-protocol', + symbol: utils.formatSymbol('stETH'), + tvlUsd: await utils.getData('https://api.llama.fi/tvl/asymetrix-protocol'), + apyReward: await getApy(), + rewardTokens: [asxContract.options.address], // [ASX] + underlyingTokens: ['0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'], // [stETH] + url: 'https://app.asymetrix.io/', + }; + + return [stakePrizePoolData]; +} + +module.exports = { + timetravel: false, + apy: getApyData, +}; diff --git a/src/adaptors/asymmetry-usdaf/index.js b/src/adaptors/asymmetry-usdaf/index.js new file mode 100644 index 0000000000..a90f9d547a --- /dev/null +++ b/src/adaptors/asymmetry-usdaf/index.js @@ -0,0 +1,357 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const BOLD_TOKEN = '0x9cf12ccd6020b6888e4d4c4e4c7aca33c1eb91f8'; + +const YSYBOLD_BRANCH = { + activePool: '0xb87e1e1c4cc2decada13025a8dc8a94bdb77fb63', + defaultPool: '0x27f539ec3fa3e548e10d4ac883534eba891bb212', + stabilityPool: '0x83e5bde77d7477ecd972e338541b90af57675536', + borrowerOperations: '0x57bd20ae68f845b35b76fe6e0239c9929eb48469', + collToken: '0x23346b04a7f55b8760e5860aa5a77383d63491cd'.toLowerCase(), + symbol: 'YSYBOLD' +} + +const SCRVUSD_BRANCH = { + activePool: '0x244c422663328233a5d1bd5045ff943ba97d046e', + defaultPool: '0xc20a51f66c917feff80d1e089199f727060c0369', + stabilityPool: '0xd48dc7cddc481f596bd9a97755c7ac696ad4ea87', + borrowerOperations: '0x9e601005deaaee8294c686e28e1affd04cc13830', + collToken: '0x0655977feb2f289a4ab78af67bab0d17aab84367'.toLowerCase(), + symbol: 'SCRVUSD' +} + +const SUSDS_BRANCH = { + activePool: '0x08eaafd8fbb12cf12d6765e80c5b0ff8490c232d', + defaultPool: '0xfab7396e2a6a3364e02ed26d2f80a354aa923b88', + stabilityPool: '0xb571781cedf07257d60d6b252a3d8b24150ded97', + borrowerOperations: '0x336d9c5ecb9d6ce79c8c077d35426e714969b41d', + collToken: '0xa3931d71877c0e7a3148cb7eb4463524fec27fbd'.toLowerCase(), + symbol: 'SUSDS' +} + +const SFRXUSD_BRANCH = { + activePool: '0x20f29569566020d8e49c9843033c370772a93774', + defaultPool: '0xfe6f765e77fd8f17ec3a985ac36c3c3ea92c946d', + stabilityPool: '0x446f358e3a927cc68f342141d78aa2d1c54e18f0', + borrowerOperations: '0x2538cd346429ea59902e02448bb7a7c098e4554e', + collToken: '0xcf62f905562626cfcdd2261162a51fd02fc9c5b6'.toLowerCase(), + symbol: 'SFRXUSD' +} + +const TBTC_BRANCH = { + activePool: '0xb00d1d5dfd72a440b8c04a5f7b5bc3c8159a7f44', + defaultPool: '0x254a6a3e172a81d5825122403e1bc4d47f264a07', + stabilityPool: '0x545a7ddfd863bd7ea0bfc689125169598085f75e', + borrowerOperations: '0xda9af112edfd837eebc1780433481426a52556e0', + collToken: '0x18084fba666a33d37592fa2633fd49a74dd93a88'.toLowerCase(), + symbol: 'TBTC' +} + +const WBTC_BRANCH = { + activePool: '0xf507e264d507ef64a72aeaf4cc8c270d008fc48a', + defaultPool: '0x01e37634cbd25ec7ffe680ece5eec178ff51ef2d', + stabilityPool: '0x922faa141e95e43a9deeab8dade3ac8d4a32ad5c', + borrowerOperations: '0x664507f1445657d36d8064663653b7810971f411', + collToken: '0xe065bc161b90c9c4bba2de7f1e194b70a3267c47'.toLowerCase(), + symbol: 'WBTC' +} + +const branches = [YSYBOLD_BRANCH, SCRVUSD_BRANCH, SUSDS_BRANCH, SFRXUSD_BRANCH, TBTC_BRANCH, WBTC_BRANCH]; + +const SP_YIELD_SPLIT = 0.75; + +const ABIS = { + getTotalBoldDeposits: { + inputs: [], + name: 'getTotalBoldDeposits', + outputs: [ + { + internalType: 'uint256', + name: 'totalBoldDeposits', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getCollBalance: { + inputs: [], + name: 'getCollBalance', + outputs: [ + { + internalType: 'uint256', + name: 'collBalance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getBoldDebt: { + inputs: [], + name: 'getBoldDebt', + outputs: [ + { + internalType: 'uint256', + name: 'boldDebt', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [], + name: 'MCR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getNewApproxAvgInterestRateFromTroveChange: { + inputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'appliedRedistBoldDebtGain', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'appliedRedistCollGain', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collIncrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collDecrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtIncrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtDecrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'newWeightedRecordedDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oldWeightedRecordedDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'upfrontFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'batchAccruedManagementFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'newWeightedRecordedBatchManagementFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oldWeightedRecordedBatchManagementFee', + type: 'uint256', + }, + ], + internalType: 'struct TroveChange', + name: '_troveChange', + type: 'tuple', + }, + ], + name: 'getNewApproxAvgInterestRateFromTroveChange', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + } + }; + + const getSPSupplyAndApy = async (spAddr, avgBranchInterestRate, branchBoldSupply) => { + const spSupply = (await sdk.api.abi.call({ + target: spAddr, + abi: ABIS.getTotalBoldDeposits, + chain: 'ethereum', + })).output / 1e18; + + // Yield is the branch interest rate amplifyed by ratio of branch supply to the BOLD in the SP + const spApy = avgBranchInterestRate * SP_YIELD_SPLIT * branchBoldSupply / spSupply; + + return [spSupply, spApy]; + } + + const getPrices = async (addresses) => { + const req = addresses.map((address) => `ethereum:${address}`).join(',').toLowerCase(); + const prices = (await superagent.get(`https://coins.llama.fi/prices/current/${req}`)).body.coins; + + const pricesObj = Object.fromEntries( + Object.entries(prices).map(([address, priceData]) => [address.split(':')[1].toLowerCase(), priceData.price]) + ); + + return pricesObj; + } + + const getBranchColl = async (collPools) => { + const results = await sdk.api.abi.multiCall({ + calls: collPools.map((poolAddr) => ({ + target: poolAddr, + params: [], + })), + abi: ABIS.getCollBalance, + chain: 'ethereum', + }); + + const totalColl = results.output.map(x => Number(x.output)).reduce((a, b) => a + b); + return totalColl / 1e18; + } + + const getBranchDebt = async (debtPools) => { + const results = await sdk.api.abi.multiCall({ + calls: debtPools.map((poolAddr) => ({ + target: poolAddr, + params: [], + })), + abi: ABIS.getBoldDebt, + chain: 'ethereum', + }); + + const totalDebt = results.output.map(x => Number(x.output)).reduce((a, b) => a + b); + return totalDebt / 1e18; + } + + const getLTV = async (borrowerOpsAddr) =>{ + const res = (await sdk.api.abi.call({ + target: borrowerOpsAddr, + abi: ABIS.getMCR, + chain: 'ethereum', + }) + ); + + return 1 / (res.output / 1e18); + } + + const getNewApproxAvgInterestRateFromTroveChange = async(activePoolAddr) => { + const res = await sdk.api.abi.call({ + target: activePoolAddr, + abi: ABIS.getNewApproxAvgInterestRateFromTroveChange, + params: [ + [0, // appliedRedistBoldDebtGain + 0, // appliedRedistCollGain + 0, // collIncrease + 0, // collDecrease + 0, // debtIncrease + 0, // debtDecrease + 0, // newWeightedRecordedDebt + 0, // oldWeightedRecordedDebt + 0, // upfrontFee + 0, // batchAccruedManagementFee + 0, // newWeightedRecordedBatchManagementFee + 0] // oldWeightedRecordedBatchManagementFee + ], + chain: 'ethereum', + }); + + // convert from 18 decimals and make percentage + return res.output / 1e16; + } + + const main = async () => { + const prices = await getPrices( + [YSYBOLD_BRANCH.collToken, + SCRVUSD_BRANCH.collToken, + SUSDS_BRANCH.collToken, + SFRXUSD_BRANCH.collToken, + TBTC_BRANCH.collToken, + '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', // WBTC - collToken is wrapper + BOLD_TOKEN + ] + ); + + YSYBOLD_BRANCH.price = prices[YSYBOLD_BRANCH.collToken]; + SCRVUSD_BRANCH.price = prices[SCRVUSD_BRANCH.collToken]; + SUSDS_BRANCH.price = prices[SUSDS_BRANCH.collToken]; + SFRXUSD_BRANCH.price = prices[SFRXUSD_BRANCH.collToken]; + TBTC_BRANCH.price = prices[TBTC_BRANCH.collToken]; + WBTC_BRANCH.price = prices['0x2260fac5e5542a773aa44fbcfedf7c193bc2c599']; // WBTC + + const pools = []; + + for (const branch of branches) { + const collPools = [branch.activePool, branch.defaultPool]; + + const totalColl = await getBranchColl(collPools); + const totalCollUsd = totalColl * branch.price + + const ltv = await getLTV(branch.borrowerOperations); + const borrowApy = await getNewApproxAvgInterestRateFromTroveChange(branch.activePool); + + const totalDebt = await getBranchDebt(collPools); + const totalDebtUsd = totalDebt * prices[BOLD_TOKEN]; + + const [spSupply, spApy] = await getSPSupplyAndApy(branch.stabilityPool, borrowApy, totalDebt); + const spSupplyUsd = spSupply * prices[BOLD_TOKEN]; + + const spPool = + { + pool: branch.stabilityPool, + project: 'asymmetry-usdaf', + symbol: 'USDaf', + chain: 'ethereum', + apy: spApy, + tvlUsd: spSupplyUsd, + underlyingTokens: [BOLD_TOKEN], + rewardTokens: [BOLD_TOKEN, branch.collToken], + poolMeta: `${branch.symbol} Stability Pool` + } + + const borrowPool = + { + pool: branch.activePool, + project: 'asymmetry-usdaf', + symbol: branch.symbol, + chain: 'ethereum', + apy: 0, + tvlUsd: totalCollUsd, + apyBaseBorrow: borrowApy, + totalSupplyUsd: totalCollUsd, + totalBorrowUsd: totalDebtUsd, + ltv: ltv, + mintedCoin: 'USDaf', + underlyingTokens: [branch.collToken], + } + + pools.push(spPool, borrowPool); + }; + + return pools; + } + +module.exports = { + timetravel: false, + apy: main, + url: 'https://usdaf.asymmetry.finance/', +}; \ No newline at end of file diff --git a/src/adaptors/atlas-exchange/index.js b/src/adaptors/atlas-exchange/index.js new file mode 100644 index 0000000000..1edf995aa3 --- /dev/null +++ b/src/adaptors/atlas-exchange/index.js @@ -0,0 +1,97 @@ +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +CHAINS_API = { + hemi: 'https://api.studio.thegraph.com/query/43776/atlas-analytics/version/latest', +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + volumeUSD + fee + token0 { + symbol + id + } + token1 { + symbol + id + } + totalValueLockedToken0 + totalValueLockedToken1 + } + } +`; + +const queryPrior = gql` + { + pools (first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, url, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + CHAINS_API[chainString], + ]); + + let data = (await request(url, query.replace('', block))) + .pools; + + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pools; + + data = data.map((p) => ({ + ...p, + reserve0: p.totalValueLockedToken0, + reserve1: p.totalValueLockedToken1, + feeTier: p.fee * 10, + })); + data = await utils.tvl(data, chainString); + + data = data.map((p) => utils.apy(p, dataPrior, [])); + + return data.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'atlas-exchange', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + underlyingTokens: [p.token0.id, p.token1.id], + poolMeta: `${p.feeTier / 1e4}%`, + volumeUsd1d: p.volumeUSD1d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const data = await Promise.all( + Object.entries(CHAINS_API).map(([chain, url]) => + topLvl(chain, url, timestamp) + ) + ); + + return data.flat().filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + apy: main, + timetravel: false, + url: 'https://atlasexchange.xyz/pools', +}; diff --git a/src/adaptors/atlendis/index.js b/src/adaptors/atlendis/index.js new file mode 100644 index 0000000000..16e086f3e2 --- /dev/null +++ b/src/adaptors/atlendis/index.js @@ -0,0 +1,72 @@ +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const baseUrl = 'https://atlendis.herokuapp.com/graphql'; +const urlPolygon = `${baseUrl}/atlendis-hosted-service-polygon`; + +const query = gql` + { + v1PoolStatuses { + state + pool { + id + identifier + } + normalizedAvailableAmount + normalizedBorrowedAmount + adjustedPendingAmount + weightedAverageLendingRate + } + } +`; + +const buildPool = (entry) => { + const APY_TOKEN_DECIMALS = 18; + const TVL_TOKEN_DECIMALS = 18; + + entry = { ...entry }; + + // calculate TVL + entry.tvl = + Number(entry.normalizedAvailableAmount) + + Number(entry.adjustedPendingAmount); + + entry.tvl = entry.tvl / 10 ** TVL_TOKEN_DECIMALS; + + // calculate APY + entry.apy = + (100 * Number(entry.weightedAverageLendingRate)) / 10 ** APY_TOKEN_DECIMALS; + + const symbolSplit = entry.pool.identifier.split('-'); + // construct return Object + const newObj = { + pool: entry.pool.id, + chain: utils.formatChain('polygon'), + project: 'atlendis', + symbol: symbolSplit[1], + poolMeta: `${symbolSplit[0]} ${symbolSplit[2]}`, + tvlUsd: entry.tvl, + apyBase: entry.apy, + url: `https://app.atlendis.io/pools/${entry.pool.id}/deposit`, + }; + + return newObj; +}; + +const main = async () => { + // pull data + let data = await request(urlPolygon, query); + + // build pool objects + data = data.v1PoolStatuses + .filter((p) => p.state !== 'Closed') + .map((el) => buildPool(el)); + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/atrix/index.ts b/src/adaptors/atrix/index.ts new file mode 100644 index 0000000000..0db5bba3a0 --- /dev/null +++ b/src/adaptors/atrix/index.ts @@ -0,0 +1,54 @@ +const utils = require('../utils'); + +const API_URL: string = 'https://api.atrix.finance/api/all'; + +interface Pool { + key: string; + marketData: { + stats: { marketName: string }; + }; + farms: Array<{ + tvlUsd: number; + apr: number; + crops: Array<{ cropRewardTokenAccount: string }>; + }>; + mints: { + base: { + key: string; + symbol: string; + }; + quote: { + key: string; + symbol: string; + }; + }; +} + +const getApy = async () => { + const { pools } = await utils.getData(API_URL); + const poolsWithFarms: Array = pools.filter(({ farms }) => farms.length); + + const apy = poolsWithFarms.map((pool) => { + return { + pool: pool.key, + chain: utils.formatChain('solana'), + project: 'atrix', + symbol: utils.formatSymbol( + `${pool.mints.base.symbol}-${pool.mints.quote.symbol}` + ), + tvlUsd: pool.farms[0]?.tvlUsd || 0, + apy: pool.farms[0]?.apr || 0, + apyReward: pool.farms[0]?.apr || 0, + underlyingTokens: [pool.mints.base.key, pool.mints.quote.key], + rewardTokens: [pool.farms[0].crops[0].cropRewardTokenAccount], + url: `https://app.atrix.finance/liquidity/${pool.key}/deposit`, + }; + }); + + return apy; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/aura/abis/balancerPool.json b/src/adaptors/aura/abis/balancerPool.json new file mode 100644 index 0000000000..a83ceb2f43 --- /dev/null +++ b/src/adaptors/aura/abis/balancerPool.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "getPoolId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/aura/abis/booster.json b/src/adaptors/aura/abis/booster.json new file mode 100644 index 0000000000..d976c4518c --- /dev/null +++ b/src/adaptors/aura/abis/booster.json @@ -0,0 +1,59 @@ +[ + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { + "internalType": "address", + "name": "stash", + "type": "address" + }, + { + "internalType": "bool", + "name": "shutdown", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/aura/abis/l2coordinator.json b/src/adaptors/aura/abis/l2coordinator.json new file mode 100644 index 0000000000..25a9caeb07 --- /dev/null +++ b/src/adaptors/aura/abis/l2coordinator.json @@ -0,0 +1,9 @@ +[ + { + "inputs": [], + "name": "mintRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/aura/config.js b/src/adaptors/aura/config.js new file mode 100644 index 0000000000..cd330f62da --- /dev/null +++ b/src/adaptors/aura/config.js @@ -0,0 +1,99 @@ +// Chain-specific configuration +const CHAIN_CONFIG = { + ethereum: { + llamaChainName: 'Ethereum', + balancerChainName: 'MAINNET', + booster: '0xA57b8d98dAE62B26Ec3bcC4a365338157060B234', + chainId: 1, + tokens: { + AURA: '0xc0c293ce456ff0ed870add98a0828dd4d2903dbf', + BAL: '0xba100000625a3754423978a60c9317c58a424e3d', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-mainnet/v0.0.1/', + }, + arbitrum: { + llamaChainName: 'Arbitrum', + balancerChainName: 'ARBITRUM', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 42161, + l2Coordinator: '0xeC1c780A275438916E7CEb174D80878f29580606', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0x040d1edc9569d4bab2d15287dc5a4f10f56a56b8', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-arbitrum/v0.0.1/', + }, + base: { + llamaChainName: 'Base', + balancerChainName: 'BASE', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 8453, + l2Coordinator: '0x8b2970c237656d3895588B99a8bFe977D5618201', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0x4158734d47fc9692176b5085e0f52ee0da5d47f1', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-base/v0.0.1/', + }, + avalanche: { + llamaChainName: 'Avalanche', + balancerChainName: 'AVALANCHE', + sdkChainName: 'avax', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 43114, + l2Coordinator: '0x8b2970c237656d3895588B99a8bFe977D5618201', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0xe15bcb9e0ea69e6ab9fa080c4c4a5632896298c3', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-avalanche/v0.0.1/', + }, + gnosis: { + llamaChainName: 'xDai', + balancerChainName: 'GNOSIS', + sdkChainName: 'xdai', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 100, + l2Coordinator: '0x8b2970c237656d3895588B99a8bFe977D5618201', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0x7ef541e2a22058048904fe5744f9c7e4c57af717', + }, + subgraph: + 'https://subgraph.satsuma-prod.com/cae76ab408ca/1xhub-ltd/aura-finance-gnosis/api', + }, + optimism: { + llamaChainName: 'Optimism', + balancerChainName: 'OPTIMISM', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 10, + l2Coordinator: '0xeC1c780A275438916E7CEb174D80878f29580606', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0xfe8b128ba8c78aabc59d4c64cee7ff28e9379921', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-optimism/v0.0.1/', + }, + polygon: { + llamaChainName: 'Polygon', + balancerChainName: 'POLYGON', + booster: '0x98Ef32edd24e2c92525E59afc4475C1242a30184', + chainId: 137, + l2Coordinator: '0x8b2970c237656d3895588B99a8bFe977D5618201', + tokens: { + AURA: '0x1509706a6c66ca549ff0cb464de88231ddbe213b', + BAL: '0x9a71012b13ca4d3d0cdc72a177df3ef03b0e76a3', + }, + subgraph: + 'https://api.subgraph.ormilabs.com/api/public/396b336b-4ed7-469f-a8f4-468e1e26e9a8/subgraphs/aura-finance-polygon/v0.0.1/', + }, +}; + +module.exports = { + CHAIN_CONFIG, +}; diff --git a/src/adaptors/aura/constants.js b/src/adaptors/aura/constants.js new file mode 100644 index 0000000000..db9792f527 --- /dev/null +++ b/src/adaptors/aura/constants.js @@ -0,0 +1,15 @@ +// Common time and calculation constants +const COMMON_CONFIG = { + SECONDS_PER_YEAR: 365 * 24 * 60 * 60, + QUEUED_REWARDS_EXTENSION: 7 * 24 * 60 * 60, + DEFAULT_TOKEN_DECIMALS: 18, + AIP_42_ENABLED: true, // 40% reduction applied to most pools (AIP-42) +}; + +// Balancer V3 API endpoint +const BALANCER_API_ENDPOINT = 'https://api-v3.balancer.fi/graphql'; + +module.exports = { + COMMON_CONFIG, + BALANCER_API_ENDPOINT, +}; diff --git a/src/adaptors/aura/data/get-active-pools.js b/src/adaptors/aura/data/get-active-pools.js new file mode 100644 index 0000000000..432894abd1 --- /dev/null +++ b/src/adaptors/aura/data/get-active-pools.js @@ -0,0 +1,23 @@ +const { getPoolCount, fetchPoolInfo } = require('./rpc/booster'); + +/** + * Get all active (non-shutdown) pools from the booster contract + */ +async function getActivePools(chainName, chainConfig) { + if (!chainConfig?.booster) return []; + + const poolLength = await getPoolCount(chainConfig.booster, chainName); + const allPoolsRaw = await fetchPoolInfo( + chainConfig.booster, + poolLength, + chainName + ); + + return allPoolsRaw.flatMap(({ output }, index) => + output && !output.shutdown ? [{ ...output, poolIndex: index }] : [] + ); +} + +module.exports = { + getActivePools, +}; diff --git a/src/adaptors/aura/data/get-balancer-data.js b/src/adaptors/aura/data/get-balancer-data.js new file mode 100644 index 0000000000..bec08be8bc --- /dev/null +++ b/src/adaptors/aura/data/get-balancer-data.js @@ -0,0 +1,62 @@ +const { getPoolIds } = require('./rpc/balancer-pool'); +const { getBalancerPoolsData } = require('./subgraph/balancer-pools'); + +/** + * Get Balancer pool data with processed APRs, staking rewards, and underlying tokens + */ +async function getBalancerData(activePools, sdkChainName, chainConfig) { + const poolIdResults = await getPoolIds( + activePools.map((pool) => pool.lptoken), + sdkChainName + ); + + const balancerPoolsDataMap = await getBalancerPoolsData( + activePools.map((pool, i) => + poolIdResults[i]?.success && poolIdResults[i]?.output + ? poolIdResults[i].output + : pool.lptoken + ), + chainConfig.balancerChainName + ); + + return activePools.reduce((acc, pool, i) => { + const balancerPoolId = + poolIdResults[i]?.success && poolIdResults[i]?.output + ? poolIdResults[i].output + : pool.lptoken; + const poolData = balancerPoolsDataMap[balancerPoolId.toLowerCase()]; + if (!poolData) return acc; + + const apyBase = poolData.dynamicData?.aprItems + ? poolData.dynamicData.aprItems.reduce((aprAcc, item) => { + const aprValue = item.apr * 100 || 0; + + if ( + item.type === 'SWAP_FEE' || + item.type === 'SWAP_FEE_24H' || + item.type === 'IB_YIELD' + ) { + aprAcc += aprValue; + } + + return aprAcc; + }, 0) + : 0; + + acc[pool.poolIndex] = { + apyBase, + underlyingTokens: + poolData.poolTokens?.flatMap((token) => + token.underlyingToken && token.useUnderlyingForAddRemove + ? [token.address, token.underlyingToken.address] + : [token.address] + ) || [], + }; + + return acc; + }, {}); +} + +module.exports = { + getBalancerData, +}; diff --git a/src/adaptors/aura/data/get-pool-tvls.js b/src/adaptors/aura/data/get-pool-tvls.js new file mode 100644 index 0000000000..31502a88fb --- /dev/null +++ b/src/adaptors/aura/data/get-pool-tvls.js @@ -0,0 +1,43 @@ +const { getTotalSupplies } = require('./rpc/erc20'); +const utils = require('../../utils'); + +/** + * Get TVL for Aura pools + */ +async function getPoolTvls(pools, chainName) { + if (!pools?.length) return {}; + + try { + const [totalSupplyResults, tokenPrices] = await Promise.all([ + getTotalSupplies( + pools.map((pool) => pool.token), + chainName + ), + utils + .getData( + `https://coins.llama.fi/prices/current/${pools + .map((pool) => `${chainName}:${pool.lptoken}`) + .join(',') + .toLowerCase()}` + ) + .then((data) => data.coins), + ]); + + return pools.reduce((acc, pool, index) => { + const priceKey = `${chainName}:${pool.lptoken.toLowerCase()}`; + const price = tokenPrices[priceKey]?.price; + const totalSupply = totalSupplyResults[index]?.output; + + acc[pool.poolIndex] = + price && totalSupply ? (Number(totalSupply) / 1e18) * price : 0; + + return acc; + }, {}); + } catch { + return {}; + } +} + +module.exports = { + getPoolTvls, +}; diff --git a/src/adaptors/aura/data/get-rewards-data.js b/src/adaptors/aura/data/get-rewards-data.js new file mode 100644 index 0000000000..75a53329cd --- /dev/null +++ b/src/adaptors/aura/data/get-rewards-data.js @@ -0,0 +1,111 @@ +const { getAuraPoolRewards } = require('./subgraph/rewards'); +const { calculateRewardApr } = require('../utils/calculate-reward-apr'); +const { calculateAuraMintAmount } = require('../utils/calculate-aura-mint'); +const { isRewardActive } = require('../utils/is-reward-active'); +const { fetchTokenPrices } = require('../utils/token-prices'); +const { getMintRate } = require('./rpc/l2coordinator'); +const { COMMON_CONFIG } = require('../constants'); + +/** + * Get rewards data for all pools + */ +async function getRewardsData( + activePools, + chainName, + chainConfig, + tvlsData, + auraGlobals, + sdkChainName +) { + const subgraphData = await getAuraPoolRewards(chainName); + if (!subgraphData?.pools) return {}; + + // Collect all reward tokens for pricing + const rewardTokens = new Set(); + rewardTokens.add(chainConfig.tokens.AURA); + rewardTokens.add(chainConfig.tokens.BAL); + + subgraphData.pools.forEach((pool) => { + pool.rewardData?.forEach((r) => { + if (r.token?.id) rewardTokens.add(r.token.id); + }); + }); + + const [tokenPrices, mintRate] = await Promise.all([ + fetchTokenPrices(rewardTokens, sdkChainName), + getMintRate(chainConfig.l2Coordinator, sdkChainName), + ]); + + const auraTokenAddress = chainConfig.tokens.AURA.toLowerCase(); + const balTokenAddress = chainConfig.tokens.BAL.toLowerCase(); + + return subgraphData.pools.reduce((acc, subgraphPool) => { + const poolIndex = parseInt(subgraphPool.id); + const tvl = tvlsData[poolIndex]; + + if (isNaN(poolIndex) || !subgraphPool.rewardData?.length || !tvl) { + return acc; + } + + acc[poolIndex] = subgraphPool.rewardData.reduce((rewards, r) => { + const rewardToken = r.token?.id?.toLowerCase(); + + const tokenPrice = tokenPrices[rewardToken]; + const isActive = isRewardActive(r.periodFinish, r.queuedRewards); + + // Skip inactive rewards + if (!isActive) return rewards; + if (!tokenPrice) return rewards; + + const apr = calculateRewardApr( + r.rewardRate || '0', + tokenPrice, + tvl, + r.token?.decimals + ); + + if (apr > 0) { + rewards.push({ rewardToken, apr }); + } + + // Calculate minted AURA for BAL rewards + if (rewardToken === balTokenAddress) { + const balPerYear = + BigInt(r.rewardRate || '0') * BigInt(COMMON_CONFIG.SECONDS_PER_YEAR); + const mintedAuraPerYear = calculateAuraMintAmount( + balPerYear.toString(), + auraGlobals + ); + const auraPrice = tokenPrices[auraTokenAddress]; + + if (auraPrice && BigInt(mintedAuraPerYear) > 0n) { + // Apply mintRate multiplier for L2 chains + const adjustedMintedAura = + (BigInt(mintedAuraPerYear) * mintRate) / 1000000000000000000n; + const auraApr = + (((Number(adjustedMintedAura) / 1e18) * auraPrice) / tvl) * 100; + + if (auraApr > 0) { + // Find existing AURA reward and add to it, or create new entry + const existingAuraReward = rewards.find( + (reward) => reward.rewardToken === auraTokenAddress + ); + if (existingAuraReward) { + existingAuraReward.apr += auraApr; + } else { + rewards.push({ rewardToken: auraTokenAddress, apr: auraApr }); + } + } + } + } + + return rewards; + }, []); + + return acc; + }, {}); +} + +module.exports = { + getRewardsData, +}; diff --git a/src/adaptors/aura/data/rpc/balancer-pool.js b/src/adaptors/aura/data/rpc/balancer-pool.js new file mode 100644 index 0000000000..5121ba9a2c --- /dev/null +++ b/src/adaptors/aura/data/rpc/balancer-pool.js @@ -0,0 +1,19 @@ +const sdk = require('@defillama/sdk'); +const balancerPoolABI = require('../../abis/balancerPool.json'); + +/** + * Get pool IDs for multiple Balancer pools + */ +async function getPoolIds(lpTokens, chain) { + const result = await sdk.api.abi.multiCall({ + abi: balancerPoolABI.find(({ name }) => name === 'getPoolId'), + calls: lpTokens.map((token) => ({ target: token })), + chain, + permitFailure: true, + }); + return result.output; +} + +module.exports = { + getPoolIds, +}; diff --git a/src/adaptors/aura/data/rpc/booster.js b/src/adaptors/aura/data/rpc/booster.js new file mode 100644 index 0000000000..d0ed291beb --- /dev/null +++ b/src/adaptors/aura/data/rpc/booster.js @@ -0,0 +1,36 @@ +const sdk = require('@defillama/sdk'); +const boosterABI = require('../../abis/booster.json'); + +/** + * Get the total number of pools from booster contract + */ +async function getPoolCount(booster, chain) { + const result = await sdk.api.abi.call({ + abi: boosterABI.find(({ name }) => name === 'poolLength'), + target: booster, + chain, + permitFailure: true, + }); + return parseInt(result.output ?? 0); +} + +/** + * Fetch pool information for multiple pools + */ +async function fetchPoolInfo(booster, poolCount, chain) { + const result = await sdk.api.abi.multiCall({ + abi: boosterABI.find(({ name }) => name === 'poolInfo'), + calls: Array.from({ length: poolCount }, (_, i) => i).map((index) => ({ + target: booster, + params: [index], + })), + chain, + permitFailure: true, + }); + return result.output; +} + +module.exports = { + getPoolCount, + fetchPoolInfo, +}; diff --git a/src/adaptors/aura/data/rpc/erc20.js b/src/adaptors/aura/data/rpc/erc20.js new file mode 100644 index 0000000000..baaf4f6e09 --- /dev/null +++ b/src/adaptors/aura/data/rpc/erc20.js @@ -0,0 +1,35 @@ +const sdk = require('@defillama/sdk'); + +/** + * Get symbols for multiple ERC20 tokens + */ +async function getSymbols(tokenAddresses, chain) { + const result = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokenAddresses.map((address) => ({ target: address })), + chain, + permitFailure: true, + }); + return result.output.reduce((acc, { output }, idx) => { + acc[idx] = output?.replace(/-BPT$/, '') || null; + return acc; + }, {}); +} + +/** + * Get total supplies for multiple ERC20 tokens + */ +async function getTotalSupplies(tokenAddresses, chain) { + const result = await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: tokenAddresses.map((address) => ({ target: address })), + chain, + permitFailure: true, + }); + return result.output; +} + +module.exports = { + getSymbols, + getTotalSupplies, +}; diff --git a/src/adaptors/aura/data/rpc/l2coordinator.js b/src/adaptors/aura/data/rpc/l2coordinator.js new file mode 100644 index 0000000000..4755aefbab --- /dev/null +++ b/src/adaptors/aura/data/rpc/l2coordinator.js @@ -0,0 +1,28 @@ +const sdk = require('@defillama/sdk'); +const l2CoordinatorABI = require('../../abis/l2coordinator.json'); + +/** + * Get mintRate from L2Coordinator contract + * Returns 1e18 (100% multiplier) as fallback + */ +async function getMintRate(l2Coordinator, chain) { + if (!l2Coordinator) return 1000000000000000000n; + + try { + const result = await sdk.api.abi.call({ + abi: l2CoordinatorABI.find(({ name }) => name === 'mintRate'), + target: l2Coordinator, + chain, + permitFailure: true, + }); + return result.success && result.output + ? BigInt(result.output) + : 1000000000000000000n; + } catch { + return 1000000000000000000n; + } +} + +module.exports = { + getMintRate, +}; diff --git a/src/adaptors/aura/data/subgraph/balancer-pools.js b/src/adaptors/aura/data/subgraph/balancer-pools.js new file mode 100644 index 0000000000..6859702916 --- /dev/null +++ b/src/adaptors/aura/data/subgraph/balancer-pools.js @@ -0,0 +1,55 @@ +const axios = require('axios'); +const { BALANCER_API_ENDPOINT } = require('../../constants'); + +/** + * Get pool data from Balancer V3 API + */ +async function getBalancerPoolsData(poolIdentifiers, balancerChainName) { + if (!balancerChainName) return {}; + + const query = ` + query Pools($chains: [GqlChain!]!, $ids: [String!] ) { + poolGetPools( + where: { chainIn: $chains, idIn: $ids } + first: 1000 + ) { + id + address + poolTokens { + address + underlyingToken { + address + } + useUnderlyingForAddRemove + } + dynamicData { + aprItems { + apr + type + } + } + } + } + `; + + try { + const data = await axios + .post(BALANCER_API_ENDPOINT, { + query, + variables: { chains: [balancerChainName], ids: poolIdentifiers }, + }) + .then((res) => res.data.data.poolGetPools); + + return data.reduce((acc, pool) => { + if (pool.id) acc[pool.id.toLowerCase()] = pool; + if (pool.address) acc[pool.address.toLowerCase()] = pool; + return acc; + }, {}); + } catch { + return {}; + } +} + +module.exports = { + getBalancerPoolsData, +}; diff --git a/src/adaptors/aura/data/subgraph/globals.js b/src/adaptors/aura/data/subgraph/globals.js new file mode 100644 index 0000000000..3805b356df --- /dev/null +++ b/src/adaptors/aura/data/subgraph/globals.js @@ -0,0 +1,38 @@ +const axios = require('axios'); +const { CHAIN_CONFIG } = require('../../config'); + +let globalsCache = null; + +/** + * Get Aura globals data from mainnet subgraph + */ +async function getAuraGlobals() { + if (globalsCache) return globalsCache; + + const query = ` + query { + global(id: "global") { + auraTotalSupply + auraMaxSupply + auraReductionPerCliff + auraTotalCliffs + } + } + `; + + try { + const response = await axios.post(CHAIN_CONFIG.ethereum.subgraph, { + query, + }); + if (response.data.errors) return null; + + globalsCache = response.data.data.global; + return globalsCache; + } catch { + return null; + } +} + +module.exports = { + getAuraGlobals, +}; diff --git a/src/adaptors/aura/data/subgraph/rewards.js b/src/adaptors/aura/data/subgraph/rewards.js new file mode 100644 index 0000000000..92649422dd --- /dev/null +++ b/src/adaptors/aura/data/subgraph/rewards.js @@ -0,0 +1,41 @@ +const axios = require('axios'); +const { CHAIN_CONFIG } = require('../../config'); + +/** + * Get pool rewards data from Aura subgraph + */ +async function getAuraPoolRewards(chainName) { + const chainConfig = CHAIN_CONFIG[chainName]; + if (!chainConfig?.subgraph) return null; + + const query = ` + query Dynamics { + pools(first: 1000, skip: 0) { + id + lpToken { + id + } + rewardData { + token { + id + decimals + } + rewardRate + periodFinish + queuedRewards + } + } + } + `; + + try { + const response = await axios.post(chainConfig.subgraph, { query }); + return response.data.errors ? null : response.data.data; + } catch { + return null; + } +} + +module.exports = { + getAuraPoolRewards, +}; diff --git a/src/adaptors/aura/index.js b/src/adaptors/aura/index.js new file mode 100644 index 0000000000..733efaa3ab --- /dev/null +++ b/src/adaptors/aura/index.js @@ -0,0 +1,96 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const { CHAIN_CONFIG } = require('./config'); +const { getAuraGlobals } = require('./data/subgraph/globals'); +const { getSymbols } = require('./data/rpc/erc20'); +const { getActivePools } = require('./data/get-active-pools'); +const { getPoolTvls } = require('./data/get-pool-tvls'); +const { getBalancerData } = require('./data/get-balancer-data'); +const { getRewardsData } = require('./data/get-rewards-data'); +const { setupRpcProvider } = require('./utils/setup-rpc'); +const utils = require('../utils'); + +async function poolsFunction() { + const allPools = []; + const auraGlobals = await getAuraGlobals(); + if (!auraGlobals) { + return allPools; + } + + for (const [chainName, chainConfig] of Object.entries(CHAIN_CONFIG)) { + try { + // Setup custom RPC provider for this chain if config is present + setupRpcProvider(chainName, chainConfig); + + const sdkChainName = chainConfig.sdkChainName || chainName; + const activePools = await getActivePools(sdkChainName, chainConfig); + if (activePools.length === 0) continue; + + const lpTokens = activePools.map((pool) => pool.lptoken); + + const [symbolsData, tvlsData, balancerData] = await Promise.all([ + getSymbols(lpTokens, sdkChainName), + getPoolTvls(activePools, sdkChainName), + getBalancerData(activePools, sdkChainName, chainConfig), + ]); + + const rewardsData = await getRewardsData( + activePools, + chainName, + chainConfig, + tvlsData, + auraGlobals, + sdkChainName + ); + + const chainPools = activePools.map((pool, idx) => { + const poolIndex = pool.poolIndex; + const poolBalancerData = balancerData[poolIndex] || { + apyBase: 0, + underlyingTokens: [], + }; + + // Calculate reward APR and collect reward tokens from Aura subgraph only + const { apyReward, rewardTokens } = ( + rewardsData[poolIndex] || [] + ).reduce( + (acc, reward) => { + acc.apyReward += reward.apr; + if (reward.apr > 0 && reward.rewardToken) { + acc.rewardTokens.push(reward.rewardToken); + } + return acc; + }, + { apyReward: 0, rewardTokens: [] } + ); + + return { + pool: `${pool.lptoken.toLowerCase()}-aura`, + chain: chainConfig.llamaChainName, + project: 'aura', + symbol: utils.formatSymbol(symbolsData[idx] ?? 'Unknown'), + tvlUsd: tvlsData[poolIndex] ?? 0, + apyBase: poolBalancerData.apyBase, + apyReward, + rewardTokens: Array.from(new Set(rewardTokens || [])), + underlyingTokens: poolBalancerData.underlyingTokens, + poolMeta: null, + url: `https://app.aura.finance/#/${chainConfig.chainId}/pool/${poolIndex}`, + }; + }); + + allPools.push(...chainPools); + } catch (_err) { + console.error(`Error processing ${chainName}:`, _err.message); + // Skip chain on error + } + } + + return allPools; +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.aura.finance/', +}; diff --git a/src/adaptors/aura/utils/calculate-aura-mint.js b/src/adaptors/aura/utils/calculate-aura-mint.js new file mode 100644 index 0000000000..f035037851 --- /dev/null +++ b/src/adaptors/aura/utils/calculate-aura-mint.js @@ -0,0 +1,41 @@ +const { COMMON_CONFIG } = require('../constants'); + +/** + * Calculate AURA mint amount for a given BAL amount + */ +function calculateAuraMintAmount( + balEarned, + globals, + applyAip42 = COMMON_CONFIG.AIP_42_ENABLED +) { + if (!globals?.auraTotalSupply) return '0'; + + const balEarnedBN = BigInt(balEarned); + if (balEarnedBN < 500000000000000n) return '0'; + + const auraTotalSupply = BigInt(globals.auraTotalSupply); + const auraMaxSupply = BigInt(globals.auraMaxSupply); + const auraReductionPerCliff = BigInt(globals.auraReductionPerCliff); + const auraTotalCliffs = BigInt(globals.auraTotalCliffs); + + const emissionsMinted = auraTotalSupply - auraMaxSupply; + const cliff = emissionsMinted / auraReductionPerCliff; + + if (cliff >= auraTotalCliffs) return '0'; + + const reduction = ((auraTotalCliffs - cliff) * 25n) / 10n + 700n; + let amount = (balEarnedBN * reduction) / auraTotalCliffs; + + // Apply max supply limit + const amtTillMax = auraMaxSupply - emissionsMinted; + if (amount > amtTillMax) amount = amtTillMax; + + // Apply AIP-42 reduction (40% of original) + if (applyAip42) amount = (amount * 4n) / 10n; + + return amount.toString(); +} + +module.exports = { + calculateAuraMintAmount, +}; diff --git a/src/adaptors/aura/utils/calculate-reward-apr.js b/src/adaptors/aura/utils/calculate-reward-apr.js new file mode 100644 index 0000000000..27bc680e63 --- /dev/null +++ b/src/adaptors/aura/utils/calculate-reward-apr.js @@ -0,0 +1,17 @@ +const { COMMON_CONFIG } = require('../constants'); + +/** + * Calculate APR from reward rate + */ +function calculateRewardApr(rewardRate, tokenPrice, tvl, decimals = 18) { + if (!rewardRate || !tokenPrice || !tvl) return 0; + + const rewardPerYear = Number(rewardRate) * COMMON_CONFIG.SECONDS_PER_YEAR; + const rewardPerYearScaled = rewardPerYear / Math.pow(10, decimals); + + return ((rewardPerYearScaled * tokenPrice) / tvl) * 100; +} + +module.exports = { + calculateRewardApr, +}; diff --git a/src/adaptors/aura/utils/is-reward-active.js b/src/adaptors/aura/utils/is-reward-active.js new file mode 100644 index 0000000000..53c752f20e --- /dev/null +++ b/src/adaptors/aura/utils/is-reward-active.js @@ -0,0 +1,19 @@ +const { COMMON_CONFIG } = require('../constants'); + +/** + * Check if rewards are currently active + */ +function isRewardActive(periodFinish, queuedRewards) { + const now = Math.floor(Date.now() / 1000); + let finish = parseInt(periodFinish || '0', 10); + + if (queuedRewards && BigInt(queuedRewards) > 0n) { + finish += COMMON_CONFIG.QUEUED_REWARDS_EXTENSION; + } + + return finish > now; +} + +module.exports = { + isRewardActive, +}; diff --git a/src/adaptors/aura/utils/setup-rpc.js b/src/adaptors/aura/utils/setup-rpc.js new file mode 100644 index 0000000000..777a8796f6 --- /dev/null +++ b/src/adaptors/aura/utils/setup-rpc.js @@ -0,0 +1,23 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); + +/** + * Configure SDK to use custom RPC provider for a chain + */ +function setupRpcProvider(chainName, chainConfig) { + if (chainConfig.rpc && chainConfig.chainId) { + const sdkChainName = chainConfig.sdkChainName || chainName; + const network = { + name: sdkChainName, + chainId: chainConfig.chainId, + }; + sdk.api.config.setProvider( + sdkChainName, + new ethers.providers.JsonRpcProvider(chainConfig.rpc, network) + ); + } +} + +module.exports = { + setupRpcProvider, +}; diff --git a/src/adaptors/aura/utils/token-prices.js b/src/adaptors/aura/utils/token-prices.js new file mode 100644 index 0000000000..aef64ecc3d --- /dev/null +++ b/src/adaptors/aura/utils/token-prices.js @@ -0,0 +1,37 @@ +const utils = require('../../utils'); + +/** + * Fetch token prices from DefiLlama + */ +async function fetchTokenPrices(tokenAddresses, chainName) { + const tokenPrices = {}; + + const priceKeys = Array.from(tokenAddresses) + .filter((addr) => addr) + .map((addr) => `${chainName}:${addr}`); + + if (priceKeys.length === 0) { + return tokenPrices; + } + + try { + const prices = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys.join(',')}` + ); + + Object.entries(prices.coins || {}).forEach(([key, data]) => { + const address = key.split(':')[1]?.toLowerCase(); + if (address) { + tokenPrices[address] = data.price || 0; + } + }); + } catch (error) { + console.error('Error fetching token prices:', error); + } + + return tokenPrices; +} + +module.exports = { + fetchTokenPrices, +}; diff --git a/src/adaptors/auragi-finance/index.ts b/src/adaptors/auragi-finance/index.ts new file mode 100644 index 0000000000..6f8a2db50b --- /dev/null +++ b/src/adaptors/auragi-finance/index.ts @@ -0,0 +1,113 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL = 'https://api.auragi.finance/api/v1/pairs'; +const SUBGRAPH_URL = sdk.graph.modifyEndpoint('DtNQcRXx82k4azEb5QvUjRbmXSNLTUsUePzPY6PtryEc'); + +const swapPairsQuery = (skip) => { + return gql` + query MyQuery { + pairs(first: 100, skip: ${skip}, where: {reserveUSD_gt: 10000}) { + reserve0 + reserve1 + token1 { + id + symbol + } + token0 { + id + symbol + } + reserveUSD + id + } + } + ` +} + +const getPairs = async () => { + let pairs = [] + let index = 0 + let res + do { + res = await request(SUBGRAPH_URL, swapPairsQuery(index), {}) + if (res.pairs.length > 0) { + pairs = [...pairs, ...res.pairs] + } + index += res.pairs.length + } while (res.pairs.length > 0) + return pairs +}; + +const getApy = async () => { + // APR is retrieved using our api, tvl pairs etc trough subgraph + const { data: poolsRes } = await utils.getData(API_URL) + + const apyDict = {} + const alreadySeen = [] + + for (const pool of poolsRes) { + apyDict[pool.address.toLowerCase()] = pool?.apr + } + + const pairs = await getPairs() + for (const pair of pairs) { + const token0Key = 'arbitrum:' + pair.token0.id.toLowerCase() + const token1Key = 'arbitrum:' + pair.token1.id.toLowerCase() + + if (!alreadySeen.includes(token0Key)) { + alreadySeen.push(token0Key) + } + + if (!alreadySeen.includes(token1Key)) { + alreadySeen.push(token1Key) + } + } + + // asking price to defillama chunking requests (currently running with 1 request could be lowered if needed) + let fullCoin = {} + const chunkSize = 60 + for (let i = 0; i < alreadySeen.length; i += chunkSize) { + const chunk = alreadySeen.slice(i, i + chunkSize) + + const { coins } = await utils.getData(`https://coins.llama.fi/prices/current/${chunk.join(',')}?searchWidth=4h`) + fullCoin = { ...fullCoin, ...coins } + } + + const pools = pairs.map((pair) => { + let tvl = 0 + + if (fullCoin['arbitrum:' + pair.token0.id.toLowerCase()] && fullCoin['arbitrum:' + pair.token1.id.toLowerCase()]) { + const token0ValueInReserve = parseFloat(pair.reserve0) * parseFloat(fullCoin['arbitrum:' + pair.token0.id.toLowerCase()].price) + const token1ValueInReserve = parseFloat(pair.reserve1) * parseFloat(fullCoin['arbitrum:' + pair.token1.id.toLowerCase()].price) + + tvl = token0ValueInReserve + token1ValueInReserve + } + else { + // fallbacking to the one from api if defillama price are missing + tvl = parseFloat(pair.reserveUSD) + } + + return { + pool: pair.id, + chain: utils.formatChain('arbitrum'), + project: 'auragi-finance', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: tvl, + apyReward: parseFloat(apyDict[pair.id.toLowerCase()]), + underlyingTokens: [pair.token0.id, pair.token1.id], + rewardTokens: [ + '0xFF191514A9baba76BfD19e3943a4d37E8ec9a111', // AGI + ], + }; + }) + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://auragi.finance/pools', +}; diff --git a/src/adaptors/aurelius/abiLendingPool.js b/src/adaptors/aurelius/abiLendingPool.js new file mode 100644 index 0000000000..ddf300738e --- /dev/null +++ b/src/adaptors/aurelius/abiLendingPool.js @@ -0,0 +1,692 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/aurelius/abiProtocolDataProvider.js b/src/adaptors/aurelius/abiProtocolDataProvider.js new file mode 100644 index 0000000000..1c698fcae2 --- /dev/null +++ b/src/adaptors/aurelius/abiProtocolDataProvider.js @@ -0,0 +1,148 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/aurelius/abiYieldReader.js b/src/adaptors/aurelius/abiYieldReader.js new file mode 100644 index 0000000000..f6a478e454 --- /dev/null +++ b/src/adaptors/aurelius/abiYieldReader.js @@ -0,0 +1,300 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "protocolDataProviderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lendingOracleAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ILENDING_ORACLE", + "outputs": [ + { + "internalType": "contract ILendingOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_DATA_PROVIDER", + "outputs": [ + { + "internalType": "contract ProtocolDataProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARDER", + "outputs": [ + { + "internalType": "contract IRewarder0612", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetFullYieldBreakdown", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetRewardsAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getDepositAndBorrowAPRs", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolBalancesUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolYearlyRewardsUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReceiptTokenAddresses", + "outputs": [ + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardsDataEPS", + "outputs": [ + { + "internalType": "uint256", + "name": "aTokenRewardEPS", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vTokenRewardEPS", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/aurelius/index.js b/src/adaptors/aurelius/index.js new file mode 100644 index 0000000000..c9e81efd92 --- /dev/null +++ b/src/adaptors/aurelius/index.js @@ -0,0 +1,181 @@ +const ethers = require('ethers'); +const { JsonRpcProvider } = require('ethers'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiYieldReader = require('./abiYieldReader'); + +const utils = require('../utils'); + +const chains = { + mantle: { + LendingPool: '0x7c9C6F5BEd9Cfe5B9070C7D3322CF39eAD2F9492', + ProtocolDataProvider: '0xedB4f24e4b74a6B1e20e2EAf70806EAC19E1FA54', + url: 'mantle', + YieldReader: '0xAdeA539C144178AF7Ae8a4Bf6084d38Cf0E85D26', + rewardTokens: ['0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8'] + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + const rewardTokens = addresses.rewardTokens; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output.filter((address) => address.toLowerCase() !== '0x4206931337dc273a630d328dA6441786BfaD668f'.toLowerCase());; + + // try catches incase of safemath error + let rewardsData; + try { + rewardsData = await sdk.api.abi.multiCall({ + calls: reservesList.map((reserve) => ({ + target: addresses.YieldReader, + params: [reserve], + })), + abi: abiYieldReader.find((m) => m.name === 'getAssetRewardsAPR'), + chain: sdkChain, + failOnRevert: false, // Add this option to prevent failing on reverts + }); + } catch (error) { + console.error(`Error fetching rewards data for chain ${chain}:`, error); + // Implement fallback mechanism or use default values + rewardsData = { + output: reservesList.map(() => ({ success: false, output: null })) + }; + } + + // Process the results, handling potential failures + const processedRewardsData = rewardsData.output.map((result, index) => { + if (result.success && Array.isArray(result.output) && result.output.length === 2) { + return { + apyReward: Number(result.output[0]) / 1e16, + apyRewardBorrow: Number(result.output[1]) / 1e16 + }; + } else { + console.warn(`Failed to get rewards data for reserve ${reservesList[index]} on chain ${chain}`); + return { apyReward: 0, apyRewardBorrow: 0 }; + } + }); + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + + const { apyReward, apyRewardBorrow } = processedRewardsData[i]; + + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const poolSymbol = symbols[i].toLowerCase() + const url = `https://app.aurelius.finance/markets/${poolSymbol}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'aurelius', + chain, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + rewardTokens, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/aurigami/auriLensAbi.js b/src/adaptors/aurigami/auriLensAbi.js new file mode 100644 index 0000000000..4b470ac5b0 --- /dev/null +++ b/src/adaptors/aurigami/auriLensAbi.js @@ -0,0 +1,559 @@ +module.exports = [ + { + inputs: [ + { internalType: 'contract IERC20', name: '_WNEAR', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + inputs: [], + name: 'WNEAR', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract AuToken', name: 'auToken', type: 'address' }, + ], + name: 'auTokenBalances', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'uint256', name: 'balanceOf', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowBalanceCurrent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balanceOfUnderlying', + type: 'uint256', + }, + { internalType: 'uint256', name: 'tokenBalance', type: 'uint256' }, + { internalType: 'uint256', name: 'tokenAllowance', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenBalances', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + ], + name: 'auTokenBalancesAll', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'uint256', name: 'balanceOf', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowBalanceCurrent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balanceOfUnderlying', + type: 'uint256', + }, + { internalType: 'uint256', name: 'tokenBalance', type: 'uint256' }, + { internalType: 'uint256', name: 'tokenAllowance', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenBalances[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + ], + name: 'auTokenMetadataAllNonView', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { + internalType: 'uint256', + name: 'exchangeRateCurrent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactorMantissa', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBorrows', type: 'uint256' }, + { internalType: 'uint256', name: 'totalReserves', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'totalCash', type: 'uint256' }, + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'address', + name: 'underlyingAssetAddress', + type: 'address', + }, + { internalType: 'uint256', name: 'auTokenDecimals', type: 'uint256' }, + { + internalType: 'uint256', + name: 'underlyingDecimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'plyRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'plyRewardBorrowSpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardBorrowSpeed', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenMetadata[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract AuToken', name: 'auToken', type: 'address' }, + ], + name: 'auTokenMetadataNonView', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { + internalType: 'uint256', + name: 'exchangeRateCurrent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactorMantissa', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBorrows', type: 'uint256' }, + { internalType: 'uint256', name: 'totalReserves', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'totalCash', type: 'uint256' }, + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'address', + name: 'underlyingAssetAddress', + type: 'address', + }, + { internalType: 'uint256', name: 'auTokenDecimals', type: 'uint256' }, + { + internalType: 'uint256', + name: 'underlyingDecimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'plyRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'plyRewardBorrowSpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardBorrowSpeed', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenMetadata', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract AuToken', name: 'auToken', type: 'address' }, + ], + name: 'auTokenUnderlyingPrice', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'uint256', name: 'underlyingPrice', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenUnderlyingPrice', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + ], + name: 'auTokenUnderlyingPriceAll', + outputs: [ + { + components: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'uint256', name: 'underlyingPrice', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AuTokenUnderlyingPrice[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'claimOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'contract AuriFairLaunchInterface', + name: 'fairLaunch', + type: 'address', + }, + { internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }, + ], + name: 'claimRewards', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'plyAccrured', type: 'uint256' }, + { internalType: 'uint256', name: 'auroraClaimable', type: 'uint256' }, + { internalType: 'uint256', name: 'wnearClaimable', type: 'uint256' }, + ], + internalType: 'struct AuriLens.RewardBalancesMetadata', + name: 'rewardData', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getAccountLimits', + outputs: [ + { + components: [ + { + internalType: 'contract AuToken[]', + name: 'markets', + type: 'address[]', + }, + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'shortfall', type: 'uint256' }, + ], + internalType: 'struct AuriLens.AccountLimits', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getAddresses', + outputs: [ + { internalType: 'address', name: 'ply', type: 'address' }, + { internalType: 'address', name: 'aurora', type: 'address' }, + { internalType: 'address', name: 'wnear', type: 'address' }, + { internalType: 'address', name: 'pulp', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract PULPInterface', name: 'pulp', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'int256', name: 'weekInt', type: 'int256' }, + ], + name: 'getPercentLock', + outputs: [ + { internalType: 'uint256', name: 'percentLock', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: 'comptroller', + type: 'address', + }, + { internalType: 'contract AuToken', name: 'auToken', type: 'address' }, + ], + name: 'getRewardSpeeds', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'plyRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'plyRewardBorrowSpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardSupplySpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'auroraRewardBorrowSpeed', + type: 'uint256', + }, + ], + internalType: 'struct AuriLens.RewardSpeeds', + name: 'rewardSpeeds', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract PULPInterface', name: 'pulp', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'targetUnlockPercent', type: 'uint256' }, + ], + name: 'getWeekToUnlock', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newOwner', type: 'address' }, + { internalType: 'bool', name: 'direct', type: 'bool' }, + { internalType: 'bool', name: 'renounce', type: 'bool' }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newImplementation', type: 'address' }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newImplementation', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, +]; diff --git a/src/adaptors/aurigami/comptrollerAbi.js b/src/adaptors/aurigami/comptrollerAbi.js new file mode 100644 index 0000000000..b3a1b60d20 --- /dev/null +++ b/src/adaptors/aurigami/comptrollerAbi.js @@ -0,0 +1,1316 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { inputs: [], name: 'AssetNotUsedAsCollateral', type: 'error' }, + { inputs: [], name: 'InsufficientLiquidity', type: 'error' }, + { inputs: [], name: 'InsufficientShortfall', type: 'error' }, + { inputs: [], name: 'InvalidCollateralFactor', type: 'error' }, + { inputs: [], name: 'MarketAlreadyListed', type: 'error' }, + { inputs: [], name: 'MarketCollateralFactorZero', type: 'error' }, + { inputs: [], name: 'MarketNotListed', type: 'error' }, + { inputs: [], name: 'NonzeroBorrowBalance', type: 'error' }, + { inputs: [], name: 'PriceError', type: 'error' }, + { inputs: [], name: 'TooMuchRepay', type: 'error' }, + { inputs: [], name: 'Unauthorized', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorPlySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'plyDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'plyBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'plyDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'plyBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMintCap', + type: 'uint256', + }, + ], + name: 'NewMintCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldMintCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newMintCapGuardian', + type: 'address', + }, + ], + name: 'NewMintCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'PlyGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'isSupply', + type: 'bool', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'SpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'newStatus', + type: 'bool', + }, + ], + name: 'WhitelistStatusChanged', + type: 'event', + }, + { + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantPly', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newMintCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketMintCaps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_maxAssets', type: 'uint256' }], + name: '_setMaxAssets', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newMintCapGuardian', + type: 'address', + }, + ], + name: '_setMintCapGuardian', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'rewardSpeeds', + type: 'uint256[]', + }, + { internalType: 'bool[]', name: 'isSupply', type: 'bool[]' }, + ], + name: '_setRewardSpeeds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + ], + name: '_supportMarket', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract AuToken', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract AuToken', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'aurora', + outputs: [ + { + internalType: 'contract EIP20Interface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { + internalType: 'contract AuToken', + name: 'auToken', + type: 'address', + }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address', name: 'holder', type: 'address' }, + ], + name: 'claimReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + ], + name: 'claimReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract AuToken[]', + name: 'auTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'auTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract AuToken[]', name: '', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { + internalType: 'contract AuToken[]', + name: 'assetsIn', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'auTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'initialIndexConstant', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'address', name: 'claimer', type: 'address' }, + ], + name: 'isAllowedToClaimReward', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'isWhitelisted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'auTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'auTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'auTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'auTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isPlyed', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'mintCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ply', + outputs: [ + { + internalType: 'contract EIP20Interface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pulp', + outputs: [ + { + internalType: 'contract PULPInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardAurora', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardClaimStart', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardPly', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + name: 'rewardRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'bool', name: '', type: 'bool' }, + ], + name: 'rewardSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'auTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'auTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract PULPInterface', + name: 'newPulp', + type: 'address', + }, + ], + name: 'setLockAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint32', + name: 'newRewardClaimStart', + type: 'uint32', + }, + ], + name: 'setRewardClaimStart', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract EIP20Interface', + name: 'newPly', + type: 'address', + }, + { + internalType: 'contract EIP20Interface', + name: 'newAurora', + type: 'address', + }, + ], + name: 'setTokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'addr', type: 'address' }, + { internalType: 'bool', name: 'whitelisted', type: 'bool' }, + ], + name: 'setWhitelisted', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'auToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/aurigami/ercDelegatorAbi.js b/src/adaptors/aurigami/ercDelegatorAbi.js new file mode 100644 index 0000000000..c5e43b6088 --- /dev/null +++ b/src/adaptors/aurigami/ercDelegatorAbi.js @@ -0,0 +1,885 @@ +module.exports = [ + { + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + { internalType: 'address payable', name: 'admin_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'BadInput', type: 'error' }, + { inputs: [], name: 'InvalidAccountPair', type: 'error' }, + { inputs: [], name: 'InvalidCloseAmountRequested', type: 'error' }, + { inputs: [], name: 'MarketNotFresh', type: 'error' }, + { inputs: [], name: 'TokenInsufficientCash', type: 'error' }, + { inputs: [], name: 'Unauthorized', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'auTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: '_acceptAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'accrueInterest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getBorrowDataOfAccount', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getSupplyDataOfOneAccount', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account1', type: 'address' }, + { internalType: 'address', name: 'account2', type: 'address' }, + ], + name: 'getSupplyDataOfTwoAccount', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'interestRateModel', + outputs: [ + { internalType: 'contract InterestRateModel', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isAuToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract AuTokenInterface', + name: 'auTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'supplyRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/aurigami/index.js b/src/adaptors/aurigami/index.js new file mode 100644 index 0000000000..19654011b6 --- /dev/null +++ b/src/adaptors/aurigami/index.js @@ -0,0 +1,243 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const comptrollerAbi = require('./comptrollerAbi'); +const ercDelegatorAbi = require('./ercDelegatorAbi'); +const auriLensAbi = require('./auriLensAbi'); + +const UNITROLLER_ADDRESS = '0x817af6cfAF35BdC1A634d6cC94eE9e4c68369Aeb'; +const auriLens = '0xFfdFfBDB966Cb84B50e62d70105f2Dbf2e0A1e70'; +const CHAIN = 'aurora'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'rewardSpeeds'; +const SUPPLY_RATE = 'supplyRatePerTimestamp'; +const BORROW_RATE = 'borrowRatePerTimestamp'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const SECONDS_PER_DAY = 86400; +const PROJECT_NAME = 'aurigami'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xC9BdeEd33CD01541e1eeD10f90519d2C06Fe3feB'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'COMP', + address: '0x09C9D464b58d96837f8d8b6f4d9fE4aD408d3A4f'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = SECONDS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market, i) => ({ + target: UNITROLLER_ADDRESS, + params: [i, market, false], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: UNITROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: UNITROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardSpeeds = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: allMarkets.map((market, i) => ({ + target: auriLens, + params: [UNITROLLER_ADDRESS, market], + })), + abi: auriLensAbi.find(({ name }) => name === 'getRewardSpeeds'), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const supplyRate = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegatorAbi + ); + + const borrowRate = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegatorAbi + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegatorAbi + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegatorAbi + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegatorAbi + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegatorAbi + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegatorAbi + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegatorAbi + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRate[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRate[i] / 10 ** 18); + + const apyReward = + (((rewardSpeeds[i].plyRewardSupplySpeed / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((rewardSpeeds[i].plyRewardBorrowSpeed / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalBorrowUsd) * + 100; + + return { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: Number.isFinite(apyRewardBorrow) + ? apyRewardBorrow + : null, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.aurigami.finance/', +}; diff --git a/src/adaptors/autofarm/index.js b/src/adaptors/autofarm/index.js new file mode 100644 index 0000000000..b2e63155e5 --- /dev/null +++ b/src/adaptors/autofarm/index.js @@ -0,0 +1,104 @@ +const superagent = require("superagent"); +const utils = require("../utils"); + +const chainsMapping = { + aurora: "aurora", + avax: "avalanche", + boba: "boba", + bsc: "binance", + celo: "celo", + cronos: "cronos", + evmos: "evmos", + fantom: "fantom", + gnosis: "xdai", + harmony: "harmony", + heco: "heco", + kcc: "kcc", + moonbeam: "moonbeam", + moonriver: "moonriver", + oasis: "oasis", + okc: "okexchain", + polygon: "polygon", + velas: "velas", + wanchain: "wanchain", +}; + +async function getAutofarmBuildId() { + const homeUrl = "https://autofarm.network/"; + const home = (await superagent.get(homeUrl)).text; + const start = home.indexOf('"buildId":'); + return home.slice(start + 11, start + 32); +} + +async function getMetadataRoot() { + const buildId = await getAutofarmBuildId(); + const url = `https://autofarm.network/_next/data/${buildId}/vaults.json`; + return (await superagent.get(url)).body.pageProps.initialFarmDataByChain; +} + +function formatPoolsApyChain(chain) { + // Lack of standardization inside autofarm data structures + if (chain === "gnosis") return "xdai"; + if (chain === "okc") return "okex"; + return chain; +} + +async function getPoolsApy(chain) { + const poolsUrl = `https://static.autofarm.network/${formatPoolsApyChain( + chain + )}/farm_data_live.json`; + return (await superagent.get(poolsUrl)).body; +} + +function cleanLP(text) { + return text.replace(" BLP", "").replace(" LP", ""); +} + +function autofarmApyItem(chain, item) { + return { + pool: `${item.wantAddress.toLowerCase()}-${item.pid}-${chainsMapping[chain]}-autofarm`, + chain: utils.formatChain(chainsMapping[chain]), + project: "autofarm", + symbol: utils.formatSymbol(cleanLP(item.wantName)), + poolMeta: item.farmName, + tvlUsd: Number(item.poolWantTVL), + apy: item.APY_total * 100, + underlyingTokens: [item.wantAddress], + }; +} + +async function autofarmApyAllItems() { + const metadataRoot = await getMetadataRoot(); + + // Iterate through hardcoded chains + const farmsByChain = await Promise.all( + Object.keys(chainsMapping).map(async (chain) => { + const poolsApy = await getPoolsApy(chain); + const poolsMetadata = metadataRoot[chain].pools; + + // Combine pool APY and Metadata in a single object + const pools = Object.keys(poolsMetadata) + .filter((key) => key != "tokens") // Removing extra info on json + .map((key) => { + return Object.assign({}, poolsMetadata[key], poolsApy[key]); + }); + + // Generate Llama's APY object for individual and depositable items + const activePools = pools.filter((v) => v.allowDeposits); + return activePools.map((item) => { + return autofarmApyItem(chain, item); + }); + }) + ); + + // Flatten list of lists + let farms = [].concat.apply([], farmsByChain); + + return farms.filter((p) => utils.keepFinite(p)); +} + +module.exports = { + timetravel: false, + apy: autofarmApyAllItems, + url: "https://autofarm.network/", +}; diff --git a/src/adaptors/autofinance/abis/Autopool.js b/src/adaptors/autofinance/abis/Autopool.js new file mode 100644 index 0000000000..8652c196f9 --- /dev/null +++ b/src/adaptors/autofinance/abis/Autopool.js @@ -0,0 +1,1393 @@ +module.exports = { + autopoolAbi: [ + { + inputs: [ + { + internalType: 'contract ISystemRegistry', + name: 'systemRegistry', + type: 'address', + }, + { internalType: 'address', name: '_vaultAsset', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AccessDenied', type: 'error' }, + { inputs: [], name: 'DepositFailed', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'maxDeposit', type: 'uint256' }, + ], + name: 'ERC4626DepositExceedsMax', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxRedeem', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxWithdraw', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'maxMint', type: 'uint256' }, + ], + name: 'ERC4626MintExceedsMax', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'deficit', type: 'uint256' }], + name: 'InsufficientFundsInDestinations', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'destination', type: 'address' }, + ], + name: 'InvalidDestination', + type: 'error', + }, + { inputs: [], name: 'InvalidDestinationVault', type: 'error' }, + { + inputs: [{ internalType: 'string', name: 'paramName', type: 'string' }], + name: 'InvalidParam', + type: 'error', + }, + { inputs: [], name: 'InvalidParams', type: 'error' }, + { + inputs: [ + { + internalType: 'enum IAutopool.VaultShutdownStatus', + name: 'status', + type: 'uint8', + }, + ], + name: 'InvalidShutdownStatus', + type: 'error', + }, + { inputs: [], name: 'InvalidUser', type: 'error' }, + { inputs: [], name: 'IsNotPaused', type: 'error' }, + { inputs: [], name: 'IsPaused', type: 'error' }, + { inputs: [], name: 'ItemExists', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'oldNav', type: 'uint256' }, + { internalType: 'uint256', name: 'newNav', type: 'uint256' }, + ], + name: 'NavChanged', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'oldNav', type: 'uint256' }, + { internalType: 'uint256', name: 'newNav', type: 'uint256' }, + ], + name: 'NavDecreased', + type: 'error', + }, + { inputs: [], name: 'NavOpsInProgress', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'destinationVault', type: 'address' }, + ], + name: 'RebalanceDestinationsMatch', + type: 'error', + }, + { + inputs: [{ internalType: 'string', name: 'message', type: 'string' }], + name: 'RebalanceFailed', + type: 'error', + }, + { inputs: [], name: 'ReentrancyGuardReentrantCall', type: 'error' }, + { + inputs: [{ internalType: 'string', name: 'item', type: 'string' }], + name: 'RegistryItemMissing', + type: 'error', + }, + { inputs: [], name: 'RewarderAlreadySet', type: 'error' }, + { inputs: [], name: 'UndefinedAddress', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + ], + name: 'ValueSharesMismatch', + type: 'error', + }, + { inputs: [], name: 'VaultShutdown', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'currentShares', type: 'uint256' }, + { internalType: 'uint256', name: 'cachedShares', type: 'uint256' }, + ], + name: 'WithdrawShareCalcInvalid', + type: 'error', + }, + { inputs: [], name: 'WithdrawalFailed', type: 'error' }, + { inputs: [], name: 'WithdrawalIncomplete', type: 'error' }, + { + inputs: [{ internalType: 'string', name: 'paramName', type: 'string' }], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'AddedToRemovalQueue', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debtValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'claimed', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'claimGasUsed', + type: 'uint256', + }, + ], + name: 'DestinationDebtReporting', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'DestinationVaultAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'DestinationVaultRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'fees', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'feeSink', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintedShares', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'profit', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'idle', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + ], + name: 'FeeCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'idle', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + ], + name: 'Nav', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'fees', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'feeSink', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintedShares', + type: 'uint256', + }, + ], + name: 'PeriodicFeeCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + ], + name: 'RemovedFromRemovalQueue', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newRewarder', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'oldRewarder', + type: 'address', + }, + ], + name: 'RewarderSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'enum IAutopool.VaultShutdownStatus', + name: 'reason', + type: 'uint8', + }, + ], + name: 'Shutdown', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + indexed: false, + internalType: 'string', + name: 'desc', + type: 'string', + }, + ], + name: 'SymbolAndDescSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'amounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'address[]', + name: 'destinations', + type: 'address[]', + }, + ], + name: 'TokensPulled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'amounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'address[]', + name: 'destinations', + type: 'address[]', + }, + ], + name: 'TokensRecovered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address[]', + name: 'destinations', + type: 'address[]', + }, + ], + name: 'WithdrawalQueueSet', + type: 'event', + }, + { + inputs: [], + name: 'DEAD_ADDRESS', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'FEE_DIVISOR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ONE', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'WETH_INIT_DEPOSIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'accessController', + outputs: [ + { + internalType: 'contract IAccessController', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'destinations', type: 'address[]' }, + ], + name: 'addDestinations', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'autoPoolStrategy', + outputs: [ + { + internalType: 'contract IAutopoolStrategy', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOfActual', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { + internalType: 'uint256', + name: 'totalAssetsForPurpose', + type: 'uint256', + }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'enum Math.Rounding', name: 'rounding', type: 'uint8' }, + ], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { + internalType: 'uint256', + name: 'totalAssetsForPurpose', + type: 'uint256', + }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'enum Math.Rounding', name: 'rounding', type: 'uint8' }, + ], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC3156FlashBorrower', + name: 'receiver', + type: 'address', + }, + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + internalType: 'struct IStrategy.RebalanceParams', + name: 'rebalanceParams', + type: 'tuple', + }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'flashRebalance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAssetBreakdown', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'totalIdle', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtMin', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtMax', type: 'uint256' }, + ], + internalType: 'struct IAutopool.AssetBreakdown', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtReportingQueue', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'destVault', type: 'address' }], + name: 'getDestinationInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'cachedDebtValue', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'cachedMinDebtValue', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'cachedMaxDebtValue', + type: 'uint256', + }, + { internalType: 'uint256', name: 'lastReport', type: 'uint256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + ], + internalType: 'struct AutopoolDebt.DestinationInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDestinations', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getFeeSettings', + outputs: [ + { + components: [ + { internalType: 'address', name: 'feeSink', type: 'address' }, + { + internalType: 'uint256', + name: 'totalAssetsHighMark', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalAssetsHighMarkTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastPeriodicFeeTake', + type: 'uint256', + }, + { + internalType: 'address', + name: 'periodicFeeSink', + type: 'address', + }, + { + internalType: 'uint256', + name: 'periodicFeeBps', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'streamingFeeBps', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'navPerShareLastFeeMark', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'navPerShareLastFeeMarkTimestamp', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'rebalanceFeeHighWaterMarkEnabled', + type: 'bool', + }, + ], + internalType: 'struct IAutopool.AutopoolFeeSettings', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPastRewarders', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getProfitUnlockSettings', + outputs: [ + { + components: [ + { + internalType: 'uint48', + name: 'unlockPeriodInSeconds', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'fullProfitUnlockTime', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'lastProfitUnlockTime', + type: 'uint48', + }, + { + internalType: 'uint256', + name: 'profitUnlockRate', + type: 'uint256', + }, + ], + internalType: 'struct IAutopool.ProfitUnlockSettings', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRemovalQueue', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getSystemRegistry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getWithdrawalQueue', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'strategy', type: 'address' }, + { internalType: 'string', name: 'symbolSuffix', type: 'string' }, + { internalType: 'string', name: 'descPrefix', type: 'string' }, + { internalType: 'bytes', name: '', type: 'bytes' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'dest', type: 'address' }], + name: 'isDestinationQueuedForRemoval', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'destination', type: 'address' }, + ], + name: 'isDestinationRegistered', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_pastRewarder', type: 'address' }, + ], + name: 'isPastRewarder', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isShutdown', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'wallet', type: 'address' }], + name: 'maxDeposit', + outputs: [ + { internalType: 'uint256', name: 'maxAssets', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'wallet', type: 'address' }], + name: 'maxMint', + outputs: [ + { internalType: 'uint256', name: 'maxShares', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [ + { internalType: 'uint256', name: 'maxShares', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [ + { internalType: 'uint256', name: 'maxAssets', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oldestDebtReporting', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'tokens', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'address[]', name: 'destinations', type: 'address[]' }, + ], + name: 'recover', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'destinations', type: 'address[]' }, + ], + name: 'removeDestinations', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewarder', + outputs: [ + { internalType: 'contract IMainRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newFeeSink', type: 'address' }, + ], + name: 'setFeeSink', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'fee', type: 'uint256' }], + name: 'setPeriodicFeeBps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newPeriodicFeeSink', + type: 'address', + }, + ], + name: 'setPeriodicFeeSink', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint48', + name: 'newUnlockPeriodSeconds', + type: 'uint48', + }, + ], + name: 'setProfitUnlockPeriod', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'enabled', type: 'bool' }], + name: 'setRebalanceFeeHighWaterMarkEnabled', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_rewarder', type: 'address' }], + name: 'setRewarder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'fee', type: 'uint256' }], + name: 'setStreamingFeeBps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: 'newSymbol', type: 'string' }, + { internalType: 'string', name: 'newName', type: 'string' }, + ], + name: 'setSymbolAndDescAfterShutdown', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'enum IAutopool.VaultShutdownStatus', + name: 'reason', + type: 'uint8', + }, + ], + name: 'shutdown', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'shutdownStatus', + outputs: [ + { + internalType: 'enum IAutopool.VaultShutdownStatus', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'enum IAutopool.TotalAssetPurpose', + name: 'purpose', + type: 'uint8', + }, + ], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unlockedShares', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'numToProcess', type: 'uint256' }, + ], + name: 'updateDebtReporting', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'vaultType', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/autofinance/abis/AutopoolETHStrategy.js b/src/adaptors/autofinance/abis/AutopoolETHStrategy.js new file mode 100644 index 0000000000..524c763e0a --- /dev/null +++ b/src/adaptors/autofinance/abis/AutopoolETHStrategy.js @@ -0,0 +1,1108 @@ +module.exports = { + autopoolETHStrategyAbi: [ + { + inputs: [ + { + internalType: 'contract ISystemRegistry', + name: '_systemRegistry', + type: 'address', + }, + { + components: [ + { + components: [ + { internalType: 'uint16', name: 'initInDays', type: 'uint16' }, + { + internalType: 'uint16', + name: 'tightenThresholdInViolations', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'tightenStepInDays', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'relaxThresholdInDays', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'relaxStepInDays', + type: 'uint16', + }, + { internalType: 'uint16', name: 'maxInDays', type: 'uint16' }, + { internalType: 'uint16', name: 'minInDays', type: 'uint16' }, + ], + internalType: + 'struct AutopoolETHStrategyConfig.SwapCostOffsetConfig', + name: 'swapCostOffset', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint8', + name: 'lookback1InDays', + type: 'uint8', + }, + { + internalType: 'uint8', + name: 'lookback2InDays', + type: 'uint8', + }, + { + internalType: 'uint8', + name: 'lookback3InDays', + type: 'uint8', + }, + ], + internalType: + 'struct AutopoolETHStrategyConfig.NavLookbackConfig', + name: 'navLookback', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'maxNormalOperationSlippage', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxTrimOperationSlippage', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxEmergencyOperationSlippage', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxShutdownOperationSlippage', + type: 'uint256', + }, + ], + internalType: 'struct AutopoolETHStrategyConfig.SlippageConfig', + name: 'slippage', + type: 'tuple', + }, + { + components: [ + { internalType: 'uint256', name: 'baseYield', type: 'uint256' }, + { internalType: 'uint256', name: 'feeYield', type: 'uint256' }, + { + internalType: 'uint256', + name: 'incentiveYield', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'priceDiscountExit', + type: 'int256', + }, + { + internalType: 'int256', + name: 'priceDiscountEnter', + type: 'int256', + }, + { + internalType: 'int256', + name: 'pricePremium', + type: 'int256', + }, + ], + internalType: 'struct AutopoolETHStrategyConfig.ModelWeights', + name: 'modelWeights', + type: 'tuple', + }, + { + internalType: 'uint16', + name: 'pauseRebalancePeriodInDays', + type: 'uint16', + }, + { + internalType: 'uint256', + name: 'rebalanceTimeGapInSeconds', + type: 'uint256', + }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { + internalType: 'uint40', + name: 'staleDataToleranceInSeconds', + type: 'uint40', + }, + { + internalType: 'int256', + name: 'maxAllowedDiscount', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'lstPriceGapTolerance', + type: 'uint256', + }, + { internalType: 'address[5]', name: 'hooks', type: 'address[5]' }, + ], + internalType: 'struct AutopoolETHStrategyConfig.StrategyConfig', + name: 'conf', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AccessDenied', type: 'error' }, + { inputs: [], name: 'CannotConvertUintToInt', type: 'error' }, + { inputs: [], name: 'CannotConvertUintToInt', type: 'error' }, + { inputs: [], name: 'IdleHighThresholdViolated', type: 'error' }, + { inputs: [], name: 'InconsistentIdleThresholds', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'InsufficientAssets', + type: 'error', + }, + { + inputs: [{ internalType: 'string', name: 'paramName', type: 'string' }], + name: 'InvalidConfig', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint40', name: 'current', type: 'uint40' }, + { internalType: 'uint40', name: 'provided', type: 'uint40' }, + ], + name: 'InvalidNavTimestamp', + type: 'error', + }, + { + inputs: [{ internalType: 'string', name: 'paramName', type: 'string' }], + name: 'InvalidParam', + type: 'error', + }, + { inputs: [], name: 'InvalidRebalanceToIdle', type: 'error' }, + { inputs: [], name: 'LSTPriceGapToleranceExceeded', type: 'error' }, + { inputs: [], name: 'MaxDiscountExceeded', type: 'error' }, + { inputs: [], name: 'MaxPremiumExceeded', type: 'error' }, + { inputs: [], name: 'MaxSlippageExceeded', type: 'error' }, + { inputs: [], name: 'NavHistoryInsufficient', type: 'error' }, + { inputs: [], name: 'NotAutopoolETH', type: 'error' }, + { inputs: [], name: 'OnlyRebalanceToIdleAvailable', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'address', name: 'trueUnderlyer', type: 'address' }, + { internalType: 'address', name: 'providedUnderlyer', type: 'address' }, + ], + name: 'RebalanceDestinationUnderlyerMismatch', + type: 'error', + }, + { inputs: [], name: 'RebalanceDestinationsMatch', type: 'error' }, + { inputs: [], name: 'RebalanceTimeGapNotMet', type: 'error' }, + { + inputs: [{ internalType: 'string', name: 'name', type: 'string' }], + name: 'StaleData', + type: 'error', + }, + { inputs: [], name: 'StrategyPaused', type: 'error' }, + { inputs: [], name: 'SwapCostExceeded', type: 'error' }, + { inputs: [], name: 'SystemRegistryMismatch', type: 'error' }, + { inputs: [], name: 'UndefinedAddress', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'dest', type: 'address' }], + name: 'UnregisteredDestination', + type: 'error', + }, + { + inputs: [{ internalType: 'string', name: 'paramName', type: 'string' }], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'assetIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'numViolationsOne', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'numViolationsTwo', + type: 'uint256', + }, + { + indexed: false, + internalType: 'int256', + name: 'discount', + type: 'int256', + }, + ], + name: 'DestTrimRebalanceDetails', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'trimAmount', + type: 'uint256', + }, + ], + name: 'DestViolationMaxTrimAmount', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newValue', + type: 'uint256', + }, + ], + name: 'DustPositionPortionSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newLowValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newHighValue', + type: 'uint256', + }, + ], + name: 'IdleThresholdsSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newPriceGap', + type: 'uint256', + }, + ], + name: 'LstPriceGapSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'navPerShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nav1', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nav2', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nav3', + type: 'uint256', + }, + ], + name: 'PauseStart', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'PauseStop', type: 'event' }, + { + anonymous: false, + inputs: [ + { + components: [ + { internalType: 'uint256', name: 'inPrice', type: 'uint256' }, + { internalType: 'uint256', name: 'outPrice', type: 'uint256' }, + { internalType: 'uint256', name: 'inEthValue', type: 'uint256' }, + { internalType: 'uint256', name: 'outEthValue', type: 'uint256' }, + { internalType: 'uint256', name: 'swapCost', type: 'uint256' }, + { internalType: 'uint256', name: 'slippage', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct SummaryStats.RebalanceValueStats', + name: 'valueStats', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct IStrategy.RebalanceParams', + name: 'params', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct IStrategy.SummaryStats', + name: 'outSummaryStats', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct IStrategy.SummaryStats', + name: 'inSummaryStats', + type: 'tuple', + }, + { + indexed: false, + internalType: 'uint256', + name: 'swapOffsetPeriod', + type: 'uint256', + }, + { + indexed: false, + internalType: 'int256', + name: 'predictedAnnualizedGain', + type: 'int256', + }, + ], + name: 'RebalanceBetweenDestinations', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + components: [ + { internalType: 'uint256', name: 'inPrice', type: 'uint256' }, + { internalType: 'uint256', name: 'outPrice', type: 'uint256' }, + { internalType: 'uint256', name: 'inEthValue', type: 'uint256' }, + { internalType: 'uint256', name: 'outEthValue', type: 'uint256' }, + { internalType: 'uint256', name: 'swapCost', type: 'uint256' }, + { internalType: 'uint256', name: 'slippage', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct SummaryStats.RebalanceValueStats', + name: 'valueStats', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct IStrategy.SummaryStats', + name: 'outSummary', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + indexed: false, + internalType: 'struct IStrategy.RebalanceParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'RebalanceToIdle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'enum AutopoolETHStrategy.RebalanceToIdleReasonEnum', + name: 'reason', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint256', + name: 'maxSlippage', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'slippage', + type: 'uint256', + }, + ], + name: 'RebalanceToIdleReason', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { + indexed: false, + internalType: 'uint40', + name: 'lastRebalanceTimestamp', + type: 'uint40', + }, + { + indexed: false, + internalType: 'uint40', + name: 'lastTimestampAddedToDestination', + type: 'uint40', + }, + { + indexed: false, + internalType: 'uint40', + name: 'swapCostOffsetPeriod', + type: 'uint40', + }, + ], + name: 'SuccessfulRebalanceBetweenDestinations', + type: 'event', + }, + { + inputs: [], + name: 'accessController', + outputs: [ + { + internalType: 'contract IAccessController', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'autoPool', + outputs: [ + { internalType: 'contract IAutopool', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'defaultLstPriceGapTolerance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'dustPositionPortions', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'expiredRewardTolerance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'destAddress', type: 'address' }, + { + internalType: 'enum IAutopoolStrategy.RebalanceDirection', + name: 'direction', + type: 'uint8', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'getDestinationSummaryStats', + outputs: [ + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + internalType: 'struct IStrategy.SummaryStats', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getHooks', + outputs: [ + { internalType: 'address[]', name: 'hooks', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + internalType: 'struct IStrategy.RebalanceParams', + name: 'rebalanceParams', + type: 'tuple', + }, + ], + name: 'getRebalanceOutSummaryStats', + outputs: [ + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + internalType: 'struct IStrategy.SummaryStats', + name: 'outSummary', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getSystemRegistry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'idleHighThreshold', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'idleLowThreshold', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_autoPool', type: 'address' }], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastAddTimestampByDestination', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastPausedTimestamp', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastRebalanceTimestamp', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lstPriceGapTolerance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxAllowedDiscount', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxDiscount', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxEmergencyOperationSlippage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxNormalOperationSlippage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxPremium', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxShutdownOperationSlippage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxTrimOperationSlippage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'navLookback1InDays', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'navLookback2InDays', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'navLookback3InDays', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'navTrackingState', + outputs: [ + { internalType: 'uint8', name: 'len', type: 'uint8' }, + { internalType: 'uint8', name: 'currentIndex', type: 'uint8' }, + { + internalType: 'uint40', + name: 'lastFinalizedTimestamp', + type: 'uint40', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'navPerShare', type: 'uint256' }, + ], + name: 'navUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseRebalancePeriodInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + internalType: 'struct IStrategy.RebalanceParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'rebalanceSuccessfullyExecuted', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rebalanceTimeGapInSeconds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newValue', type: 'uint256' }], + name: 'setDustPositionPortions', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newLowValue', type: 'uint256' }, + { internalType: 'uint256', name: 'newHighValue', type: 'uint256' }, + ], + name: 'setIdleThresholds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'priceGapTolerance', type: 'uint256' }, + ], + name: 'setLstPriceGapTolerance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'staleDataToleranceInSeconds', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetInit', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetInitInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetMaxInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetMinInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetPeriodInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetRelaxStepInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetRelaxThresholdInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetTightenStepInDays', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'swapCostOffsetTightenThresholdInViolations', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'destinationIn', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { + internalType: 'address', + name: 'destinationOut', + type: 'address', + }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + internalType: 'struct IStrategy.RebalanceParams', + name: 'params', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'baseApr', type: 'uint256' }, + { internalType: 'uint256', name: 'feeApr', type: 'uint256' }, + { internalType: 'uint256', name: 'incentiveApr', type: 'uint256' }, + { + internalType: 'uint256', + name: 'safeTotalSupply', + type: 'uint256', + }, + { internalType: 'int256', name: 'priceReturn', type: 'int256' }, + { internalType: 'int256', name: 'maxDiscount', type: 'int256' }, + { internalType: 'int256', name: 'maxPremium', type: 'int256' }, + { internalType: 'uint256', name: 'ownedShares', type: 'uint256' }, + { internalType: 'int256', name: 'compositeReturn', type: 'int256' }, + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + internalType: 'struct IStrategy.SummaryStats', + name: 'outSummary', + type: 'tuple', + }, + ], + name: 'verifyRebalance', + outputs: [ + { internalType: 'bool', name: 'success', type: 'bool' }, + { internalType: 'string', name: 'message', type: 'string' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'violationTrackingState', + outputs: [ + { internalType: 'uint8', name: 'violationCount', type: 'uint8' }, + { internalType: 'uint8', name: 'len', type: 'uint8' }, + { internalType: 'uint16', name: 'violations', type: 'uint16' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightBase', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightPriceDiscountEnter', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightPriceDiscountExit', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'weightPricePremium', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/autofinance/abis/ERC20.js b/src/adaptors/autofinance/abis/ERC20.js new file mode 100644 index 0000000000..66454852fc --- /dev/null +++ b/src/adaptors/autofinance/abis/ERC20.js @@ -0,0 +1,125 @@ +module.exports = { + erc20Abi: [ + { + type: 'function', + name: 'allowance', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { name: 'to', type: 'address', indexed: true, internalType: 'address' }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + ], +}; diff --git a/src/adaptors/autofinance/index.js b/src/adaptors/autofinance/index.js new file mode 100644 index 0000000000..dc241fda6d --- /dev/null +++ b/src/adaptors/autofinance/index.js @@ -0,0 +1,58 @@ +const axios = require('axios'); + +async function getPoolsForSystem(settings) { + const { data } = await axios.get( + `https://autopools-api.tokemaklabs.com/api/${settings.chainId}/${settings.systemName}` + ); + + const pools = data.autopools.map((pool) => { + const rewardTokens = new Set(pool.rewards.map((x) => x.rewardToken)); + const apyReward = pool.rewards.reduce((p, c) => { + return p + c.rewardApy; + }, 0); + + return { + pool: pool.id, + chain: settings.chainName, + project: 'autofinance', + symbol: pool.baseAssetSymbol, + tvlUsd: Number(pool.tvlUsd), + rewardTokens: Array.from(rewardTokens), + underlyingTokens: [pool.baseAssetId], + apyBase: Number(pool.baseApy), + apyReward: apyReward, + url: 'https://app.auto.finance/autopool?id=' + pool.id, + poolMeta: pool.symbol, + }; + }); + + return pools; +} + +async function main() { + const { data } = await axios.get( + 'https://v2-config.tokemaklabs.com/api/systems' + ); + const systems = data + .filter((x) => x.publishToDefillama) + .map((x) => { + return { + chainId: Number(x.chainId), + systemName: x.systemName, + chainName: x.chainName, + }; + }); + + const pools = []; + for (const system of systems) { + pools.push(...(await getPoolsForSystem(system))); + } + console.log(pools); + return pools; +} + +module.exports = { + timeTravel: false, + apy: main, + url: 'https://app.auto.finance', +}; diff --git a/src/adaptors/avalon-finance/index.js b/src/adaptors/avalon-finance/index.js new file mode 100644 index 0000000000..3866668db6 --- /dev/null +++ b/src/adaptors/avalon-finance/index.js @@ -0,0 +1,157 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('../aave-v3/poolAbi'); + +const protocolDataProviders = { + bob: '0xfabb0fDca4348d5A40EB1BB74AEa86A1C4eAd7E2', +}; + +const getApy = async (market) => { + const chain = market; + + const protocolDataProvider = protocolDataProviders[market]; + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + const totalBorrowUsd = totalSupplyUsd - tvlUsd; + + const marketUrlParam = + market === 'ethereum' + ? 'mainnet' + : market === 'avax' + ? 'avalanche' + : market === 'xdai' + ? 'gnosis' + : market === 'bsc' + ? 'bnb' + : market; + + const url = `https:/lend.avalonfinance.xyz/reserve-overview/?underlyingAsset=${pool.tokenAddress.toLowerCase()}&marketName=proto_${marketUrlParam}_v3`; + + return { + pool: `${aTokens[i].tokenAddress}-${ + market === 'avax' ? 'avalanche' : market + }`.toLowerCase(), + chain, + project: 'avalon-finance', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + url, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + }; + }) + .filter((i) => Boolean(i)); +}; + + +const apy = async () => { + const pools = await Promise.allSettled( + Object.keys(protocolDataProviders).map(async (market) => getApy(market)) + ); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/avant-avbtc/index.js b/src/adaptors/avant-avbtc/index.js new file mode 100644 index 0000000000..762c8e4e2d --- /dev/null +++ b/src/adaptors/avant-avbtc/index.js @@ -0,0 +1,29 @@ +const { getData } = require('../avant-aveth/shared') + +// Avalanche tokens +const avBTC = '0xfd2c2A98009d0cBed715882036e43d26C4289053' +const savBTC = '0x649342c6bff544d82DF1B2bA3C93e0C22cDeBa84' // Staked avBTC (ERC-4626) + +async function apy() { + const savBTCData = await getData('avax', savBTC, avBTC) + + return [ + { + pool: `${savBTC}-avax`, + chain: 'avax', + project: 'avant-avbtc', + symbol: 'savBTC', + tvlUsd: savBTCData.tvlUsd, + apyBase: savBTCData.apyBase, + underlyingTokens: [avBTC], + poolMeta: 'ERC-4626: savBTC → avBTC', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} diff --git a/src/adaptors/avant-aveth/index.js b/src/adaptors/avant-aveth/index.js new file mode 100644 index 0000000000..89bfbbc123 --- /dev/null +++ b/src/adaptors/avant-aveth/index.js @@ -0,0 +1,30 @@ +const { getData } = require('./shared') + +// Ethereum tokens +const avETH = '0x9469470C9878bf3d6d0604831d9A3A366156f7EE' +const savETH = '0xDA06eE2dACF9245Aa80072a4407deBDea0D7e341' // Staked avETH (ERC-4626) +const wETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + +async function apy() { + const savETHData = await getData('ethereum', savETH, avETH, wETH) + + return [ + { + pool: `${savETH}-ethereum`, + chain: 'ethereum', + project: 'avant-aveth', + symbol: 'savETH', + tvlUsd: savETHData.tvlUsd, + apyBase: savETHData.apyBase, + underlyingTokens: [avETH], + poolMeta: 'ERC-4626: savETH → avETH', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} diff --git a/src/adaptors/avant-aveth/shared.js b/src/adaptors/avant-aveth/shared.js new file mode 100644 index 0000000000..6659d7cb4b --- /dev/null +++ b/src/adaptors/avant-aveth/shared.js @@ -0,0 +1,94 @@ +const sdk = require('@defillama/sdk') +const axios = require('axios') +const utils = require('../utils') + +const abi = { + convertToAssets: { "inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function" }, + totalAssets: { "inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"" ,"type":"uint256"}],"stateMutability":"view","type":"function" }, +} + +const DAY = 86_400 +const SCALE = BigInt(1e18) +const SHARES = BigInt(1e18) + +async function getBlockAtTimestamp(chain, ts) { + const { data } = await axios.get(`https://coins.llama.fi/block/${chain}/${ts}`) + return { block: data.height || data.number, ts: data.timestamp || ts } +} + +async function readShareToAssetRatio(chain, blockNumber, vault) { + const { output } = await sdk.api.abi.call({ + target: vault, + abi: abi.convertToAssets, + params: [SHARES.toString()], + chain, + block: blockNumber, + }) + return BigInt(output) +} + +function ratioToDaily(rNow, rPrev, secondsBigOrNum) { + if (rPrev === 0n || rNow === 0n) return 0 + const qFP = (rNow * SCALE) / rPrev + const q = Number(qFP) / Number(SCALE) + if (!(q > 0) || !isFinite(q)) return 0 + const seconds = Number(secondsBigOrNum) || 1 + const exp = DAY / seconds + return Math.pow(q, exp) - 1 +} + +async function computeApyBase(chain, vault) { + const nowTs = Math.floor(Date.now() / 1e3) + const WEEK = 7 * DAY + + const [{ block: bNow, ts: tNow }, { block: bPast, ts: tPast }] = await Promise.all([ + getBlockAtTimestamp(chain, nowTs), + getBlockAtTimestamp(chain, nowTs - WEEK), + ]) + + const [rNow, rPast] = await Promise.all([ + readShareToAssetRatio(chain, bNow, vault), + readShareToAssetRatio(chain, bPast, vault) + ]) + if (rNow === 0n || rPast === 0n || rNow === rPast) return 0 + + const daily = ratioToDaily(rNow, rPast, Math.max(1, tNow - tPast)) + if (!daily) return 0 + + const aprBase = daily * 365 * 100 + return utils.aprToApy(aprBase, 365) // number +} + +async function getPrice(chain, token, tokenSubstitute) { + async function _getPrice(chain, tokenAddress) { + const priceKey = `${chain}:${tokenAddress}` + const { data } = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + price = data.coins?.[priceKey]?.price ?? 0 + return price + } + const price = await _getPrice(chain, token) + if (price) { + return price + } else if (tokenSubstitute) { + return await _getPrice(chain, tokenSubstitute) + } + return 1 +} + +async function getData(chain, vault, underlying, underlyingSubstitute = undefined) { + const { output: totalAssetsBn } = await sdk.api.abi.call({ + target: vault, + abi: abi.totalAssets, + chain, + }) + + const price = await getPrice(chain, underlying, underlyingSubstitute) + const tvlUsd = (Number(totalAssetsBn) / 1e18) * price + const apyBase = await computeApyBase(chain, vault) + + return { tvlUsd, apyBase } +} + +module.exports = { + getData, +} diff --git a/src/adaptors/avant-avusd/index.js b/src/adaptors/avant-avusd/index.js new file mode 100644 index 0000000000..39b9a1417b --- /dev/null +++ b/src/adaptors/avant-avusd/index.js @@ -0,0 +1,29 @@ +const { getData } = require('../avant-aveth/shared') + +// Avalanche tokens +const avUSD = '0x24dE8771bC5DdB3362Db529Fc3358F2df3A0E346' +const savUSD = '0x06d47F3fb376649c3A9Dafe069B3D6E35572219E' // Staked avUSD (ERC-4626) + +async function apy() { + const savUSDData = await getData('avax', savUSD, avUSD) + + return [ + { + pool: `${savUSD}-avax`, + chain: 'avax', + project: 'avant-avusd', + symbol: 'savUSD', + tvlUsd: savUSDData.tvlUsd, + apyBase: savUSDData.apyBase, + underlyingTokens: [avUSD], + poolMeta: 'ERC-4626: savUSD → avUSD', + url: 'https://www.avantprotocol.com', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.avantprotocol.com', +} diff --git a/src/adaptors/avantis/index.js b/src/adaptors/avantis/index.js new file mode 100644 index 0000000000..275770bb8f --- /dev/null +++ b/src/adaptors/avantis/index.js @@ -0,0 +1,47 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { getBlocksByTime, getData } = require('../utils'); + +const ADDRESSES = { + base: { + AvantisVault: '0x944766f715b51967E56aFdE5f0Aa76cEaCc9E7f9', + USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, +}; + +const main = async (timestamp = null) => { + const { meta } = await getData( + 'https://api.avantisfi.com/v1/vault/returns-7-days' + ); + + let vaultTvl = await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.USDC, + params: [ADDRESSES.base.AvantisVault], + chain: 'base', + // block: block, + }); + + vaultTvl = vaultTvl.output / 1e6; + + const dailyReturns = meta.averageJrFees / vaultTvl; + const apy = (1 + dailyReturns) ** 365 - 1; + + return [ + { + pool: `AVANTIS-${ADDRESSES.base.AvantisVault}-base`.toLowerCase(), + chain: 'base', + project: 'avantis', + symbol: 'USDC', + poolMeta: 'vault', + tvlUsd: vaultTvl, + apyBase: apy * 100, + url: 'https://www.avantisfi.com/earn/avantis-vault', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/avault/index.js b/src/adaptors/avault/index.js new file mode 100644 index 0000000000..afe8475b58 --- /dev/null +++ b/src/adaptors/avault/index.js @@ -0,0 +1,13 @@ +const axios = require('axios'); + +const main = async () => { + const res = (await axios.get('https://www.avault.network/api/v0/yield/info')) + .data.data; + return res; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.avault.network/vault', +}; diff --git a/src/adaptors/azuro/index.js b/src/adaptors/azuro/index.js new file mode 100644 index 0000000000..f7c1736135 --- /dev/null +++ b/src/adaptors/azuro/index.js @@ -0,0 +1,71 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); + +const CHAINS = { + gnosis: 'Gnosis', + polygon: 'PolygonUSDT', + chiliz: 'Chiliz', +}; + +const getUrl = (chain) => + `https://thegraph.azuro.org/subgraphs/name/azuro-protocol/azuro-api-${chain}-v3`; + +const aprUrl = "https://api.azuro.org/apr"; + +const query = gql` + { + liquidityPoolContracts( + where: {address_not_in: ["0x2a838ab9b037db117576db8d0dcc3b686748ef7c", "0xac004b512c33d029cf23abf04513f1f380b3fd0a"]} + ) { + apr + address + asset + chainId + chainName + coreAddresses + token + tvl + } + } +`; + +const fetchAprData = async () => { + const { data } = await utils.getData(aprUrl); + return data; +}; + +const fetchLiquidityPools = async (chain) => { + const { liquidityPoolContracts } = await request(getUrl(chain), query); + return liquidityPoolContracts; +}; + +const poolsFunction = async () => { + const aprData = await fetchAprData(); + + let pools = []; + + for (const chain of Object.keys(CHAINS)) { + const liquidityPools = await fetchLiquidityPools(chain); + + liquidityPools.forEach(pool => { + const apr = aprData.find(aprItem => aprItem.chain === CHAINS[chain]); + pools.push({ + pool: pool.address, + chain: chain, + project: 'azuro', + symbol: utils.formatSymbol(pool.asset), + tvlUsd: Number(pool.tvl), + apyBase: apr ? Number(apr.aprDayAgo) : Number(pool.apr), + poolMeta: '7 day lockup', + }); + }); + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://azuro.org/app/liquidity', +}; diff --git a/src/adaptors/b14g/index.js b/src/adaptors/b14g/index.js new file mode 100644 index 0000000000..8cf1f645c5 --- /dev/null +++ b/src/adaptors/b14g/index.js @@ -0,0 +1,568 @@ +const sdk = require('@defillama/sdk'); +const STAKING_CONTRACT = '0xee21ab613d30330823D35Cf91A84cE964808B83F'; +const MARKETPLACE_CONTRACT = '0x04EA61C431F7934d51fEd2aCb2c5F942213f8967'; +const WBTC_VAULT_CONTRACT = '0xa3CD4D4A568b76CFF01048E134096D2Ba0171C27'; +const { getLatestBlock } = require('@defillama/sdk/build/util'); +const { getPrices } = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const { RateLimiter } = require('limiter'); + +const url = (addrs) => + 'https://blockchain.info/multiaddr?active=' + addrs.join('|'); + +const delay = 3 * 60 * 60; // 3 hours + +const limiter = new RateLimiter({ tokensPerInterval: 1, interval: 10_000 }); + +async function _sumTokensBlockchain({ balances = {}, owners = [] }) { + console.time('bitcoin' + owners.length + '___' + owners[0]); + const STEP = 200; + for (let i = 0; i < owners.length; i += STEP) { + const { + data: { addresses }, + } = await fetchURL(url(owners.slice(i, i + STEP))); + for (const addr of addresses) + sdk.util.sumSingleBalance(balances, 'bitcoin', addr.final_balance / 1e8); + } + + console.timeEnd('bitcoin' + owners.length + '___' + owners[0]); + return balances; +} + +const withLimiter = + (fn, tokensToRemove = 1) => + async (...args) => { + await limiter.removeTokens(tokensToRemove); + return fn(...args); + }; + +const sumTokensBlockchain = withLimiter(_sumTokensBlockchain); + +async function sumTokens({ balances = {}, owners = [], timestamp }) { + if (typeof timestamp === 'object' && timestamp.timestamp) + timestamp = timestamp.timestamp; + const now = Date.now() / 1e3; + + if (!timestamp || now - timestamp < delay) { + try { + await sumTokensBlockchain({ balances, owners }); + return balances; + } catch (e) { + sdk.log('bitcoin sumTokens error', e.toString()); + } + } +} + +function reserveBytes(txHashTemp) { + let txHash = ''; + if (txHashTemp.length % 2 === 1) { + txHashTemp = '0' + txHashTemp; + } + txHashTemp = txHashTemp.split('').reverse().join(''); + for (let i = 0; i < txHashTemp.length - 1; i += 2) { + txHash += txHashTemp[i + 1] + txHashTemp[i]; + } + return txHash; +} + +const totalBTC = async () => { + const btcTxHashLockApi = + 'https://api.b14g.xyz/restake/marketplace/defillama/btc-tx-hash'; + const { + data: { + data: { result }, + }, + } = await fetchURL(btcTxHashLockApi); + const hashes = result.map((r) => r.txHash); + const hashMap = {}; + for (const hash of hashes) { + const addresses = []; + const { data: tx } = await fetchURL( + `https://mempool.space/api/tx/${reserveBytes(hash.slice(2))}` + ); + let vinAddress = tx.vin.map((el) => el.prevout.scriptpubkey_address); + tx.vout.forEach((el) => { + if ( + el.scriptpubkey_type !== 'op_return' && + !vinAddress.includes(el.scriptpubkey_address) + ) { + addresses.push(el.scriptpubkey_address); + } + }); + hashMap[hash] = addresses; + } + const owners = [...new Set(Object.values(hashMap).flat())]; + return await sumTokens({ owners }); +}; + +const exchangeRateAbi = { + inputs: [ + { + internalType: 'uint256', + name: '_dualCore', + type: 'uint256', + }, + ], + name: 'exchangeCore', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', +}; + +const getTurnRoundBlockNumber = async (blockNumber) => { + const roundTag = ( + await sdk.api.abi.call({ + target: '0x0000000000000000000000000000000000001005', + chain: 'core', + abi: 'uint256:roundTag', + }) + ).output; + return ( + await sdk.api.util.getLogs({ + keys: [], + chain: 'core', + target: '0x0000000000000000000000000000000000001005', + topic: 'turnedRound(uint256)', + fromBlock: blockNumber.block - 86400, + toBlock: blockNumber.block, + }) + ).output.filter( + (el) => parseInt(el.data) === parseInt(roundTag.toString()) + )[0].blockNumber; +}; + +const getCORERewardForBTCHolderPerDay = async (blockNumber) => { + //get all order + let allOrder = ( + await sdk.api.util.getLogs({ + keys: [], + chain: 'core', + target: MARKETPLACE_CONTRACT, + topic: 'CreateRewardReceiver(address,address,uint256,uint256)', + fromBlock: 19942300, + toBlock: blockNumber.block, + }) + ).output.map((el) => { + return { + order: el.topics[2].replace('000000000000000000000000', ''), + owner: el.topics[1].replace('000000000000000000000000', ''), + }; + }); + + //filter order active, remove expired + let listTxHash = []; + let listOrderActive = ( + await sdk.api.abi.multiCall({ + abi: { + outputs: [{ name: '', internalType: 'bytes32[]', type: 'bytes32[]' }], + inputs: [ + { name: 'delegator', internalType: 'address', type: 'address' }, + ], + name: 'getTxIdsByDelegator', + stateMutability: 'view', + type: 'function', + }, + calls: allOrder.map((el) => { + return { + target: '0x0000000000000000000000000000000000001014', + params: [el.order], + }; + }), + chain: 'core', + }) + ).output + .map((el, index) => { + return { + ...el, + order: allOrder[index].order, + owner: allOrder[index].owner, + }; + }) + .filter((order) => { + listTxHash = listTxHash.concat(order.output); + return order.output.length > 0; + }); + + // total BTC stake in order + let btcStake = + ( + await sdk.api.abi.multiCall({ + abi: { + outputs: [ + { name: 'amount', internalType: 'uint64', type: 'uint64' }, + { + name: 'outputIndex', + internalType: 'uint32', + type: 'uint32', + }, + { name: 'blockTimestamp', internalType: 'uint64', type: 'uint64' }, + { + name: 'lockTime', + internalType: 'uint32', + type: 'uint32', + }, + { name: 'usedHeight', internalType: 'uint32', type: 'uint32' }, + ], + inputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + name: 'btcTxMap', + stateMutability: 'view', + type: 'function', + }, + calls: listTxHash.map((el) => { + return { + target: '0x0000000000000000000000000000000000001014', + params: [el], + }; + }), + chain: 'core', + }) + ).output.reduce((acc, el) => acc + parseInt(el.output.amount), 0) / 1e8; + let turnRoundBlockNumber = await getTurnRoundBlockNumber(blockNumber); + + let rewardBTCBeforeTurnround = ( + await sdk.api.abi.multiCall({ + abi: 'uint256:pendingRewardForBTC', + calls: listOrderActive.map((el) => { + return { + target: el.order, + }; + }), + block: turnRoundBlockNumber, + chain: 'core', + }) + ).output.reduce((acc, el) => acc + parseInt(el.output), 0); + let rewardBTCAfterTurnround = ( + await sdk.api.abi.multiCall({ + abi: { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'txHash', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + internalType: 'struct Marketplace.ClaimParamOnBehalf[]', + name: 'claimParam', + type: 'tuple[]', + }, + ], + name: 'claimBTCRewardProxyOnBehalf', + outputs: [ + { + internalType: 'uint256[]', + name: 'amounts', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + calls: listOrderActive.map((el) => { + return { + params: [ + [{ receiver: el.order, txHash: el.output[0], to: el.owner }], + ], + target: MARKETPLACE_CONTRACT, + }; + }), + block: turnRoundBlockNumber + 1, + chain: 'core', + chunkSize: 20, + permitFailure: true, + }) + ).output.reduce((acc, el) => acc + parseInt(el.output), 0); + return { + reward: (rewardBTCAfterTurnround - rewardBTCBeforeTurnround) / 1e18, + btcStake, + }; +}; + +const getDualCOREVault = async (blockNumber) => { + const [totalStake, exchangeRateYesterday, currentExchangeRate] = + await Promise.all([ + sdk.api.abi.call({ + chain: 'core', + target: STAKING_CONTRACT, + abi: 'uint256:totalStaked', + }), + sdk.api.abi.call({ + chain: 'core', + target: STAKING_CONTRACT, + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockNumber.block - 28800, + }), + sdk.api.abi.call({ + chain: 'core', + target: STAKING_CONTRACT, + abi: exchangeRateAbi, + params: ['1000000000000000000'], + }), + ]); + // this vault is auto compound + let apy = + ((currentExchangeRate.output / exchangeRateYesterday.output) ** 365 - 1) * + 100; + return { apy, totalStake: totalStake.output / 1e18 }; +}; + +const getBTCMarketplace = async (blockNumber, corePrice, btcPrice) => { + const totalBTCLock = await totalBTC(); + const coreRewardForBTCHolderPerDay = await getCORERewardForBTCHolderPerDay( + blockNumber + ); + const btcLock = Math.min( + totalBTCLock.bitcoin, + coreRewardForBTCHolderPerDay.btcStake + ); + const apy = + ((corePrice * coreRewardForBTCHolderPerDay.reward) / btcLock / btcPrice) * + 365 * + 100; + return { totalLock: btcLock, apy }; +}; + +const getWBTCVault = async (blockNumber, corePrice, btcPrice) => { + const totalStake = await sdk.api.abi.call({ + target: '0x2e3ea6cf100632a4a4b34f26681a6f50347775c9', + params: '0xa3CD4D4A568b76CFF01048E134096D2Ba0171C27', // wbtc vault address + abi: 'erc20:balanceOf', + chain: 'core', + }); + + const wbtcReserve = await sdk.api.abi.call({ + chain: 'core', + target: '0x0CEa9F0F49F30d376390e480ba32f903B43B19C5', + params: '0x5832f53d147b3d6cd4578b9cbd62425c7ea9d0bd', + abi: { + outputs: [ + { + components: [ + { + components: [ + { + name: 'data', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'configuration', + internalType: 'struct DataTypes.ReserveConfigurationMap', + type: 'tuple', + }, + { + name: 'liquidityIndex', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'currentLiquidityRate', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'variableBorrowIndex', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'currentVariableBorrowRate', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'currentStableBorrowRate', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'lastUpdateTimestamp', + internalType: 'uint40', + type: 'uint40', + }, + { + name: 'id', + internalType: 'uint16', + type: 'uint16', + }, + { + name: 'aTokenAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'stableDebtTokenAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'variableDebtTokenAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'interestRateStrategyAddress', + internalType: 'address', + type: 'address', + }, + { + name: 'accruedToTreasury', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'unbacked', + internalType: 'uint128', + type: 'uint128', + }, + { + name: 'isolationModeTotalDebt', + internalType: 'uint128', + type: 'uint128', + }, + ], + name: '', + internalType: 'struct DataTypes.ReserveData', + type: 'tuple', + }, + ], + inputs: [ + { + name: 'asset', + internalType: 'address', + type: 'address', + }, + ], + name: 'getReserveData', + stateMutability: 'view', + type: 'function', + }, + }); + const wbtcRate = wbtcReserve.output[2] / 1e25; //currentLiquidityRate + const liquidityIndex = wbtcReserve.output[1]; + const lastRoundClaim = await sdk.api.abi.call({ + chain: 'core', + target: '0xa3CD4D4A568b76CFF01048E134096D2Ba0171C27', + abi: 'uint:lastRoundClaim', + }); + const rewardDataLog = await sdk.api.abi.multiCall({ + abi: { + inputs: [ + { + internalType: 'uint256', + name: 'round', + type: 'uint256', + }, + ], + name: 'rewardDataLog', + outputs: [ + { + internalType: 'uint256', + name: 'accPerShare', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + calls: [ + { + target: '0xa3CD4D4A568b76CFF01048E134096D2Ba0171C27', + params: [lastRoundClaim.output - 1], + }, + { + target: '0xa3CD4D4A568b76CFF01048E134096D2Ba0171C27', + params: [lastRoundClaim.output], + }, + ], + chain: 'core', + }); + const coreReward = + (rewardDataLog.output[1].output.accPerShare - + rewardDataLog.output[0].output.accPerShare) / + 1e28; + const coreAPR = + (coreReward / (liquidityIndex / 1e27) / btcPrice) * corePrice * 365 * 100; + const apy = ((1 + (coreAPR + wbtcRate) / 365 / 100) ** 365 - 1) * 100; + return { apy, totalStake: totalStake.output / 1e8 }; +}; +const getApy = async () => { + const blockNumber = await getLatestBlock('core'); + const price = await getPrices( + [ + '0x0000000000000000000000000000000000000000', + '0x5832f53d147b3d6cd4578b9cbd62425c7ea9d0bd', + ], + 'core' + ); + const wBTCVault = await getWBTCVault( + blockNumber, + price.pricesBySymbol.core, + price.pricesBySymbol.wbtc + ); + const dualCOREVault = await getDualCOREVault(blockNumber); + const btcMarketplace = await getBTCMarketplace( + blockNumber, + price.pricesBySymbol.core, + price.pricesBySymbol.wbtc + ); + + return [ + { + pool: `${STAKING_CONTRACT}-core`, + project: 'b14g', + symbol: 'CORE', + tvlUsd: dualCOREVault.totalStake * price.pricesBySymbol.core, + apyBase: dualCOREVault.apy, + chain: 'core', + url: 'https://app.b14g.xyz/vaults/core', + }, + { + pool: `${WBTC_VAULT_CONTRACT}-core`, + project: 'b14g', + symbol: 'WBTC', + tvlUsd: wBTCVault.totalStake * price.pricesBySymbol.wbtc, + apyBase: wBTCVault.apy, + chain: 'core', + url: 'https://app.b14g.xyz/vaults/core', + }, + { + pool: `${MARKETPLACE_CONTRACT}-bitcoin`, + project: 'b14g', + symbol: 'BTC', + tvlUsd: btcMarketplace.totalLock * price.pricesBySymbol.wbtc, + apyBase: btcMarketplace.apy, + chain: 'bitcoin', + url: 'https://app.b14g.xyz/marketplace', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/babel.config.js b/src/adaptors/babel.config.js new file mode 100644 index 0000000000..7ae8152bab --- /dev/null +++ b/src/adaptors/babel.config.js @@ -0,0 +1,9 @@ +module.exports = function (api) { + api.cache(true); + + return { + presets: ['@babel/preset-typescript'], + plugins: [['@babel/plugin-transform-runtime']], + sourceType: 'unambiguous', + }; +}; diff --git a/src/adaptors/babydogeswap/index.js b/src/adaptors/babydogeswap/index.js new file mode 100644 index 0000000000..99ac735877 --- /dev/null +++ b/src/adaptors/babydogeswap/index.js @@ -0,0 +1,149 @@ +const { request, gql } = require('graphql-request'); + +const { getLpTokens } = require('./utils'); +const utils = require('../utils'); + +const url = + 'https://graph-bsc-mainnet.babydoge.com/subgraphs/name/babydoge/faas'; + +const WEEKS_IN_YEAR = 52.1429; + +const TOTAL_FEE = 0.003; +const LP_HOLDERS_FEE = 0.002; + +const ZERO_FEE_PAIRS = ['0x0536c8b0c3685b6e3c62a7b5c4e8b83f938f12d1']; + +const query = gql` + { + farms(first: 1000, block: {number: }) { + id + APR + totalStakedUsdValue + isStakeTokenLpToken + rewardToken { + id + symbol + } + stakeToken { + id + isLpToken + symbol + token0 { + id + symbol + } + token1 { + id + symbol + } + } + } + } +`; + +const farmDataMapping = (entry, lpTokens) => { + entry = { ...entry }; + entry['lpTokenInfo'] = entry.isStakeTokenLpToken + ? lpTokens.find( + ({ id }) => + id?.toLocaleLowerCase() === entry.stakeToken?.id?.toLocaleLowerCase() + ) + : null; + return entry; +}; + +const getLpFeesAndApr = (volumeUSD, volumeUSDWeek, liquidityUSD) => { + const totalFees24h = volumeUSD * TOTAL_FEE; + const totalFees7d = volumeUSDWeek * TOTAL_FEE; + const lpFees24h = volumeUSD * LP_HOLDERS_FEE; + const lpFees7d = volumeUSDWeek * LP_HOLDERS_FEE; + + const lpApr7d = + liquidityUSD > 0 + ? (volumeUSDWeek * LP_HOLDERS_FEE * WEEKS_IN_YEAR * 100) / liquidityUSD + : 0; + return { + totalFees24h, + totalFees7d, + lpFees24h, + lpFees7d, + lpApr7d: lpApr7d !== Infinity ? lpApr7d : 0, + }; +}; + +const farmApy = (entry) => { + entry = { ...entry }; + const index = ZERO_FEE_PAIRS.findIndex( + (v) => v.toLocaleLowerCase() === entry.stakeToken.id.toLocaleLowerCase() + ); + if ( + index > -1 || + !entry.lpTokenInfo || + entry.lpTokenInfo.reserveUSD === '0' + ) { + entry['apy'] = 0; + return entry; + } + + const { lpApr7d } = getLpFeesAndApr( + parseFloat(entry.lpTokenInfo.volumeUSD), + parseFloat(entry.lpTokenInfo.volumeUSD_avg7d), + parseFloat(entry.lpTokenInfo.reserveUSD) + ); + + entry['apy'] = lpApr7d; + return entry; +}; + +const main = async (timestamp = null) => { + const [block, blockPrior] = await utils.getBlocks('bsc', timestamp, [url]); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.farms; + + // get lp tokens + let lpTokens = await getLpTokens(dataNow); + + // matching lp tokens to farms + dataNow = dataNow.map((el) => farmDataMapping(el, lpTokens)); + + // calculate APY + const data = dataNow.map((el) => farmApy(el)); + const pools = data.map((p) => { + let symbol; + let underlyingTokens; + // lp tokens + if (p.stakeToken.isLpToken) { + symbol = `${p.stakeToken.token0.symbol}-${p.stakeToken.token1.symbol}`; + underlyingTokens = [p.stakeToken.token0.id, p.stakeToken.token1.id]; + + // single staking + } else { + symbol = p.stakeToken.symbol; + underlyingTokens = [p.stakeToken.id]; + } + + return { + pool: p.id, + chain: utils.formatChain('binance'), + project: 'babydogeswap', + symbol, + tvlUsd: Number(p.totalStakedUsdValue), + rewardTokens: [p.rewardToken.id], + apyReward: Number(p.APR) * 100, + apyBase: Number(p.apy), + underlyingTokens, + poolMeta: `Stake ${symbol}, Earn ${p.rewardToken.symbol}`, + }; + }); + + return pools.filter((p) => p && utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://babydogeswap.com/farms', +}; diff --git a/src/adaptors/babydogeswap/utils.js b/src/adaptors/babydogeswap/utils.js new file mode 100644 index 0000000000..30e1eeeb1d --- /dev/null +++ b/src/adaptors/babydogeswap/utils.js @@ -0,0 +1,180 @@ +const { request, gql } = require('graphql-request'); +const { getUnixTime, subDays, subWeeks, startOfMinute } = require('date-fns'); +const { chunk } = require('lodash'); +const axios = require('axios'); + +const info_url = + 'https://graph-bsc-mainnet.babydoge.com/subgraphs/name/babydoge/exchange'; + +const block_url = + 'https://graph-bsc-mainnet.babydoge.com/subgraphs/name/babydoge/blocks'; + +const getBlockSubqueries = (timestamps) => + timestamps.map((timestamp) => { + return `t${timestamp}:blocks(first: 1, orderBy: timestamp, orderDirection: desc, where: { timestamp_gt: ${timestamp}, timestamp_lt: ${ + timestamp + 600 + } }) { + number + }`; + }); + +const blocksQueryConstructor = (subqueries) => { + return gql`query blocks { + ${subqueries} + }`; +}; + +const multiQuery = async ( + queryConstructor, + subqueries, + endpoint, + skipCount = 100 +) => { + try { + const results = await Promise.all( + chunk(subqueries, skipCount).map((subqueryChunk) => + request(endpoint, queryConstructor(subqueryChunk)) + ) + ); + + return results.reduce((obj, item) => ({ ...obj, ...item }), {}); + } catch (error) { + console.error('Failed to fetch info data', error); + return null; + } +}; + +const getDeltaTimestamps = () => { + const utcCurrentTime = getUnixTime(new Date()) * 1000; + const t24h = getUnixTime(startOfMinute(subDays(utcCurrentTime, 1))); + const t48h = getUnixTime(startOfMinute(subDays(utcCurrentTime, 2))); + const t7d = getUnixTime(startOfMinute(subWeeks(utcCurrentTime, 1))); + const t14d = getUnixTime(startOfMinute(subWeeks(utcCurrentTime, 2))); + return [t24h, t48h, t7d, t14d]; +}; + +const getBlocksFromTimestamps = async ( + timestamps, + sortDirection = 'desc', + skipCount = 500 +) => { + if (timestamps?.length === 0) { + return []; + } + + const fetchedData = await multiQuery( + blocksQueryConstructor, + getBlockSubqueries(timestamps), + block_url, + skipCount + ); + + const sortingFunction = + sortDirection === 'desc' + ? (a, b) => b.number - a.number + : (a, b) => a.number - b.number; + + const blocks = []; + if (fetchedData) { + for (const key of Object.keys(fetchedData)) { + if (fetchedData[key].length > 0) { + blocks.push({ + timestamp: key.split('t')[1], + number: parseInt(fetchedData[key][0].number, 10), + }); + } + } + // graphql-request does not guarantee same ordering of batched requests subqueries, hence manual sorting + blocks.sort(sortingFunction); + } + return blocks; +}; + +const getAmountChange = (valueNow, valueBefore) => { + if (valueNow && valueBefore) { + return valueNow - valueBefore; + } + if (valueNow) { + return valueNow; + } + return 0; +}; + +const getPercentChange = (valueNow, valueBefore) => { + if (valueNow && valueBefore) { + return ((valueNow - valueBefore) / valueBefore) * 100; + } + return 0; +}; + +const getChangeForPeriod = ( + valueNow, + valueOnePeriodAgo, + valueTwoPeriodsAgo +) => { + const currentPeriodAmount = getAmountChange(valueNow, valueOnePeriodAgo); + const previousPeriodAmount = getAmountChange( + valueOnePeriodAgo, + valueTwoPeriodsAgo + ); + const percentageChange = getPercentChange( + currentPeriodAmount, + previousPeriodAmount + ); + return [currentPeriodAmount, percentageChange]; +}; + +const getLpTokens = async (farms) => { + const timestamps = getDeltaTimestamps(); + const blocks = ( + await Promise.all( + timestamps.map((t) => axios.get(`https://coins.llama.fi/block/bsc/${t}`)) + ) + ).map((b) => b.data.height); + + const pairs = farms + .filter((farm) => farm.isStakeTokenLpToken) + .map((farm) => farm.stakeToken?.id); + if (pairs.length > 0) { + const lpQuery = gql` + { + ${pairs + .map( + (pair) => ` + pd${pair}:pair(id: "${pair}") { + name + totalSupply + reserveUSD + volumeUSD + } + d7${pair}:pair(id: "${pair}" block: {number: ${blocks[2]}}) { + name + totalSupply + reserveUSD + volumeUSD + } + + ` + ) + .join('')} + }`; + const data = await request(info_url, lpQuery); + const keys = Object.keys(data).filter((key) => key.startsWith('pd')); + const lpTokens = keys.map((key) => { + const id = key.slice(2); + const [volumeUSDWeek] = getChangeForPeriod( + Number(data[key]?.volumeUSD), + Number(data[`d7${id}`]?.volumeUSD) + ); + return { + ...data[key], + id, + volumeUSD_avg7d: volumeUSDWeek, + }; + }); + return lpTokens; + } + return []; +}; + +exports.getLpTokens = getLpTokens; diff --git a/src/adaptors/badger-dao/index.js b/src/adaptors/badger-dao/index.js index 1c7c2eff58..3368d31c56 100755 --- a/src/adaptors/badger-dao/index.js +++ b/src/adaptors/badger-dao/index.js @@ -1,42 +1,159 @@ +/** + * Badger DAO supports a comprehensive API to understand protocol offerings and yields. + * + * Badger SDK is available should this project ever convert to proper typescript. + * https://github.com/Badger-Finance/badger-sdk + * + * Badger API documentation is available via Swagger. + * https://api.badger.com/docs + * + * Any issues or upgrades to yield server offerings please contact @hellojintao (twitter) or jintao#0713 (discord). + */ const utils = require('../utils'); -const buildPool = (entry, chainString) => { - const newObj = { - pool: entry.vaultToken, - chain: utils.formatChain(chainString), - project: 'badger-dao', - symbol: utils.formatSymbol(entry.name), - tvlUsd: entry.value, - apy: entry.apr, - }; - - return newObj; -}; +// utilize badger-sdk network object if typescript becomes available +// https://github.com/Badger-Finance/badger-sdk/blob/main/src/config/enums/network.enum.ts +const SUPPORTED_NETWORKS = [ + 'ethereum', + 'polygon', + 'arbitrum', + 'binance-smart-chain', + 'fantom', + 'optimism', +]; -const topLvl = async (chainString) => { - // pull data - const s = chainString === 'binance' ? 'bsc' : chainString; - const url = `https://api.badger.com/v2/vaults?chain=${s}¤cy=usd`; - let data = await utils.getData(url); +// Vault Objects Definitions - // build pool objects - data = data.map((el) => buildPool(el, chainString)); +// export interface VaultYieldSummary extends YieldSummary { +// sources: YieldSource[]; +// } - return data; -}; +// export interface YieldSource { +// name: string; +// performance: YieldSummary; +// boostable: boolean; +// } + +// export interface YieldSummary { +// baseYield: number; +// grossYield: number; +// minYield: number; +// maxYield: number; +// minGrossYield: number; +// maxGrossYield: number; +// } + +// export interface VaultDTOV3 extends VaultDTO { +// address: string; +// apr: VaultYieldSummary; +// apy: VaultYieldSummary; +// yieldProjection: VaultYieldProjectionV3; +// } + +// export interface VaultYieldProjection { +// harvestValue: number; +// harvestApr: number; +// harvestTokens: TokenRate[]; +// harvestPeriodApr: number; +// harvestPeriodApy: number; +// harvestPeriodSources: TokenRate[]; +// harvestPeriodSourcesApy: TokenRate[]; +// yieldValue: number; +// yieldApr: number; +// yieldTokens: TokenRate[]; +// yieldPeriodApr: number; +// yieldPeriodSources: TokenRate[]; +// nonHarvestApr: number; +// nonHarvestApy: number; +// } + +// export interface VaultDTO { +// asset: string; +// available: number; +// balance: number; +// behavior: VaultBehavior; +// boost: BoostConfig; +// bouncer: BouncerType; +// lastHarvest: number; +// name: string; +// pricePerFullShare: number; +// protocol: Protocol; +// state: VaultState; +// strategy: VaultStrategy; +// tokens: TokenValue[]; +// type: VaultType; +// underlyingToken: string; +// value: number; +// vaultAsset: string; +// vaultToken: string; +// version: VaultVersion; +// } + +const project = 'badger-dao'; + +const influenceVaults = ['0xBA485b556399123261a5F9c95d413B4f93107407']; + +async function queryVaults(chain) { + try { + const url = `https://api.badger.com/v3/vaults/list?chain=${chain}`; + const data = await utils.getData(url); + + let chainName = chain; + if (chain === 'binance-smart-chain') { + chain = 'bsc'; + } + + return data.map((e) => { + const { + apr: { sources }, + yieldProjection: { harvestApr, harvestTokens, nonHarvestApr }, + tokens, + protocol, + value: tvlUsd, + vaultToken: pool, + } = e; + + let apyBase = e.apy.baseYield; + let apyReward = sources + .filter((s) => s.name.includes('Badger Rewards')) + .reduce((total, s) => (total += s.performance.baseYield), 0); + + if (e.version === 'v1.5' && !influenceVaults.includes(pool)) { + apyBase = harvestApr; + apyReward = nonHarvestApr; + } + + const rewardTokens = harvestTokens.map((h) => h.address); + const underlyingTokens = tokens.map((t) => t.address); + + return { + pool, + chain: utils.formatChain(chain), + project, + symbol: utils.formatSymbol(e.name), + tvlUsd, + apyBase, + apyReward, + rewardTokens, + underlyingTokens, + }; + }); + } catch (e) { + if (e.message.includes('Internal Server Error')) { + return []; + } else { + throw e; + } + } +} const main = async () => { - const data = await Promise.all([ - topLvl('ethereum'), - topLvl('polygon'), - topLvl('arbitrum'), - topLvl('fantom'), - topLvl('binance'), - ]); + const data = await Promise.all(SUPPORTED_NETWORKS.map((n) => queryVaults(n))); return data.flat(); }; module.exports = { timetravel: false, apy: main, + url: 'https://app.badger.com', }; diff --git a/src/adaptors/bagful/index.js b/src/adaptors/bagful/index.js new file mode 100644 index 0000000000..3022741284 --- /dev/null +++ b/src/adaptors/bagful/index.js @@ -0,0 +1,95 @@ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +let tokenInfoMapping = {}; + +const AGGREGATOR_ADDRESS = '0x6bD057Dae9aA5aE05c782F2eB988CBdE53Be9620'; +const POOL_INFOS_ADDRESS = '0x0099A786a41b0b7b11E326Eb1d8FE84f9337548F'; + +async function apy() { + let abi = sdk.api.abi; + let { output: poolTvlInfos } = await abi.call({ + target: AGGREGATOR_ADDRESS, + abi: abiJSON.getPoolTvl, + chain: 'linea', + }); + let { output: poolApyInfos } = await abi.call({ + target: POOL_INFOS_ADDRESS, + abi: abiJSON.getAllPools, + chain: 'linea', + }); + let priceKeys = Array.from( + new Set( + poolApyInfos.flatMap((item) => [ + `linea:${item.asset}`, + `linea:${item.reward}`, + ]) + ) + ); + let { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys.join(',').toLowerCase()}` + ); + + let poolTvlInfoMap = {}; + for (const poolTvl of poolTvlInfos) { + poolTvlInfoMap[poolTvl.pid] = poolTvl.tvl; + } + + return poolApyInfos.map((poolApy) => { + let tvl = poolTvlInfoMap[poolApy.pid]; + let coin = coins[`linea:${poolApy.asset}`.toLocaleLowerCase()]; + if (coin === undefined || tvl === undefined) { + return undefined; + } + let apy; + let tvlUsd = BigNumber(tvl) + .div(Math.pow(10, poolApy.assetDecimals)) + .multipliedBy(coin.price) + .toNumber(); + tvlUsd = parseFloat(tvlUsd.toFixed(2)); + + if (poolApy.isFixedRate) { + apy = poolApy.fixedRate / 100; + } else { + let rewardCoin = coins[`linea:${poolApy.reward}`.toLocaleLowerCase()]; + if (rewardCoin === undefined) { + return undefined; + } + + apy = + tvlUsd === 0 + ? 0 + : (BigNumber(poolApy.rewardAmount) + .div(Math.pow(10, poolApy.rewardDecimals)) + .multipliedBy(rewardCoin.price) * + 365) / + tvlUsd; + apy = parseFloat((apy * 100).toFixed(2)); + } + + return { + chain: 'linea', + project: 'bagful', + pool: poolApy.farmAddress, + symbol: poolApy.assetSymbol, + underlyingTokens: [poolApy.asset], + tvlUsd, + apy, + url: `https://bagful.io/vault/${poolApy.farmAddress}/${poolApy.asset}`, + }; + }); +} + +let abiJSON = { + getPoolTvl: + 'function getPoolTotalTvl() view returns (tuple(uint256 pid, address poolAddress,address poolAssets, uint256 tvl)[])', + getAllPools: + 'function getAllPools() view returns (tuple(uint256 pid, address asset, string assetSymbol, uint256 assetDecimals, address farmAddress, bool isFixedRate, uint256 fixedRate, address reward, uint256 rewardDecimals, uint256 rewardAmount)[])', +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://bagful.io', +}; diff --git a/src/adaptors/bakerfi/index.js b/src/adaptors/bakerfi/index.js new file mode 100644 index 0000000000..1a382e3afe --- /dev/null +++ b/src/adaptors/bakerfi/index.js @@ -0,0 +1,129 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); + +const API_URL = 'https://api-v1.bakerfi.ai/api'; + +const oracles = { + ethereum: { + ethToUSD: '0x0D01EdB9af465d8518999d2a9547526D0A887842', + }, + base: { + ethToUSD: '0xddC3b00b6185484B54c00C154E6bB70c4942E910', + }, + arbitrum: { + ethToUSD: '0xE5873ea8B9BBcd7ed61A0feAC3f5e2c94b0086a4', + }, +}; +const vaults = [ + { + id: 'cm2lwpkwh00005q2qadxhpokp', + pool: `0x01280b3683fE20Dc9cCF4D9526418F252871E4F7-ethereum`.toLowerCase(), + chain: 'ethereum', + contract: '0x01280b3683fE20Dc9cCF4D9526418F252871E4F7', + project: 'bakerfi', + symbol: utils.formatSymbol('ETH'), + apyReward: 0, // APY from pool LM rewards in %, + rewardTokens: ['0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: ['0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'wstETH/ETH AAVEv3 Ethereum Vault', // A string value which can stand for any specif + }, + { + id: 'cly4i95530008kl5eesquxqyc', + pool: `0x37327c99bBc522e677a97d01021dB20227faF60A-base`.toLowerCase(), + chain: 'base', + contract: '0x37327c99bBc522e677a97d01021dB20227faF60A', + project: 'bakerfi', + symbol: utils.formatSymbol('ETH'), + apyReward: 0, // APY from pool LM rewards in %, + rewardTokens: ['0x4200000000000000000000000000000000000006'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: ['0x4200000000000000000000000000000000000006'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'wstETH/ETH AAVEv3 Base Vault', // A string value which can stand for any specif + }, + { + id: 'cm2subkbi0000ihv5e7www0ic', + pool: `0x892022FE1431fdE03836725BBD0f0380e21E2095-base`.toLowerCase(), + chain: 'base', + contract: '0x892022FE1431fdE03836725BBD0f0380e21E2095', + project: 'bakerfi', + symbol: utils.formatSymbol('ETH'), + apyReward: 0, // APY from pool LM rewards in %, + rewardTokens: ['0x4200000000000000000000000000000000000006'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: ['0x4200000000000000000000000000000000000006'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'wstETH/ETH Morpho Base Vault', // A string value which can stand for any specif + }, + { + id: 'cm1p7hcba0000125ua7hxn8m3', + pool: `0x4c6d58749126FEBb1D28E8B8FdE97DC3107996d3-arbitrum`.toLowerCase(), + chain: 'arbitrum', + contract: '0x4c6d58749126FEBb1D28E8B8FdE97DC3107996d3', + project: 'bakerfi', + symbol: utils.formatSymbol('ETH'), + apyReward: 0, // APY from pool LM rewards in %, + rewardTokens: ['0x82af49447d8a07e3bd95bd0d56f35241523fbab1'], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: ['0x82af49447d8a07e3bd95bd0d56f35241523fbab1'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'wstETH/ETH AAVEv3 Arbitrum Vault', // A string value which can stand for any specif + }, + { + id: '6f0f805c35fbb925ec5c28085f2b3f', + pool: `0x909d587c482766814B368d5b136d98819B9373d7-ethereum`.toLowerCase(), + chain: 'ethereum', + contract: '0x909d587c482766814B368d5b136d98819B9373d7', + project: 'bakerfi', + symbol: utils.formatSymbol('USDC'), + apyReward: 0, // APY from pool LM rewards in %, + underlyingTokens: ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'Stable USD Ethereum Vault', // A string value which can stand for any specif + }, + { + id: '8445df8580569e3abfd828cf4ed24f', + pool: `0x4BA3f77a8072217dabd7FeD28DB244A5d32C572E-base`.toLowerCase(), + chain: 'base', + contract: '0x4BA3f77a8072217dabd7FeD28DB244A5d32C572E', + project: 'bakerfi', + symbol: utils.formatSymbol('USDC'), + apyReward: 0, // APY from pool LM rewards in %, + underlyingTokens: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: 'Stable USD Base Vault', // A string value which can stand for any specif + }, +]; + +async function readVaultsInfo(args) { + const res = []; + + for (const vault of vaults) { + const { id, contract, ...rest } = vault; + const ethUSDOracle = oracles[vault.chain].ethToUSD; + + const tvlInEth = await sdk.api.abi.call({ + target: contract, + chain: vault.chain, + abi: 'uint256:totalAssets', + }); + + const ethToUSD = await sdk.api.abi.call({ + target: ethUSDOracle, + chain: vault.chain, + abi: 'uint256:getLatestPrice', + }); + + const tvlUsd = + (BigInt(tvlInEth.output) * BigInt(ethToUSD.output)) / BigInt(1e36); + + const { data } = await axios.get(`${API_URL}/vaults/${id}/yield`); + + res.push({ + ...rest, + tvlUsd: Number(tvlUsd), + apyBase: data.yield, + }); + } + + return res; +} + +module.exports = { + timetravel: false, + apy: readVaultsInfo, + url: 'https://bakerfi.ai/app', +}; diff --git a/src/adaptors/balancer-v2/abis/balancer_token_admin.json b/src/adaptors/balancer-v2/abis/balancer_token_admin.json new file mode 100644 index 0000000000..b7483501aa --- /dev/null +++ b/src/adaptors/balancer-v2/abis/balancer_token_admin.json @@ -0,0 +1,243 @@ +[ + { + "inputs": [ + { "internalType": "contract IVault", "name": "vault", "type": "address" }, + { + "internalType": "contract IBalancerToken", + "name": "balancerToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "MiningParametersUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_RATE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_COEFFICIENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_TIME", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "available_supply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "futureEpochTimeWrite", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "future_epoch_time_write", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "selector", "type": "bytes4" } + ], + "name": "getActionId", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthorizer", + "outputs": [ + { "internalType": "contract IAuthorizer", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAvailableSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalancerToken", + "outputs": [ + { + "internalType": "contract IBalancerToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFutureEpochTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInflationRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMiningEpoch", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVault", + "outputs": [ + { "internalType": "contract IVault", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "mintableInTimeframe", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "mintable_in_timeframe", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "snapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startEpochTimeWrite", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start_epoch_time_write", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateMiningParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "update_mining_parameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/balancer/abis/gauge_arbitrum.json b/src/adaptors/balancer-v2/abis/gauge_arbitrum.json similarity index 64% rename from src/adaptors/balancer/abis/gauge_arbitrum.json rename to src/adaptors/balancer-v2/abis/gauge_arbitrum.json index 9bb7316e2c..dc3e730e30 100644 --- a/src/adaptors/balancer/abis/gauge_arbitrum.json +++ b/src/adaptors/balancer-v2/abis/gauge_arbitrum.json @@ -1,130 +1,199 @@ [ { - "name": "Deposit", + "name": "Approval", "inputs": [ - { "name": "provider", "type": "address", "indexed": true }, - { "name": "value", "type": "uint256", "indexed": false } + { "name": "_owner", "type": "address", "indexed": true }, + { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Withdraw", + "name": "Transfer", "inputs": [ - { "name": "provider", "type": "address", "indexed": true }, - { "name": "value", "type": "uint256", "indexed": false } + { "name": "_from", "type": "address", "indexed": true }, + { "name": "_to", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Transfer", + "name": "Deposit", "inputs": [ - { "name": "_from", "type": "address", "indexed": true }, - { "name": "_to", "type": "address", "indexed": true }, + { "name": "_user", "type": "address", "indexed": true }, { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Approval", + "name": "Withdraw", "inputs": [ - { "name": "_owner", "type": "address", "indexed": true }, - { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_user", "type": "address", "indexed": true }, { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { "name": "_user", "type": "address", "indexed": true }, + { "name": "_original_balance", "type": "uint256", "indexed": false }, + { "name": "_original_supply", "type": "uint256", "indexed": false }, + { "name": "_working_balance", "type": "uint256", "indexed": false }, + { "name": "_working_supply", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, { "stateMutability": "nonpayable", "type": "constructor", "inputs": [ - { "name": "_bal_token", "type": "address" }, - { "name": "_vault", "type": "address" }, - { "name": "_authorizerAdaptor", "type": "address" } + { "name": "_voting_escrow_delegation_proxy", "type": "address" }, + { "name": "_bal_pseudo_minter", "type": "address" }, + { "name": "_authorizer_adaptor", "type": "address" }, + { "name": "_version", "type": "string" } ], "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "decimals", - "inputs": [], - "outputs": [{ "name": "", "type": "uint256" }] + "name": "deposit", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "version", - "inputs": [], - "outputs": [{ "name": "", "type": "string" }] + "name": "deposit", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "reward_contract", - "inputs": [], - "outputs": [{ "name": "", "type": "address" }] + "name": "withdraw", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "last_claim", - "inputs": [], - "outputs": [{ "name": "", "type": "uint256" }] + "name": "withdraw", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "claimed_reward", + "name": "transferFrom", "inputs": [ - { "name": "_addr", "type": "address" }, - { "name": "_token", "type": "address" } + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } ], - "outputs": [{ "name": "", "type": "uint256" }] + "outputs": [{ "name": "", "type": "bool" }] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "claimable_reward", + "name": "approve", "inputs": [ - { "name": "_addr", "type": "address" }, - { "name": "_token", "type": "address" } + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } ], - "outputs": [{ "name": "", "type": "uint256" }] + "outputs": [{ "name": "", "type": "bool" }] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "reward_data", - "inputs": [{ "name": "_token", "type": "address" }], - "outputs": [ - { - "name": "", - "type": "tuple", - "components": [ - { "name": "token", "type": "address" }, - { "name": "distributor", "type": "address" }, - { "name": "period_finish", "type": "uint256" }, - { "name": "rate", "type": "uint256" }, - { "name": "last_update", "type": "uint256" }, - { "name": "integral", "type": "uint256" } - ] - } - ] + "name": "permit", + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" }, + { "name": "_deadline", "type": "uint256" }, + { "name": "_v", "type": "uint8" }, + { "name": "_r", "type": "bytes32" }, + { "name": "_s", "type": "bytes32" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_added_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_subtracted_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] }, { "stateMutability": "nonpayable", "type": "function", - "name": "claimable_reward_write", + "name": "user_checkpoint", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", "inputs": [ { "name": "_addr", "type": "address" }, { "name": "_token", "type": "address" } ], "outputs": [{ "name": "", "type": "uint256" }] }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { "name": "_user", "type": "address" }, + { "name": "_reward_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, { "stateMutability": "nonpayable", "type": "function", @@ -159,68 +228,64 @@ { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", - "inputs": [{ "name": "_value", "type": "uint256" }], + "name": "claim_rewards", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_receiver", "type": "address" }, + { "name": "_reward_indexes", "type": "uint256[]" } + ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", + "name": "add_reward", "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_addr", "type": "address" } + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", + "name": "set_reward_distributor", "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_addr", "type": "address" }, - { "name": "_claim_rewards", "type": "bool" } + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "withdraw", - "inputs": [{ "name": "_value", "type": "uint256" }], + "name": "deposit_reward_token", + "inputs": [ + { "name": "_reward_token", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "withdraw", - "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_claim_rewards", "type": "bool" } - ], + "name": "killGauge", + "inputs": [], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "transfer", - "inputs": [ - { "name": "_to", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "unkillGauge", + "inputs": [], + "outputs": [] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "transferFrom", - "inputs": [ - { "name": "_from", "type": "address" }, - { "name": "_to", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "decimals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", @@ -233,60 +298,39 @@ "outputs": [{ "name": "", "type": "uint256" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "approve", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "permit", - "inputs": [ - { "name": "_owner", "type": "address" }, - { "name": "_spender", "type": "address" }, - { "name": "_value", "type": "uint256" }, - { "name": "_deadline", "type": "uint256" }, - { "name": "_v", "type": "uint8" }, - { "name": "_r", "type": "bytes32" }, - { "name": "_s", "type": "bytes32" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "bal_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "increaseAllowance", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_added_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "bal_pseudo_minter", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "decreaseAllowance", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_subtracted_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "voting_escrow_delegation_proxy", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "set_rewards", - "inputs": [ - { "name": "_reward_contract", "type": "address" }, - { "name": "_claim_sig", "type": "bytes32" }, - { "name": "_reward_tokens", "type": "address[8]" } - ], - "outputs": [] + "name": "authorizer_adaptor", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "nonpayable", @@ -294,17 +338,37 @@ "name": "initialize", "inputs": [ { "name": "_lp_token", "type": "address" }, - { "name": "_reward_contract", "type": "address" }, - { "name": "_claim_sig", "type": "bytes32" } + { "name": "_version", "type": "string" } ], "outputs": [] }, { "stateMutability": "view", "type": "function", - "name": "lp_token", + "name": "DOMAIN_SEPARATOR", "inputs": [], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "bytes32" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] }, { "stateMutability": "view", @@ -323,66 +387,120 @@ { "stateMutability": "view", "type": "function", - "name": "name", + "name": "lp_token", "inputs": [], - "outputs": [{ "name": "", "type": "string" }] + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "view", "type": "function", - "name": "symbol", + "name": "version", "inputs": [], "outputs": [{ "name": "", "type": "string" }] }, { "stateMutability": "view", "type": "function", - "name": "DOMAIN_SEPARATOR", + "name": "factory", "inputs": [], - "outputs": [{ "name": "", "type": "bytes32" }] + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "view", "type": "function", - "name": "nonces", + "name": "working_balances", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_tokens", + "name": "working_supply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", "inputs": [{ "name": "arg0", "type": "uint256" }], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_balances", + "name": "integrate_checkpoint_of", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "rewards_receiver", + "name": "integrate_fraction", "inputs": [{ "name": "arg0", "type": "address" }], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "claim_sig", - "inputs": [], - "outputs": [{ "name": "", "type": "bytes" }] + "name": "integrate_inv_supply", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_integral", + "name": "integrate_inv_supply_of", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { "name": "distributor", "type": "address" }, + { "name": "period_finish", "type": "uint256" }, + { "name": "rate", "type": "uint256" }, + { "name": "last_update", "type": "uint256" }, + { "name": "integral", "type": "uint256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, { "stateMutability": "view", "type": "function", @@ -392,5 +510,19 @@ { "name": "arg1", "type": "address" } ], "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] } ] diff --git a/src/adaptors/balancer-v2/abis/gauge_base.json b/src/adaptors/balancer-v2/abis/gauge_base.json new file mode 100644 index 0000000000..dc3e730e30 --- /dev/null +++ b/src/adaptors/balancer-v2/abis/gauge_base.json @@ -0,0 +1,528 @@ +[ + { + "name": "Approval", + "inputs": [ + { "name": "_owner", "type": "address", "indexed": true }, + { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Transfer", + "inputs": [ + { "name": "_from", "type": "address", "indexed": true }, + { "name": "_to", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Deposit", + "inputs": [ + { "name": "_user", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { "name": "_user", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { "name": "_user", "type": "address", "indexed": true }, + { "name": "_original_balance", "type": "uint256", "indexed": false }, + { "name": "_original_supply", "type": "uint256", "indexed": false }, + { "name": "_working_balance", "type": "uint256", "indexed": false }, + { "name": "_working_supply", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "_voting_escrow_delegation_proxy", "type": "address" }, + { "name": "_bal_pseudo_minter", "type": "address" }, + { "name": "_authorizer_adaptor", "type": "address" }, + { "name": "_version", "type": "string" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" }, + { "name": "_deadline", "type": "uint256" }, + { "name": "_v", "type": "uint8" }, + { "name": "_r", "type": "bytes32" }, + { "name": "_s", "type": "bytes32" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_added_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_subtracted_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "user_checkpoint", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { "name": "_user", "type": "address" }, + { "name": "_reward_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards_receiver", + "inputs": [{ "name": "_receiver", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [{ "name": "_addr", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_receiver", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_receiver", "type": "address" }, + { "name": "_reward_indexes", "type": "uint256[]" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_reward", + "inputs": [ + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_reward_distributor", + "inputs": [ + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit_reward_token", + "inputs": [ + { "name": "_reward_token", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "killGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "unkillGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { "name": "owner", "type": "address" }, + { "name": "spender", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "bal_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "bal_pseudo_minter", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voting_escrow_delegation_proxy", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "authorizer_adaptor", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "_lp_token", "type": "address" }, + { "name": "_version", "type": "string" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lp_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "version", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "factory", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_balances", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_supply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint_of", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_fraction", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply_of", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { "name": "distributor", "type": "address" }, + { "name": "period_finish", "type": "uint256" }, + { "name": "rate", "type": "uint256" }, + { "name": "last_update", "type": "uint256" }, + { "name": "integral", "type": "uint256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral_for", + "inputs": [ + { "name": "arg0", "type": "address" }, + { "name": "arg1", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] + } +] diff --git a/src/adaptors/balancer/abis/gauge_controller_ethereum.json b/src/adaptors/balancer-v2/abis/gauge_controller_ethereum.json similarity index 100% rename from src/adaptors/balancer/abis/gauge_controller_ethereum.json rename to src/adaptors/balancer-v2/abis/gauge_controller_ethereum.json diff --git a/src/adaptors/balancer/abis/gauge_ethereum.json b/src/adaptors/balancer-v2/abis/gauge_ethereum.json similarity index 100% rename from src/adaptors/balancer/abis/gauge_ethereum.json rename to src/adaptors/balancer-v2/abis/gauge_ethereum.json diff --git a/src/adaptors/balancer-v2/abis/gauge_gnosis.json b/src/adaptors/balancer-v2/abis/gauge_gnosis.json new file mode 100644 index 0000000000..fe29133d39 --- /dev/null +++ b/src/adaptors/balancer-v2/abis/gauge_gnosis.json @@ -0,0 +1,397 @@ +[ + { + "name": "Deposit", + "inputs": [ + { "name": "provider", "type": "address", "indexed": true }, + { "name": "value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { "name": "provider", "type": "address", "indexed": true }, + { "name": "value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Transfer", + "inputs": [ + { "name": "_from", "type": "address", "indexed": true }, + { "name": "_to", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Approval", + "inputs": [ + { "name": "_owner", "type": "address", "indexed": true }, + { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "_bal_token", "type": "address" }, + { "name": "_vault", "type": "address" }, + { "name": "_authorizerAdaptor", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "version", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_contract", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_claim", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [{ "name": "_token", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { "name": "token", "type": "address" }, + { "name": "distributor", "type": "address" }, + { "name": "period_finish", "type": "uint256" }, + { "name": "rate", "type": "uint256" }, + { "name": "last_update", "type": "uint256" }, + { "name": "integral", "type": "uint256" } + ] + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_reward_write", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards_receiver", + "inputs": [{ "name": "_receiver", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [{ "name": "_addr", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_receiver", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_addr", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_addr", "type": "address" }, + { "name": "_claim_rewards", "type": "bool" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_claim_rewards", "type": "bool" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { "name": "owner", "type": "address" }, + { "name": "spender", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" }, + { "name": "_deadline", "type": "uint256" }, + { "name": "_v", "type": "uint8" }, + { "name": "_r", "type": "bytes32" }, + { "name": "_s", "type": "bytes32" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_added_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_subtracted_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards", + "inputs": [ + { "name": "_reward_contract", "type": "address" }, + { "name": "_claim_sig", "type": "bytes32" }, + { "name": "_reward_tokens", "type": "address[8]" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "_lp_token", "type": "address" }, + { "name": "_reward_contract", "type": "address" }, + { "name": "_claim_sig", "type": "bytes32" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lp_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_balances", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claim_sig", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral_for", + "inputs": [ + { "name": "arg0", "type": "address" }, + { "name": "arg1", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + } + ] + \ No newline at end of file diff --git a/src/adaptors/balancer/abis/gauge_polygon.json b/src/adaptors/balancer-v2/abis/gauge_polygon.json similarity index 64% rename from src/adaptors/balancer/abis/gauge_polygon.json rename to src/adaptors/balancer-v2/abis/gauge_polygon.json index 9bb7316e2c..dc3e730e30 100644 --- a/src/adaptors/balancer/abis/gauge_polygon.json +++ b/src/adaptors/balancer-v2/abis/gauge_polygon.json @@ -1,130 +1,199 @@ [ { - "name": "Deposit", + "name": "Approval", "inputs": [ - { "name": "provider", "type": "address", "indexed": true }, - { "name": "value", "type": "uint256", "indexed": false } + { "name": "_owner", "type": "address", "indexed": true }, + { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Withdraw", + "name": "Transfer", "inputs": [ - { "name": "provider", "type": "address", "indexed": true }, - { "name": "value", "type": "uint256", "indexed": false } + { "name": "_from", "type": "address", "indexed": true }, + { "name": "_to", "type": "address", "indexed": true }, + { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Transfer", + "name": "Deposit", "inputs": [ - { "name": "_from", "type": "address", "indexed": true }, - { "name": "_to", "type": "address", "indexed": true }, + { "name": "_user", "type": "address", "indexed": true }, { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, { - "name": "Approval", + "name": "Withdraw", "inputs": [ - { "name": "_owner", "type": "address", "indexed": true }, - { "name": "_spender", "type": "address", "indexed": true }, + { "name": "_user", "type": "address", "indexed": true }, { "name": "_value", "type": "uint256", "indexed": false } ], "anonymous": false, "type": "event" }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { "name": "_user", "type": "address", "indexed": true }, + { "name": "_original_balance", "type": "uint256", "indexed": false }, + { "name": "_original_supply", "type": "uint256", "indexed": false }, + { "name": "_working_balance", "type": "uint256", "indexed": false }, + { "name": "_working_supply", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, { "stateMutability": "nonpayable", "type": "constructor", "inputs": [ - { "name": "_bal_token", "type": "address" }, - { "name": "_vault", "type": "address" }, - { "name": "_authorizerAdaptor", "type": "address" } + { "name": "_voting_escrow_delegation_proxy", "type": "address" }, + { "name": "_bal_pseudo_minter", "type": "address" }, + { "name": "_authorizer_adaptor", "type": "address" }, + { "name": "_version", "type": "string" } ], "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "decimals", - "inputs": [], - "outputs": [{ "name": "", "type": "uint256" }] + "name": "deposit", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "version", - "inputs": [], - "outputs": [{ "name": "", "type": "string" }] + "name": "deposit", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "reward_contract", - "inputs": [], - "outputs": [{ "name": "", "type": "address" }] + "name": "withdraw", + "inputs": [{ "name": "_value", "type": "uint256" }], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "last_claim", - "inputs": [], - "outputs": [{ "name": "", "type": "uint256" }] + "name": "withdraw", + "inputs": [ + { "name": "_value", "type": "uint256" }, + { "name": "_user", "type": "address" } + ], + "outputs": [] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "claimed_reward", + "name": "transferFrom", "inputs": [ - { "name": "_addr", "type": "address" }, - { "name": "_token", "type": "address" } + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } ], - "outputs": [{ "name": "", "type": "uint256" }] + "outputs": [{ "name": "", "type": "bool" }] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "claimable_reward", + "name": "approve", "inputs": [ - { "name": "_addr", "type": "address" }, - { "name": "_token", "type": "address" } + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } ], - "outputs": [{ "name": "", "type": "uint256" }] + "outputs": [{ "name": "", "type": "bool" }] }, { - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function", - "name": "reward_data", - "inputs": [{ "name": "_token", "type": "address" }], - "outputs": [ - { - "name": "", - "type": "tuple", - "components": [ - { "name": "token", "type": "address" }, - { "name": "distributor", "type": "address" }, - { "name": "period_finish", "type": "uint256" }, - { "name": "rate", "type": "uint256" }, - { "name": "last_update", "type": "uint256" }, - { "name": "integral", "type": "uint256" } - ] - } - ] + "name": "permit", + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" }, + { "name": "_deadline", "type": "uint256" }, + { "name": "_v", "type": "uint8" }, + { "name": "_r", "type": "bytes32" }, + { "name": "_s", "type": "bytes32" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_added_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_subtracted_value", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] }, { "stateMutability": "nonpayable", "type": "function", - "name": "claimable_reward_write", + "name": "user_checkpoint", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [{ "name": "addr", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", "inputs": [ { "name": "_addr", "type": "address" }, { "name": "_token", "type": "address" } ], "outputs": [{ "name": "", "type": "uint256" }] }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { "name": "_user", "type": "address" }, + { "name": "_reward_token", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, { "stateMutability": "nonpayable", "type": "function", @@ -159,68 +228,64 @@ { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", - "inputs": [{ "name": "_value", "type": "uint256" }], + "name": "claim_rewards", + "inputs": [ + { "name": "_addr", "type": "address" }, + { "name": "_receiver", "type": "address" }, + { "name": "_reward_indexes", "type": "uint256[]" } + ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", + "name": "add_reward", "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_addr", "type": "address" } + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "deposit", + "name": "set_reward_distributor", "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_addr", "type": "address" }, - { "name": "_claim_rewards", "type": "bool" } + { "name": "_reward_token", "type": "address" }, + { "name": "_distributor", "type": "address" } ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "withdraw", - "inputs": [{ "name": "_value", "type": "uint256" }], + "name": "deposit_reward_token", + "inputs": [ + { "name": "_reward_token", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "withdraw", - "inputs": [ - { "name": "_value", "type": "uint256" }, - { "name": "_claim_rewards", "type": "bool" } - ], + "name": "killGauge", + "inputs": [], "outputs": [] }, { "stateMutability": "nonpayable", "type": "function", - "name": "transfer", - "inputs": [ - { "name": "_to", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "unkillGauge", + "inputs": [], + "outputs": [] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "transferFrom", - "inputs": [ - { "name": "_from", "type": "address" }, - { "name": "_to", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "decimals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", @@ -233,60 +298,39 @@ "outputs": [{ "name": "", "type": "uint256" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "approve", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "permit", - "inputs": [ - { "name": "_owner", "type": "address" }, - { "name": "_spender", "type": "address" }, - { "name": "_value", "type": "uint256" }, - { "name": "_deadline", "type": "uint256" }, - { "name": "_v", "type": "uint8" }, - { "name": "_r", "type": "bytes32" }, - { "name": "_s", "type": "bytes32" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "bal_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "increaseAllowance", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_added_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "bal_pseudo_minter", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "decreaseAllowance", - "inputs": [ - { "name": "_spender", "type": "address" }, - { "name": "_subtracted_value", "type": "uint256" } - ], - "outputs": [{ "name": "", "type": "bool" }] + "name": "voting_escrow_delegation_proxy", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function", - "name": "set_rewards", - "inputs": [ - { "name": "_reward_contract", "type": "address" }, - { "name": "_claim_sig", "type": "bytes32" }, - { "name": "_reward_tokens", "type": "address[8]" } - ], - "outputs": [] + "name": "authorizer_adaptor", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "nonpayable", @@ -294,17 +338,37 @@ "name": "initialize", "inputs": [ { "name": "_lp_token", "type": "address" }, - { "name": "_reward_contract", "type": "address" }, - { "name": "_claim_sig", "type": "bytes32" } + { "name": "_version", "type": "string" } ], "outputs": [] }, { "stateMutability": "view", "type": "function", - "name": "lp_token", + "name": "DOMAIN_SEPARATOR", "inputs": [], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "bytes32" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] }, { "stateMutability": "view", @@ -323,66 +387,120 @@ { "stateMutability": "view", "type": "function", - "name": "name", + "name": "lp_token", "inputs": [], - "outputs": [{ "name": "", "type": "string" }] + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "view", "type": "function", - "name": "symbol", + "name": "version", "inputs": [], "outputs": [{ "name": "", "type": "string" }] }, { "stateMutability": "view", "type": "function", - "name": "DOMAIN_SEPARATOR", + "name": "factory", "inputs": [], - "outputs": [{ "name": "", "type": "bytes32" }] + "outputs": [{ "name": "", "type": "address" }] }, { "stateMutability": "view", "type": "function", - "name": "nonces", + "name": "working_balances", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_tokens", + "name": "working_supply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", "inputs": [{ "name": "arg0", "type": "uint256" }], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_balances", + "name": "integrate_checkpoint_of", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "rewards_receiver", + "name": "integrate_fraction", "inputs": [{ "name": "arg0", "type": "address" }], - "outputs": [{ "name": "", "type": "address" }] + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "claim_sig", - "inputs": [], - "outputs": [{ "name": "", "type": "bytes" }] + "name": "integrate_inv_supply", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] }, { "stateMutability": "view", "type": "function", - "name": "reward_integral", + "name": "integrate_inv_supply_of", "inputs": [{ "name": "arg0", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { "name": "distributor", "type": "address" }, + { "name": "period_finish", "type": "uint256" }, + { "name": "rate", "type": "uint256" }, + { "name": "last_update", "type": "uint256" }, + { "name": "integral", "type": "uint256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, { "stateMutability": "view", "type": "function", @@ -392,5 +510,19 @@ { "name": "arg1", "type": "address" } ], "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] } ] diff --git a/src/adaptors/balancer/abis/protocol_fees_collector.json b/src/adaptors/balancer-v2/abis/protocol_fees_collector.json similarity index 100% rename from src/adaptors/balancer/abis/protocol_fees_collector.json rename to src/adaptors/balancer-v2/abis/protocol_fees_collector.json diff --git a/src/adaptors/balancer-v2/childChainGauges.js b/src/adaptors/balancer-v2/childChainGauges.js new file mode 100644 index 0000000000..f54f16e0ee --- /dev/null +++ b/src/adaptors/balancer-v2/childChainGauges.js @@ -0,0 +1,48 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { capitalizeFirstLetter } = require('../utils'); + +const urlGaugesEthereum = sdk.graph.modifyEndpoint('4sESujoqmztX6pbichs4wZ1XXyYrkooMuHA8sKkYxpTn'); + +// For reference - this is how chains are stored in the gauges subgraph +// const chainToEnum = { +// arbitrum: 0, +// xdai: 1, +// polygon: 2, +// optimism: 3, +// avalanche: 4, +// polygonZkEvm: 5, +// base: 6, +// }; + +const queryChildGauge = gql` + query ($chain: String!) { + rootGauges(where: { chain: $chain }) { + chain + id + recipient + relativeWeightCap + } + } +`; + +/** + * @param chain chainString + * @returns array of: {chain, id (root gauge address on ethereum), recipient (gauge on child chain), relativeWeightCap} + */ +const getChildChainRootGauge = async (chain) => { + chain = capitalizeFirstLetter(chain); + + const variables = { chain }; + const { rootGauges } = await request( + urlGaugesEthereum, + queryChildGauge, + variables + ); + + return rootGauges; +}; + +module.exports = { + getChildChainRootGauge, +}; diff --git a/src/adaptors/balancer-v2/index.js b/src/adaptors/balancer-v2/index.js new file mode 100755 index 0000000000..ccce424e27 --- /dev/null +++ b/src/adaptors/balancer-v2/index.js @@ -0,0 +1,605 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const gaugeABIEthereum = require('./abis/gauge_ethereum.json'); +const gaugeABIArbitrum = require('./abis/gauge_arbitrum.json'); +const gaugeABIPolygon = require('./abis/gauge_polygon.json'); +const gaugeABIGnosis = require('./abis/gauge_gnosis.json'); +const gaugeABIBase = require('./abis/gauge_base.json'); +const balTokenAdminABI = require('./abis/balancer_token_admin.json'); +const gaugeControllerEthereum = require('./abis/gauge_controller_ethereum.json'); +const protocolFeesCollectorABI = require('./abis/protocol_fees_collector.json'); +const { lte } = require('lodash'); +const { excludePools } = require('../../utils/exclude'); +const { getChildChainRootGauge } = require('./childChainGauges.js'); + +// Subgraph URLs +const urlEthereum = sdk.graph.modifyEndpoint( + 'C4ayEZP2yTXRAB8vSaTrgN4m9anTe9Mdm2ViyiAuV9TV' +); +const urlPolygon = sdk.graph.modifyEndpoint( + 'H9oPAbXnobBRq1cB3HDmbZ1E8MWQyJYQjT1QDJMrdbNp' +); +const urlGnosis = sdk.graph.modifyEndpoint( + 'EJezH1Cp31QkKPaBDerhVPRWsKVZLrDfzjrLqpmv6cGg' +); +const urlArbitrum = sdk.graph.modifyEndpoint( + '98cQDy6tufTJtshDCuhh9z2kWXsQWBHVh2bqnLHsGAeS' +); +const urlBaseChain = sdk.graph.modifyEndpoint( + 'E7XyutxXVLrp8njmjF16Hh38PCJuHm12RRyMt5ma4ctX' +); +const urlAvalanche = sdk.graph.modifyEndpoint( + '7asfmtQA1KYu6CP7YVm5kv4bGxVyfAHEiptt2HMFgkHu' +); + +const urlGaugesEthereum = sdk.graph.modifyEndpoint( + '4sESujoqmztX6pbichs4wZ1XXyYrkooMuHA8sKkYxpTn' +); +const urlGaugesPolygon = sdk.graph.modifyEndpoint( + 'AkD2HEjNoupFb1y3fERdhmFC1UbKvQUBwsu5fREAEcJd' +); +const urlGaugesGnosis = sdk.graph.modifyEndpoint( + '4nTERBBaGRc1PgLcGvtvvqupSFu7y8Ee2xKZFNM5aw56' +); +const urlGaugesArbitrum = sdk.graph.modifyEndpoint( + 'Bb1hVjJZ52kL23chZyyGWJKrGEg3S6euuNa1YA6XRU4J' +); +const urlGaugesBase = `https://api.studio.thegraph.com/query/24660/balancer-gauges-base/version/latest`; +const urlGaugesAvalanche = sdk.graph.modifyEndpoint( + 'BZ2DkZkaQKdBqDTRdur8kHM95ZFVt4fBudKmnvobiyN' +); + +const protocolFeesCollector = '0xce88686553686DA562CE7Cea497CE749DA109f9F'; +const gaugeController = '0xC128468b7Ce63eA702C1f104D55A2566b13D3ABD'; +const balancerTokenAdmin = '0xf302f9F50958c5593770FDf4d4812309fF77414f'; + +const BAL = '0xba100000625a3754423978a60c9317c58a424e3d'; + +const queryGauge = gql` + { + liquidityGauges(first: 200) { + id + symbol + poolId + totalSupply + factory { + id + } + tokens { + id + symbol + decimals + } + } + } +`; + +const query = gql` + { + pools( + first: 200 + orderBy: "totalLiquidity" + orderDirection: "desc" + where: { totalShares_gt: 0.01 } + skip: 0 + ) { + id + tokensList + totalSwapFee + totalShares + tokens { + address + balance + symbol + weight + } + address + } + } +`; + +const queryPrior = gql` +{ + pools( + first: 1000 + orderBy: "totalLiquidity" + orderDirection: "desc" + where: { totalShares_gt: 0.01 } + block: {number: } + ) { + id + tokensList + totalSwapFee + tokens { + address + balance + symbol + weight + } + } +} +`; + +// for Balancer Aave Boosted StablePool (there are 2 pools, but underlying addresses for one of them +// don't return any price data from our api, the other pool does though and both have the same underlying tokens) +// specifically, bb-a-usdc, bb-a-dai, bb-a-usdt +// -> use this mapping to get price data for both of them +const bbTokenMapping = { + '0x2f4eb100552ef93840d5adc30560e5513dfffacb': + '0x2bbf681cc4eb09218bee85ea2a5d3d13fa40fc0c', + '0x82698aecc9e28e9bb27608bd52cf57f704bd1b83': + '0x9210f1204b5a24742eba12f710636d76240df3d0', + '0xae37d54ae477268b9997d4161b96b8200755935c': + '0x804cdb9116a10bb78768d3252355a1b18067bf8f', +}; + +// for Balancer Aave Boosted StablePool on Polygon there is no price data +// Using underlying assets for price +const polygonBBTokenMapping = { + '0x178e029173417b1f9c8bc16dcec6f697bc323746': + '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063', // DAI + '0xf93579002dbe8046c43fefe86ec78b1112247bb8': + '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', // USDC + '0xff4ce5aaab5a627bf82f4a571ab1ce94aa365ea6': + '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', // USDT +}; + +// for Balancer Agave Boosted StablePool on Gnosis there is no price data +// Using underlying assets for price +const gnosisBBTokenMapping = { + '0x41211bba6d37f5a74b22e667533f080c7c7f3f13': + '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', // wxDAI + '0xe7f88d7d4ef2eb18fcf9dd7216ba7da1c46f3dd6': + '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83', // USDC + '0xd16f72b02da5f51231fde542a8b9e2777a478c88': + '0x4ecaba5870353805a9f068101a40e0f32ed605c6', // USDT +}; + +const correctMaker = (entry) => { + entry = { ...entry }; + // for some reason the MKR symbol is not there, add this manually for + // token address 0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2 = makerdao + for (const x of entry.tokens) { + if (x.address === '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2') { + x.symbol = 'MKR'; + } + } + + return entry; +}; + +const tvl = (entry, tokenPriceList, chainString) => { + entry = { ...entry }; + + // remove the pool address from tvl calculation to calculate tvl from underlying tokens only + let balanceDetails = entry.tokens.filter((i) => i.address !== entry.address); + + balanceDetails = balanceDetails.filter( + (t) => + ![ + 'B-STETH-Stable', + 'B-STMATIC-STABLE', + 'B-MATICX-STABLE', + 'B-CSMATIC', + 'CBETH-WSTETH-BPT', + 'ANKRETH/WSTETH', + 'GHO/BB-A-USD', + 'B-ETHX/BB-A-WETH', + 'ETHX-WETH-BPT', + 'SAVAX-WAVAX-BPT', + 'GGAVAX-WAVAX-BPT', + 'YYAVAX-WAVAX-BPT', + ].includes(t.symbol.toUpperCase().trim()) + ); + + const d = { + id: entry.id, + symbol: balanceDetails.map((tok) => tok.symbol).join('-'), + tvl: 0, + totalShares: entry.totalShares, + tokensList: entry.tokensList, + }; + const symbols = []; + const tokensList = []; + const emptyPrice = []; + let price; + for (const el of balanceDetails) { + price = tokenPriceList[`${chainString}:${el.address.toLowerCase()}`]?.price; + if ( + el.address.toLowerCase() === + '0x7dff46370e9ea5f0bad3c4e29711ad50062ea7a4'.toLowerCase() + ) + price = + tokenPriceList['solana:So11111111111111111111111111111111111111112'] + ?.price; + if ( + entry.id === + '0xa13a9247ea42d743238089903570127dda72fe4400000000000000000000035d' + ) { + price = tokenPriceList[`ethereum:${bbTokenMapping[el.address]}`]?.price; + } + if ( + chainString == 'polygon' && + entry.id === + '0x48e6b98ef6329f8f0a30ebb8c7c960330d64808500000000000000000000075b' + ) { + price = + tokenPriceList[`polygon:${polygonBBTokenMapping[el.address]}`]?.price; + } + if ( + chainString == 'xdai' && + entry.id === + '0xfedb19ec000d38d92af4b21436870f115db22725000000000000000000000010' + ) { + price = tokenPriceList[`xdai:${gnosisBBTokenMapping[el.address]}`]?.price; + } + if (price === undefined) { + emptyPrice.push(el); + } + price = price ?? 0; + d.tvl += Number(el.balance) * price; + } + + if (entry.tokens.length === 2 && emptyPrice.length === 1) { + // use weight to correct tvl + const multiplier = 1 / (1 - Number(emptyPrice[0].weight)); + d.tvl *= multiplier; + } + + return d; +}; + +const aprLM = async (tvlData, urlLM, queryLM, chainString, gaugeABI) => { + // copy + const data = tvlData.map((a) => ({ ...a })); + + // get liquidity gauges for each pool + const { liquidityGauges } = await request(urlLM, queryLM); + + let childChainRootGauges; + if (chainString != 'ethereum') { + childChainRootGauges = await getChildChainRootGauge( + chainString === 'avax' + ? 'avalanche' + : chainString === 'xdai' + ? 'gnosis' + : chainString + ); + } + + // Global source of truth for the inflation rate. All mainnet gauges use the BalancerTokenAdmin contract to update their locally stored inflation rate during checkpoints. + const inflationRate = + ( + await sdk.api.abi.call({ + target: balancerTokenAdmin, + abi: balTokenAdminABI.find((n) => n.name === 'getInflationRate'), + chain: 'ethereum', + }) + ).output / 1e18; + + // Price is used for additional non-BAL reward tokens + let price; + + // get BAL price + const balKey = `ethereum:${BAL}`.toLowerCase(); + const balPrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${balKey}`) + ).body.coins[balKey].price; + + // add LM rewards if available to each pool in data + for (const pool of liquidityGauges) { + try { + const x = data.find((el) => el.id === pool.poolId); + if (x === undefined) { + continue; + } + + const aprLMRewards = []; + const rewardTokens = []; + + // pool.id returned for mainnet will be the correct gauge address required for the gauge_relative_weight call + let relativeWeightParams = pool.id; + + // pool.id returned for child chains is the child chain gauge, so we must replace this with it's mainnet root chain gauge that gauge_relative_weight expects. + if (chainString != 'ethereum') { + const poolGaugeOnEthereum = childChainRootGauges.find( + (gauge) => gauge.recipient == pool.id + ); + + if (poolGaugeOnEthereum) { + relativeWeightParams = poolGaugeOnEthereum.id; + } + } + + // get relative weight (of base BAL token rewards for a pool) + const relativeWeight = + ( + await sdk.api.abi.call({ + target: gaugeController, + abi: gaugeControllerEthereum.find( + (n) => n.name === 'gauge_relative_weight' + ), + params: [relativeWeightParams], + chain: 'ethereum', + }) + ).output / 1e18; + + // for base BAL rewards + if (relativeWeight !== 0) { + const workingSupply = + ( + await sdk.api.abi.call({ + target: pool.id, + abi: gaugeABI.find((n) => n.name === 'working_supply'), + chain: chainString, + }) + ).output / 1e18; + + // bpt == balancer pool token + const bptPrice = x.tvl / x.totalShares; + const balPayable = inflationRate * 7 * 86400 * relativeWeight; + const weeklyReward = (0.4 / (workingSupply + 0.4)) * balPayable; + const yearlyReward = weeklyReward * 52 * balPrice; + const aprLM = (yearlyReward / bptPrice) * 100; + aprLMRewards.push(aprLM === Infinity ? 0 : aprLM); + rewardTokens.push(BAL); + } + + // first need to find the reward token + // (balancer UI loops up to 8times, will replicate the same logic) + const MAX_REWARD_TOKENS = 8; + for (let i = 0; i < MAX_REWARD_TOKENS; i++) { + // get token reward address + const add = ( + await sdk.api.abi.call({ + target: pool.id, + abi: gaugeABI.find((n) => n.name === 'reward_tokens'), + params: [i], + chain: chainString, + }) + ).output.toLowerCase(); + if (add === '0x0000000000000000000000000000000000000000') { + break; + } + + // get cg price of reward token + const key = `${chainString}:${add}`.toLowerCase(); + const price = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key]?.price; + + // call reward data + const { rate, period_finish } = ( + await sdk.api.abi.call({ + target: pool.id, + abi: gaugeABI.find((n) => n.name === 'reward_data'), + params: [add], + chain: chainString, + }) + ).output; + + if (period_finish * 1000 < new Date().getTime()) continue; + const inflationRate = rate / 1e18; + const tokenPayable = inflationRate * 7 * 86400; + const totalSupply = + ( + await sdk.api.abi.call({ + target: pool.id, + abi: gaugeABI.find((n) => n.name === 'totalSupply'), + chain: chainString, + }) + ).output / 1e18; + + const weeklyRewards = (1 / (totalSupply + 1)) * tokenPayable; + const yearlyRewards = weeklyRewards * 52 * price; + const bptPrice = x.tvl / x.totalShares; + const aprLM = (yearlyRewards / bptPrice) * 100; + + aprLMRewards.push(aprLM === Infinity ? null : aprLM); + rewardTokens.push(add); + } + // add up individual LM rewards + x.aprLM = aprLMRewards + .filter((i) => isFinite(i)) + .reduce((a, b) => a + b, 0); + + x.rewardTokens = rewardTokens; + } catch (err) { + console.log('failed for', pool.poolId); + } + } + return data; +}; + +const aprFee = (el, dataNow, dataPrior, swapFeePercentage) => { + const swapFeeNow = dataNow.find((x) => x.id === el.id)?.totalSwapFee; + const swapFeePrior = dataPrior.find((x) => x.id === el.id)?.totalSwapFee; + const swapFee24h = Number(swapFeeNow) - Number(swapFeePrior); + + el.aprFee = ((swapFee24h * 365) / el.tvl) * 100 * swapFeePercentage; + return el; +}; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + urlGauge, + queryGauge, + gaugeABI, + swapFeePercentage +) => { + const [_, blockPrior] = await utils.getBlocks(chainString, null, [url]); + // pull data + let dataNow = await request(url, query); + let dataPrior = await request( + url, + queryPrior.replace('', blockPrior) + ); + + // correct for missing maker symbol + dataNow = dataNow.pools.map((el) => correctMaker(el)); + dataPrior = dataPrior.pools.map((el) => correctMaker(el)); + + // for tvl, we gonna pull token prices from our price api, which we use to calculate tvl + // note: the subgraph already comes with usd tvl values, but sometimes they are inflated + const tokenList = [ + ...new Set( + dataNow + .map((el) => el.tokens) + .flat() + .map((el) => el.address) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokenList.length / maxSize); + let pricesA = []; + let keys = ''; + for (const p of [...Array(pages).keys()]) { + keys = tokenList + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `${chainString}:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await superagent.get(`https://coins.llama.fi/prices/current/${keys}`)) + .body.coins, + ]; + } + let tokenPriceList = {}; + for (const p of pricesA) { + tokenPriceList = { ...tokenPriceList, ...p }; + } + + // calculate tvl + let tvlInfo = dataNow.map((el) => tvl(el, tokenPriceList, chainString)); + + // calculate fee apy + tvlInfo = tvlInfo.map((el) => + aprFee(el, dataNow, dataPrior, swapFeePercentage) + ); + + // calculate reward apr + tvlInfo = await aprLM(tvlInfo, urlGauge, queryGauge, chainString, gaugeABI); + + // build pool objects + return tvlInfo.map((p) => { + const chainUrl = + chainString === 'avax' + ? 'avalanche' + : chainString === 'xdai' + ? 'gnosis' + : chainString; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'balancer-v2', + symbol: utils.formatSymbol(p.symbol), + tvlUsd: p.tvl, + apyBase: p.aprFee, + apyReward: + p.id === + '0x8167a1117691f39e05e9131cfa88f0e3a620e96700020000000000000000038c' // WETH-T wrong bal apr + ? 0 + : p.aprLM, + rewardTokens: p.rewardTokens, + underlyingTokens: p.tokensList, + url: `https://balancer.fi/pools/${chainUrl}/v2/${p.id}`, + }; + }); +}; + +const main = async () => { + // balancer splits off a pct cut of swap fees to the protocol, get pct value: + const swapFeePercentage = + ( + await sdk.api.abi.call({ + target: protocolFeesCollector, + abi: protocolFeesCollectorABI.find( + (n) => n.name === 'getSwapFeePercentage' + ), + chain: 'ethereum', + }) + ).output / 1e18; + + const data = await Promise.allSettled([ + topLvl( + 'ethereum', + urlEthereum, + query, + queryPrior, + urlGaugesEthereum, + queryGauge, + gaugeABIEthereum, + swapFeePercentage + ), + topLvl( + 'polygon', + urlPolygon, + query, + queryPrior, + urlGaugesPolygon, + queryGauge, + gaugeABIPolygon, + swapFeePercentage + ), + topLvl( + 'arbitrum', + urlArbitrum, + query, + queryPrior, + urlGaugesArbitrum, + queryGauge, + gaugeABIArbitrum, + swapFeePercentage + ), + topLvl( + 'xdai', + urlGnosis, + query, + queryPrior, + urlGaugesGnosis, + queryGauge, + gaugeABIGnosis, + swapFeePercentage + ), + topLvl( + 'base', + urlBaseChain, + query, + queryPrior, + urlGaugesBase, + queryGauge, + gaugeABIBase, + swapFeePercentage + ), + topLvl( + 'avax', + urlAvalanche, + query, + queryPrior, + urlGaugesAvalanche, + queryGauge, + gaugeABIArbitrum, + swapFeePercentage + ), + ]); + + return data + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => utils.keepFinite(p) && !excludePools.includes(p.pool)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/balancer-v3/index.ts b/src/adaptors/balancer-v3/index.ts new file mode 100644 index 0000000000..4b4c7f54ce --- /dev/null +++ b/src/adaptors/balancer-v3/index.ts @@ -0,0 +1,124 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); + +const query = gql` + query GetPools($chain: GqlChain!) { + poolGetPools( + first: 1000 + where: { chainIn: [$chain], protocolVersionIn: [3] } + ) { + chain + symbol + address + poolTokens { + address + symbol + } + dynamicData { + totalLiquidity + aprItems { + type + apr + rewardTokenAddress + } + } + } + } +`; + +const getV3Pools = async (backendChain, chainString) => { + try { + const { poolGetPools } = await request( + 'https://api-v3.balancer.fi/graphql', + query, + { chain: backendChain } + ); + + return poolGetPools.map((pool) => { + const aprItems = pool.dynamicData.aprItems || []; + + const baseApr = aprItems + .filter( + (item) => item.type === 'IB_YIELD' || item.type === 'SWAP_FEE_24H' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const stakingApr = aprItems + .filter((item) => item.type === 'STAKING') + .reduce((sum, item) => sum + Number(item.apr), 0); + + const rewardTokens = aprItems + .filter((item) => item.type === 'STAKING' && item.rewardTokenAddress) + .map((item) => item.rewardTokenAddress); + + const underlyingTokens = pool.poolTokens + .map((token) => token.address) + .filter(Boolean); + + const chainUrl = + chainString === 'xdai' + ? 'gnosis' + : chainString === 'avax' + ? 'avalanche' + : chainString; + + return { + pool: pool.address, + chain: utils.formatChain(chainString), + project: 'balancer-v3', + symbol: utils.formatSymbol(pool.symbol), + tvlUsd: Number(pool.dynamicData.totalLiquidity), + apyBase: baseApr * 100, + apyReward: stakingApr * 100, + rewardTokens: rewardTokens, + underlyingTokens: underlyingTokens, + url: `https://balancer.fi/pools/${chainUrl}/v3/${pool.address}`, + }; + }); + } catch (error) { + console.error( + `Error fetching Balancer V3 pools for ${chainString}:`, + error + ); + return []; + } +}; + +const poolsFunction = async () => { + const [ + mainnetPools, + gnosisPools, + arbitrumPools, + optimismPools, + avalanchePools, + basePools, + hyperliquidPools, + plasmaPools, + ] = await Promise.all([ + getV3Pools('MAINNET', 'ethereum'), + getV3Pools('GNOSIS', 'xdai'), + getV3Pools('ARBITRUM', 'arbitrum'), + getV3Pools('OPTIMISM', 'optimism'), + getV3Pools('AVALANCHE', 'avax'), + getV3Pools('BASE', 'base'), + getV3Pools('HYPEREVM', 'hyperliquid'), + getV3Pools('PLASMA', 'plasma'), + ]); + + return [ + ...mainnetPools, + ...gnosisPools, + ...arbitrumPools, + ...optimismPools, + ...avalanchePools, + ...basePools, + ...hyperliquidPools, + ...plasmaPools, + ]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://balancer.fi/pools', +}; diff --git a/src/adaptors/balancer/index.js b/src/adaptors/balancer/index.js deleted file mode 100755 index e566965e12..0000000000 --- a/src/adaptors/balancer/index.js +++ /dev/null @@ -1,384 +0,0 @@ -const { request, gql } = require('graphql-request'); -const Web3 = require('web3'); -const utils = require('../utils'); -const gaugeABIEthereum = require('./abis/gauge_ethereum.json'); -const gaugeABIArbitrum = require('./abis/gauge_arbitrum.json'); -const gaugeABIPolygon = require('./abis/gauge_polygon.json'); -const gaugeControllerEthereum = require('./abis/gauge_controller_ethereum.json'); -const protocolFeesCollectorABI = require('./abis/protocol_fees_collector.json'); - -// Subgraph URLs -const urlBase = 'https://api.thegraph.com/subgraphs/name/balancer-labs'; -const urlEthereum = `${urlBase}/balancer-v2`; -const urlPolygon = `${urlBase}/balancer-polygon-v2`; -const urlArbitrum = `${urlBase}/balancer-arbitrum-v2`; - -const urlGaugesEthereum = `${urlBase}/balancer-gauges`; -const urlGaugesPolygon = `${urlBase}/balancer-gauges-polygon`; -const urlGaugesArbitrum = `${urlBase}/balancer-gauges-arbitrum`; - -const protocolFeesCollector = '0xce88686553686DA562CE7Cea497CE749DA109f9F'; - -const queryGauge = gql` - { - liquidityGauges(first: 999) { - id - symbol - poolId - totalSupply - factory { - id - } - tokens { - id - symbol - decimals - } - } - } -`; - -const query = gql` - { - pools( - first: 1000 - orderBy: "totalLiquidity" - orderDirection: "desc" - where: { totalShares_gt: 0.01 } - skip: 0 - ) { - id - tokensList - totalSwapFee - totalShares - tokens { - address - balance - symbol - } - } - } -`; - -const queryPrior = gql` -{ - pools( - first: 1000 - orderBy: "totalLiquidity" - orderDirection: "desc" - where: { totalShares_gt: 0.01 } - block: {number: } - ) { - id - tokensList - totalSwapFee - tokens { - address - balance - symbol - } - } -} -`; - -// coingecko chain mapping -const networkMappingCG = { - ethereum: 'ethereum', - polygon: 'polygon-pos', - arbitrum: 'arbitrum-one', -}; - -const correctMaker = (entry) => { - entry = { ...entry }; - // for some reason the MKR symbol is not there, add this manually for - // token address 0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2 = makerdao - for (const x of entry.tokens) { - if (x.address === '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2') { - x.symbol = 'MKR'; - } - } - - return entry; -}; - -const tvl = (entry, tokenPriceList) => { - entry = { ...entry }; - - const balanceDetails = entry.tokens; - const d = { - id: entry.id, - symbol: balanceDetails.map((tok) => tok.symbol).join('-'), - tvl: 0, - totalShares: entry.totalShares - }; - for (const el of balanceDetails) { - // some addresses are from tokens which are not listed on coingecko so these will result in undefined - const price = tokenPriceList[el.address]?.usd; - // if price is undefined of one token in pool, the total tvl will be NaN - d.tvl += Number(el.balance) * price; - } - - return d; -}; - -const aprLM = async (tvlData, urlLM, queryLM, chainString, gaugeABI) => { - // copy - const data = tvlData.map((a) => ({ ...a })); - - // get liquidity gauges for each pool - const { liquidityGauges } = await request(urlLM, queryLM); - - // web 3 connection - if (chainString === 'ethereum') { - conn = process.env.INFURA_CONNECTION; - } else if (chainString === 'arbitrum') { - conn = process.env.ALCHEMY_CONNECTION_ARBITRUM; - } else if (chainString === 'polygon') { - conn = process.env.ALCHEMY_CONNECTION_POLYGON; - } - const web3 = new Web3(conn); - - // get BAL inflation rate (constant among gauge contract ids) - if (chainString === 'ethereum') { - const gaugeContract = new web3.eth.Contract( - gaugeABI, - liquidityGauges[0].id - ); - inflationRate = - (await gaugeContract.methods.inflation_rate().call()) / 1e18; - - const gaugeController = '0xC128468b7Ce63eA702C1f104D55A2566b13D3ABD'; - gaugeControllerContract = new web3.eth.Contract( - gaugeControllerEthereum, - gaugeController - ); - - // get BAL price - balToken = '0xba100000625a3754423978a60c9317c58a424e3d'; - - // get cg price of reward token - prices = await utils.getCGpriceData( - balToken, - false, - networkMappingCG[chainString] - ); - } - - // add LM rewards if available to each pool in data - for (const pool of liquidityGauges) { - const x = data.find((el) => el.id === pool.poolId); - if (x === undefined) { - continue; - } - - // connect to specific gauge contract - const gauge = new web3.eth.Contract(gaugeABI, pool.id); - - const aprLMRewards = []; - - if (chainString === 'ethereum') { - // get relative weight (of base BAL token rewards for a pool) - const relativeWeight = - (await gaugeControllerContract.methods - .gauge_relative_weight(pool.id) - .call()) / 1e18; - - // for base BAL rewards - if (relativeWeight !== 0) { - const workingSupply = - (await gauge.methods.working_supply().call()) / 1e18; - // bpt == balancer pool token - const bptPrice = x.tvl / x.totalShares; - const balPayable = inflationRate * 7 * 86400 * relativeWeight; - const weeklyReward = (0.4 / (workingSupply + 0.4)) * balPayable; - const yearlyReward = weeklyReward * 52 * prices[balToken].usd; - const aprLM = (yearlyReward / bptPrice) * 100; - aprLMRewards.push(aprLM === Infinity ? 0 : aprLM); - } - } - - // first need to find the reward token - // (balancer UI loops up to 8times, will replicate the same logic) - const MAX_REWARD_TOKENS = 8; - for (let i = 0; i < MAX_REWARD_TOKENS; i++) { - // get token reward address - const add = (await gauge.methods.reward_tokens(i).call()).toLowerCase(); - if (add === '0x0000000000000000000000000000000000000000') { - break; - } - - // get cg price of reward token - const prices = await utils.getCGpriceData( - add, - false, - networkMappingCG[chainString] - ); - - // call reward data - const { rate } = await gauge.methods.reward_data(add).call(); - const inflationRate = rate / 1e18; - const tokenPayable = inflationRate * 7 * 86400; - const totalSupply = (await gauge.methods.totalSupply().call()) / 1e18; - - const weeklyRewards = (1 / (totalSupply + 1)) * tokenPayable; - const yearlyRewards = weeklyRewards * 52 * prices[add].usd; - const bptPrice = x.tvl / x.totalShares; - const aprLM = (yearlyRewards / bptPrice) * 100; - - aprLMRewards.push(aprLM === Infinity ? null : aprLM); - } - - // add up individual LM rewards - x.aprLM = aprLMRewards - .filter((i) => isFinite(i)) - .reduce((a, b) => a + b, 0); - } - return data; -}; - -const aprFee = (el, dataNow, dataPrior, swapFeePercentage) => { - const swapFeeNow = dataNow.find((x) => x.id === el.id)?.totalSwapFee; - const swapFeePrior = dataPrior.find((x) => x.id === el.id)?.totalSwapFee; - const swapFee24h = Number(swapFeeNow) - Number(swapFeePrior); - - el.aprFee = ((swapFee24h * 365) / el.tvl) * 100 * swapFeePercentage; - return el; -}; - -const buildPool = (el, chainString) => { - const newObj = { - pool: el.id, - chain: utils.formatChain(chainString), - project: 'balancer', - symbol: utils.formatSymbol(el.symbol), - tvlUsd: el.tvl, - apy: el.aprFee + (el?.aprLM ?? 0), - }; - - return newObj; -}; - -const topLvl = async ( - chainString, - url, - query, - queryPrior, - urlGauge, - queryGauge, - gaugeABI, - swapFeePercentage -) => { - const [_, blockPrior] = await utils.getBlocks(chainString, null, [url]); - // pull data - let dataNow = await request(url, query); - let dataPrior = await request( - url, - queryPrior.replace('', blockPrior) - ); - - // correct for missing maker symbol - dataNow = dataNow.pools.map((el) => correctMaker(el)); - dataPrior = dataPrior.pools.map((el) => correctMaker(el)); - - // get unique tokenList (addresses)(for which we pull prices from cg) - const tokenList = [ - ...new Set( - dataNow - .map((el) => el.tokens) - .flat() - .map((el) => el.address) - ), - ]; - - // NOTE(!) had to split the list cause i was getting errors on full list - // guess because of too many token - const idxSplitter = Math.floor(tokenList.length / 2); - const tokenListP1 = tokenList.splice(0, idxSplitter); - const tokenListP2 = tokenList.splice(idxSplitter); - - // pull prices from coingecko - const tokenPriceList1 = await utils.getCGpriceData( - tokenListP1.join(), - false, - networkMappingCG[chainString] - ); - const tokenPriceList2 = await utils.getCGpriceData( - tokenListP2.join(), - false, - networkMappingCG[chainString] - ); - - const tokenPriceList = { ...tokenPriceList1, ...tokenPriceList2 }; - - // calculate tvl - let tvlInfo = dataNow.map((el) => tvl(el, tokenPriceList)); - - // calculate fee apy - tvlInfo = tvlInfo.map((el) => - aprFee(el, dataNow, dataPrior, swapFeePercentage) - ); - - // calculate reward apr - tvlInfo = await aprLM(tvlInfo, urlGauge, queryGauge, chainString, gaugeABI); - - // build pool objects - let data = tvlInfo.map((el) => buildPool(el, chainString)); - - // remove samples for which apy is NaN (usually the case if tvl is Nan, because of no price from CG) - data = data.filter((el) => Number.isNaN(el.apy) !== true); - - return data; -}; - -const main = async () => { - // balancer splits off a pct cut of swap fees to the protocol, get pct value: - conn = process.env.INFURA_CONNECTION; - const web3 = new Web3(conn); - - const feeCollectorContract = new web3.eth.Contract( - protocolFeesCollectorABI, - protocolFeesCollector - ); - const swapFeePercentage = - (await feeCollectorContract.methods.getSwapFeePercentage().call()) / 1e18; - - const data = await Promise.all([ - topLvl( - 'ethereum', - urlEthereum, - query, - queryPrior, - urlGaugesEthereum, - queryGauge, - gaugeABIEthereum, - swapFeePercentage - ), - topLvl( - 'polygon', - urlPolygon, - query, - queryPrior, - urlGaugesPolygon, - queryGauge, - gaugeABIPolygon, - swapFeePercentage - ), - topLvl( - 'arbitrum', - urlArbitrum, - query, - queryPrior, - urlGaugesArbitrum, - queryGauge, - gaugeABIArbitrum, - swapFeePercentage - ), - ]); - - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/balmy/index.ts b/src/adaptors/balmy/index.ts new file mode 100755 index 0000000000..2c4a830f45 --- /dev/null +++ b/src/adaptors/balmy/index.ts @@ -0,0 +1,244 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +// Balmy's Earn showcases existing yield opportunities and allows users to manage all their yield positions in one place. We've also added the concept of Guardians. These are accounts that +// have the job of monitoring all transactions in a blockchain and when they predict a hack is about to happen, they can rescue user funds from the underlying protocol. +// As discussed with the Defi-Llama team, we will only be listing vaults (we call them strategies) that provide an extra yield on top of the underlying protocol. This is so that we don't repeat +// the same pools already on the Defi-Llama yield section. We will be fetching the underlying protocol's APY (using Defi-Llama's yield API) and adding the Balmy yield on top of it. + +const API = 'https://api.balmy.xyz'; +const LIQ_MINING_MANAGER = '0xE7615B68BFe7664488881080DF9dD62681A781A1' + +async function getPoolsInChain(chainId: number, chainName: string, { strategies, tokens }: StrategiesInChainResponse, mappings: Record): Promise { + const strategiesToFetch = strategies + .filter((strategy) => strategy.farm.rewards && strategy.farm.rewards.tokens.length > 0) // If there are no rewards, we'll skip the strategy + .filter((strategy) => strategy.farm.id in mappings) // If we can't map from farm id to defi llama yield id, we'll skip the strategy + + const currentEmissions = await fetchCurrentEmissions(chainName, strategiesToFetch); + + const strategiesWithCurrentEmissions = strategiesToFetch + .filter((strategy) => strategy.id in currentEmissions) + + const [tvls, apys] = await Promise.all([ + fetchTvl(chainName, strategiesWithCurrentEmissions), + fetchAPYs(strategiesWithCurrentEmissions, mappings), + ]); + + return strategiesWithCurrentEmissions.map((strategy) => { + const [_, registry, id] = strategy.id.split('-'); + + const tvl = Number(tvls[strategy.id]); + const { price, decimals } = tokens[strategy.farm.asset.address]; + const tvlUsd = price * (tvl / 10 ** decimals); + + let extraRewardAPY = 0; + const emissions = currentEmissions[strategy.id]; + for (const [reward, emissionPerSecond] of Object.entries(emissions)) { + const { price, decimals } = tokens[reward]; + const emissionInUSD = price * (Number(emissionPerSecond) / 10 ** decimals); + const yearlyEmission = emissionInUSD * 60 * 60 * 24 * 365; + extraRewardAPY += (yearlyEmission * 100) / tvlUsd; + } + + const apy = apys[strategy.farm.id]; + return { + // The pool doesn't return an ERC20, so we will be using the `{registry}-{assignedId}-{chainName}` format + pool: `${registry}-${id}-${chainName}`.toLowerCase(), + chain: chainName, + project: 'balmy', + symbol: `${tokens[strategy.farm.asset.address].symbol}`, + url: `https://app.balmy.xyz/earn/vaults/${chainId}/${strategy.id}`, + underlyingTokens: [strategy.farm.asset.address], + rewardTokens: strategy.farm.rewards.tokens.map((token) => token.address), + tvlUsd, + apyBase: apy.apyBase, + apyReward: apy.apyReward + extraRewardAPY, + poolMeta: strategy.farm.protocol, + } + }) +} + +async function fetchCurrentEmissions(chainName: string, strategies: StrategiesInChainResponse['strategies']) { + const rewardsPerStrategy = strategies.flatMap((strategy) => { + const [_, __, id] = strategy.id.split('-'); + return strategy.farm.rewards.tokens.map((reward) => { + return { + strategyId: strategy.id, + assignedId: id, + reward: reward.address, + }; + }); + }); + + // Fetch emission data on the liq mining manager + const emissionData: { emissionPerSecond: `${bigint}`; deadline: `${bigint}`; }[] = await sdk.api.abi.multiCall({ + calls: rewardsPerStrategy.map(({ assignedId, reward }) => ({ + target: LIQ_MINING_MANAGER, + params: [assignedId, reward], + })), + abi: LIQ_MINING_MANAGER_CAMPAIGN_EMISSION_, + chain: chainName.toLowerCase(), + }).then(({ output }) => output.map(({ output }) => output)) + + // Filter out emissions that have already ended, and group them by strategyId + const nowInSeconds = Math.floor(Date.now() / 1000); + const currentEmissions: Record> = {}; // strategyId -> reward -> emissionPerSecond + emissionData.forEach(({ emissionPerSecond, deadline }, i) => { + if (BigInt(deadline) < BigInt(nowInSeconds)) return; + const { strategyId, reward } = rewardsPerStrategy[i]; + if (!currentEmissions[strategyId]) currentEmissions[strategyId] = {}; + currentEmissions[strategyId][reward] = BigInt(emissionPerSecond); + }); + + return currentEmissions; +} + +async function fetchTvl(chainName: string, strategies: StrategiesInChainResponse['strategies']) { + // Fetch addresses by id + const addresses: string[] = await sdk.api.abi.multiCall({ + calls: strategies.map((strategy) => { + const [_, registry, assignedId] = strategy.id.split('-'); + return { + target: registry, + params: [assignedId], + } + }), + abi: STRATEGY_REGISTRY_GET_STRATEGY, + chain: chainName.toLowerCase(), + }).then(({ output }) => output.map(({ output }) => output)) + + // Fetch balances + const balances: { tokens: string[], balances: `${bigint}`[] }[] = await sdk.api.abi.multiCall({ + calls: addresses.map((address) => ({ + target: address, + params: [], + })), + abi: STRATEGY_TOTAL_BALANCES, + chain: chainName.toLowerCase(), + }).then(({ output }) => output.map(({ output }) => output)) + + // Only report the balance of the first token (since the rest are rewards) + const result: Record = {}; // strategyId -> balance + balances.forEach(({ balances }, i) => { + result[strategies[i].id] = balances[0]; + }); + return result; +} + +async function fetchAPYs(strategies: StrategiesInChainResponse['strategies'], mappings: Record): Promise> { + // As discussed with the Defi-Llama team, we will fetch individual APYs for each strategy by using the chart endpoint + const farmIds = strategies + .map(({ farm }) => farm.id) + .filter((item, pos) => strategies.findIndex(({ farm }) => farm.id === item) === pos); // Remove duplicates + + const apys = await Promise.all(farmIds.map(async (farmId) => { + const url = `https://yields.llama.fi/chart/${mappings[farmId]}` + const data: { data: { apyBase: number, apyReward: number }[] } = await utils.getData(url) + const { apyBase, apyReward } = data.data[data.data.length - 1] + return [farmId, { apyBase: apyBase ?? 0, apyReward: apyReward ?? 0 }] + })) + return Object.fromEntries(apys); +} + +async function fetchChains() { + const chains = await utils.getData('https://api.llama.fi/chains'); + return Object.fromEntries(chains.map(({ chainId, name }) => [chainId, name])); +} + +async function fetchMappings() { + const data = await utils.getData(`${API}/v1/earn/defi-llama/mappings`); + return data.poolIdsByFarm; +} + +const apy = async () => { + const [strategies, chains, mappings]: [StrategiesResponse, Record, Record] = await Promise.all([ + utils.getData(`${API}/v1/earn/strategies/supported`), + fetchChains(), + fetchMappings(), + ]); + + const allPools = await Promise.all(Object.entries(strategies.strategiesByNetwork) + .map(([chainId, strategies]) => getPoolsInChain(Number(chainId), chains[chainId], strategies, mappings))); + + return allPools + .flat() + .filter((p) => utils.keepFinite(p)); +}; + +// ABIS +const LIQ_MINING_MANAGER_CAMPAIGN_EMISSION_ = { + inputs: [ + { internalType: 'StrategyId', name: 'strategyId', type: 'uint96' }, + { internalType: 'address', name: 'token', type: 'address' }, + ], + name: 'campaignEmission', + outputs: [ + { internalType: 'uint256', name: 'emissionPerSecond', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', +}; + +const STRATEGY_REGISTRY_GET_STRATEGY = { + inputs: [{ internalType: 'StrategyId', name: 'strategyId', type: 'uint96' }], + name: 'getStrategy', + outputs: [{ internalType: 'contract IEarnStrategy', name: 'strategy', type: 'address' }], + stateMutability: 'view', + type: 'function', +}; + +const STRATEGY_TOTAL_BALANCES = { + inputs: [], + name: 'totalBalances', + outputs: [ + { internalType: 'address[]', name: 'tokens', type: 'address[]' }, + { internalType: 'uint256[]', name: 'balances', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', +} + +// TYPES +type StrategiesResponse = { + strategiesByNetwork: Record +} + +type StrategiesInChainResponse = { + strategies: { + id: string; + farm: { + id: string; + protocol: string; + asset: { + address: string; + } + rewards?: { + tokens: { address: string }[] + } + } + }[], + tokens: Record; +} + +type Pool = { + pool: string, + chain: string, + project: 'balmy', + symbol: string, + tvlUsd: number, + apyBase: number, + apyReward: number, + rewardTokens: string[] + url: string, + underlyingTokens: string[] +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/bancor-v3/index.js b/src/adaptors/bancor-v3/index.js new file mode 100644 index 0000000000..9c7e69df14 --- /dev/null +++ b/src/adaptors/bancor-v3/index.js @@ -0,0 +1,30 @@ +const utils = require('../utils'); + +const POOLS_URL = 'https://api-v3.bancor.network/pools'; + +const apy = async () => { + const { data } = await utils.getData(POOLS_URL); + + const pools = data.map((pool) => { + const apy = + (((Number(pool.fees7d.usd) / 10) * 52) / Number(pool.stakedBalance.usd)) * + 100; + return { + pool: `bancor-${pool.poolDltId}`, + project: 'bancor-v3', + chain: utils.formatChain('ethereum'), + symbol: pool.name, + tvlUsd: Number(pool.stakedBalance.usd), + apyBase: Number.isFinite(apy) ? apy : 0, + + underlyingTokens: [pool.poolDltId], + }; + }); + return pools; +}; + +module.exports = { + apy, + url: 'https://app.bancor.network/earn', + timetravel: false, +}; diff --git a/src/adaptors/bancor/index.js b/src/adaptors/bancor/index.js deleted file mode 100755 index 6321425e95..0000000000 --- a/src/adaptors/bancor/index.js +++ /dev/null @@ -1,54 +0,0 @@ -const utils = require('../utils'); - -const url = 'https://api-v2.bancor.network/pools'; - -const apy = (entry) => { - entry = { ...entry }; - if (entry.name === null || entry.name === undefined) { - return; - } - const annualiser = 365; - const numer = Number(entry.fees_24h.usd) * annualiser; - const denom = Number(entry.liquidity.usd); - const apr = (numer / denom) * 100; - - entry.key = entry.name.replace('/', '-'); - entry.apr = Number.isNaN(apr) ? 0 : apr; - - return entry; -}; - -const buildPool = (entry, chainString) => { - const newObj = { - pool: entry.converter_dlt_id, - chain: utils.formatChain(chainString), - project: 'bancor', - symbol: utils.formatSymbol(entry.key), - tvlUsd: entry.liquidity.usd, - apy: entry.apr, - }; - return newObj; -}; - -const topLvl = async (chainString, url) => { - // pull data - let data = await utils.getData(url); - - // calculate apy - data = data.data.map((el) => apy(el)); - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async () => { - const data = await Promise.all([topLvl('ethereum', url)]); - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/bank-of-chain/index.js b/src/adaptors/bank-of-chain/index.js new file mode 100644 index 0000000000..fca2089515 --- /dev/null +++ b/src/adaptors/bank-of-chain/index.js @@ -0,0 +1,76 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const vault_abi = require('./vault_abi.json'); +const USD_APY_URL = + 'https://service-pr02-sg.bankofchain.io/apy/vault_apy?chainId=1&duration=monthly&offset=0&limit=1&tokenType=USDi'; +const ETH_APY_URL = + 'https://service-pr02-sg.bankofchain.io/apy/vault_apy?chainId=1&duration=monthly&offset=0&limit=1&tokenType=ETHi'; +const USD_VAULT_ADDRESS = '0x30D120f80D60E7b58CA9fFaf1aaB1815f000B7c3'; +const ETH_VAULT_ADDRESS = '0x8f0Cb368C63fbEDF7a90E43fE50F7eb8B9411746'; +const ethAddress = '0x0000000000000000000000000000000000000000'; + +const usd_apy = async () => { + const { content } = await utils.getData(USD_APY_URL); + const apy = Number(content[0].apy); + const trackedAssets = await sdk.api.abi.call({ + abi: vault_abi.getTrackedAssets, + chain: 'ethereum', + target: USD_VAULT_ADDRESS, + }); + const totalAsset = await sdk.api.abi.call({ + abi: vault_abi.totalAssets, + chain: 'ethereum', + target: USD_VAULT_ADDRESS, + }); + + return { + pool: `${USD_VAULT_ADDRESS}-ethereum`, + chain: utils.formatChain('ethereum'), + project: 'bank-of-chain', + symbol: 'USDi', + tvlUsd: Number(totalAsset.output / 10 ** 18), + apyBase: Number.isFinite(apy) ? apy : 0, + underlyingTokens: trackedAssets.output, + }; +}; + +const eth_apy = async () => { + const { content } = await utils.getData(ETH_APY_URL); + const apy = Number(content[0].apy); + const trackedAssets = await sdk.api.abi.call({ + abi: vault_abi.getTrackedAssets, + chain: 'ethereum', + target: ETH_VAULT_ADDRESS, + }); + const totalAsset = await sdk.api.abi.call({ + abi: vault_abi.totalAssets, + chain: 'ethereum', + target: ETH_VAULT_ADDRESS, + }); + const key = 'ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + const ethPriceUSD = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + + return { + pool: `${ETH_VAULT_ADDRESS}-ethereum`, + chain: utils.formatChain('ethereum'), + project: 'bank-of-chain', + symbol: 'ETHi', + tvlUsd: Number((totalAsset.output * ethPriceUSD) / 10 ** 18), + apyBase: Number.isFinite(apy) ? apy : 0, + underlyingTokens: trackedAssets.output, + }; +}; + +const apy = async () => { + const pools = [await usd_apy(), await eth_apy()]; + return pools; +}; + +module.exports = { + apy, + url: 'https://bankofchain.io', + timetravel: false, +}; diff --git a/src/adaptors/bank-of-chain/vault_abi.json b/src/adaptors/bank-of-chain/vault_abi.json new file mode 100644 index 0000000000..ce5d17a4fd --- /dev/null +++ b/src/adaptors/bank-of-chain/vault_abi.json @@ -0,0 +1,28 @@ +{ + "getTrackedAssets":{ + "inputs": [], + "name": "getTrackedAssets", + "outputs": [ + { + "internalType": "address[]", + "name": "_assets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAssets":{ + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + } \ No newline at end of file diff --git a/src/adaptors/barnbridge/IProvider.js b/src/adaptors/barnbridge/IProvider.js new file mode 100644 index 0000000000..b5b3a3cfd3 --- /dev/null +++ b/src/adaptors/barnbridge/IProvider.js @@ -0,0 +1,21 @@ +const sdk = require('@defillama/sdk'); + +const IProvider = require('./abis/IProvider.js'); + +exports.underlyingBalance = async (chain, target) => + ( + await sdk.api.abi.call({ + abi: IProvider.find((i) => i.name === 'underlyingBalance'), + chain: chain.name, + target: target, + }) + ).output; + +exports.totalUnRedeemed = async (chain, target) => + ( + await sdk.api.abi.call({ + abi: IProvider.find((i) => i.name === 'totalUnRedeemed'), + chain: chain.name, + target: target, + }) + ).output; diff --git a/src/adaptors/barnbridge/SmartYield.js b/src/adaptors/barnbridge/SmartYield.js new file mode 100644 index 0000000000..eb6fa006a3 --- /dev/null +++ b/src/adaptors/barnbridge/SmartYield.js @@ -0,0 +1,16 @@ +const sdk = require('@defillama/sdk'); + +const SmartYield = require('./abis/SmartYield.js'); + +exports.poolByProvider = async (chain, provider) => { + const pool = ( + await sdk.api.abi.call({ + abi: SmartYield.find((i) => i.name === 'poolByProvider'), + chain: chain.name, + target: chain.address, + params: [provider], + }) + ).output; + + return pool; +}; diff --git a/src/adaptors/barnbridge/abis/IProvider.js b/src/adaptors/barnbridge/abis/IProvider.js new file mode 100644 index 0000000000..095b63fe99 --- /dev/null +++ b/src/adaptors/barnbridge/abis/IProvider.js @@ -0,0 +1,370 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'addTotalUnRedeemed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'claimRewardsTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'start', + type: 'uint40', + }, + { + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateralBond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'enum IProvider.DebtStatus', + name: 'status', + type: 'uint8', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + ], + internalType: 'struct IProvider.Debt', + name: 'debt', + type: 'tuple', + }, + ], + name: 'computeHealthFactor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'start', + type: 'uint40', + }, + { + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateralBond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'enum IProvider.DebtStatus', + name: 'status', + type: 'uint8', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + ], + internalType: 'struct IProvider.Debt', + name: '_debt', + type: 'tuple', + }, + ], + name: 'computeLtv', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'disableBorrowAsset', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'enableBorrowAsset', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getBorrowRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getHealthFactor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'preHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'repay', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'bool', + name: 'useAsCollateral', + type: 'bool', + }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'smartYield', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalUnRedeemed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'underlyingBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/barnbridge/abis/SmartYield.js b/src/adaptors/barnbridge/abis/SmartYield.js new file mode 100644 index 0000000000..49cb5343f0 --- /dev/null +++ b/src/adaptors/barnbridge/abis/SmartYield.js @@ -0,0 +1,1328 @@ +module.exports = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'providerBalance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'AddLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'BondIssued', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'BondRedeemed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'oldBond', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newBond', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newAmount', + type: 'uint256', + }, + ], + name: 'BondRolledOver', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nextId', + type: 'uint256', + }, + { + components: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'start', + type: 'uint40', + }, + { + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateralBond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'enum IProvider.DebtStatus', + name: 'status', + type: 'uint8', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + ], + indexed: false, + internalType: 'struct IProvider.Debt', + name: 'debt', + type: 'tuple', + }, + ], + name: 'Borrowed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'depositCap', + type: 'uint256', + }, + ], + name: 'DepositCapSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'nextTerm', + type: 'address', + }, + { + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'realizedYield', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'depositCap', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'liquidated', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct SmartYield.TermInfo', + name: 'term', + type: 'tuple', + }, + ], + name: 'InjectedRealizedYield', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debtId', + type: 'uint256', + }, + { + components: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'start', + type: 'uint40', + }, + { + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateralBond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'enum IProvider.DebtStatus', + name: 'status', + type: 'uint8', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + ], + indexed: false, + internalType: 'struct IProvider.Debt', + name: 'debt', + type: 'tuple', + }, + ], + name: 'Liquidated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'controller', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'provider', + type: 'address', + }, + ], + name: 'PoolCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'providerBalance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RemoveLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debtId', + type: 'uint256', + }, + { + components: [ + { + internalType: 'address', + name: 'borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'start', + type: 'uint40', + }, + { + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateralBond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'enum IProvider.DebtStatus', + name: 'status', + type: 'uint8', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + ], + indexed: false, + internalType: 'struct IProvider.Debt', + name: 'debt', + type: 'tuple', + }, + ], + name: 'Repaied', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'claimedAmounts', + type: 'uint256', + }, + ], + name: 'RewardsClaimed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + ], + name: 'TermLiquidated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'controller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'nextTerm', + type: 'address', + }, + { + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'realizedYield', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'depositCap', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'liquidated', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct SmartYield.TermInfo', + name: 'currentTerm', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'nextTerm', + type: 'address', + }, + { + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'realizedYield', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'depositCap', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'liquidated', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct SmartYield.TermInfo', + name: 'term', + type: 'tuple', + }, + ], + name: 'TermSetUp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'addLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bondTokenImpl', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_bondAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: '_borrowAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: '_borrowAmount', + type: 'uint256', + }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'buyBond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'address', + name: '_to', + type: 'address', + }, + ], + name: 'claimReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'controller', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_healthFactorGuard', + type: 'uint256', + }, + ], + name: 'createPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'address', + name: '_asset', + type: 'address', + }, + ], + name: 'disableBorrowAsset', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'address', + name: '_asset', + type: 'address', + }, + ], + name: 'enableBorrowAsset', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_debtId', + type: 'uint256', + }, + ], + name: 'getHealthFactor', + outputs: [ + { + internalType: 'uint256', + name: 'healthFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'compoundedBalance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + ], + name: 'getTermInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeRate', + type: 'uint256', + }, + { + internalType: 'address', + name: 'nextTerm', + type: 'address', + }, + { + internalType: 'address', + name: 'bond', + type: 'address', + }, + { + internalType: 'uint256', + name: 'realizedYield', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'depositCap', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'liquidated', + type: 'bool', + }, + ], + internalType: 'struct SmartYield.TermInfo', + name: 'termInfo', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_controller', + type: 'address', + }, + { + internalType: 'address', + name: '_bondTokenImpl', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'keeper', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_debtId', + type: 'uint256', + }, + ], + name: 'liquidateDebt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256[]', + name: '_amountOutMins', + type: 'uint256[]', + }, + ], + name: 'liquidateTerm', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'poolByProvider', + outputs: [ + { + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + internalType: 'uint256', + name: 'liquidityProviderBalance', + type: 'uint256', + }, + { + internalType: 'address', + name: 'activeTerm', + type: 'address', + }, + { + internalType: 'uint256', + name: 'healthFactorGuard', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'nextDebtId', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + ], + name: 'preHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'provideRealizedYield', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'providerByBond', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'redeemBond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'removeLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_debtId', + type: 'uint256', + }, + ], + name: 'repay', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_tokenAmount', + type: 'uint256', + }, + ], + name: 'rolloverBond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newController', + type: 'address', + }, + ], + name: 'setController', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bond', + type: 'address', + }, + { + internalType: 'uint256', + name: '_depositCap', + type: 'uint256', + }, + ], + name: 'setDepositCap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_healthFactorGuard', + type: 'uint256', + }, + ], + name: 'setHealthFactorGuard', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_keeper', + type: 'address', + }, + ], + name: 'setKeeper', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'uint256', + name: '_start', + type: 'uint256', + }, + { + internalType: 'uint16', + name: '_termLength', + type: 'uint16', + }, + { + internalType: 'uint16', + name: '_feeRate', + type: 'uint16', + }, + { + internalType: 'address', + name: '_currentTerm', + type: 'address', + }, + { + internalType: 'uint256', + name: '_depositCap', + type: 'uint256', + }, + ], + name: 'setNextTermFor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'paused', + type: 'bool', + }, + ], + name: 'setPaused', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + { + internalType: 'address', + name: '_asset', + type: 'address', + }, + { + internalType: 'bool', + name: '_useAsCollateral', + type: 'bool', + }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_vault', + type: 'address', + }, + ], + name: 'setVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bondProvider', + type: 'address', + }, + ], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vault', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/barnbridge/index.js b/src/adaptors/barnbridge/index.js new file mode 100644 index 0000000000..75d055327d --- /dev/null +++ b/src/adaptors/barnbridge/index.js @@ -0,0 +1,91 @@ +const sdk = require('@defillama/sdk'); +const { getActiveTerms, getPastAndActiveTerms } = require('./subgraph.js'); + +const { + totalValueLockedForTerms, + earnedYieldByProviderForTerms, + earnedYieldIfNextTermOfActiveTerm, + apyBase, +} = require('./numbers.js'); + +const CHAINS = [ + { + id: 1, + name: 'ethereum', + url: sdk.graph.modifyEndpoint('37rapC8GX3YmFpv1y8BWmu5xvHPLTRvn3uxQHd6CEmJ7'), + address: '0xc67cb09d08521cD1dE6BAAC46824261eb1dB8800', + }, + { + id: 42161, + name: 'arbitrum', + url: sdk.graph.modifyEndpoint('CCYS6JgDCPHdMphsnHSrosEkbmmBhb69gwKLqRaxuCwK'), + address: '0xf878a060D4d51704B14e8f68B51185bF5DbFE3A1', + }, + { + id: 10, + name: 'optimism', + url: sdk.graph.modifyEndpoint('Fu6e7h47iJ2V4FdsPbogouXVSdDhmBET4gtKPNSZU7tM'), + address: '0x45c158E0ee76c76E525BaB941991268249e95331', + }, +]; + +const apy = async () => { + const pools = await Promise.all( + CHAINS.map(async (chain) => { + const pastAndActiveTerms = (await getPastAndActiveTerms(chain.url)).map( + (i) => ({ + ...i, + provider: i.provider.id, + }) + ); + + const activeTerms = (await getActiveTerms(chain.url)).map((i) => ({ + ...i, + provider: i.provider.id, + })); + + const tvlUsd = await totalValueLockedForTerms( + chain, + pastAndActiveTerms, + true + ); + + const earnedYieldsByProvider = await earnedYieldByProviderForTerms( + chain, + pastAndActiveTerms + ); + + return await Promise.all( + pastAndActiveTerms.map(async (term) => { + const earnedYield = earnedYieldIfNextTermOfActiveTerm( + activeTerms, + term.id, + earnedYieldsByProvider[term.provider] + ); + + const _apyBase = apyBase(term, earnedYield); + + return { + pool: `${term.id}`.toLowerCase(), + chain: chain.name, + project: 'barnbridge', + symbol: term.underlyingSymbol, + poolMeta: term.assetName, + tvlUsd, + apyBase: _apyBase, + underlyingTokens: [term.underlying], + url: `https://app.barnbridge.com/smart-yield/pools/details/?id=${term.id}&chainId=${chain.id}`, + }; + }) + ); + }) + ); + + return pools.flat(); +}; + +module.exports = { + apy, + url: 'https://app.barnbridge.com/smart-yield/pools/', + timetravel: false, +}; diff --git a/src/adaptors/barnbridge/numbers.js b/src/adaptors/barnbridge/numbers.js new file mode 100644 index 0000000000..963c189bc9 --- /dev/null +++ b/src/adaptors/barnbridge/numbers.js @@ -0,0 +1,169 @@ +const superagent = require('superagent'); +const { uniqBy, sumBy } = require('lodash'); + +const { poolByProvider } = require('./SmartYield.js'); +const { underlyingBalance, totalUnRedeemed } = require('./IProvider.js'); + +const getAssetUsdPrice = async (chain, asset) => { + const key = `${chain.name}:${asset}`.toLowerCase(); + const assetPriceUSD = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + + return assetPriceUSD; +}; + +const getPrices = async (chain, terms) => { + const assets = [...new Set(terms.map((term) => term.underlying))]; + + const assetAndUsdPrices = await Promise.all( + assets.map(async (asset) => [asset, await getAssetUsdPrice(chain, asset)]) + ); + + return Object.fromEntries(assetAndUsdPrices); +}; + +const userDepositsForTerms = async (chain, terms, valueInUSD) => { + const prices = await getPrices(chain, terms); + + const userDeposits = sumBy(terms, (term) => { + const value = valueInUSD + ? (term.currentDepositedAmount / `1e${term.underlyingDecimals}`) * + prices[term.underlying] + : term.currentDepositedAmount / `1e${term.underlyingDecimals}`; + + return value; + }); + + return userDeposits; +}; + +const liquidityProviderBalanceForTerms = async ( + chain, + terms, + valueInUSD = false +) => { + const prices = await getPrices(chain, terms); + + const providers = uniqBy(terms, 'provider').map((term) => ({ + provider: term.provider, + decimals: term.underlyingDecimals, + underlying: term.underlying, + })); + + const values = await Promise.all( + providers.map(async ({ provider, decimals, underlying }) => { + const liquidityProviderBalance = (await poolByProvider(chain, provider)) + .liquidityProviderBalance; + + const value = valueInUSD + ? (liquidityProviderBalance / `1e${decimals}`) * prices[underlying] + : liquidityProviderBalance / `1e${decimals}`; + + return { value, decimals, underlying }; + }) + ); + + const liquidityProviderBalance = sumBy( + values, + ({ value, decimals, underlying }) => value + ); + + return liquidityProviderBalance; +}; + +const totalValueLockedForTerms = async (chain, terms, valueInUSD) => { + const liquidityProviderBalance = await liquidityProviderBalanceForTerms( + chain, + terms, + valueInUSD + ); + + const userDeposits = await userDepositsForTerms(chain, terms, valueInUSD); + + return liquidityProviderBalance + userDeposits; +}; + +const earnedYieldIfNextTermOfActiveTerm = ( + activeTerms, + termId, + earnedYield +) => { + // Return earned yield only when the term we're viewing (termId) is the next term of the currently active term. + + const nextTerm = activeTerms.find( + (term) => + term.nextTerm && + termId && + term.nextTerm.id.toLowerCase() === termId.toLowerCase() + ); + + return nextTerm && earnedYield ? earnedYield : 0; +}; + +const earnedYieldByProviderForTerms = async (chain, terms) => { + const providers = uniqBy(terms, 'provider').map((term) => ({ + provider: term.provider, + decimals: term.underlyingDecimals, + underlying: term.underlying, + })); + + const providerValues = await Promise.all( + providers.map(async ({ provider, decimals, underlying }) => { + const _underlyingBalance = await underlyingBalance(chain, provider); + const _totalUnRedeemed = await totalUnRedeemed(chain, provider); + + const value = + _underlyingBalance / `1e${decimals}` - + _totalUnRedeemed / `1e${decimals}`; + + return { provider, value }; + }) + ); + + const earnedYieldByProvider = providerValues.reduce( + (previousValue, currentValue) => ({ + ...previousValue, + [currentValue.provider]: currentValue.value, + }), + {} + ); + + return earnedYieldByProvider; +}; + +const yieldToBeDistributed = (term, earnedYield) => { + const realizedYield = +term.realizedYield / `1e${term.underlyingDecimals}`; + return realizedYield + earnedYield; +}; + +const apyBase = (term, earnedYield) => { + const userDeposits = +term.depositedAmount / `1e${term.underlyingDecimals}`; + + const timeDifference = +term.end - +term.start; + const timeInYear = 60 * 60 * 24 * 365; + const fee = +term.feeRate / 10000; + + const numberOfPeriods = timeDifference / timeInYear; + + const totalFee = (fee / numberOfPeriods) * 100; + + const totalRealizedYield = yieldToBeDistributed(term, earnedYield); + + const apy = + +userDeposits === 0 + ? 0 + : (+totalRealizedYield / +userDeposits / timeDifference) * + timeInYear * + 100; + + return apy - totalFee; +}; + +module.exports = { + liquidityProviderBalanceForTerms, + totalValueLockedForTerms, + earnedYieldIfNextTermOfActiveTerm, + earnedYieldByProviderForTerms, + apyBase, +}; diff --git a/src/adaptors/barnbridge/subgraph.js b/src/adaptors/barnbridge/subgraph.js new file mode 100644 index 0000000000..c9f730a331 --- /dev/null +++ b/src/adaptors/barnbridge/subgraph.js @@ -0,0 +1,79 @@ +const { request, gql } = require('graphql-request'); + +exports.getActiveTerms = async (url) => { + const now = Math.floor(Date.now() / 1000); + + const query = gql` + { + terms(where: { start_lte: ${now}, end_gt: ${now} }) { + id + assetName + assetSymbol + assetDecimals + underlying + underlyingName + underlyingSymbol + underlyingDecimals + start + end + depositCap + feeRate + realizedYield + depositedAmount + currentDepositedAmount + liquidated + txCount + provider { + id + } + network + nextTerm { + id + } + } + } + `; + + const { terms } = await request(url, query); + + return terms; +}; + +exports.getPastAndActiveTerms = async (url) => { + const now = Math.floor(Date.now() / 1000); + + const query = gql` + { + terms(where: { end_gt: ${now} }) { + id + assetName + assetSymbol + assetDecimals + underlying + underlyingName + underlyingSymbol + underlyingDecimals + start + end + depositCap + feeRate + realizedYield + depositedAmount + currentDepositedAmount + liquidated + txCount + provider { + id + } + network + nextTerm { + id + } + } + } + `; + + const { terms } = await request(url, query); + + return terms; +}; diff --git a/src/adaptors/baseswap-v2/anytoken.js b/src/adaptors/baseswap-v2/anytoken.js new file mode 100644 index 0000000000..f3332ce677 --- /dev/null +++ b/src/adaptors/baseswap-v2/anytoken.js @@ -0,0 +1,34 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, +]; \ No newline at end of file diff --git a/src/adaptors/baseswap-v2/index.js b/src/adaptors/baseswap-v2/index.js new file mode 100755 index 0000000000..8bf5a1ff14 --- /dev/null +++ b/src/adaptors/baseswap-v2/index.js @@ -0,0 +1,404 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const masterchefAbi = require('./masterchef'); +const nftpoolAbi = require('./nftpool'); +const smartchefinitializableAbi = require('./smartchefinitializable'); +const anytokenAbi = require('./anytoken'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const masterchef = '0x6fc0f134a1f20976377b259687b1c15a5d422b47'; +const BSWAP = '0x78a087d713be963bf307b18f2ff8122ef9a63ae9'; +const BSX = '0xd5046b976188eb40f6de40fb527f89c05b323385'; +const XBSX = '0xe4750593d1fc8e74b31549212899a72162f315fa'; +const WETH = '0x4200000000000000000000000000000000000006'; +const USDBC = '0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca'; +const EDE = '0x0a074378461fb7ed3300ea638c6cc38246db4434'; + +const project = 'baseswap-v2'; + +const symbols = { + [BSWAP]: 'BSWAP', + [BSX]: 'BSX', + [XBSX]: 'XBSX', + [WETH]: 'WETH', + [USDBC]: 'USDBC', +}; + +const staker_contracts = [ + '0x64fcfa940f286af1261107f993189379e8d3ae1c', // BSWAP USDbC + '0x86dbd5baae91ac576e8e5197eb2497603d0056ea', // BSWAP WETH + '0x55da9a8a85d37764934a8915621baa00fafdc3eb', // BSX USDbC + '0x26fd5de668f091222791cc0ea45ac072d7bfe0cd', // BSX WETH + '0x8d52e213d741684dec1d37a6ee7814ae32942c1e', // BSX EDE + '0x326929eae4e1923b9d08de6bd8b2e16f7dd35cd4', // xBSX USDbC +]; + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint( + sdk.graph.modifyEndpoint('BWHCfpXMHFDx3u4E14hEwv4ST7SUyN89FKJ2RjzWKgA9') +); + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + totalSupply + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + // single staking pools + stakers = staker_contracts.reduce((hash, elem) => { + hash[elem] = {}; + return hash; + }, {}); + + const ssStakedTokens = ( + await sdk.api.abi.multiCall({ + calls: [...Object.keys(stakers)].map((i) => ({ + target: i, + })), + abi: smartchefinitializableAbi.find((m) => m.name === 'stakedToken'), + chain: chainString, + }) + ).output.map((o) => [o.input.target, o.output.toLowerCase()]); + ssStakedTokens.forEach((e) => (stakers[e[0]]['stakedToken'] = e[1])); + + const ssRewardTokens = ( + await sdk.api.abi.multiCall({ + calls: [...Object.keys(stakers)].map((i) => ({ + target: i, + })), + abi: smartchefinitializableAbi.find((m) => m.name === 'rewardToken'), + chain: chainString, + }) + ).output.map((o) => [o.input.target, o.output.toLowerCase()]); + ssRewardTokens.forEach((e) => (stakers[e[0]]['rewardToken'] = e[1])); + + const ssRewardsPerSecond = ( + await sdk.api.abi.multiCall({ + calls: [...Object.keys(stakers)].map((i) => ({ + target: i, + })), + abi: smartchefinitializableAbi.find((m) => m.name === 'rewardPerSecond'), + chain: chainString, + }) + ).output.map((o) => [o.input.target, o.output.toLowerCase()]); + ssRewardsPerSecond.forEach((e) => (stakers[e[0]]['rewardPerSecond'] = e[1])); + + const ssBalancesOf = ( + await sdk.api.abi.multiCall({ + calls: [...Object.keys(stakers)].map((i) => ({ + target: stakers[i].stakedToken, + params: [i], + })), + abi: anytokenAbi.find((m) => m.name === 'balanceOf'), + chain: chainString, + }) + ).output.map((o) => [o.input.params, o.output]); + ssBalancesOf.forEach((e) => (stakers[e[0]]['balanceOf'] = e[1])); + + const ssStakedTokensDecimals = ( + await sdk.api.abi.multiCall({ + calls: [...new Set(Object.values(stakers).map((e) => e.stakedToken))].map( + (i) => ({ + target: i, + }) + ), + abi: anytokenAbi.find((m) => m.name === 'decimals'), + chain: chainString, + }) + ).output.reduce((hash, elem) => { + hash[elem.input.target] = elem.output; + return hash; + }, {}); + Object.values(stakers).forEach((e) => { + e.stakedTokenDecimals = ssStakedTokensDecimals[e.stakedToken]; + }); + + const ssRewardTokensDecimals = ( + await sdk.api.abi.multiCall({ + calls: [...new Set(Object.values(stakers).map((e) => e.rewardToken))].map( + (i) => ({ + target: i, + }) + ), + abi: anytokenAbi.find((m) => m.name === 'decimals'), + chain: chainString, + }) + ).output.reduce((hash, elem) => { + hash[elem.input.target] = elem.output; + return hash; + }, {}); + Object.values(stakers).forEach((e) => { + e.rewardTokenDecimals = ssRewardTokensDecimals[e.rewardToken]; + }); + + // lp farming + const activePoolsLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'activePoolsLength'), + chain: chainString, + }) + ).output; + + const activePoolAddressesByIndex = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(activePoolsLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'getActivePoolAddressByIndex'), + chain: chainString, + }) + ).output.map((o) => o.output); + + // const poolInfos = ( + // await sdk.api.abi.multiCall({ + // calls: [...activePoolAddressesByIndex].map((i) => ({ + // target: masterchef, + // params: [i] + // })), + // abi: masterchefAbi.find((m) => m.name === 'getPoolInfo'), + // chain: chainString, + // }) + // ).output.map((o) => o.output); + + const poolInfos = ( + await sdk.api.abi.multiCall({ + calls: [...activePoolAddressesByIndex].map((i) => ({ + target: i, + })), + abi: nftpoolAbi.find((m) => m.name === 'getPoolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const bswapTotalAllocPoints = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPointsWETH'), + chain: chainString, + }) + ).output; + + const bsxTotalAllocPoints = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPoints'), + chain: chainString, + }) + ).output; + + const emissionRates = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'emissionRates'), + chain: chainString, + }) + ).output; + + const bswapPerSec = emissionRates['wethRate'] / 1e18; + const bsxPerSec = emissionRates['mainRate'] / 1e18; + + const bswapPriceKey = `base:${BSWAP}`; + const bswapPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${bswapPriceKey}`) + ).data.coins[bswapPriceKey]?.price; + + const bsxPriceKey = `base:${BSX}`; + const bsxPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${bsxPriceKey}`) + ).data.coins[bsxPriceKey]?.price; + + const wethPriceKey = `base:${WETH}`; + const wethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${wethPriceKey}`) + ).data.coins[wethPriceKey]?.price; + + const usdbcPriceKey = `base:${USDBC}`; + const usdbcPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${usdbcPriceKey}`) + ).data.coins[usdbcPriceKey]?.price; + + const edePriceKey = `base:${EDE}`; + const edePrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${edePriceKey}`) + ).data.coins[edePriceKey]?.price; + + const prices = { + [BSWAP]: bswapPrice, + [BSX]: bsxPrice, + [XBSX]: bsxPrice, + [WETH]: wethPrice, + [USDBC]: usdbcPrice, + [EDE]: edePrice, + }; + + const bswapPerYearUsd = bswapPerSec * 86400 * 365 * bswapPrice; + const bsxPerYearUsd = bsxPerSec * 86400 * 365 * bsxPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString; + const url = `https://baseswap.fi/add/${token0}/${token1}`; + + const bswapAllocPoints = poolInfos.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.allocPointsWETH; + + const bsxAllocPoints = poolInfos.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.allocPoints; + + let lpSupply = poolInfos.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.lpSupply; + lpSupply = lpSupply / 1e18; + const ratio = lpSupply / p.totalSupply || 1; + + const bswapApyReward = + (((bswapAllocPoints / bswapTotalAllocPoints) * bswapPerYearUsd) / + (p.totalValueLockedUSD * ratio)) * + 100; + const bsxApyReward = + (((bsxAllocPoints / bsxTotalAllocPoints) * bsxPerYearUsd) / + (p.totalValueLockedUSD * ratio)) * + 100; + + const apyReward = bswapApyReward + bsxApyReward || 0; + + let rewardTokens = []; + bswapApyReward > 0 && rewardTokens.push(BSWAP); + bsxApyReward > 0 && rewardTokens.push(BSX, XBSX); + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project, + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward, + rewardTokens, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + // return only pools with apyReward > 0 + dataNow = dataNow.filter((el) => el.apyReward > 0); + + Object.entries(stakers).forEach(([key, val]) => { + balanceUSD = + (val.balanceOf / Math.pow(10, val.stakedTokenDecimals)) * + prices[val.stakedToken]; + rewardPerSecond = + val.rewardPerSecond / Math.pow(10, val.rewardTokenDecimals); + rewardAPR = + (rewardPerSecond * 86400 * 365 * prices[val.rewardToken]) / balanceUSD; + dataNow.push({ + pool: key, + chain: utils.formatChain(chainString), + project, + symbol: symbols[val.stakedToken], + tvlUsd: balanceUSD, + apyBase: 0, + apyReward: rewardAPR * 100, + rewardTokens: [val.rewardToken], + underlyingTokens: [val.stakedToken], + url: 'https://baseswap.fi/pools', + }); + }); + + return dataNow; +}; + +const main = async (timestamp = null) => { + let data = await topLvl( + 'base', + url, + query, + queryPrior, + 'baseswap', + timestamp + ); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/baseswap-v2/masterchef.js b/src/adaptors/baseswap-v2/masterchef.js new file mode 100644 index 0000000000..f0d1e6823a --- /dev/null +++ b/src/adaptors/baseswap-v2/masterchef.js @@ -0,0 +1,879 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract IProtocolToken", + "name": "_mainToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_wethPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + }, + { + "internalType": "contract IYieldBooster", + "name": "_boost", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidStartTime", + "type": "error" + }, + { + "inputs": [], + "name": "PoolAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "PoolNotExists", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountWETH", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "name": "PoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPointsWETH", + "type": "uint256" + } + ], + "name": "PoolSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserveWETH", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + } + ], + "name": "PoolUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "emergencyUnlock", + "type": "bool" + } + ], + "name": "SetEmergencyUnlock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousYieldBooster", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newYieldBooster", + "type": "address" + } + ], + "name": "SetYieldBooster", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "name": "TreasuryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "WethRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "weth", + "type": "address" + } + ], + "name": "WethUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activePoolsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INFTPool", + "name": "nftPool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPointsWETH", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "addUnlockOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountWETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dummyToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyUnlock", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdrawFromPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emissionRates", + "outputs": [ + { + "internalType": "uint256", + "name": "mainRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wethRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getActivePoolAddressByIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getPoolAddressByIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolAddress", + "type": "address" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPointsWETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveWETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolEmissionRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolEmissionRateWETH", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isUnlockOperator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mainChef", + "outputs": [ + { + "internalType": "contract IBaseswapMasterChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mainChefPoolId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "removeUnlockOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPointsWETH", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "emergencyUnlock_", + "type": "bool" + } + ], + "name": "setEmergencyUnlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_weth", + "type": "address" + } + ], + "name": "setWethReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wethRate", + "type": "uint256" + } + ], + "name": "setWethRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IYieldBooster", + "name": "yieldBooster_", + "type": "address" + } + ], + "name": "setYieldBooster", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_dummyToken", + "type": "address" + }, + { + "internalType": "contract IBaseswapMasterChef", + "name": "_oldChef", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_poolId", + "type": "uint256" + } + ], + "name": "start", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPointsWETH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftPool", + "type": "address" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "updateTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wethPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wethToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFromPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "yieldBooster", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +]; diff --git a/src/adaptors/baseswap-v2/nftpool.js b/src/adaptors/baseswap-v2/nftpool.js new file mode 100644 index 0000000000..45ba9d264a --- /dev/null +++ b/src/adaptors/baseswap-v2/nftpool.js @@ -0,0 +1,1390 @@ +module.exports = [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AddToPosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + } + ], + "name": "CreatePosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pending", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pendingWETH", + "type": "uint256" + } + ], + "name": "HarvestPosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + } + ], + "name": "LockPosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accRewardsPerShare", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accRewardsPerShareWETH", + "type": "uint256" + } + ], + "name": "PoolUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boostPoints", + "type": "uint256" + } + ], + "name": "SetBoost", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxGlobalMultiplier", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxBoostMultiplier", + "type": "uint256" + } + ], + "name": "SetBoostMultiplierSettings", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "emergencyUnlock", + "type": "bool" + } + ], + "name": "SetEmergencyUnlock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxLockDuration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxLockMultiplier", + "type": "uint256" + } + ], + "name": "SetLockMultiplierSettings", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "SetOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isAdded", + "type": "bool" + } + ], + "name": "SetUnlockOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "xTokenRewardsShare", + "type": "uint256" + } + ], + "name": "SetXTokenRewardsShare", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawFromPosition", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_BOOST_MULTIPLIER_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_GLOBAL_MULTIPLIER_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LOCK_MULTIPLIER_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountToAdd", + "type": "uint256" + } + ], + "name": "addToPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "boost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + } + ], + "name": "createPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyUnlock", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "boostPoints", + "type": "uint256" + } + ], + "name": "getMultiplierByBoostPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + } + ], + "name": "getMultiplierByLockDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMultiplierSettings", + "outputs": [ + { + "internalType": "uint256", + "name": "maxGlobalMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxLockDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxLockMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBoostMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "protocolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "xToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardsPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardsPerShareWETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lpSupplyWithMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPointsWETH", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getStakingPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountWithMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startLockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebtWETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "boostPoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "harvestPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "harvestPositionTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "harvestPositionsTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "hasDeposits", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMasterChef", + "name": "master_", + "type": "address" + }, + { + "internalType": "contract IERC20Metadata", + "name": "token", + "type": "address" + }, + { + "internalType": "contract IXToken", + "name": "xToken", + "type": "address" + }, + { + "internalType": "contract IERC20Metadata", + "name": "lpToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isUnlocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockDuration", + "type": "uint256" + } + ], + "name": "lockPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [ + { + "internalType": "contract IMasterChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "pendingRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "mainAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wethAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "renewLockPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxGlobalMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBoostMultiplier", + "type": "uint256" + } + ], + "name": "setBoostMultiplierSettings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "emergencyUnlock_", + "type": "bool" + } + ], + "name": "setEmergencyUnlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxLockDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxLockMultiplier", + "type": "uint256" + } + ], + "name": "setLockMultiplierSettings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator_", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "xTokenRewardsShare_", + "type": "uint256" + } + ], + "name": "setXTokenRewardsShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unboost", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountToWithdraw", + "type": "uint256" + } + ], + "name": "withdrawFromPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "xTokenRewardsShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "yieldBooster", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +]; diff --git a/src/adaptors/baseswap-v2/smartchefinitializable.js b/src/adaptors/baseswap-v2/smartchefinitializable.js new file mode 100644 index 0000000000..4b1e239bf3 --- /dev/null +++ b/src/adaptors/baseswap-v2/smartchefinitializable.js @@ -0,0 +1,625 @@ +module.exports = [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "tokenRecovered", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AdminTokenRecovery", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "poolLimitPerUser", + "type": "uint256" + } + ], + "name": "NewPoolLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rewardPerSecond", + "type": "uint256" + } + ], + "name": "NewRewardPerSecond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + } + ], + "name": "NewStartAndEndTimes", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "blockTime", + "type": "uint256" + } + ], + "name": "RewardsStop", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION_FACTOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SMART_CHEF_FACTORY", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accTokenPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bonusEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "emergencyRewardWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "hasUserLimit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBEP20", + "name": "_stakedToken", + "type": "address" + }, + { + "internalType": "contract IBEP20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_bonusEndTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_poolLimitPerUser", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLimitPerUser", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenAmount", + "type": "uint256" + } + ], + "name": "recoverWrongTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setDepositFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakedToken", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stopReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_hasUserLimit", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_poolLimitPerUser", + "type": "uint256" + } + ], + "name": "updatePoolLimitPerUser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPerSecond", + "type": "uint256" + } + ], + "name": "updateRewardPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_bonusEndTime", + "type": "uint256" + } + ], + "name": "updateStartAndEndBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]; diff --git a/src/adaptors/basex/index.js b/src/adaptors/basex/index.js new file mode 100644 index 0000000000..ce138fce9c --- /dev/null +++ b/src/adaptors/basex/index.js @@ -0,0 +1,111 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const api = 'https://api-backend-0191c757fded.herokuapp.com/graphql'; + +const query = gql` + { + getV3Pools( + chainId: 8453 + first: 25 + skip: 0 + orderBy: totalLiquidity + orderDirection: desc + textSearch: null + ) { + ...GqlV3PoolFragment + __typename + } + count: poolGetV3PoolsCount( + chainId: 8453 + first: 25 + skip: 0 + orderBy: totalLiquidity + orderDirection: desc + textSearch: null + ) + } + + fragment GqlV3PoolFragment on GqlV3Pool { + id + address + symbol + feeTier + swapFee + type + token0 { + ...GqlTokenFragment + __typename + } + token1 { + ...GqlTokenFragment + __typename + } + aprItems { + id + title + type + apr + __typename + } + dynamicData { + totalLiquidity + fees24h + volume24h + reserves0 + reserves1 + __typename + } + __typename + } + + fragment GqlTokenFragment on GqlToken { + id + address + name + symbol + decimals + chainId + logoURI + tradeable + isQuoteToken + isStableCoin + currentPrice { + price + __typename + } + __typename + } +`; + +const apy = async () => { + const data = await request(api, query); + + const pools = data.getV3Pools.map((p) => { + const apyBase = + p.aprItems.find((i) => i.type === 'SWAP_FEE')?.apr * 100 ?? null; + const apyReward = + p.aprItems.find((i) => i.type === 'NATIVE_REWARD')?.apr * 100 ?? null; + + return { + pool: p.address, + chain: 'base', + project: 'basex', + symbol: p.symbol, + tvlUsd: p.dynamicData.totalLiquidity, + apyBase, + apyReward, + underlyingTokens: [p.token0.address, p.token1.address], + rewardTokens: + apyReward > 0 ? ['0xd5046b976188eb40f6de40fb527f89c05b323385'] : null, + url: `https://baseswap.fi/pool/v3/${p.id}`, + volumeUsd1d: p.dynamicData.volume24h, + }; + }); + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/basisos/index.js b/src/adaptors/basisos/index.js new file mode 100644 index 0000000000..98476da417 --- /dev/null +++ b/src/adaptors/basisos/index.js @@ -0,0 +1,217 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +/** + * @dev Fetches all vault addresses from the DataProvider contract. + * @returns {Promise} An object containing an array of vault addresses. + */ +async function getAllVaults() { + const DATA_PROVIDER_ADDRESS = '0xDD5C8aB2E9F113b397ff2b8528C649bAEf24dF97' + + const vaults = await sdk.api.abi.call({ + target: DATA_PROVIDER_ADDRESS, + abi: 'address[]:getAllVaults', + chain: 'arbitrum', + }) + + return vaults +} + +/** + * @dev Fetches the total value locked (TVL) in a given vault. + * @param {string} vaultAddress The address of the vault. + * @returns {Promise} An object containing the TVL. + */ +async function getTvl(vaultAddress) { + const tvl = await sdk.api.abi.call({ + target: vaultAddress, + abi: 'uint256:totalAssets', + chain: 'arbitrum', + }) + + return tvl +} + +/** + * @dev Fetches the strategy address for a given vault. + * @param {string} vaultAddress The address of the vault. + * @returns {Promise} An object containing the strategy address. + */ +async function getStrategyAddress(vaultAddress) { + const strategy = await sdk.api.abi.call({ + target: vaultAddress, + abi: 'address:strategy', + chain: 'arbitrum', + }) + + return strategy +} + +/** + * @dev Fetches the product token address for a given strategy. + * @param {string} strategyAddress The address of the strategy. + * @returns {Promise} An object containing the product token address. + */ +async function getProductToken(strategyAddress) { + const product = await sdk.api.abi.call({ + target: strategyAddress.output, + abi: 'address:product', + chain: 'arbitrum', + }) + + return product +} + +/** + * @dev Fetches the asset token address for a given vault. + * @param {string} vaultAddress The address of the vault. + * @returns {Promise} An object containing the asset token address. + */ +async function getAssetToken(vaultAddress) { + const asset = await sdk.api.abi.call({ + target: vaultAddress, + abi: 'address:asset', + chain: 'arbitrum', + }) + + return asset +} + +/** + * @dev Fetches the symbol of a given token. + * @param {string} tokenAddress The address of the token. + * @returns {Promise} An object containing the token symbol. + */ +async function getTokenSymbol(tokenAddress) { + const symbol = await sdk.api.abi.call({ + target: tokenAddress.output, + abi: 'string:symbol', + chain: 'arbitrum', + }) + + return symbol +} + +/** + * @dev Fetches the decimal precision of a given asset token. + * @param {string} assetAddress The address of the asset token. + * @returns {Promise} An object containing the decimal precision. + */ +async function getAssetDecimal(assetAddress) { + const decimal = await sdk.api.abi.call({ + target: assetAddress.output, + abi: 'uint8:decimals', + chain: 'arbitrum', + }) + + return decimal +} + +/** + * @dev Fetches the hedge manager address for a given strategy. + * @param {string} strategyAddress The address of the strategy. + * @returns {Promise} An object containing the hedge manager address. + */ +async function getHedgeManagerAddress(strategyAddress) { + const hedgeManager = await sdk.api.abi.call({ + target: strategyAddress.output, + abi: 'address:hedgeManager', + chain: 'arbitrum', + }) + + return hedgeManager +} + +/** + * @dev Fetches the Hyperliquid agent address for a given hedge manager. + * @param {string} hedgeManagerAddress The address of the hedge manager. + * @returns {Promise} An object containing the agent address. + */ +async function getAgentAddress(hedgeManagerAddress) { + const agent = await sdk.api.abi.call({ + target: hedgeManagerAddress.output, + abi: 'address:agent', + chain: 'arbitrum', + }) + + return agent +} + +/** + * @dev Fetches the Hyperliquid position fees for a given agent for the last 24 hours. + * @param {string} agentAddress The address of the agent. + * @returns {Promise} An object containing the fees data. + */ +async function getHyperliquidPositionFees(agentAddress){ + const params = { + "type": 'userFunding', + "user": agentAddress.output, + "startTime": parseInt(Date.now() - 86400 * 1000), // now - 1d + "endTime": parseInt(Date.now()) // now + } + + const feesData = await utils.getData( + 'https://api.hyperliquid.xyz/info', query = params + ); + + return feesData +} + +/** + * @dev Calculates the APY base from the fees data and TVL. + * @param {object} feesData The fees data object. + * @param {number} tvl The total value locked in USD. + * @returns {number} The APY base. + */ +async function getApyBase(feesData, tvl){ + const totalFees = feesData.reduce((acc, curr) => acc + Number(curr.delta.usdc), 0); + const apyBase = totalFees / tvl; + + return apyBase * 365 * 100 +} + +/** + * @dev Calculates the APY for each BasisOS vault. + * @returns {Promise>} An array of pool objects, each containing APY and other relevant information. + */ +async function apy() { + const vaults = await getAllVaults(); + const pools = []; + + for (const vault of vaults.output) { + const tvl_in_asset = await getTvl(vault); + + const strategyAddress = await getStrategyAddress(vault); + const productToken = await getProductToken(strategyAddress); + const symbol = await getTokenSymbol(productToken); + const assetToken = await getAssetToken(vault); + const assetDecimal = await getAssetDecimal(assetToken); + + const hedgeManagerAddress = await getHedgeManagerAddress(strategyAddress); + const agentAddress = await getAgentAddress(hedgeManagerAddress); + const hyperliquidPositionFees = await getHyperliquidPositionFees(agentAddress); + + const tvl_in_usd = Number(tvl_in_asset.output) / 10 ** Number(assetDecimal.output); + + const apyBase = await getApyBase(hyperliquidPositionFees, tvl_in_usd); + + pools.push({ + pool: `${vault}-arbitrum`.toLowerCase(), + symbol: utils.formatSymbol(symbol.output), + project: 'basisos', + chain: utils.formatChain('arbitrum'), + tvlUsd: tvl_in_usd, + underlyingTokens: [productToken.output, assetToken.output], + apyBase: apyBase, + }); + } + + return pools; +} + + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://basisos.org/vaults', +}; \ No newline at end of file diff --git a/src/adaptors/beanstalk/index.js b/src/adaptors/beanstalk/index.js new file mode 100644 index 0000000000..d56d6ba3b8 --- /dev/null +++ b/src/adaptors/beanstalk/index.js @@ -0,0 +1,113 @@ +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); +const axios = require('axios'); + +const chains = { + "ethereum": { + // Replant 8/6/2022. Current yield history on the subgraph does not include prior values + startBlock: 15289934, + startTime: 1659800414, + api: "https://api.bean.money/silo/yield", + subgraph: "https://graph.bean.money/bean_eth/", + // For Bean tokens which are no longer tracked by a Beanstalk, specifies an end block + oldTokens: { + // 2022 Exploit + "0xdc59ac4fefa32293a95889dc396682858d52e5db": 14602790, + // 2024 L2 migration + "0xbea0000029ad1c77d3d5d23ba2d8893db9d1efab": 20921738 + } + }, + "arbitrum": { + // L2 migration 10/10/2024 + startBlock: 262211594, + startTime: 1728528834, + api: "https://api.bean.money/silo/yield", + subgraph: "https://graph.bean.money/bean/", + oldTokens: {} + } +}; + +async function getPools(timestamp = null) { + const pools = await Promise.all(Object.keys(chains).map(chain => getPoolsForChain(chain, timestamp))); + return pools.flat(); +} + +async function getPoolsForChain(chain, timestamp) { + + if (timestamp && timestamp < chains[chain].startTime) { + return []; + } + + const resultPools = []; + + // When a timestamp is specified, determine which block to use + let block; + if (timestamp) { + [block] = await utils.getBlocksByTime([timestamp], chain); + } + + // Query subgraph to identify each yield-bearing pool and its info + const poolData = await request(chains[chain].subgraph, gql` + { + beans${block ? `(block: {number: ${block}})` : ''} { + id + lastSeason + pools { + id + liquidityUSD + tokens { + id + name + } + } + } + }` + ); + + // Avoid presenting old bean tokens that are not current to the requested time + const beans = poolData.beans.filter(bean => { + const endBlock = chains[chain].oldTokens[bean.id]; + return !endBlock || endBlock > block; + }); + + for (const bean of beans) { + + // Get apy info + const apy = await axios.post(chains[chain].api, { + season: bean.lastSeason, + emaWindows: [720], + tokens: bean.pools.map(p => p.id), + options: { + initType: 'NEW' + } + }); + // Uses the available window if fewer datapoints were available + const yields = apy.data.yields[Object.keys(apy.data.yields)[0]]; + const pools = bean.pools.filter(p => yields[p.id]); + + // Add results for each pool + for (const pool of pools) { + // Sort BEAN to be first in the token list + const tokens = pool.tokens[0].name === 'BEAN' ? pool.tokens : [pool.tokens[1], pool.tokens[0]]; + resultPools.push({ + pool: (`${pool.id}-${chain}`).toLowerCase(), + chain: utils.formatChain(chain), + project: 'beanstalk', + symbol: `${tokens[0].name}-${tokens[1].name}`, + tvlUsd: parseInt(pool.liquidityUSD), + apyBase: 0, + apyReward: Math.round(yields[pool.id].bean * 10000) / 100, + rewardTokens: [bean.id], + underlyingTokens: tokens.map(p => p.id.toLowerCase()), + poolMeta: 'Beanstalk Silo' + }); + } + } + return resultPools; +} + +module.exports = { + timetravel: true, + apy: getPools, + url: 'https://app.bean.money/#/silo' +}; diff --git a/src/adaptors/bedrock-unieth/index.js b/src/adaptors/bedrock-unieth/index.js new file mode 100644 index 0000000000..750f80d3fc --- /dev/null +++ b/src/adaptors/bedrock-unieth/index.js @@ -0,0 +1,131 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const { differenceInDays, isBefore, parseISO, startOfDay, subDays } = require('date-fns'); + +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const UNIETH_CONTRACT_ADDRESS = '0xF1376bceF0f78459C0Ed0ba5ddce976F1ddF51F4'; + +/** + * tvlUsd = CurrentReserve / ExchangeRatio * uniETHPrice + */ +async function useTvlUsd(totalSupply) { + const priceKey = `ethereum:${UNIETH_CONTRACT_ADDRESS}`; + const uniETHPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + return totalSupply.mul(ethers.utils.parseEther(String(uniETHPrice))); +} +async function useE2LSServerLatestQuarterly() { + const url = 'https://app.bedrock.technology/unieth/api/v1/e2ls/latest/quarterly'; + return axios.get(url); +} +async function useE2LSServerLatestQuarterlyDailyEarnExchangeRatios(exchangeRatios) { + const result = []; + for (let i = 0; i <= exchangeRatios.length - 1; i++) { + const prevItem = exchangeRatios[i - 1]; + const item = exchangeRatios[i]; + if (prevItem != null) { + const dailyEarn = ethers.utils.parseUnits(item.exchangeRatio, 'wei').sub( + prevItem.exchangeRatio + ); + result.push({ + ...item, + dailyEarn: ethers.utils.formatUnits(dailyEarn, 'wei'), + }); + } else { + result.push({ + ...item, + dailyEarn: '0', + }); + } + } + return result; +} +async function useE2LSServerDailyEarnExchangeRatios(exchangeRatios, limit) { + const dailyEarnExchangeRatios = await useE2LSServerLatestQuarterlyDailyEarnExchangeRatios(exchangeRatios); + const lastItem = dailyEarnExchangeRatios.at(-1); + if (lastItem) { + const firstCreatedAt = subDays( + startOfDay(parseISO(lastItem.createdAt)), + limit + ); + return dailyEarnExchangeRatios.filter(val => + isBefore(firstCreatedAt, startOfDay(parseISO(val.createdAt))) + ); + } + return []; +} +function useE2LSServerEarn( + exchangeRatios +) { + return exchangeRatios.reduce( + (acc, item) => acc.add(item.dailyEarn), + ethers.constants.Zero + ); +} +function useE2LSServerReturn( + exchangeRatios +) { + const earnAsBigNumber = useE2LSServerEarn(exchangeRatios); + if (exchangeRatios.length == 0) { + return ethers.constants.Zero; + } + const initialExchangeRatio = ethers.utils.parseUnits( + exchangeRatios[0].exchangeRatio, 'wei' + ).sub(exchangeRatios[0].dailyEarn); + return earnAsBigNumber + .mul(ethers.constants.WeiPerEther) + .div(initialExchangeRatio); +} +/** + * 年化收益率 + * @param {number} limit 时间周期(天) + */ +async function useE2LSServerAPY(exchangeRatios, + limit +) { + const limitExchangeRatios = await useE2LSServerDailyEarnExchangeRatios(exchangeRatios, limit); + const returnAsBigNumber = useE2LSServerReturn(limitExchangeRatios); + if (limitExchangeRatios.length <= 2) { + return ethers.constants.Zero; + } + const firstItem = limitExchangeRatios.at(0); + const lastItem = limitExchangeRatios.at(-1); + const pDays = differenceInDays( + startOfDay(parseISO(lastItem.createdAt)), + startOfDay(parseISO(firstItem.createdAt)) + ); + const daysInYear = 365; + const apyAsBigNumber = returnAsBigNumber + .div(pDays + 1) + .add(ethers.constants.WeiPerEther) + .pow(daysInYear) + .div(ethers.constants.WeiPerEther.pow(daysInYear - 1)) + .sub(ethers.constants.WeiPerEther); + return apyAsBigNumber; +} + +const getApy = async () => { + const data = await useE2LSServerLatestQuarterly(); + const exchangeRatios = data?.data.data ?? []; + const lastItem = exchangeRatios.at(-1); + const currentReserve = ethers.utils.parseUnits(lastItem.currentReserve, 'wei'); + const exchangeRatio = ethers.utils.parseUnits(lastItem.exchangeRatio, 'wei'); + const totalSupply = currentReserve.div(exchangeRatio); + const tvlUsd = await useTvlUsd(totalSupply); + const apyAsBigNumber30 = await useE2LSServerAPY(exchangeRatios, 30); + return [ + { + pool: UNIETH_CONTRACT_ADDRESS, + chain: 'ethereum', + project: 'bedrock-unieth', + symbol: 'uniETH', + tvlUsd: Number(ethers.utils.formatEther(tvlUsd)), + apyBase: 100 * Number(ethers.utils.formatEther(apyAsBigNumber30)), + underlyingTokens: [weth], + } + ]; +}; +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.bedrock.technology/unieth', +}; diff --git a/src/adaptors/beefy-finance/index.js b/src/adaptors/beefy-finance/index.js deleted file mode 100644 index 0e8fda17c4..0000000000 --- a/src/adaptors/beefy-finance/index.js +++ /dev/null @@ -1,75 +0,0 @@ -const utils = require('../utils'); - -const urlApy = 'https://api.beefy.finance/apy'; -const urlTvl = 'https://api.beefy.finance/tvl'; -// they also have this endpoint with vault id info, ids are not addresses though -// 'https://api.beefy.finance/vaults' - -// NOTE(!) some of those sometimes are in the api response, sometimes they aren't... -// need to check with team -const networkMapping = { - 43114: 'avalanche', - // 1666600000: 'harmony', - 42220: 'celo', - 42161: 'arbitrum', - // 1285: 'moonriver', - // 1088: 'metis', - 250: 'fantom', - 137: 'polygon', - // 128: 'heco', - // 122: 'fuse', - 56: 'binance', - // 25: 'cronos', -}; - -const apy = (dataTvl, dataApy, networkMapping) => { - const data = []; - for (const chain of Object.keys(networkMapping)) { - poolData = dataTvl[chain]; - for (const pool of Object.keys(poolData)) { - if (dataApy[pool] === undefined) { - continue; - } - data.push({ - id: `${pool}-${chain}`, - symbol: pool.split('-').slice(1).join('-'), - network: chain, - tvl: poolData[pool], - apy: dataApy[pool], - }); - } - } - return data; -}; - -const buildPool = (entry) => { - const newObj = { - pool: entry.id, - chain: utils.formatChain(networkMapping[entry.network]), - project: 'beefy-finance', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.tvl, - apy: entry.apy * 100, - }; - - return newObj; -}; - -const main = async () => { - // pull data - const dataApy = await utils.getData(urlApy); - const dataTvl = await utils.getData(urlTvl); - - // calculate apy - let data = apy(dataTvl, dataApy, networkMapping); - - // build pool objects - data = data.map((el) => buildPool(el)); - - return data; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/beefy/index.js b/src/adaptors/beefy/index.js new file mode 100644 index 0000000000..bb9ffa2fda --- /dev/null +++ b/src/adaptors/beefy/index.js @@ -0,0 +1,173 @@ +const { + formatChain, + formatSymbol, + getData, + removeDuplicates, +} = require('../utils'); + +const url = 'https://api.beefy.finance'; +const urlApy = `${url}/apy`; +const urlTvl = `${url}/tvl`; +const urlVaults = `${url}/harvestable-vaults`; +const urlGovVaults = `${url}/gov-vaults`; +const urlAddressbook = `${url}/tokens`; + +const urlVaultsStatus = `${url}/vaults`; + +const networkMapping = { + 1: 'ethereum', + 10: 'optimism', + 25: 'cronos', + 56: 'bsc', + 100: 'gnosis', + 122: 'fuse', + 128: 'heco', + 137: 'polygon', + 169: 'manta', + 250: 'fantom', + 252: 'fraxtal', + 324: 'zksync', + 1088: 'metis', + 1101: 'polygon_zkevm', + 1284: 'moonbeam', + 1285: 'moonriver', + 2222: 'kava', + 5000: 'mantle', + 7700: 'canto', + 8453: 'base', + 34443: 'mode', + 42161: 'arbitrum', + 42220: 'celo', + 42262: 'oasis', + 43114: 'avalanche', + 59144: 'linea', + 1313161554: 'aurora', + 1666600000: 'harmony', + 146: 'sonic', +}; + +const extractePoolMetaDate = (string) => { + // match DDMMMYY + const pattern = /(\d{2}[A-Za-z]{3}\d{2})/; + const match = string.match(pattern); + + if (match) { + const datePart = match[1]; + const nonDatePart = string.replace(datePart, '').trim(); + return { nonDatePart, datePart }; + } else { + return { nonDatePart: string, datePart: null }; + } +}; + +const main = async () => { + const [apys, tvlsByChain, vaults, govVaults, tokens, vaultStatus] = + await Promise.all( + [ + urlApy, + urlTvl, + urlVaults, + urlGovVaults, + urlAddressbook, + urlVaultsStatus, + ].map((u) => getData(u)) + ); + + const data = []; + for (const [chainId, tvls] of Object.entries(tvlsByChain)) { + const llamaChain = networkMapping[chainId]; + if (!llamaChain) { + // console.debug(`Skipping chain ${chainId}, not in networkMapping`); + continue; + } + + for (const [vaultId, tvl] of Object.entries(tvls)) { + const s = vaultStatus.find( + (i) => i.id.toLowerCase() === vaultId.toLowerCase() + ); + if (s && ['eol', 'paused'].includes(s.status.toLowerCase())) continue; + + let vault = vaults.find((v) => v.id === vaultId); + if (vault === undefined) { + vault = govVaults.find((v) => v.id === vaultId); + } + + if (vault === undefined) { + // console.debug(`Skipping vault ${vaultId}, no vault data`); + continue; + } + + if (tvl === undefined || tvl === null) { + // console.debug(`Skipping vault ${vaultId}, no TVL data`); + continue; + } + + const apy = apys[vaultId] || 0; + + const { + assets, + name, + platformId, + depositTokenAddresses, + earnContractAddress, + chain, + type, + tokenAddress, + oracleId, + } = vault; + + const tokenSymbols = []; + const tokenAddresses = []; + + for (const assetId of assets) { + const token = tokens[chain]?.[assetId]; + if (token) { + const { address, symbol } = token; + if (address) { + tokenAddresses.push( + address === 'native' + ? '0x0000000000000000000000000000000000000000' + : address + ); + } + if (symbol) { + tokenSymbols.push(symbol); + } + } else { + // fallback to assetId if token not found + tokenSymbols.push(assetId); + } + } + + const underlyingTokens = + tokenAddresses.length === 0 && assets.length === 1 + ? [tokenAddress] + : type === 'cowcentrated' + ? depositTokenAddresses + : tokenAddresses; + + const poolDetails = extractePoolMetaDate(name).datePart; + let poolMeta = formatChain(platformId); + poolMeta = poolDetails !== null ? `${poolMeta}-${poolDetails}` : poolMeta; + + data.push({ + pool: `${earnContractAddress}-${llamaChain}`.toLowerCase(), + chain: formatChain(llamaChain), + project: 'beefy', + symbol: formatSymbol(tokenSymbols.join('-')), + tvlUsd: tvl, + apy: apy * 100, + poolMeta, + underlyingTokens, + url: `https://app.beefy.com/vault/${vaultId}`, + }); + } + } + + return removeDuplicates(data); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/beets-dex-v3/index.ts b/src/adaptors/beets-dex-v3/index.ts new file mode 100644 index 0000000000..ae96aef461 --- /dev/null +++ b/src/adaptors/beets-dex-v3/index.ts @@ -0,0 +1,13 @@ +const { getPools } = require('../beets-dex/utils'); + +const poolsFunction = async () => { + const [sonicPoolsV3] = await Promise.all([getPools('SONIC', 'sonic', 3)]); + + return [...sonicPoolsV3]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://beets.fi/pools', +}; diff --git a/src/adaptors/beets-dex/index.ts b/src/adaptors/beets-dex/index.ts new file mode 100644 index 0000000000..ffc7ad2032 --- /dev/null +++ b/src/adaptors/beets-dex/index.ts @@ -0,0 +1,13 @@ +const { getPools } = require('./utils'); + +const poolsFunction = async () => { + const [sonicPoolsV2] = await Promise.all([getPools('SONIC', 'sonic', 2)]); + + return [...sonicPoolsV2]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://beets.fi/pools', +}; diff --git a/src/adaptors/beets-dex/utils.ts b/src/adaptors/beets-dex/utils.ts new file mode 100644 index 0000000000..b4f94edb88 --- /dev/null +++ b/src/adaptors/beets-dex/utils.ts @@ -0,0 +1,92 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); + +const query = gql` + query GetPools($chain: GqlChain!, $version: Int!) { + poolGetPools( + first: 1000 + where: { chainIn: [$chain], protocolVersionIn: [$version], minTvl: 10000 } + ) { + id + chain + symbol + address + poolTokens { + address + symbol + } + dynamicData { + totalLiquidity + aprItems { + type + apr + rewardTokenAddress + } + } + } + } +`; + +const getPools = async (backendChain, chainString, version) => { + try { + const { poolGetPools } = await request( + 'https://backend-v3.beets-ftm-node.com/graphql', + query, + { chain: backendChain, version: version } + ); + + return poolGetPools.map((pool) => { + const aprItems = pool.dynamicData.aprItems || []; + + const baseApr = aprItems + .filter( + (item) => item.type === 'SWAP_FEE_24H' || item.type === 'IB_YIELD' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const stakingApr = aprItems + .filter( + (item) => + item.type === 'STAKING' || + item.type === 'MABEETS_EMISSIONS' || + item.type === 'STAKING_BOOST' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const rewardTokens = aprItems + .filter( + (item) => + (item.type === 'STAKING' || + item.type === 'MABEETS_EMISSIONS' || + item.type === 'STAKING_BOOST') && + item.rewardTokenAddress + ) + .map((item) => item.rewardTokenAddress); + + const underlyingTokens = pool.poolTokens + .map((token) => token.address) + .filter(Boolean); + + return { + pool: pool.address, + chain: utils.formatChain(chainString), + project: version === 3 ? 'beets-dex-v3' : 'beets-dex', + symbol: utils.formatSymbol(pool.symbol), + tvlUsd: Number(pool.dynamicData.totalLiquidity), + apyBase: baseApr * 100, + apyReward: stakingApr * 100, + rewardTokens: rewardTokens, + underlyingTokens: underlyingTokens, + url: `https://beets.fi/pools/${chainString}/v${version}/${pool.id}`, + }; + }); + } catch (error) { + console.error( + `Error fetching Beets V${version} pools for ${chainString}:`, + error + ); + return []; + } +}; + +module.exports = { getPools }; diff --git a/src/adaptors/beforeTests.js b/src/adaptors/beforeTests.js new file mode 100644 index 0000000000..e4a6548246 --- /dev/null +++ b/src/adaptors/beforeTests.js @@ -0,0 +1,85 @@ +const path = require('path'); +const axios = require('axios'); +const fs = require('fs'); + +try { + const envPath = path.resolve(__dirname, '../../config.env'); + require('dotenv').config({ path: envPath }); +} catch (e) {} + +// support requiring TS adapters directly (eg: index.ts) +try { + const tsConfigPath = path.resolve(__dirname, '../../tsconfig.json'); + require('ts-node').register({ transpileOnly: true, project: tsConfigPath }); +} catch (e) { + // ts-node may not be installed in some contexts; ignore if unavailable +} + +module.exports = async function () { + const adapter = process.env.npm_config_adapter; + const timestamp = process.env.npm_config_timestamp; + const isFast = !!process.env.npm_config_fast; + if (!adapter) { + console.error( + `Missing argument, you need to provide the adapter name. Eg: npm run test --adapter=aave-v2` + ); + process.exit(1); + } + + const cwd = process.cwd(); + const isFileArg = /\.(ts|js)$/i.test(adapter); + + const candidates = []; + if (isFileArg) { + candidates.push(path.resolve(cwd, adapter)); + if (!cwd.includes('src/adaptors')) + candidates.push(path.resolve(cwd, 'src/adaptors', adapter)); + } else { + const baseDir = cwd.includes('src/adaptors') + ? path.resolve(cwd, adapter) + : path.resolve(cwd, 'src/adaptors', adapter); + candidates.push(path.join(baseDir, 'index.js')); + candidates.push(path.join(baseDir, 'index.ts')); + } + + const resolvedAdapterPath = candidates.find((p) => fs.existsSync(p)); + if (!resolvedAdapterPath) { + console.error( + `Adapter not found. Tried:\n${candidates + .map((p) => ' - ' + p) + .join('\n')}` + ); + process.exit(1); + } + + const module = require(resolvedAdapterPath); + + global.adapter = adapter; + global.apy = (await module.apy(timestamp)).sort( + (a, b) => b.tvlUsd - a.tvlUsd + ); + global.poolsUrl = module.url; + + const outputDir = path.resolve(__dirname, '../../.test-adapter-output'); + fs.mkdirSync(outputDir, { recursive: true }); + fs.writeFileSync( + path.join(outputDir, `${adapter}.json`), + JSON.stringify(global.apy) + ); + + if (!isFast) { + global.protocolsSlug = [ + ...new Set( + (await axios.get('https://api.llama.fi/protocols')).data.map( + (protocol) => protocol.slug + ) + ), + ]; + + global.uniquePoolIdentifiersDB = new Set( + (await axios.get('https://yields.llama.fi/distinctID')).data + .filter((p) => p.project !== global.apy[0].project) + .map((p) => p.pool) + ); + } +}; diff --git a/src/adaptors/bella-protocol/abi.js b/src/adaptors/bella-protocol/abi.js new file mode 100644 index 0000000000..cb890e524e --- /dev/null +++ b/src/adaptors/bella-protocol/abi.js @@ -0,0 +1,2533 @@ +exports.ContractAbis = { + miniAbi: [ + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', type: 'uint256' }], + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + type: 'function', + }, + ], + erc20TokenAbi: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + bVaultAbi: [ + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { internalType: 'address', name: '_controller', type: 'address' }, + { internalType: 'address', name: 'whiteList', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'available', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'balance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'controller', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'deposit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'earn', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getPricePerFullShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'governance', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'max', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'min', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'pause', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'pauseRoles', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'rebalance', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_controller', type: 'address' }, + ], + name: 'setController', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_governance', type: 'address' }, + ], + name: 'setGovernance', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_min', type: 'uint256' }], + name: 'setMin', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'admin', type: 'address' }], + name: 'setPauseRole', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_withdrawalFee', type: 'uint256' }, + ], + name: 'setWithdrawalFee', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'admin', type: 'address' }], + name: 'unSetPauseRole', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlyingBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'unpause', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'whiteList', + outputs: [ + { internalType: 'contract WhiteList', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'withdraw', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'withdrawAll', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'withdrawalFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'withdrawalMax', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + bStakingAbi: [ + { + inputs: [ + { internalType: 'contract IERC20', name: '_bella', type: 'address' }, + { internalType: 'uint256', name: '_startTime', type: 'uint256' }, + { internalType: 'address', name: 'governance', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IERC20', + name: '_underlyingToken', + type: 'address', + }, + { internalType: 'uint256[3]', name: 'boost', type: 'uint256[3]' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'bella', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'bellaPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'boostInfo', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'claimAllBella', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: 'savingType', type: 'uint256' }, + ], + name: 'claimBella', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'claimingBellas', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'unlockTime', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'collectBella', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'collectiableBella', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'currentUnlockCycle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'delayedBella', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + { internalType: 'uint256', name: 'savingType', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: 'savingType', type: 'uint256' }, + ], + name: 'earnedBella', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'earnedBellaAll', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'earnedBellaAllPool', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: 'savingType', type: 'uint256' }, + ], + name: 'emergencyWithdraw', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getBtokenStaked', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isOwner', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'nextUnlockCycle', type: 'uint256' }, + ], + name: 'lock', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'massUpdatePools', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { + internalType: 'contract IERC20', + name: 'underlyingToken', + type: 'address', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accBellaPerShare', type: 'uint256' }, + { + internalType: 'uint256', + name: 'totalEffectiveAmount', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'renounceOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'set', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'startTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unlockEndTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'userInfos', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'effectiveAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'earnedBella', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + { internalType: 'uint256', name: 'savingType', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'withdrawAll', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + bLockerAbi: [ + { + inputs: [ + { + internalType: 'address', + name: 'governence', + type: 'address', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'bel', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isOwner', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'renounceOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'saved', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'userSavings', + outputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'unlockTime', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'savingType', + type: 'uint256', + }, + ], + name: 'lock', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'withdraw', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingReward', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'withdrawDust', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + crvPoolAbi: [ + { + name: 'TokenExchange', + inputs: [ + { type: 'address', name: 'buyer', indexed: true }, + { type: 'int128', name: 'sold_id', indexed: false }, + { type: 'uint256', name: 'tokens_sold', indexed: false }, + { type: 'int128', name: 'bought_id', indexed: false }, + { type: 'uint256', name: 'tokens_bought', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'AddLiquidity', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256[3]', name: 'token_amounts', indexed: false }, + { type: 'uint256[3]', name: 'fees', indexed: false }, + { type: 'uint256', name: 'invariant', indexed: false }, + { type: 'uint256', name: 'token_supply', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidity', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256[3]', name: 'token_amounts', indexed: false }, + { type: 'uint256[3]', name: 'fees', indexed: false }, + { type: 'uint256', name: 'token_supply', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidityOne', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256', name: 'token_amount', indexed: false }, + { type: 'uint256', name: 'coin_amount', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidityImbalance', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256[3]', name: 'token_amounts', indexed: false }, + { type: 'uint256[3]', name: 'fees', indexed: false }, + { type: 'uint256', name: 'invariant', indexed: false }, + { type: 'uint256', name: 'token_supply', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'CommitNewAdmin', + inputs: [ + { type: 'uint256', name: 'deadline', indexed: true }, + { type: 'address', name: 'admin', indexed: true }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewAdmin', + inputs: [{ type: 'address', name: 'admin', indexed: true }], + anonymous: false, + type: 'event', + }, + { + name: 'CommitNewFee', + inputs: [ + { type: 'uint256', name: 'deadline', indexed: true }, + { type: 'uint256', name: 'fee', indexed: false }, + { type: 'uint256', name: 'admin_fee', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewFee', + inputs: [ + { type: 'uint256', name: 'fee', indexed: false }, + { type: 'uint256', name: 'admin_fee', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RampA', + inputs: [ + { type: 'uint256', name: 'old_A', indexed: false }, + { type: 'uint256', name: 'new_A', indexed: false }, + { type: 'uint256', name: 'initial_time', indexed: false }, + { type: 'uint256', name: 'future_time', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'StopRampA', + inputs: [ + { type: 'uint256', name: 'A', indexed: false }, + { type: 'uint256', name: 't', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + outputs: [], + inputs: [ + { type: 'address', name: '_owner' }, + { type: 'address[3]', name: '_coins' }, + { type: 'address', name: '_pool_token' }, + { type: 'uint256', name: '_A' }, + { type: 'uint256', name: '_fee' }, + { type: 'uint256', name: '_admin_fee' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + name: 'A', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 5227, + }, + { + name: 'get_virtual_price', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1133537, + }, + { + name: 'calc_token_amount', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'uint256[3]', name: 'amounts' }, + { type: 'bool', name: 'deposit' }, + ], + stateMutability: 'view', + type: 'function', + gas: 4508776, + }, + { + name: 'add_liquidity', + outputs: [], + inputs: [ + { type: 'uint256[3]', name: 'amounts' }, + { type: 'uint256', name: 'min_mint_amount' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 6954858, + }, + { + name: 'get_dy', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'int128', name: 'i' }, + { type: 'int128', name: 'j' }, + { type: 'uint256', name: 'dx' }, + ], + stateMutability: 'view', + type: 'function', + gas: 2673791, + }, + { + name: 'get_dy_underlying', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'int128', name: 'i' }, + { type: 'int128', name: 'j' }, + { type: 'uint256', name: 'dx' }, + ], + stateMutability: 'view', + type: 'function', + gas: 2673474, + }, + { + name: 'exchange', + outputs: [], + inputs: [ + { type: 'int128', name: 'i' }, + { type: 'int128', name: 'j' }, + { type: 'uint256', name: 'dx' }, + { type: 'uint256', name: 'min_dy' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 2818066, + }, + { + name: 'remove_liquidity', + outputs: [], + inputs: [ + { type: 'uint256', name: '_amount' }, + { type: 'uint256[3]', name: 'min_amounts' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 192846, + }, + { + name: 'remove_liquidity_imbalance', + outputs: [], + inputs: [ + { type: 'uint256[3]', name: 'amounts' }, + { type: 'uint256', name: 'max_burn_amount' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 6951851, + }, + { + name: 'calc_withdraw_one_coin', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'uint256', name: '_token_amount' }, + { type: 'int128', name: 'i' }, + ], + stateMutability: 'view', + type: 'function', + gas: 1102, + }, + { + name: 'remove_liquidity_one_coin', + outputs: [], + inputs: [ + { type: 'uint256', name: '_token_amount' }, + { type: 'int128', name: 'i' }, + { type: 'uint256', name: 'min_amount' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 4025523, + }, + { + name: 'ramp_A', + outputs: [], + inputs: [ + { type: 'uint256', name: '_future_A' }, + { type: 'uint256', name: '_future_time' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 151919, + }, + { + name: 'stop_ramp_A', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 148637, + }, + { + name: 'commit_new_fee', + outputs: [], + inputs: [ + { type: 'uint256', name: 'new_fee' }, + { type: 'uint256', name: 'new_admin_fee' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 110461, + }, + { + name: 'apply_new_fee', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 97242, + }, + { + name: 'revert_new_parameters', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 21895, + }, + { + name: 'commit_transfer_ownership', + outputs: [], + inputs: [{ type: 'address', name: '_owner' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 74572, + }, + { + name: 'apply_transfer_ownership', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 60710, + }, + { + name: 'revert_transfer_ownership', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 21985, + }, + { + name: 'admin_balances', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'i' }], + stateMutability: 'view', + type: 'function', + gas: 3481, + }, + { + name: 'withdraw_admin_fees', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 21502, + }, + { + name: 'donate_admin_fees', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 111389, + }, + { + name: 'kill_me', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 37998, + }, + { + name: 'unkill_me', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 22135, + }, + { + name: 'coins', + outputs: [{ type: 'address', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2220, + }, + { + name: 'balances', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2250, + }, + { + name: 'fee', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2171, + }, + { + name: 'admin_fee', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2201, + }, + { + name: 'owner', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2231, + }, + { + name: 'initial_A', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2261, + }, + { + name: 'future_A', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2291, + }, + { + name: 'initial_A_time', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2321, + }, + { + name: 'future_A_time', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2351, + }, + { + name: 'admin_actions_deadline', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2381, + }, + { + name: 'transfer_ownership_deadline', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2411, + }, + { + name: 'future_fee', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2441, + }, + { + name: 'future_admin_fee', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2471, + }, + { + name: 'future_owner', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2501, + }, + ], + crvPoolGaugeAbi: [ + { + name: 'Deposit', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256', name: 'value', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'Withdraw', + inputs: [ + { type: 'address', name: 'provider', indexed: true }, + { type: 'uint256', name: 'value', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'UpdateLiquidityLimit', + inputs: [ + { type: 'address', name: 'user', indexed: false }, + { type: 'uint256', name: 'original_balance', indexed: false }, + { type: 'uint256', name: 'original_supply', indexed: false }, + { type: 'uint256', name: 'working_balance', indexed: false }, + { type: 'uint256', name: 'working_supply', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + outputs: [], + inputs: [ + { type: 'address', name: 'lp_addr' }, + { type: 'address', name: '_minter' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + name: 'user_checkpoint', + outputs: [{ type: 'bool', name: '' }], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 2079152, + }, + { + name: 'claimable_tokens', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 1998318, + }, + { + name: 'kick', + outputs: [], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 2084532, + }, + { + name: 'set_approve_deposit', + outputs: [], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'bool', name: 'can_deposit' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 35766, + }, + { + name: 'deposit', + outputs: [], + inputs: [{ type: 'uint256', name: '_value' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'deposit', + outputs: [], + inputs: [ + { type: 'uint256', name: '_value' }, + { type: 'address', name: 'addr' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'withdraw', + outputs: [], + inputs: [{ type: 'uint256', name: '_value' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 2208318, + }, + { + name: 'integrate_checkpoint', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2297, + }, + { + name: 'minter', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1421, + }, + { + name: 'crv_token', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1451, + }, + { + name: 'lp_token', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1481, + }, + { + name: 'controller', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1511, + }, + { + name: 'voting_escrow', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1541, + }, + { + name: 'balanceOf', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 1725, + }, + { + name: 'totalSupply', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1601, + }, + { + name: 'future_epoch_time', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1631, + }, + { + name: 'approved_to_deposit', + outputs: [{ type: 'bool', name: '' }], + inputs: [ + { type: 'address', name: 'arg0' }, + { type: 'address', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 1969, + }, + { + name: 'working_balances', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 1845, + }, + { + name: 'working_supply', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1721, + }, + { + name: 'period', + outputs: [{ type: 'int128', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1751, + }, + { + name: 'period_timestamp', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 1890, + }, + { + name: 'integrate_inv_supply', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 1920, + }, + { + name: 'integrate_inv_supply_of', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 1995, + }, + { + name: 'integrate_checkpoint_of', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2025, + }, + { + name: 'integrate_fraction', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2055, + }, + { + name: 'inflation_rate', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1931, + }, + ], + crvGaugeControllerAbi: [ + { + name: 'CommitOwnership', + inputs: [{ type: 'address', name: 'admin', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'ApplyOwnership', + inputs: [{ type: 'address', name: 'admin', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'AddType', + inputs: [ + { type: 'string', name: 'name', indexed: false }, + { type: 'int128', name: 'type_id', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewTypeWeight', + inputs: [ + { type: 'int128', name: 'type_id', indexed: false }, + { type: 'uint256', name: 'time', indexed: false }, + { type: 'uint256', name: 'weight', indexed: false }, + { type: 'uint256', name: 'total_weight', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewGaugeWeight', + inputs: [ + { type: 'address', name: 'gauge_address', indexed: false }, + { type: 'uint256', name: 'time', indexed: false }, + { type: 'uint256', name: 'weight', indexed: false }, + { type: 'uint256', name: 'total_weight', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'VoteForGauge', + inputs: [ + { type: 'uint256', name: 'time', indexed: false }, + { type: 'address', name: 'user', indexed: false }, + { type: 'address', name: 'gauge_addr', indexed: false }, + { type: 'uint256', name: 'weight', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewGauge', + inputs: [ + { type: 'address', name: 'addr', indexed: false }, + { type: 'int128', name: 'gauge_type', indexed: false }, + { type: 'uint256', name: 'weight', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + outputs: [], + inputs: [ + { type: 'address', name: '_token' }, + { type: 'address', name: '_voting_escrow' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + name: 'commit_transfer_ownership', + outputs: [], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 37597, + }, + { + name: 'apply_transfer_ownership', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 38497, + }, + { + name: 'gauge_types', + outputs: [{ type: 'int128', name: '' }], + inputs: [{ type: 'address', name: '_addr' }], + stateMutability: 'view', + type: 'function', + gas: 1625, + }, + { + name: 'add_gauge', + outputs: [], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'int128', name: 'gauge_type' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'add_gauge', + outputs: [], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'int128', name: 'gauge_type' }, + { type: 'uint256', name: 'weight' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'checkpoint', + outputs: [], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + gas: 18033784416, + }, + { + name: 'checkpoint_gauge', + outputs: [], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + gas: 18087678795, + }, + { + name: 'gauge_relative_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'view', + type: 'function', + }, + { + name: 'gauge_relative_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'uint256', name: 'time' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + name: 'gauge_relative_weight_write', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'gauge_relative_weight_write', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'uint256', name: 'time' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'add_type', + outputs: [], + inputs: [{ type: 'string', name: '_name' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'add_type', + outputs: [], + inputs: [ + { type: 'string', name: '_name' }, + { type: 'uint256', name: 'weight' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'change_type_weight', + outputs: [], + inputs: [ + { type: 'int128', name: 'type_id' }, + { type: 'uint256', name: 'weight' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 36246310050, + }, + { + name: 'change_gauge_weight', + outputs: [], + inputs: [ + { type: 'address', name: 'addr' }, + { type: 'uint256', name: 'weight' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 36354170809, + }, + { + name: 'vote_for_gauge_weights', + outputs: [], + inputs: [ + { type: 'address', name: '_gauge_addr' }, + { type: 'uint256', name: '_user_weight' }, + ], + stateMutability: 'nonpayable', + type: 'function', + gas: 18142052127, + }, + { + name: 'get_gauge_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'addr' }], + stateMutability: 'view', + type: 'function', + gas: 2974, + }, + { + name: 'get_type_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'int128', name: 'type_id' }], + stateMutability: 'view', + type: 'function', + gas: 2977, + }, + { + name: 'get_total_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2693, + }, + { + name: 'get_weights_sum_per_type', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'int128', name: 'type_id' }], + stateMutability: 'view', + type: 'function', + gas: 3109, + }, + { + name: 'admin', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1841, + }, + { + name: 'future_admin', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1871, + }, + { + name: 'token', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1901, + }, + { + name: 'voting_escrow', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1931, + }, + { + name: 'n_gauge_types', + outputs: [{ type: 'int128', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1961, + }, + { + name: 'n_gauges', + outputs: [{ type: 'int128', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 1991, + }, + { + name: 'gauge_type_names', + outputs: [{ type: 'string', name: '' }], + inputs: [{ type: 'int128', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 8628, + }, + { + name: 'gauges', + outputs: [{ type: 'address', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2160, + }, + { + name: 'vote_user_slopes', + outputs: [ + { type: 'uint256', name: 'slope' }, + { type: 'uint256', name: 'power' }, + { type: 'uint256', name: 'end' }, + ], + inputs: [ + { type: 'address', name: 'arg0' }, + { type: 'address', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 5020, + }, + { + name: 'vote_user_power', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2265, + }, + { + name: 'last_user_vote', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'address', name: 'arg0' }, + { type: 'address', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 2449, + }, + { + name: 'points_weight', + outputs: [ + { type: 'uint256', name: 'bias' }, + { type: 'uint256', name: 'slope' }, + ], + inputs: [ + { type: 'address', name: 'arg0' }, + { type: 'uint256', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 3859, + }, + { + name: 'time_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'address', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2355, + }, + { + name: 'points_sum', + outputs: [ + { type: 'uint256', name: 'bias' }, + { type: 'uint256', name: 'slope' }, + ], + inputs: [ + { type: 'int128', name: 'arg0' }, + { type: 'uint256', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 3970, + }, + { + name: 'time_sum', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2370, + }, + { + name: 'points_total', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2406, + }, + { + name: 'time_total', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + gas: 2321, + }, + { + name: 'points_type_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'int128', name: 'arg0' }, + { type: 'uint256', name: 'arg1' }, + ], + stateMutability: 'view', + type: 'function', + gas: 2671, + }, + { + name: 'time_type_weight', + outputs: [{ type: 'uint256', name: '' }], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + gas: 2490, + }, + ], +}; diff --git a/src/adaptors/bella-protocol/address.js b/src/adaptors/bella-protocol/address.js new file mode 100644 index 0000000000..5bfa051f38 --- /dev/null +++ b/src/adaptors/bella-protocol/address.js @@ -0,0 +1,55 @@ +exports.crvBaseApyUrl = 'http://stats.curve.fi/raw-stats/apys.json'; + +exports.ContractAddresses = { + // curr vault support tokens + usdtTokenAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7', + usdcTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + arpaTokenAddress: '0xba50933c268f567bdc86e1ac131be072c6b0b71a', + wbtcTokenAddress: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + daiTokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f', + busdTokenAddress: '0x4fabb145d64652a948d72533023f6e7a623c7c53', + hbtcTokenAddress: '0x0316EB71485b0Ab14103307bf65a021042c6d380', + + // vault contracts + bVaultUsdtAddress: '0x2c23276107b45E64c8c59482f4a24f4f2E568ea6', + bVaultUsdcAddress: '0x8016907D54eD8BCf5da100c4D0EB434C0185dC0E', + bVaultArpaAddress: '0x750d30A8259E63eD72a075f5b6630f08ce7996d0', + bVaultWbtcAddress: '0x3fb6b07d77dace1BA6B5f6Ab1d8668643d15a2CC', + bVaultHbtcAddress: '0x8D9A39706d3B66446a298f1ae735730257Ec6108', + bVaultBusdAddress: '0x378388aa69f3032FA46150221210C7FA70A35153', + // bVaultDaiAddress: "0xa150329108FE255d9B62430B855c17DE6Bf54299", // CHANGE TO PROD!!! + + // staking contracts + bStakingContractAddress: '0x6Cb6FF550Ea4473Ed462F8bda38aE3226C04649d', + + // locker contracts + bLockerContractAddress: '0x20b91c9826E1a500570ea9c6396DBa8cff473A93', + + // token contracts + bellaTokenAddress: '0xa91ac63d040deb1b7a5e4d4134ad23eb0ba07e14', + wethTokenAddress: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + crvTokenAddress: '0xD533a949740bb3306d119CC777fa900bA034cd52', + + // uni pool address + usdcUsdtPoolAddress: '0x3041cbd36888becc7bbcbc0045e3b1f144466f5f', + belUsdtUniPoolAddress: '0xf0d1109e723cb06e400e2e57d0b6c7c32bedf61a', + arpaUsdtUniPoolAddress: '0x9F624b25991b99D7b14d6740A9D581DD77980808', + wbtcUsdtUniPoolAddress: '0x0de0fa91b6dbab8c8503aaa2d1dfa91a192cb149', + wethUsdtUniPoolAddress: '0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852', + crvEthUniPoolAddress: '0x3da1313ae46132a397d90d95b1424a9a7e3e0fce', + // daiUsdtUniPoolAddress: '', // CHANGE TO PROD + busdUsdtUniPoolAddress: '0xa0abda1f980e03d7eadb78aed8fc1f2dd0fe83dd', + hbtcEthUniPoolAddress: '0xa6f4eae7fdaa20e632c45d4cd39e4f3961892322', + + // crv pool address + crvGaugeControllerAddress: '0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB', + + crv3poolAddress: '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7', + crv3poolGaugeAddress: '0xbFcF63294aD7105dEa65aA58F8AE5BE2D9d0952A', + + crvhbtcPoolAddress: '0x4CA9b3063Ec5866A4B82E437059D2C43d1be596F', + crvhbtcPoolGaugeAddress: '0x4c18E409Dc8619bFb6a1cB56D114C3f592E0aE79', + + crvbusdPoolAddress: '0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27', + crvbusdPoolGaugeAddress: '0x69Fb7c45726cfE2baDeE8317005d3F94bE838840', +}; diff --git a/src/adaptors/bella-protocol/apy.js b/src/adaptors/bella-protocol/apy.js new file mode 100644 index 0000000000..f2309674e0 --- /dev/null +++ b/src/adaptors/bella-protocol/apy.js @@ -0,0 +1,459 @@ +const { ContractAddresses, crvBaseApyUrl } = require('./address'); +const { api } = require('@defillama/sdk'); +const { ContractAbis } = require('./abi'); +const { + TokenPriceAcquireMethode, + ConfigContent, + StakingTokens, + VaultTokens, +} = require('./token'); +const fetch = require('node-fetch'); + +const chain = 'ethereum'; +const callAbi = (abi, target, _config) => { + const { name: fName, ...callConfig } = + typeof _config === 'string' ? { name: _config } : _config; + return api.abi.call( + Object.assign( + { + chain, + target, + abi: abi.find(({ name }) => name === fName), + }, + callConfig + ) + ); +}; + +const getTokenBalance = (tokenAddress, poolAddress, unit = 18) => { + return callAbi(ContractAbis.miniAbi, tokenAddress, { + name: 'balanceOf', + params: poolAddress, + }).then(({ output }) => { + return output / Math.pow(10, unit); + }); +}; + +const getTokenPriceUniUsdtPool = async ( + tokenAddress, + poolAddress, + formatUnit +) => { + if (tokenAddress === ContractAddresses.usdtTokenAddress) { + return 1; + } else { + const [tokenBalance, usdtBalance] = await Promise.all([ + getTokenBalance(tokenAddress, poolAddress, formatUnit), + getTokenBalance(ContractAddresses.usdtTokenAddress, poolAddress, 6), + ]); + + return (usdtBalance / tokenBalance).toFixed(3); + } +}; + +const getTokenUsdtPriceUniEthPool = async ( + tokenContractAddress, + uniTokenUniPoolAddress, + formatUnit +) => { + if (tokenContractAddress === ContractAddresses.usdtTokenAddress) { + return 1; + } else { + const [tokenBalance, ethBalance, ethPrice] = await Promise.all([ + getTokenBalance(tokenContractAddress, uniTokenUniPoolAddress, formatUnit), + getTokenBalance( + ContractAddresses.wethTokenAddress, + uniTokenUniPoolAddress + ), + getTokenPriceUniUsdtPool( + ContractAddresses.wethTokenAddress, + ContractAddresses.wethUsdtUniPoolAddress + ), + ]); + + const alignedTokenBalance = parseFloat(tokenBalance); + const alignedEthBalance = parseFloat(ethBalance); + return ((alignedEthBalance * ethPrice) / alignedTokenBalance).toFixed(3); + } +}; + +const get3poolStrategyApy = async () => { + const values = await Promise.all([ + callAbi( + ContractAbis.crvPoolAbi, + ContractAddresses.crv3poolAddress, + 'get_virtual_price' + ), + + fetch(crvBaseApyUrl).then((res) => res.json()), + callAbi( + ContractAbis.crvPoolGaugeAbi, + ContractAddresses.crv3poolGaugeAddress, + 'inflation_rate' + ), + callAbi( + ContractAbis.crvGaugeControllerAbi, + ContractAddresses.crvGaugeControllerAddress, + { + params: ContractAddresses.crv3poolGaugeAddress, + name: 'gauge_relative_weight', + } + ), + callAbi( + ContractAbis.crvPoolGaugeAbi, + ContractAddresses.crv3poolGaugeAddress, + 'working_supply' + ), + getTokenUsdtPriceUniEthPool( + ContractAddresses.crvTokenAddress, + ContractAddresses.crvEthUniPoolAddress + ), + ]); + + const virtualPrice = values[0].output / 1e18; + const baseApy = parseFloat(values[1].apy.day['3pool']) * 100; + const inflationRate = values[2].output / 1e18; + const relativeWeight = values[3].output / 1e18; + const totalEffectiveStaked = values[4].output / 1e18; + const crvPrice = values[5]; + + const gaugeApy = + (inflationRate * + relativeWeight * + 60 * + 60 * + 24 * + 365 * + 100 * + crvPrice * + 0.4) / + totalEffectiveStaked / + virtualPrice; + + return parseFloat((baseApy + gaugeApy).toFixed(2)); +}; + +const getTotalAllocPoint = (tokenAddress) => { + return callAbi( + ContractAbis.bStakingAbi, + tokenAddress, + 'totalAllocPoint' + ).then(({ output }) => output / 1e18); +}; + +const getCurrPoolAllocPoint = (tokenAddress, poolId) => { + return callAbi(ContractAbis.bStakingAbi, tokenAddress, { + name: 'poolInfo', + params: poolId, + }).then(({ output }) => output.allocPoint / 1e18); +}; + +const getBelPerSecond = (tokenAddress) => { + return callAbi(ContractAbis.bStakingAbi, tokenAddress, 'bellaPerSecond').then( + ({ output }) => output / 1e18 + ); +}; + +const getTokenTotalSupply = (tokenAddress, formatUnit, callback) => { + return callAbi(ContractAbis.erc20TokenAbi, tokenAddress, 'totalSupply').then( + ({ output }) => output / Math.pow(10, formatUnit) + ); +}; + +const getTokenPriceBinance = (tokenBasePair) => { + return tokenBasePair === 'USDT' + ? new Promise((resolve) => resolve(1)) + : fetch(ConfigContent.binancePriceApi + tokenBasePair) + .then((response) => response.text()) + .then((_res) => { + let res = JSON.parse(_res); + return res.price; + }) + .catch((error) => console.log('error', error)); +}; + +const getTokenPriceCoingecko = (tokenId) => { + return tokenId === 'usd' + ? new Promise((resolve) => resolve(1)) + : fetch(ConfigContent.coingeckoPriceApi + tokenId + '&vs_currencies=usd') + .then((response) => response.text()) + .then((_res) => { + let res = JSON.parse(_res); + + return res[tokenId].usd; + }) + .catch((error) => console.log('error', error)); +}; + +const getBTokenPrice = (vaultContractAddress) => { + let priceRate = 1; + let token; + let tokenPrice = 0; + let bTokenPrice = 0; + + function getTokenObjFromVaultAddress(vaultContractAddress) { + VaultTokens.find((o) => { + if (o.bTokenContractAddress === vaultContractAddress) { + token = o; + return true; + } + }); + } + + return callAbi( + ContractAbis.bVaultAbi, + vaultContractAddress, + 'getPricePerFullShare' + ) + .then(({ output }) => output / 1e18) + .then((priceRate) => { + getTokenObjFromVaultAddress(vaultContractAddress); + + if (token.priceSrc === TokenPriceAcquireMethode.BINANCE_API) { + // use binance as price source (need to focus with binance api accessability from different area) + return getTokenPriceBinance(token.binanceApiSymbol).then( + (_tokenPrice) => { + tokenPrice = _tokenPrice; + + return (bTokenPrice = tokenPrice * priceRate); + } + ); + } else if (token.priceSrc === TokenPriceAcquireMethode.UNISWAP_USDT_LP) { + // use uniswap X/USDT pool + return getTokenPriceUniUsdtPool( + token.tokenContractAddress, + token.uniPoolAddress, + token.tokenDecimal + ).then((_tokenPrice) => { + tokenPrice = _tokenPrice; + return (bTokenPrice = tokenPrice * priceRate); + }); + } else if (token.priceSrc === TokenPriceAcquireMethode.UNISWAP_ETH_LP) { + // use uniswap X/ETH pool + return getTokenUsdtPriceUniEthPool( + token.tokenContractAddress, + token.uniPoolAddress, + token.tokenDecimal + ).then((_tokenPrice) => { + tokenPrice = _tokenPrice; + return (bTokenPrice = tokenPrice * priceRate); + }); + } else { + // use coingecko api as price source + return getTokenPriceCoingecko(token.coingeckoApiTokenId).then( + (_tokenPrice) => { + tokenPrice = _tokenPrice; + + return (bTokenPrice = tokenPrice * priceRate); + } + ); + } + }); +}; + +const getTotalAum = (token) => { + let bTokenTotalSupply = 0; + + return getTokenTotalSupply(token.bTokenContractAddress, token.bTokenDecimal) + .then((_bTokenTotalSupply) => { + bTokenTotalSupply = _bTokenTotalSupply; + + return getBTokenPrice(token.bTokenContractAddress); + }) + .then((_bTokenPrice) => { + return _bTokenPrice * bTokenTotalSupply; + }) + .catch(() => { + return 0; + }); +}; + +const getDistributionApy = async (token) => { + let weeklyRewardBelInUsd = 0; + let totalStakingBTokenInUsd = 0; + let distributionApy = 0; + + const values = await Promise.all([ + getTokenPriceUniUsdtPool( + ContractAddresses.bellaTokenAddress, + ContractAddresses.belUsdtUniPoolAddress + ), + getTotalAllocPoint(ContractAddresses.bStakingContractAddress), + getCurrPoolAllocPoint( + ContractAddresses.bStakingContractAddress, + token.bPoolId + ), + getBelPerSecond(ContractAddresses.bStakingContractAddress), + getTotalAum(token), + ]); + + const belPrice = values[0]; + const totalAllocPoint = values[1]; + const currPoolAllocPoint = values[2]; + const belPerSecond = values[3]; + const bTokenValue = values[4]; + + weeklyRewardBelInUsd = + (belPrice * belPerSecond * 60 * 60 * 24 * 7 * currPoolAllocPoint) / + totalAllocPoint; + + totalStakingBTokenInUsd = totalStakingBTokenInUsd + bTokenValue; + + const apy = (() => { + if (totalStakingBTokenInUsd === 0) { + return parseFloat(distributionApy.toFixed(2)); + } else { + if (token.symbol === 'bBUSD') { + // return '-'; + return 0; + } else { + distributionApy = + (weeklyRewardBelInUsd * 365 * 100) / 7 / totalStakingBTokenInUsd; + return parseFloat(distributionApy.toFixed(2)); + } + } + })(); + + return { apy, tvlUsd: bTokenValue }; +}; + +const getWbtcStrategyApy = async () => { + const values = await Promise.all([ + callAbi( + ContractAbis.crvPoolAbi, + ContractAddresses.crvhbtcPoolAddress, + 'get_virtual_price' + ), + fetch(ConfigContent.crvBaseApyUrl).then((res) => res.json()), + callAbi( + ContractAbis.crvPoolGaugeAbi, + ContractAddresses.crvhbtcPoolGaugeAddress, + 'inflation_rate' + ), + callAbi( + ContractAbis.crvGaugeControllerAbi, + ContractAddresses.crvGaugeControllerAddress, + { + name: 'gauge_relative_weight', + params: ContractAddresses.crvhbtcPoolGaugeAddress, + } + ), + callAbi( + ContractAbis.crvPoolGaugeAbi, + ContractAddresses.crvhbtcPoolGaugeAddress, + 'working_supply' + ), + getTokenUsdtPriceUniEthPool( + ContractAddresses.crvTokenAddress, + ContractAddresses.crvEthUniPoolAddress + ), + getTokenPriceUniUsdtPool( + ContractAddresses.wbtcTokenAddress, + ContractAddresses.wbtcUsdtUniPoolAddress, + 8 + ), + ]); + + const virtualPriceNormalize = values[0].output / 1e18; + const baseApy = parseFloat(values[1].apy.day['hbtc']) * 100; + const inflattionRateNormalize = values[2].output / 1e18; + const relativeWeigthNomalize = values[3].output / 1e18; + const totalEffectiveStakedNormalize = values[4].output / 1e18; + const crvPrice = values[5]; + const wbtcPrice = values[6]; + + const gaugeApy = + (inflattionRateNormalize * + relativeWeigthNomalize * + 60 * + 60 * + 24 * + 365 * + 100 * + crvPrice * + 0.4) / + totalEffectiveStakedNormalize / + virtualPriceNormalize / + wbtcPrice; + + return parseFloat((baseApy + gaugeApy).toFixed(2)); +}; + +const getApy = async () => { + const [ + // wbtc + wbtc_s, + wbtc_d, + // hbtc + // hbtc_s, + hbtc_d, + // usdt + usdt_s, + usdt_d, + // usdc + usdc_d, + // arpa + arpa_d, + ] = await Promise.all([ + // wbtc + getWbtcStrategyApy(), + getDistributionApy(StakingTokens[3]), + // hbtc + getDistributionApy(StakingTokens[4]), + + // USDT + get3poolStrategyApy(), + getDistributionApy(StakingTokens[0]), + + // USDC + getDistributionApy(StakingTokens[1]), + // ARPA + getDistributionApy(StakingTokens[2]), + ]); + + return Object.entries({ + usdt: { + strategyApy: usdt_s, + distributionApy: usdt_d.apy, + tvlUsd: usdt_d.tvlUsd, + pool: StakingTokens[0].bTokenContractAddress, + }, + usdc: { + strategyApy: usdt_s, + distributionApy: usdc_d.apy, + tvlUsd: usdc_d.tvlUsd, + pool: StakingTokens[1].bTokenContractAddress, + }, + arpa: { + strategyApy: 0, + distributionApy: arpa_d.apy, + tvlUsd: arpa_d.tvlUsd, + pool: StakingTokens[2].bTokenContractAddress, + }, + wbtc: { + strategyApy: wbtc_s, + distributionApy: wbtc_d.apy, + tvlUsd: wbtc_d.tvlUsd, + pool: StakingTokens[3].bTokenContractAddress, + }, + hbtc: { + strategyApy: wbtc_s, + distributionApy: hbtc_d.apy, + tvlUsd: hbtc_d.tvlUsd, + pool: StakingTokens[4].bTokenContractAddress, + }, + }).reduce((prev, cur) => { + const { strategyApy, distributionApy, tvlUsd, pool } = cur[1]; + return { + ...prev, + [cur[0]]: { + strategyApy: parseFloat(strategyApy.toFixed(2)), + distributionApy: parseFloat(distributionApy.toFixed(2)), + tvlUsd: parseFloat(tvlUsd.toFixed(3)), + pool, + }, + }; + }, {}); +}; + +exports.getApy = getApy; diff --git a/src/adaptors/bella-protocol/index.js b/src/adaptors/bella-protocol/index.js new file mode 100644 index 0000000000..ee9289bd2f --- /dev/null +++ b/src/adaptors/bella-protocol/index.js @@ -0,0 +1,28 @@ +const utils = require('../utils'); +const { getApy } = require('./apy'); + +const buildPool = + (chain) => + ([name, { strategyApy, distributionApy, tvlUsd, pool }]) => { + return { + pool: [pool, chain].join('-'), + chain: utils.formatChain(chain), + project: 'bella-protocol', + symbol: utils.formatSymbol(name.toUpperCase()), + rewardTokens: ['0xcA7aE36A38eA4dE50DFEeCF6A4c44fC074811a6c'], + apyBase: strategyApy, + apyReward: distributionApy, + tvlUsd, + url: `https://fs.bella.fi/#/flex-savings/${name.toUpperCase()}`, + }; + }; + +const main = async () => { + const apy = await getApy(); + return Object.entries(apy).map(buildPool('ethereum')); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/bella-protocol/token.js b/src/adaptors/bella-protocol/token.js new file mode 100644 index 0000000000..b24be53e85 --- /dev/null +++ b/src/adaptors/bella-protocol/token.js @@ -0,0 +1,196 @@ +const { ContractAddresses } = require('./address'); + +const TokenPriceAcquireMethode = { + BINANCE_API: 'BINANCE_API', + COINGECKO_API: 'COINGECKO_API', + UNISWAP_USDT_LP: 'UNISWAP_USDT_LP', + UNISWAP_ETH_LP: 'UNISWAP_ETH_LP', +}; + +exports.TokenPriceAcquireMethode = TokenPriceAcquireMethode; + +exports.VaultTokens = [ + { + name: 'USDT', + tokenContractAddress: ContractAddresses.usdtTokenAddress, + tokenDecimal: 6, + bTokenContractAddress: ContractAddresses.bVaultUsdtAddress, + bTokenDecimal: 6, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'USDT', + uniPoolAddress: '', + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: false, + }, + { + name: 'USDC', + tokenContractAddress: ContractAddresses.usdcTokenAddress, + tokenDecimal: 6, + bTokenContractAddress: ContractAddresses.bVaultUsdcAddress, + bTokenDecimal: 6, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'USDCUSDT', + uniPoolAddress: ContractAddresses.usdcUsdtPoolAddress, + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: false, + }, + { + name: 'ARPA', + tokenContractAddress: ContractAddresses.arpaTokenAddress, + tokenDecimal: 18, + bTokenContractAddress: ContractAddresses.bVaultArpaAddress, + bTokenDecimal: 18, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'ARPAUSDT', + uniPoolAddress: ContractAddresses.arpaUsdtUniPoolAddress, + coingeckoApiTokenId: '', + coreStrategy: 'ARPA', + onhold: false, + }, + { + name: 'WBTC', + tokenContractAddress: ContractAddresses.wbtcTokenAddress, + tokenDecimal: 8, + bTokenContractAddress: ContractAddresses.bVaultWbtcAddress, + bTokenDecimal: 8, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'BTCUSDT', + uniPoolAddress: ContractAddresses.wbtcUsdtUniPoolAddress, + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: false, + }, + { + name: 'HBTC', + tokenContractAddress: ContractAddresses.hbtcTokenAddress, + tokenDecimal: 18, + bTokenContractAddress: ContractAddresses.bVaultHbtcAddress, + bTokenDecimal: 18, + priceSrc: TokenPriceAcquireMethode.UNISWAP_ETH_LP, + binanceApiSymbol: 'BTCUSDT', + uniPoolAddress: ContractAddresses.hbtcEthUniPoolAddress, + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: false, + }, + { + name: 'BUSD', + tokenContractAddress: ContractAddresses.busdTokenAddress, + tokenDecimal: 18, + bTokenContractAddress: ContractAddresses.bVaultBusdAddress, + bTokenDecimal: 18, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'BUSDUSDT', + uniPoolAddress: ContractAddresses.busdUsdtUniPoolAddress, + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: false, + }, + { + name: 'DAI', + tokenContractAddress: ContractAddresses.daiTokenAddress, + tokenDecimal: 18, + bTokenContractAddress: ContractAddresses.bVaultDaiAddress, + bTokenDecimal: 18, + priceSrc: TokenPriceAcquireMethode.UNISWAP_USDT_LP, + binanceApiSymbol: 'DAIUSDT', + uniPoolAddress: '', // change to prod + coingeckoApiTokenId: '', + coreStrategy: 'CRV', + onhold: true, + }, +]; + +exports.ConfigContent = { + // nav url + governanceUrl: 'https://snapshot.page/#/bella', + liquiditMiningUrl: 'https://liquidity.bella.fi', + lockerUrl: 'https://locker.bella.fi/', + + // tutorial url + bannerUrl: + 'https://bellaofficial.medium.com/tutorial-on-bella-flex-savings-v2-e622716313ca', + + // staking monthly reward + weeklyStakingBelReward: 5000, + + // const url + peckShieldAuditUrl: + 'https://github.com/peckshield/publications/blob/master/audit_reports/bella_audit_report_2020_48_en_1_0.pdf', + binancePriceApi: 'https://api.binance.com/api/v3/avgPrice?symbol=', + coingeckoPriceApi: 'https://api.coingecko.com/api/v3/simple/price?ids=', + crvBaseApyUrl: 'http://stats.curve.fi/raw-stats/apys.json', + + // 3pool crv api + crvApy: 13.89, + wbtcApy: 12.03, + + // arpa strategy apy + arpaVaultContractAddress: '0x750d30A8259E63eD72a075f5b6630f08ce7996d0', + arpaRewardAmount: 1000000, +}; + +exports.StakingTokens = [ + { + id: 1, + title: 'USDT Tea', + desc: 'Stake bUSDT for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultUsdtAddress, + bTokenDecimal: 6, + bPoolId: 0, + symbol: 'bUSDT', + weeklyRewardBel: 8160, + }, + { + id: 2, + title: 'USDC Cake', + desc: 'Stake bUSDC for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultUsdcAddress, + bTokenDecimal: 6, + bPoolId: 1, + symbol: 'bUSDC', + weeklyRewardBel: 5175, + }, + { + id: 3, + title: 'ARPA Cake', + desc: 'Stake bARPA for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultArpaAddress, + bTokenDecimal: 18, + bPoolId: 2, + symbol: 'bARPA', + weeklyRewardBel: 9000, + }, + { + id: 4, + title: 'WBTC Cocktail', + desc: 'Stake bWBTC for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultWbtcAddress, + bTokenDecimal: 8, + bPoolId: 3, + symbol: 'bWBTC', + weeklyRewardBel: 12800, + }, + { + id: 5, + title: 'HBTC Sake', + desc: 'Stake bHBTC for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultHbtcAddress, + bTokenDecimal: 18, + bPoolId: 4, + symbol: 'bHBTC', + weeklyRewardBel: 1750, + }, + { + id: 6, + title: 'BUSD Champagne', + desc: 'Stake bBUSD for BEL Rewards', + bTokenContractAddress: ContractAddresses.bVaultBusdAddress, + bTokenDecimal: 18, + bPoolId: 5, + symbol: 'bBUSD', + weeklyRewardBel: 0, + }, +]; diff --git a/src/adaptors/benddao-lending/index.js b/src/adaptors/benddao-lending/index.js new file mode 100644 index 0000000000..3056fc0365 --- /dev/null +++ b/src/adaptors/benddao-lending/index.js @@ -0,0 +1,216 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const BigNumber = require('bignumber.js'); + +const AddressMap = { + ethereum: { + WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + UiPoolDataProvider: '0x5250cCE48E43AB930e45Cc8E71C87Ca4B51244cf', + LendPoolAddressProvider: '0x24451F47CaF13B24f4b5034e1dF6c0E401ec0e46', + Bend: '0x0d02755a5700414B26FF040e1dE35D337DF56218', + BendProtocolIncentivesController: + '0x26FC1f11E612366d3367fc0cbFfF9e819da91C8d', + UniswapV2PairWETH: '0x336ef4e633b1117dca08c1a57f4139c62c32c935', + StakedBUNI: '0x647C509AF2A2b2294bB79fCE12DaEc8e7cf938f7', + }, +}; + +const ChainName = { + ethereum: 'Ethereum', +}; + +const projectSlug = 'benddao-lending'; + +async function apy() { + const pools = await Promise.all( + ['ethereum'].map(async (chain) => { + const [prices, { output: reserveList }] = await Promise.all([ + (async () => { + const coins = [ + `${chain}:${AddressMap[chain].WETH}`, + `${chain}:${AddressMap[chain].Bend}`, + ] + .join(',') + .toLowerCase(); + + const ret = await superagent.get( + `https://coins.llama.fi/prices/current/${coins}` + ); + return ret.body.coins; + })(), + sdk.api.abi.call({ + target: AddressMap[chain].UiPoolDataProvider, + abi: 'function getSimpleReservesData(address provider) view returns (tuple(address underlyingAsset, string name, string symbol, uint256 decimals, uint256 reserveFactor, bool borrowingEnabled, bool isActive, bool isFrozen, uint128 liquidityIndex, uint128 variableBorrowIndex, uint128 liquidityRate, uint128 variableBorrowRate, uint40 lastUpdateTimestamp, address bTokenAddress, address debtTokenAddress, address interestRateAddress, uint256 availableLiquidity, uint256 totalVariableDebt, uint256 priceInEth, uint256 variableRateSlope1, uint256 variableRateSlope2)[])', + params: [AddressMap[chain].LendPoolAddressProvider], + chain, + }), + ]); + + const ethPriceUsd = + prices[`${chain}:${AddressMap[chain].WETH}`.toLowerCase()].price; + const bendPriceUsd = + prices[`${chain}:${AddressMap[chain].Bend}`.toLowerCase()].price; + + return ( + await Promise.all( + // Lend Pool + [ + Promise.all( + reserveList.map(async (reserve) => { + const [ + { + output: [ + { output: bTokenAsset }, + { output: debtTokenAsset }, + ], + }, + + { + output: [ + { output: bTokenTotalSupply }, + { output: debtTokenTotalSupply }, + ], + }, + ] = await Promise.all([ + sdk.api.abi.multiCall({ + target: AddressMap[chain].BendProtocolIncentivesController, + abi: 'function assets(address) view returns (uint128 emissionPerSecond, uint128 lastUpdateTimestamp, uint256 index)', + calls: [ + { params: [reserve.bTokenAddress] }, + { params: [reserve.debtTokenAddress] }, + ], + chain, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: [ + { target: reserve.bTokenAddress }, + { target: reserve.debtTokenAddress }, + ], + }), + ]); + + const usdPrice = new BigNumber(reserve.priceInEth) + .multipliedBy(ethPriceUsd) + .shiftedBy(-18) + .shiftedBy(0 - reserve.decimals); + + const availableLiquidityUsd = new BigNumber( + reserve.availableLiquidity + ).multipliedBy(usdPrice); + const totalVariableDebtUsd = new BigNumber( + reserve.totalVariableDebt + ).multipliedBy(usdPrice); + + return { + pool: `${reserve.bTokenAddress}-${chain}`, + chain: ChainName[chain], + project: projectSlug, + symbol: reserve.symbol, + tvlUsd: availableLiquidityUsd.toNumber(), + apyBase: new BigNumber(reserve.liquidityRate) + .shiftedBy(-27) + .multipliedBy(100) + .toNumber(), + apyReward: new BigNumber(bTokenAsset.emissionPerSecond) + .multipliedBy(365 * 24 * 60 * 60) + .multipliedBy(bendPriceUsd) + .dividedBy(bTokenTotalSupply) + .dividedBy(ethPriceUsd) + .multipliedBy(100) + .toNumber(), + rewardTokens: [AddressMap[chain].Bend], + underlyingTokens: [reserve.underlyingAsset], + url: 'https://benddao.xyz', + apyBaseBorrow: new BigNumber(reserve.variableBorrowRate) + .shiftedBy(-27) + .multipliedBy(100) + .toNumber(), + apyRewardBorrow: new BigNumber( + debtTokenAsset.emissionPerSecond + ) + .multipliedBy(365 * 24 * 60 * 60) + .multipliedBy(bendPriceUsd) + .dividedBy(debtTokenTotalSupply) + .dividedBy(ethPriceUsd) + .multipliedBy(100) + .toNumber(), + totalSupplyUsd: availableLiquidityUsd + .plus(totalVariableDebtUsd) + .toNumber(), + totalBorrowUsd: totalVariableDebtUsd.toNumber(), + borrowable: reserve.borrowingEnabled, + }; + }) + ), + + // Liquidity Pool + (async () => { + const [ + { output: apr }, + { + output: [{ output: wethBalance }, { output: bendBalance }], + }, + ] = await Promise.all([ + sdk.api.abi.call({ + target: AddressMap[chain].StakedBUNI, + abi: 'uint256:apr', + chain, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + chain, + calls: [ + { + target: AddressMap[chain].WETH, + params: [AddressMap[chain].UniswapV2PairWETH], + }, + { + target: AddressMap[chain].Bend, + params: [AddressMap[chain].UniswapV2PairWETH], + }, + ], + }), + ]); + + return { + pool: `${AddressMap[chain].UniswapV2PairWETH}-${chain}`, + chain: ChainName[chain], + project: projectSlug, + symbol: 'BEND-WETH', + tvlUsd: new BigNumber( + new BigNumber(wethBalance) + .shiftedBy(-18) + .multipliedBy(ethPriceUsd) + ) + .plus( + new BigNumber(bendBalance) + .shiftedBy(-18) + .multipliedBy(bendPriceUsd) + ) + .toNumber(), + apyBase: new BigNumber(apr) + .shiftedBy(-18) + .multipliedBy(100) + .toNumber(), + rewardTokens: [AddressMap[chain].Bend], + underlyingTokens: [ + AddressMap[chain].Bend, + AddressMap[chain].WETH, + ], + url: 'https://benddao.xyz', + }; + })(), + ] + ) + ).flat(); + }) + ); + + return pools.flat(); +} + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/benqi-lending/abi.js b/src/adaptors/benqi-lending/abi.js new file mode 100644 index 0000000000..d90db52d96 --- /dev/null +++ b/src/adaptors/benqi-lending/abi.js @@ -0,0 +1,3361 @@ +module.exports = { + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'rewardToken', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowRewardSpeed', + type: 'uint256', + }, + ], + name: 'BorrowRewardSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorQiSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'qiDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'qiBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'qiDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'qiBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'QiGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'rewardToken', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract QiToken', + name: 'qiToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSupplyRewardSpeed', + type: 'uint256', + }, + ], + name: 'SupplyRewardSpeedUpdated', + type: 'event', + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantQi', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract QiToken[]', + name: 'qiTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + { internalType: 'uint256', name: 'supplyRewardSpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowRewardSpeed', type: 'uint256' }, + ], + name: '_setRewardSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [ + { internalType: 'contract QiToken', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [ + { internalType: 'contract QiToken', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'borrowRewardSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract QiToken', name: 'qiToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + { + internalType: 'contract QiToken[]', + name: 'qiTokens', + type: 'address[]', + }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { + internalType: 'address payable[]', + name: 'holders', + type: 'address[]', + }, + { + internalType: 'contract QiToken[]', + name: 'qiTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimReward', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'qiTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract QiToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract QiToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'qiTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialIndexConstant', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'qiTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'qiTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'qiTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'qiTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isQied', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'qiAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rewardAvax', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rewardQi', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'qiTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'qiTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newQiAddress', type: 'address' }, + ], + name: 'setQiAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'supplyRewardSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'qiToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + qiAvax: [ + { + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + { internalType: 'address payable', name: 'admin_', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'qiTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isQiToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'contract QiToken', + name: 'qiTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'mint', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'repayBorrow', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'borrower', type: 'address' }], + name: 'repayBorrowBehalf', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + qiErc: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'qiTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isQiToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract QiTokenInterface', + name: 'qiTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/benqi-lending/index.js b/src/adaptors/benqi-lending/index.js new file mode 100644 index 0000000000..4278f6c0b6 --- /dev/null +++ b/src/adaptors/benqi-lending/index.js @@ -0,0 +1,242 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const { Web3 } = require('web3'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { comptrollerAbi, qiAvax, qiErc } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x486Af39519B4Dc9a7fCcd318217352830E8AD9b4'; + +const AVAX = { + decimals: 18, + symbol: 'AVAX', + address: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', +}; + +const QI = { + decimals: 18, + symbol: 'QI', + address: '0x8729438eb15e2c8b576fcc6aecda6a148776c0f5', +}; + +const REWARD_TYPES = { + QI: 0, + AVAX: 1, +}; + +const SECONDS_PER_DAY = 86400; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const secondsPerDay = 86400; // seconds per day + const daysPerYear = 365; + + return ( + (Math.pow((ratePerTimestamps / 1e18) * secondsPerDay + 1, daysPerYear) - + 1) * + 100 + ); +}; + +const getRewards = async (rewardType, markets, isBorrow = false) => { + return ( + await sdk.api.abi.multiCall({ + chain: 'avax', + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [rewardType, market], + })), + abi: comptrollerAbi.find( + ({ name }) => name === `${isBorrow ? 'borrow' : 'supply'}RewardSpeeds` + ), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: 'avax', + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const getApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: 'avax', + abi: comptrollerAbi.find(({ name }) => name === 'getAllMarkets'), + permitFailure: true, + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const marketsInfo = ( + await sdk.api.abi.multiCall({ + chain: 'avax', + calls: allMarkets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: market, + })), + abi: comptrollerAbi.find(({ name }) => name === 'markets'), + permitFailure: true, + }) + ).output.map(({ output }) => output); + + const qiRewards = await getRewards(REWARD_TYPES.QI, allMarkets); + const avaxRewards = await getRewards(REWARD_TYPES.AVAX, allMarkets); + + const qiBorrowRewards = await getRewards(REWARD_TYPES.QI, allMarkets, true); + const avaxBorrowRewards = await getRewards( + REWARD_TYPES.AVAX, + allMarkets, + true + ); + const supplyRatePerTimestamp = await multiCallMarkets( + allMarkets, + 'supplyRatePerTimestamp', + qiErc + ); + + const borrowRatePerTimestamp = await multiCallMarkets( + allMarkets, + 'borrowRatePerTimestamp', + qiErc + ); + + const marketsCash = await multiCallMarkets(allMarkets, 'getCash', qiErc); + const totalBorrows = await multiCallMarkets( + allMarkets, + 'totalBorrows', + qiErc + ); + const totalReserves = await multiCallMarkets( + allMarkets, + 'totalReserves', + qiErc + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + 'underlying', + qiErc + ); + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + qiErc + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + qiErc + ); + + const prices = await getPrices( + underlyingTokens.concat([AVAX.address]).map((token) => 'avax:' + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || AVAX.address; + const decimals = Number(underlyingDecimals[i]) || AVAX.decimals; + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + prices[token.toLowerCase()]; + + const totalBorrowUsd = + (Number(totalBorrows[i]) / 10 ** decimals) * prices[token.toLowerCase()]; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRatePerTimestamp[i]); + const apyBaseBorrow = calculateApy(borrowRatePerTimestamp[i]); + + const qiApy = + (((qiRewards[i] / 10 ** QI.decimals) * + SECONDS_PER_DAY * + 365 * + prices[QI.address]) / + totalSupplyUsd) * + 100; + const avaxApy = + (((avaxRewards[i] / 10 ** AVAX.decimals) * + SECONDS_PER_DAY * + 365 * + prices[AVAX.address]) / + totalSupplyUsd) * + 100; + + const qiBorrowApy = + (((qiBorrowRewards[i] / 10 ** QI.decimals) * + SECONDS_PER_DAY * + 365 * + prices[QI.address]) / + totalBorrowUsd) * + 100; + const avaxBorrowApy = + (((avaxBorrowRewards[i] / 10 ** AVAX.decimals) * + SECONDS_PER_DAY * + 365 * + prices[AVAX.address]) / + totalBorrowUsd) * + 100; + + const apyRewardBorrow = qiBorrowApy + avaxBorrowApy; + + return { + pool: market, + chain: utils.formatChain('avalanche'), + project: 'benqi-lending', + symbol: underlyingSymbols[i] || AVAX.symbol, + tvlUsd, + apyBase, + apyReward: qiApy + avaxApy, + underlyingTokens: [token], + rewardTokens: [ + qiApy ? QI.address : null, + avaxApy ? AVAX.address : null, + ].filter(Boolean), + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: Number.isFinite(apyRewardBorrow) ? apyRewardBorrow : 0, + ltv: marketsInfo[i].collateralFactorMantissa / 10 ** 18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.benqi.fi/markets', +}; diff --git a/src/adaptors/benqi-staked-avax/index.js b/src/adaptors/benqi-staked-avax/index.js new file mode 100644 index 0000000000..856d3182cf --- /dev/null +++ b/src/adaptors/benqi-staked-avax/index.js @@ -0,0 +1,82 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const SAVAX_ADDRESS = '0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE'; +const AVAX_ADDRESS = '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7'; + +const abi = { + totalPooledAvax: { + inputs: [], + name: 'totalPooledAvax', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; + +const getAvaxPrice = async () => { + const pricesResponse = await superagent.get( + `https://coins.llama.fi/prices/current/avax:${AVAX_ADDRESS.toLowerCase()}` + ); + return pricesResponse.body.coins[`avax:${AVAX_ADDRESS.toLowerCase()}`].price; +}; + +const fetchTotalPooledAvax = async () => { + const { output } = await sdk.api.abi.call({ + target: SAVAX_ADDRESS, + chain: 'avax', + abi: abi.totalPooledAvax, + }); + return output; +}; + +const fetchStakingApr = async () => { + const aprResponse = await superagent.get( + 'https://api.benqi.fi/liquidstaking/apr' + ); + return Number(aprResponse.body.apr); +}; + +const convertAprToApy = (apr) => { + return Math.pow(1 + apr / 26, 26) - 1; +}; + +const calculateTvl = (totalPooledAvax, avaxPrice) => { + return (totalPooledAvax / 1e18) * avaxPrice; +}; + +const main = async () => { + try { + const [totalPooledAvax, avaxPrice, stakingApr] = await Promise.all([ + fetchTotalPooledAvax(), + getAvaxPrice(), + fetchStakingApr(), + ]); + + const tvlUsd = calculateTvl(totalPooledAvax, avaxPrice); + const apy = convertAprToApy(stakingApr); + + return [ + { + pool: SAVAX_ADDRESS, + chain: utils.formatChain('avalanche'), + project: 'benqi-staked-avax', + symbol: 'sAVAX', + tvlUsd, + apyBase: apy * 100, + underlyingTokens: [AVAX_ADDRESS], + poolMeta: 'Unstaking Cooldown: 15days', + }, + ]; + } catch (error) { + console.error('Error fetching data:', error.message); + throw new Error(`Failed to fetch data: ${error.message}`); + } +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://staking.benqi.fi/stake', +}; diff --git a/src/adaptors/beraborrow/abi.js b/src/adaptors/beraborrow/abi.js new file mode 100644 index 0000000000..e6b9290f05 --- /dev/null +++ b/src/adaptors/beraborrow/abi.js @@ -0,0 +1,14 @@ +module.exports = { + balanceOf: 'erc20:balanceOf', + totalSupply: 'erc20:totalSupply', + totalAssets: 'function totalAssets() public view returns (uint256)', + totalCollateral: 'function totalCollateral() public view returns (uint256)', + totalDebt: 'function totalDebt() public view returns (uint256)', + getStETH: 'function getStETHByWstETH(uint256) public view returns (uint256)', + usdcBalance: 'function usdcBalance() public view returns (uint256)', + slippage: 'function slippageTolerance() public view returns (uint256)', + ethToUsdc: 'function ethToUsdc(uint256) public view returns (uint256)', + lqtyGain: + 'function getDepositorLQTYGain(address) public view returns (uint256)', + rewardRate: 'function rewardRate() public view returns (uint256)', +}; diff --git a/src/adaptors/beraborrow/index.js b/src/adaptors/beraborrow/index.js new file mode 100644 index 0000000000..1f0b47ca30 --- /dev/null +++ b/src/adaptors/beraborrow/index.js @@ -0,0 +1,165 @@ +const { ethers } = require('ethers'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi'); +const BigNumber = require('bignumber.js'); +const superagent = require('superagent'); + +const BB_SNECT = '0x1d22592F66Fc92e0a64eE9300eAeca548cd466c5'; +const NECT = '0x1ce0a25d13ce4d52071ae7e02cf1f6606f4c79d3'; + +const chain = 'berachain'; + +const DECIMALS = new BigNumber((1e18).toString()); + +const COINS = [BB_SNECT, NECT]; + +const vaultMeta = { + [BB_SNECT]: { + asset: NECT, + symbol: 'BB.sNECT', + name: 'BB.sNECT Vault', + }, +}; + +const apy = async () => { + const prices = await getPrices(COINS); + const strategyApys = await Promise.all( + [BB_SNECT].map((vault) => calcErc4626PoolApy(vault, prices)) + ); + return strategyApys; +}; + +async function getPrices(addresses) { + const coins = getCoinsURI(addresses); + const url = `https://coins.llama.fi/prices/current/${coins}`; + return await fetchPrices(url); +} + +async function getPricesDaysBefore(addresses, days) { + const coins = getCoinsURI(addresses); + const timestamp = getTimestampDaysBefore(days); + const url = `https://coins.llama.fi/prices/historical/${timestamp}/${coins}`; + return await fetchPrices(url); +} + +async function fetchPrices(url) { + const prices = (await superagent.get(url)).body.coins; + const pricesByAddresses = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + return pricesByAddresses; +} + +function getCoinsURI(addresses) { + return `${addresses.map((address) => `${chain}:${address}`)}`; +} + +async function getBlockNumberDaysBefore(days) { + const daysBefore = getTimestampDaysBefore(days); + return await getBlockNumber(daysBefore); +} + +function getTimestampDaysBefore(days) { + return Math.floor(Date.now() / 1000) - 24 * 60 * 60 * days; +} + +async function getBlockNumber(timestamp) { + const response = await superagent.get( + `https://coins.llama.fi/block/berachain/${timestamp}` + ); + return response.body.height; +} + +async function calcErc4626PoolApy(vault, prices) { + const tvlUsd = await calcTvl(vault, prices); + + const sharePriceNow = await calcSharePrice(vault, prices); + + const sharePriceYesterday = await calcSharePrice(vault, prices, 1); + const apyBase = calcApy(sharePriceNow, sharePriceYesterday, 1); + + const sharePriceWeekBefore = await calcSharePrice(vault, prices, 7); + const apyBase7d = calcApy(sharePriceNow, sharePriceWeekBefore, 7); + + return { + pool: `${vault}-${chain}`, + chain, + project: 'beraborrow', + symbol: vaultMeta[vault].symbol, + tvlUsd, + underlyingTokens: [vaultMeta[vault].asset], + rewardTokens: [], + apyBase, + apyBase7d, + apyReward: 0, + poolMeta: vaultMeta[vault].name, + url: 'https://app.beraborrow.com/vault', + }; +} + +async function calcTvl(vault, prices) { + const asset = vaultMeta[vault].asset; + const price = prices[asset.toLowerCase()]; + const assets = await totalAssets(vault); + const tvlUsd = assets.multipliedBy(price).div(DECIMALS); + return tvlUsd.toNumber(); +} + +async function calcSharePrice(vault, prices, days = 0) { + let assetPrices = prices; + let block = 'latest'; + if (days > 0) { + assetPrices = await getPricesDaysBefore(COINS, days); + block = await getBlockNumberDaysBefore(days); + } + const assets = await calcAssets(vault, assetPrices, block); + const shares = await getShares(vault, block); + const sharePrice = getSharePrice(assets, shares); + return sharePrice; +} + +async function calcAssets(vault, prices, block = 'latest') { + const assets = await totalAssets(vault, block); + return assets; +} + +const totalAssets = async (vault, block = 'latest') => { + return new BigNumber(await callAbi(vault, abi.totalAssets, null, block)); +}; + +function calcApy(sharePriceNow, sharePriceBefore, daysBetween) { + return sharePriceBefore.isZero() + ? 0 + : sharePriceNow + .minus(sharePriceBefore) + .multipliedBy(36500) + .div(daysBetween) + .div(sharePriceBefore) + .toNumber(); +} + +async function getShares(vault, block = 'latest') { + return new BigNumber(await totalSupply(vault, block)); +} + +async function getSharePrice(assets, shares) { + return shares.isZero() ? new BigNumber(0) : assets.div(shares); +} + +async function callAbi(target, abi, params, block = 'latest') { + return (await sdk.api.abi.call({ target, abi, params, block, chain })).output; +} + +const totalSupply = async (token, block = 'latest') => { + return await callAbi(token, abi.totalSupply, null, block); +}; + +module.exports = { + timetravel: true, + apy, + url: 'https://beraborrow.com', +}; diff --git a/src/adaptors/berancia/abis.ts b/src/adaptors/berancia/abis.ts new file mode 100644 index 0000000000..2d15f2325a --- /dev/null +++ b/src/adaptors/berancia/abis.ts @@ -0,0 +1,20 @@ +const erc20Abi = [ + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [ + { + name: '', + type: 'string', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { + erc20Abi, +}; diff --git a/src/adaptors/berancia/index.ts b/src/adaptors/berancia/index.ts new file mode 100644 index 0000000000..9fe6c0c28d --- /dev/null +++ b/src/adaptors/berancia/index.ts @@ -0,0 +1,184 @@ +const utils = require('../utils'); + +const CONFIG = { + chain: utils.formatChain('berachain'), + project: 'berancia', + apiUrl: 'https://app.berancia.io/api/vault-stats', + appUrl: 'https://app.berancia.io/', + rpcUrl: 'https://rpc.berachain.com', + poolMeta: 'BGT Maximizer', + poolMetaLeveraged: 'BGT Maximizer Leveraged', + fetchConfig: { + timeout: 30000, // 30 seconds + retries: 3, + retryDelay: 1000, // 1 second + }, +}; + +interface Pool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; +} + +interface BeranciaResponse { + vaults: { + address: string; + symbol: string; + apy: { + base: string; + leveraged: string | null; + multiplier: number | null; + }; + tvl: { + total: string | null; + base: string | null; + }; + tokenSymbols: string[]; + }[]; +} + +const fetchWithTimeout = async ( + url: string, + timeoutMs: number +): Promise => { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeoutMs); + + try { + const response = await fetch(url, { signal: controller.signal }); + clearTimeout(timeoutId); + return response; + } catch (error) { + clearTimeout(timeoutId); + if (error.name === 'AbortError') { + throw new Error(`Fetch timeout after ${timeoutMs}ms`); + } + throw error; + } +}; + +const fetchWithRetry = async ( + url: string, + config = CONFIG.fetchConfig +): Promise => { + let lastError: Error; + + for (let attempt = 0; attempt < config.retries; attempt++) { + try { + const response = await fetchWithTimeout(url, config.timeout); + + if (!response.ok) { + throw new Error( + `HTTP error! status: ${response.status} - ${response.statusText}` + ); + } + + return response; + } catch (error) { + lastError = error; + + if (attempt < config.retries - 1) { + await new Promise((resolve) => setTimeout(resolve, config.retryDelay)); + } + } + } + + throw lastError; +}; + +const validateBeranciaResponse = (data: unknown): data is BeranciaResponse => { + return ( + data !== null && + typeof data === 'object' && + 'vaults' in data && + Array.isArray((data as any).vaults) + ); +}; + +const parseJsonResponse = async ( + response: Response, + validator: (data: unknown) => data is T, + errorMessage: string = 'Invalid response structure' +): Promise => { + try { + const data: unknown = await response.json(); + + if (!validator(data)) { + throw new Error(errorMessage); + } + + return data; + } catch (error) { + throw new Error(`Failed to parse JSON response: ${error.message}`); + } +}; + +const safeParseNumber = (value: string | null | undefined): number => { + if (value === null || value === undefined || value === '') { + return 0; + } + + const parsed = Number(value); + return isNaN(parsed) ? 0 : parsed; +}; + +const truncateToTwoDecimals = (value: number): number => { + return Math.floor(value * 100) / 100; +}; + +const parseAndFormatNumeric = (value: string | null | undefined): number => { + const parsed = safeParseNumber(value); + return truncateToTwoDecimals(parsed); +}; + +const transformVaultToPool = ( + vault: BeranciaResponse['vaults'][0], + commonData: { chain: string; project: string } +): Pool => { + const isLeveraged = + vault.apy.leveraged !== null && + vault.apy.leveraged !== undefined && + vault.apy.leveraged !== ''; + const apyValue = isLeveraged ? vault.apy.leveraged : vault.apy.base; + + return { + ...commonData, + pool: vault.address, + tvlUsd: parseAndFormatNumeric(vault.tvl.total), + apyBase: parseAndFormatNumeric(apyValue), + symbol: vault.tokenSymbols.join('-'), + poolMeta: isLeveraged ? CONFIG.poolMetaLeveraged : CONFIG.poolMeta, + }; +}; + +const getPools = async (): Promise => { + const response = await fetchWithRetry(CONFIG.apiUrl); + const data = await parseJsonResponse( + response, + validateBeranciaResponse, + 'Invalid response structure: missing vaults array' + ); + + const commonData = { chain: CONFIG.chain, project: CONFIG.project }; + + const pools = data.vaults.map((vault) => + transformVaultToPool(vault, commonData) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: CONFIG.appUrl, +}; diff --git a/src/adaptors/berapaw/index.js b/src/adaptors/berapaw/index.js new file mode 100644 index 0000000000..35514b1ceb --- /dev/null +++ b/src/adaptors/berapaw/index.js @@ -0,0 +1,248 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const SECONDS_PER_YEAR = 31557600; // 365.25 days per year + +// Contract addresses +const ADDRESSES = { + WBERA: '0x6969696969696969696969696969696969696969', + LBGT: '0xBaadCC2962417C01Af99fb2B7C75706B9bd6Babe', + PPAW: '0x03c86e21623f25Eca0eA544890c7603B9a33E1AC', + WBERA_LBGT_WEIGHTED: '0x705Fc16BA5A1EB67051934F2Fb17EacaE660F6c7', + WBERA_LBGT_WEIGHTED_POOL_ID: '0x705fc16ba5a1eb67051934f2fb17eacae660f6c70002000000000000000000d5', + REWARD_COLLECTOR: '0x3ea91AE9e47EdBC43e64C6DDF99D67207296eC28', + LBGT_WBERA_STAKING: '0xa77dee7bc36c463bB3E39804c9C7b13427D712B0', + LBGT_WBERA_LBGT_STAKING: '0xF0422bC37f1d2D1B57596cCA5A64E30c71D10170', + HUB_VAULT: '0x4Be03f781C497A489E3cB0287833452cA9B9E80B', + ST_LBGT_VAULT: '0xFace73a169e2CA2934036C8Af9f464b5De9eF0ca' +}; + +// Helper functions +const callContract = async (target, abi, params = []) => { + return sdk.api.abi.call({ + target, + abi, + params, + chain: 'berachain', + }).then(res => res.output); +}; + +const getTokenPrice = async (tokenAddress) => { + const priceData = (await utils.getPrices([tokenAddress], 'berachain')).pricesByAddress; + return priceData[String(tokenAddress).toLowerCase()] || 0; +}; + +const getRewardRate = async (address) => { + return callContract(address, 'uint256:rewardRate'); +}; + +const getTotalAssets = async (vaultAddress) => { + return callContract(vaultAddress, 'uint256:totalAssets'); +}; + +const getTotalSupply = async (address) => { + return callContract(address, 'uint256:totalSupply'); +}; + +const getActualSupply = async (address) => { + return callContract(address, 'uint256:getActualSupply'); +}; + +const getPoolTokens = async () => { + return callContract(ADDRESSES.HUB_VAULT, 'function getPoolTokens(bytes32 poolId) view returns (address[] tokens, uint256[] balances, uint256 lastChangeBlock)', [ADDRESSES.WBERA_LBGT_WEIGHTED_POOL_ID]); +}; + +// TVL and APR calculations +const getStLbgtTvlUsd = async () => { + const deposits = await getTotalAssets(ADDRESSES.ST_LBGT_VAULT); + const uTokenAddress = await callContract(ADDRESSES.ST_LBGT_VAULT, 'address:asset'); + const price = await getTokenPrice(uTokenAddress); + return (deposits / 1e18) * price; +}; + +const getStLbgtApr = async () => { + const rewardRate = await getRewardRate(ADDRESSES.REWARD_COLLECTOR); + const poolAssets = await getTotalAssets(ADDRESSES.ST_LBGT_VAULT); + const rewardRatePerYear = (rewardRate * SECONDS_PER_YEAR) / 1e18; + return (rewardRatePerYear / poolAssets) * 100; +}; + +const getLpTvlUsd = async (vaultAddress, uTokenAddress) => { + const [vaultSupply, totalSupply, poolData] = await Promise.all([ + getTotalSupply(vaultAddress), + getActualSupply(uTokenAddress), + getPoolTokens() + ]); + + const tokenPrices = await Promise.all( + poolData.tokens.map(token => getTokenPrice(token)) + ); + + const totalPoolValue = poolData.balances.reduce((acc, balance, i) => { + const tokenValue = (Number(balance) / 1e18) * tokenPrices[i]; + return acc + tokenValue; + }, 0); + + return Number(vaultSupply) === 0 ? 0 : (Number(vaultSupply) / Number(totalSupply)) * totalPoolValue; +}; + +const calculateApr = async (stakingTvlUsd, rewardTokenAddress, stakingAddress) => { + const [price, rewardRate] = await Promise.all([ + getTokenPrice(rewardTokenAddress), + getRewardRate(stakingAddress) + ]); + + if (!price) return 0; + + const rewardRatePerYear = (rewardRate * SECONDS_PER_YEAR) / (1e18 * 1e18); // additional 1e18 to account for rewardRate precision + return (rewardRatePerYear * price) / stakingTvlUsd * 100; +}; + +const getLpApr = async (stakingTvlUsd) => { + const [aprPpaw, aprLbgt] = await Promise.all([ + calculateApr(stakingTvlUsd, ADDRESSES.PPAW, ADDRESSES.LBGT_WBERA_STAKING), + calculateApr(stakingTvlUsd, ADDRESSES.LBGT, ADDRESSES.LBGT_WBERA_LBGT_STAKING) + ]); + return aprPpaw + aprLbgt; +}; + +const getVaultsFromApi = async () => { + const query = { + operationName: "GetVaults", + variables: { + orderBy: "apr", + orderDirection: "desc", + pageSize: 300, + where: { + includeNonWhitelisted: false, + }, + }, + query: `query GetVaults($where: GqlRewardVaultFilter, $pageSize: Int, $skip: Int, $orderBy: GqlRewardVaultOrderBy = bgtCapturePercentage, $orderDirection: GqlRewardVaultOrderDirection = desc, $search: String) { + polGetRewardVaults( + where: $where + first: $pageSize + skip: $skip + orderBy: $orderBy + orderDirection: $orderDirection + search: $search + ) { + vaults { + id: vaultAddress + vaultAddress + address: vaultAddress + isVaultWhitelisted + dynamicData { + allTimeReceivedBGTAmount + apr + tvl + bgtCapturePercentage + activeIncentivesValueUsd + activeIncentivesRateUsd + } + stakingToken { + address + name + symbol + decimals + } + metadata { + name + logoURI + url + protocolName + description + } + activeIncentives { + active + remainingAmount + remainingAmountUsd + incentiveRate + tokenAddress + token { + address + name + symbol + decimals + } + } + } + } + }` + }; + + const response = await utils.getData('https://api.berachain.com/', query); + return response.data.polGetRewardVaults.vaults; +}; + +const getPoolData = async () => { + const [stLbgtTvl, lpLbgtWberaTvl, apiVaults, lbgtPrice, beraPrice] = await Promise.all([ + getStLbgtTvlUsd(), + getLpTvlUsd(ADDRESSES.LBGT_WBERA_STAKING, ADDRESSES.WBERA_LBGT_WEIGHTED), + getVaultsFromApi(), + getTokenPrice(ADDRESSES.LBGT), + getTokenPrice(ADDRESSES.WBERA), + ]); + + const pools = []; + + // Add stLbgt staking + pools.push({ + pool: ADDRESSES.ST_LBGT_VAULT, + chain: 'berachain', + project: 'berapaw', + symbol: 'LBGT', + tvlUsd: stLbgtTvl, + apyReward: utils.aprToApy(await getStLbgtApr(), 365 * 24 * 60 / 5), // compounding every 5 minutes + rewardTokens: [ADDRESSES.LBGT], + underlyingTokens: [ADDRESSES.LBGT], + }); + + // Add lp_lbgt_wbera staking + pools.push({ + pool: ADDRESSES.LBGT_WBERA_STAKING, + chain: 'berachain', + project: 'berapaw', + symbol: '50WBERA-50LBGT-WEIGHTED', + tvlUsd: lpLbgtWberaTvl, + apyReward: await getLpApr(lpLbgtWberaTvl), + rewardTokens: [ADDRESSES.LBGT, ADDRESSES.PPAW], + underlyingTokens: [ADDRESSES.WBERA_LBGT_WEIGHTED], + }); + + // Add vaults + for (const vault of apiVaults) { + if (!vault.isVaultWhitelisted) continue; + + // Calculate BGT APR + let bgtApr = 0; + if (vault.dynamicData?.apr) { + bgtApr = parseFloat(vault.dynamicData.apr) * 100; + } + + // Calculate LBGT APR using formula: lbgtApr = bgtApr × (lbgtPrice / beraPrice) + let lbgtApr = bgtApr; + if (beraPrice && lbgtPrice) { + lbgtApr = bgtApr * (lbgtPrice / beraPrice); + } + + pools.push({ + pool: vault.vaultAddress, + chain: 'berachain', + project: 'berapaw', + symbol: vault.stakingToken.symbol, + tvlUsd: parseFloat(vault.dynamicData.tvl), + apyReward: lbgtApr, + rewardTokens: [ADDRESSES.LBGT], + underlyingTokens: [vault.stakingToken.address], + url: 'https://www.berapaw.com/vaults', + }); + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPoolData, + url: 'https://www.berapaw.com/stake', +}; diff --git a/src/adaptors/betswirl/abi.json b/src/adaptors/betswirl/abi.json new file mode 100644 index 0000000000..310af29ee9 --- /dev/null +++ b/src/adaptors/betswirl/abi.json @@ -0,0 +1,128 @@ +[ + { + "inputs": [], + "name": "getInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "__totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct SingleStaking.Token", + "name": "_stakingToken", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct SingleStaking.Token", + "name": "token", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardsDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + } + ], + "internalType": "struct SingleStaking.Reward", + "name": "rewardData", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "lastTimeRewardApplicable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardForDuration", + "type": "uint256" + } + ], + "internalType": "struct SingleStaking.RewardToken[]", + "name": "_rewardTokens", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/betswirl/index.js b/src/adaptors/betswirl/index.js new file mode 100644 index 0000000000..3ee5bb084c --- /dev/null +++ b/src/adaptors/betswirl/index.js @@ -0,0 +1,71 @@ +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); +const utils = require('../utils'); +const ABI = require('./abi'); +const { default: BigNumber } = require('bignumber.js'); + +const gammaMerklesOpportunities = [ + { + id: '646147034480640434' + }, +]; + +const getApy = async () => { + return ( + await Promise.all( + gammaMerklesOpportunities + .map(async (gammaMerkleOpportunity) => { + try { + const merkleData = await utils.getData(`https://api.merkl.xyz/v4/opportunities/${gammaMerkleOpportunity.id}`); + const chainId = merkleData.chain.id; + const chainName = merkleData.chain.name.toLowerCase(); + const tvlUsd = merkleData.tvl; + const apr = merkleData.apr; + const rewardTokenAddress = + merkleData.rewardsRecord.breakdowns[0].token.address; + const identifier = merkleData.identifier; + const stakedTokenSymbol = merkleData.tokens[0].symbol; + const url = merkleData.depositUrl; + + const token0Address = ( + await sdk.api.abi.call({ + target: identifier, + abi: 'address:token0', + chain: chainName, + }) + ).output; + + const token1Address = ( + await sdk.api.abi.call({ + target: identifier, + abi: 'address:token1', + chain: chainName, + }) + ).output; + + + return { + pool: `${identifier}-${chainName}`.toLowerCase(), + chain: utils.formatChain(chainName), + project: 'betswirl', + symbol: utils.formatSymbol(stakedTokenSymbol), + tvlUsd: tvlUsd, + apy: apr, + rewardTokens: [rewardTokenAddress], + underlyingTokens: [token0Address, token1Address], + poolMeta: `Gamma vault ${stakedTokenSymbol}`, + url: url + }; + } catch (error) { + console.error(`Error processing opportunity ${gammaMerkleOpportunity.id}:`, error); + return null; + } + }) + ) + ).filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: getApy +}; diff --git a/src/adaptors/bex/index.ts b/src/adaptors/bex/index.ts new file mode 100644 index 0000000000..4405664436 --- /dev/null +++ b/src/adaptors/bex/index.ts @@ -0,0 +1,88 @@ +const { request, gql } = require('graphql-request'); + +const BEX_API_URL = 'https://api.berachain.com'; +const BEX_URL = 'https://hub.berachain.com'; +const CHAIN = 'Berachain'; +const PROJECT = 'bex'; +const BGT_ADDRESS = '0x656b95E550C07a9ffe548bd4085c72418Ceb1dba'; + +async function getPoolData() { + const allPools = await getPools(); + + const filteredPools = await filterPools(allPools); + + const pools = []; + for (const pool of filteredPools.poolGetPools) { + const poolData = { + pool: `${pool.address}-${CHAIN}`, + chain: CHAIN, + project: PROJECT, + symbol: pool.name.replace(' | ', '-'), + tvlUsd: Number(pool.dynamicData.totalLiquidity), + apyBase: pool.dynamicData.aprItems[0]?.apr + ? Number(pool.dynamicData.aprItems[0].apr) * 100 + : null, + apyReward: Number(pool.rewardVault?.dynamicData.apr) * 100, + rewardTokens: [BGT_ADDRESS], + underlyingTokens: [ + pool.address, + ...pool.displayTokens.map((token) => token.address), + ], + url: `${BEX_URL}/pools/${pool.id}/details/`, + poolMeta: pool.symbol.split('-').pop() || '', + }; + pools.push(poolData); + } + return pools; +} + +async function filterPools(pools) { + // const poolMustHaveApr = (pool) => pool.dynamicData.aprItems.length > 0; + const poolMustHaveRewardVault = (pool) => pool.rewardVault !== null; + + return { + poolGetPools: pools.poolGetPools + // .filter(poolMustHaveApr) + .filter(poolMustHaveRewardVault), + }; +} + +async function getPools() { + const query = gql` + query GetPoolData { + poolGetPools( + orderBy: totalLiquidity + orderDirection: desc + where: { minTvl: 10000 } + ) { + id + address + chain + name + symbol + chain + displayTokens { + address + } + rewardVault { + dynamicData { + apr + } + } + dynamicData { + aprItems { + apr + } + totalLiquidity + } + } + } + `; + return await request(BEX_API_URL, query); +} + +module.exports = { + timetravel: false, + apy: getPoolData, + url: 'https://hub.berachain.com/pools/', +}; diff --git a/src/adaptors/bfx-(blast-futures)/index.js b/src/adaptors/bfx-(blast-futures)/index.js new file mode 100644 index 0000000000..8be782b4ab --- /dev/null +++ b/src/adaptors/bfx-(blast-futures)/index.js @@ -0,0 +1,46 @@ +const utils = require('../utils'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const CHAIN = 'blast'; +const USDB = '0x4300000000000000000000000000000000000003'; +const API_URL = 'https://api.bfx.trade/vaults'; + +const getApy = async () => { + let pools = []; + + const response = await axios.get(API_URL, { + headers: { eid: 'bfx' }, + }); + pools = response.data.result; + + const tvl = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: USDB, + params: '0x3Ba925fdeAe6B46d0BB4d424D829982Cb2F7309e', + chain: 'blast', + }) + ).output; + + const tvlValue = Number(tvl) / 1e18; + + return pools.map((p) => ({ + chain: utils.formatChain(CHAIN), + project: 'bfx-(blast-futures)', + pool: 'Dynamic AMM LP', + symbol: 'USDB', + tvlUsd: tvlValue * Number(p.share_price), + apyBase: Number(p.apy) * 100, + // apyReward: Number('0.15') * 100, + // rewardTokens: [USDB], + poolMeta: `Dynamic Market Maker`, + url: `https://bfx.trade/vaults/platformOverview?vault_wallet=0x2688c2bb0eeea0cd10de520699090a36469d788a`, + })); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://bfx.trade/vaults', +}; diff --git a/src/adaptors/bifi/index.js b/src/adaptors/bifi/index.js new file mode 100644 index 0000000000..e206ad4c72 --- /dev/null +++ b/src/adaptors/bifi/index.js @@ -0,0 +1,37 @@ +const axios = require('axios'); + +const url = 'https://biholder-view.thebifrost.io/chains/bfc/bifi'; + +const apy = async () => { + const [markets, handlers] = await Promise.all( + ['bifi-market', 'handlers'].map((i) => axios.get(`${url}/${i}`)) + ); + + return markets.data.map((p) => { + const handler = handlers.data.find( + (i) => i.tokenHandlerId === p.token_handler_id + ); + + const totalSupplyUsd = Number(p.deposit_value); + const totalBorrowUsd = Number(p.borrow_value); + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + return { + pool: handler.handlerAddress, + symbol: handler.tokenSymbol, + chain: 'Bifrost Network', + project: 'bifi', + tvlUsd, + apyBase: Number(p.deposit_apy), + apyBaseBorrow: Number(p.borrow_apy), + totalSupplyUsd, + totalBorrowUsd, + underlyingTokens: [handler.tokenAddress], + }; + }); +}; + +module.exports = { + apy, + url: 'https://crosschain.bifi.finance/', +}; diff --git a/src/adaptors/bifrost-liquid-staking/index.js b/src/adaptors/bifrost-liquid-staking/index.js new file mode 100644 index 0000000000..8b8e427e39 --- /dev/null +++ b/src/adaptors/bifrost-liquid-staking/index.js @@ -0,0 +1,127 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require("bignumber.js") +const utils = require('../utils'); + +const veth = '0x4bc3263eb5bb2ef7ad9ab6fb68be80e43b43801f'; +const veth_1='0xc3d088842dcf02c13699f936bb83dfbbc6f721ab' + +const getApy = async () => { + const contract_veth = (await sdk.api.erc20.totalSupply({ target: veth })).output / 1e18; + const contract_veth1 = (await sdk.api.erc20.totalSupply({ target: veth_1 })).output / 1e18; + const contract_veth1_null_address_balance = (await sdk.api.erc20.balanceOf({ owner:'0x000000000000000000000000000000000000dEaD',target: veth_1, })).output / 1e18; + + const vToken = await utils.getData('https://api.bifrost.app/api/site'); + + const priceKeys = [ + 'ethereum', + 'filecoin', + 'polkadot', + 'kusama', + 'bifrost-native-coin', + 'moonbeam', + 'moonriver', + 'astar' + ] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const vDOT = { + pool: 'polkadot-vdot', + chain: 'Polkadot', + project: 'bifrost-liquid-staking', + symbol: 'vDOT', + tvlUsd: vToken.vDOT.tvm * prices['coingecko:polkadot'].price, + apyBase: Number(vToken.vDOT.apyBase), + apyReward: Number(vToken.vDOT.apyReward), + rewardTokens: ['DOT'], + }; + + const vGLMR = { + pool: 'moonbeam-vglmr', + chain: 'Moonbeam', + project: 'bifrost-liquid-staking', + symbol: 'vGLMR', + tvlUsd: vToken.vGLMR.tvm * prices['coingecko:moonbeam'].price, + apyBase: Number(vToken.vGLMR.apyBase), + apyReward: Number(vToken.vGLMR.apyReward), + rewardTokens: ['GLMR'], + }; + + const vFIL = { + pool: 'filecoin-vfil', + chain: 'Filecoin', + project: 'bifrost-liquid-staking', + symbol: 'vFIL', + tvlUsd: vToken.vFIL.tvm * prices['coingecko:filecoin'].price, + apyBase: Number(vToken.vFIL.apyBase), + apyReward: Number(vToken.vFIL.apyReward), + rewardTokens: ['FIL'], + }; + + const vASTR = { + pool: 'astar-vstr', + chain: 'Astar', + project: 'bifrost-liquid-staking', + symbol: 'vASTR', + tvlUsd: vToken.vASTR.tvm * prices['coingecko:astar'].price, + apyBase: Number(vToken.vASTR.apyBase), + apyReward: Number(vToken.vASTR.apyReward), + rewardTokens: ['ASTR'], + }; + + const vMOVR = { + pool: 'moonriver-vmovr', + chain: 'Moonriver', + project: 'bifrost-liquid-staking', + symbol: 'vMOVR', + tvlUsd: vToken.vMOVR.tvm * prices['coingecko:moonriver'].price, + apyBase: Number(vToken.vMOVR.apyBase), + apyReward: Number(vToken.vMOVR.apyReward), + rewardTokens: ['MOVR'], + }; + + const vBNC = { + pool: 'bifrost-vbnc', + chain: 'Bifrost', + project: 'bifrost-liquid-staking', + symbol: 'vBNC', + tvlUsd: vToken.vBNC.tvm * prices['coingecko:bifrost-native-coin'].price, + apyBase: Number(vToken.vBNC.apyBase), + apyReward: Number(vToken.vBNC.apyReward), + rewardTokens: ['BNC'], + }; + + const vKSM = { + pool: 'kusama-vksm', + chain: 'Kusama', + project: 'bifrost-liquid-staking', + symbol: 'vKSM', + tvlUsd: vToken.vKSM.tvm * prices['coingecko:kusama'].price, + apyBase: Number(vToken.vKSM.apyBase), + apyReward: Number(vToken.vKSM.apyReward), + rewardTokens: ['KSM'], + }; + + const vETH = { + pool: veth, + chain: 'ethereum', + project: 'bifrost-liquid-staking', + symbol: 'veth', + tvlUsd: new BigNumber(contract_veth).plus(contract_veth1).minus(contract_veth1_null_address_balance).toNumber() * prices['coingecko:ethereum'].price, + apyBase: vToken.vETH2.apyBase, + apyReward:vToken.vETH2.apyReward, + underlyingTokens: [veth], + rewardTokens: ['ETH'], + }; + + return [vETH, vDOT, vGLMR, vMOVR, vKSM, vBNC, vFIL, vASTR]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://bifrost.app/vstaking', +}; diff --git a/src/adaptors/binance-staked-eth/index.js b/src/adaptors/binance-staked-eth/index.js new file mode 100644 index 0000000000..cc21de7789 --- /dev/null +++ b/src/adaptors/binance-staked-eth/index.js @@ -0,0 +1,59 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const wbeth = '0xa2E3356610840701BDf5611a53974510Ae27E2e1'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const project = 'binance-staked-eth'; +const symbol = 'wbeth'; + +const apy = async () => { + const tvlEthereum = + (await sdk.api.erc20.totalSupply({ target: wbeth })).output / 1e18; + + const tvlBsc = + (await sdk.api.erc20.totalSupply({ target: wbeth, chain: 'bsc' })).output / + 1e18; + + const wbethExchangeRateRaw = await sdk.api.abi.call({ + target: wbeth, + abi: 'uint256:exchangeRate', + chain: 'ethereum', + }); + + const wbethExchangeRate = wbethExchangeRateRaw.output / 1e18; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const apr = + ( + await axios.get( + 'https://www.binance.com/bapi/earn/v1/public/pos/cftoken/project/getPurchasableProject' + ) + ).data.data.annualInterestRate * 100; + + return [ + { + pool: `${wbeth}-ethereum`, + chain: 'ethereum', + project, + symbol, + underlyingTokens: [weth], + apyBase: apr, + tvlUsd: tvlEthereum * ethPrice * wbethExchangeRate, + }, + { + pool: `${wbeth}-bsc`, + chain: 'bsc', + project, + symbol, + underlyingTokens: [weth], + apyBase: apr, + tvlUsd: tvlBsc * ethPrice * wbethExchangeRate, + }, + ]; +}; + +module.exports = { apy, url: 'https://www.binance.com/en/eth2' }; diff --git a/src/adaptors/binance-staked-sol/index.js b/src/adaptors/binance-staked-sol/index.js new file mode 100644 index 0000000000..e3e7c568c0 --- /dev/null +++ b/src/adaptors/binance-staked-sol/index.js @@ -0,0 +1,33 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const BNSOL_ADDRESS = 'BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85'; +const priceKey = `solana:${BNSOL_ADDRESS}`; + +const apy = async () => { + const totalSupply = await getTotalSupply(BNSOL_ADDRESS); + + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const currentPrice = priceResponse.data.coins[priceKey].price; + + const binanceResponse = await axios.get( + 'https://www.binance.com/bapi/earn/v1/friendly/earn/restaking/project/detail' + ); + const apy = binanceResponse.data.data.apy; + + return [ + { + pool: BNSOL_ADDRESS, + chain: 'Solana', + project: 'binance-staked-sol', + symbol: 'BNSOL', + tvlUsd: totalSupply * currentPrice, + apyBase: apy * 100, + underlyingTokens: [BNSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://www.binance.com/en/solana-staking' }; diff --git a/src/adaptors/biswap-v2/abis.js b/src/adaptors/biswap-v2/abis.js new file mode 100644 index 0000000000..8c798de538 --- /dev/null +++ b/src/adaptors/biswap-v2/abis.js @@ -0,0 +1,922 @@ +module.exports = { + masterChefABI: [ + { + inputs: [ + { internalType: 'contract BSWToken', name: '_BSW', type: 'address' }, + { internalType: 'address', name: '_devaddr', type: 'address' }, + { internalType: 'address', name: '_refAddr', type: 'address' }, + { internalType: 'address', name: '_safuaddr', type: 'address' }, + { internalType: 'uint256', name: '_BSWPerBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_startBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_stakingPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_devPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_refPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_safuPercent', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'BONUS_MULTIPLIER', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'BSW', + outputs: [ + { internalType: 'contract BSWToken', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'BSWPerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'contract IBEP20', name: '_lpToken', type: 'address' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositedBsw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'devPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'devaddr', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'enterStaking', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_from', type: 'uint256' }, + { internalType: 'uint256', name: '_to', type: 'uint256' }, + ], + name: 'getMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastBlockDevWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'leaveStaking', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingBSW', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'percentDec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IBEP20', name: 'lpToken', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'accBSWPerShare', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'refAddr', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'refPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'safuPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'safuaddr', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_devaddr', type: 'address' }], + name: 'setDevAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_refaddr', type: 'address' }], + name: 'setRefAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_safuaddr', type: 'address' }], + name: 'setSafuAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stakingPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'startBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newAmount', type: 'uint256' }], + name: 'updateBswPerBlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'multiplierNumber', type: 'uint256' }, + ], + name: 'updateMultiplier', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawDevAndRefFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + lpTokenABI: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'devFee', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint32', name: '_devFee', type: 'uint32' }], + name: 'setDevFee', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint32', name: '_swapFee', type: 'uint32' }], + name: 'setSwapFee', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'swapFee', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/biswap-v2/index.js b/src/adaptors/biswap-v2/index.js new file mode 100644 index 0000000000..608ddc4c3f --- /dev/null +++ b/src/adaptors/biswap-v2/index.js @@ -0,0 +1,196 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { chunk } = require('lodash'); + +const { masterChefABI, lpTokenABI } = require('./abis'); +const utils = require('../utils'); + +const API_URL = sdk.graph.modifyEndpoint( + '2D9rXpMTvAgofWngsyRE17jKr5ywrU4W3Eaa71579qkd' +); + +const MASTERCHEF_ADDRESS = '0xDbc1A13490deeF9c3C12b44FE77b503c1B061739'; +const BSW_TOKEN = '0x965f527d9159dce6288a2219db51fc6eef120dd1'; + +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = Math.floor((60 / BSC_BLOCK_TIME) * 60 * 24 * 365); +const WEEKS_PER_YEAR = 52; +const FEE_RATE = 0.0005; +const CHAIN = 'bsc'; + +const apy = async () => { + const nonLpPools = [0]; + + const poolsCount = ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: CHAIN, + abi: masterChefABI.find((m) => m.name === 'poolLength'), + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: CHAIN, + abi: masterChefABI.find((m) => m.name === 'totalAllocPoint'), + }) + ).output; + + const bswPerBlock = + ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: CHAIN, + abi: masterChefABI.find((m) => m.name === 'BSWPerBlock'), + }) + ).output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter(({ i }) => !nonLpPools.includes(i)); + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const [reservesData, supplyData, masterChefBalData] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + utils.makeMulticall( + lpTokenABI.filter(({ name }) => name === method)[0], + lpTokens, + 'bsc', + method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null + ) + ) + ); + + const [tokens0, tokens1] = await Promise.all( + ['token0', 'token1'].map((method) => + utils.makeMulticall( + lpTokenABI.filter(({ name }) => name === method)[0], + lpTokens, + 'bsc' + ) + ) + ); + + const { pricesByAddress: tokensPrices } = await utils.getPrices( + [...new Set([...tokens0, ...tokens1])], + CHAIN + ); + + const pairsInfo = await utils.uniswap.getPairsInfo(lpTokens, API_URL); + + const lpChunks = chunk(lpTokens, 10); + + const pairVolumes = await Promise.all( + lpChunks.map((lpsChunk) => + request( + API_URL, + gql` + query volumesQuery { + ${lpsChunk + .slice(0, 10) + .map( + (token, i) => `token_${token.toLowerCase()}:pairDayDatas( + orderBy: date + orderDirection: desc + first: 7 + where: { pairAddress: "${token.toLowerCase()}" } + ) { + dailyVolumeUSD + }` + ) + .join('\n')} + + } + ` + ) + ) + ); + + const volumesMap = pairVolumes.flat().reduce( + (acc, curChunk) => ({ + ...acc, + ...Object.entries(curChunk).reduce((innerAcc, [key, val]) => ({ + ...innerAcc, + [key.split('_')[1]]: val, + })), + }), + {} + ); + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairsInfo[pool.lpToken.toLowerCase()]; + + if (!pairInfo) return {}; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = utils.uniswap + .calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo?.token0, + pairInfo?.token1, + tokensPrices + ) + .toString(); + + const lpReservesUsd = utils.uniswap + .calculateReservesUSD( + reserves, + 1, + pairInfo?.token0, + pairInfo?.token1, + tokensPrices + ) + .toString(); + + const lpFees7D = + (volumesMap[pool.lpToken.toLowerCase()] || []).reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * FEE_RATE; + const apyBase = ((lpFees7D * WEEKS_PER_YEAR) / lpReservesUsd) * 100; + + const apyReward = utils.uniswap.calculateApy( + poolInfo, + totalAllocPoint, + bswPerBlock, + tokensPrices[BSW_TOKEN], + masterChefReservesUsd, + BLOCKS_PER_YEAR + ); + + return { + pool: pool.lpToken, + chain: utils.formatChain('binance'), + project: 'biswap-v2', + symbol: pairInfo.name, + tvlUsd: Number(masterChefReservesUsd), + apyBase, + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [BSW_TOKEN], + url: `https://exchange.biswap.org/#/add/${tokens0[i]}/${tokens1[i]}`, + }; + }); + + return res.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/bitu-protocol/index.js b/src/adaptors/bitu-protocol/index.js new file mode 100644 index 0000000000..154e67a2e2 --- /dev/null +++ b/src/adaptors/bitu-protocol/index.js @@ -0,0 +1,47 @@ +const { gql, request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const SUBGRAPH_URL = + 'https://api.studio.thegraph.com/query/70783/bitu-protocol/version/latest'; + +const BITU = '0x654a32542a84bea7d2c2c1a1ed1aaaf26888e6bd'; +const sBITU = '0x61183a27ab5FDaCC4D46F5aF9Eb9E6A93afd76d4'; + +const Query = gql` + query RewardTotal { + rewardTotal(id: "BITU") { + dyr + } + } +`; + +const apy = async () => { + const { + rewardTotal: { dyr }, + } = await request(SUBGRAPH_URL, Query); + + const totalAssets = + ( + await sdk.api.abi.call({ + target: sBITU, + abi: 'uint:totalAssets', + chain: 'bsc', + }) + ).output / 1e18; + + return [ + { + pool: '0x61183a27ab5FDaCC4D46F5aF9Eb9E6A93afd76d4', + project: 'bitu-protocol', + chain: 'bsc', + symbol: 'sBITU', + tvlUsd: totalAssets, + apyBase: (Math.pow(1 + +dyr, 365) - 1) * 100, + }, + ]; +}; + +module.exports = { + apy: apy, + url: 'https://bitu.io', +}; diff --git a/src/adaptors/blastnyan/helper.json b/src/adaptors/blastnyan/helper.json new file mode 100644 index 0000000000..d2ee4c2c1f --- /dev/null +++ b/src/adaptors/blastnyan/helper.json @@ -0,0 +1,63 @@ +[ + { + "inputs": [], + "name": "getBlnyanLpPrice", + "outputs": [ + { "internalType": "uint256", "name": "wethBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "wethValue", "type": "uint256" }, + { "internalType": "uint256", "name": "blnyanBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "blnyanValue", "type": "uint256" }, + { "internalType": "uint256", "name": "supply", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "getBlnyanPrice", + "outputs": [ + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "getEthPrice", + "outputs": [ + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "getPoolInfo", + "outputs": [ + { "internalType": "uint256", "name": "_staked", "type": "uint256" }, + { "internalType": "uint256", "name": "_rewardRate", "type": "uint256" }, + { "internalType": "uint256", "name": "_userStaked", "type": "uint256" }, + { "internalType": "uint256", "name": "_userEarned", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "getTokenPriceUSDC", + "outputs": [ + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/blastnyan/index.js b/src/adaptors/blastnyan/index.js new file mode 100644 index 0000000000..445926cfc4 --- /dev/null +++ b/src/adaptors/blastnyan/index.js @@ -0,0 +1,111 @@ +const utils = require('../utils'); +const { Web3 } = require('web3'); + +const { default: BigNumber } = require('bignumber.js'); +const axios = require('axios'); + +const viewHelperABI = require('./helper.json'); + +const HELPER_ADDRESS = '0xbBB04C9D7065EF7E5ED58EecE34321eA96D37287'; +const TOKEN_ADDRESS = '0x9aAC39ca368D27bf03887CCe32f28b44F466072F'; +const LP_TOKEN_ADDRESS = '0x0E9309f32881899F6D4aC2711c6E21367A84CA26'; +const LP_REWARD_ADDRESS = '0xF63Ef9F4320f9d16731a40ff1f58a966ee086806'; +const STAKING_REWARD_ADDRESS = '0xA76D6dc805d0EbEcb3787c781ce3A18feEF020cb'; +const WETH_ADDRESS = '0x4300000000000000000000000000000000000004'; +const DEPLOYER_ADDRESS = '0x32754478de813A42C9eD6e3e8d00d66c6009b40f'; +const YEAR = 365 * 60 * 60 * 24; + +const web3 = new Web3(new Web3.providers.HttpProvider('https://rpc.blast.io')); + +async function getLPStakingInfo() { + var poolInfo = await helper.methods + .getPoolInfo(LP_REWARD_ADDRESS, DEPLOYER_ADDRESS) + .call(); + + var lpPrice = await helper.methods.getBlnyanLpPrice().call(); + + var tokenValue = + (Number(lpPrice.wethBalance) * Number(lpPrice.wethValue) + + Number(lpPrice.blnyanBalance) * Number(lpPrice.blnyanValue)) / + Number(lpPrice.supply); + + poolValueEth = (Number(poolInfo._staked) / 1e18) * Number(tokenValue); + ethYearly = YEAR * Number(poolInfo._rewardRate); + + apyReward = (ethYearly / poolValueEth) * 100; + + const ethPrice = ( + await axios.get('https://coins.llama.fi/prices/current/coingecko:ethereum') + ).data.coins['coingecko:ethereum'].price; + + const tvlUsd = (poolValueEth * ethPrice) / 1e18; + + data = { + pool: LP_TOKEN_ADDRESS, + chain: utils.formatChain('blast'), + project: 'blastnyan', + symbol: 'blNYAN-WETH', + tvlUsd, + apyBase: 0, + apyReward, + underlyingTokens: [TOKEN_ADDRESS, WETH_ADDRESS], + rewardTokens: [WETH_ADDRESS], + poolMeta: 'BlastNYAN Earning Pool: Stake LP to EARN TAXED WETH', + }; + + return data; +} + +const getblNyanStakingInfo = async () => { + var poolInfo = await helper.methods + .getPoolInfo(STAKING_REWARD_ADDRESS, DEPLOYER_ADDRESS) + .call(); + + var blNYANPrice = await helper.methods.getBlnyanPrice(1e18).call(); + poolValue = Number(poolInfo._staked); + + yearly = YEAR * Number(poolInfo._rewardRate); + apr = yearly / poolValue; + + asEth = (Number(poolValue) * Number(blNYANPrice)) / 1e18; + asEth = Math.floor(asEth).toString(); + + usd = await helper.methods.getTokenPriceUSDC(asEth.toString()).call(); + + usd = Number(usd) / 1e18; + + data = { + pool: TOKEN_ADDRESS, + chain: utils.formatChain('blast'), + project: 'blastnyan', + symbol: 'blNYAN', + tvlUsd: Number(usd), + apyBase: Number(0), + apyReward: Number(apr) * 100, + underlyingTokens: [TOKEN_ADDRESS], + rewardTokens: [TOKEN_ADDRESS], + poolMeta: 'BlastNYAN Single Asset Staking Farm', + }; + + return data; +}; + +const helper = new web3.eth.Contract(viewHelperABI, HELPER_ADDRESS); + +const getApy = async () => { + const poolsApy = []; + + const lpData = await getLPStakingInfo(); + const poolData = await getblNyanStakingInfo(); + + poolsApy.push(lpData); + poolsApy.push(poolData); + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://BlastNYAN.com/', +}; diff --git a/src/adaptors/blazeswap/index.js b/src/adaptors/blazeswap/index.js new file mode 100644 index 0000000000..65aad5e723 --- /dev/null +++ b/src/adaptors/blazeswap/index.js @@ -0,0 +1,144 @@ +const utils = require('../utils'); + +/** + * @typedef {Object} LPPage + * @property {string} address + * @property {Object} token0 + * @property {string} token0.address + * @property {string} token0.symbol + * @property {Object} token1 + * @property {string} token1.address + * @property {string} token1.symbol + * @property {Array} statistics + * @property {number} statistics.tvlUSD + * @property {number} statistics.feeUSD + * @property {string} statistics.period + * @property {Array} emissions + * @property {number} emissions.dailyEmission + * @property {string} emissions.startDate + * @property {string} emissions.endDate + */ + +/** + * @typedef {Object} Pool + * @property {string} pool + * @property {string} chain + * @property {string} project + * @property {string} symbol + * @property {number} tvlUsd + * @property {number} apyBase + * @property {number} apyReward + * @property {Array} rewardTokens + * @property {Array} underlyingTokens + * @property {string} poolMeta + * @property {string} url + * @property {number} apyBaseBorrow + * @property {number} apyRewardBorrow + * @property {number} totalSupplyUsd + * @property {number} totalBorrowUsd + * @property {number} ltv + */ + +/** + * + * @returns {Promise} + */ +function getFlrPrice() { + return utils.getData('https://api.flaremetrics.io/v2/defi/flare/price'); +} + +/** + * + * @param {number} limit + * @param {number} offset + * @returns {Promise} + */ +function getLPPage(limit, offset) { + return utils.getData( + `https://api.flaremetrics.io/v2/defi/flare/liquidity-pools?product=blazeswap-pool&tvlUSD=10000&limit=${limit}&offset=${offset}` + ); +} + +/** + * @param {number} now + * @param {number} flrPrice + * @returns {(lp: LPPage) => Pool[]} + */ +function makePoolFlatmap(now, flrPrice) { + /** + * @param {LPPage} lp + */ + return function poolFlatMap(lp) { + const chain = 'Flare'; + const address = lp.address; + const token0symbol = lp.token0.symbol; + const token1symbol = lp.token1.symbol; + const token0address = lp.token0.address; + const token1address = lp.token1.address; + const stats = lp.statistics.find(s => s.period == '1d'); + + if (!stats) return []; + + const tvlUsd = stats.tvlUSD; + const feeUsd = stats.feeUSD; + + const apyBase = feeUsd / tvlUsd * 365 * 100; + /** + * @type {Pool} + */ + const pool = { + pool: `${address}-${chain}`.toLowerCase(), + chain, + project: 'blazeswap', + symbol: `${token0symbol}-${token1symbol}`, + tvlUsd, + apyBase, + underlyingTokens: [token0address, token1address], + }; + + const emissions = lp.emissions || []; + const emission = emissions.find(e => { + const startDate = Date.parse(e.startDate); + const endDate = Date.parse(e.endDate); + return now >= startDate && now < endDate; + }); + + if (!emission) { + if (apyBase == 0) return []; + + return pool; + } + + pool.apyReward = emission.dailyEmission * flrPrice / tvlUsd * 365 * 100; + pool.rewardTokens = ['0x26d460c3Cf931Fb2014FA436a49e3Af08619810e']; // rFLR + + return pool; + }; +} + +async function poolsFunction() { + const now = Date.now(); + const flrPrice = await getFlrPrice(); + /** + * @type {LPPage[]} + */ + const liquidityPools = []; + const limit = 250; + + for (let i = 0; i < 10; i += 1) { + const offset = i * limit; + const lpPage = await getLPPage(limit, offset); + + liquidityPools.push(...lpPage); + + if (lpPage.length < limit) break; + } + + return liquidityPools.flatMap(makePoolFlatmap(now, flrPrice)); +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.blazeswap.xyz/pool/', +}; diff --git a/src/adaptors/blend-pools-v2/index.js b/src/adaptors/blend-pools-v2/index.js new file mode 100644 index 0000000000..65bf7a6758 --- /dev/null +++ b/src/adaptors/blend-pools-v2/index.js @@ -0,0 +1,102 @@ +const { + PoolV2, + BackstopToken, + Backstop, + FixedMath, + TokenMetadata, +} = require('@blend-capital/blend-sdk'); +const { getPrices, keepFinite, formatChain, getData } = require('../utils'); + +const BACKSTOP_ID = 'CAQQR5SWBXKIGZKPBZDH3KM5GQ5GUTPKB7JAFCINLZBC5WXPJKRG3IM7'; +const BLND_ID = 'CD25MNVTZDL4Y3XBCPCJXGXATV5WUHHOWMYFF4YBEGU5FCPGMYTVG5JY'; +const BLEND_POOLS = [ + 'CAJJZSGMMM3PD7N33TAPHGBUGTB43OC73HVIK2L2G6BNGGGYOSSYBXBD', + 'CCCCIQSDILITHMM7PBSLVDT5MISSY7R26MNZXCX4H7J5JQ5FPIYOGYFS', +]; +const NETWORK = { + rpc: 'https://soroban-rpc.creit.tech/', + passphrase: 'Public Global Stellar Network ; September 2015', +}; + +const getApy = async (poolId, backstop, blndPrice) => { + const pool = await PoolV2.load(NETWORK, poolId); + // Skip pools that have been admin frozen - Pool is very likely to be broken + if (pool.metadata.status === 4) return []; + + const prices = await getPrices(pool.metadata.reserveList, 'stellar'); + let pools = []; + + for (const reserve of Array.from(pool.reserves.values())) { + const price = prices.pricesByAddress[reserve.assetId.toLowerCase()]; + + if (price) { + let tokenMetadata = await TokenMetadata.load(NETWORK, reserve.assetId); + let supplyEmissionsAPR = undefined; + let borrowEmissionsAPR = undefined; + if (reserve.supplyEmissions) { + const supplyEmissionsPerAsset = + reserve.supplyEmissions.emissionsPerYearPerToken( + reserve.totalSupply(), + reserve.config.decimals + ); + + supplyEmissionsAPR = (supplyEmissionsPerAsset * blndPrice) / price; + } + if (reserve.borrowEmissions) { + const borrowEmissionsPerAsset = + reserve.borrowEmissions.emissionsPerYearPerToken( + reserve.totalLiabilities(), + reserve.config.decimals + ); + borrowEmissionsAPR = (borrowEmissionsPerAsset * blndPrice) / price; + } + + let totalSupply = reserve.totalSupplyFloat() * price; + let totalBorrow = reserve.totalLiabilitiesFloat() * price; + const url = `https://mainnet.blend.capital/dashboard/?poolId=${poolId}`; + + pools.push({ + pool: `${pool.id}-${reserve.assetId}-stellar`.toLowerCase(), + chain: formatChain('stellar'), + project: 'blend-pools-v2', + symbol: tokenMetadata.symbol, + tvlUsd: totalSupply - totalBorrow, + //Estimated weekly compounding + apyBase: reserve.supplyApr * 100, + apyReward: supplyEmissionsAPR * 100, + underlyingTokens: [reserve.assetId], + rewardTokens: borrowEmissionsAPR || supplyEmissionsAPR ? [BLND_ID] : [], + totalSupplyUsd: totalSupply, + totalBorrowUsd: totalBorrow, + // Estimated daily compounding + apyBaseBorrow: reserve.estBorrowApy * 100, + apyRewardBorrow: borrowEmissionsAPR * 100, + ltv: totalBorrow / totalSupply, + poolMeta: `${pool.metadata.name} Pool`, + url, + }); + } + } + return pools; +}; + +const apy = async () => { + let backstop = await Backstop.load(NETWORK, BACKSTOP_ID); + let pools = []; + const data = await getData( + 'https://coins.llama.fi/prices/current/coingecko:blend' + ); + for (const poolId of BLEND_POOLS) { + let poolApys = await getApy( + poolId, + backstop, + data.coins['coingecko:blend'].price + ); + pools.push(...poolApys); + } + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/blend-pools/index.js b/src/adaptors/blend-pools/index.js new file mode 100644 index 0000000000..356c0e5586 --- /dev/null +++ b/src/adaptors/blend-pools/index.js @@ -0,0 +1,103 @@ +const { + PoolV1, + BackstopToken, + Backstop, + FixedMath, + TokenMetadata, +} = require('@blend-capital/blend-sdk'); +const { getPrices, keepFinite, formatChain, getData } = require('../utils'); + +const BACKSTOP_ID = 'CAO3AGAMZVRMHITL36EJ2VZQWKYRPWMQAPDQD5YEOF3GIF7T44U4JAL3'; +const BLND_ID = 'CD25MNVTZDL4Y3XBCPCJXGXATV5WUHHOWMYFF4YBEGU5FCPGMYTVG5JY'; +const BLEND_POOLS = [ + 'CDVQVKOY2YSXS2IC7KN6MNASSHPAO7UN2UR2ON4OI2SKMFJNVAMDX6DP', + 'CBP7NO6F7FRDHSOFQBT2L2UWYIZ2PU76JKVRYAQTG3KZSQLYAOKIF2WB', + 'CDE65QK2ROZ32V2LVLBOKYPX47TYMYO37Z6ASQTBRTBNK53C7C6QF4Y7', + 'CAQF5KNOFIGRI24NQRRGUPD46Q45MGMXZMRTQFXS25Y4NZVNPT34GM6S', +]; +const NETWORK = { + rpc: 'https://soroban-rpc.creit.tech/', + passphrase: 'Public Global Stellar Network ; September 2015', +}; + +const getApy = async (poolId, backstop, blndPrice) => { + const pool = await PoolV1.load(NETWORK, poolId); + // Skip pools that have been admin frozen - Pool is very likely to be broken + if (pool.metadata.status === 4) return []; + + const prices = await getPrices(pool.metadata.reserveList, 'stellar'); + let pools = []; + + for (const reserve of Array.from(pool.reserves.values())) { + const price = prices.pricesByAddress[reserve.assetId.toLowerCase()]; + + if (price) { + let tokenMetadata = await TokenMetadata.load(NETWORK, reserve.assetId); + let supplyEmissionsAPR = undefined; + let borrowEmissionsAPR = undefined; + if (reserve.supplyEmissions) { + const supplyEmissionsPerAsset = + reserve.supplyEmissions.emissionsPerYearPerToken( + reserve.totalSupply(), + reserve.config.decimals + ); + + supplyEmissionsAPR = (supplyEmissionsPerAsset * blndPrice) / price; + } + if (reserve.borrowEmissions) { + const borrowEmissionsPerAsset = + reserve.borrowEmissions.emissionsPerYearPerToken( + reserve.totalLiabilities(), + reserve.config.decimals + ); + borrowEmissionsAPR = (borrowEmissionsPerAsset * blndPrice) / price; + } + + let totalSupply = reserve.totalSupplyFloat() * price; + let totalBorrow = reserve.totalLiabilitiesFloat() * price; + const url = `https://mainnet.blend.capital/dashboard/?poolId=${poolId}`; + + pools.push({ + pool: `${pool.id}-${reserve.assetId}-stellar`.toLowerCase(), + chain: formatChain('stellar'), + project: 'blend-pools', + symbol: tokenMetadata.symbol, + tvlUsd: totalSupply - totalBorrow, + apyBase: reserve.supplyApr * 100, + apyReward: supplyEmissionsAPR * 100, + underlyingTokens: [reserve.assetId], + rewardTokens: borrowEmissionsAPR || supplyEmissionsAPR ? [BLND_ID] : [], + totalSupplyUsd: totalSupply, + totalBorrowUsd: totalBorrow, + // Estimated daily compounding + apyBaseBorrow: reserve.estBorrowApy * 100, + apyRewardBorrow: borrowEmissionsAPR * 100, + ltv: totalBorrow / totalSupply, + poolMeta: `${pool.metadata.name} Pool`, + url, + }); + } + } + return pools; +}; + +const apy = async () => { + let backstop = await Backstop.load(NETWORK, BACKSTOP_ID); + let pools = []; + const data = await getData( + 'https://coins.llama.fi/prices/current/coingecko:blend' + ); + for (const poolId of BLEND_POOLS) { + let poolApys = await getApy( + poolId, + backstop, + data.coins['coingecko:blend'].price + ); + pools.push(...poolApys); + } + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/blue-planet/abis.js b/src/adaptors/blue-planet/abis.js new file mode 100644 index 0000000000..f0fa001573 --- /dev/null +++ b/src/adaptors/blue-planet/abis.js @@ -0,0 +1,168 @@ +module.exports = { + gammaFarmAbi: [ + { + "inputs": [], + "name": "GAMMAPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accGAMMAPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accGAMMAPerFactorPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gammaRewardBoostPercentage", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalFactor", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "want", + "type": "address" + }, + { + "internalType": "address", + "name": "strat", + "type": "address" + }, + { + "internalType": "address", + "name": "gToken", + "type": "address" + }, + { + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "isInfinity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "hasStratRewards", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isBoosted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + lpTokenABI: [ + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + gammaReservoirAbi: [{ + "inputs": [], + "name": "farmV2DripRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }] +}; diff --git a/src/adaptors/blue-planet/index.js b/src/adaptors/blue-planet/index.js new file mode 100644 index 0000000000..e2dce277f3 --- /dev/null +++ b/src/adaptors/blue-planet/index.js @@ -0,0 +1,220 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const { gammaFarmAbi, lpTokenABI, gammaReservoirAbi } = require('./abis'); +const utils = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const RPC_URL = 'https://bsc-dataseed1.binance.org/'; +const API_URL = sdk.graph.modifyEndpoint( + '6VnGdhHKmys4uJ8Dnb4ow9eg794kqnE8v35Gmwrjo1iW' +); +const LP_APRS = 'https://api.planet.finance/v2/markets/getpoolsinfo'; +const GAMMA_FARM_ADDRESS = '0x9EBce8B8d535247b2a0dfC0494Bc8aeEd7640cF9'; +const GAMMA = '0xb3Cb6d2f8f2FDe203a022201C81a96c167607F15'; +const GAMMA_RESERVOIR_ADDRESS = '0x7cF0E175908Fc6D7f51CE793271D5c0BD674660F'; + +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = (60 / BSC_BLOCK_TIME) * 60 * 24 * 365; + +const web3 = new Web3(RPC_URL); + +const pairQuery = gql` + query pairQuery($id: ID!) { + pair(id: $id) { + name + id + token0 { + id + decimals + } + token1 { + id + decimals + } + } + } +`; + +const farmv2driprate = async () => { + const reservoir_inst = await new web3.eth.Contract( + gammaReservoirAbi, + GAMMA_RESERVOIR_ADDRESS + ); + const farmv2dripR = await reservoir_inst.methods.farmV2DripRate().call(); + return farmv2dripR; +}; + +const getPairInfo = (pair) => { + const pairInfo = request(API_URL, pairQuery, { id: pair.toLowerCase() }); + + return pairInfo; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + cakePerBlock, + cakePrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + const cakePerYear = BLOCKS_PER_YEAR * cakePerBlock; + + return ((poolWeight * cakePerYear * cakePrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + pairName, + reserves, + reservesRatio, + bnbPrice, + gammaPrice, + ethPrice, + token0decimals, + token1decimals +) => { + const [token0, token1] = pairName.split('-'); + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1decimals)); + + if (token0.includes('USD')) return reserve0.times(2); + if (token0.includes('BNB')) return reserve0.times(bnbPrice).times(2); + if (token0.includes('Gamma')) return reserve0.times(gammaPrice).times(2); + if (token0.includes('ETH')) return reserve0.times(ethPrice).times(2); + if (token1.includes('USD')) return reserve1.times(2); + if (token1.includes('BNB')) return reserve1.times(bnbPrice).times(2); + if (token1.includes('Gamma')) return reserve1.times(gammaPrice).times(2); + if (token1.includes('ETH')) return reserve1.times(ethPrice).times(2); + return reserve0.times(2); +}; + +const getBaseTokensPrice = async () => { + const priceKeys = ['green-planet', 'ethereum', 'binancecoin'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const gammaPrice = prices['coingecko:green-planet'].price; + const ethPrice = prices['coingecko:ethereum'].price; + const bnbPrice = prices['coingecko:binancecoin'].price; + + return { gammaPrice, ethPrice, bnbPrice }; +}; + +const main = async () => { + const { gammaPrice, ethPrice, bnbPrice } = await getBaseTokensPrice(); + const gammaFarmInst = new web3.eth.Contract(gammaFarmAbi, GAMMA_FARM_ADDRESS); + const { data: lpAprs } = await fetchURL(LP_APRS); + const aprsObj = {}; + for (const key of Object.keys(lpAprs)) { + if ( + lpAprs[key].farmAddress.toLowerCase() == GAMMA_FARM_ADDRESS.toLowerCase() + ) { + aprsObj[lpAprs[key].wantAddress.toLowerCase()] = { + baseApy: lpAprs[key].tradeFeeApy ? lpAprs[key].tradeFeeApy : 0, + rewardApy: lpAprs[key].gammaApy, + }; + } + } + const poolsCount = await gammaFarmInst.methods.poolLength().call(); + const totalAllocPoint = await gammaFarmInst.methods.totalAllocPoint().call(); + const gammaRateToRegularFarm = await farmv2driprate(); + const normalizedGammaPerBlock = gammaRateToRegularFarm / 1e18; + + const [poolsRes] = await Promise.all( + ['poolInfo'].map((method) => + sdk.api.abi.multiCall({ + abi: gammaFarmAbi.filter(({ name }) => name === method)[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: GAMMA_FARM_ADDRESS, + params: i, + })), + chain: 'bsc', + permitFailure: true, + }) + ) + ); + const poolsInfo = poolsRes.output.map((res) => res.output); + + const [reservesRes, supplyRes, gammaFarmBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: poolsInfo.map((poolInfo) => ({ + target: poolInfo.want, + params: method === 'balanceOf' ? [poolInfo.strat] : null, + })), + chain: 'bsc', + permitFailure: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const gammaFarmBalData = gammaFarmBalancesRes.output.map((res) => res.output); + + const pools = await Promise.all( + poolsInfo.map((pool, i) => + getPairInfo(poolsInfo[i].want).then(({ pair: pairInfo }) => { + // the first two pools are inifinity vault, etc. + if (i < 2) return; + if (!pairInfo) return null; + + const poolInfo = poolsInfo[i]; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const gammaFarmBalance = gammaFarmBalData[i]; + const reserveUSD = calculateReservesUSD( + pairInfo.name, + reserves, + gammaFarmBalance / supply, + bnbPrice, + gammaPrice, + ethPrice, + pairInfo.token0.decimals, + pairInfo.token1.decimals + ) + .div(1e18) + .toString(); + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizedGammaPerBlock, + gammaPrice, + reserveUSD + ); + const pool = { + pool: pairInfo.id, + chain: utils.formatChain('binance'), + project: 'blue-planet', + symbol: pairInfo.name, + tvlUsd: Number(reserveUSD), + apyBase: aprsObj[pairInfo.id.toLowerCase()].baseApy, + apyReward: aprsObj[pairInfo.id.toLowerCase()].rewardApy, + rewardTokens: + aprsObj[pairInfo.id.toLowerCase()].rewardApy > 0 ? [GAMMA] : [], + underlyingTokens: [pairInfo.token0.id, pairInfo.token1.id], + }; + return pool; + }) + ) + ); + return pools.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.planet.finance/pools', +}; diff --git a/src/adaptors/bluefin-spot/index.js b/src/adaptors/bluefin-spot/index.js new file mode 100644 index 0000000000..f150bbc921 --- /dev/null +++ b/src/adaptors/bluefin-spot/index.js @@ -0,0 +1,36 @@ +const axios = require('axios'); + +const apyDataUrl = 'https://swap.api.sui-prod.bluefin.io/api/v1/pools/apy/stats'; + +const apy = async () => { + const response = await axios.get(apyDataUrl); + const pools = response.data.data; + + return pools + .map((p) => { + const stats = p.apyStats[0]; + const apyBase = Number(stats.aprFee); + const apyReward = Number(stats.aprRewards); + // Extract reward token addresses from rewards array + const rewardTokens = p.rewards?.map((reward) => reward.symbol) || []; + return { + pool: p.pool, + chain: 'Sui', + project: 'bluefin-spot', + symbol: `${p.coinA.symbol}-${p.coinB.symbol}`, + underlyingTokens: [p.coinA.coinType, p.coinB.coinType], + rewardTokens, + tvlUsd: Number(stats.tvlUsd), + apyBase, + apyReward: apyReward > 0 ? apyReward : 0, + poolMeta: `(${Number(p.feeRate)}%)`, + url: `https://trade.bluefin.io/deposit/${p.pool}`, + }; + }) + .filter((i) => i.tvlUsd >= 1e4) // show pools with at least $10,000 TVL + .sort((a, b) => b.tvlUsd - a.tvlUsd); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/blueshift/abi.json b/src/adaptors/blueshift/abi.json new file mode 100644 index 0000000000..a93c13f2fe --- /dev/null +++ b/src/adaptors/blueshift/abi.json @@ -0,0 +1,360 @@ +{ + "ERC20": { + "balanceOf": { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + }, + "BlueshiftRegistry": { + "getPortfolios": { + "inputs": [], + "name": "getPortfolios", + "outputs": [ + { + "components": [ + { + "internalType": "string[]", + "name": "name", + "type": "string[]" + }, + { + "internalType": "address[]", + "name": "contractAddress", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "baseTokenAddress", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "lpTokenAddress", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "lpTokenPrice", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "totalValue", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "tokenCount", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "baseTokenPriceCoefficient", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "address[]", + "name": "tokenAddress", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amount", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "price", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "depositLimit", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "withdrawLimit", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "depositEMAPrice", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "withdrawEMAPrice", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "portfolioShare", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "targetWeight", + "type": "uint256[]" + } + ], + "internalType": "struct BlueshiftPortfolioAndPairRegistry.TokenInfo[]", + "name": "tokens", + "type": "tuple[]" + } + ], + "internalType": "struct BlueshiftPortfolioAndPairRegistry.PortfolioInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } + }, + "BlueshiftMinter": { + "token": { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "contract BlueshiftToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAprWeights": { + "inputs": [], + "name": "getAprWeights", + "outputs": [ + { + "internalType": "uint16[]", + "name": "", + "type": "uint16[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getFarms": { + "inputs": [], + "name": "getFarms", + "outputs": [ + { + "internalType": "contract IEarningV2[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getStakings": { + "inputs": [], + "name": "getStakings", + "outputs": [ + { + "internalType": "contract IEarningV2[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getStatusFarms": { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "getStatusFarms", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReward", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "internalType": "struct IMinterV3.FarmInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getStatusStaking": { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "getStatusStaking", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReward", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "farm", + "type": "address" + } + ], + "internalType": "struct IMinterV3.FarmInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } + }, + "BlueshiftEarning": { + "getAccDeposit": { + "inputs": [], + "name": "getAccDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getToken": { + "inputs": [], + "name": "getToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + } +} \ No newline at end of file diff --git a/src/adaptors/blueshift/config.json b/src/adaptors/blueshift/config.json new file mode 100644 index 0000000000..ce1231dbcb --- /dev/null +++ b/src/adaptors/blueshift/config.json @@ -0,0 +1,22 @@ +{ + "network": { + "milkomeda": "Cardano", + "milkomeda_a1": "Algorand", + "kava": "Kava" + }, + "apiUrl": { + "milkomeda": "https://api.blueshift.fi/api", + "milkomeda_a1": "https://a1.api.blueshift.fi/api", + "kava": "https://kava.api.blueshift.fi/api" + }, + "registry": { + "milkomeda": "0xb42F2f37Dedf435F4916665d6B4c2cC643A17f14", + "milkomeda_a1": "0xa98C276d262Cc3Bf660189E2eBE74c4B8C18e50a", + "kava": "0x49399653f651A25924b3D8718276b5b4372577b1" + }, + "minter": { + "milkomeda": "0xdE6AB15d0786a0034B28Ed7e6B21ed95099CF48B", + "milkomeda_a1": "0x6455b3FE3cB9815d71D296f0CFFEfc1d591A91f3", + "kava": "0x39F220f50f67BC6d7CeD35affba82191c43668b5" + } +} \ No newline at end of file diff --git a/src/adaptors/blueshift/index.js b/src/adaptors/blueshift/index.js new file mode 100644 index 0000000000..936cd9d586 --- /dev/null +++ b/src/adaptors/blueshift/index.js @@ -0,0 +1,363 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { BigNumber } = require('ethers'); +const { AddressZero } = require('@ethersproject/constants'); + +const abi = require('./abi.json'); +const config = require('./config.json'); + +const BLOCKS_PER_YEAR = 8e6; + +const MONTHS_IN_YEAR = 12; +const DAYS_IN_YEAR = 365; +const NUMBER_OF_PERIODS = DAYS_IN_YEAR; + +const ONE = (decimals) => BigNumber.from(10).pow(decimals); +const TRANSFORM_TO_PERCENTS = (num) => num * 100; + +function formatBigNumber(num, decimals) { + if (num.length > decimals) { + return ( + num.slice(0, num.length - decimals) + + '.' + + num.slice(num.length - decimals) + ); + } else { + return '0.' + '0'.repeat(decimals - num.length) + num; + } +} + +async function getFees(chain, portfolios) { + const res = {}; + + const fees = ( + await utils.getData(`${config.apiUrl[chain]}/portfolio/fee`, { + portfolio: portfolios, + period: 30, + }) + ).fee; + + for (let i = 0; i < fees.length; ++i) { + res[portfolios[i]] = fees[i]; + } + + return res; +} + +async function getTokenVsUsdPrice(token) { + const priceKey = `coingecko:${token}`; + const { coins: bluesPrice } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + + const [i, f] = bluesPrice[priceKey].price.toString().split('.'); + + if (f === undefined) { + return BigNumber.from(i + '0'.repeat(6)); + } else { + return BigNumber.from( + i + f.slice(0, 6) + '0'.repeat(f.length < 6 ? 6 - f.length : 0) + ); + } +} + +function apy(apr, aprWeights) { + const apr1 = apr * Number(formatBigNumber(aprWeights[0], 4)); + const apr2 = + apr * + (Number(formatBigNumber(aprWeights[1], 4)) + + Number(formatBigNumber(aprWeights[2], 4))); + + const apy1 = (1 + apr1 / NUMBER_OF_PERIODS) ** NUMBER_OF_PERIODS; + + // console.log("weight1:", Number(formatBigNumber(aprWeights[0], 4))); + // console.log("weight2:", Number(formatBigNumber(aprWeights[1], 4))); + // console.log("weight3:", Number(formatBigNumber(aprWeights[2], 4))); + // console.log("apr1:", apr1); + // console.log("apr2:", apr2); + // console.log("apy1:", apy1); + + return apy1 + (apr2 / apr1) * (apy1 - 1) - 1; +} + +async function farming( + chain, + aprWeights, + rewardToken, + BLUES_PRICE, + portfolios +) { + const res = []; + const transform = (addr) => `${chain}:${addr}`; + const fixBalances = i => i + + const fees = await getFees(chain, portfolios.contractAddress); + + const farms = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.getFarms, + chain: chain, + target: config.minter[chain], + params: [], + }) + ).output; + + const farmInfos = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.getStatusFarms, + chain: chain, + target: config.minter[chain], + params: [ + AddressZero, + (await sdk.api.util.getLatestBlock(chain)).timestamp, + ], + }) + ).output; + + for (let farm of farms) { + const receivedToken = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftEarning.getToken, + chain: chain, + target: farm, + params: [], + }) + ).output; + + let indexOfPortfolioWithReceivedToken = undefined; + + for (let i = 0; i < portfolios.lpTokenAddress.length; ++i) { + if (portfolios.lpTokenAddress[i] === receivedToken) { + indexOfPortfolioWithReceivedToken = i; + break; + } + } + + if (indexOfPortfolioWithReceivedToken === undefined) { + continue; + } + + const farmInfo = farmInfos.filter((farmInfo) => farmInfo.farm === farm)[0]; + if (farmInfo === undefined) { + continue; + } + + const tokensAddresses = + portfolios.tokens[indexOfPortfolioWithReceivedToken].tokenAddress; + + const tokensSymbols = ( + await sdk.api.abi.multiCall({ + abi: abi.ERC20.symbol, + chain: chain, + calls: tokensAddresses.map((tokenAddress) => ({ + target: tokenAddress, + params: [], + })), + requery: true, + }) + ).output.map((s) => s.output); + + const rewardedFee = Number( + formatBigNumber( + BigNumber.from( + fees[portfolios.contractAddress[indexOfPortfolioWithReceivedToken]] + ) + .mul(MONTHS_IN_YEAR) + .toString(), + 6 + ) + ); + const rewardedStake = Number( + formatBigNumber( + BigNumber.from(farmInfo.rewardPerBlock) + .mul(BLOCKS_PER_YEAR) + .mul(BLUES_PRICE) + .div(ONE(18)) + .toString(), + 6 + ) + ); + + let tvl = farmInfo.accDeposited; + tvl = BigNumber.from(tvl) + .mul( + BigNumber.from( + portfolios.lpTokenPrice[indexOfPortfolioWithReceivedToken] + ) + ) + .div(ONE(18)); + + let balances = {}; + let tvlUsd = 0; + sdk.util.sumSingleBalance( + balances, + transform(portfolios.baseTokenAddress[indexOfPortfolioWithReceivedToken]), + tvl.toString() + ); + fixBalances(balances); + // tvlUsd = (await sdk.util.computeTVL(balances, 'now')).usdTvl; + tvlUsd = 0; + + const aprBase = rewardedFee / tvlUsd; + const aprReward = rewardedStake / tvlUsd; + + const apyBase = tokensAddresses.includes(rewardToken) + ? apy(aprBase, aprWeights) + : aprBase; + const apyReward = aprReward; + + // console.log(tokensSymbols); + // console.log("aprBase:", aprBase.toString()); + // console.log("aprReward:", aprReward.toString()); + // console.log("apyBase:", apyBase.toString()); + // console.log("apyReward:", apyReward.toString()); + + res.push({ + pool: farm.toLowerCase(), + chain: utils.formatChain(chain), + project: 'blueshift', + symbol: tokensSymbols.join('-'), + apyBase: TRANSFORM_TO_PERCENTS(apyBase), + apyReward: TRANSFORM_TO_PERCENTS(apyReward), + tvlUsd: tvlUsd, + rewardTokens: [rewardToken], + underlyingTokens: tokensAddresses, + url: `https://app.blueshift.fi/#/farming?network=${config.network[chain]}`, + poolMeta: portfolios.name[indexOfPortfolioWithReceivedToken], + }); + } + + return res; +} + +async function staking(chain, aprWeights, rewardToken, BLUES_PRICE) { + const res = []; + + const stakings = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.getStakings, + chain: chain, + target: config.minter[chain], + params: [], + }) + ).output; + + const stakingInfos = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.getStatusStaking, + chain: chain, + target: config.minter[chain], + params: [ + AddressZero, + (await sdk.api.util.getLatestBlock(chain)).timestamp, + ], + }) + ).output; + + for (let staking of stakings) { + const receivedToken = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftEarning.getToken, + chain: chain, + target: staking, + params: [], + }) + ).output; + + const stakingInfo = stakingInfos.filter( + (stakingInfo) => stakingInfo.farm === staking + )[0]; + if (stakingInfo === undefined) { + continue; + } + + let tvl = stakingInfo.accDeposited; + const tvlUsd = BigNumber.from(tvl).mul(BLUES_PRICE).div(ONE(18)).toString(); + + const aprReward = BigNumber.from(stakingInfo.rewardPerBlock) + .mul(BLOCKS_PER_YEAR) + .mul(10000) + .div(tvl); + const apyReward = apy( + Number(formatBigNumber(aprReward.toString(), 4)), + aprWeights + ); + + // console.log("aprReward:", formatBigNumber(aprReward.toString(), 4)); + // console.log("apyReward:", apyReward.toString()); + + res.push({ + pool: `${staking}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'blueshift', + symbol: 'BLUES', + apyBase: null, + apyReward: TRANSFORM_TO_PERCENTS(apyReward), + tvlUsd: Number(formatBigNumber(tvlUsd.toString(), 6)), + rewardTokens: [rewardToken], + underlyingTokens: [rewardToken], + url: `https://app.blueshift.fi/#/staking?network=${config.network[chain]}`, + }); + } + + return res; +} + +async function poolsApy(chain) { + const BLUES_PRICE = await getTokenVsUsdPrice('blueshift'); + + const portfolios = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftRegistry.getPortfolios, + chain: chain, + target: config.registry[chain], + params: [], + }) + ).output; + + const rewardToken = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.token, + chain: chain, + target: config.minter[chain], + params: [], + }) + ).output; + + const aprWeights = ( + await sdk.api.abi.call({ + abi: abi.BlueshiftMinter.getAprWeights, + chain: chain, + target: config.minter[chain], + params: [], + }) + ).output; + + const farmingPools = await farming( + chain, + aprWeights, + rewardToken, + BLUES_PRICE, + portfolios + ); + const stakingPools = await staking( + chain, + aprWeights, + rewardToken, + BLUES_PRICE + ); + + return [...farmingPools, ...stakingPools].filter((i) => utils.keepFinite(i)); +} + +module.exports = { + timetravel: false, + apy: async () => + ( + await Promise.all( + ['milkomeda', 'milkomeda_a1'].map( + async (chain) => await poolsApy(chain) + ) + ) + ).reduce((a, b) => [...a, ...b]), +}; diff --git a/src/adaptors/blume/index.js b/src/adaptors/blume/index.js new file mode 100644 index 0000000000..b47902145e --- /dev/null +++ b/src/adaptors/blume/index.js @@ -0,0 +1,213 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { ercDelegator } = require('../compound-v2/abi'); + +const comptrollerAbi = require('../orbit-protocol/comptrollerAbi.json'); + +const COMPTROLLER_ADDRESS = '0x4EdF556c5664b4f86Ec50dB0F58B58B26210DC31'; +const CHAIN = 'blast'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 2; +const PROJECT_NAME = 'blume'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x4300000000000000000000000000000000000004'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const apy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplySpeeds = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowSpeeds = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const tvlUsd = (marketsCash[i] / 10 ** decimals) * price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + + const apyBase = calculateApy(supplySpeeds[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowSpeeds[i] / 10 ** 18); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + underlyingTokens: [token], + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + debtCeilingUsd: (borrowCaps[i] / 1e18) * price, + }; + } + return poolReturned; + }); + + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.orbitlending.io/markets', +}; diff --git a/src/adaptors/bmx-classic-perps/abis/abi.json b/src/adaptors/bmx-classic-perps/abis/abi.json new file mode 100644 index 0000000000..61291d0ce0 --- /dev/null +++ b/src/adaptors/bmx-classic-perps/abis/abi.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/bmx-classic-perps/index.js b/src/adaptors/bmx-classic-perps/index.js new file mode 100644 index 0000000000..9a3354fb56 --- /dev/null +++ b/src/adaptors/bmx-classic-perps/index.js @@ -0,0 +1,270 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); + +const project = 'bmx-classic-perps'; + +// Base +const tokenAddressBMXBase = '0x548f93779fBC992010C07467cBaf329DD5F059B7'; +const mlpManagerAddressBase = '0x9fAc7b75f367d5B35a6D6D0a09572eFcC3D406C5'; + +const feeBmxTrackerAddressBase = '0x38E5be3501687500E6338217276069d16178077E'; +const stakedBmxTrackerAddressBase = + '0x3085F25Cbb5F34531229077BAAC20B9ef2AE85CB'; + +const feeBltTrackerAddressBase = '0xa2242d0A8b0b5c1A487AbFC03Cd9FEf6262BAdCA'; +const stakedBltTrackerAddressBase = + '0x2D5875ab0eFB999c1f49C798acb9eFbd1cfBF63c'; + +// Mode +const tokenAddressBMXMode = '0x66eEd5FF1701E6ed8470DC391F05e27B1d0657eb'; +const mlpManagerAddressMode = '0xf9Fc0B2859f9B6d33fD1Cea5B0A9f1D56C258178'; + +const feeBmxTrackerAddressMode = '0x548f93779fBC992010C07467cBaf329DD5F059B7'; +const stakedBmxTrackerAddressMode = + '0x773F34397d5F378D993F498Ee646FFe4184E00A3'; + +const feeBltTrackerAddressMode = '0xCcBF79AA51919f1711E40293a32bbC71F8842FC3'; +const stakedBltTrackerAddressMode = + '0x6c72ADbDc1029ee901dC97C5604487285D972A4f'; + +const secondsPerYear = 31536000; + +async function getAdjustedAmount(pTarget, pChain, pAbi, pParams = []) { + let decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: pChain, + }); + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * secondsPerYear + : supply.output * 10 ** -decimals.output; +} + +async function getBltTVL(pChain) { + let tvl = await sdk.api.abi.call({ + target: pChain == 'base' ? mlpManagerAddressBase : mlpManagerAddressMode, + abi: abi['getAumInUsdg'], + chain: pChain, + params: [false], + }); + + return tvl.output * 10 ** -18; +} + +async function getPoolBMX( + pChain, + pInflationTrackerAddress, + pStakedBmx, + pStakedEsBmx, + pFeeBmx, + pInflationBmx, + pPriceData +) { + const tvlBmx = + pPriceData.bmx.price * + (await getAdjustedAmount( + pChain == 'base' ? tokenAddressBMXBase : tokenAddressBMXMode, + pChain, + 'erc20:balanceOf', + pChain == 'base' + ? [stakedBmxTrackerAddressBase] + : [stakedBmxTrackerAddressMode] + )); + + const tvsBmx = pStakedBmx * pPriceData.bmx.price; + const tvsEsBmx = pStakedEsBmx * pPriceData.bmx.price; + + const yearlyFeeBmx = pFeeBmx * pPriceData.ethereum.price; + const yearlyInflationBmx = pInflationBmx * pPriceData.bmx.price; + + const apyFee = (yearlyFeeBmx / tvsBmx) * 100; + const apyInflation = (yearlyInflationBmx / tvsEsBmx) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project, + symbol: utils.formatSymbol('BMX'), + tvlUsd: tvlBmx, + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + pChain === 'base' ? [tokenAddressBMXBase] : [tokenAddressBMXMode], + underlyingTokens: [ + pChain === 'base' ? tokenAddressBMXBase : tokenAddressBMXMode, + ], + }; +} + +async function getPoolBLT( + pChain, + pTvl, + pInflationTrackerAddress, + pFeeBlt, + pInflationBlt, + pPriceData +) { + const yearlyFeeBlt = pFeeBlt * pPriceData.ethereum.price; + const yearlyInflationBlt = pInflationBlt * pPriceData.bmx.price; + const apyFee = (yearlyFeeBlt / pTvl) * 100; + const apyInflation = (yearlyInflationBlt / pTvl) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project, + symbol: + pChain === 'base' + ? 'ETH-BTC-YFI-AERO-MOG-USDC-USDbC' + : 'ETH-BTC-MODE-weETH-USDC', + tvlUsd: parseFloat(pTvl), + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + pChain === 'base' ? [tokenAddressBMXBase] : [tokenAddressBMXMode], + underlyingTokens: [ + pChain === 'base' + ? '0xe771b4E273dF31B85D7A7aE0Efd22fb44BdD0633' + : '0x952AdBB385296Dcf86a668f7eaa02DF7eb684439', + ], + poolMeta: pChain === 'base' ? 'BLT' : 'MLT', + }; +} + +const getPools = async () => { + let pools = []; + + const priceKeys = ['ethereum', 'bmx'].map((t) => `coingecko:${t}`).join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const priceData = { + bmx: prices['coingecko:bmx'], + ethereum: prices['coingecko:ethereum'], + }; + + // Base + const baseStakedBmx = await getAdjustedAmount( + feeBmxTrackerAddressBase, + 'base', + 'erc20:totalSupply' + ); + const baseStakedEsBmx = await getAdjustedAmount( + stakedBmxTrackerAddressBase, + 'base', + 'erc20:totalSupply' + ); + const baseFeeBmx = await getAdjustedAmount( + feeBmxTrackerAddressBase, + 'base', + abi['tokensPerInterval'] + ); + const baseInflationBmx = await getAdjustedAmount( + stakedBmxTrackerAddressBase, + 'base', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolBMX( + 'base', + stakedBmxTrackerAddressBase, + baseStakedBmx, + baseStakedEsBmx, + baseFeeBmx, + baseInflationBmx, + priceData + ) + ); + + const baseFeeBlt = await getAdjustedAmount( + feeBltTrackerAddressBase, + 'base', + abi['tokensPerInterval'] + ); + const baseInflationBlt = await getAdjustedAmount( + stakedBltTrackerAddressBase, + 'base', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolBLT( + 'base', + await getBltTVL('base'), + stakedBltTrackerAddressBase, + baseFeeBlt, + baseInflationBlt, + priceData + ) + ); + + // Mode + const modeStakedBmx = await getAdjustedAmount( + feeBmxTrackerAddressMode, + 'mode', + 'erc20:totalSupply' + ); + const modeStakedEsBmx = await getAdjustedAmount( + stakedBmxTrackerAddressMode, + 'mode', + 'erc20:totalSupply' + ); + const modeFeeBmx = await getAdjustedAmount( + feeBmxTrackerAddressMode, + 'mode', + abi['tokensPerInterval'] + ); + const modeInflationBmx = await getAdjustedAmount( + stakedBmxTrackerAddressMode, + 'mode', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolBMX( + 'mode', + stakedBmxTrackerAddressMode, + modeStakedBmx, + modeStakedEsBmx, + modeFeeBmx, + modeInflationBmx, + priceData + ) + ); + + const modeFeeBlt = await getAdjustedAmount( + feeBltTrackerAddressMode, + 'mode', + abi['tokensPerInterval'] + ); + const modeInflationBlt = await getAdjustedAmount( + stakedBltTrackerAddressMode, + 'mode', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolBLT( + 'mode', + await getBltTVL('mode'), + stakedBltTrackerAddressMode, + modeFeeBlt, + modeInflationBlt, + priceData + ) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://www.bmx.trade/deli-shop', +}; diff --git a/src/adaptors/bolide/index.js b/src/adaptors/bolide/index.js new file mode 100644 index 0000000000..1116ef266e --- /dev/null +++ b/src/adaptors/bolide/index.js @@ -0,0 +1,53 @@ +const utils = require('../utils'); + +const MASTER_CHEF = '0x3782C47E62b13d579fe748946AEf7142B45B2cf7'; + +const poolsFunction = async () => { + const data = await utils.getData('https://bolide.fi/api/v1/vaults/list'); + + const pools = []; + + for (const vault of data.vaults) { + for (const token of vault.tokens) { + let poolAddress; + + if (vault.address === MASTER_CHEF) { + if (token.name === 'BLID') { + poolAddress = `${vault.address}0`; + } else { + poolAddress = `${vault.address}1`; + } + } else { + poolAddress = `${vault.address}${token.name}`; + } + + pools.push({ + pool: poolAddress, + chain: getChainNameById(vault.chainId), + project: 'bolide', + symbol: token.name, + tvlUsd: token.tvl, + apy: vault.baseApy, + }); + } + } + + return pools.filter((p) => p.chain); +}; + +const getChainNameById = (chainId) => { + switch (chainId) { + case 1: + return 'ethereum'; + case 56: + return 'binance'; + case 137: + return 'polygon'; + } +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.bolide.fi/#/', +}; diff --git a/src/adaptors/bracket-vaults/index.js b/src/adaptors/bracket-vaults/index.js new file mode 100644 index 0000000000..03aeb4d4cb --- /dev/null +++ b/src/adaptors/bracket-vaults/index.js @@ -0,0 +1,184 @@ +const utils = require('../utils'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); + +const CHAIN = "ethereum"; + +// Configuration constants +const DAYS_PER_YEAR = 365; +const SECONDS_PER_DAY = 86400; + +// Contract addresses +const ADDRESSES = { + vaults: { + brUSDC: '0xb8ca40E2c5d77F0Bc1Aa88B2689dddB279F7a5eb', // USDC+ Vault + brETH: '0x3588e6Cb5DCa99E35bA2E2a5D42cdDb46365e71B', // ETH+ Vault + bravUSDC: '0x9f96E4B65059b0398B922792d3fF9F10B4567533', // Avant+ Vault + }, + underlyingTokens: { + brUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC + brETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH + bravUSDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC + } +}; + +const BRACKET_LENS_ADDRESS = '0xcdc3a8374532Ddb762c76604f30F6a9FDd29082c' + +const VAULT_DECIMALS = { + '0xb8ca40E2c5d77F0Bc1Aa88B2689dddB279F7a5eb': 6, + '0x3588e6Cb5DCa99E35bA2E2a5D42cdDb46365e71B': 18, + '0x9f96E4B65059b0398B922792d3fF9F10B4567533': 6, +} + +const VAULT_START_TIMESTAMP = { + '0xb8ca40E2c5d77F0Bc1Aa88B2689dddB279F7a5eb': 1750111200, + '0x3588e6Cb5DCa99E35bA2E2a5D42cdDb46365e71B': 1755727200, + '0x9f96E4B65059b0398B922792d3fF9F10B4567533': 1754258400, +} + +const UNDERLYING_SYMBOL = { + brUSDC: 'USDC', + brETH: 'wETH', + bravUSDC: 'USDC' +}; + +const getVaultData = async (vaultAddress) => { + const epoch = await sdk.api.abi.call({ + target: vaultAddress, + abi: "function epoch() view returns (uint16)", + chain: CHAIN, + }); + + const queryEpoch = epoch.output - 1; + + console.log("epoch:", epoch.output); + console.log("queryEpoch:", queryEpoch); + + const nav = await sdk.api.abi.call({ + target: vaultAddress, + abi: "function navs(uint16 epoch) view returns (uint256)", + chain: CHAIN, + params: [queryEpoch], + }); + + console.log("nav:", nav.output); + + const nextLock = await sdk.api.abi.call({ + target: vaultAddress, + abi: "function nextLock() view returns (uint48)", + chain: CHAIN, + }); + console.log("nextLock:", nextLock.output); + const lockFrequency = await sdk.api.abi.call({ + target: vaultAddress, + abi: "function lockFrequency() view returns (uint48)", + chain: CHAIN, + }); + console.log("lockFrequency:", lockFrequency.output); + + const lastLock = nextLock.output - lockFrequency.output; + + console.log("lastLock:", lastLock); + + return {lastLock, nav: nav.output}; +} + +const getVaultAPY = async (vaultAddress) => { + const { lastLock, nav } = await getVaultData(vaultAddress); + + const startTimestamp = VAULT_START_TIMESTAMP[vaultAddress]; + const startNav = Math.pow(10, VAULT_DECIMALS[vaultAddress]); + + const ratio = Number(nav) / Number(startNav); + if (ratio <= 0) { + console.error(`Error fetching vault data for ${vaultAddress}:`, 'ratio <= 0'); + return 0; + } + console.log("ratio:", ratio); + + const elapsedDays = Math.floor((lastLock - startTimestamp) / SECONDS_PER_DAY); + if (elapsedDays <= 0) { + console.error(`Error fetching vault data for ${vaultAddress}:`, 'elapsedSeconds <= 0'); + return 0; + }; + console.log("elapsedDays:", elapsedDays); + + const elapsedYears = Number(elapsedDays) / DAYS_PER_YEAR; + if (elapsedYears <= 0) { + console.error(`Error fetching vault data for ${vaultAddress}:`, 'elapsedYears <= 0'); + return 0; + } + console.log("elapsedYears:", elapsedYears); + + + // // If less than a year elapsed, annualize compounding return to be APY + // // APY = (ratio)^(1/elapsedYears) - 1, even if elapsedYears < 1 + return (Math.pow(ratio, 1 / elapsedYears) - 1) * 100; +} + + +const getTokenPrice = async (priceKey, amount, decimals) => { + try { + const response = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`); + if (!response.data?.coins?.[priceKey]?.price) { + console.warn(`No price found for ${priceKey}`); + return 0; + } + return (response.data.coins[priceKey].price * amount) / 10 ** decimals; + } catch (error) { + console.error(`Error fetching price for ${priceKey}:`, error.message); + return 0; + } +}; + +const getVaultTVL = async (vaultType, vaultAddress, vaultDecimals) => { + const underlyingAddress = ADDRESSES.underlyingTokens[vaultType]; + const priceKey = `${CHAIN}:${underlyingAddress}`; + + const tvl = await sdk.api.abi.call({ + target: BRACKET_LENS_ADDRESS, + abi: "function getTVL(address vault) view returns (uint256)", + chain: CHAIN, + params: [vaultAddress], + }) + + return getTokenPrice(priceKey, Number(tvl.output), vaultDecimals); +}; + + +const main = async () => { + const pools = []; + + for (const [vaultType, vaultAddress] of Object.entries(ADDRESSES.vaults)) { + try { + const vaultDecimals = VAULT_DECIMALS[vaultAddress]; + const tvlUSD = await getVaultTVL(vaultType, vaultAddress, vaultDecimals); + const apy = await getVaultAPY(vaultAddress); + + if (tvlUSD !== undefined && apy !== undefined) { + pools.push({ + pool: vaultAddress, + chain: utils.formatChain(CHAIN), + project: 'bracket-vaults', + symbol: UNDERLYING_SYMBOL[vaultType], + tvlUsd: Number(tvlUSD.toFixed(2)), + apyBase: Number(apy.toFixed(2)), + underlyingTokens: [ADDRESSES.underlyingTokens[vaultType]], + }); + } + + } catch (error) { + console.error(`Error processing vault ${vaultType}:`, error.message); + } + } + + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://bracket.fi/' +}; diff --git a/src/adaptors/brinc-finance/brc_abi.json b/src/adaptors/brinc-finance/brc_abi.json new file mode 100644 index 0000000000..3db3e1a6b7 --- /dev/null +++ b/src/adaptors/brinc-finance/brc_abi.json @@ -0,0 +1,981 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "reserveAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "buyTaxRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "buyTaxScale", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sellTaxRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sellTaxScale", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "reserveRatio", + "type": "uint32" + }, + { + "internalType": "address", + "name": "curveAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRate", + "type": "uint256" + } + ], + "name": "BuyTaxRateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldScale", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newScale", + "type": "uint256" + } + ], + "name": "BuyTaxScaleChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRate", + "type": "uint256" + } + ], + "name": "SellTaxRateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldScale", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newScale", + "type": "uint256" + } + ], + "name": "SellTaxScaleChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "Snapshot", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "snapshotId", + "type": "uint256" + } + ], + "name": "balanceOfAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "buyTaxRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "buyTaxScale", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserveBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_reserveRatio", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "fundCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_firstReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_firstSupply", + "type": "uint256" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserveBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_reserveRatio", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "liquidateReserveAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mintCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mintForSpecificReserveAmount", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserveBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_reserveWeight", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "purchaseTargetAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserveRatio", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserveBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_reserveWeight", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "saleTargetAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sellTaxRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sellTaxScale", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + } + ], + "name": "setBuyTaxRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_scale", + "type": "uint256" + } + ], + "name": "setBuyTaxScale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + } + ], + "name": "setSellTaxRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_scale", + "type": "uint256" + } + ], + "name": "setSellTaxScale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "snapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "snapshotId", + "type": "uint256" + } + ], + "name": "totalSupplyAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/brinc-finance/index.js b/src/adaptors/brinc-finance/index.js new file mode 100644 index 0000000000..ac498283f0 --- /dev/null +++ b/src/adaptors/brinc-finance/index.js @@ -0,0 +1,339 @@ +// const JSBI = require('jsbi'); +// const { +// CurrencyAmount, +// Percent, +// Token, +// TradeType, +// } = require('@uniswap/sdk-core'); +// const { AlphaRouter } = require('@uniswap/smart-order-router'); +// const { default: BigNumber } = require('bignumber.js'); +// const { JsonRpcProvider } = require('@ethersproject/providers'); +// const StakingABI = require('./staking_abi.json'); +// const BrcABI = require('./brc_abi.json'); +// const utils = require('../utils'); +// const {Web3} = require('web3'); +// const jsonRpcProvider = new JsonRpcProvider( +// process.env.ALCHEMY_CONNECTION_ARBITRUM +// ); +// const web3 = new Web3(process.env.ALCHEMY_CONNECTION_ARBITRUM); + +// const STAKING_CONTRACT = '0x9A28f7Ab9aEb4f14Fc4c580938F8F5E89ce98084'; +// const BRC = '0xB5de3f06aF62D8428a8BF7b4400Ea42aD2E0bc53'; +// const GBRC = '0x62C7e128e7c3205964429F58A0C6f63a776D10d1'; +// const ChainId = 42161; + +// const stakingContract = new web3.eth.Contract(StakingABI, STAKING_CONTRACT); +// const brcContract = new web3.eth.Contract(BrcABI, BRC); +// const BLOCKS_PER_MONTH = 199384; +// const TOTAL_POOLS_WEIGHT = 568; +// const PoolNames = [ +// 'BRC 7Days', +// 'BRC 30Days', +// 'BRC 90Days', +// 'BRC-gBRC 7Days', +// 'BRC-gBRC 30Days', +// 'BRC-gBRC 90Days', +// ]; + +// let gBRCCost = 0; +// let daiCost = 0; +// let govBrincPerWeek = 0; +// let stakingBRCSupply = 0; +// let stakingRatio = 0; +// let totalSupplyMultWeight = 0; +// let MODE1Weight = 0; +// let MODE2Weight = 0; +// let MODE3Weight = 0; +// let MODE4Weight = 0; +// let MODE5Weight = 0; +// let MODE6Weight = 0; + +// const getAllPoolWeights = async () => { +// MODE1Weight = Number(await stakingContract.methods.getPoolWeight(0).call()); +// MODE2Weight = Number(await stakingContract.methods.getPoolWeight(1).call()); +// MODE3Weight = Number(await stakingContract.methods.getPoolWeight(2).call()); +// MODE4Weight = Number(await stakingContract.methods.getPoolWeight(3).call()); +// MODE5Weight = Number(await stakingContract.methods.getPoolWeight(4).call()); +// MODE6Weight = Number(await stakingContract.methods.getPoolWeight(5).call()); +// }; + +// const getPoolWeight = (stakePool) => { +// switch (stakePool) { +// case 0: +// return MODE1Weight; +// case 1: +// return MODE2Weight; +// case 2: +// return MODE3Weight; +// case 3: +// return MODE4Weight; +// case 4: +// return MODE5Weight; +// case 5: +// return MODE6Weight; +// default: +// return ( +// MODE1Weight + +// MODE2Weight + +// MODE3Weight + +// MODE4Weight + +// MODE5Weight + +// MODE6Weight +// ); +// } +// }; + +// const getPoolTVL = async (stakePool, brcSupply, gbrcSupply) => { +// let totalPrice = await getBRCPrice(brcSupply); +// if (stakePool >= 3) { +// // brcSupply is used here because current version of staking contract +// // has had its ratio increased from 1BRC:1gBRC(old) to 1BRC:100gBRC(current) +// // TVL of dual staking pools is thus apparently higher than set here +// // but this is set as a lower boundary +// totalPrice = Number(totalPrice) + (await getGBRCPrice(brcSupply)); +// } +// return totalPrice; +// }; + +// const getBRCPrice = async (amount) => { +// const brcPrice = await brcContract.methods +// .mintCost(new BigNumber(amount).toFixed()) +// .call(); +// return brcPrice / 1e18; +// }; + +// const getGBRCPriceFromBRC = async (amount) => { +// try { +// const token = new Token(ChainId, BRC, 18, 'BRC', 'Brinc Token'); +// const toToken = new Token(ChainId, GBRC, 18, 'gBRC', 'Governance Token'); + +// const swapOptions = { +// recipient: '0xa1B94ef0f24d7F4fd02285EFcb9202E6C6EC655B', +// slippageTolerance: new Percent(5, 100), +// deadline: Math.floor(Date.now() / 1000 + 1800), +// }; + +// const currencyAmount = CurrencyAmount.fromRawAmount( +// token, +// JSBI.BigInt(amount) +// ); +// const router = new AlphaRouter({ +// chainId: ChainId, +// provider: jsonRpcProvider, +// }); + +// return router +// .route(currencyAmount, toToken, TradeType.EXACT_INPUT, swapOptions) +// .then((res) => { +// if (res) { +// return res.quote.toFixed(toToken.decimals); +// } else { +// return 0; +// } +// }) +// .catch((err) => { +// console.log('cost quote brc->gbrc error', err); +// return '0'; +// }); +// } catch (error) { +// console.log('getGBRCPriceFromBRC', error); +// } +// }; + +// const getGBRCPrice = async (amount) => { +// try { +// return (Number(daiCost) / Number(gBRCCost)) * (amount / 1e18); +// } catch (error) { +// console.log('Failed to getGBRCPrice \n Error => ', error); +// return new BigNumber(0); +// } +// }; + +// const loadEssentials = async () => { +// // pool weights +// await getAllPoolWeights(); + +// // load prices +// daiCost = await getBRCPrice((1e18).toString()); +// gBRCCost = await getGBRCPriceFromBRC((1e18).toString()); + +// // load how much rewards are distributed per week +// const govBrincPerBlock = await stakingContract.methods +// .getGovBrincPerBlock() +// .call(); +// const govBrincPerMonth = new BigNumber(+govBrincPerBlock).times( +// BLOCKS_PER_MONTH +// ); +// govBrincPerWeek = new BigNumber(govBrincPerMonth.toString()).div(4); + +// // load total BRC held by staking contract +// stakingBRCSupply = await brcContract.methods +// .balanceOf(STAKING_CONTRACT) +// .call(); + +// // load BRC-gBRC staking ratio +// stakingRatio = await stakingContract.methods.getRatioBtoG().call(); +// }; + +// const getAPR = async (brcStake, weight) => { +// if (Number(totalSupplyMultWeight) === 0) { +// const pool1SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(0).call() +// ).times(MODE1Weight); +// const pool2SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(1).call() +// ).times(MODE2Weight); +// const pool3SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(2).call() +// ).times(MODE3Weight); +// const pool4SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(3).call() +// ).times(MODE4Weight); +// const pool5SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(4).call() +// ).times(MODE5Weight); +// const pool6SupplyMultWeight = new BigNumber( +// await stakingContract.methods.getPoolSupply(5).call() +// ).times(MODE6Weight); +// totalSupplyMultWeight = new BigNumber(pool1SupplyMultWeight) +// .plus(pool2SupplyMultWeight) +// .plus(pool3SupplyMultWeight) +// .plus(pool4SupplyMultWeight) +// .plus(pool5SupplyMultWeight) +// .plus(pool6SupplyMultWeight); +// } +// // ((totalRewards * brcStake * weight ) / totalSupplyWeight ) / brcStake +// return new BigNumber(govBrincPerWeek) +// .times(brcStake) +// .times(weight) +// .div(totalSupplyMultWeight) +// .div(brcStake) +// .times(5200); +// }; + +// const getPoolData = async (pool) => { +// const _brcStake = await stakingContract.methods.getPoolSupply(pool).call(); +// const brcStake = new BigNumber(_brcStake.toString()); +// const gbrcStaked = new BigNumber(+stakingRatio).div(1e10).times(+brcStake); + +// const calApr = await getAPR(brcStake, getPoolWeight(pool)); +// return { +// apr: calApr, +// brcStaked: brcStake, +// gbrcStaked: pool < 3 ? 0 : gbrcStaked, +// }; +// }; + +// const getAPYAndSupply = async (pool) => { +// const { apr, brcStaked, gbrcStaked } = await getPoolData(pool); +// switch (pool) { +// case 0: +// return { +// apy: new BigNumber(apr / 100) +// .div(52) +// .plus(1) +// .pow(52) +// .minus(1) +// .times(100), +// brcStaked, +// gbrcStaked, +// }; +// case 1: +// return { +// apy: new BigNumber(apr / 100) +// .div(12) +// .plus(1) +// .pow(12) +// .minus(1) +// .times(100), +// brcStaked, +// gbrcStaked, +// }; +// case 2: +// return { +// apy: new BigNumber(apr / 100).div(4).plus(1).pow(4).minus(1).times(100), +// brcStaked, +// gbrcStaked, +// }; +// case 3: +// return { +// apy: new BigNumber(apr / 100) +// .div(52) +// .plus(1) +// .pow(52) +// .minus(1) +// .times(100), +// brcStaked, +// gbrcStaked, +// }; +// case 4: +// return { +// apy: new BigNumber(apr / 100) +// .div(12) +// .plus(1) +// .pow(12) +// .minus(1) +// .times(100), +// brcStaked, +// gbrcStaked, +// }; +// case 5: +// return { +// apy: new BigNumber(apr / 100).div(4).plus(1).pow(4).minus(1).times(100), +// brcStaked, +// gbrcStaked, +// }; +// default: +// return { +// apy: 0, +// brcStaked: 0, +// gbrcStaked: 0, +// }; +// } +// }; + +// const getPools = async () => { +// let apys = []; + +// // pool index starts from 3 to exclude BRC-only pools +// for (let stakePool = 3; stakePool < 6; stakePool++) { +// const { apy, brcStaked, gbrcStaked } = await getAPYAndSupply(stakePool); +// apys.push({ +// tvl: await getPoolTVL(stakePool, brcStaked, gbrcStaked), +// apy: apy.toString(), +// symbol: PoolNames[stakePool], +// poolId: 'pool' + stakePool, +// }); +// } +// return apys; +// }; + +// const buildPool = (entry) => { +// const newObj = { +// pool: entry.poolId + '-brinc-finance-staking', +// chain: 'Arbitrum', // chain where the pool is +// project: 'brinc-finance', // protocol (using the slug again) +// symbol: entry.symbol.split(' ')[0], +// poolMeta: entry.symbol.split(' ')[1], +// tvlUsd: parseInt(entry.tvl, 10), // number representing current USD TVL in pool +// apy: parseFloat(entry.apy), +// rewardTokens: [GBRC], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) +// underlyingTokens: [BRC, GBRC], // Array of underlying token addresses from a pool, +// }; +// return newObj; +// }; + +// async function main() { +// return loadEssentials().then((_) => { +// return getPools().then((pools) => { +// const data = pools.map((pool) => buildPool(pool)); +// return data; +// }); +// }); +// } + +// module.exports = { +// timetravel: false, +// apy: main, +// url: 'https://app.brinc.fi/stake', +// }; diff --git a/src/adaptors/brinc-finance/staking_abi.json b/src/adaptors/brinc-finance/staking_abi.json new file mode 100644 index 0000000000..a940646fc2 --- /dev/null +++ b/src/adaptors/brinc-finance/staking_abi.json @@ -0,0 +1,856 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum BrincStaking.StakeMode", + "name": "mode", + "type": "uint8" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldGovBrincPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newGovBrincPerBlock", + "type": "uint256" + } + ], + "name": "GovBrincPerBlockChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum BrincStaking.StakeMode", + "name": "mode", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldLockTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLockTime", + "type": "uint256" + } + ], + "name": "LockTimeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldRatioBrcToGov", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRatioBrcToGov", + "type": "uint256" + } + ], + "name": "RatioBrcToGovChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Resumed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TreasuryMint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum BrincStaking.StakeMode", + "name": "mode", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldWeight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWeight", + "type": "uint256" + } + ], + "name": "WeightChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "brincToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBrincTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGovBrincPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGovTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastRewardBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPausedBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + } + ], + "name": "getPoolAccGovBrincPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + } + ], + "name": "getPoolLockTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + } + ], + "name": "getPoolSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + } + ], + "name": "getPoolWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRatioBtoG", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStakeCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getUserInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "brcStakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gBrcStakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "enum BrincStaking.StakeMode", + "name": "mode", + "type": "uint8" + } + ], + "internalType": "struct BrincStaking.UserInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "govBrincPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "govBrincToken", + "outputs": [ + { + "internalType": "contract IBrincGovToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "_brincToken", + "type": "address" + }, + { + "internalType": "contract IBrincGovToken", + "name": "_brincGovToken", + "type": "address" + }, + { + "internalType": "contract IStakedBrincGovToken", + "name": "_stakedGovBrincToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_govBrincPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_ratioBrcToGov", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pausedBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "pendingRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "", + "type": "uint8" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accGovBrincPerShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "brcOnly", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ratioBrcToGov", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resume", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakedGovBrincToken", + "outputs": [ + { + "internalType": "contract IStakedBrincGovToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "totalRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryRewardBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_updatedGovBrincPerBlock", + "type": "uint256" + } + ], + "name": "updateGovBrincPerBlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_updatedLockTime", + "type": "uint256" + } + ], + "name": "updateLockTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_updatedRatioBrcToGov", + "type": "uint256" + } + ], + "name": "updateRatioBrcToGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum BrincStaking.StakeMode", + "name": "_mode", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "updateWeight", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "brcStakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gBrcStakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "enum BrincStaking.StakeMode", + "name": "mode", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/brunch/index.js b/src/adaptors/brunch/index.js new file mode 100644 index 0000000000..4f8972cf4e --- /dev/null +++ b/src/adaptors/brunch/index.js @@ -0,0 +1,83 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { formatUnits } = require("ethers").utils; + +const BUSD_ADDRESS = "0x602BaeaB9B0DE4a99C457cf1249088932AA04FaC"; +const SBUSD_ADDRESS = "0x451812019238785086CFAC408D8A64f06898f6f5"; +const SPOT_PRICE_ORACLE_ADDRESS = "0x095e7e8993A436adf87C90Da2314Da1EfB8F1bA0"; + +const CHAIN = "sonic"; + +const apy = async () => { + const [ + { output: rewardRatePerSecond }, + { output: rewardDistributionEnd }, + { output: totalReserves }, + { output: pendingReward }, + { output: balance }, + { output: [,underlyingPrice] } + ] = await Promise.all([ + sdk.api.abi.call({ + target: SBUSD_ADDRESS, + abi: "function rewardRatePerSecond() view returns (uint256)", + chain: CHAIN, + }), + sdk.api.abi.call({ + target: SBUSD_ADDRESS, + abi: "function rewardDistributionEnd() view returns (uint256)", + chain: CHAIN, + }), + sdk.api.abi.call({ + target: SBUSD_ADDRESS, + abi: "function totalReserves() view returns (uint256)", + chain: CHAIN, + }), + sdk.api.abi.call({ + target: SBUSD_ADDRESS, + abi: "function pendingReward() view returns (uint256)", + chain: CHAIN, + }), + sdk.api.abi.call({ + target: BUSD_ADDRESS, + abi: "function balanceOf(address) view returns (uint256)", + params: [SBUSD_ADDRESS], + chain: CHAIN, + }), + sdk.api.abi.call({ + target: SPOT_PRICE_ORACLE_ADDRESS, + abi: "function currentPrice() view returns (uint256,uint256)", + chain: CHAIN, + }), + ]); + + const tvl = BigInt(balance) - BigInt(pendingReward) - BigInt(totalReserves); + + // underlyingPrice has 8 decimals, BUSD is 18 decimals => scale to 10^26 + const tvlUsd = Number(formatUnits(tvl * BigInt(underlyingPrice), 26)); + + const now = Math.floor(Date.now() / 1000); + const apr = (tvl > 0n && rewardDistributionEnd > now) + ? formatUnits(BigInt(rewardRatePerSecond) * 86400n * 365n * 1_0000_0000n / tvl, 6) // scale factor = 1e6 + : 0; + + return [ + { + pool: SBUSD_ADDRESS, + chain: CHAIN, + project: 'brunch', + symbol: utils.formatSymbol('sbUSD'), + tvlUsd, + underlyingTokens: [BUSD_ADDRESS], + apyBase: apr, + apyReward: 0, + rewardTokens: null, + } + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://brunch.finance/stake', +}; diff --git a/src/adaptors/btcfi-cdp/index.js b/src/adaptors/btcfi-cdp/index.js new file mode 100644 index 0000000000..a7e25c3dad --- /dev/null +++ b/src/adaptors/btcfi-cdp/index.js @@ -0,0 +1,29 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const API_URL = + 'https://boost-gateway.btcfi.one/v1/products/5534c4c2-9cb4-4514-99f5-4c79a7030b27'; +const PROJECT_NAME = 'btcfi-cdp'; + +const apy = async () => { + const response = await axios.get(API_URL); + const data = response.data; + + const cbBTCPool = { + pool: `0x4F7aB59b5AC112970F5dD66D8a7ac505c8E5e08B-base`.toLowerCase(), + chain: utils.formatChain('base'), + project: PROJECT_NAME, + symbol: 'cbBTC', // cbBTC + tvlUsd: Number(data.tvl), + apyBase: Number(data.estimatedApyRate), + underlyingTokens: ['0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf'], // cbBTC address + url: 'https://btcfi.one/', + }; + + return [cbBTCPool]; +}; + +module.exports = { + apy: apy, + url: 'https://btcfi.one/', +}; diff --git a/src/adaptors/bunni/abis/BunniHub.json b/src/adaptors/bunni/abis/BunniHub.json new file mode 100644 index 0000000000..786cd426d4 --- /dev/null +++ b/src/adaptors/bunni/abis/BunniHub.json @@ -0,0 +1,813 @@ +[ + { + "inputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "factory_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "protocolFee_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Compound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "NewBunni", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "PayProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolFee", + "type": "uint256" + } + ], + "name": "SetProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "compound", + "outputs": [ + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "deployBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IBunniHub.DepositParams", + "name": "params", + "type": "tuple" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "setProtocolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokenList", + "type": "address[]" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct IBunniHub.WithdrawParams", + "name": "params", + "type": "tuple" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint128", + "name": "removedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/bunni/abis/BunniLens.json b/src/adaptors/bunni/abis/BunniLens.json new file mode 100644 index 0000000000..060d9ff454 --- /dev/null +++ b/src/adaptors/bunni/abis/BunniLens.json @@ -0,0 +1,119 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBunniHub", + "name": "hub_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { + "internalType": "contract IBunniHub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "pricePerFullShare", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/bunni/abis/ChildGauge.json b/src/adaptors/bunni/abis/ChildGauge.json new file mode 100644 index 0000000000..893387caa0 --- /dev/null +++ b/src/adaptors/bunni/abis/ChildGauge.json @@ -0,0 +1,1266 @@ +[ + { + "name": "Approval", + "inputs": [ + { + "name": "_owner", + "type": "address", + "indexed": true + }, + { + "name": "_spender", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Transfer", + "inputs": [ + { + "name": "_from", + "type": "address", + "indexed": true + }, + { + "name": "_to", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Deposit", + "inputs": [ + { + "name": "_user", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { + "name": "_user", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { + "name": "_user", + "type": "address", + "indexed": true + }, + { + "name": "_original_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "_original_supply", + "type": "uint256", + "indexed": false + }, + { + "name": "_working_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "_working_supply", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewTokenlessProduction", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewGaugeState", + "inputs": [ + { + "name": "new_gauge_state", + "type": "uint8", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewManager", + "inputs": [ + { + "name": "new_manager", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "DepositRewardToken", + "inputs": [ + { + "name": "reward_token", + "type": "address", + "indexed": true + }, + { + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Kick", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetRewardDistributor", + "inputs": [ + { + "name": "reward_token", + "type": "address", + "indexed": true + }, + { + "name": "distributor", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "AddReward", + "inputs": [ + { + "name": "reward_token", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "ClaimRewards", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true + }, + { + "name": "receiver", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetRewardsReceiver", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true + }, + { + "name": "receiver", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_factory", + "type": "address" + }, + { + "name": "_uniswap_poor_oracle", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_user", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_user", + "type": "address" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_user", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_user", + "type": "address" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_deadline", + "type": "uint256" + }, + { + "name": "_v", + "type": "uint8" + }, + { + "name": "_r", + "type": "bytes32" + }, + { + "name": "_s", + "type": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_added_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_subtracted_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "user_checkpoint", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { + "name": "_user", + "type": "address" + }, + { + "name": "_reward_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards_receiver", + "inputs": [ + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_reward", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_reward_distributor", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "kick", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit_reward_token", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_manager", + "inputs": [ + { + "name": "_manager", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "makeGaugePermissionless", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "killGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "unkillGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_tokenless_production", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "rescue_token", + "inputs": [ + { + "name": "_token", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "rescue_token", + "inputs": [ + { + "name": "_token", + "type": "address" + }, + { + "name": "_recipient", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "factory", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_lp_token", + "type": "address" + }, + { + "name": "_manager", + "type": "address" + }, + { + "name": "_position_key", + "type": "bytes32" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokenless_production", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_state", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lp_token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "manager", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "position_key", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_balances", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_supply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_fraction", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_tokenless_production_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "distributor", + "type": "address" + }, + { + "name": "period_finish", + "type": "uint256" + }, + { + "name": "rate", + "type": "uint256" + }, + { + "name": "last_update", + "type": "uint256" + }, + { + "name": "integral", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral_for", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/bunni/abis/GaugeController.json b/src/adaptors/bunni/abis/GaugeController.json new file mode 100644 index 0000000000..7a756dff26 --- /dev/null +++ b/src/adaptors/bunni/abis/GaugeController.json @@ -0,0 +1,825 @@ +[ + { + "name": "AddType", + "inputs": [ + { + "name": "name", + "type": "string", + "indexed": false + }, + { + "name": "type_id", + "type": "int128", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewTypeWeight", + "inputs": [ + { + "name": "type_id", + "type": "int128", + "indexed": false + }, + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + }, + { + "name": "total_weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewGaugeWeight", + "inputs": [ + { + "name": "gauge_address", + "type": "address", + "indexed": false + }, + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + }, + { + "name": "total_weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "VoteForGauge", + "inputs": [ + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "user", + "type": "address", + "indexed": false + }, + { + "name": "gauge_addr", + "type": "address", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewGauge", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": false + }, + { + "name": "gauge_type", + "type": "int128", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewPendingAdmin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "name": "new_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_voting_escrow", + "type": "address" + }, + { + "name": "_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voting_escrow", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_exists", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_types", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "gauge_type", + "type": "int128" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "gauge_type", + "type": "int128" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "checkpoint", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "checkpoint_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_relative_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_relative_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "gauge_relative_weight_write", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_type", + "inputs": [ + { + "name": "_name", + "type": "string" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_type", + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_type_weight", + "inputs": [ + { + "name": "type_id", + "type": "int128" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_gauge_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "vote_for_many_gauge_weights", + "inputs": [ + { + "name": "_gauge_addrs", + "type": "address[8]" + }, + { + "name": "_user_weight", + "type": "uint256[8]" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "vote_for_gauge_weights", + "inputs": [ + { + "name": "_gauge_addr", + "type": "address" + }, + { + "name": "_user_weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_gauge_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_type_weight", + "inputs": [ + { + "name": "type_id", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_total_weight", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_weights_sum_per_type", + "inputs": [ + { + "name": "type_id", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_pending_admin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_admin", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "pending_admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_gauge_types", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_gauges", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_type_names", + "inputs": [ + { + "name": "arg0", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauges", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "vote_user_slopes", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "slope", + "type": "uint256" + }, + { + "name": "power", + "type": "uint256" + }, + { + "name": "end", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "vote_user_power", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_user_vote", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_weight", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "bias", + "type": "uint256" + }, + { + "name": "slope", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_weight", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_sum", + "inputs": [ + { + "name": "arg0", + "type": "int128" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "bias", + "type": "uint256" + }, + { + "name": "slope", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_sum", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_total", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_total", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_type_weight", + "inputs": [ + { + "name": "arg0", + "type": "int128" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_type_weight", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + } + ] \ No newline at end of file diff --git a/src/adaptors/bunni/abis/LiquidityGauge.json b/src/adaptors/bunni/abis/LiquidityGauge.json new file mode 100644 index 0000000000..d1a6ace40a --- /dev/null +++ b/src/adaptors/bunni/abis/LiquidityGauge.json @@ -0,0 +1,1229 @@ +[ + { + "name": "Deposit", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true + }, + { + "name": "original_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "original_supply", + "type": "uint256", + "indexed": false + }, + { + "name": "working_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "working_supply", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Transfer", + "inputs": [ + { + "name": "_from", + "type": "address", + "indexed": true + }, + { + "name": "_to", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Approval", + "inputs": [ + { + "name": "_owner", + "type": "address", + "indexed": true + }, + { + "name": "_spender", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RewardDistributorUpdated", + "inputs": [ + { + "name": "reward_token", + "type": "address", + "indexed": true + }, + { + "name": "distributor", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RelativeWeightCapChanged", + "inputs": [ + { + "name": "new_relative_weight_cap", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewPendingAdmin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "name": "new_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewTokenlessProduction", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "minter", + "type": "address" + }, + { + "name": "uniswap_poor_oracle", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_addr", + "type": "address" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_deadline", + "type": "uint256" + }, + { + "name": "_v", + "type": "uint8" + }, + { + "name": "_r", + "type": "bytes32" + }, + { + "name": "_s", + "type": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_added_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_subtracted_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "user_checkpoint", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards_receiver", + "inputs": [ + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "kick", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit_reward_token", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_reward", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_reward_distributor", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "makeGaugePermissionless", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "killGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "unkillGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_pending_admin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_admin", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_tokenless_production", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { + "name": "_user", + "type": "address" + }, + { + "name": "_reward_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_epoch_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_lp_token", + "type": "address" + }, + { + "name": "relative_weight_cap", + "type": "uint256" + }, + { + "name": "_voting_escrow_delegation", + "type": "address" + }, + { + "name": "_admin", + "type": "address" + }, + { + "name": "_position_key", + "type": "bytes32" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setRelativeWeightCap", + "inputs": [ + { + "name": "relative_weight_cap", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "getRelativeWeightCap", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "getCappedRelativeWeight", + "inputs": [ + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "pure", + "type": "function", + "name": "getMaxRelativeWeightCap", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokenless_production", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "pending_admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voting_escrow_delegation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lp_token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_state", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "position_key", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "distributor", + "type": "address" + }, + { + "name": "period_finish", + "type": "uint256" + }, + { + "name": "rate", + "type": "uint256" + }, + { + "name": "last_update", + "type": "uint256" + }, + { + "name": "integral", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral_for", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_balances", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_supply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_fraction", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + } + ] \ No newline at end of file diff --git a/src/adaptors/bunni/abis/OptionsOracle.json b/src/adaptors/bunni/abis/OptionsOracle.json new file mode 100644 index 0000000000..0304042663 --- /dev/null +++ b/src/adaptors/bunni/abis/OptionsOracle.json @@ -0,0 +1,225 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBalancerTwapOracle", + "name": "balancerTwapOracle_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "uint16", + "name": "multiplier_", + "type": "uint16" + }, + { + "internalType": "uint56", + "name": "secs_", + "type": "uint56" + }, + { + "internalType": "uint56", + "name": "ago_", + "type": "uint56" + }, + { + "internalType": "uint128", + "name": "minPrice_", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BalancerOracle__TWAPOracleNotReady", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "multiplier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "secs", + "type": "uint56" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "ago", + "type": "uint56" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "minPrice", + "type": "uint128" + } + ], + "name": "SetParams", + "type": "event" + }, + { + "inputs": [], + "name": "ago", + "outputs": [ + { + "internalType": "uint56", + "name": "", + "type": "uint56" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "balancerTwapOracle", + "outputs": [ + { + "internalType": "contract IBalancerTwapOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPrice", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "multiplier", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "secs", + "outputs": [ + { + "internalType": "uint56", + "name": "", + "type": "uint56" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "multiplier_", + "type": "uint16" + }, + { + "internalType": "uint56", + "name": "secs_", + "type": "uint56" + }, + { + "internalType": "uint56", + "name": "ago_", + "type": "uint56" + }, + { + "internalType": "uint128", + "name": "minPrice_", + "type": "uint128" + } + ], + "name": "setParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/adaptors/bunni/abis/TokenAdmin.json b/src/adaptors/bunni/abis/TokenAdmin.json new file mode 100644 index 0000000000..a9364c8b69 --- /dev/null +++ b/src/adaptors/bunni/abis/TokenAdmin.json @@ -0,0 +1,390 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20Mintable", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "MiningParametersUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_RATE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_COEFFICIENT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "available_supply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "futureEpochTimeWrite", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "future_epoch_time_write", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAvailableSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFutureEpochTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInflationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMiningEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getToken", + "outputs": [ + { + "internalType": "contract IERC20Mintable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "mintableInTimeframe", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "mintable_in_timeframe", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startEpochTimeWrite", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start_epoch_time_write", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateMiningParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "update_mining_parameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/adaptors/bunni/index.js b/src/adaptors/bunni/index.js new file mode 100644 index 0000000000..d7a9deefcb --- /dev/null +++ b/src/adaptors/bunni/index.js @@ -0,0 +1,435 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); +const { request, gql } = require('graphql-request'); + +const hub = '0xb5087f95643a9a4069471a28d32c569d9bd57fe4'; +const lens = '0xb73f303472c4fd4ff3b9f59ce0f9b13e47fbfd19'; +const zeroAddress = '0x0000000000000000000000000000000000000000'; + +const admin = { + ethereum: '0x4cc39af0d46b0f66fd33778c6629a696bdc310a0', + polygon: '', + arbitrum: '', + optimism: '', +}; + +const controller = { + ethereum: '0x901c8aa6a61f74ac95e7f397e22a0ac7c1242218', + polygon: '', + arbitrum: '', + optimism: '', +}; + +const lit = { + ethereum: '0xfd0205066521550d7d7ab19da8f72bb004b4c341', + polygon: '', + arbitrum: '', + optimism: '', +}; + +const olit = { + ethereum: '0x627fee87d0d9d2c55098a06ac805db8f98b158aa', + polygon: '', + arbitrum: '0x0ffB33812FA5cd8bCE181Db3FD76E11935105B12', + optimism: '', +}; + +const oracle = { + ethereum: '0x9d43ccb1ad7e0081cc8a8f1fd54d16e54a637e30', + polygon: '', + arbitrum: '', + optimism: '', +}; + +const hubABI = require('./abis/BunniHub.json'); +const lensABI = require('./abis/BunniLens.json'); +const adminABI = require('./abis/TokenAdmin.json'); +const gaugeABI = require('./abis/LiquidityGauge.json'); +const childGaugeABI = require('./abis/ChildGauge.json'); +const controllerABI = require('./abis/GaugeController.json'); +const oracleABI = require('./abis/OptionsOracle.json'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + 'HH4HFj4rFnm5qnkb8MbEdP2V5eD9rZnLJE921YQAs7AV' + ), + polygon: sdk.graph.modifyEndpoint( + '7WkeneDon7GY3CdcZW3rsPi4pRfDthwe1nWGKX21dRgC' + ), +}; + +const query = gql` + { + bunniTokens(first: 1000, block: {number: }) { + id + address + liquidity + tickLower + tickUpper + pool { + id + fee + tick + token0 + token1 + liquidity + totalFeesToken0 + totalFeesToken1 + } + gauge { + address + } + } + } +`; + +const queryPrior = gql` + { + pools(first: 1000, block: {number: }) { + id + totalFeesToken0 + totalFeesToken1 + } + } +`; + +const apy = (apr, num_periods) => { + const periodic_rate = apr / num_periods / 100; + const apy = Math.pow(1 + periodic_rate, num_periods) - 1; + return apy * 100; +}; + +const topLvl = async (chainString, url, query, queryPrior, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + let [ + dataNow, + dataPrior, + { output: protocolFee }, + { output: inflationRate }, + { output: multiplier }, + ] = await Promise.all([ + request(url, query.replace('', block)), + request(url, queryPrior.replace('', blockPrior)), + sdk.api.abi.call({ + target: hub, + abi: hubABI.find((n) => n.name === 'protocolFee'), + chain: chainString, + }), + + admin['ethereum'] && + sdk.api.abi.call({ + target: admin['ethereum'], + abi: adminABI.find((n) => n.name === 'rate'), + chain: 'ethereum', + }), + oracle['ethereum'] && + sdk.api.abi.call({ + target: oracle['ethereum'], + abi: oracleABI.find((n) => n.name === 'multiplier'), + chain: 'ethereum', + }), + ]); + + dataNow = dataNow.bunniTokens; + dataPrior = dataPrior.pools; + protocolFee = protocolFee / 1e18; + inflationRate = inflationRate ? inflationRate / 1e18 : null; + multiplier = multiplier ? multiplier / 10000 : null; + + // create a list of unique tokens + let tokens = dataNow.reduce((tokens, b) => { + if (!tokens.includes(b.pool.token0)) tokens.push(b.pool.token0); + if (!tokens.includes(b.pool.token1)) tokens.push(b.pool.token1); + return tokens; + }, []); + + // add LIT to the token list (used for calculating oLIT price) + if (lit[chainString] && !tokens.includes(lit[chainString])) + tokens.push(lit[chainString]); + + // create of list of gauges + const gauges = dataNow.reduce((gauges, b) => { + if (b.gauge) gauges.push(b.gauge?.address); + return gauges; + }, []); + + const week = 604800 * 1000; + const this_period_timestamp = (Math.floor(Date.now() / week) * week) / 1000; + + const [ + { output: tokenSymbols }, + { output: tokenDecimals }, + { output: reserves }, + { output: shares }, + { output: gaugesWorkingSupply }, + { output: gaugesTokenlessProduction }, + { output: gaugesIsKilled }, + { output: gaugesRelativeWeight }, + { output: gaugesExists }, + { output: gaugesInflationRate }, + ] = await Promise.all([ + sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((token) => ({ target: token })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((token) => ({ target: token })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: lensABI.find((n) => n.name === 'getReserves'), + target: lens, + calls: dataNow.map((b) => ({ + params: [ + { pool: b.pool.id, tickLower: b.tickLower, tickUpper: b.tickUpper }, + ], + })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: lensABI.find((n) => n.name === 'pricePerFullShare'), + target: lens, + calls: dataNow.map((b) => ({ + params: [ + { pool: b.pool.id, tickLower: b.tickLower, tickUpper: b.tickUpper }, + ], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'working_supply'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'tokenless_production'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'is_killed'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + chainString == 'ethereum' && + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'getCappedRelativeWeight'), + calls: gauges.map((gauge) => ({ + target: gauge, + params: [this_period_timestamp], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: controllerABI.find((n) => n.name === 'gauge_exists'), + target: controller['ethereum'], + calls: gauges.map((gauge) => ({ params: [gauge] })), + chain: 'ethereum', + }), + chainString != 'ethereum' && + gauges.length && + sdk.api.abi.multiCall({ + abi: childGaugeABI.find((n) => n.name === 'inflation_rate'), + calls: gauges.map((gauge) => ({ + target: gauge, + params: [Math.floor(this_period_timestamp / 604800)], + })), + chain: chainString, + }), + ]); + + // fetch token prices + let keys = tokens.map((token) => `${chainString}:${token}`).join(','); + if (chainString != 'ethereum') + keys = keys.concat(`,ethereum:${lit['ethereum']}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${keys}`) + ).data.coins; + + // calculate the price of oLIT + let optionPrice = 0; + if (lit['ethereum']) { + const litPrice = prices[`ethereum:${lit['ethereum']}`] + ? prices[`ethereum:${lit['ethereum']}`].price + : 0; + optionPrice = litPrice * multiplier; + } + + let poolData = dataNow.map((b) => { + // reserve info + const reserve = reserves.find( + (r) => + r.input.params[0].pool == b.pool.id && + r.input.params[0].tickLower == b.tickLower && + r.input.params[0].tickUpper == b.tickUpper + ).output; + + // share info + const share = shares.find( + (s) => + s.input.params[0].pool == b.pool.id && + s.input.params[0].tickLower == b.tickLower && + s.input.params[0].tickUpper == b.tickUpper + ).output; + + // token0 info + const token0Decimals = tokenDecimals.find( + (d) => d.input.target == b.pool.token0 + ).output; + const token0Price = prices[`${chainString}:${b.pool.token0}`] + ? prices[`${chainString}:${b.pool.token0}`].price + : 0; + const token0Redeem = share.amount0 / Math.pow(10, token0Decimals); + const token0Reserve = reserve.reserve0 / Math.pow(10, token0Decimals); + const token0Symbol = tokenSymbols.find( + (s) => s.input.target == b.pool.token0 + ).output; + + // token1 info + const token1Decimals = tokenDecimals.find( + (d) => d.input.target == b.pool.token1 + ).output; + const token1Price = prices[`${chainString}:${b.pool.token1}`] + ? prices[`${chainString}:${b.pool.token1}`].price + : 0; + const token1Redeem = share.amount1 / Math.pow(10, token1Decimals); + const token1Reserve = reserve.reserve1 / Math.pow(10, token1Decimals); + const token1Symbol = tokenSymbols.find( + (s) => s.input.target == b.pool.token1 + ).output; + + // calculate swap fee apr + let baseApr = 0; + + const tick = parseInt(b.pool.tick); + const tickLower = parseInt(b.tickLower); + const tickUpper = parseInt(b.tickUpper); + const tvl = token0Reserve * token0Price + token1Reserve * token1Price; + + if ( + tvl > 0 && + parseInt(b.pool.liquidity) > 0 && + tickLower <= tick && + tick <= tickUpper + ) { + const prior = dataPrior.find((d) => d.id === b.pool.id); + + if (prior) { + const fee0 = + ((b.pool.totalFeesToken0 - prior.totalFeesToken0) / + Math.pow(10, token0Decimals)) * + token0Price; + const fee1 = + ((b.pool.totalFeesToken1 - prior.totalFeesToken1) / + Math.pow(10, token1Decimals)) * + token1Price; + const fee = Math.min(fee0, fee1) * 365; + baseApr = + ((fee * parseInt(b.liquidity)) / parseInt(b.pool.liquidity) / tvl) * + (1 - protocolFee) * + 100; + } + } + + // calculate reward apr + let rewardApr = null; + let rewardTokens = null; + + if (b.gauge) { + const exists = gaugesExists.find( + (g) => g.input.params[0] == b.gauge?.address + )?.output; + const killed = gaugesIsKilled.find( + (g) => g.input.target == b.gauge?.address + )?.output; + + // we only care about gauges that have been whitelisted and have not been killed + if (exists && !killed) { + const relativeWeight = gaugesRelativeWeight + ? gaugesRelativeWeight.find( + (g) => g.input.target == b.gauge?.address + ).output / 1e18 + : 0; + const tokenlessProduction = gaugesTokenlessProduction.find( + (g) => g.input.target == b.gauge?.address + )?.output; + const workingSupply = + gaugesWorkingSupply.find((g) => g.input.target == b.gauge?.address) + ?.output / 1e18; + + const gaugeInflationRate = + gaugesInflationRate && + gaugesInflationRate.find((g) => g.input.target == b.gauge?.address) + ?.output / 1e18; + const relativeInflation = gaugeInflationRate + ? gaugeInflationRate + : inflationRate * relativeWeight; + + // we only care about gauges that receive rewards (ie those that receive votes) + if (relativeInflation > 0) { + const bunniPrice = + token0Redeem * token0Price + token1Redeem * token1Price; + const annualRewardUSD = + relativeInflation * optionPrice * 86400 * 365; + + // if nothing has been staked, calculate what rewardApr would be if 1 wei was staked + const workingSupplyUSD = + (workingSupply > 0 ? workingSupply : 1e-18) * bunniPrice; + + if (workingSupplyUSD > 0) { + rewardApr = + (annualRewardUSD * tokenlessProduction) / workingSupplyUSD; + rewardTokens = [olit[chainString]]; + } + } + } + } + + return { + pool: b.address, + chain: utils.formatChain(chainString), + project: 'bunni', + symbol: `${token0Symbol}-${token1Symbol}`, + tvlUsd: token0Reserve * token0Price + token1Reserve * token1Price, + apyBase: apy(baseApr, 365), + ...(rewardApr && { apyReward: apy(rewardApr, 365) }), + ...(rewardTokens && { rewardTokens: rewardTokens }), + underlyingTokens: [b.pool.token0, b.pool.token1], + poolMeta: `${parseInt(b.pool.fee) / 10000}%`, + url: `https://bunni.pro/pools/${chainString}/${b.pool.id}/${b.address}`, + }; + }); + + return poolData; + } catch (e) { + console.log(e); + return []; + } +}; + +const main = async (timestamp = null) => { + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push(await topLvl(chain, url, query, queryPrior, timestamp)); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: `https://bunni.pro/pools`, +}; diff --git a/src/adaptors/burrow/index.ts b/src/adaptors/burrow/index.ts new file mode 100644 index 0000000000..6408710b9f --- /dev/null +++ b/src/adaptors/burrow/index.ts @@ -0,0 +1,42 @@ +const axios = require('axios'); + +async function commonCall(url, method, args = {}) { + const result = await axios({ + method: 'get', + url: url + method, + params: args, + }); + if (result.data.error) { + throw new Error(`${result.data.error.message}: ${result.data.error.data}`); + } + return result.data; +} + +function getBurrowStats() { + return commonCall('https://api.burrow.finance/get_rewards', ''); +} + +async function getBurrowFarms() { + const stats = await getBurrowStats(); + return stats.map((item) => ({ + pool: 'burrow-pool-' + item.token_id, + chain: 'NEAR', + project: 'burrow', + symbol: item.symbol, + tvlUsd: item.tvl_usd, + apyReward: item.apy_reward + item.apy_reward_tvl, + apyBase: item.apy_base, + underlyingTokens: [item.token_id], + rewardTokens: item.reward_tokens, + apyBaseBorrow: item.apy_base_borrow, + totalSupplyUsd: item.total_supply_usd, + totalBorrowUsd: item.total_borrow_usd, + ltv: item.ltv / 1e4, + })); +} + +module.exports = { + timetravel: false, + apy: getBurrowFarms, + url: 'https://app.burrow.cash/deposit/', +}; diff --git a/src/adaptors/bybit-staked-sol/index.js b/src/adaptors/bybit-staked-sol/index.js new file mode 100644 index 0000000000..ce1d31728b --- /dev/null +++ b/src/adaptors/bybit-staked-sol/index.js @@ -0,0 +1,35 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); +const utils = require('../utils'); + +const BBSOL_ADDRESS = 'Bybit2vBJGhPF52GBdNaQfUJ6ZpThSgHBobjWZpLPb4B'; +const priceKey = `solana:${BBSOL_ADDRESS}`; + +const apy = async () => { + const totalSupply = await getTotalSupply(BBSOL_ADDRESS); + + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const currentPrice = priceResponse.data.coins[priceKey].price; + + const bybitResponseBBSOL = await axios.get( + 'https://api2.bybit.com/spot/api/web3/staking/v3/pool/apys?poolId=77&span=1' + ); + const apys = bybitResponseBBSOL.data.result.apys; + const bbSolApy = Number(apys[apys.length - 1].apy); + + return [ + { + pool: BBSOL_ADDRESS, + chain: utils.formatChain('solana'), + project: 'bybit-staked-sol', + symbol: 'BBSOL', + tvlUsd: totalSupply * currentPrice, + apy: bbSolApy, + underlyingTokens: [BBSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://www.bybit.com/en/web3/staking/BybitSOL' }; diff --git a/src/adaptors/c3-exchange/axios.js b/src/adaptors/c3-exchange/axios.js new file mode 100644 index 0000000000..a7f81e67b1 --- /dev/null +++ b/src/adaptors/c3-exchange/axios.js @@ -0,0 +1,23 @@ +const axios = require('axios') + +const algoAPI = axios.create({ + baseURL: 'https://mainnet-idx.algonode.cloud', + timeout: 300000, +}) + +async function getGlobalState(appId) { + const response = await algoAPI.get(`/v2/applications/${appId}`) + const globalState = response.data.application.params['global-state'] + return globalState +} + +async function getBoxData(appId, boxId) { + const response = await algoAPI.get(`/v2/applications/${appId}/box?name=${boxId}`) + const data = Buffer.from(response.data.value, 'base64') + return data +} + +module.exports = { + getGlobalState, + getBoxData, +} \ No newline at end of file diff --git a/src/adaptors/c3-exchange/calculations.js b/src/adaptors/c3-exchange/calculations.js new file mode 100644 index 0000000000..d097bc4d8e --- /dev/null +++ b/src/adaptors/c3-exchange/calculations.js @@ -0,0 +1,95 @@ +const BigNumber = require('bignumber.js') + +const RATIO_ONE = 1_000n +const RATE_ONE = 1_000_000_000_000n +const PRICE_SCALE_FACTOR = 1_000_000_000_000n +const SECONDS_PER_YEAR = 60 * 60 * 24 * 365 + +// Calculates an exponential using bigints +function ratioExp(base, exponent) { + let result = RATE_ONE + let power = BigInt(base) + while (exponent > 0n) { + if (exponent & 1n) + result = result * power / RATE_ONE + power = power * power / RATE_ONE + exponent = exponent >> 1n + } + return result +} + +// Calculates the utilization rate of a pool +function calculateUtilizationRate(borrowed, liquidity) { + return liquidity === 0n ? 0n : borrowed * RATE_ONE / liquidity +} + +// Calculates the interest rate of the pool +function calculateInterestRate(poolRates, borrowed, liquidity) { + const { optimalUtilization, minRate, maxRate, optRate } = poolRates + const optimalUtilizationRate = optimalUtilization * RATE_ONE / RATIO_ONE + const utilizationRate = calculateUtilizationRate(borrowed, liquidity) + const interestRate = utilizationRate < optimalUtilizationRate ? + minRate + utilizationRate * (optRate - minRate) / optimalUtilizationRate : + optRate + (utilizationRate - optimalUtilizationRate) * (maxRate - optRate) / (RATE_ONE - optimalUtilizationRate) + + return interestRate +} + +// Calculate the new pool data given the old pool data and a relative time delta +function calculatePoolRates(poolData, relativeTime) { + const { borrowed, liquidity, borrowIndex, lendIndex, lastUpdateTime, poolRates } = poolData + + // Calculate accrued interest + const deltaTime = relativeTime - lastUpdateTime + const interestRateInSeconds = calculateInterestRate(poolRates, borrowed, liquidity) + const compoundingRate = ratioExp(RATE_ONE + interestRateInSeconds, deltaTime) + const accruedInterest = (compoundingRate - RATE_ONE) * borrowed / RATE_ONE + + // Calculate new pool data + const newBorrowed = borrowed + accruedInterest + const newLiquidity = liquidity + accruedInterest + const newBorrowIndex = borrowed === 0n ? RATE_ONE : borrowIndex * newBorrowed / borrowed + const newLendIndex = liquidity === 0n ? RATE_ONE : lendIndex * newLiquidity / liquidity + + return { newBorrowed, newLiquidity, newBorrowIndex, newLendIndex } +} + +// Annualizes a per-second interest raet into an APR +function annualizedInterestRate(interestRateInSeconds) { + const rateInBig = ratioExp(RATE_ONE + interestRateInSeconds, BigInt(SECONDS_PER_YEAR)) - RATE_ONE + const annualizedRate = new BigNumber(rateInBig.toString()).dividedBy(new BigNumber(RATE_ONE.toString())).toNumber() + return annualizedRate +} + +// Calculates borrow and lend using on-chain data and then applying time based +// interest offset to reflect contract activity more accurately. This follows the +// contract logic for interest calculation. +function calculateBorrowAndLendAPR(initTimestamp, poolData) { + const currentTimestamp = Math.floor(Date.now() / 1_000) + const relativeTime = BigInt(currentTimestamp - initTimestamp) + const poolRates = calculatePoolRates(poolData, relativeTime) + const utilizationRate = calculateUtilizationRate(poolRates.newBorrowed, poolRates.newLiquidity) + const borrowRateInSeconds = calculateInterestRate(poolData.poolRates, poolRates.newBorrowed, poolRates.newLiquidity) + const lendRateInSeconds = borrowRateInSeconds * utilizationRate / RATE_ONE + const borrowApr = annualizedInterestRate(borrowRateInSeconds) + const lendApr = annualizedInterestRate(lendRateInSeconds) + return { borrowApr, lendApr } +} + +// Calculates the TVL given price and pool state +function calculateTVL(price, borrowed, liquidity) { + const totalBorrowUsd = new BigNumber(price).times(new BigNumber(borrowed)).dividedBy(new BigNumber(PRICE_SCALE_FACTOR)).toNumber() + const totalSupplyUsd = new BigNumber(price).times(new BigNumber(liquidity)).dividedBy(new BigNumber(PRICE_SCALE_FACTOR)).toNumber() + const tvlUsd = totalSupplyUsd - totalBorrowUsd + + return { + tvlUsd, + totalBorrowUsd, + totalSupplyUsd, + } +} + +module.exports = { + calculateBorrowAndLendAPR, + calculateTVL, +} diff --git a/src/adaptors/c3-exchange/codec.js b/src/adaptors/c3-exchange/codec.js new file mode 100644 index 0000000000..93e04bd959 --- /dev/null +++ b/src/adaptors/c3-exchange/codec.js @@ -0,0 +1,177 @@ +const { formatSymbol, formatChain } = require('../utils') + +function decodeUint(value, index = 0, length = 8) { + let num = BigInt(0) + for (let i = 0; i < length; i++) { + num = (num << 8n) | BigInt(value[index++]) + } + return num +} + +function getSymbol(assetId) { + const symbolMap = { + 0: 'ALGO', + 893309613: 'AVAX', + 1058926737: 'BTC', + 891648844: 'BNB', + 1221549217: 'ARB', + 1007352535: 'USDC', + 887406851: 'ETH', + 887648583: 'SOL', + 1684682524: 'PYTH', + 1703994770: 'W', + } + + return symbolMap[assetId] ? formatSymbol(symbolMap[assetId]) : undefined +} + +function getUrl(assetId) { + const urlMap = { + 0: 'ALGO-USDC', + 893309613: 'AVAX-USDC', + 1058926737: 'BTC-USDC', + 1221549217: 'ARB-USDC', + 887406851: 'ETH-USDC', + 887648583: 'SOL-USDC', + 1684682524: 'PYTH-USDC', + 1703994770: 'W-USDC', + } + + const pairId = urlMap[assetId] + return pairId ? `https://c3.io/trade/${pairId}` : undefined +} + +function getChain(assetId) { + const chainMap = { + 0: 'algorand', //ALGO + 893309613: 'avax', //AVAX + 1058926737: 'bitcoin', //BTC + 891648844: 'bsc', //BNB + 1221549217: 'arbitrum', //ARB + 1007352535: 'avax', //USDC + 887406851: 'ethereum', //ETH + 887648583: 'solana', //SOL + 1684682524: 'solana', //PYTH + 1703994770: 'solana', //W + } + + return chainMap[assetId] ? formatChain(chainMap[assetId]) : undefined +} + +function getTokenAddress(assetId) { + const tokenAddressesMap = { + 0: ['0'], //ALGO - Algorand + 893309613: ['0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7'], //AVAX - Avax + 1058926737: ['0x2260fac5e5542a773aa44fbcfedf7c193bc2c599'], //BTC - Ethereum + 891648844: ['0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'], //BNB - bsc + 1221549217: ['0x912CE59144191C1204E64559FE8253a0e49E6548'], //ARB - Arbitrum + 1007352535: ['0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'], //USDC - Avax + 887406851: ['0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'], //ETH - Ethereum + 887648583: ['So11111111111111111111111111111111111111112'], //SOL - Solana + 1684682524: ['HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3'], //PYTH - Solana + 1703994770: ['85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ'], //W - Solana + } + + return tokenAddressesMap[assetId] +} + +function globalStateToBlob(globalState) { + // Collect the parts of the data block + const parts = [] + for (let i = 0; i < globalState.length; i++) { + const entry = globalState[i] + + const indexBuffer = Buffer.from(entry.key, 'base64') + if (indexBuffer.length !== 1) continue + + const index = indexBuffer[0] + if (index >= 64) continue + + const data = Buffer.from(entry.value.bytes, 'base64') + + parts[index] = data + } + + // Concatenate parts + const collectedData = Buffer.concat(parts) + + return collectedData +} + +function parsePricecasterData(count, data) { + // Parse out asset ID an normalized price for instruments from contract data + const priceMap = {} + let ptr = 0 + + const readUint = (length = 8) => { + const result = decodeUint(data, ptr, length) + ptr += length + return result + } + + for (let i = 0; i < count; i++) { + // Load relevant fields from data + const assetId = readUint() + const normalizedPrice = readUint() + ptr += 2*8 + 4 + 7*8 // Skip unused fields + + // Append data to map + priceMap[assetId] = normalizedPrice + } + + return priceMap +} + +function parseInstrumentData(count, data) { + // Parse out relevant info for instruments from contract data + const result = [] + let ptr = 0 + + const readUint = (length = 8) => { + const result = decodeUint(data, ptr, length) + ptr += length + return result + } + + for (let i = 0; i < count; i++) { + // Decode relevant fields from instrument data + const assetId = readUint() + ptr += 4*2 // Skip liquidation related fields + const lastUpdateTime = readUint(4) + const borrowIndex = readUint() + const lendIndex = readUint() + const optimalUtilization = readUint(2) + const minRate = readUint() + const optRate = readUint() + const maxRate = readUint() + const borrowed = readUint() + const liquidity = readUint() + + result.push({ + assetId, + lastUpdateTime, + borrowIndex, + lendIndex, + borrowed, + liquidity, + poolRates: { + optimalUtilization, + minRate, + optRate, + maxRate, + } + }) + } + + return result +} + +module.exports = { + getSymbol, + getUrl, + getChain, + getTokenAddress, + globalStateToBlob, + parsePricecasterData, + parseInstrumentData, +} diff --git a/src/adaptors/c3-exchange/getter.js b/src/adaptors/c3-exchange/getter.js new file mode 100644 index 0000000000..05f956d61f --- /dev/null +++ b/src/adaptors/c3-exchange/getter.js @@ -0,0 +1,38 @@ +const { globalStateToBlob, parsePricecasterData, parseInstrumentData } = require('./codec') +const { getGlobalState, getBoxData } = require('./axios') + +const CORE_APP_ID = 1257259627 + +const TAG_INSTRUMENT_COUNT = Buffer.from('c').toString('base64') +const TAG_INIT_TIMESTAMP = Buffer.from('t').toString('base64') +const TAG_PRICECASTER_ID = Buffer.from('p').toString('base64') +const INSTRUMENT_BOX_ID = 'str:i' + +async function getPriceMap(coreState) { + const pricecasterState = await getGlobalState(coreState.pricecasterId) + const priceData = globalStateToBlob(pricecasterState) + const result = parsePricecasterData(coreState.instrumentCount, priceData) + return result +} + +async function getCoreData() { + const coreState = await getGlobalState(CORE_APP_ID) + const instrumentCount = coreState.find((x) => x.key == TAG_INSTRUMENT_COUNT).value.uint + const initTimestamp = coreState.find((x) => x.key == TAG_INIT_TIMESTAMP).value.uint + const pricecasterId = coreState.find((x) => x.key == TAG_PRICECASTER_ID).value.uint + + const boxData = await getBoxData(CORE_APP_ID, INSTRUMENT_BOX_ID) + const instruments = parseInstrumentData(instrumentCount, boxData) + + return { + instrumentCount, + initTimestamp, + pricecasterId, + instruments, + } +} + +module.exports = { + getPriceMap, + getGlobalData: getCoreData, +} diff --git a/src/adaptors/c3-exchange/index.js b/src/adaptors/c3-exchange/index.js new file mode 100644 index 0000000000..0ca434c21f --- /dev/null +++ b/src/adaptors/c3-exchange/index.js @@ -0,0 +1,51 @@ +const { getGlobalData, getInstrumentData, getPriceMap } = require('./getter') +const { getSymbol, getUrl, getChain, getTokenAddress } = require('./codec') +const { calculateTVL, calculateBorrowAndLendAPR } = require('./calculations') + +function translateInstrumentData(initTimestamp, priceData, instrument) { + // Load token name, chain and price + const symbol = getSymbol(instrument.assetId) + const chain = getChain(instrument.assetId) + const price = priceData[instrument.assetId] + if (symbol === undefined || chain === undefined || price === undefined) return undefined + + // Calculate fields + const { tvlUsd, totalBorrowUsd, totalSupplyUsd } = calculateTVL(price, instrument.borrowed, instrument.liquidity) + const { borrowApr, lendApr } = calculateBorrowAndLendAPR(initTimestamp, instrument) + + return { + pool: `${instrument.assetId}-algorand`, + chain, + project: 'c3-exchange', + symbol, + tvlUsd, + apyBase: lendApr * 100, + underlyingTokens: getTokenAddress(instrument.assetId), + apyBaseBorrow: borrowApr * 100, + totalSupplyUsd, + totalBorrowUsd, + url: getUrl(instrument.assetId), + // apyReward?: number + // rewardTokens?: Array + // poolMeta?: string + // apyRewardBorrow?: number; + // ltv?: number + } +} + +async function apy() { + // Load relevant on-chain data + const globalData = await getGlobalData() + const priceData = await getPriceMap(globalData) + const result = globalData.instruments + .map((x) => translateInstrumentData(globalData.initTimestamp, priceData, x)) + .filter((x) => x !== undefined) + + return result +} + +module.exports = { + timetravel: false, + apy, + url: 'https://c3.io/earn', +} diff --git a/src/adaptors/cadabra-finance/index.js b/src/adaptors/cadabra-finance/index.js new file mode 100644 index 0000000000..d312a1e6a9 --- /dev/null +++ b/src/adaptors/cadabra-finance/index.js @@ -0,0 +1,201 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const axios = require('axios'); + +const cadabraConfig = [ + { + chain: 'bsc', + abra: '0xcA1c644704feBf4ab81f85daca488d1623C28e63', + lens: '0x2A479CFf64574Ed192f42509a205e3eb94Dc258C', + wrappersLens: '0x08639AE6D35105820fE708770158C482e4257d85', + }, + { + chain: 'arbitrum', + abra: '0x65114046C6e73AF794308547124aD5C8dcE3be6F', + wrappersLens: '0xAb8185196B53118468765E8AEB526A20770ae329', + }, + { + chain: 'sonic', + abra: '0xcA1c644704feBf4ab81f85daca488d1623C28e63', + wrappersLens: '0x0385aD4E3CA6a770165AeA4693421Dd4D9bCCb4e', + }, +] + +const networkMapping = { + 1: 'ethereum', + 10: 'optimism', + 25: 'cronos', + 56: 'bsc', + 100: 'gnosis', + 122: 'fuse', + 128: 'heco', + 137: 'polygon', + 146: 'sonic', + 169: 'manta', + 250: 'fantom', + 252: 'fraxtal', + 324: 'zksync', + 1088: 'metis', + 1101: 'polygon_zkevm', + 1284: 'moonbeam', + 1285: 'moonriver', + 2222: 'kava', + 5000: 'mantle', + 7700: 'canto', + 8453: 'base', + 34443: 'mode', + 42161: 'arbitrum', + 42220: 'celo', + 42262: 'oasis', + 43114: 'avalanche', + 59144: 'linea', + 1313161554: 'aurora', + 1666600000: 'harmony', +}; + +const main = async () => { + let allTokens = new Set(); + let wrapperInfoByChain = new Map(); + + for (const config of cadabraConfig) { + let wrappers = await collectWrappers(config.wrappersLens, config.chain) + const result = ( + await sdk.api.abi.multiCall({ + abi: 'function reserves() view returns(address[] memory, uint256[] memory)', + calls: wrappers.map((w) => ({target:w})), + chain: config.chain + }) + ).output + + result.forEach((out )=> { + let tokens = out.output[0].map((t) => chainToken(config.chain, t)) + tokens.forEach(t => allTokens.add(t)) + wrapperInfoByChain[chainToken(config.chain, out.input.target)] = { + tokens: tokens, + amounts: out.output[1], + } + }) + + if (typeof config.lens !== 'undefined') { + let token0 = (await sdk.api.abi.call({ + abi: 'function token0() view returns(address)', + target: config.lens, + chain: config.chain + })).output + token0 = chainToken(config.chain, token0) + let token1 = (await sdk.api.abi.call({ + abi: 'function token1() view returns(address)', + target: config.lens, + chain: config.chain + })).output + token1 = chainToken(config.chain, token1) + const frp = (await sdk.api.abi.call({ + abi: 'function fullRangePair() view returns(address)', + target: config.lens, + chain: config.chain + })).output; + + const [frpReserve0, frpReserve1] = (await sdk.api.abi.call({ + abi: 'function fullRangePairReserves()\n' + + ' view\n' + + ' returns (uint256 reserve0, uint256 reserve1)', + target: config.lens, + chain: config.chain + })).output; + + allTokens.add(token0) + allTokens.add(token1) + + wrapperInfoByChain[chainToken(config.chain, frp)] = { + tokens: [token0, token1], + amounts: [frpReserve0, frpReserve1], + } + } + } + + let prices = await getPrices(Array.from(allTokens)); + return await collectFinalInfo(wrapperInfoByChain, prices) +}; + +async function collectFinalInfo(wrapperInfoByChain, prices){ + const strategies = await utils.getData( + 'https://app.cadabra.finance/api/system/strategies' + ); + + const abraByChain = new Map() + cadabraConfig.forEach(config => abraByChain[config.chain] = config.abra) + + return Object.values(strategies).filter(pool => !pool.isTestStrategy).map((pool) => { + const apyReward = Number(pool.apr) * 100; + const chain = networkMapping[pool.chainId] + + const tokens = pool.tokens.map(p => p.address) + const tokensSymbol = pool.tokens.map(p => p.symbol) + + return { + pool: `cadabra-${pool.id}-${chain}`.toLowerCase(), + chain: chain, + project: 'cadabra-finance', + symbol: tokensSymbol.join('-'), + tvlUsd: calculateTvl(chain, pool.adapters, wrapperInfoByChain, prices), + apyReward, + url: `https://app.cadabra.finance/strategies/${pool.id.toLowerCase()}/${pool.chainId}`, + rewardTokens: [abraByChain[chain]], + underlyingTokens: tokens, + }; + }); +} + +function calculateTvl(chain, adapters, wrapperInfoByChain, prices) { + let totalTvl = 0 + + for (let adapter of adapters) { + let address = chainToken(chain, adapter.address); + let info = wrapperInfoByChain[address] + + for (let i = 0; i < info.tokens.length; i++) { + let token = info.tokens[i] + let amount = info.amounts[i] + let price = prices[token] + + totalTvl += amount / 10 ** price.decimals * price.price + } + } + + return totalTvl +} + +async function getPrices(allTokens){ + let results = {}; + if (allTokens.length > 0) { + for (let i = 0; i < allTokens.length; i += 100) { + const { + data: { coins }, + } = await axios.get( + `https://coins.llama.fi/prices/current/${allTokens.slice(i, i + 100)}` + ); + for (const key of Object.keys(coins)) { + results[key] = coins[key]; + } + } + } + return results; +} + +function chainToken(chain, token) { + return (chain + ':' + token).toLowerCase() +} + +async function collectWrappers(wrappersLens, chain) { + return (await sdk.api.abi.call({ + abi: 'function wrappers() view returns(address[] memory)', + target: wrappersLens, + chain: chain + })).output; +} + +module.exports = { + timetravel: false, + apy: main, +}; \ No newline at end of file diff --git a/src/adaptors/camelot-v2/factory.js b/src/adaptors/camelot-v2/factory.js new file mode 100644 index 0000000000..3ba1439aae --- /dev/null +++ b/src/adaptors/camelot-v2/factory.js @@ -0,0 +1,348 @@ +module.exports = [ + { + inputs: [{ internalType: 'address', name: 'feeTo_', type: 'address' }], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'FeePercentOwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevFeeTo', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newFeeTo', + type: 'address', + }, + ], + name: 'FeeToTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'prevOwnerFeeShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'ownerFeeShare', + type: 'uint256', + }, + ], + name: 'OwnerFeeShareUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token0', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token1', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'pair', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'length', + type: 'uint256', + }, + ], + name: 'PairCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'referrer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'prevReferrerFeeShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'referrerFeeShare', + type: 'uint256', + }, + ], + name: 'ReferrerFeeShareUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'SetStableOwnershipTransferred', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'OWNER_FEE_SHARE_MAX', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'REFERER_FEE_SHARE_MAX', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allPairs', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'allPairsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tokenA', type: 'address' }, + { internalType: 'address', name: 'tokenB', type: 'address' }, + ], + name: 'createPair', + outputs: [{ internalType: 'address', name: 'pair', type: 'address' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feeInfo', + outputs: [ + { internalType: 'uint256', name: '_ownerFeeShare', type: 'uint256' }, + { internalType: 'address', name: '_feeTo', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feePercentOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feeTo', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'getPair', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'ownerFeeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'referrersFeeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_feePercentOwner', type: 'address' }, + ], + name: 'setFeePercentOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: '_feeTo', type: 'address' }], + name: 'setFeeTo', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'setOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'newOwnerFeeShare', type: 'uint256' }, + ], + name: 'setOwnerFeeShare', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'referrer', type: 'address' }, + { internalType: 'uint256', name: 'referrerFeeShare', type: 'uint256' }, + ], + name: 'setReferrerFeeShare', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_setStableOwner', type: 'address' }, + ], + name: 'setSetStableOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'setStableOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/camelot-v2/index.js b/src/adaptors/camelot-v2/index.js new file mode 100644 index 0000000000..dd146d6d2f --- /dev/null +++ b/src/adaptors/camelot-v2/index.js @@ -0,0 +1,241 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const masterchefAbi = require('./masterchef'); +const stakingPositionAbi = require('./stakingPosition'); +const factoryAbi = require('./factory'); +const lp = require('./lp'); +const lpAbi = require('./lp'); +const axios = require('axios'); + +const masterchef = '0x55401A4F396b3655f66bf6948A1A4DC61Dfc21f4'; +const factory = '0x6EcCab422D763aC031210895C81787E87B43A652'; +const GRAIL = '0x3d9907f9a368ad0a51be60f7da3b97cf940982d8'; + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint( + '8zagLSufxk5cVhzkzai3tyABwJh53zxn9tmUYJcJxijG' +); + +const query = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + reserve0 + reserve1 + token0 { + id + symbol + } + token1 { + id + symbol + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + // --- fee tier + const allPairsLength = ( + await sdk.api.abi.call({ + target: factory, + abi: factoryAbi.find((m) => m.name === 'allPairsLength'), + chain: chainString, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: factory, + params: [i], + })), + abi: factoryAbi.find((m) => m.name === 'allPairs'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const token0FeePercent = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: lpAbi.find((m) => m.name === 'token0FeePercent'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const token1FeePercent = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: lpAbi.find((m) => m.name === 'token1FeePercent'), + chain: chainString, + }) + ).output.map((o) => o.output); + + // --- rewards + const poolsLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolsLength'), + chain: chainString, + }) + ).output; + + const pools = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'getPoolAddressByIndex'), + chain: chainString, + }) + ).output.map((o) => o.output); + + let poolInfo = ( + await sdk.api.abi.multiCall({ + calls: pools.map((i) => ({ + target: i, + })), + abi: stakingPositionAbi.find((m) => m.name === 'getPoolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const lpTokens = poolInfo.map((p) => p.lpToken); + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((i) => ({ + target: i, + })), + abi: lp.find((m) => m.name === 'totalSupply'), + chain: chainString, + }) + ).output.map((o) => o.output); + + poolInfo = poolInfo.map((p, i) => ({ ...p, totalSupply: totalSupply[i] })); + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPoint'), + chain: chainString, + }) + ).output; + + const grailPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'emissionRate'), + chain: chainString, + }) + ).output / 1e18; + + const priceKey = `arbitrum:${GRAIL}`; + const grailPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const grailPerYearUsd = grailPerSec * 86400 * 365 * grailPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + data = await utils.tvl(data, chainString); + + // add fee tier + data = data.map((p) => { + const idx = allPairs.findIndex( + (i) => i.toLowerCase() === p.id.toLowerCase() + ); + const feeAvg = + ((Number(token0FeePercent[idx]) + Number(token1FeePercent[idx])) / 2) * + 10; + return { ...p, feeTier: feeAvg }; + }); + + // calculate apy + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + // build pool objects + data = data.map((p) => { + const pi = poolInfo.find( + (pi) => pi.lpToken.toLowerCase() === p.id?.toLowerCase() + ); + + const farmReserveRatio = pi?.lpSupplyWithMultiplier / pi?.totalSupply; + + const apyReward = + (((pi?.allocPoint / totalAllocPoint) * grailPerYearUsd) / + (p.totalValueLockedUSD * farmReserveRatio)) * + 100; + + // rewards are 20% in liquid grail and 80% in non-transferable xgrail (which can be used to boost though) + // gonna report 20% grail only + + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'camelot-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward: apyReward * 0.2, + underlyingTokens: [p.token0.id, p.token1.id], + rewardTokens: apyReward > 0 ? [GRAIL] : [], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([topLvl('arbitrum', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://app.camelot.exchange/liquidity', +}; diff --git a/src/adaptors/camelot-v2/lp.js b/src/adaptors/camelot-v2/lp.js new file mode 100644 index 0000000000..65d0d5cb14 --- /dev/null +++ b/src/adaptors/camelot-v2/lp.js @@ -0,0 +1,626 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { indexed: false, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'DrainWrongToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'token0FeePercent', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'token1FeePercent', + type: 'uint16', + }, + ], + name: 'FeePercentUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'SetPairTypeImmutable', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'prevStableSwap', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'stableSwap', + type: 'bool', + }, + ], + name: 'SetStableSwap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Skim', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'FEE_DENOMINATOR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MAX_FEE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'drainWrongToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + ], + name: 'getAmountOut', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint16', name: '_token0FeePercent', type: 'uint16' }, + { internalType: 'uint16', name: '_token1FeePercent', type: 'uint16' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pairTypeImmutable', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'precisionMultiplier0', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'precisionMultiplier1', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint16', name: 'newToken0FeePercent', type: 'uint16' }, + { internalType: 'uint16', name: 'newToken1FeePercent', type: 'uint16' }, + ], + name: 'setFeePercent', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'setPairTypeImmutable', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bool', name: 'stable', type: 'bool' }, + { internalType: 'uint112', name: 'expectedReserve0', type: 'uint112' }, + { internalType: 'uint112', name: 'expectedReserve1', type: 'uint112' }, + ], + name: 'setStableSwap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'stableSwap', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + { internalType: 'address', name: 'referrer', type: 'address' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0FeePercent', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1FeePercent', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/camelot-v2/masterchef.js b/src/adaptors/camelot-v2/masterchef.js new file mode 100644 index 0000000000..3ba12d541a --- /dev/null +++ b/src/adaptors/camelot-v2/masterchef.js @@ -0,0 +1,318 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IGrailTokenV2', + name: 'grailToken_', + type: 'address', + }, + { internalType: 'uint256', name: 'startTime_', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ClaimRewards', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + ], + name: 'PoolAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + ], + name: 'PoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reserve', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + ], + name: 'PoolUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'emergencyUnlock', + type: 'bool', + }, + ], + name: 'SetEmergencyUnlock', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousYieldBooster', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newYieldBooster', + type: 'address', + }, + ], + name: 'SetYieldBooster', + type: 'event', + }, + { + inputs: [], + name: 'activePoolsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract INFTPool', name: 'nftPool', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'bool', name: 'withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'claimRewards', + outputs: [ + { internalType: 'uint256', name: 'rewardsAmount', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyUnlock', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emissionRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getActivePoolAddressByIndex', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getPoolAddressByIndex', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'poolAddress_', type: 'address' }, + ], + name: 'getPoolInfo', + outputs: [ + { internalType: 'address', name: 'poolAddress', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'reserve', type: 'uint256' }, + { internalType: 'uint256', name: 'poolEmissionRate', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'grailToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'poolAddress', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'bool', name: 'withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'emergencyUnlock_', type: 'bool' }], + name: 'setEmergencyUnlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IYieldBooster', + name: 'yieldBooster_', + type: 'address', + }, + ], + name: 'setYieldBooster', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'nftPool', type: 'address' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'yieldBooster', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/camelot-v2/stakingPosition.js b/src/adaptors/camelot-v2/stakingPosition.js new file mode 100644 index 0000000000..afdc34f103 --- /dev/null +++ b/src/adaptors/camelot-v2/stakingPosition.js @@ -0,0 +1,909 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'AddToPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'approved', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockDuration', + type: 'uint256', + }, + ], + name: 'CreatePosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { indexed: false, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'pending', + type: 'uint256', + }, + ], + name: 'HarvestPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockDuration', + type: 'uint256', + }, + ], + name: 'LockPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenIds', + type: 'uint256[]', + }, + ], + name: 'MergePositions', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accRewardsPerShare', + type: 'uint256', + }, + ], + name: 'PoolUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'boostPoints', + type: 'uint256', + }, + ], + name: 'SetBoost', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'maxGlobalMultiplier', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'maxBoostMultiplier', + type: 'uint256', + }, + ], + name: 'SetBoostMultiplierSettings', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'emergencyUnlock', + type: 'bool', + }, + ], + name: 'SetEmergencyUnlock', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'maxLockDuration', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'maxLockMultiplier', + type: 'uint256', + }, + ], + name: 'SetLockMultiplierSettings', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'operator', + type: 'address', + }, + ], + name: 'SetOperator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'isAdded', type: 'bool' }, + ], + name: 'SetUnlockOperator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'xGrailRewardsShare', + type: 'uint256', + }, + ], + name: 'SetXGrailRewardsShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'splitAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTokenId', + type: 'uint256', + }, + ], + name: 'SplitPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawFromPosition', + type: 'event', + }, + { + inputs: [], + name: 'MAX_BOOST_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_GLOBAL_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_LOCK_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amountToAdd', type: 'uint256' }, + ], + name: 'addToPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseURI', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'boost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'createPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyUnlock', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'exists', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'boostPoints', type: 'uint256' }, + ], + name: 'getMultiplierByBoostPoints', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'getMultiplierByLockDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getMultiplierSettings', + outputs: [ + { internalType: 'uint256', name: 'maxGlobalMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxBoostMultiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPoolInfo', + outputs: [ + { internalType: 'address', name: 'lpToken', type: 'address' }, + { internalType: 'address', name: 'grailToken', type: 'address' }, + { internalType: 'address', name: 'xGrailToken', type: 'address' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardsPerShare', type: 'uint256' }, + { internalType: 'uint256', name: 'lpSupply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lpSupplyWithMultiplier', + type: 'uint256', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getStakingPosition', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'uint256', + name: 'amountWithMultiplier', + type: 'uint256', + }, + { internalType: 'uint256', name: 'startLockTime', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'lockMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'boostPoints', type: 'uint256' }, + { internalType: 'uint256', name: 'totalMultiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'harvestPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvestPositionTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'tokenIds', type: 'uint256[]' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvestPositionsTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'hasDeposits', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ICamelotMaster', + name: 'master_', + type: 'address', + }, + { internalType: 'contract IERC20', name: 'grailToken', type: 'address' }, + { + internalType: 'contract IXGrailToken', + name: 'xGrailToken', + type: 'address', + }, + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'initialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_operator', type: 'address' }], + name: 'isUnlockOperator', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isUnlocked', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastTokenId', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'lockPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'master', + outputs: [ + { internalType: 'contract ICamelotMaster', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'tokenIds', type: 'uint256[]' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'mergePositions', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'operator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'pendingRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'renewLockPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'bytes', name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'operator', type: 'address' }, + { internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'maxGlobalMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxBoostMultiplier', type: 'uint256' }, + ], + name: 'setBoostMultiplierSettings', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'emergencyUnlock_', type: 'bool' }], + name: 'setEmergencyUnlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'maxLockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockMultiplier', type: 'uint256' }, + ], + name: 'setLockMultiplierSettings', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator_', type: 'address' }], + name: 'setOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_operator', type: 'address' }, + { internalType: 'bool', name: 'add', type: 'bool' }, + ], + name: 'setUnlockOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'xGrailRewardsShare_', type: 'uint256' }, + ], + name: 'setXGrailRewardsShare', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'splitAmount', type: 'uint256' }, + ], + name: 'splitPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'unboost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'unlockOperator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unlockOperatorsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amountToWithdraw', type: 'uint256' }, + ], + name: 'withdrawFromPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'xGrailRewardsShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'yieldBooster', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/camelot-v3/index.js b/src/adaptors/camelot-v3/index.js new file mode 100644 index 0000000000..95ec344e6f --- /dev/null +++ b/src/adaptors/camelot-v3/index.js @@ -0,0 +1,137 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint( + '3utanEBA9nqMjPnuQP1vMCCys6enSM3EawBpKTVwnUw2' +); + +const query = gql` + { + pools(first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + token0 { + symbol + id + decimals + } + token1 { + id + symbol + decimals + } + reserve0: totalValueLockedToken0 + reserve1: totalValueLockedToken1 + feeOtZ + feeZtO + + } + } +`; + +const queryPrior = gql` + { + pools(first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pools; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pools; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pools; + + // subgraph resever values are completely wrong + const balanceCalls = []; + for (const pool of data) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + data = data.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + data = await utils.tvl(data, chainString); + + data = data.map((p) => ({ + ...p, + feeTier: (Number(p.feeOtZ) + Number(p.feeZtO)) / 2, + })); + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + data = data.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'camelot-v3', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens: [p.token0.id, p.token1.id], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + url: `https://app.camelot.exchange/pools/${p.id}`, + }; + }); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([topLvl('arbitrum', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: main, +}; diff --git a/src/adaptors/canto-lending/abis.json b/src/adaptors/canto-lending/abis.json new file mode 100644 index 0000000000..e2e3cf7246 --- /dev/null +++ b/src/adaptors/canto-lending/abis.json @@ -0,0 +1,309 @@ +{ + "getAllMarkets": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address[]", + "name": "", + "internalType": "contract CToken[]" + } + ], + "name": "getAllMarkets", + "inputs": [] + }, + "markets": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "bool", + "name": "isListed", + "internalType": "bool" + }, + { + "type": "uint256", + "name": "collateralFactorMantissa", + "internalType": "uint256" + }, + { + "type": "bool", + "name": "isComped", + "internalType": "bool" + } + ], + "name": "markets", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + "compSpeeds": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "compSpeeds", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + "compSupplySpeeds": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "compSupplySpeeds", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + "compBorrowSpeeds": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "compBorrowSpeeds", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + "getCash": { + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalBorrows": { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalReserves": { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "borrowRatePerBlock": { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "supplyRatePerBlock": { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "underlying": { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + "oracle": { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract PriceOracle" + } + ], + "name": "oracle", + "inputs": [] + }, + "getUnderlyingPrice": { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "_pToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "token0": { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "token1": { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "getReserves": { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "totalSupply": { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/canto-lending/index.js b/src/adaptors/canto-lending/index.js new file mode 100644 index 0000000000..5a9d0a9198 --- /dev/null +++ b/src/adaptors/canto-lending/index.js @@ -0,0 +1,317 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const abi = require('./abis.json'); + +const utils = require('../utils'); + +const unitroller = '0x5E23dC409Fc2F832f83CEc191E245A191a4bCc5C'; +const WCANTO = '0x826551890Dc65655a0Aceca109aB11AbDbD7a07B'; + +const getOutput = ({ output }) => output.map(({ output }) => output); + +const poolInfo = async (chain) => { + const allMarkets = await sdk.api.abi.call({ + target: unitroller, + chain, + abi: abi.getAllMarkets, + }); + + const yieldMarkets = allMarkets.output.map((pool) => { + return { pool }; + }); + + const [markets, compSupplySpeeds, compBorrowSpeeds] = await Promise.all( + ['markets', 'compSupplySpeeds', 'compBorrowSpeeds'].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + target: unitroller, + calls: yieldMarkets.map((pool) => ({ + params: pool.pool, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + const collateralFactor = markets.map((data) => data.collateralFactorMantissa); + + const [ + borrowRatePerBlock, + supplyRatePerBlock, + getCash, + totalBorrows, + totalReserves, + underlyingToken, + tokenSymbol, + ] = await Promise.all( + [ + 'borrowRatePerBlock', + 'supplyRatePerBlock', + 'getCash', + 'totalBorrows', + 'totalReserves', + 'underlying', + 'symbol', + ].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: yieldMarkets.map((address) => ({ + target: address.pool, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + underlyingToken.find((token, index, arr) => { + if (token === null) arr[index] = WCANTO; + }); + + const [underlyingTokenDecimals, underlyingTokenSymbol] = await Promise.all( + ['decimals', 'symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: underlyingToken.map((token) => ({ + target: token, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + + underlyingTokenDecimals.map((decimal, i, arr) => { + arr[i] = Math.pow(10, Number(decimal)); + }); + + const lpPoolsIdx = []; + const coinPoolsIdx = []; + tokenSymbol.map((symbol, idx) => { + if (/[/]/.test(symbol) === true) { + lpPoolsIdx.push(idx); + } else { + coinPoolsIdx.push(idx); + } + }); + + const lpPools = lpPoolsIdx.map((idx) => underlyingToken[idx]); + const lpPrices = await unwrapLP(chain, lpPools); + + const coinPools = coinPoolsIdx.map((idx) => underlyingToken[idx]); + const coinPrices = await getPrices(chain, coinPools); + + const prices = { + ...coinPrices, + ...lpPrices, + }; + + yieldMarkets.map((data, i) => { + data.collateralFactor = collateralFactor[i]; + data.borrowRate = borrowRatePerBlock[i]; + data.supplyRate = supplyRatePerBlock[i]; + data.compSupplySpeeds = compSupplySpeeds[i]; + data.compBorrowSpeeds = compBorrowSpeeds[i]; + data.getCash = getCash[i]; + data.totalBorrows = totalBorrows[i]; + data.totalReserves = totalReserves[i]; + data.underlyingToken = underlyingToken[i]; + data.tokenSymbol = underlyingTokenSymbol[i]; + data.price = prices[underlyingToken[i].toLowerCase()]?.usd; + data.underlyingTokenDecimals = underlyingTokenDecimals[i]; + }); + + return { yieldMarkets }; +}; + +const unwrapLP = async (chain, lpTokens) => { + const [token0, token1, getReserves, totalSupply, symbol] = await Promise.all( + ['token0', 'token1', 'getReserves', 'totalSupply', 'symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: lpTokens.map((token) => ({ + target: token, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + + const token0Decimals = ( + await sdk.api.abi.multiCall({ + abi: abi.decimals, + calls: token0.map((token) => ({ + target: token, + })), + chain, + permitFailure: true, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + const token1Decimals = ( + await sdk.api.abi.multiCall({ + abi: abi.decimals, + calls: token1.map((token) => ({ + target: token, + })), + chain, + permitFailure: true, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + const token0Price = await getPrices(chain, token0); + const token1Price = await getPrices(chain, token1); + + const lpMarkets = lpTokens.map((lpToken) => { + return { lpToken }; + }); + + lpMarkets.map((token, i) => { + token.lpPrice = + ((getReserves[i]._reserve0 / token0Decimals[i]) * + token0Price[token0[i].toLowerCase()].usd + + (getReserves[i]._reserve1 / token1Decimals[i]) * + token1Price[token1[i].toLowerCase()].usd) / + (totalSupply[i] / 1e18); + }); + + const lpPrices = {}; + lpMarkets.map((lp) => { + lpPrices[lp.lpToken.toLowerCase()] = { usd: lp.lpPrice }; + }); + + return lpPrices; +}; + +const getPrices = async (chain, addresses) => { + const priceKeys = addresses + .map((a) => `${chain}:${a.toLowerCase()}`) + .join(','); + + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).body.coins; + + return Object.entries(prices).reduce((acc, [k, v]) => { + acc[k.replace(`${chain}:`, '')] = { usd: v.price }; + return acc; + }, {}); +}; + +function calculateApy(rate, price = 1, tvl = 1) { + // supply rate per block * number of blocks per year + const BLOCK_TIME = 6; + const YEARLY_BLOCKS = (365 * 24 * 60 * 60) / BLOCK_TIME; + const safeTvl = tvl === 0 ? 1 : tvl; + const apy = (((rate / 1e18) * YEARLY_BLOCKS * price) / safeTvl) * 100; + return apy; +} + +function calculateTvl(cash, borrows, reserves, price, decimals) { + // ( cash + totalBorrows ) * underlying price = balance + const tvl = + ((parseFloat(cash) + parseFloat(borrows) - parseFloat(reserves)) / + decimals) * + price; + return tvl; +} + +const getApy = async () => { + const wCantoPrice = (await getPrices('canto', [WCANTO]))[ + WCANTO.toLowerCase() + ]; + + const yieldPools = (await poolInfo('canto')).yieldMarkets.map((pool, i) => { + const totalSupplyUsd = calculateTvl( + pool.getCash, + pool.totalBorrows, + pool.totalReserves, + pool.price, + pool.underlyingTokenDecimals + ); + const totalBorrowUsd = calculateTvl( + 0, + pool.totalBorrows, + 0, + pool.price, + pool.underlyingTokenDecimals + ); + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + const apyBase = calculateApy(pool.supplyRate); + const apyReward = calculateApy( + pool.compSupplySpeeds, + wCantoPrice.usd, + totalSupplyUsd + ); + const apyBaseBorrow = calculateApy(pool.borrowRate); + const apyRewardBorrow = calculateApy( + pool.compBorrowSpeeds, + wCantoPrice.usd, + totalBorrowUsd + ); + const ltv = parseInt(pool.collateralFactor) / 1e18; + + const readyToExport = exportFormatter( + pool.pool, + 'Canto', + pool.tokenSymbol.replace('sAMM-', '').replace('vAMM-', ''), + tvlUsd, + apyBase, + apyReward, + pool.underlyingToken, + [WCANTO], + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv + ); + + return readyToExport; + }); + + return yieldPools.filter( + (i) => + utils.keepFinite(i) && + i.pool !== '0xee602429ef7ece0a13e4ffe8dbc16e101049504c-canto' + ); +}; + +function exportFormatter( + pool, + chain, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv +) { + return { + pool: `${pool}-${chain}`.toLowerCase(), + chain, + project: 'canto-lending', + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [underlyingTokens], + rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + }; +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://lending.canto.io/', +}; diff --git a/src/adaptors/cap/index.js b/src/adaptors/cap/index.js new file mode 100644 index 0000000000..99c6211b7e --- /dev/null +++ b/src/adaptors/cap/index.js @@ -0,0 +1,40 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { capConfig, capABI } = require('./lib/configs'); + + +const poolsFunction = async () => { + const chain = 'ethereum'; + const infra = capConfig[chain].infra; + const cUSD = capConfig[chain].tokens.cUSD; + const stcUSD = capConfig[chain].tokens.stcUSD; + + const stcUSDInfos = await utils.getERC4626Info(stcUSD.address, chain); + const cUSDPriceRes = await sdk.api.abi.call({ + abi: capABI.Oracle.getPrice, + target: infra.oracle.address, + chain, + params: [cUSD.address], + }); + + const cUSDPrice = BigInt(cUSDPriceRes.output[0]); + const tvlCUSD = BigInt(stcUSDInfos.tvl); + const tvlUsd = cUSDPrice * tvlCUSD / BigInt(10) ** BigInt(cUSD.decimals); + const tvlUsdNum = Number(tvlUsd) / 10 ** infra.oracle.priceDecimals; + + const stcUSDPool = { + pool: stcUSDInfos.pool, + chain: utils.formatChain(chain), + project: 'cap', + symbol: utils.formatSymbol(stcUSD.id), + tvlUsd: tvlUsdNum, + apy: stcUSDInfos.apyBase, + }; + + return [stcUSDPool]; +}; + +module.exports = { + apy: poolsFunction, + url: 'https://cap.app', +}; \ No newline at end of file diff --git a/src/adaptors/cap/lib/configs.js b/src/adaptors/cap/lib/configs.js new file mode 100644 index 0000000000..b8e5b3e796 --- /dev/null +++ b/src/adaptors/cap/lib/configs.js @@ -0,0 +1,81 @@ + +const capConfig = { + ethereum: { + fromBlock: 22867447, + fromTime: 1751892875, + infra: { + oracle: { + priceDecimals: 8, + address: '0xcD7f45566bc0E7303fB92A93969BB4D3f6e662bb', + fromBlock: 22867447, + }, + lender: { + address: '0x15622c3dbbc5614E6DFa9446603c1779647f01FC', + fromBlock: 22867447, + }, + delegation: { + address: '0xF3E3Eae671000612CE3Fd15e1019154C1a4d693F', + fromBlock: 22867447, + }, + }, + tokens: { + cUSD: { + id: 'cUSD', + coingeckoId: 'cap-usd', + decimals: 18, + address: '0xcCcc62962d17b8914c62D74FfB843d73B2a3cccC', + fromBlock: 22874015, + }, + stcUSD: { + id: 'stcUSD', + coingeckoId: 'cap-staked-usd', + decimals: 18, + address: '0x88887bE419578051FF9F4eb6C858A951921D8888', + fromBlock: 22874056, + }, + }, + symbiotic: { + // no good way to fetch it on chain? + networkMiddlewareToNetwork: { + // this one is deprecated + '0x8c9140fe6650e56a0a07e86455d745f8f7843b6d': '0x44f7e678e8412dbef1fd930f60af2bd125095962', + + // this one is the new one (and default) + '0x09a3976d8d63728d20dcdfee1e531c206ba91225': '0x98e52ea7578f2088c152e81b17a9a459bf089f2a', + default: '0x98e52ea7578f2088c152e81b17a9a459bf089f2a', + } + } + }, +}; + +const capABI = { + Oracle: { + getPrice: 'function getPrice(address _token) external view returns (uint256,uint256)', + }, + Vault: { + AddAssetEvent: 'event AddAsset(address asset)', + totalSupplies: 'function totalSupplies(address _token) external view returns (uint256 totalSupply)', + }, + Lender: { + ReserveAssetAddedEvent: 'event ReserveAssetAdded(address indexed asset, address vault, address debtToken, address interestReceiver, uint256 id)', + }, + Delegation: { + AddAgentEvent: 'event AddAgent(address agent, address network, uint256 ltv, uint256 liquidationThreshold)', + }, + SymbioticNetworkMiddleware: { + coverageByVault: 'function coverageByVault(address _network, address _agent, address _vault, address _oracle, uint48 _timestamp) public view returns (uint256 collateralValue, uint256 collateral)', + vaults: 'function vaults(address _agent) external view returns (address vaultAddress)', + } +} + +const symbioticABI = { + Vault: { + collateral: 'function collateral() public view returns (address)', + } +} + +module.exports = { + capConfig, + capABI, + symbioticABI, +} diff --git a/src/adaptors/carrot-liquidity/index.js b/src/adaptors/carrot-liquidity/index.js new file mode 100644 index 0000000000..673de0b055 --- /dev/null +++ b/src/adaptors/carrot-liquidity/index.js @@ -0,0 +1,34 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const CRT_POOL = 'FfCRL34rkJiMiX5emNDrYp3MdWH2mES3FvDQyFppqgpJ'; + +const getApy = async () => { + const performanceData = (await axios.get(`https://api.deficarrot.com/performance?vault=${CRT_POOL}&useCache=true`)).data; + + const metricsData = (await axios.get( + `https://api.deficarrot.com/vault?vault=${CRT_POOL}&useCache=true` + )).data; + + const crtPool = { + pool: CRT_POOL, + chain: 'Solana', + project: 'carrot-liquidity', + symbol: utils.formatSymbol('USDC-USDT-PYUSD'), + underlyingTokens: metricsData.assets.map(asset => asset.mint), + tvlUsd: Number(metricsData.tvl), + apyBase: Number(performanceData.navAPY[0].apy), + }; + + return [crtPool]; +}; + +module.exports = { + apy: getApy, + url: 'https://use.deficarrot.com/', +}; + + +// we also have the historical data for the APY if it can be used that would be great +// https://api.deficarrot.com//historicalVaultApy?vault=FfCRL34rkJiMiX5emNDrYp3MdWH2mES3FvDQyFppqgpJ&interval=DAY + diff --git a/src/adaptors/cat-in-a-box/abis/cdp.json b/src/adaptors/cat-in-a-box/abis/cdp.json new file mode 100644 index 0000000000..db9ea65186 --- /dev/null +++ b/src/adaptors/cat-in-a-box/abis/cdp.json @@ -0,0 +1,605 @@ +[ + { + "inputs":[ + { + "internalType":"address", + "name":"_synthetic", + "type":"address" + }, + { + "internalType":"contract IERC20", + "name":"_collateral", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_ltv", + "type":"uint256" + }, + { + "internalType":"address", + "name":"_feeSplitAddress", + "type":"address" + }, + { + "internalType":"address", + "name":"_psm", + "type":"address" + } + ], + "stateMutability":"nonpayable", + "type":"constructor" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"_deposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"bool", + "name":"amount", + "type":"bool" + } + ], + "name":"_flagset", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"_liquidate", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"_mint", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"_repay", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"fee", + "type":"uint256" + } + ], + "name":"_stabilisePeg", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"user", + "type":"address" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"_withdrawal", + "type":"event" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_depositor", + "type":"address" + } + ], + "name":"Owing", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"collateral", + "outputs":[ + { + "internalType":"contract IERC20", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"debt", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"deposit", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"deposited", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"enableRepaying", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"feeSplitAddress", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"lastPoints", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"liquidate", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ltv", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"mint", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes[]", + "name":"data", + "type":"bytes[]" + } + ], + "name":"multicall", + "outputs":[ + { + "internalType":"bytes[]", + "name":"results", + "type":"bytes[]" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"pointMultiplier", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_depositor", + "type":"address" + } + ], + "name":"poke", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"psm", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"repay", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_depositor", + "type":"address" + } + ], + "name":"resolvingFeePerToken", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_depositor", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_additionalDebt", + "type":"uint256" + } + ], + "name":"resolvingFeePerTokenAfterMoreDebt", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bool", + "name":"flag", + "type":"bool" + } + ], + "name":"setRepayFlag", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "internalType":"address", + "name":"_depositor", + "type":"address" + } + ], + "name":"stabilisePeg", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"synthetic", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalDebt", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalPoints", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totaldeposits", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"unclaimed", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"withdraw", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/cat-in-a-box/abis/oracle.json b/src/adaptors/cat-in-a-box/abis/oracle.json new file mode 100644 index 0000000000..53e54894c9 --- /dev/null +++ b/src/adaptors/cat-in-a-box/abis/oracle.json @@ -0,0 +1,547 @@ +[ + { + "inputs":[ + { + "internalType":"address", + "name":"_aggregator", + "type":"address" + }, + { + "internalType":"address", + "name":"_accessController", + "type":"address" + } + ], + "stateMutability":"nonpayable", + "type":"constructor" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"int256", + "name":"current", + "type":"int256" + }, + { + "indexed":true, + "internalType":"uint256", + "name":"roundId", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"updatedAt", + "type":"uint256" + } + ], + "name":"AnswerUpdated", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"roundId", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"startedBy", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"startedAt", + "type":"uint256" + } + ], + "name":"NewRound", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"to", + "type":"address" + } + ], + "name":"OwnershipTransferRequested", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"to", + "type":"address" + } + ], + "name":"OwnershipTransferred", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"acceptOwnership", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"accessController", + "outputs":[ + { + "internalType":"contract AccessControllerInterface", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"aggregator", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_aggregator", + "type":"address" + } + ], + "name":"confirmAggregator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"decimals", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"description", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_roundId", + "type":"uint256" + } + ], + "name":"getAnswer", + "outputs":[ + { + "internalType":"int256", + "name":"", + "type":"int256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint80", + "name":"_roundId", + "type":"uint80" + } + ], + "name":"getRoundData", + "outputs":[ + { + "internalType":"uint80", + "name":"roundId", + "type":"uint80" + }, + { + "internalType":"int256", + "name":"answer", + "type":"int256" + }, + { + "internalType":"uint256", + "name":"startedAt", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"updatedAt", + "type":"uint256" + }, + { + "internalType":"uint80", + "name":"answeredInRound", + "type":"uint80" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_roundId", + "type":"uint256" + } + ], + "name":"getTimestamp", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"latestAnswer", + "outputs":[ + { + "internalType":"int256", + "name":"", + "type":"int256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"latestRound", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"latestRoundData", + "outputs":[ + { + "internalType":"uint80", + "name":"roundId", + "type":"uint80" + }, + { + "internalType":"int256", + "name":"answer", + "type":"int256" + }, + { + "internalType":"uint256", + "name":"startedAt", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"updatedAt", + "type":"uint256" + }, + { + "internalType":"uint80", + "name":"answeredInRound", + "type":"uint80" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"latestTimestamp", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"owner", + "outputs":[ + { + "internalType":"address payable", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint16", + "name":"", + "type":"uint16" + } + ], + "name":"phaseAggregators", + "outputs":[ + { + "internalType":"contract AggregatorV2V3Interface", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"phaseId", + "outputs":[ + { + "internalType":"uint16", + "name":"", + "type":"uint16" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_aggregator", + "type":"address" + } + ], + "name":"proposeAggregator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"proposedAggregator", + "outputs":[ + { + "internalType":"contract AggregatorV2V3Interface", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint80", + "name":"_roundId", + "type":"uint80" + } + ], + "name":"proposedGetRoundData", + "outputs":[ + { + "internalType":"uint80", + "name":"roundId", + "type":"uint80" + }, + { + "internalType":"int256", + "name":"answer", + "type":"int256" + }, + { + "internalType":"uint256", + "name":"startedAt", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"updatedAt", + "type":"uint256" + }, + { + "internalType":"uint80", + "name":"answeredInRound", + "type":"uint80" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"proposedLatestRoundData", + "outputs":[ + { + "internalType":"uint80", + "name":"roundId", + "type":"uint80" + }, + { + "internalType":"int256", + "name":"answer", + "type":"int256" + }, + { + "internalType":"uint256", + "name":"startedAt", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"updatedAt", + "type":"uint256" + }, + { + "internalType":"uint80", + "name":"answeredInRound", + "type":"uint80" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_accessController", + "type":"address" + } + ], + "name":"setController", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_to", + "type":"address" + } + ], + "name":"transferOwnership", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"version", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + } +] diff --git a/src/adaptors/cat-in-a-box/index.js b/src/adaptors/cat-in-a-box/index.js new file mode 100644 index 0000000000..e59c90654a --- /dev/null +++ b/src/adaptors/cat-in-a-box/index.js @@ -0,0 +1,81 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const axios = require('axios'); + +const oracleAbi = require('./abis/oracle.json'); +const cdpAbi = require('./abis/cdp.json'); + +const oracleContract = '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'; +const cdpContract = '0x7f0A0C7149a46Bf943cCd412da687144b49C6014'; + +const getCats = async () => { + const decimals = ( + await sdk.api.abi.call({ + target: oracleContract, + abi: 'erc20:decimals', + }) + ).output; + + const ethereumPriceInDollar = + ( + await sdk.api.abi.call({ + target: oracleContract, + abi: oracleAbi.find((m) => m.name === 'latestAnswer'), + }) + ).output / + 10 ** decimals; + + let tvl = ( + await sdk.api.abi.call({ + target: cdpContract, + abi: cdpAbi.find((m) => m.name === 'totaldeposits'), + }) + ).output; + + let tdl = ( + await sdk.api.abi.call({ + target: cdpContract, + abi: cdpAbi.find((m) => m.name === 'totalDebt'), + }) + ).output; + + tvl = ethers.utils.formatEther(tvl); + tdl = ethers.utils.formatEther(tdl); + + const lidoStethApr = ( + await axios.get('https://eth-api.lido.fi/v1/protocol/steth/apr/last') + )['data'].apr; + const userPoints = 1 - 0; + const totalPoints = tvl + 1 - tdl; + let totalProtocolYieldCollateral = (tvl + 1) * (lidoStethApr / 100); + const protocolFeesCollateral = + totalProtocolYieldCollateral / 100 + + (totalProtocolYieldCollateral * tdl) / ((tvl + 1) * 4); + totalProtocolYieldCollateral -= protocolFeesCollateral; + let depositAprCollateral = + totalProtocolYieldCollateral / (totalPoints / userPoints); + if (isNaN(depositAprCollateral)) { + depositAprCollateral = 0; + } + let depositAprPercentage = 100 / (1 / depositAprCollateral); + if (isNaN(depositAprPercentage)) { + depositAprPercentage = 0; + } + + return [ + { + pool: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84-ethereum-cat-in-a-box', + chain: 'Ethereum', + project: 'cat-in-a-box', + symbol: 'stETH', + tvlUsd: Math.round(tvl * ethereumPriceInDollar * 100) / 100, + apyBase: Math.round(depositAprPercentage * 100) / 100, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getCats, + url: 'https://catinabox.finance/app', +}; diff --git a/src/adaptors/cbridge/index.js b/src/adaptors/cbridge/index.js index 88cba1a669..9844ee3e39 100644 --- a/src/adaptors/cbridge/index.js +++ b/src/adaptors/cbridge/index.js @@ -7,7 +7,10 @@ const buildPool = (entry) => { project: 'cbridge', symbol: utils.formatSymbol(entry.token.token.symbol), tvlUsd: entry.total_liquidity, - apy: (entry.farming_apy + entry.lp_fee_earning_apy) * 100, + apyBase: entry.lp_fee_earning_apy * 100, + apyReward: entry.farming_apy * 100, + rewardTokens: entry.farming_session_tokens.map((t) => t.token.address), + underlyingTokens: [entry.token.token.address], }; return newObj; @@ -38,4 +41,5 @@ const main = async () => { module.exports = { timetravel: false, apy: main, + url: 'https://cbridge.celer.network/liquidity', }; diff --git a/src/adaptors/celeron/index.js b/src/adaptors/celeron/index.js new file mode 100644 index 0000000000..af37c12ee4 --- /dev/null +++ b/src/adaptors/celeron/index.js @@ -0,0 +1,87 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { ethers } = require('ethers'); + +const DATA_ADDRESS = '0x3306597d0eAba6e753FDEF4FB689Fe46449D3920'; +const CHAIN = 'berachain'; + +async function apy() { + let farmAddresses = ( + await sdk.api.abi.call({ + target: DATA_ADDRESS, + abi: abi.getFarmAddressInfos, + chain: CHAIN, + }) + ).output; + + let poolTvlMapping = new Map(); + + for (let farmAddress of farmAddresses) { + let result = ( + await sdk.api.abi.call({ + target: farmAddress, + abi: abi.getTvl, + chain: CHAIN, + }) + ).output; + poolTvlMapping.set(farmAddress.toLowerCase(), result); + } + + let pools = ( + await sdk.api.abi.call({ + target: DATA_ADDRESS, + abi: abi.getPoolInfos, + chain: CHAIN, + }) + ).output; + + let priceFlag = pools + .map((item) => { + return `${CHAIN}:${item.asset},${CHAIN}:${item.reward}`; + }) + .join(','); + + let { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceFlag}` + ); + + let data = pools.map((pool) => { + let poolTvl = poolTvlMapping + .get(pool.farmAddress.toLowerCase()) + .find((item) => item.pid == pool.pid); + + let tvl = parseFloat( + ethers.utils.formatUnits(poolTvl.tvl, pool.assetDecimals) + ); + let reward = pool.rewardAmount; + + let assetPrice = coins[`berachain:${pool.asset}`].price; + let rewardPrice = coins[`berachain:${pool.reward}`].price; + let apy = + tvl == 0 ? 0 : ((rewardPrice * reward * 365) / (tvl * assetPrice)) * 100; + return { + chain: CHAIN, + pool: pool.farmAddress, + symbol: pool.assetSymbol, + underlyingTokens: [pool.asset], + tvlUsd: tvl * assetPrice, + apyBase: apy, + url: `https://celeron.xyz/vault`, + project: 'celeron', + }; + }); + return utils.removeDuplicates(data); +} + +let abi = { + getFarmAddressInfos: 'function getFarmAddressInfos() view returns(address[])', + getPoolInfos: + 'function getPoolInfos() public view returns(tuple(uint256 pid,address farmAddress, address asset, string assetSymbol, uint256 assetDecimals, address reward, uint256 rewardDecimals, uint256 rewardAmount)[])', + getTvl: + 'function getPoolTotalTvl() view returns (tuple(uint256 pid, address assets, uint256 tvl)[])', +}; + +module.exports = { + apy, + url: 'https://celeron.xyz/', +}; diff --git a/src/adaptors/cellana-finance/index.js b/src/adaptors/cellana-finance/index.js new file mode 100644 index 0000000000..77e48b5a77 --- /dev/null +++ b/src/adaptors/cellana-finance/index.js @@ -0,0 +1,314 @@ +const utils = require('../utils'); +const BigNumber = require("bignumber.js"); +//https://coins.llama.fi/prices/current/aptos:0x1::aptos_coin::AptosCoin +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; + +const APT_ADDR = "0x1::aptos_coin::AptosCoin"; +const APT_PRICE_ID = 'coingecko:aptos'; +const CELL_fungible_asset_address = '0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12' +const APT_fungible_asset_address = '0xedc2704f2cef417a06d1756a04a16a9fa6faaed13af469be9cdfcac5a21a8e2e' +const RESOURCE_CONTRACT = '0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1' +async function getResources(account) { + let url = `${NODE_URL}/accounts/${account}/resources?limit=9999` + const res = await utils.getData(url) + return res +} +let cellPrice; +let aptPrice; +async function view(payload) { + + try { + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [] + return data + } catch (e) { + console.log(e) + return null; + } +} +async function getPoolsAddress() { + const payload = { + function: `${RESOURCE_CONTRACT}::liquidity_pool::all_pool_addresses`, + type_arguments: [], + arguments: [], + }; + try { + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [] + return data[0] + } catch (e) { + console.log(e) + return null; + } +} +async function getWrapper(address) { + const payload = { + function: `${RESOURCE_CONTRACT}::coin_wrapper::get_original`, + type_arguments: [], + arguments: [address], + }; + try { + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [] + return data[0] + } catch (e) { + console.log(e) + return null; + } +} +async function getTokenPrice(tokenAddr) { + if (tokenAddr == CELL_fungible_asset_address) return [await getCELLPrice(aptPrice), 'CELL', '8'] + if (tokenAddr.indexOf(":") < 0) { + tokenAddr = await getWrapper(tokenAddr) + } + const price = (await utils.getData(`${COINS_LLAMA_PRICE_URL}aptos:${tokenAddr}`)) + if (!price || !price.coins || !price.coins["aptos:" + tokenAddr]?.symbol) { + let name = tokenAddr.split('::'); + return [null,name[2],null] + } + return [price?.coins["aptos:" + tokenAddr]?.price, price?.coins["aptos:" + tokenAddr]?.symbol, + price?.coins["aptos:" + tokenAddr]?.decimals + ] +} +async function getEpoch() { + const payload = { + function: `${RESOURCE_CONTRACT}::epoch::now`, + type_arguments: [], + arguments: [], + }; + const data = await view(payload); + return data[0]; +}; +async function main() { + const aptRes = await utils.getData(`${COINS_LLAMA_PRICE_URL}${APT_PRICE_ID}`) + aptPrice = aptRes['coins'][APT_PRICE_ID]['price'] + cellPrice = await getCELLPrice(aptPrice) + // let poolResource = await getResources("0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1"); + // const poolsAddresses = poolResource.find(i => i.type.includes('::liquidity_pool::LiquidityPoolConfigs'))?.data.all_pools?.inline_vec + let poolsAddresses = await getPoolsAddress() + + let res = []; + const pools = await Promise.all(poolsAddresses.map(async ({ inner }) => { + let rs = await calculateRewardApy(inner, aptPrice, cellPrice); + res.push(rs[0]) + // res.push(rs[1]) + })); + + return utils.removeDuplicates([...res]); + +} +async function getCurrentVotes (poolAddress ) { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::vote_manager::current_votes`, + type_arguments: [], + arguments: [poolAddress], + }; + const data = await view(payload); + return data[0]; + } catch (e) { + return 0; + } +}; +async function getReserve(lpAddress) { + + const fungibleAssetPoolStore = (await getResources(lpAddress)).find(i => i.type.includes('liquidity_pool::LiquidityPool'))?.data + const fungibleAssetAddressToken1 = fungibleAssetPoolStore?.token_store_1?.inner + const fungibleAssetAddressToken2 = fungibleAssetPoolStore?.token_store_2?.inner + const fungibleAssetTokenStore_1 = (await getResources(fungibleAssetAddressToken1)).find(i => i.type.includes('fungible_asset::FungibleStore'))?.data + const fungibleAssetTokenStore_2 = (await getResources(fungibleAssetAddressToken2)).find(i => i.type.includes('fungible_asset::FungibleStore'))?.data + // reserve0Address = fungibleAssetTokenStore_1?.metadata?.inner + // reserve1Address = fungibleAssetTokenStore_2?.metadata?.inner + + const reserve0Address = await getWrapper(fungibleAssetTokenStore_1?.metadata?.inner) + const reserve1Address = await getWrapper(fungibleAssetTokenStore_2?.metadata?.inner) + const reserve0 = fungibleAssetTokenStore_1?.balance; + const reserve1 = fungibleAssetTokenStore_2?.balance; + return { reserve0, reserve1, reserve0Address, reserve1Address } + + + +} + +async function getCELLPrice(aptPrice) { + const balances = {} + const data = await getResources('0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1') + const poolsAddresses = data.find(i => i.type.includes('::liquidity_pool::LiquidityPoolConfigs'))?.data.all_pools?.inline_vec + for (const pool of poolsAddresses) { + const fungibleAssetPoolStore = (await getResources(pool.inner)).find(i => i.type.includes('liquidity_pool::LiquidityPool'))?.data + const fungibleAssetAddressToken1 = fungibleAssetPoolStore?.token_store_1?.inner + const fungibleAssetAddressToken2 = fungibleAssetPoolStore?.token_store_2?.inner + const fungibleAssetTokenStore_1 = (await getResources(fungibleAssetAddressToken1)).find(i => i.type.includes('fungible_asset::FungibleStore'))?.data + const fungibleAssetTokenStore_2 = (await getResources(fungibleAssetAddressToken2)).find(i => i.type.includes('fungible_asset::FungibleStore'))?.data + const token_1_address = fungibleAssetTokenStore_1?.metadata?.inner + const token_2_address = fungibleAssetTokenStore_2?.metadata?.inner + if (token_1_address == CELL_fungible_asset_address) { + const cell_balance = fungibleAssetTokenStore_1?.balance; + + //caculator CELL price + if (token_2_address == APT_fungible_asset_address) { + const apt_balance = fungibleAssetTokenStore_2?.balance; + const cellPrice = (new BigNumber(apt_balance)).div(new BigNumber(cell_balance)).toNumber() * aptPrice + return cellPrice + } + + } else if (token_2_address == CELL_fungible_asset_address) { + const cell_balance = fungibleAssetTokenStore_2?.balance; + if (token_1_address == APT_fungible_asset_address) { + const apt_balance = fungibleAssetTokenStore_1?.balance; + const cellPrice = (new BigNumber(apt_balance)).div(new BigNumber(cell_balance)).toNumber() * aptPrice + return cellPrice + } + } + } +} + +async function getGaugeAddress(poolAddress) { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::vote_manager::get_gauge`, + type_arguments: [], + arguments: [poolAddress], + }; + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [] + return data[0]?.inner + } catch (e) { + console.log(e) + return null + } + +}; +async function getRewardsPool(gaugeAddress) { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::gauge::rewards_pool`, + type_arguments: [], + arguments: [gaugeAddress], + }; + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [] + return data[0]?.inner; + } catch (e) { + + console.log(e) + return null + } + +}; +getFeesAddress = async (poolAddress) => { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::vote_manager::fees_pool`, + type_arguments: [], + arguments: [poolAddress], + }; + const data = await view(payload); + return data[0].inner + } catch (e) { + console.log('getFeesAddress error: ' + e); + return null; + } +}; +getBribeAddress = async (poolAddress) => { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::vote_manager::incentive_pool`, + type_arguments: [], + arguments: [poolAddress], + }; + const data = await view(payload); + return data[0].inner; + } catch (e) { + console.log('getBribeAddress error: ' + e); + return null; + } +}; + +async function getRewardRate(poolAddress) { + try { + const payload = { + function: `0x4bf51972879e3b95c4781a5cdcb9e1ee24ef483e7d22f2d903626f126df62bd1::rewards_pool_continuous::reward_rate`, + type_arguments: [], + arguments: [poolAddress], + }; + const data = (await utils.getData(`https://fullnode.mainnet.aptoslabs.com/v1/view`, payload)) || [0]; + + return data[0]; + } catch (e) { + console.log(e) + return 0 + + } + +} + +async function calculateRewardApy(poolAddress, aptPrice, cellPrice) { + let gauge = await getGaugeAddress(poolAddress) + let rewardPoolAddress = await getRewardsPool(gauge) + let rewardperSecond = await getRewardRate(rewardPoolAddress) + let rewardPerDay = (new BigNumber(rewardperSecond)).div((new BigNumber(10)).pow(8)).toNumber() * 24 * 60 * 60 + let { reserve0, reserve1, reserve0Address, reserve1Address } = await getReserve(poolAddress) + let price0, price1, coinSymbol0, coinSymbol1, decimals1, decimals0; + if (reserve0Address == CELL_fungible_asset_address) { + price0 = cellPrice; + coinSymbol0 = 'CELL' + decimals0 = 8; + [price1, coinSymbol1, decimals1] = await getTokenPrice(reserve1Address); + } + else if (reserve1Address == CELL_fungible_asset_address) { + price1 = cellPrice + coinSymbol1 = 'CELL'; + decimals1 = 8; + [price0, coinSymbol0, decimals0] = await getTokenPrice(reserve0Address) + } + else { + [price0, coinSymbol0, decimals0] = await getTokenPrice(reserve0Address); + [price1, coinSymbol1, decimals1] = await getTokenPrice(reserve1Address) + } + const coinSymbol = `${coinSymbol0}-${coinSymbol1}` + let reserve0Value = (new BigNumber(reserve0)).div((new BigNumber(10)).pow(decimals0)).toNumber() * price0 + let reserve1Value = (new BigNumber(reserve1)).div((new BigNumber(10)).pow(decimals1)).toNumber() * price1 + if (!reserve0Value) reserve0Value = reserve1Value + if (!reserve1Value) reserve1Value = reserve0Value + const total = reserve0Value + reserve1Value; + let apyReward = calcAptRewardApy(rewardPerDay, cellPrice, total,) + + + const lpPool = { + pool: `cellana-finance-${utils.formatSymbol(coinSymbol)}`, + chain: utils.formatChain('aptos'), + project: 'cellana-finance', + symbol: utils.formatSymbol(coinSymbol), + tvlUsd: total, + apyBase: 0, + apyReward: apyReward, + rewardTokens: [CELL_fungible_asset_address] + } + const rs = [lpPool] + return rs; +} +function calcAptRewardApy(rewardPerDay, rewardPrice, tvl) { + return (rewardPerDay * 365 * rewardPrice / tvl) * 100 +} +//vote reward +fetchRewards = async ( + address, + epoch, +) => { + try { + const payload = { + function: `${RESOURCE_CONTRACT}::rewards_pool::total_rewards`, + type_arguments: [], + arguments: [address, epoch + ''], + }; + const data = await view(payload); + return data[0] + } catch (e) { + console.log(e); + return null; + } +} + + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.cellana.finance', +}; \ No newline at end of file diff --git a/src/adaptors/ceto-swap/abi/ERC20.json b/src/adaptors/ceto-swap/abi/ERC20.json new file mode 100644 index 0000000000..46be323f51 --- /dev/null +++ b/src/adaptors/ceto-swap/abi/ERC20.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ceto-swap/abi/ERC20MasterChef.json b/src/adaptors/ceto-swap/abi/ERC20MasterChef.json new file mode 100644 index 0000000000..aaa078e4b8 --- /dev/null +++ b/src/adaptors/ceto-swap/abi/ERC20MasterChef.json @@ -0,0 +1,49 @@ +[ + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ceto-swap/abi/LP.json b/src/adaptors/ceto-swap/abi/LP.json new file mode 100644 index 0000000000..be7c126b2a --- /dev/null +++ b/src/adaptors/ceto-swap/abi/LP.json @@ -0,0 +1,87 @@ +[ + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ceto-swap/abi/MasterChef.json b/src/adaptors/ceto-swap/abi/MasterChef.json new file mode 100644 index 0000000000..d8cf2cc8ed --- /dev/null +++ b/src/adaptors/ceto-swap/abi/MasterChef.json @@ -0,0 +1,74 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "components": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardSharePerShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isStarted", + "type": "bool" + } + ], + "internalType": "struct IFarm.PoolInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sharesPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ceto-swap/index.js b/src/adaptors/ceto-swap/index.js new file mode 100644 index 0000000000..aab5d31bee --- /dev/null +++ b/src/adaptors/ceto-swap/index.js @@ -0,0 +1,241 @@ +const LPAbi = require('./abi/LP.json'); +const ERC20Abi = require('./abi/ERC20.json'); +const MasterChefAbi = require('./abi/MasterChef.json'); +const ERC20MasterChefAbi = require('./abi/ERC20MasterChef.json'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); +const sdk = require('@defillama/sdk'); + +const pools = { + usdex_plus_usdc: { + address: '0x3838753b9b9b7cf26ddc71d0f1a0ee0b9144aba5', + pid: 0, + }, + weth_usdc: { + address: '0xd6359083da64e79ad7c54106ee71a889268f0462', + pid: 5, + }, + stone_weth: { + address: '0x05db409bc3c2629e2987dc7aa87c39376bc49477', + pid: 7, + }, + ceto_usdex_plus: { + address: '0xef799451a28a1432712d19df82e512d985d685d4', + pid: 1, + }, + ceto_weth: { + address: '0x6c72baee6d7074e54add3f617ec5d6b22afe779b', + pid: 4, + }, + bceto_weth: { + address: '0x3afed5925034bb3b730ffdae6d98b6df45c0ff74', + pid: 6, + }, + manta_weth: { + address: '0xb9454b5fc78c826cf028f4e513b0e0a4d2bf51a9', + pid: 2, + }, + stgai_manta: { + address: '0x75791775dc127d4441ecc532be128214ca4c6f72', + pid: 3, + }, +} + +const TOKEN = { + USDC: '0xb73603c5d87fa094b7314c74ace2e64d165016fb', + CETO: '0x3af03e8c993900f0ea6b84217071e1d4cc783982' +} + +const PROJECT_SLUG = 'ceto-swap' +const MASTERCHEF_ADDRESS = '0x78343ABFC1381D4358161c2f73Fc0990CCD5cbE0'; +const BLOCKS_PER_YEAR = 31536000; + +function setPrices(prices, info) { + const tokenPrice0 = prices[info.token0.toLowerCase()] + const tokenPrice1 = info.token1.toLowerCase() === TOKEN.USDC ? 1 : prices[info.token1.toLowerCase()] + const token1ReservesBN = new BigNumber(info.reserves[1]).div(info.token1.toLowerCase() === TOKEN.USDC ? 1e6 : 1e18); + const token0ReservesBN = new BigNumber(info.reserves[0]).div(1e18); + if (!tokenPrice0) { + const reserve = token1ReservesBN.times(tokenPrice1); + const priceBN = reserve.div(token0ReservesBN); + prices[info.token0.toLowerCase()] = priceBN; + } else if (!tokenPrice1) { + const reserve = token0ReservesBN.times(tokenPrice0); + const priceBN = reserve.div(token1ReservesBN); + prices[info.token1.toLowerCase()] = priceBN + } +} + +async function getLpTotalAmount(pool, quoteToken) { + const [ + { output: quoteTokenBlanceLP }, + { output: lpTokenBalanceMC }, + { output: lpTotalSupply }, + { output: quoteTokenDecimals } + ] = await Promise.all([ + sdk.api.abi.call({ + target: quoteToken, + chain: 'manta', + abi: ERC20MasterChefAbi[0], + params: [pool.address] + }), + sdk.api.abi.call({ + target: pool.address, + chain: 'manta', + abi: ERC20MasterChefAbi[0], + params: [MASTERCHEF_ADDRESS] + }), + sdk.api.abi.call({ + target: pool.address, + chain: 'manta', + abi: ERC20MasterChefAbi[2], + }), + sdk.api.abi.call({ + target: quoteToken, + chain: 'manta', + abi: ERC20MasterChefAbi[1], + }), + ]); + const lpTokenRatio = new BigNumber(lpTokenBalanceMC).div(lpTotalSupply); + const lpTotal = new BigNumber(quoteTokenBlanceLP) + .div(new BigNumber(10).pow(quoteTokenDecimals)) + .times(2) + .times(lpTokenRatio) + return lpTotal; +} + +async function getApy(pool, info, prices) { + const [ + { output: poolInfo }, + { output: totalAllocPoint }, + { output: sharesPerSecond } + ] = await Promise.all([ + sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'manta', + abi: MasterChefAbi[0], + params: [pool.pid] + }), + sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'manta', + abi: MasterChefAbi[1], + }), + sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'manta', + abi: MasterChefAbi[2], + }), + ]) + const allocPoint = new BigNumber(poolInfo[1].toString()); + const poolWeight = allocPoint.div(new BigNumber(totalAllocPoint)); + const rewardPerBlock = poolWeight.times(sharesPerSecond || 10).div(10 ** 18); + const rewardPerYear = rewardPerBlock.times(BLOCKS_PER_YEAR); + const price0 = prices[info.token0.toLowerCase()]; + const price1 = prices[info.token1.toLowerCase()]; + const quoteToken = price0 ? info.token0.toLowerCase() : info.token1.toLowerCase(); + const lpTotal = await getLpTotalAmount(pool, quoteToken); + const apyInCeto = rewardPerYear.times(prices[TOKEN.CETO]); + const totalValue = lpTotal.times(price0 || price1); + const apy = apyInCeto.div(totalValue); + return apy; +} + +async function getPoolsInfo() { + const poolsInfo = {}; + for (const pool of Object.values(pools)) { + const poolAddress = pool.address; + const [ + { output: totalSupply }, + { output: reserves }, + { output: token0 }, + { output: token1 }, + { output: decimals } + ] = await Promise.all([ + sdk.api.abi.call({ + target: poolAddress, + chain: 'manta', + abi: LPAbi[0], + }), + sdk.api.abi.call({ + target: poolAddress, + chain: 'manta', + abi: LPAbi[1], + }), + sdk.api.abi.call({ + target: poolAddress, + chain: 'manta', + abi: LPAbi[2], + }), + sdk.api.abi.call({ + target: poolAddress, + chain: 'manta', + abi: LPAbi[3], + }), + sdk.api.abi.call({ + target: poolAddress, + chain: 'manta', + abi: LPAbi[4], + }), + ]) + poolsInfo[poolAddress.toLowerCase()] = { + totalSupply, + reserves: { 0: reserves['0'], 1: reserves['1'] }, + token0: token0.toLowerCase(), + token1: token1.toLowerCase(), + decimals, + } + } + const prices = {} + const tvl = {}; + for (const pool of Object.values(pools)) { + const poolAddress = pool.address; + const info = poolsInfo[poolAddress.toLowerCase()]; + const [{ output: symbol0 }, { output: symbol1 }] = await Promise.all([ + sdk.api.abi.call({ + target: info.token0, + chain: 'manta', + abi: ERC20Abi[0], + }), + sdk.api.abi.call({ + target: info.token1, + chain: 'manta', + abi: ERC20Abi[0], + }) + ]) + const symbol = `${symbol0}/${symbol1}`; + setPrices(prices, info); + const price0 = prices[info.token0.toLowerCase()]; + const price1 = prices[info.token1.toLowerCase()]; + const token0ReservesBN = new BigNumber(info.reserves[0]).div(1e18); + const token1ReservesBN = new BigNumber(info.reserves[1]).div(info.token1.toLowerCase() === TOKEN.USDC ? 1e6 : 1e18); + const tvl0BN = price0.times(token0ReservesBN); + const tvl1BN = price0.times(token0ReservesBN); + const tvlUsd = tvl0BN.plus(tvl1BN).toNumber(); + tvl[poolAddress] = { + pool: poolAddress, + chain: utils.formatChain('manta'), + project: PROJECT_SLUG, + symbol, + tvlUsd, + url: 'https://cetoswap.com/#/farms', + } + } + const res = []; + for (const pool of Object.values(pools)) { + const poolAddress = pool.address; + const currentTvl = tvl[poolAddress]; + const info = poolsInfo[poolAddress.toLowerCase()]; + const apy = await getApy(pool, info, prices); + res.push({ + ...currentTvl, + apy: apy.times(100).toNumber(), + }) + } + return res; +} + + +module.exports = { + apy: getPoolsInfo, +}; \ No newline at end of file diff --git a/src/adaptors/cetus-clmm/index.js b/src/adaptors/cetus-clmm/index.js new file mode 100644 index 0000000000..da614e34da --- /dev/null +++ b/src/adaptors/cetus-clmm/index.js @@ -0,0 +1,74 @@ +const axios = require('axios'); +const { getPools } = require('../morfi/gql-requests'); + +const chains = { + sui: 'https://api-sui.cetus.zone/v3/sui/clmm/stats_pools?is_vaults=false&display_all_pools=true&has_mining=true&has_farming=true&no_incentives=true&order_by=-tvl&limit=100&offset=0', + aptos: 'https://api.cetus.zone/v2/swap/count', +}; + +const apy = async (chain) => { + if (chain === 'sui') { + let pools = (await axios.get(chains[chain])).data.data.list; + + return pools + .map((p) => { + const apyBase = Number(p?.stats[0].apr) * 100; + const apyReward = p.totalApr * 100 - apyBase; + + let rewardTokens = p.miningRewarders?.map((rewards) => { + return rewards.coinType; + }); + return { + pool: p.pool, + chain: chain, + project: 'cetus-clmm', + symbol: [p.coinA.symbol, p.coinB.symbol].join('-'), + underlyingTokens: [p.coinA.coinType, p.coinB.coinType], + rewardTokens, + tvlUsd: Number(p.tvl), + apyBase: apyBase, + apyReward: apyReward > 0 ? apyReward : 0, + volumeUsd1d: Number(p?.stats[0].vol), + poolMeta: `${Number(p.feeRate) / 100}%`, + url: `https://app.cetus.zone/liquidity/deposit?poolAddress=${p.pool}`, + }; + }) + .filter((i) => i.tvlUsd <= 1e8); + } + const data = (await axios.get(chains[chain])).data.data.pools; + + return data + .map((p) => { + const apyReward = p.rewarder_apr.reduce( + (a, b) => a + Number(b.replace('%', '')), + 0 + ); + return { + chain, + project: 'cetus-clmm', + pool: p.swap_account, + symbol: p.symbol, + tvlUsd: Number(p.tvl_in_usd), + apyBase: Number(p.apr_24h.replace('%', '')), + volumeUsd1d: Number(p.vol_in_usd_24h), + apyReward, + rewardTokens: apyReward > 0 ? ['sui', 'cetus'] : [], + poolMeta: `${Number(p.fee) * 100}%`, + underlyingTokens: [p.token_a_address, p.token_b_address], + url: `https://app.cetus.zone/liquidity/deposit?poolAddress=${p.swap_account}`, + }; + }) + .filter((i) => i.tvlUsd <= 1e8); +}; + +const main = async () => { + const pools = await Promise.all( + Object.keys(chains).map((chain) => apy(chain)) + ); + + return pools.flat(); +}; + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/chainflip/index.ts b/src/adaptors/chainflip/index.ts new file mode 100644 index 0000000000..6f9de5ebfe --- /dev/null +++ b/src/adaptors/chainflip/index.ts @@ -0,0 +1,27 @@ +const utils = require('../utils'); +const superagent = require('superagent'); + +const getPool = async () => { + const apyData = await superagent.get( + 'https://explorer-service-processor.chainflip.io/defi-llama/yield' + ); + const [pool] = apyData.body; + + const btcPool = { + pool: 'chainflip-boost-btc', + chain: utils.formatChain('bitcoin'), + project: 'chainflip', + symbol: utils.formatSymbol('BTC'), + tvlUsd: pool.tvl, + apy: pool.apy, + url: 'https://scan.chainflip.io/pools/Btc/boost', + }; + + return [btcPool]; +}; + +module.exports = { + timetravel: false, + apy: getPool, + url: 'https://scan.chainflip.io/pools/Btc/boost', +}; diff --git a/src/adaptors/chronos-v1/abiGauge.json b/src/adaptors/chronos-v1/abiGauge.json new file mode 100644 index 0000000000..24764a20c2 --- /dev/null +++ b/src/adaptors/chronos-v1/abiGauge.json @@ -0,0 +1,633 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_rewardToken", "type": "address" }, + { "internalType": "address", "name": "_ve", "type": "address" }, + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "address", "name": "_distribution", "type": "address" }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { "internalType": "bool", "name": "_isForPair", "type": "bool" }, + { "internalType": "address", "name": "_maNFTs", "type": "address" }, + { "internalType": "uint256", "name": "_maGaugeId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "to", + "type": "uint256" + } + ], + "name": "Merged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "Splited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DISTRIBUTION", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_VE", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "_balances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "_depositEpoch", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "_start", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adjustWeights", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "balanceOfToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "depositTo", + "outputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_from", "type": "uint256" }, + { "internalType": "uint256", "name": "_to", "type": "uint256" } + ], + "name": "harvestAndMerge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "harvestAndSplit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maGaugeId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maNFTs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "maturityLevelOfTokenMaxArray", + "outputs": [ + { "internalType": "uint256", "name": "_matLevel", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "maturityLevelOfTokenMaxBoost", + "outputs": [ + { "internalType": "uint256", "name": "_matLevel", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardForDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_distribution", "type": "address" } + ], + "name": "setDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { "internalType": "uint256", "name": "_totalWeight", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "updateReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "weightOfToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "weightOfUser", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "withdrawAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAndHarvestAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/chronos-v1/abiPair.json b/src/adaptors/chronos-v1/abiPair.json new file mode 100644 index 0000000000..835c4bc01f --- /dev/null +++ b/src/adaptors/chronos-v1/abiPair.json @@ -0,0 +1,672 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimStakingFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isStable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/chronos-v1/abiPairFactory.json b/src/adaptors/chronos-v1/abiPairFactory.json new file mode 100644 index 0000000000..e493894d42 --- /dev/null +++ b/src/adaptors/chronos-v1/abiPairFactory.json @@ -0,0 +1,351 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "volatileFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "changeMadeTimestamp", + "type": "uint256" + } + ], + "name": "FeesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REFERRAL_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REFERRAL_FEE_", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dibs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_stable", "type": "bool" }], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_dibs", "type": "address" } + ], + "name": "setDibs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_stableFee", "type": "uint256" }, + { "internalType": "uint256", "name": "_volatileFee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_refFee", "type": "uint256" } + ], + "name": "setReferralFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feehandler", "type": "address" } + ], + "name": "setStakingFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setStakingFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingFeeHandler", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingNFTFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/chronos-v1/abiVoter.json b/src/adaptors/chronos-v1/abiVoter.json new file mode 100644 index 0000000000..37e589b962 --- /dev/null +++ b/src/adaptors/chronos-v1/abiVoter.json @@ -0,0 +1,920 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "internal_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "external_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "_initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_restTime", "type": "uint256" } + ], + "name": "changeRestTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_fees", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_tokenId", "type": "uint256[]" } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "external_bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugesDistributionTimestmap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "increaseGaugeApprovals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "address[]", "name": "_pools", "type": "address[]" } + ], + "name": "initGauges", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_gauges", "type": "address" }, + { "internalType": "address", "name": "_bribes", "type": "address" }, + { "internalType": "address", "name": "_maNFTs", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "internal_bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGaugeTotally", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maGaugeId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maNFTs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "poolVoteLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_bribeFactory", "type": "address" } + ], + "name": "setBribeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gaugeFactory", "type": "address" } + ], + "name": "setGaugeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_maNFTs", "type": "address" } + ], + "name": "setMaNFTs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" }, + { "internalType": "address", "name": "_internal", "type": "address" }, + { "internalType": "address", "name": "_external", "type": "address" } + ], + "name": "setNewBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_factory", "type": "address" } + ], + "name": "setPairFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_token", "type": "address[]" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/chronos-v1/index.js b/src/adaptors/chronos-v1/index.js new file mode 100644 index 0000000000..40129641c2 --- /dev/null +++ b/src/adaptors/chronos-v1/index.js @@ -0,0 +1,160 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xce9240869391928253ed9cc9bcb8cb98cb5b0722'; +const voter = '0xc72b5c6d2c33063e89a50b2f77c99193ae6cee6c'; +const CHR = '0x15b2fb8f08e4ac1ce019eadae02ee92aedf06851'; + +const project = 'chronos-v1'; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: 'arbitrum', + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: 'arbitrum', + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'arbitrum', + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalWeight = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'totalWeight'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'totalSupply'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(CHR) + ), + ]; + const priceKeys = tokens + .map((i) => `arbitrum:${i}`) + .concat('coingecko:usd-freedom') + .join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = + poolMeta.t0 === '0xae48b7C8e096896E32D53F10d0Bf89f82ec7b987' + ? prices['coingecko:usd-freedom']?.price + : prices[`arbitrum:${poolMeta.t0}`]?.price; + const p1 = prices[`arbitrum:${poolMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const pairPrice = (tvlUsd * 1e18) / totalSupply[i]; + const totalRewardPerDay = + ((rewardRate[i] * 86400) / 1e18) * prices[`arbitrum:${CHR}`]?.price; + + const apyReward = + (totalRewardPerDay * 36500) / ((totalWeight[i] * pairPrice) / 1e18); + + return { + pool: p, + chain: utils.formatChain('arbitrum'), + project, + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [CHR] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.chronos.exchange/liquidity', +}; diff --git a/src/adaptors/cian-yield-layer/index.js b/src/adaptors/cian-yield-layer/index.js new file mode 100644 index 0000000000..17793e72c4 --- /dev/null +++ b/src/adaptors/cian-yield-layer/index.js @@ -0,0 +1,82 @@ +const axios = require('axios'); + +const apiUrl_avax = 'https://data.cian.app/api/v1/staking_avax/apr'; +const apiUrl_btc = 'https://data.cian.app/api/v1/staking_btc/apr'; +const apiUrl_maticx = 'https://data.cian.app/polygon/api/v1/staking_matic/apy'; +const apiUrl_stmatic = + 'https://data.cian.app/polygon/api/v1/staking_stmatic/apy'; +const apiUrl_maticX6x = + 'https://data.cian.app/polygon/api/v1/staking_matic6x/apy'; +const apiUrl_steth = 'https://data.cian.app/ethereum/api/v1/staking_eth/apy'; +const apiUrl_matrixport = + 'https://data.cian.app/ethereum/api/v1/staking_in1_eth/apy'; +const apiUrl_stethVault_eth = + 'https://data.cian.app/ethereum/api/v1/eth_vault_steth/apy'; +const apiUrl_wstethVault_arbitrum = + 'https://data.cian.app/arbitrum/api/v1/arb_vault_wsteth/apy'; +const apiUrl_wstethVault_optimism = + 'https://data.cian.app/optimism/api/v1/op_vault_wsteth/apy'; +const apiUrl_wbethVault_bsc = + 'https://data.cian.app/bsc/api/v1/bsc_vault_wbeth/apy'; + +async function fetch() { + const response_avax = (await axios.get(apiUrl_avax)).data.data; + const response_btc = (await axios.get(apiUrl_btc)).data.data; + const response_maticx = (await axios.get(apiUrl_maticx)).data.data; + const response_stmatic = (await axios.get(apiUrl_stmatic)).data.data; + const response_maticX6x = (await axios.get(apiUrl_maticX6x)).data.data; + const response_steth = (await axios.get(apiUrl_steth)).data.data; + const response_matrixport = (await axios.get(apiUrl_matrixport)).data.data; + const response_stethVault_eth = (await axios.get(apiUrl_stethVault_eth)).data + .data; + const response_wstethVault_arbitrum = ( + await axios.get(apiUrl_wstethVault_arbitrum) + ).data.data; + const response_wstethVault_optimism = ( + await axios.get(apiUrl_wstethVault_optimism) + ).data.data; + const response_wbethVault_bsc = (await axios.get(apiUrl_wbethVault_bsc)).data + .data; + + return [ + ...response_avax, + ...response_btc, + ...response_maticx, + ...response_stmatic, + ...response_maticX6x, + response_steth, + response_matrixport, + response_stethVault_eth, + response_wstethVault_arbitrum, + response_wstethVault_optimism, + response_wbethVault_bsc, + ]; +} + +const main = async () => { + const data = await fetch(); + + return data + .filter((p) => p) + .map((p) => { + // if - in symbol -> split, keep 1 in array, otherwise don't split + let symbolSplit = p.symbol.split('-'); + symbolSplit = symbolSplit.length > 1 ? symbolSplit[1] : symbolSplit[0]; + const symbol = symbolSplit.replace(/ *\([^)]*\) */g, ''); + // extract content within () -> meta data + const poolMeta = /\(([^)]+)\)/.exec(symbolSplit)[1]; + + return { + ...p, + symbol, + poolMeta, + project: 'cian-yield-layer', + }; + }); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://dapp.cian.app', +}; diff --git a/src/adaptors/circuit-protocol/index.js b/src/adaptors/circuit-protocol/index.js new file mode 100644 index 0000000000..e2f02b8d5b --- /dev/null +++ b/src/adaptors/circuit-protocol/index.js @@ -0,0 +1,67 @@ +const utils = require('../utils'); + +const url = 'https://api.circuit.farm'; +const urlApy = `${url}/apy`; +const urlTvl = `${url}/tvl`; +const urlMeta = `${url}/vaults`; + +const networkMapping = { + 5000: 'mantle', +} + +const crctMapping = { + 5000: '0x0000000000000000000000000000000000000000' +} + + +const main = async () => { + const [apy, tvl, meta] = await Promise.all( + [urlApy, urlTvl, urlMeta].map((u) => utils.getData(u)) + ); + + let data = []; + for (const chain of Object.keys(networkMapping)) { + const poolData = tvl[chain]; + for (const pool of Object.keys(poolData)) { + if (apy[pool] === undefined) { + continue; + } + const poolMeta = meta.find((m) => m?.id === pool); + const platformId = poolMeta?.platformId; + + const poolId = + poolMeta === undefined + ? crctMapping[chain] + : poolMeta.earnedTokenAddress; + + const isActive = poolMeta === undefined || poolMeta.status == 'active'; + + if (!poolId) continue; + + const underlyingTokens = (!!poolMeta && poolMeta.assets.length === 1 && poolMeta.tokenAddress) ? [poolMeta.tokenAddress] : undefined; + + data.push({ + pool: `${poolId}-${networkMapping[chain]}`.toLowerCase(), + chain: utils.formatChain(networkMapping[chain]), + project: 'circuit-protocol', + symbol: + poolMeta === undefined + ? 'CRCT' + : utils.formatSymbol(poolMeta?.assets.join('-')), + tvlUsd: poolData[pool], + apy: isActive ? apy[pool] * 100 : 0, + poolMeta: + platformId === undefined ? null : utils.formatChain(platformId), + underlyingTokens, + }); + } + } + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://circuit.farm/', +}; diff --git a/src/adaptors/civfund/abi.json b/src/adaptors/civfund/abi.json new file mode 100644 index 0000000000..fc46a12756 --- /dev/null +++ b/src/adaptors/civfund/abi.json @@ -0,0 +1,45 @@ +{ + "poolLength": { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "token0": { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + "token1": { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/civfund/index.js b/src/adaptors/civfund/index.js new file mode 100644 index 0000000000..59b1047021 --- /dev/null +++ b/src/adaptors/civfund/index.js @@ -0,0 +1,65 @@ +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const utils = require('../utils'); +const ABI = require('./abi.json'); + +const CIV_TOKEN = '0x37fE0f067FA808fFBDd12891C0858532CFE7361d'; +const MASTERCHEF_ADDRESS = '0x8a774F790aBEAEF97b118112c790D0dcccA61099'; +const POOLS_ONE_TOKEN = [ + '0x73a83269b9bbafc427e76be0a2c1a1db2a26f4c2', + '0x37fe0f067fa808ffbdd12891c0858532cfe7361d' +]; +const API_POOL_DATA = (poolId) => `https://api.civfund.org/getPoolData/${poolId}/?chainId=1`; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'ethereum', + abi: ABI.poolLength, + }); + + const poolRes = await Promise.all([...Array(Number(poolLength.output)).keys()].map((i) => utils.getData(API_POOL_DATA(i)))); + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: ABI[method], + calls: poolRes.filter(e => !POOLS_ONE_TOKEN.includes(e.lpToken)).map(({lpToken}) => ({ + target: lpToken, + })), + chain: 'ethereum', + requery: true, + }) + ) + ); + let tokens0 = underlyingToken0.output.map((res) => res.output); + let tokens1 = underlyingToken1.output.map((res) => res.output); + + tokens0 = [ + ...POOLS_ONE_TOKEN, + ...tokens0, + ]; + tokens1 = [undefined, undefined, ...tokens0]; + + const poolApy = poolRes.map((pool, i) => { + const apy = pool.roiPerYearPerc; + return { + pool: `ethereum:${pool.lpToken}`, + chain: utils.formatChain('ethereum'), + project: 'civfund', + symbol: `${pool.symbol1}${pool.symbol2 ? '-' + pool.symbol2 : ''}`, + tvlUsd: Number(pool.tvlUSD), + apy, + underlyingTokens: !pool.symbol2 ? [pool.lpToken] : [tokens0[i], tokens1[i]], + rewardTokens: ['0x73a83269b9bbafc427e76be0a2c1a1db2a26f4c2'] // ONE + } + }); + + return poolApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://civfund.org/', +}; diff --git a/src/adaptors/clave/abiClaveStaking.json b/src/adaptors/clave/abiClaveStaking.json new file mode 100644 index 0000000000..0929591942 --- /dev/null +++ b/src/adaptors/clave/abiClaveStaking.json @@ -0,0 +1,444 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_limitPerUser", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_totalLimit", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "ZK", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "finishAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getApy", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitPerUser", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "registry1", + "outputs": [ + { + "internalType": "contract IClaveRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "registry2", + "outputs": [ + { + "internalType": "contract IClaveRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_limitPerUser", + "type": "uint256" + } + ], + "name": "setLimitPerUser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_totalLimit", + "type": "uint256" + } + ], + "name": "setTotalLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updatedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/clave/index.js b/src/adaptors/clave/index.js new file mode 100644 index 0000000000..708fec3cec --- /dev/null +++ b/src/adaptors/clave/index.js @@ -0,0 +1,99 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); +const { + BigNumber, + utils: { formatUnits }, +} = require('ethers'); + +const abiClaveStaking = require('./abiClaveStaking.json'); + +const ZK = '0x5a7d6b2f92c77fad6ccabd7ee0624e64907eaf3e'; +const ZtakeV1Address = '0x9248F1Ee8cBD029F3D22A92EB270333a39846fB2'; + +const ONE_YEAR = 31557600; + +const POOL_CONFIG = { + zk: { + name: `clave-zk`, + abi: abiClaveStaking, + chain: 'era', + contract: ZtakeV1Address, + token: ZK, + type: 'v1', + }, +}; + +const buildTokenParam = (chain, address) => { + return `${chain}:${address}`; +}; + +const buildPriceUrl = (chain, address) => { + return `https://coins.llama.fi/prices/current/${buildTokenParam( + chain, + address + )}`; +}; + +const getTokenData = async (address) => { + const { data } = await axios.get(buildPriceUrl('era', address)); + return data.coins[buildTokenParam('era', address)]; +}; + +const getV1PoolData = async ({ abi, contract, chain, name, token }) => { + const { output: totalSupply } = await sdk.api.abi.call({ + target: contract, + abi: abi.find((m) => m.name === 'totalSupply'), + chain, + }); + + const { output: finishAt } = await sdk.api.abi.call({ + target: contract, + abi: abi.find((m) => m.name === 'finishAt'), + chain, + }); + + const { output: rewardRate } = await sdk.api.abi.call({ + target: contract, + abi: abi.find((m) => m.name === 'rewardRate'), + chain, + }); + + const { decimals, price, symbol } = await getTokenData(token); + + const formattedtotalSupply = formatUnits(totalSupply, decimals); + const tvlUsd = Number(formattedtotalSupply) * price; + + const NOW = finishAt >= Math.floor(Date.now() / 1000); + let formattedRewardAmount = 0; + let apyReward = 0; + + if (finishAt > NOW) { + formattedRewardAmount = formatUnits( + BigNumber.from(rewardRate).mul(ONE_YEAR).mul(100), + decimals + ); + apyReward = Number(formattedRewardAmount) / Number(formattedtotalSupply); + } + + return { + pool: name, + chain: utils.formatChain(chain), + project: 'clave', + symbol: utils.formatSymbol(symbol), + tvlUsd, + apyReward, + rewardTokens: [ZK], + }; +}; + +const getApy = async () => { + const zkPool = await getV1PoolData(POOL_CONFIG.zk); + return [zkPool].filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://getclave.io', +}; diff --git a/src/adaptors/clearpool-lending/index.js b/src/adaptors/clearpool-lending/index.js new file mode 100644 index 0000000000..2c4e44010f --- /dev/null +++ b/src/adaptors/clearpool-lending/index.js @@ -0,0 +1,66 @@ +// pnpm i -f +// pnpm i jest -g +// npm run test --adapter=clearpool + +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const toSentenceCase = (str) => { + if (!str) return str; + return str[0].toUpperCase() + str.slice(1).toLowerCase(); +}; + +const poolsFunction = async () => { + const query = gql` + { + allPools { + pool + chain + project + symbol + tvlUsd + apyBase + apyReward + rewardTokens + underlyingTokens + poolMeta + url + apyBaseBorrow + } + } + `; + const result = await request( + 'https://squid.subsquid.io/cpool-squid/v/v1/graphql', + query + ); + let pools = []; + if (result && result.allPools) { + result.allPools.map((pool) => { + let chainName; + switch (pool?.chain) { + case 'MAINNET': + chainName = 'Ethereum'; + break; + case 'ZKEVM': + chainName = 'Polygon zkEVM'; + break; + default: + chainName = toSentenceCase(pool.chain); + } + pool.chain = chainName; + pools.push(pool); + }); + } + + return pools.map((i) => ({ + ...i, + pool: i.pool.replace('-mainnet', '-ethereum'), + project: 'clearpool-lending', + })); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://clearpool.finance/', +}; diff --git a/src/adaptors/clip-finance/index.js b/src/adaptors/clip-finance/index.js new file mode 100644 index 0000000000..bf8bfc3a8b --- /dev/null +++ b/src/adaptors/clip-finance/index.js @@ -0,0 +1,81 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const CHAINS = { + bsc: 'bsc', + linea: 'linea', + base: 'base', +}; + +const POOLS_PAGE = 'https://clip.finance/earn'; + +const getUrl = (path, queries) => + `https://stats-kixqx.ondigitalocean.app/${path}${queries}`; + +const getPoolsApy = async () => { + const pools = []; + + // const poolsData = pairsToObj( + await Promise.all( + Object.keys(CHAINS).map(async (chain) => { + const apyResponse = await axios.get( + getUrl('pools-apy', `?chain=${CHAINS[chain]}`) + ); + const tvlResponse = await axios.get( + getUrl('pools-tvl', `?chain=${CHAINS[chain]}`) + ); + + const apyResponseData = apyResponse?.data; + const tvlResponseData = tvlResponse?.data; + + if (tvlResponseData?.status === 'pools_tvl_calculated') { + Object.keys(tvlResponseData.data).forEach((pool) => { + const poolData = tvlResponseData.data[pool]; + + const poolTvlSuccess = + poolData?.status === 'pool_tvl_calculated' && + poolData?.tvlUsd !== 0; + + const poolApySuccess = + apyResponseData?.status === 'pools_apy_calculated' && + apyResponseData?.data?.[pool]?.status === 'pool_apy_calculated'; + + const poolTotalApy = poolApySuccess + ? Number(apyResponseData.data[pool].apyTotal) + : 0; + + if (poolTvlSuccess) { + const poolObj = { + pool: `${poolData.poolAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'clip-finance', + symbol: poolData.tokensSymbols?.map((symbol) => symbol).join('-'), + tvlUsd: poolData.tvlUsd, + apy: poolTotalApy, + underlyingTokens: poolData.underlyingTokens, + url: `${POOLS_PAGE}/${pool}`, + }; + + // add reward and base APYs if reward token exists + if (!!apyResponseData?.data?.[pool]?.rewardTokenAddress) { + const rewardToken = apyResponseData.data[pool].rewardTokenAddress; + poolObj.rewardTokens = [rewardToken]; + poolObj.apyReward = Number(apyResponseData.data[pool].rewardApy); + poolObj.apyBase = Number(apyResponseData.data[pool].feeApy); + } + + pools.push(poolObj); + } + }); + } + }) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPoolsApy, + url: POOLS_PAGE, +}; diff --git a/src/adaptors/clipper/index.js b/src/adaptors/clipper/index.js new file mode 100644 index 0000000000..3714a056b3 --- /dev/null +++ b/src/adaptors/clipper/index.js @@ -0,0 +1,66 @@ +const { request } = require('graphql-request'); +const utils = require('../utils'); + +const ChainId = { + ETHEREUM: 1, + POLYGON: 137, + OPTIMISM: 10, + ARBITRUM: 42161, +}; + +const ChainNameById = { + [ChainId.ETHEREUM]: 'ethereum', + [ChainId.POLYGON]: 'polygon', + [ChainId.OPTIMISM]: 'optimism', + [ChainId.ARBITRUM]: 'arbitrum', +}; + +/** APIs url constants */ +const CLIPPER_POOL_API = 'https://clipper.exchange/api/apy'; +/** */ + +const getData = async (chainId) => { + const poolStatus = await utils.getData( + `${CLIPPER_POOL_API}?chain=${chainId}` + ); + return poolStatus; +}; + +const buildPoolInfo = (chainName, poolStatus, dailyPoolStatuses) => { + const { value_in_usd, address } = poolStatus.pool; + const assetSymbols = poolStatus.assets.map((asset) => asset.name).join('-'); + const formattedSymbol = utils.formatSymbol(assetSymbols); + const apy = poolStatus.apy; + + return { + pool: chainName === 'arbitrum' ? address.concat('-arbitrum') : address, + chain: utils.formatChain(chainName), + project: 'clipper', + symbol: formattedSymbol, + tvlUsd: value_in_usd, + apy, + }; +}; + +const topLvl = async (chainId) => { + const poolStatus = await getData(chainId); + const chainName = ChainNameById[chainId]; + + return buildPoolInfo(chainName, poolStatus); +}; + +const main = async () => { + const data = await Promise.allSettled([ + topLvl(ChainId.ETHEREUM), + topLvl(ChainId.POLYGON), + topLvl(ChainId.OPTIMISM), + topLvl(ChainId.ARBITRUM), + ]); + return data.filter((c) => c.status === 'fulfilled').map((c) => c.value); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://clipper.exchange/app/liquidity/pool', +}; diff --git a/src/adaptors/clober-v2/index.ts b/src/adaptors/clober-v2/index.ts new file mode 100644 index 0000000000..dd0065e5d5 --- /dev/null +++ b/src/adaptors/clober-v2/index.ts @@ -0,0 +1,62 @@ +const utils = require('../utils'); + +const API_URL = 'https://app.clober.io/api/chains/143/pools'; + +interface Pool { + key: string; + lpCurrency: { + id: string; + address: string; + name: string; + symbol: string; + decimals: number; + }; + currencyA: { + address: string; + name: string; + symbol: string; + decimals: number; + }; + currencyB: { + address: string; + name: string; + symbol: string; + decimals: number; + }; + totalTvlUSD: string; + apy: string; + baseApy: string; + merkleApy: string; +} + +const apy = async () => { + const data: Array = await utils.getData(API_URL); + + const pools = data.map((pool) => { + const merkleApy = Number(pool.merkleApy) || 0; + return { + pool: pool.key, + chain: utils.formatChain('monad'), + project: 'clober-v2', + symbol: pool.lpCurrency.symbol, + tvlUsd: Number(pool.totalTvlUSD), + apyBase: Number(pool.baseApy) || 0, + apyReward: merkleApy, + underlyingTokens: [pool.currencyA.address, pool.currencyB.address], + rewardTokens: + merkleApy > 0 + ? [ + '0x0000000000000000000000000000000000000000', // MON + ] + : [], + url: `https://app.clober.io/earn/${pool.key}`, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/coinbase-wrapped-staked-eth/abi.js b/src/adaptors/coinbase-wrapped-staked-eth/abi.js new file mode 100644 index 0000000000..3c01d968fe --- /dev/null +++ b/src/adaptors/coinbase-wrapped-staked-eth/abi.js @@ -0,0 +1,749 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'authorizer', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'nonce', + type: 'bytes32', + }, + ], + name: 'AuthorizationCanceled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'authorizer', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'nonce', + type: 'bytes32', + }, + ], + name: 'AuthorizationUsed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + name: 'Blacklisted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newBlacklister', + type: 'address', + }, + ], + name: 'BlacklisterChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'burner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oracle', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newExchangeRate', + type: 'uint256', + }, + ], + name: 'ExchangeRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newMasterMinter', + type: 'address', + }, + ], + name: 'MasterMinterChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'minterAllowedAmount', + type: 'uint256', + }, + ], + name: 'MinterConfigured', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldMinter', + type: 'address', + }, + ], + name: 'MinterRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newOracle', + type: 'address', + }, + ], + name: 'OracleUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Pause', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'PauserChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newRescuer', + type: 'address', + }, + ], + name: 'RescuerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + name: 'UnBlacklisted', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpause', type: 'event' }, + { + inputs: [], + name: 'CANCEL_AUTHORIZATION_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'RECEIVE_WITH_AUTHORIZATION_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'TRANSFER_WITH_AUTHORIZATION_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'authorizer', type: 'address' }, + { internalType: 'bytes32', name: 'nonce', type: 'bytes32' }, + ], + name: 'authorizationState', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'blacklist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'blacklister', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'authorizer', type: 'address' }, + { internalType: 'bytes32', name: 'nonce', type: 'bytes32' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'cancelAuthorization', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'minterAllowedAmount', type: 'uint256' }, + ], + name: 'configureMinter', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'currency', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'decrement', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRate', + outputs: [ + { internalType: 'uint256', name: '_exchangeRate', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'increment', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: 'tokenName', type: 'string' }, + { internalType: 'string', name: 'tokenSymbol', type: 'string' }, + { internalType: 'string', name: 'tokenCurrency', type: 'string' }, + { internalType: 'uint8', name: 'tokenDecimals', type: 'uint8' }, + { internalType: 'address', name: 'newMasterMinter', type: 'address' }, + { internalType: 'address', name: 'newPauser', type: 'address' }, + { internalType: 'address', name: 'newBlacklister', type: 'address' }, + { internalType: 'address', name: 'newOwner', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'string', name: 'newName', type: 'string' }], + name: 'initializeV2', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'lostAndFound', type: 'address' }, + ], + name: 'initializeV2_1', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'isBlacklisted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isMinter', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'masterMinter', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'minter', type: 'address' }], + name: 'minterAllowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracle', + outputs: [{ internalType: 'address', name: '_oracle', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauser', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'validAfter', type: 'uint256' }, + { internalType: 'uint256', name: 'validBefore', type: 'uint256' }, + { internalType: 'bytes32', name: 'nonce', type: 'bytes32' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'receiveWithAuthorization', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'minter', type: 'address' }], + name: 'removeMinter', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'tokenContract', + type: 'address', + }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'rescueERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rescuer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'validAfter', type: 'uint256' }, + { internalType: 'uint256', name: 'validBefore', type: 'uint256' }, + { internalType: 'bytes32', name: 'nonce', type: 'bytes32' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'transferWithAuthorization', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'unBlacklist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newBlacklister', type: 'address' }, + ], + name: 'updateBlacklister', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newExchangeRate', type: 'uint256' }, + ], + name: 'updateExchangeRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newMasterMinter', type: 'address' }, + ], + name: 'updateMasterMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOracle', type: 'address' }], + name: 'updateOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_newPauser', type: 'address' }], + name: 'updatePauser', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newRescuer', type: 'address' }], + name: 'updateRescuer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/coinbase-wrapped-staked-eth/index.js b/src/adaptors/coinbase-wrapped-staked-eth/index.js new file mode 100644 index 0000000000..044ed1acf8 --- /dev/null +++ b/src/adaptors/coinbase-wrapped-staked-eth/index.js @@ -0,0 +1,60 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abi = require('./abi.js'); + +const token = '0xBe9895146f7AF43049ca1c1AE358B0541Ea49704'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = ( + await axios.get('https://api.exchange.coinbase.com/wrapped-assets/CBETH') + ).data.circulating_supply; + + const timestamp1dayAgo = Math.floor(Date.now() / 1000) - 86400; + const duration = 1; // day + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'exchangeRate'), + chain: 'ethereum', + }), + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'exchangeRate'), + chain: 'ethereum', + block: block1dayAgo, + }), + ]); + + const apr = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18 / duration) * + 365 * + 100; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'coinbase-wrapped-staked-eth', + symbol: 'cbeth', + tvlUsd: tvl * ethPrice, + apyBase: apr, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://coinbase.com', +}; diff --git a/src/adaptors/coinhain/index.ts b/src/adaptors/coinhain/index.ts new file mode 100644 index 0000000000..a0db2f6882 --- /dev/null +++ b/src/adaptors/coinhain/index.ts @@ -0,0 +1,104 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); + +const query = gql` + query GetPools($chain: GqlChain!) { + poolGetPools( + first: 1000 + where: { chainIn: [$chain], protocolVersionIn: [3] } + ) { + chain + symbol + address + poolTokens { + address + symbol + } + dynamicData { + totalLiquidity + aprItems { + type + apr + rewardTokenAddress + } + } + } + } +`; + +const getV3Pools = async (backendChain, chainString) => { + try { + const { poolGetPools } = await request( + 'https://api.coinhain.fi/graphql', + query, + { chain: backendChain } + ); + + return poolGetPools + .filter( + (pool) => + pool.address.toLowerCase() !== + '0xfd3b274a5f0316ef3499de0a207b37ff9d7eefec' + ) + .map((pool) => { + const aprItems = pool.dynamicData.aprItems || []; + + const baseApr = aprItems + .filter( + (item) => item.type === 'IB_YIELD' || item.type === 'SWAP_FEE_24H' + ) + .reduce((sum, item) => sum + Number(item.apr), 0); + + const stakingApr = aprItems + .filter((item) => item.type === 'STAKING') + .reduce((sum, item) => sum + Number(item.apr), 0); + + const rewardTokens = aprItems + .filter((item) => item.type === 'STAKING' && item.rewardTokenAddress) + .map((item) => item.rewardTokenAddress); + + const underlyingTokens = pool.poolTokens + .map((token) => token.address) + .filter(Boolean); + + const chainUrl = chainString; + + return { + pool: pool.address, + chain: utils.formatChain(chainString), + project: 'coinhain', + symbol: utils.formatSymbol(pool.symbol), + tvlUsd: Number(pool.dynamicData.totalLiquidity), + apyBase: baseApr * 100, + apyReward: stakingApr * 100, + rewardTokens: rewardTokens, + underlyingTokens: underlyingTokens, + url: `https://app.coinhain.fi/pools/${chainUrl}/v3/${pool.address}`, + }; + }); + } catch (error) { + console.error( + `Error fetching Coinhain pools for ${chainString}:`, + error + ); + return []; + } +}; + +const poolsFunction = async () => { + const [ + bscPools + ] = await Promise.all([ + getV3Pools('BSC', 'bsc'), + ]); + + return [ + ...bscPools, + ]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://coinhain.fi/pools', +}; diff --git a/src/adaptors/colend-protocol/abis/ISubscriptionDataIncentiveProvider.json b/src/adaptors/colend-protocol/abis/ISubscriptionDataIncentiveProvider.json new file mode 100644 index 0000000000..99962fad55 --- /dev/null +++ b/src/adaptors/colend-protocol/abis/ISubscriptionDataIncentiveProvider.json @@ -0,0 +1,918 @@ +{ + "abi": [ + { + "type": "function", + "name": "getFullReservesIncentiveData", + "inputs": [ + { + "name": "subscriptionPool", + "type": "address", + "internalType": "contract ISubscriptionPool" + }, + { + "name": "user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]", + "components": [ + { + "name": "underlyingAsset", + "type": "address", + "internalType": "address" + }, + { + "name": "trackingIncentiveData", + "type": "tuple", + "internalType": "struct ISubscriptionDataIncentiveProvider.IncentiveData", + "components": [ + { + "name": "tokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "incentiveControllerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardsTokenInformation", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.RewardInfo[]", + "components": [ + { + "name": "rewardTokenSymbol", + "type": "string", + "internalType": "string" + }, + { + "name": "rewardTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardPriceId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "emissionPerSecond", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "incentivesLastUpdateTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokenIncentivesIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "emissionEndTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardPriceFeed", + "type": "int256", + "internalType": "int256" + }, + { + "name": "rewardTokenDecimals", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "precision", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "priceFeedDecimals", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ] + } + ] + }, + { + "name": "", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]", + "components": [ + { + "name": "underlyingAsset", + "type": "address", + "internalType": "address" + }, + { + "name": "trackingTokenIncentivesUserData", + "type": "tuple", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserIncentiveData", + "components": [ + { + "name": "tokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "incentiveControllerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "userRewardsInformation", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]", + "components": [ + { + "name": "rewardTokenSymbol", + "type": "string", + "internalType": "string" + }, + { + "name": "rewardPriceId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rewardTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "userUnclaimedRewards", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokenIncentivesUserIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardPriceFeed", + "type": "int256", + "internalType": "int256" + }, + { + "name": "priceFeedDecimals", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "rewardTokenDecimals", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getReservesIncentivesData", + "inputs": [ + { + "name": "subscriptionPool", + "type": "address", + "internalType": "contract ISubscriptionPool" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]", + "components": [ + { + "name": "underlyingAsset", + "type": "address", + "internalType": "address" + }, + { + "name": "trackingIncentiveData", + "type": "tuple", + "internalType": "struct ISubscriptionDataIncentiveProvider.IncentiveData", + "components": [ + { + "name": "tokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "incentiveControllerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardsTokenInformation", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.RewardInfo[]", + "components": [ + { + "name": "rewardTokenSymbol", + "type": "string", + "internalType": "string" + }, + { + "name": "rewardTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardPriceId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "emissionPerSecond", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "incentivesLastUpdateTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokenIncentivesIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "emissionEndTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardPriceFeed", + "type": "int256", + "internalType": "int256" + }, + { + "name": "rewardTokenDecimals", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "precision", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "priceFeedDecimals", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserReservesIncentivesData", + "inputs": [ + { + "name": "subscriptionPool", + "type": "address", + "internalType": "contract ISubscriptionPool" + }, + { + "name": "user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]", + "components": [ + { + "name": "underlyingAsset", + "type": "address", + "internalType": "address" + }, + { + "name": "trackingTokenIncentivesUserData", + "type": "tuple", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserIncentiveData", + "components": [ + { + "name": "tokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "incentiveControllerAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "userRewardsInformation", + "type": "tuple[]", + "internalType": "struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]", + "components": [ + { + "name": "rewardTokenSymbol", + "type": "string", + "internalType": "string" + }, + { + "name": "rewardPriceId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rewardTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "userUnclaimedRewards", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokenIncentivesUserIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rewardPriceFeed", + "type": "int256", + "internalType": "int256" + }, + { + "name": "priceFeedDecimals", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "rewardTokenDecimals", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ] + } + ] + } + ], + "stateMutability": "view" + } + ], + "bytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "methodIdentifiers": { + "getFullReservesIncentiveData(address,address)": "47637536", + "getReservesIncentivesData(address)": "976fafc5", + "getUserReservesIncentivesData(address,address)": "799bdcf5" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ISubscriptionPool\",\"name\":\"subscriptionPool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getFullReservesIncentiveData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"underlyingAsset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"incentiveControllerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"rewardTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"rewardTokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"rewardPriceId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"emissionPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"incentivesLastUpdateTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenIncentivesIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"emissionEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rewardPriceFeed\",\"type\":\"int256\"},{\"internalType\":\"uint8\",\"name\":\"rewardTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"precision\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"priceFeedDecimals\",\"type\":\"uint8\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.RewardInfo[]\",\"name\":\"rewardsTokenInformation\",\"type\":\"tuple[]\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.IncentiveData\",\"name\":\"trackingIncentiveData\",\"type\":\"tuple\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"underlyingAsset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"incentiveControllerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"rewardTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"rewardPriceId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"userUnclaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenIncentivesUserIndex\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rewardPriceFeed\",\"type\":\"int256\"},{\"internalType\":\"uint8\",\"name\":\"priceFeedDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"rewardTokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]\",\"name\":\"userRewardsInformation\",\"type\":\"tuple[]\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserIncentiveData\",\"name\":\"trackingTokenIncentivesUserData\",\"type\":\"tuple\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISubscriptionPool\",\"name\":\"subscriptionPool\",\"type\":\"address\"}],\"name\":\"getReservesIncentivesData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"underlyingAsset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"incentiveControllerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"rewardTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"rewardTokenAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"rewardPriceId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"emissionPerSecond\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"incentivesLastUpdateTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenIncentivesIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"emissionEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rewardPriceFeed\",\"type\":\"int256\"},{\"internalType\":\"uint8\",\"name\":\"rewardTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"precision\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"priceFeedDecimals\",\"type\":\"uint8\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.RewardInfo[]\",\"name\":\"rewardsTokenInformation\",\"type\":\"tuple[]\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.IncentiveData\",\"name\":\"trackingIncentiveData\",\"type\":\"tuple\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISubscriptionPool\",\"name\":\"subscriptionPool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getUserReservesIncentivesData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"underlyingAsset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"incentiveControllerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"rewardTokenSymbol\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"rewardPriceId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"userUnclaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenIncentivesUserIndex\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"rewardPriceFeed\",\"type\":\"int256\"},{\"internalType\":\"uint8\",\"name\":\"priceFeedDecimals\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"rewardTokenDecimals\",\"type\":\"uint8\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]\",\"name\":\"userRewardsInformation\",\"type\":\"tuple[]\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserIncentiveData\",\"name\":\"trackingTokenIncentivesUserData\",\"type\":\"tuple\"}],\"internalType\":\"struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/interfaces/ISubscriptionDataIncentiveProvider.sol\":\"ISubscriptionDataIncentiveProvider\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[\":@/=src/\",\":@aave/core-v3/contracts/=node_modules/@aave/core-v3/contracts/\",\":@aave/periphery-v3/contracts/=node_modules/@aave/periphery-v3/contracts/\",\":@ensdomains/=node_modules/@aave/periphery-v3/node_modules/@ensdomains/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@solmate/=node_modules/solmate/src/\",\":eth-gas-reporter/=node_modules/@aave/core-v3/node_modules/eth-gas-reporter/\",\":forge-std/=node_modules/forge-std/src/\",\":hardhat-deploy/=node_modules/@aave/core-v3/node_modules/hardhat-deploy/\",\":hardhat/=node_modules/@aave/core-v3/node_modules/hardhat/\",\":solmate/=node_modules/solmate/\",\":test/=test/\"],\"viaIR\":true},\"sources\":{\"node_modules/@aave/core-v3/contracts/interfaces/IAaveIncentivesController.sol\":{\"keccak256\":\"0x906b896fdcb878d1472f740a70680f26e9a601dc28701113ab1f89cd9edce0bd\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://b17473265a3ec2ec73dac797e0e60c147590f4e5cc7016f8eb61efbe072c49e0\",\"dweb:/ipfs/QmchQGeuyUw3VW4Kgwfg5Ys9ky1F7Q6QCcKbywbRaEUPt7\"]},\"node_modules/@aave/core-v3/contracts/interfaces/IPool.sol\":{\"keccak256\":\"0xbfd2077251c8dc766a56d45f4b03eb07f3441323e79c0f794efea3657a99747f\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://c6ff6221de0ea877932c73c0b99d3e4535f293053ae44f9f9d6b9d265e9af2f6\",\"dweb:/ipfs/QmSTaEKrhz1xNVnx4oBzWw8DenYPShVzJoP1A9GTEWkAzX\"]},\"node_modules/@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol\":{\"keccak256\":\"0x16468a4e76d9a330d9dcf9ff7ad0754265bd4d8aa81da5c468eb72fe08c85042\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://eb6e658e297ff3caa6a8e098a7eb082ddb71c54f88b2d5398e8995bb86732e1e\",\"dweb:/ipfs/QmZ5M8LaSZ3HdBEPwLT4KtsZYWcUqttX9eKpNdoYrWN4yW\"]},\"node_modules/@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol\":{\"keccak256\":\"0x771cb99fd8519c974f7e12130387c4d9a997a6e8d0ac10e4303b842fe53efa88\",\"license\":\"BUSL-1.1\",\"urls\":[\"bzz-raw://0f41689d1d58bc13678c749bae8830f5a8b19b89cd135e962bf07d483350f828\",\"dweb:/ipfs/QmQSNGDxjYGqT1GU2CZzsWUTNcAtcfkg1jDGTH516nCAfN\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db\",\"dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9\"]},\"src/interfaces/ISoulboundToken.sol\":{\"keccak256\":\"0x641ddca9f150248160e993026516ed3e3fbb5a02e6e8c23c19fef07d0f1d6e7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5166928e574e0d12409ecdccc809fc03963fa9e0aa7fb219315eef6b669301c5\",\"dweb:/ipfs/QmQXsakfZdgR579MaxPsoetzxEoYRXM9CJZ21Xph3rTfia\"]},\"src/interfaces/ISubscriptionDataIncentiveProvider.sol\":{\"keccak256\":\"0x896067a3c5948bb8740a272839440a59e60de77ce6dac4f9ff0da5de2995b3a9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://14c51a5b11ba32679a200de4c167516eb28878814e6e18816fcfca61da1eb5b4\",\"dweb:/ipfs/QmaVyx5Jzf77fcMLcEFAbKD7LB6izgAsrzfFhhdNBjvEA8\"]},\"src/interfaces/ISubscriptionPool.sol\":{\"keccak256\":\"0x6a2dd9a596cdaad3ac1b451a158f040e6f87e7547350547a5d6e7e6c87bf4b15\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7a301a0a9731df8cf1effe8cd6ef3594f913c18d3da86a072bcd380d4e7d6a2d\",\"dweb:/ipfs/QmSf5c2jm9MNoBvMkpx6dBaqZmgVCKJoqM16ug1mCcs5XP\"]},\"src/interfaces/IVirtualRewardTrackingToken.sol\":{\"keccak256\":\"0xf15fe407c1192166c01444807c979adfcc184303509dbf1ea183fc4106f7e632\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ae763bbfef658b65ea26bb029fb6a57c29e457dbc1a4f174e0f22f8d48c00d0b\",\"dweb:/ipfs/QmW1DKjbTkBqamvNqsEFBdEQ2DzHSRTpwzTDD4VAdJpTod\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.28+commit.7893614a" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { + "internalType": "contract ISubscriptionPool", + "name": "subscriptionPool", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getFullReservesIncentiveData", + "outputs": [ + { + "internalType": "struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]", + "name": "", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.IncentiveData", + "name": "trackingIncentiveData", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.RewardInfo[]", + "name": "rewardsTokenInformation", + "type": "tuple[]", + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "rewardPriceId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "emissionPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "incentivesLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionEndTimestamp", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "precision", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + } + ] + } + ] + } + ] + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]", + "name": "", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserIncentiveData", + "name": "trackingTokenIncentivesUserData", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]", + "name": "userRewardsInformation", + "type": "tuple[]", + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "rewardPriceId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "userUnclaimedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesUserIndex", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + } + ] + } + ] + } + ] + } + ] + }, + { + "inputs": [ + { + "internalType": "contract ISubscriptionPool", + "name": "subscriptionPool", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getReservesIncentivesData", + "outputs": [ + { + "internalType": "struct ISubscriptionDataIncentiveProvider.AggregatedReserveIncentiveData[]", + "name": "", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.IncentiveData", + "name": "trackingIncentiveData", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.RewardInfo[]", + "name": "rewardsTokenInformation", + "type": "tuple[]", + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "rewardPriceId", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "emissionPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "incentivesLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionEndTimestamp", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "precision", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + } + ] + } + ] + } + ] + } + ] + }, + { + "inputs": [ + { + "internalType": "contract ISubscriptionPool", + "name": "subscriptionPool", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getUserReservesIncentivesData", + "outputs": [ + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserReserveIncentiveData[]", + "name": "", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserIncentiveData", + "name": "trackingTokenIncentivesUserData", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "internalType": "struct ISubscriptionDataIncentiveProvider.UserRewardInfo[]", + "name": "userRewardsInformation", + "type": "tuple[]", + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "rewardPriceId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "userUnclaimedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesUserIndex", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + } + ] + } + ] + } + ] + } + ] + } + ], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@/=src/", + "@aave/core-v3/contracts/=node_modules/@aave/core-v3/contracts/", + "@aave/periphery-v3/contracts/=node_modules/@aave/periphery-v3/contracts/", + "@ensdomains/=node_modules/@aave/periphery-v3/node_modules/@ensdomains/", + "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", + "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", + "@solmate/=node_modules/solmate/src/", + "eth-gas-reporter/=node_modules/@aave/core-v3/node_modules/eth-gas-reporter/", + "forge-std/=node_modules/forge-std/src/", + "hardhat-deploy/=node_modules/@aave/core-v3/node_modules/hardhat-deploy/", + "hardhat/=node_modules/@aave/core-v3/node_modules/hardhat/", + "solmate/=node_modules/solmate/", + "test/=test/" + ], + "optimizer": { + "enabled": true, + "runs": 10000 + }, + "metadata": { + "bytecodeHash": "none" + }, + "compilationTarget": { + "src/interfaces/ISubscriptionDataIncentiveProvider.sol": "ISubscriptionDataIncentiveProvider" + }, + "evmVersion": "shanghai", + "libraries": {}, + "viaIR": true + }, + "sources": { + "node_modules/@aave/core-v3/contracts/interfaces/IAaveIncentivesController.sol": { + "keccak256": "0x906b896fdcb878d1472f740a70680f26e9a601dc28701113ab1f89cd9edce0bd", + "urls": [ + "bzz-raw://b17473265a3ec2ec73dac797e0e60c147590f4e5cc7016f8eb61efbe072c49e0", + "dweb:/ipfs/QmchQGeuyUw3VW4Kgwfg5Ys9ky1F7Q6QCcKbywbRaEUPt7" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/interfaces/IPool.sol": { + "keccak256": "0xbfd2077251c8dc766a56d45f4b03eb07f3441323e79c0f794efea3657a99747f", + "urls": [ + "bzz-raw://c6ff6221de0ea877932c73c0b99d3e4535f293053ae44f9f9d6b9d265e9af2f6", + "dweb:/ipfs/QmSTaEKrhz1xNVnx4oBzWw8DenYPShVzJoP1A9GTEWkAzX" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol": { + "keccak256": "0x16468a4e76d9a330d9dcf9ff7ad0754265bd4d8aa81da5c468eb72fe08c85042", + "urls": [ + "bzz-raw://eb6e658e297ff3caa6a8e098a7eb082ddb71c54f88b2d5398e8995bb86732e1e", + "dweb:/ipfs/QmZ5M8LaSZ3HdBEPwLT4KtsZYWcUqttX9eKpNdoYrWN4yW" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol": { + "keccak256": "0x771cb99fd8519c974f7e12130387c4d9a997a6e8d0ac10e4303b842fe53efa88", + "urls": [ + "bzz-raw://0f41689d1d58bc13678c749bae8830f5a8b19b89cd135e962bf07d483350f828", + "dweb:/ipfs/QmQSNGDxjYGqT1GU2CZzsWUTNcAtcfkg1jDGTH516nCAfN" + ], + "license": "BUSL-1.1" + }, + "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "keccak256": "0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7", + "urls": [ + "bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db", + "dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9" + ], + "license": "MIT" + }, + "src/interfaces/ISoulboundToken.sol": { + "keccak256": "0x641ddca9f150248160e993026516ed3e3fbb5a02e6e8c23c19fef07d0f1d6e7a", + "urls": [ + "bzz-raw://5166928e574e0d12409ecdccc809fc03963fa9e0aa7fb219315eef6b669301c5", + "dweb:/ipfs/QmQXsakfZdgR579MaxPsoetzxEoYRXM9CJZ21Xph3rTfia" + ], + "license": "MIT" + }, + "src/interfaces/ISubscriptionDataIncentiveProvider.sol": { + "keccak256": "0x896067a3c5948bb8740a272839440a59e60de77ce6dac4f9ff0da5de2995b3a9", + "urls": [ + "bzz-raw://14c51a5b11ba32679a200de4c167516eb28878814e6e18816fcfca61da1eb5b4", + "dweb:/ipfs/QmaVyx5Jzf77fcMLcEFAbKD7LB6izgAsrzfFhhdNBjvEA8" + ], + "license": "MIT" + }, + "src/interfaces/ISubscriptionPool.sol": { + "keccak256": "0x6a2dd9a596cdaad3ac1b451a158f040e6f87e7547350547a5d6e7e6c87bf4b15", + "urls": [ + "bzz-raw://7a301a0a9731df8cf1effe8cd6ef3594f913c18d3da86a072bcd380d4e7d6a2d", + "dweb:/ipfs/QmSf5c2jm9MNoBvMkpx6dBaqZmgVCKJoqM16ug1mCcs5XP" + ], + "license": "MIT" + }, + "src/interfaces/IVirtualRewardTrackingToken.sol": { + "keccak256": "0xf15fe407c1192166c01444807c979adfcc184303509dbf1ea183fc4106f7e632", + "urls": [ + "bzz-raw://ae763bbfef658b65ea26bb029fb6a57c29e457dbc1a4f174e0f22f8d48c00d0b", + "dweb:/ipfs/QmW1DKjbTkBqamvNqsEFBdEQ2DzHSRTpwzTDD4VAdJpTod" + ], + "license": "MIT" + } + }, + "version": 1 + }, + "id": 85 +} diff --git a/src/adaptors/colend-protocol/abis/ISubscriptionPool.json b/src/adaptors/colend-protocol/abis/ISubscriptionPool.json new file mode 100644 index 0000000000..cd8eb0e999 --- /dev/null +++ b/src/adaptors/colend-protocol/abis/ISubscriptionPool.json @@ -0,0 +1,1296 @@ +{ + "abi": [ + { + "type": "function", + "name": "batchSyncUserBalance", + "inputs": [ + { + "name": "ops", + "type": "tuple[]", + "internalType": "struct ISubscriptionPool.SyncBalanceOperation[]", + "components": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + }, + { + "name": "accounts", + "type": "address[]", + "internalType": "address[]" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createVirtualRewardTrackingToken", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IVirtualRewardTrackingToken" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "incentivesController", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IAaveIncentivesController" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isSubscriptionAllowed", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "overrideUserBalance", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + }, + { + "name": "newBalance", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "pool", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IPool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setIncentivesController", + "inputs": [ + { + "name": "controller", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setSoulboundToken", + "inputs": [ + { + "name": "newToken", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setSubscriptionAllowed", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + }, + { + "name": "allowed", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setTrackingTokenImpl", + "inputs": [ + { + "name": "_trackingTokenImpl", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "soulboundToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ISoulboundToken" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "supply", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "onBehalfOf", + "type": "address", + "internalType": "address" + }, + { + "name": "referralCode", + "type": "uint16", + "internalType": "uint16" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "syncUserBalance", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + }, + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "trackingTokenImpl", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "virtualRewardTrackingTokens", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "BalanceOverridden", + "inputs": [ + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "balance", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BalanceSynced", + "inputs": [ + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "balance", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BatchBalanceSynced", + "inputs": [ + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "accounts", + "type": "address[]", + "indexed": false, + "internalType": "address[]" + }, + { + "name": "balances", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "IncentivesControllerUpdated", + "inputs": [ + { + "name": "oldController", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newController", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "PoolUpdated", + "inputs": [ + { + "name": "oldPool", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newPool", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SoulboundTokenUpdated", + "inputs": [ + { + "name": "oldToken", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newToken", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SubscriptionAllowedUpdated", + "inputs": [ + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldAllowed", + "type": "bool", + "indexed": false, + "internalType": "bool" + }, + { + "name": "newAllowed", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Supply", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "VirtualRewardTrackingTokenCreated", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Withdraw", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "asset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "InvalidATokenAddress", + "inputs": [] + }, + { + "type": "error", + "name": "TrackingTokenAlreadyCreated", + "inputs": [ + { + "name": "createdTrackingTokenAddr", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "TrackingTokenPoolMismatched", + "inputs": [ + { + "name": "subscriptionPool", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenPool", + "type": "address", + "internalType": "address" + } + ] + } + ], + "bytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x", + "sourceMap": "", + "linkReferences": {} + }, + "methodIdentifiers": { + "batchSyncUserBalance((address,address[])[])": "7e9477b6", + "createVirtualRewardTrackingToken(address)": "1317dc29", + "incentivesController()": "af1df255", + "isSubscriptionAllowed(address)": "e948fb20", + "overrideUserBalance(address,address,uint256)": "08942c16", + "pool()": "16f0115b", + "setIncentivesController(address)": "e655dbd8", + "setSoulboundToken(address)": "2432a951", + "setSubscriptionAllowed(address,bool)": "dba49658", + "setTrackingTokenImpl(address)": "9fa70aca", + "soulboundToken()": "a7192492", + "supply(address,uint256,address,uint16)": "617ba037", + "syncUserBalance(address,address)": "eaaed22b", + "trackingTokenImpl()": "f23a9b8c", + "virtualRewardTrackingTokens(address)": "2c8b9295" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"InvalidATokenAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"createdTrackingTokenAddr\",\"type\":\"address\"}],\"name\":\"TrackingTokenAlreadyCreated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriptionPool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenPool\",\"type\":\"address\"}],\"name\":\"TrackingTokenPoolMismatched\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"}],\"name\":\"BatchBalanceSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldController\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newController\",\"type\":\"address\"}],\"name\":\"IncentivesControllerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldPool\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newPool\",\"type\":\"address\"}],\"name\":\"PoolUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newToken\",\"type\":\"address\"}],\"name\":\"SoulboundTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"oldAllowed\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"newAllowed\",\"type\":\"bool\"}],\"name\":\"SubscriptionAllowedUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Supply\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"VirtualRewardTrackingTokenCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"}],\"internalType\":\"struct ISubscriptionPool.SyncBalanceOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"}],\"name\":\"batchSyncUserBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"createVirtualRewardTrackingToken\",\"outputs\":[{\"internalType\":\"contract IVirtualRewardTrackingToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"incentivesController\",\"outputs\":[{\"internalType\":\"contract IAaveIncentivesController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"isSubscriptionAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"overrideUserBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pool\",\"outputs\":[{\"internalType\":\"contract IPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setIncentivesController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newToken\",\"type\":\"address\"}],\"name\":\"setSoulboundToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setSubscriptionAllowed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_trackingTokenImpl\",\"type\":\"address\"}],\"name\":\"setTrackingTokenImpl\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"soulboundToken\",\"outputs\":[{\"internalType\":\"contract ISoulboundToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"referralCode\",\"type\":\"uint16\"}],\"name\":\"supply\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"syncUserBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trackingTokenImpl\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"virtualRewardTrackingTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"batchSyncUserBalance((address,address[])[])\":{\"custom:access\":\"Only callable by accounts with the `OPERATOR_ROLE`.\",\"custom:events\":\"Emits a `BatchBalanceSynced` event after all balances are updated.\",\"details\":\"Iterates through an array of `SyncBalanceOperation` structs, each containing an asset and a list of user accounts. Updates each user's virtual reward tracking token balance to match their corresponding AToken balance. Can only be called by an account with the `OPERATOR_ROLE`.\",\"params\":{\"ops\":\"An array of `SyncBalanceOperation` structs, where each struct contains: - `asset`: The address of the ERC20 token. - `accounts`: An array of user addresses whose balances need to be synchronized.\"}},\"createVirtualRewardTrackingToken(address)\":{\"custom:access\":\"Only callable by `OPERATOR_ROLE`.\",\"custom:events\":\"Emits a `VirtualRewardTrackingTokenCreated` event with the new token address.\",\"details\":\"If a tracking token for the asset does not exist, it deploys a new one using the tracking token implementation via the `Clones` library. The new token is mapped to the asset for future use.\",\"params\":{\"asset\":\"The ERC20 token address for which the tracking token is created.\"},\"returns\":{\"_0\":\"The address of the newly created virtual reward tracking token.\"}},\"isSubscriptionAllowed(address)\":{\"params\":{\"asset\":\"The ERC20 token address.\"},\"returns\":{\"_0\":\"`true` if allowed, `false` otherwise.\"}},\"overrideUserBalance(address,address,uint256)\":{\"params\":{\"account\":\"The user's address.\",\"asset\":\"The ERC20 token address.\",\"newBalance\":\"The new balance to set.\"}},\"setIncentivesController(address)\":{\"params\":{\"controller\":\"The new Incentives Controller address.\"}},\"setSoulboundToken(address)\":{\"params\":{\"newToken\":\"The new Soulbound Token address.\"}},\"setSubscriptionAllowed(address,bool)\":{\"params\":{\"allowed\":\"`true` to allow, `false` to disallow.\",\"asset\":\"The ERC20 token address.\"}},\"setTrackingTokenImpl(address)\":{\"params\":{\"_trackingTokenImpl\":\"The new tracking token implementation address.\"}},\"supply(address,uint256,address,uint16)\":{\"custom:events\":\"Emits a `Supply` event after successfully supplying the asset.\",\"custom:requirements\":\"- `msg.sender` must have approved at least `amount` of `asset` to the subscription pool. - `asset` must be allowed for subscription.\",\"details\":\"Transfers the asset from the caller to the contract, approves the reserve pool, and supplies it. After supplying, it synchronizes the user's virtual reward tracking token balance with their AToken balance. The caller must have approved the subscription pool to spend the asset before calling this function.\",\"params\":{\"amount\":\"The amount of the asset to supply.\",\"asset\":\"The address of the ERC20 token to be supplied.\",\"onBehalfOf\":\"The address of the user on whose behalf the deposit is made.\",\"referralCode\":\"The referral code (0 if not used).\"}},\"syncUserBalance(address,address)\":{\"custom:access\":\"Only callable by accounts with the `OPERATOR_ROLE`.\",\"custom:events\":\"Emits a `BalanceSynced` event with the updated balance.\",\"details\":\"This function updates the tracked balance of the specified user for a given asset by fetching their scaled balance from the corresponding AToken. Can only be called by an account with the `OPERATOR_ROLE`.\",\"params\":{\"account\":\"The address of the user whose balance needs to be updated.\",\"asset\":\"The address of the ERC20 token for which the balance should be synchronized.\"}},\"virtualRewardTrackingTokens(address)\":{\"params\":{\"asset\":\"The ERC20 token address.\"},\"returns\":{\"_0\":\"The associated virtual reward tracking token address.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"batchSyncUserBalance((address,address[])[])\":{\"notice\":\"Batch synchronizes the virtual reward tracking token balances for multiple users and assets.\"},\"createVirtualRewardTrackingToken(address)\":{\"notice\":\"Creates a virtual reward tracking token for a specific asset.\"},\"incentivesController()\":{\"notice\":\"Returns the RewardController address.\"},\"isSubscriptionAllowed(address)\":{\"notice\":\"Checks if an asset is allowed for subscription.\"},\"overrideUserBalance(address,address,uint256)\":{\"notice\":\"Overrides a user's virtual reward tracking token balance for a specific asset.\"},\"pool()\":{\"notice\":\"Returns the reserve pool address.\"},\"setIncentivesController(address)\":{\"notice\":\"Updates the Incentives Controller.\"},\"setSoulboundToken(address)\":{\"notice\":\"Sets a new Soulbound Token contract.\"},\"setSubscriptionAllowed(address,bool)\":{\"notice\":\"Allows or disallows a specific asset for subscription.\"},\"setTrackingTokenImpl(address)\":{\"notice\":\"Sets the implementation for virtual reward tracking tokens.\"},\"soulboundToken()\":{\"notice\":\"Returns the subscription Soulbound token address.\"},\"supply(address,uint256,address,uint16)\":{\"notice\":\"Deposits a specified amount of an asset into the reserve pool on behalf of a user.\"},\"syncUserBalance(address,address)\":{\"notice\":\"Synchronizes the virtual reward tracking token balance of a user with their AToken balance.\"},\"trackingTokenImpl()\":{\"notice\":\"Returns VirtualRewardTrackingToken implementation address.\"},\"virtualRewardTrackingTokens(address)\":{\"notice\":\"Returns the virtual reward tracking token address for a given asset.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/interfaces/ISubscriptionPool.sol\":\"ISubscriptionPool\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[\":@/=src/\",\":@aave/core-v3/contracts/=node_modules/@aave/core-v3/contracts/\",\":@aave/periphery-v3/contracts/=node_modules/@aave/periphery-v3/contracts/\",\":@ensdomains/=node_modules/@aave/periphery-v3/node_modules/@ensdomains/\",\":@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/\",\":@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/\",\":@solmate/=node_modules/solmate/src/\",\":eth-gas-reporter/=node_modules/@aave/core-v3/node_modules/eth-gas-reporter/\",\":forge-std/=node_modules/forge-std/src/\",\":hardhat-deploy/=node_modules/@aave/core-v3/node_modules/hardhat-deploy/\",\":hardhat/=node_modules/@aave/core-v3/node_modules/hardhat/\",\":solmate/=node_modules/solmate/\",\":test/=test/\"],\"viaIR\":true},\"sources\":{\"node_modules/@aave/core-v3/contracts/interfaces/IAaveIncentivesController.sol\":{\"keccak256\":\"0x906b896fdcb878d1472f740a70680f26e9a601dc28701113ab1f89cd9edce0bd\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://b17473265a3ec2ec73dac797e0e60c147590f4e5cc7016f8eb61efbe072c49e0\",\"dweb:/ipfs/QmchQGeuyUw3VW4Kgwfg5Ys9ky1F7Q6QCcKbywbRaEUPt7\"]},\"node_modules/@aave/core-v3/contracts/interfaces/IPool.sol\":{\"keccak256\":\"0xbfd2077251c8dc766a56d45f4b03eb07f3441323e79c0f794efea3657a99747f\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://c6ff6221de0ea877932c73c0b99d3e4535f293053ae44f9f9d6b9d265e9af2f6\",\"dweb:/ipfs/QmSTaEKrhz1xNVnx4oBzWw8DenYPShVzJoP1A9GTEWkAzX\"]},\"node_modules/@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol\":{\"keccak256\":\"0x16468a4e76d9a330d9dcf9ff7ad0754265bd4d8aa81da5c468eb72fe08c85042\",\"license\":\"AGPL-3.0\",\"urls\":[\"bzz-raw://eb6e658e297ff3caa6a8e098a7eb082ddb71c54f88b2d5398e8995bb86732e1e\",\"dweb:/ipfs/QmZ5M8LaSZ3HdBEPwLT4KtsZYWcUqttX9eKpNdoYrWN4yW\"]},\"node_modules/@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol\":{\"keccak256\":\"0x771cb99fd8519c974f7e12130387c4d9a997a6e8d0ac10e4303b842fe53efa88\",\"license\":\"BUSL-1.1\",\"urls\":[\"bzz-raw://0f41689d1d58bc13678c749bae8830f5a8b19b89cd135e962bf07d483350f828\",\"dweb:/ipfs/QmQSNGDxjYGqT1GU2CZzsWUTNcAtcfkg1jDGTH516nCAfN\"]},\"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db\",\"dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9\"]},\"src/interfaces/ISoulboundToken.sol\":{\"keccak256\":\"0x641ddca9f150248160e993026516ed3e3fbb5a02e6e8c23c19fef07d0f1d6e7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5166928e574e0d12409ecdccc809fc03963fa9e0aa7fb219315eef6b669301c5\",\"dweb:/ipfs/QmQXsakfZdgR579MaxPsoetzxEoYRXM9CJZ21Xph3rTfia\"]},\"src/interfaces/ISubscriptionPool.sol\":{\"keccak256\":\"0x6a2dd9a596cdaad3ac1b451a158f040e6f87e7547350547a5d6e7e6c87bf4b15\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7a301a0a9731df8cf1effe8cd6ef3594f913c18d3da86a072bcd380d4e7d6a2d\",\"dweb:/ipfs/QmSf5c2jm9MNoBvMkpx6dBaqZmgVCKJoqM16ug1mCcs5XP\"]},\"src/interfaces/IVirtualRewardTrackingToken.sol\":{\"keccak256\":\"0xf15fe407c1192166c01444807c979adfcc184303509dbf1ea183fc4106f7e632\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ae763bbfef658b65ea26bb029fb6a57c29e457dbc1a4f174e0f22f8d48c00d0b\",\"dweb:/ipfs/QmW1DKjbTkBqamvNqsEFBdEQ2DzHSRTpwzTDD4VAdJpTod\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.28+commit.7893614a" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [], + "type": "error", + "name": "InvalidATokenAddress" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "createdTrackingTokenAddr", + "type": "address" + } + ], + "type": "error", + "name": "TrackingTokenAlreadyCreated" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subscriptionPool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenPool", + "type": "address" + } + ], + "type": "error", + "name": "TrackingTokenPoolMismatched" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "account", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "BalanceOverridden", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "account", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "BalanceSynced", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]", + "indexed": false + }, + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]", + "indexed": false + } + ], + "type": "event", + "name": "BatchBalanceSynced", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldController", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "newController", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "IncentivesControllerUpdated", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldPool", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "newPool", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "PoolUpdated", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldToken", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "newToken", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "SoulboundTokenUpdated", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "bool", + "name": "oldAllowed", + "type": "bool", + "indexed": false + }, + { + "internalType": "bool", + "name": "newAllowed", + "type": "bool", + "indexed": false + } + ], + "type": "event", + "name": "SubscriptionAllowedUpdated", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "Supply", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "VirtualRewardTrackingTokenCreated", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "asset", + "type": "address", + "indexed": true + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256", + "indexed": false + } + ], + "type": "event", + "name": "Withdraw", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "struct ISubscriptionPool.SyncBalanceOperation[]", + "name": "ops", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "batchSyncUserBalance" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "createVirtualRewardTrackingToken", + "outputs": [ + { + "internalType": "contract IVirtualRewardTrackingToken", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "incentivesController", + "outputs": [ + { + "internalType": "contract IAaveIncentivesController", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isSubscriptionAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "overrideUserBalance" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "pool", + "outputs": [ + { + "internalType": "contract IPool", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setIncentivesController" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setSoulboundToken" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setSubscriptionAllowed" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_trackingTokenImpl", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setTrackingTokenImpl" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "soulboundToken", + "outputs": [ + { + "internalType": "contract ISoulboundToken", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "supply" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "syncUserBalance" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "trackingTokenImpl", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "virtualRewardTrackingTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "batchSyncUserBalance((address,address[])[])": { + "custom:access": "Only callable by accounts with the `OPERATOR_ROLE`.", + "custom:events": "Emits a `BatchBalanceSynced` event after all balances are updated.", + "details": "Iterates through an array of `SyncBalanceOperation` structs, each containing an asset and a list of user accounts. Updates each user's virtual reward tracking token balance to match their corresponding AToken balance. Can only be called by an account with the `OPERATOR_ROLE`.", + "params": { + "ops": "An array of `SyncBalanceOperation` structs, where each struct contains: - `asset`: The address of the ERC20 token. - `accounts`: An array of user addresses whose balances need to be synchronized." + } + }, + "createVirtualRewardTrackingToken(address)": { + "custom:access": "Only callable by `OPERATOR_ROLE`.", + "custom:events": "Emits a `VirtualRewardTrackingTokenCreated` event with the new token address.", + "details": "If a tracking token for the asset does not exist, it deploys a new one using the tracking token implementation via the `Clones` library. The new token is mapped to the asset for future use.", + "params": { + "asset": "The ERC20 token address for which the tracking token is created." + }, + "returns": { + "_0": "The address of the newly created virtual reward tracking token." + } + }, + "isSubscriptionAllowed(address)": { + "params": { + "asset": "The ERC20 token address." + }, + "returns": { + "_0": "`true` if allowed, `false` otherwise." + } + }, + "overrideUserBalance(address,address,uint256)": { + "params": { + "account": "The user's address.", + "asset": "The ERC20 token address.", + "newBalance": "The new balance to set." + } + }, + "setIncentivesController(address)": { + "params": { + "controller": "The new Incentives Controller address." + } + }, + "setSoulboundToken(address)": { + "params": { + "newToken": "The new Soulbound Token address." + } + }, + "setSubscriptionAllowed(address,bool)": { + "params": { + "allowed": "`true` to allow, `false` to disallow.", + "asset": "The ERC20 token address." + } + }, + "setTrackingTokenImpl(address)": { + "params": { + "_trackingTokenImpl": "The new tracking token implementation address." + } + }, + "supply(address,uint256,address,uint16)": { + "custom:events": "Emits a `Supply` event after successfully supplying the asset.", + "custom:requirements": "- `msg.sender` must have approved at least `amount` of `asset` to the subscription pool. - `asset` must be allowed for subscription.", + "details": "Transfers the asset from the caller to the contract, approves the reserve pool, and supplies it. After supplying, it synchronizes the user's virtual reward tracking token balance with their AToken balance. The caller must have approved the subscription pool to spend the asset before calling this function.", + "params": { + "amount": "The amount of the asset to supply.", + "asset": "The address of the ERC20 token to be supplied.", + "onBehalfOf": "The address of the user on whose behalf the deposit is made.", + "referralCode": "The referral code (0 if not used)." + } + }, + "syncUserBalance(address,address)": { + "custom:access": "Only callable by accounts with the `OPERATOR_ROLE`.", + "custom:events": "Emits a `BalanceSynced` event with the updated balance.", + "details": "This function updates the tracked balance of the specified user for a given asset by fetching their scaled balance from the corresponding AToken. Can only be called by an account with the `OPERATOR_ROLE`.", + "params": { + "account": "The address of the user whose balance needs to be updated.", + "asset": "The address of the ERC20 token for which the balance should be synchronized." + } + }, + "virtualRewardTrackingTokens(address)": { + "params": { + "asset": "The ERC20 token address." + }, + "returns": { + "_0": "The associated virtual reward tracking token address." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "batchSyncUserBalance((address,address[])[])": { + "notice": "Batch synchronizes the virtual reward tracking token balances for multiple users and assets." + }, + "createVirtualRewardTrackingToken(address)": { + "notice": "Creates a virtual reward tracking token for a specific asset." + }, + "incentivesController()": { + "notice": "Returns the RewardController address." + }, + "isSubscriptionAllowed(address)": { + "notice": "Checks if an asset is allowed for subscription." + }, + "overrideUserBalance(address,address,uint256)": { + "notice": "Overrides a user's virtual reward tracking token balance for a specific asset." + }, + "pool()": { + "notice": "Returns the reserve pool address." + }, + "setIncentivesController(address)": { + "notice": "Updates the Incentives Controller." + }, + "setSoulboundToken(address)": { + "notice": "Sets a new Soulbound Token contract." + }, + "setSubscriptionAllowed(address,bool)": { + "notice": "Allows or disallows a specific asset for subscription." + }, + "setTrackingTokenImpl(address)": { + "notice": "Sets the implementation for virtual reward tracking tokens." + }, + "soulboundToken()": { + "notice": "Returns the subscription Soulbound token address." + }, + "supply(address,uint256,address,uint16)": { + "notice": "Deposits a specified amount of an asset into the reserve pool on behalf of a user." + }, + "syncUserBalance(address,address)": { + "notice": "Synchronizes the virtual reward tracking token balance of a user with their AToken balance." + }, + "trackingTokenImpl()": { + "notice": "Returns VirtualRewardTrackingToken implementation address." + }, + "virtualRewardTrackingTokens(address)": { + "notice": "Returns the virtual reward tracking token address for a given asset." + } + }, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@/=src/", + "@aave/core-v3/contracts/=node_modules/@aave/core-v3/contracts/", + "@aave/periphery-v3/contracts/=node_modules/@aave/periphery-v3/contracts/", + "@ensdomains/=node_modules/@aave/periphery-v3/node_modules/@ensdomains/", + "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", + "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", + "@solmate/=node_modules/solmate/src/", + "eth-gas-reporter/=node_modules/@aave/core-v3/node_modules/eth-gas-reporter/", + "forge-std/=node_modules/forge-std/src/", + "hardhat-deploy/=node_modules/@aave/core-v3/node_modules/hardhat-deploy/", + "hardhat/=node_modules/@aave/core-v3/node_modules/hardhat/", + "solmate/=node_modules/solmate/", + "test/=test/" + ], + "optimizer": { + "enabled": true, + "runs": 10000 + }, + "metadata": { + "bytecodeHash": "none" + }, + "compilationTarget": { + "src/interfaces/ISubscriptionPool.sol": "ISubscriptionPool" + }, + "evmVersion": "shanghai", + "libraries": {}, + "viaIR": true + }, + "sources": { + "node_modules/@aave/core-v3/contracts/interfaces/IAaveIncentivesController.sol": { + "keccak256": "0x906b896fdcb878d1472f740a70680f26e9a601dc28701113ab1f89cd9edce0bd", + "urls": [ + "bzz-raw://b17473265a3ec2ec73dac797e0e60c147590f4e5cc7016f8eb61efbe072c49e0", + "dweb:/ipfs/QmchQGeuyUw3VW4Kgwfg5Ys9ky1F7Q6QCcKbywbRaEUPt7" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/interfaces/IPool.sol": { + "keccak256": "0xbfd2077251c8dc766a56d45f4b03eb07f3441323e79c0f794efea3657a99747f", + "urls": [ + "bzz-raw://c6ff6221de0ea877932c73c0b99d3e4535f293053ae44f9f9d6b9d265e9af2f6", + "dweb:/ipfs/QmSTaEKrhz1xNVnx4oBzWw8DenYPShVzJoP1A9GTEWkAzX" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol": { + "keccak256": "0x16468a4e76d9a330d9dcf9ff7ad0754265bd4d8aa81da5c468eb72fe08c85042", + "urls": [ + "bzz-raw://eb6e658e297ff3caa6a8e098a7eb082ddb71c54f88b2d5398e8995bb86732e1e", + "dweb:/ipfs/QmZ5M8LaSZ3HdBEPwLT4KtsZYWcUqttX9eKpNdoYrWN4yW" + ], + "license": "AGPL-3.0" + }, + "node_modules/@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol": { + "keccak256": "0x771cb99fd8519c974f7e12130387c4d9a997a6e8d0ac10e4303b842fe53efa88", + "urls": [ + "bzz-raw://0f41689d1d58bc13678c749bae8830f5a8b19b89cd135e962bf07d483350f828", + "dweb:/ipfs/QmQSNGDxjYGqT1GU2CZzsWUTNcAtcfkg1jDGTH516nCAfN" + ], + "license": "BUSL-1.1" + }, + "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "keccak256": "0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7", + "urls": [ + "bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db", + "dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9" + ], + "license": "MIT" + }, + "src/interfaces/ISoulboundToken.sol": { + "keccak256": "0x641ddca9f150248160e993026516ed3e3fbb5a02e6e8c23c19fef07d0f1d6e7a", + "urls": [ + "bzz-raw://5166928e574e0d12409ecdccc809fc03963fa9e0aa7fb219315eef6b669301c5", + "dweb:/ipfs/QmQXsakfZdgR579MaxPsoetzxEoYRXM9CJZ21Xph3rTfia" + ], + "license": "MIT" + }, + "src/interfaces/ISubscriptionPool.sol": { + "keccak256": "0x6a2dd9a596cdaad3ac1b451a158f040e6f87e7547350547a5d6e7e6c87bf4b15", + "urls": [ + "bzz-raw://7a301a0a9731df8cf1effe8cd6ef3594f913c18d3da86a072bcd380d4e7d6a2d", + "dweb:/ipfs/QmSf5c2jm9MNoBvMkpx6dBaqZmgVCKJoqM16ug1mCcs5XP" + ], + "license": "MIT" + }, + "src/interfaces/IVirtualRewardTrackingToken.sol": { + "keccak256": "0xf15fe407c1192166c01444807c979adfcc184303509dbf1ea183fc4106f7e632", + "urls": [ + "bzz-raw://ae763bbfef658b65ea26bb029fb6a57c29e457dbc1a4f174e0f22f8d48c00d0b", + "dweb:/ipfs/QmW1DKjbTkBqamvNqsEFBdEQ2DzHSRTpwzTDD4VAdJpTod" + ], + "license": "MIT" + } + }, + "version": 1 + }, + "id": 86 +} diff --git a/src/adaptors/colend-protocol/index.js b/src/adaptors/colend-protocol/index.js new file mode 100644 index 0000000000..d17b57efcc --- /dev/null +++ b/src/adaptors/colend-protocol/index.js @@ -0,0 +1,203 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); +const ISubscriptionDataIncentiveProvider = require('./abis/ISubscriptionDataIncentiveProvider.json'); +const chain = 'core'; + +// List of PoolDataProviders where you can add additional 0x addresses as needed. +const poolDataProviders = [ + '0x567AF83d912C85c7a66d093e41D92676fA9076E3', // Main market + '0x8E43DF2503c69b090D385E36032814c73b746e3d', // LSTBTC market + // Add more PoolDataProvider addresses here as needed +]; + +const subscriptionDataIncentiveProvider = '0xa839c32CF4bA69f8c0eb06fA6BFc57C40B3f3f83'; +const subscriptionPool = '0x971A4AD43a98a0d17833aB8c9FeC25b93a38B9A3'; +const fetchMarketData = async (target) => { + const [reserveTokens, aTokens] = await Promise.all([ + sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }), + sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }), + ]).then(([reserves, atokens]) => [reserves.output, atokens.output]); + + // Helper function to calculate reward APY + const calculateRewardAPY = async ( + incentiveData, + tokenDecimals, + tokenPrice + ) => { + if ( + !incentiveData || + !incentiveData.trackingIncentiveData || + incentiveData.trackingIncentiveData.rewardsTokenInformation.length === 0 + ) { + return { apyReward: 0, rewardTokens: [] }; + } + + let trackingTokenTotalSupply = await sdk.api.abi.call({ + target: incentiveData.trackingIncentiveData.tokenAddress, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + chain, + }); + let totalSupplyInUsd = (trackingTokenTotalSupply.output / 10 ** tokenDecimals) * tokenPrice; + let totalRewardAPY = 0; + const rewardTokens = []; + incentiveData.trackingIncentiveData.rewardsTokenInformation.forEach((reward) => { + const { + rewardTokenAddress, + emissionPerSecond, + rewardPriceFeed, + rewardTokenDecimals, + priceFeedDecimals, + emissionEndTimestamp, + } = reward; + + // Skip if emissions have ended + const currentTimestamp = Math.floor(Date.now() / 1000); + if (emissionEndTimestamp > 0 && currentTimestamp > emissionEndTimestamp) { + return; + } + + // Skip if no emissions + if (!emissionPerSecond || emissionPerSecond === '0') { + return; + } + + // Calculate reward token price + const rewardPrice = + rewardPriceFeed > 0 + ? Number(rewardPriceFeed) / 10 ** Number(priceFeedDecimals) + : 0; + if ( + rewardPrice > 0 && + totalSupplyInUsd > 0 + ) { + // Calculate annual reward emissions + const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; + const annualRewardTokens = + (Number(emissionPerSecond) / 10 ** Number(rewardTokenDecimals)) * + SECONDS_PER_YEAR; + const annualRewardUSD = annualRewardTokens * rewardPrice; + // Calculate reward APY as a percentage + const rewardAPY = (annualRewardUSD / totalSupplyInUsd) * 100; + totalRewardAPY += rewardAPY; + rewardTokens.push(rewardTokenAddress); + } + }); + return { apyReward: totalRewardAPY, rewardTokens }; + }; + + const [poolsReserveData, poolsReservesConfigurationData, totalSupplyData, balanceData, decimalsData] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ target, params: p.tokenAddress })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }), + sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ target, params: p.tokenAddress })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }), + sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: aTokens.map((t) => ({ target: t.tokenAddress })), + }), + sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: aTokens.map((t, i) => ({ target: reserveTokens[i].tokenAddress, params: [t.tokenAddress] })), + }), + sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'decimals'), + calls: aTokens.map((t) => ({ target: t.tokenAddress })), + }), + ]); + + let aggregatedReserveIncentiveData = []; + try { + const incentivesResult = await sdk.api.abi.call({ + target: subscriptionDataIncentiveProvider, + abi: ISubscriptionDataIncentiveProvider.abi.find(({ name }) => name === 'getReservesIncentivesData'), + params: [subscriptionPool], + chain, + }); + aggregatedReserveIncentiveData = incentivesResult.output || []; + } catch (error) { + // Continue without incentive data if unavailable + } + + const priceKeys = reserveTokens.map((t) => `${chain}:${t.tokenAddress}`).join(','); + const pricesEthereum = (await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`)).data.coins; + + return Promise.all(reserveTokens.map(async (pool, i) => { + const p = poolsReserveData.output[i].output; + const price = pricesEthereum[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupplyData.output[i].output; + const totalSupplyUsd = (supply / 10 ** decimalsData.output[i].output) * price; + + const currentSupply = balanceData.output[i].output; + const tvlUsd = (currentSupply / 10 ** decimalsData.output[i].output) * price; + // Find matching incentive data for this reserve + const matchingIncentive = aggregatedReserveIncentiveData.find( + (inc) => + inc.underlyingAsset.toLowerCase() === pool.tokenAddress.toLowerCase() + ); + + // Calculate supply rewards (aToken incentives) + const supplyRewards = matchingIncentive + ? await calculateRewardAPY( + matchingIncentive, + decimalsData.output[i].output, + price + ) + : { apyReward: 0, rewardTokens: [] }; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + chain, + project: 'colend-protocol', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + apyReward: supplyRewards.apyReward, + rewardTokens: supplyRewards.rewardTokens, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd: totalSupplyUsd - tvlUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData.output[i].output.ltv / 10000, + borrowable: poolsReservesConfigurationData.output[i].output.borrowingEnabled, + }; + })); +}; + +const apy = async () => { + // Fetch data for all PoolDataProviders in a flexible way + const allMarketData = await Promise.all( + poolDataProviders.map(fetchMarketData) + ); + + // Combine results from all markets + const combinedMarketData = allMarketData.flat(); + + return combinedMarketData.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.colend.xyz/markets/', +}; diff --git a/src/adaptors/comb-financial/index.js b/src/adaptors/comb-financial/index.js new file mode 100644 index 0000000000..e5761aac86 --- /dev/null +++ b/src/adaptors/comb-financial/index.js @@ -0,0 +1,68 @@ +const utils = require('../utils'); +const mappings = require('./mappings.json'); + +const rewardToken = '0xaE45a827625116d6C0C40B5D7359EcF68F8e9AFD'; //COMB Token + +let finalData = []; + +const getSymbol = (poolId) => + mappings.find((pool) => pool.pool === poolId)?.symbol; +const getTokens = (poolId) => + mappings.find((pool) => pool.pool === poolId)?.tokens; + +const addVault = (id) => { + filteredVault = vaultData.find((vault) => vault.vaultId === id); + const { vaultId, tvl: tvlUsd, farmApr, apy } = filteredVault; + + const apyReward = utils.aprToApy(farmApr) * 100; + const apyBase = apy * 100; // convert endpoint APY value to % + + finalData.push({ + pool: vaultId, + chain: 'Fantom', + project: 'comb-financial', + symbol: getSymbol(vaultId), + tvlUsd, + apyBase, + apyReward, + rewardTokens: [rewardToken], + underlyingTokens: getTokens(vaultId), + }); +}; + +const poolsFunction = async () => { + poolData = await utils.getData('http://comb-breakdown.herokuapp.com/pools'); + vaultData = await utils.getData( + 'https://comb-breakdown.herokuapp.com/vaults' + ); + + poolData.map((pool) => { + const { poolId, tvl: tvlUsd, tradingApr, poolApr } = pool; + + const apyBase = utils.aprToApy(tradingApr) * 100; + const apyReward = utils.aprToApy(poolApr) * 100; + + finalData.push({ + pool: poolId, + chain: 'Fantom', + project: 'comb-financial', + symbol: getSymbol(poolId), + tvlUsd, + apyBase, + apyReward, + rewardTokens: [rewardToken], + underlyingTokens: getTokens(poolId), + }); + }); + + // Add filtered vault + addVault('gemFtmUsdc'); + + return finalData.filter((p) => p.symbol); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.comb.financial/pools', +}; diff --git a/src/adaptors/comb-financial/mappings.json b/src/adaptors/comb-financial/mappings.json new file mode 100644 index 0000000000..0e0c40c293 --- /dev/null +++ b/src/adaptors/comb-financial/mappings.json @@ -0,0 +1,94 @@ +[ + { + "pool": "spiritCombFtm", + "symbol": "COMB-FTM", + "tokens": [ + "0xaE45a827625116d6C0C40B5D7359EcF68F8e9AFD", + "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83" + ] + }, + { + "pool": "spookyBooFtm", + "symbol": "BOO-FTM", + "tokens": [ + "0x841FAD6EAe12c286d1Fd18d1d525DFfA75C7EFFE", + "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83" + ] + }, + { + "pool": "spookyFtmUsdc", + "symbol": "FTM-USDC", + "tokens": [ + "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83", + "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75" + ] + }, + { + "pool": "beetsDuetto", + "symbol": "BEETS-FTM", + "tokens": [ + "0xF24Bcf4d1e507740041C9cFd2DddB29585aDCe1e", + "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83" + ] + }, + { + "pool": "spiritLqdrFtm", + "symbol": "LQDR-FTM", + "tokens": [ + "0x10b620b2dbAC4Faa7D7FFD71Da486f5D44cd86f9", + "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83" + ] + }, + { + "pool": "spiritMaiFtm", + "symbol": "MAI-FTM", + "tokens": ["0xfB98B335551a418cD0737375a2ea0ded62Ea213b","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83"] + }, + { + "pool": "beetsQuartet", + "symbol": "USDC-FTM-BTC-ETH", + "tokens": ["0x04068DA6C83AFCFA0e13ba15A6696662335D5B75","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83","0x321162Cd933E2Be498Cd2267a90534A804051b11","0x74b23882a30290451A17c44f4F05243b6b58C76d"] + }, + { + "pool": "beetsStardust", + "symbol": "USDT-USDC-MIM", + "tokens": ["0x049d68029688eAbF473097a2fC38ef61633A3C7A","0x04068DA6C83AFCFA0e13ba15A6696662335D5B75","0x82f0B8B456c1A451378467398982d4834b6829c1"] + }, + { + "pool": "beetsFbeets", + "symbol": "FBEETS", + "tokens": [ + "0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1" + ] + }, + { + "pool": "beetsDaiOpera", + "symbol": "FTM-DAI", + "tokens": ["0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83", "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E"] + }, + { + "pool": "screamScreamFtm", + "symbol": "SCREAM-FTM", + "tokens": ["0xe0654C8e6fd4D733349ac7E09f6f23DA256bF475","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83"] + }, + { + "pool": "gemFtmUsdc", + "symbol": "GEM-FTM-USDC", + "tokens": ["0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83","0x04068DA6C83AFCFA0e13ba15A6696662335D5B75"] + }, + { + "pool": "spiritV2LqdrFtm", + "symbol": "LQDR-FTM", + "tokens": ["0x10b620b2dbAC4Faa7D7FFD71Da486f5D44cd86f9","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83"] + }, + { + "pool": "spiritV2FusdtFtm", + "symbol": "FUSDT-FTM", + "tokens": ["0x049d68029688eAbF473097a2fC38ef61633A3C7A","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83"] + }, + { + "pool": "spiritV2CombFtm", + "symbol": "COMB-FTM", + "tokens": ["0xaE45a827625116d6C0C40B5D7359EcF68F8e9AFD","0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83"] + } +] \ No newline at end of file diff --git a/src/adaptors/complifi/index.js b/src/adaptors/complifi/index.js index 7cc83c16e8..7b1569d922 100644 --- a/src/adaptors/complifi/index.js +++ b/src/adaptors/complifi/index.js @@ -1,23 +1,42 @@ const utils = require('../utils'); +const axios = require('axios'); +const retry = require('async-retry'); + +const retries = 3; const collectPools = async () => { - const [apyData, tvlData] = await Promise.all([ - utils.getData('https://eth.complifi.me/api/v2/statistics/apy?network=137'), - utils.getData('https://eth.complifi.me/api/protocol/tvl') - ]); + const apyData = ( + await retry( + async (bail) => + await axios.get( + 'https://back.compli.fi/api/v2/statistics/apy?network=137&days=30' + ), + { retries } + ) + ).data; + + const tvlData = ( + await retry( + async (bail) => + await axios.get('https://back.compli.fi/api/protocol/tvl'), + { retries } + ) + ).data; return Object.entries(apyData).map(([poolAddress, apy], i) => ({ - pool: poolAddress, - chain: utils.formatChain('polygon'), - project: 'complifi', - symbol: utils.formatSymbol(tvlData['tvlPools']['137'][poolAddress]['collateral']), - tvlUsd: tvlData['tvlPools']['137'][poolAddress]['tvl'], - apy: apy * 100, - }) - ); + pool: poolAddress, + chain: utils.formatChain('polygon'), + project: 'complifi', + symbol: utils.formatSymbol( + tvlData['tvlPools']['137'][poolAddress]['collateral'] + ), + tvlUsd: tvlData['tvlPools']['137'][poolAddress]['tvl'], + apy: apy * 100, + })); }; module.exports = { timetravel: false, apy: collectPools, + url: 'https://v2.compli.fi/invest', }; diff --git a/src/adaptors/compound-v2/abi.js b/src/adaptors/compound-v2/abi.js new file mode 100644 index 0000000000..1a4a4d34cb --- /dev/null +++ b/src/adaptors/compound-v2/abi.js @@ -0,0 +1,2102 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/compound-v2/index.js b/src/adaptors/compound-v2/index.js new file mode 100755 index 0000000000..2ea3cb0980 --- /dev/null +++ b/src/adaptors/compound-v2/index.js @@ -0,0 +1,258 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B'; +const CHAIN = 'ethereum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'compound-v2'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'COMP', + address: '0xc00e94Cb662C3520282E6f5717214004A7f26888'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = + // for maker + underlyingTokens[i]?.toLowerCase() === + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2' + ? 'MKR' + : underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + debtCeilingUsd: (borrowCaps[i] / 1e18) * price, + }; + } + return poolReturned; + }); + + return pools.filter( + (p) => + ![ + '0x158079ee67fce2f58472a96584a73c7ab9ac95c1', + '0x7713dd9ca933848f6819f38b8352d9a15ea73f67', + '0xf5dce57282a584d2746faf1593d3121fcac444dc', + '0xc11b1268c1a384e55c48c2391d8d480264a3a7f4', + ].includes(p.pool) + ); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.compound.finance/markets/v2', +}; diff --git a/src/adaptors/compound-v3/abi.js b/src/adaptors/compound-v3/abi.js new file mode 100644 index 0000000000..fd71549741 --- /dev/null +++ b/src/adaptors/compound-v3/abi.js @@ -0,0 +1,996 @@ +module.exports = [ + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'governor', type: 'address' }, + { internalType: 'address', name: 'pauseGuardian', type: 'address' }, + { internalType: 'address', name: 'baseToken', type: 'address' }, + { + internalType: 'address', + name: 'baseTokenPriceFeed', + type: 'address', + }, + { + internalType: 'address', + name: 'extensionDelegate', + type: 'address', + }, + { internalType: 'uint64', name: 'supplyKink', type: 'uint64' }, + { + internalType: 'uint64', + name: 'supplyPerYearInterestRateSlopeLow', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'supplyPerYearInterestRateSlopeHigh', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'supplyPerYearInterestRateBase', + type: 'uint64', + }, + { internalType: 'uint64', name: 'borrowKink', type: 'uint64' }, + { + internalType: 'uint64', + name: 'borrowPerYearInterestRateSlopeLow', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'borrowPerYearInterestRateSlopeHigh', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'borrowPerYearInterestRateBase', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'storeFrontPriceFactor', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'trackingIndexScale', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'baseTrackingSupplySpeed', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'baseTrackingBorrowSpeed', + type: 'uint64', + }, + { + internalType: 'uint104', + name: 'baseMinForRewards', + type: 'uint104', + }, + { internalType: 'uint104', name: 'baseBorrowMin', type: 'uint104' }, + { internalType: 'uint104', name: 'targetReserves', type: 'uint104' }, + { + components: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'priceFeed', type: 'address' }, + { internalType: 'uint8', name: 'decimals', type: 'uint8' }, + { + internalType: 'uint64', + name: 'borrowCollateralFactor', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'liquidateCollateralFactor', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'liquidationFactor', + type: 'uint64', + }, + { internalType: 'uint128', name: 'supplyCap', type: 'uint128' }, + ], + internalType: 'struct CometConfiguration.AssetConfig[]', + name: 'assetConfigs', + type: 'tuple[]', + }, + ], + internalType: 'struct CometConfiguration.Configuration', + name: 'config', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'Absurd', type: 'error' }, + { inputs: [], name: 'AlreadyInitialized', type: 'error' }, + { inputs: [], name: 'BadAsset', type: 'error' }, + { inputs: [], name: 'BadDecimals', type: 'error' }, + { inputs: [], name: 'BadDiscount', type: 'error' }, + { inputs: [], name: 'BadMinimum', type: 'error' }, + { inputs: [], name: 'BadPrice', type: 'error' }, + { inputs: [], name: 'BorrowCFTooLarge', type: 'error' }, + { inputs: [], name: 'BorrowTooSmall', type: 'error' }, + { inputs: [], name: 'InsufficientReserves', type: 'error' }, + { inputs: [], name: 'InvalidInt104', type: 'error' }, + { inputs: [], name: 'InvalidInt256', type: 'error' }, + { inputs: [], name: 'InvalidUInt104', type: 'error' }, + { inputs: [], name: 'InvalidUInt128', type: 'error' }, + { inputs: [], name: 'InvalidUInt64', type: 'error' }, + { inputs: [], name: 'LiquidateCFTooLarge', type: 'error' }, + { inputs: [], name: 'NegativeNumber', type: 'error' }, + { inputs: [], name: 'NoSelfTransfer', type: 'error' }, + { inputs: [], name: 'NotCollateralized', type: 'error' }, + { inputs: [], name: 'NotForSale', type: 'error' }, + { inputs: [], name: 'NotLiquidatable', type: 'error' }, + { inputs: [], name: 'Paused', type: 'error' }, + { inputs: [], name: 'SupplyCapExceeded', type: 'error' }, + { inputs: [], name: 'TimestampTooLarge', type: 'error' }, + { inputs: [], name: 'TooManyAssets', type: 'error' }, + { inputs: [], name: 'TooMuchSlippage', type: 'error' }, + { inputs: [], name: 'TransferInFailed', type: 'error' }, + { inputs: [], name: 'TransferOutFailed', type: 'error' }, + { inputs: [], name: 'Unauthorized', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'absorber', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'collateralAbsorbed', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'usdValue', + type: 'uint256', + }, + ], + name: 'AbsorbCollateral', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'absorber', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'basePaidOut', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'usdValue', + type: 'uint256', + }, + ], + name: 'AbsorbDebt', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'buyer', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + ], + name: 'BuyCollateral', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'supplyPaused', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'transferPaused', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'withdrawPaused', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'absorbPaused', + type: 'bool', + }, + { indexed: false, internalType: 'bool', name: 'buyPaused', type: 'bool' }, + ], + name: 'PauseAction', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'dst', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Supply', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'dst', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'SupplyCollateral', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'TransferCollateral', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'src', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'src', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawCollateral', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawReserves', + type: 'event', + }, + { stateMutability: 'payable', type: 'fallback' }, + { + inputs: [ + { internalType: 'address', name: 'absorber', type: 'address' }, + { internalType: 'address[]', name: 'accounts', type: 'address[]' }, + ], + name: 'absorb', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'accrueAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'manager', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approveThis', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseBorrowMin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseMinForRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseScale', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseTokenPriceFeed', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseTrackingBorrowSpeed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseTrackingSupplySpeed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowKink', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowPerSecondInterestRateBase', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowPerSecondInterestRateSlopeHigh', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowPerSecondInterestRateSlopeLow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'minAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'baseAmount', type: 'uint256' }, + { internalType: 'address', name: 'recipient', type: 'address' }, + ], + name: 'buyCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'extensionDelegate', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: 'i', type: 'uint8' }], + name: 'getAssetInfo', + outputs: [ + { + components: [ + { internalType: 'uint8', name: 'offset', type: 'uint8' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'priceFeed', type: 'address' }, + { internalType: 'uint64', name: 'scale', type: 'uint64' }, + { + internalType: 'uint64', + name: 'borrowCollateralFactor', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'liquidateCollateralFactor', + type: 'uint64', + }, + { internalType: 'uint64', name: 'liquidationFactor', type: 'uint64' }, + { internalType: 'uint128', name: 'supplyCap', type: 'uint128' }, + ], + internalType: 'struct CometCore.AssetInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getAssetInfoByAddress', + outputs: [ + { + components: [ + { internalType: 'uint8', name: 'offset', type: 'uint8' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'priceFeed', type: 'address' }, + { internalType: 'uint64', name: 'scale', type: 'uint64' }, + { + internalType: 'uint64', + name: 'borrowCollateralFactor', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'liquidateCollateralFactor', + type: 'uint64', + }, + { internalType: 'uint64', name: 'liquidationFactor', type: 'uint64' }, + { internalType: 'uint128', name: 'supplyCap', type: 'uint128' }, + ], + internalType: 'struct CometCore.AssetInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'utilization', type: 'uint256' }], + name: 'getBorrowRate', + outputs: [{ internalType: 'uint64', name: '', type: 'uint64' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'priceFeed', type: 'address' }], + name: 'getPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'utilization', type: 'uint256' }], + name: 'getSupplyRate', + outputs: [{ internalType: 'uint64', name: '', type: 'uint64' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getUtilization', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'governor', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'manager', type: 'address' }, + ], + name: 'hasPermission', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'initializeStorage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isAbsorbPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'isAllowed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isBorrowCollateralized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isBuyPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isLiquidatable', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isSupplyPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isWithdrawPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'liquidatorPoints', + outputs: [ + { internalType: 'uint32', name: 'numAbsorbs', type: 'uint32' }, + { internalType: 'uint64', name: 'numAbsorbed', type: 'uint64' }, + { internalType: 'uint128', name: 'approxSpend', type: 'uint128' }, + { internalType: 'uint32', name: '_reserved', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'numAssets', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bool', name: 'supplyPaused', type: 'bool' }, + { internalType: 'bool', name: 'transferPaused', type: 'bool' }, + { internalType: 'bool', name: 'withdrawPaused', type: 'bool' }, + { internalType: 'bool', name: 'absorbPaused', type: 'bool' }, + { internalType: 'bool', name: 'buyPaused', type: 'bool' }, + ], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'baseAmount', type: 'uint256' }, + ], + name: 'quoteCollateral', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'storeFrontPriceFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'supply', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'supplyFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'supplyKink', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'supplyPerSecondInterestRateBase', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'supplyPerSecondInterestRateSlopeHigh', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'supplyPerSecondInterestRateSlopeLow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'supplyTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'targetReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'totalsCollateral', + outputs: [ + { internalType: 'uint128', name: 'totalSupplyAsset', type: 'uint128' }, + { internalType: 'uint128', name: '_reserved', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'trackingIndexScale', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferAsset', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferAssetFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userBasic', + outputs: [ + { internalType: 'int104', name: 'principal', type: 'int104' }, + { internalType: 'uint64', name: 'baseTrackingIndex', type: 'uint64' }, + { internalType: 'uint64', name: 'baseTrackingAccrued', type: 'uint64' }, + { internalType: 'uint16', name: 'assetsIn', type: 'uint16' }, + { internalType: 'uint8', name: '_reserved', type: 'uint8' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userCollateral', + outputs: [ + { internalType: 'uint128', name: 'balance', type: 'uint128' }, + { internalType: 'uint128', name: '_reserved', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userNonce', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdrawFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdrawReserves', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdrawTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/compound-v3/index.js b/src/adaptors/compound-v3/index.js new file mode 100644 index 0000000000..e8e0c82a47 --- /dev/null +++ b/src/adaptors/compound-v3/index.js @@ -0,0 +1,325 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.js'); +const { keepFinite } = require('../utils.js'); + +const markets = [ + { + address: '0xc3d688B66703497DAA19211EEdff47f25384cdc3', + symbol: 'cUSDCv3', + underlying: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + underlyingSymbol: 'USDC', + rewardToken: '0xc00e94Cb662C3520282E6f5717214004A7f26888', + chain: 'ethereum', + }, + { + address: '0x3Afdc9BCA9213A35503b077a6072F3D0d5AB0840', + symbol: 'cUSDTv3', + underlying: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + underlyingSymbol: 'USDT', + rewardToken: '0xc00e94Cb662C3520282E6f5717214004A7f26888', + chain: 'ethereum', + }, + { + address: '0xA17581A9E3356d9A858b789D68B4d866e593aE94', + symbol: 'cWETHv3', + underlying: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + underlyingSymbol: 'ETH', + rewardToken: '0xc00e94Cb662C3520282E6f5717214004A7f26888', + chain: 'ethereum', + }, + { + address: '0xF25212E676D1F7F89Cd72fFEe66158f541246445', + symbol: 'cUSDCv3', + underlying: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + underlyingSymbol: 'USDC', + rewardToken: '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', + chain: 'polygon', + }, + { + address: '0xaeB318360f27748Acb200CE616E389A6C9409a07', + symbol: 'cUSDTv3', + underlying: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + underlyingSymbol: 'USDT', + rewardToken: '0x8505b9d2254A7Ae468c0E9dd10Ccea3A837aef5c', + chain: 'polygon', + }, + { + address: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA', + symbol: 'cUSDCv3', + underlying: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + underlyingSymbol: 'USDC', + rewardToken: '0x354A6dA3fcde098F8389cad84b0182725c6C91dE', + chain: 'arbitrum', + }, + { + address: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + symbol: 'cUSDCv3-native', + underlying: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + underlyingSymbol: 'USDC', + rewardToken: '0x354A6dA3fcde098F8389cad84b0182725c6C91dE', + chain: 'arbitrum', + }, + { + address: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486', + symbol: 'cWETHv3', + underlying: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + underlyingSymbol: 'WETH', + rewardToken: '0x354A6dA3fcde098F8389cad84b0182725c6C91dE', + chain: 'arbitrum', + }, + { + address: '0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07', + symbol: 'cUSDTv3', + underlying: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + underlyingSymbol: 'USDT', + rewardToken: '0x354A6dA3fcde098F8389cad84b0182725c6C91dE', + chain: 'arbitrum', + }, + { + address: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf', + symbol: 'cUSDbCv3', + underlying: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', + underlyingSymbol: 'USDbC', + rewardToken: '0x9e1028F5F1D5eDE59748FFceE5532509976840E0', + chain: 'base', + }, + { + address: '0x46e6b214b524310239732D51387075E0e70970bf', + symbol: 'cWETHv3', + underlying: '0x4200000000000000000000000000000000000006', + underlyingSymbol: 'WETH', + rewardToken: '0x9e1028F5F1D5eDE59748FFceE5532509976840E0', + chain: 'base', + }, + { + address: '0xb125E6687d4313864e53df431d5425969c15Eb2F', + symbol: 'cUSDCv3', + underlying: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + underlyingSymbol: 'USDC', + rewardToken: '0x9e1028F5F1D5eDE59748FFceE5532509976840E0', + chain: 'base', + }, + { + address: '0xB2f97c1Bd3bf02f5e74d13f02E3e26F93D77CE44', + symbol: 'cUSDCv3', + underlying: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4', + underlyingSymbol: 'USDC', + rewardToken: '0x643e160a3C3E2B7eae198f0beB1BfD2441450e86', + chain: 'scroll', + }, + { + address: '0x2e44e174f7D53F0212823acC11C01A11d58c5bCB', + symbol: 'cUSDCv3-native', + underlying: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', + underlyingSymbol: 'USDC', + rewardToken: '0x7e7d4467112689329f7E06571eD0E8CbAd4910eE', + chain: 'optimism', + }, + { + address: '0x995E394b8B2437aC8Ce61Ee0bC610D617962B214', + symbol: 'cUSDTv3', + underlying: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', + underlyingSymbol: 'USDT', + rewardToken: '0x7e7d4467112689329f7E06571eD0E8CbAd4910eE', + chain: 'optimism', + }, + { + address: '0xE36A30D249f7761327fd973001A32010b521b6Fd', + symbol: 'cWETHv3', + underlying: '0x4200000000000000000000000000000000000006', + underlyingSymbol: 'WETH', + rewardToken: '0x7e7d4467112689329f7E06571eD0E8CbAd4910eE', + chain: 'optimism', + }, +]; + +const main = async (pool) => { + const numAssets = ( + await sdk.api.abi.call({ + target: pool.address, + abi: abi.find((i) => i.name === 'numAssets'), + chain: pool.chain, + }) + ).output; + + // contains token addresses and c-factors + const assetInfoRes = await sdk.api.abi.multiCall({ + abi: abi.find((i) => i.name === 'getAssetInfo'), + calls: [...Array(Number(numAssets)).keys()].map((i) => ({ + target: pool.address, + params: i, + })), + chain: pool.chain, + }); + const assetInfo = assetInfoRes.output.map((o) => o.output); + const tokens = assetInfo.map((a) => a.asset); + + // symbols + const symbolsRes = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((t) => ({ + target: t, + })), + chain: pool.chain, + }); + const symbols = symbolsRes.output.map((o) => o.output); + + // collateral balances + const totalsCollateralRes = await sdk.api.abi.multiCall({ + abi: abi.find((i) => i.name === 'totalsCollateral'), + calls: tokens.map((t) => ({ + target: pool.address, + params: t, + })), + chain: pool.chain, + }); + const totalsCollateral = totalsCollateralRes.output.map((o) => o.output); + + // get prices + const priceKeys = [ + `${pool.chain}:${pool.underlying}`, + `${pool.chain}:${pool.rewardToken}`, + ...tokens.map((t) => `${pool.chain}:${t}`), + ].join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).body.coins; + + const collateralDecimalsRes = await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + chain: pool.chain, + calls: tokens.map((t) => ({ target: t })), + }); + const collateralDecimals = collateralDecimalsRes.output.map((o) => o.output); + + // calc collateral in usd + const collateralTotalSupplyUsd = tokens.map( + (t, i) => + (Number(totalsCollateral[i].totalSupplyAsset) * + prices[`${pool.chain}:${t}`]?.price) / + 10 ** Number(collateralDecimals[i]) + ); + + // pool utilization + const utilization = ( + await sdk.api.abi.call({ + target: pool.address, + abi: abi.find((i) => i.name === 'getUtilization'), + chain: pool.chain, + }) + ).output; + + // get rate data + const [ + supplyRate, + borrowRate, + baseTrackingBorrowSpeed, + baseTrackingSupplySpeed, + totalBorrow, + totalSupply, + trackingIndexScale, + decimals, + ] = ( + await Promise.all( + [ + 'getSupplyRate', + 'getBorrowRate', + 'baseTrackingBorrowSpeed', + 'baseTrackingSupplySpeed', + 'totalBorrow', + 'totalSupply', + 'trackingIndexScale', + 'decimals', + ].map((method) => + sdk.api.abi.call({ + target: pool.address, + abi: abi.find((i) => i.name === method), + params: + method === 'getSupplyRate' || method === 'getBorrowRate' + ? [utilization] + : null, + chain: pool.chain, + }) + ) + ) + ).map((o) => o.output); + + // --- pool array + + // 1) collateral pools (no apy fields) + const collateralOnlyPools = tokens.map((t, i) => ({ + pool: `${t}-${pool.symbol}-${pool.chain}`, + symbol: symbols[i], + chain: pool.chain.charAt(0).toUpperCase() + pool.chain.slice(1), + project: 'compound-v3', + tvlUsd: collateralTotalSupplyUsd[i], + apy: 0, + underlyingTokens: [t], + // borrow fields + totalSupplyUsd: collateralTotalSupplyUsd[i], + ltv: assetInfo[i].borrowCollateralFactor / 1e18, + poolMeta: `${pool.underlyingSymbol}-pool`, + borrowable: false, + })); + + // 2) usdc pool + // --- calc apy's + const secondsPerYear = 60 * 60 * 24 * 365; + const compPrice = prices[`${pool.chain}:${pool.rewardToken}`]?.price; + const usdcPrice = prices[`${pool.chain}:${pool.underlying}`]?.price; + + // supply side + const totalSupplyUsd = (totalSupply / 10 ** decimals) * usdcPrice; + const apyBase = (supplyRate / 1e18) * secondsPerYear * 100; + const apyReward = + (((baseTrackingSupplySpeed / trackingIndexScale) * + secondsPerYear * + compPrice) / + totalSupplyUsd) * + 100; + + // borrow side + const totalBorrowUsd = (totalBorrow / 10 ** decimals) * usdcPrice; + const apyBaseBorrow = (borrowRate / 1e18) * secondsPerYear * 100; + const apyRewardBorrow = + (((baseTrackingBorrowSpeed / trackingIndexScale) * + secondsPerYear * + compPrice) / + totalBorrowUsd) * + 100; + + return [ + ...collateralOnlyPools, + { + pool: `${pool.address}-${pool.chain}`, + symbol: pool.underlyingSymbol, + chain: pool.chain.charAt(0).toUpperCase() + pool.chain.slice(1), + project: 'compound-v3', + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase, + apyReward, + underlyingTokens: [pool.underlying], + rewardTokens: [pool.rewardToken], + // borrow fields + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + borrowable: true, + ltv: 0, + }, + ]; +}; + +const apy = async () => { + const pools = (await Promise.all(markets.map((p) => main(p)))).flat(); + return pools.filter((i) => keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://v3-app.compound.finance/markets', +}; diff --git a/src/adaptors/compound/index.js b/src/adaptors/compound/index.js deleted file mode 100755 index dbb8ee17e6..0000000000 --- a/src/adaptors/compound/index.js +++ /dev/null @@ -1,68 +0,0 @@ -const utils = require('../utils'); - -const url = 'https://api.compound.finance/api/v2/ctoken'; - -const apy = (entry, ethPriceUSD) => { - entry = { ...entry }; - - const totalSupply = - Number(entry.cash.value) + - Number(entry.reserves.value) + - Number(entry.total_borrows.value); - - entry.totalSupplyUSD = - totalSupply * Number(entry.underlying_price.value) * ethPriceUSD; - - entry.apy = - entry.supply_rate.value * 100 + Number(entry.comp_supply_apy.value); - - return entry; -}; - -const buildPool = (entry, chainString) => { - // these are deprecated, dont want to include those - // re WBTC: compound has a second WBTC token called WBTC2, which is active - // and which we also include - const exclude = ['cWBTC', 'cSAI', 'cREP']; - if (!exclude.includes(entry.symbol)) { - const newObj = { - pool: entry.token_address, - chain: utils.formatChain(chainString), - project: 'compound', - symbol: utils.formatSymbol( - entry.symbol === 'cWBTC2' ? 'cWBTC' : entry.symbol - ), - tvlUsd: entry.totalSupplyUSD, - apy: entry.apy, - }; - return newObj; - } -}; - -const topLvl = async (chainString, url) => { - // get eth price - const ethPriceUSD = await utils.getCGpriceData(chainString, true); - - // pull data - let data = await utils.getData(url); - - // calculate apy - data = data.cToken.map((el) => apy(el, ethPriceUSD.ethereum.usd)); - - // build pool objects - data = data - .map((el) => buildPool(el, chainString)) - .filter((el) => el !== undefined); - - return data; -}; - -const main = async () => { - const data = await Promise.all([topLvl('ethereum', url)]); - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/compx-yield/index.js b/src/adaptors/compx-yield/index.js new file mode 100644 index 0000000000..86f1c40433 --- /dev/null +++ b/src/adaptors/compx-yield/index.js @@ -0,0 +1,15 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const pools = await utils.getData( + 'https://api-general.compx.io/api/defillama/yield-farms' + ); + + return pools.map((i) => ({ ...i, project: 'compx-yield' })); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.compx.io/farms', +}; diff --git a/src/adaptors/concentrator/index.js b/src/adaptors/concentrator/index.js index 0f01116cda..e2f94406d7 100755 --- a/src/adaptors/concentrator/index.js +++ b/src/adaptors/concentrator/index.js @@ -1,3 +1,4 @@ +const superagent = require('superagent'); const sdk = require('@defillama/sdk'); const { default: BigNumber } = require('bignumber.js'); const utils = require('../utils'); @@ -6,281 +7,115 @@ const AladdinConvexVaultABI = require('./abis/AladdinConvexVault.json'); const AladdinCRVABI = require('./abis/AladdinCRV.json'); const curvePools = require('./pools.js'); -const convexVault = '0xc8fF37F7d057dF1BB9Ad681b53Fa4726f268E0e8'; -const convexVaultAcrv = '0x2b95A1Dcc3D405535f9ed33c219ab38E8d7e0884'; +const ALADDIN_API_BASE_URL = 'https://api.aladdin.club/'; + +const concentratorAcrv = '0x2b95A1Dcc3D405535f9ed33c219ab38E8d7e0884'; +const aladdinSdCRV = '0x43E54C2E7b3e294De3A155785F52AB49d87B9922'; +const aladdinCVXAddress = '0xb0903Ab70a7467eE5756074b31ac88aEBb8fB777'; +const aladdinRUSD = '0x07D1718fF05a8C53C8F05aDAEd57C0d672945f9a'; +const fxSaveAddress = '0x7743e50F534a7f9F1791DdE7dCD89F7783Eefc39'; +const asdPENDLEAddress = '0x606462126E4Bd5c4D153Fe09967e4C46C9c7FeCf'; -const replacements = [ - '0x99d1Fa417f94dcD62BfE781a1213c092a47041Bc', - '0x9777d7E2b60bB01759D0E2f8be2095df444cb07E', - '0x1bE5d71F2dA660BFdee8012dDc58D024448A0A59', - '0x16de59092dAE5CcF4A1E6439D611fd0653f0Bd01', - '0xd6aD7a6750A7593E092a9B218d66C0A814a3436e', - '0x83f798e925BcD4017Eb265844FDDAbb448f1707D', - '0x73a052500105205d34Daf004eAb301916DA8190f', -]; -const replacePrice = [ - { address: '0x0000000000000000000000000000000000000000', token: 'ethereum' }, - { - address: '0xFEEf77d3f69374f66429C91d732A244f074bdf74', - token: 'frax-share', - }, -]; const getAllPools = async () => { - let dataApy = await utils.getData( - 'http://concentrator-api.aladdin.club/apy/' + let vaultsInfo = await utils.getData( + `${ALADDIN_API_BASE_URL}api1/concentrator_pool_tvl_apy` ); - - const poolLength = ( - await sdk.api.abi.call({ - target: convexVault, - abi: abi.poolLength, - }) - ).output; - - return await Promise.all( - [...Array(Number(poolLength)).keys()].map(async (i) => { - const poolInfo = await sdk.api.abi.call({ - target: convexVault, - abi: AladdinConvexVaultABI.poolInfo, - params: [i], - }); - - const lpTokenSupply = await sdk.api.erc20.totalSupply({ - target: poolInfo.output.lpToken, + let pools = []; + if (vaultsInfo.data) { + vaultsInfo.data.map((item) => { + pools.push({ + tvl: item.tvl, + apy: item.apy.proApy, + symbol: item.lpName, + lpToken: item.address, }); - - const poolData = curvePools.find( - (crvPool) => - crvPool.addresses.lpToken.toLowerCase() === - poolInfo.output.lpToken.toLowerCase() - ); - const swapAddress = poolData.addresses.swap; - - const coinCalls = [...Array(Number(poolData.coins.length)).keys()].map( - (num) => { - return { - target: swapAddress, - params: [num], - }; - } - ); - - const coinsUint = sdk.api.abi.multiCall({ - abi: abi.coinsUint, - calls: coinCalls, - }); - - const coinsInt = sdk.api.abi.multiCall({ - abi: abi.coinsInt, - calls: coinCalls, - }); - - let coins = await coinsUint; - if (!coins.output[0].success) { - coins = await coinsInt; - } - - const coinBalances = await sdk.api.abi.multiCall({ - abi: 'erc20:balanceOf', - calls: coins.output.map((coin) => ({ - target: coin.output, - params: [swapAddress], - })), - }); - - const resolvedLPSupply = lpTokenSupply.output; - const lpTvl = await getLpTvl( - poolInfo, - resolvedLPSupply, - coinBalances, - poolData, - coins - ); - - const lpApy = await getLpApy(poolData, dataApy); - return { - lpTvl: lpTvl.toString(10), - lpApy: lpApy.toString(10), - poolData, - }; - }) - ); -}; - -const getLpTvl = async ( - poolInfo, - resolvedLPSupply, - coinBalances, - poolData, - coins -) => { - let lpTvl = BigNumber(0); - await Promise.all( - coinBalances.output.map(async (coinBalance, index) => { - let coinAddress = coins.output[index].output; - if (replacements.includes(coinAddress)) { - coinAddress = '0x6b175474e89094c44da98b954eedeac495271d0f'; // dai - } - if ( - coinBalance.input.target === - '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' - ) { - coinBalance = await sdk.api.eth.getBalance({ - target: coinBalance.input.params[0], - }); - coinAddress = '0x0000000000000000000000000000000000000000'; - } - const coinDecimals = poolData.coinDecimals[index]; - - const isReplace = replacePrice.find( - (item) => - item.address.toLocaleLowerCase() == coinAddress.toLocaleLowerCase() - ); - let pricesUSD = 0; - if (isReplace && isReplace.token) { - pricesUSD = await utils.getCGpriceData(isReplace.token, true); - pricesUSD = pricesUSD[isReplace.token].usd; - } else { - pricesUSD = await utils.getCGpriceData(coinAddress, false, 'ethereum'); - pricesUSD = pricesUSD[coinAddress.toLocaleLowerCase()].usd; - } - const balance = BigNumber(poolInfo.output.totalUnderlying) - .times(coinBalance.output) - .div(resolvedLPSupply); - let balancePrice = BigNumber(0); - if (!balance.isZero()) { - balancePrice = balance.times(pricesUSD).div(10 ** coinDecimals); - lpTvl = lpTvl.plus(balancePrice); - } - return balancePrice; - }) - ); - return lpTvl; -}; - -const getLpApy = async (poolData, dataApy) => { - const convexApy = getConvexInfo('CRV', dataApy) - ? getConvexInfo('CRV', dataApy).apy.project - : 0; - const convexInfo = getConvexInfo(poolData.name, dataApy); - const baseApy = convexInfo ? convexInfo.apy.current : 0; - - const acrvApy = BigNumber(parseFloat(convexApy)) - .dividedBy(100) - .dividedBy(52) - .plus(1) - .pow(52) - .minus(1) - .shiftedBy(2); - - const compoundApy = acrvApy.multipliedBy(parseFloat(baseApy)).dividedBy(100); - let apy = compoundApy.plus(BigNumber(parseFloat(baseApy))); - let ethApy = BigNumber(1) - .plus(BigNumber(parseFloat(baseApy)).div(100)) - .plus(BigNumber(compoundApy).div(100)) - .times(BigNumber(0.045 * 0.85)) - .times(100); - if (poolData.isShowEthApy) { - apy = apy.plus(BigNumber(ethApy)); - } - return apy; -}; - -const getConvexInfo = (tokenName, dataApy) => { - let data = dataApy; - try { - const info = - data.find( - (item) => - item.name === tokenName.toLocaleLowerCase() || item.name === tokenName - ) || converWebsiteInfo.find((item) => item.name === tokenName); - - if (BigNumber(parseFloat(info.apy.current)).isNaN()) { - return converWebsiteInfo.find( - (item) => item.name === tokenName.toLocaleLowerCase() - ); - } - return info; - } catch (error) { - return null; + }); } + return pools; }; -const getAcrvPoolData = async () => { - let dataApy = await utils.getData( - 'http://concentrator-api.aladdin.club/apy/' +const getATokenData = async () => { + let aTokenData = await utils.getData( + `${ALADDIN_API_BASE_URL}api1/concentrator_aToken_tvl_apy` ); - let crvPrice = await utils.getCGpriceData('convex-crv', true); - crvPrice = crvPrice['convex-crv'].usd; - const acrvTotalUnderlying = ( - await sdk.api.abi.call({ - target: convexVaultAcrv, - abi: AladdinCRVABI.totalUnderlying, - params: [], - }) - ).output; - - const acrvTotalSupply = ( - await sdk.api.abi.call({ - target: convexVaultAcrv, - abi: AladdinCRVABI.totalSupply, - params: [], - }) - ).output; - - const rate = - acrvTotalSupply * 1 - ? BigNumber(acrvTotalUnderlying).div(acrvTotalSupply) - : 1; - - const cvxcrvBalance = BigNumber(acrvTotalUnderlying) - .multipliedBy(rate) - .times(crvPrice) - .div(10 ** 18) - .toString(10); - - const convexApy = getConvexInfo('CRV', dataApy)?.apy?.project || 0; - - const apy = BigNumber(parseFloat(convexApy)) - .dividedBy(100) - .dividedBy(365) - .plus(1) - .pow(365) - .minus(1) - .shiftedBy(2); - - const newObj = { - pool: '0x2b95A1Dcc3D405535f9ed33c219ab38E8d7e0884-concentrator', - chain: utils.formatChain('ethereum'), - project: 'concentrator', - symbol: 'aCRV', - tvlUsd: parseInt(cvxcrvBalance, 10), - apy: parseFloat(apy.toString(10)), - }; + const { aCRV, asdCRV, aladdinCVX, arUSD, fxSave, asdPENDLE } = + aTokenData.data; + + const newObj = [ + { + pool: `${concentratorAcrv}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'aCRV', + tvlUsd: parseInt(aCRV.tvl, 10), + apy: parseFloat(aCRV.apy), + }, + { + pool: `${aladdinSdCRV}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'asdCRV', + tvlUsd: parseInt(asdCRV.tvl, 10), + apy: parseFloat(asdCRV.apy), + }, + { + pool: `${aladdinCVXAddress}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'aCVX', + tvlUsd: parseInt(aladdinCVX.tvl, 10), + apy: parseFloat(aladdinCVX.apy), + }, + { + pool: `${aladdinRUSD}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'arUSD', + tvlUsd: parseInt(arUSD.tvl, 10), + apy: parseFloat(arUSD.apy), + }, + { + pool: `${fxSaveAddress}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'fxSave', + tvlUsd: parseInt(fxSave.tvl, 10), + apy: parseFloat(fxSave.apy), + }, + { + pool: `${asdPENDLEAddress}-concentrator`, + chain: utils.formatChain('ethereum'), + project: 'concentrator', + symbol: 'asdPENDLE', + tvlUsd: parseInt(asdPENDLE.tvl, 10), + apy: parseFloat(asdPENDLE.apy), + }, + ]; return newObj; }; const buildPool = (entry, chainString) => { const newObj = { - pool: `${entry.poolData.addresses.lpToken}-concentrator`, + pool: `${entry.lpToken}-concentrator`.toLowerCase(), chain: utils.formatChain(chainString), project: 'concentrator', - symbol: utils.formatSymbol(entry.poolData.symbol), - tvlUsd: parseInt(entry.lpTvl, 10), - apy: parseFloat(entry.lpApy), + symbol: utils.formatSymbol(entry.symbol), + tvlUsd: parseInt(entry.tvl, 10), + apy: parseFloat(entry.apy), }; return newObj; }; const main = async () => { const dataInfo = await getAllPools(); - const acrvData = await getAcrvPoolData(); - const data = dataInfo.map((el) => buildPool(el, 'ethereum')); - data.push(acrvData); - return data; + const aTokenData = await getATokenData(); + let data = dataInfo.map((el) => buildPool(el, 'ethereum')); + data = data.concat(aTokenData); + return data.filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: false, apy: main, + url: 'https://concentrator.aladdin.club/#/vault', }; diff --git a/src/adaptors/concentrator/pools.js b/src/adaptors/concentrator/pools.js index fc28ccb762..d28dc042df 100644 --- a/src/adaptors/concentrator/pools.js +++ b/src/adaptors/concentrator/pools.js @@ -113,28 +113,28 @@ module.exports = [ }, }, - { - symbol: 'UST-3Crv', - name: 'ust-wormhole', - coins: [coins.ust, coins.crv3pool], - coinDecimals: [6, 18], - addresses: { - swap: '0xCEAF7747579696A2F0bb206a14210e3c9e6fB269', - lpToken: '0xCEAF7747579696A2F0bb206a14210e3c9e6fB269', - }, - }, + // { + // symbol: 'UST-3Crv', + // name: 'ust-wormhole', + // coins: [coins.ust, coins.crv3pool], + // coinDecimals: [6, 18], + // addresses: { + // swap: '0xCEAF7747579696A2F0bb206a14210e3c9e6fB269', + // lpToken: '0xCEAF7747579696A2F0bb206a14210e3c9e6fB269', + // }, + // }, - { - symbol: 'rETH-wstETH', - name: 'RocketPoolETH', - isShowEthApy: true, - coins: [coins.rETH, coins.wstETH], - coinDecimals: [18, 18], - addresses: { - swap: '0x447Ddd4960d9fdBF6af9a790560d0AF76795CB08', - lpToken: '0x447Ddd4960d9fdBF6af9a790560d0AF76795CB08', - }, - }, + // { + // symbol: 'rETH-wstETH', + // name: 'RocketPoolETH', + // isShowEthApy: true, + // coins: [coins.rETH, coins.wstETH], + // coinDecimals: [18, 18], + // addresses: { + // swap: '0x447Ddd4960d9fdBF6af9a790560d0AF76795CB08', + // lpToken: '0x447Ddd4960d9fdBF6af9a790560d0AF76795CB08', + // }, + // }, { symbol: 'renBTC-wBTC', @@ -146,14 +146,319 @@ module.exports = [ lpToken: '0x49849C98ae39Fff122806C06791Fa73784FB3675', }, }, + { symbol: 'PUSD-3Crv', name: 'pusd', - coins: [coins.PUSD, coins.crv3pool], + coins: [ + coins.PUSD, + coins.crv3pool + ], coinDecimals: [18, 18], addresses: { swap: '0x8EE017541375F6Bcd802ba119bdDC94dad6911A1', lpToken: '0x8EE017541375F6Bcd802ba119bdDC94dad6911A1', }, }, + + { + symbol: 'DAI-USDC-USDT-sUSD', + name: 'susd', + coins: [ + coins.dai, + coins.usdc, + coins.usdt, + coins.SUSD + ], + coinDecimals: [18, 6, 6, 18], + addresses: { + swap: '0xA5407eAE9Ba41422680e2e00537571bcC53efBfD', + lpToken: '0xC25a3A3b969415c80451098fa907EC722572917F', + }, + }, + + { + symbol: 'ETH-sETH', + name: 'seth', + coins: [ + coins.eth, + coins.seth + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xc5424b857f758e906013f3555dad202e4bdb4567', + lpToken: '0xA3D87FffcE63B53E0d54fAa1cc983B7eB0b74A9c', + }, + }, + + { + symbol: 'renBTC-wBTC-sBTC', + name: 'sbtc', + coins: [ + coins.renBTC, + coins.wbtc, + coins.sBTC + ], + coinDecimals: [8, 8, 18], + addresses: { + swap: '0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714', + lpToken: '0x075b1bb99792c9E1041bA13afEf80C91a1e70fB3', + }, + }, + + { + symbol: 'FRAX-USDC', + name: 'fraxusdc', + coins: [ + coins.frax, + coins.usdc, + ], + coinDecimals: [18, 6], + addresses: { + swap: '0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2', + lpToken: '0x3175Df0976dFA876431C2E9eE6Bc45b65d3473CC', + }, + }, + + + + { + symbol: 'MIM-3Crv', + name: 'mim', + coins: [ + coins.min, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x5a6A4D54456819380173272A5E8E9B9904BdF41B', + lpToken: '0x5a6A4D54456819380173272A5E8E9B9904BdF41B', + }, + }, + + { + symbol: 'FRAX-FPI', + name: 'fpifrax', + coins: [ + coins.frax, + coins.fpi, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xf861483fa7E511fbc37487D91B6FAa803aF5d37c', + lpToken: '0x4704aB1fb693ce163F7c9D3A31b3FF4eaF797714', + }, + }, + + { + symbol: 'alUSD-3Crv', + name: 'alusd', + coins: [ + coins.alUSD, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c', + lpToken: '0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c', + }, + }, + + { + symbol: 'cDAI-cUSDC', + name: 'Compound', + coins: [ + coins.cdai, + coins.cusdc, + ], + coinDecimals: [8, 8], + addresses: { + swap: '0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56', + lpToken: '0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2', + }, + }, + + { + symbol: 'DOLA-3Crv', + name: 'dola', + coins: [ + coins.DOLA, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xAA5A67c256e27A5d80712c51971408db3370927D', + lpToken: '0xAA5A67c256e27A5d80712c51971408db3370927D', + }, + }, + + { + symbol: 'BUSD-3Crv', + name: 'busdv2', + coins: [ + coins.busd, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a', + lpToken: '0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a', + }, + }, + + { + symbol: 'EURs-USDC', + name: 'eursusd', + coins: [ + coins.eth, + coins.usdc, + ], + coinDecimals: [18, 6], + addresses: { + swap: '0x98a7F18d4E56Cfe84E3D081B40001B3d5bD3eB8B', + lpToken: '0x3D229E1B4faab62F621eF2F6A610961f7BD7b23B', + }, + }, + + { + symbol: 'ETH-alETH', + name: 'alETH', + coins: [ + coins.eth, + coins.eth, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xC4C319E2D4d66CcA4464C0c2B32c9Bd23ebe784e', + lpToken: '0xC4C319E2D4d66CcA4464C0c2B32c9Bd23ebe784e', + }, + }, + + { + symbol: 'agEUR-EURT-EURs', + name: '3eur-pool', + coins: [ + coins.agEUR, + coins.eurt, + coins.EURS + ], + coinDecimals: [18, 6, 2], + addresses: { + swap: '0xb9446c4Ef5EBE66268dA6700D26f96273DE3d571', + lpToken: '0xb9446c4Ef5EBE66268dA6700D26f96273DE3d571', + }, + }, + + { + symbol: 'LUSD-3Crv', + name: 'lusd', + coins: [ + coins.lusd, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA', + lpToken: '0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA', + }, + }, + + { + symbol: 'FRAX-FEI-alUSD', + name: 'd3pool', + coins: [ + coins.frax, + coins.alUSD, + coins.fei + ], + coinDecimals: [18, 18, 18], + addresses: { + swap: '0xBaaa1F5DbA42C3389bDbc2c9D2dE134F5cD0Dc89', + lpToken: '0xBaaa1F5DbA42C3389bDbc2c9D2dE134F5cD0Dc89', + }, + }, + + { + symbol: 'sUSD-FRAXBP', + name: 'susdfraxbp', + coins: [ + coins.SUSD, + coins.FRAXBP, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xe3c190c57b5959Ae62EfE3B6797058B76bA2f5eF', + lpToken: '0xe3c190c57b5959Ae62EfE3B6797058B76bA2f5eF', + }, + }, + + { + symbol: 'TUSD-FRAXBP', + name: 'tusd', + coins: [ + coins.TUSD, + coins.crv3pool, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xecd5e75afb02efa118af914515d6521aabd189f1', + lpToken: '0xecd5e75afb02efa118af914515d6521aabd189f1', + }, + }, + + { + symbol: 'BUSD-FRAXBP', + name: 'busdfraxbp', + coins: [ + coins.busd, + coins.FRAXBP, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x8fdb0bB9365a46B145Db80D0B1C5C5e979C84190', + lpToken: '0x8fdb0bB9365a46B145Db80D0B1C5C5e979C84190', + }, + }, + + { + symbol: 'alUSD-FRAXBP', + name: 'alusdfraxbp', + coins: [ + coins.alUSD, + coins.FRAXBP, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0xB30dA2376F63De30b42dC055C93fa474F31330A5', + lpToken: '0xB30dA2376F63De30b42dC055C93fa474F31330A5', + }, + }, + + { + symbol: 'SILO-FRAX', + name: 'silofrax', + coins: [ + coins.SILO, + coins.frax, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x9a22CDB1CA1cdd2371cD5BB5199564C4E89465eb', + lpToken: '0x2302aaBe69e6E7A1b0Aa23aAC68fcCB8A4D2B460', + }, + }, + + { + symbol: 'TUSD-FRAXBP', + name: 'tusdfraxbp', + coins: [ + coins.TUSD, + coins.FRAXBP, + ], + coinDecimals: [18, 18], + addresses: { + swap: '0x33baeDa08b8afACc4d3d07cf31d49FC1F1f3E893', + lpToken: '0x33baeDa08b8afACc4d3d07cf31d49FC1F1f3E893', + }, + }, ]; diff --git a/src/adaptors/conic-finance/abis/conic-controller-abi.json b/src/adaptors/conic-finance/abis/conic-controller-abi.json new file mode 100644 index 0000000000..6a54819382 --- /dev/null +++ b/src/adaptors/conic-finance/abis/conic-controller-abi.json @@ -0,0 +1,630 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "cncToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "curveRegistryCacheAddress_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "convexBooster", + "type": "address" + } + ], + "name": "ConvexBoosterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "convexHandler", + "type": "address" + } + ], + "name": "ConvexHandlerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curveHandler", + "type": "address" + } + ], + "name": "CurveHandlerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curveRegistryCache", + "type": "address" + } + ], + "name": "CurveRegistryCacheSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "inflationManager", + "type": "address" + } + ], + "name": "InflationManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolShutdown", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "priceOracle", + "type": "address" + } + ], + "name": "PriceOracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "weightUpdateMinDelay", + "type": "uint256" + } + ], + "name": "WeightUpdateMinDelaySet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cncToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexBooster", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexHandler", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveHandler", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveRegistryCache", + "outputs": [ + { + "internalType": "contract ICurveRegistryCache", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyMinter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inflationManager", + "outputs": [ + { + "internalType": "contract IInflationManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "isActivePool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "isPool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastWeightUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "listActivePools", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "listPools", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpTokenStaker", + "outputs": [ + { + "internalType": "contract ILpTokenStaker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceOracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "removePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convexBooster", + "type": "address" + } + ], + "name": "setConvexBooster", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_convexHandler", + "type": "address" + } + ], + "name": "setConvexHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_curveHandler", + "type": "address" + } + ], + "name": "setCurveHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "curveRegistryCache_", + "type": "address" + } + ], + "name": "setCurveRegistryCache", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setInflationManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lpTokenStaker", + "type": "address" + } + ], + "name": "setLpTokenStaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + } + ], + "name": "setPriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "delay", + "type": "uint256" + } + ], + "name": "setWeightUpdateMinDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "shutdownPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "conicPoolAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct IConicPool.PoolWeight[]", + "name": "weights", + "type": "tuple[]" + } + ], + "internalType": "struct IController.WeightUpdate[]", + "name": "weights", + "type": "tuple[]" + } + ], + "name": "updateAllWeights", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "conicPoolAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct IConicPool.PoolWeight[]", + "name": "weights", + "type": "tuple[]" + } + ], + "internalType": "struct IController.WeightUpdate", + "name": "update", + "type": "tuple" + } + ], + "name": "updateWeights", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "weightUpdateMinDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/conic-finance/abis/conic-erc20-abi.json b/src/adaptors/conic-finance/abis/conic-erc20-abi.json new file mode 100644 index 0000000000..e1f61ef809 --- /dev/null +++ b/src/adaptors/conic-finance/abis/conic-erc20-abi.json @@ -0,0 +1,288 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/conic-finance/abis/conic-inflation-manager-abi.json b/src/adaptors/conic-finance/abis/conic-inflation-manager-abi.json new file mode 100644 index 0000000000..483af4c1d1 --- /dev/null +++ b/src/adaptors/conic-finance/abis/conic-inflation-manager-abi.json @@ -0,0 +1,400 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "PoolWeightsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "name": "RebalancingRewardHandlerAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "name": "RebalancingRewardHandlerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cncAmount", + "type": "uint256" + } + ], + "name": "TokensClaimed", + "type": "event" + }, + { + "inputs": [], + "name": "CNC", + "outputs": [ + { + "internalType": "contract ICNCToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rebalancingRewardHandler", + "type": "address" + } + ], + "name": "addPoolRebalancingRewardHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "computePoolWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "poolWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalUSDValue", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "computePoolWeights", + "outputs": [ + { + "internalType": "address[]", + "name": "pools", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "poolWeights", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "totalUSDValue", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract IController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentInflationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "currentPoolWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "executeInflationRateUpdate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getCurrentPoolInflationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deviationBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deviationAfter", + "type": "uint256" + } + ], + "name": "handleRebalancingRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + } + ], + "name": "hasPoolRebalancingRewardHandlers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastInflationRateDecay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + } + ], + "name": "rebalancingRewardHandlers", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rebalancingRewardHandler", + "type": "address" + } + ], + "name": "removePoolRebalancingRewardHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalLpInflationMinted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/conic-finance/abis/conic-pool-abi.json b/src/adaptors/conic-finance/abis/conic-pool-abi.json new file mode 100644 index 0000000000..6c43f0548b --- /dev/null +++ b/src/adaptors/conic-finance/abis/conic-pool-abi.json @@ -0,0 +1,1002 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_underlying", + "type": "address" + }, + { + "internalType": "address", + "name": "_controller", + "type": "address" + }, + { + "internalType": "address", + "name": "locker", + "type": "address" + }, + { + "internalType": "string", + "name": "_lpTokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_cvx", + "type": "address" + }, + { + "internalType": "address", + "name": "_crv", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "claimedCrv", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimedCvx", + "type": "uint256" + } + ], + "name": "ClaimedRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "CurvePoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "CurvePoolRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newThreshold", + "type": "uint256" + } + ], + "name": "DepegThresholdUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositedAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpReceived", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "HandledDepeggedCurvePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "curvePool_", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pid_", + "type": "uint256" + } + ], + "name": "HandledInvalidConvexPid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxDeviation", + "type": "uint256" + } + ], + "name": "MaxDeviationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newRatio", + "type": "uint256" + } + ], + "name": "NewMaxIdleCurveLpRatio", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "curvePool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWeight", + "type": "uint256" + } + ], + "name": "NewWeight", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Shutdown", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "CNC", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CRV", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CVX", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "addCurvePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allCurvePools", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cachedTotalUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "computeDeviationRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "computeTotalDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract IController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curvePoolsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depegThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "underlyingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minLpReceived", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stake", + "type": "bool" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "underlyingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minLpReceived", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minLpReceived", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stake", + "type": "bool" + } + ], + "name": "depositFor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllocatedUnderlying", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct IConicPool.PoolWithAmount[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getCurvePoolAtIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalAndPerPoolUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "totalUnderlying_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAllocated_", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "perPoolUnderlying_", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "curvePool", + "type": "address" + } + ], + "name": "getWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWeights", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct IConicPool.PoolWeight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "handleDepeggedCurvePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "handleInvalidConvexPid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isBalanced", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "isRegisteredCurvePool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract ILpToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxIdleCurveLpRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebalancingRewardActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "removeCurvePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardManager", + "outputs": [ + { + "internalType": "contract IRewardManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxDeviation_", + "type": "uint256" + } + ], + "name": "setMaxDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxIdleCurveLpRatio_", + "type": "uint256" + } + ], + "name": "setMaxIdleCurveLpRatio", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shutdownPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "curvePool_", + "type": "address" + } + ], + "name": "totalCurveLpBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDeviationAfterWeightUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "contract IERC20Metadata", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "conicLpAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minUnderlyingReceived", + "type": "uint256" + } + ], + "name": "unstakeAndWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newDepegThreshold_", + "type": "uint256" + } + ], + "name": "updateDepegThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct IConicPool.PoolWeight[]", + "name": "poolWeights", + "type": "tuple[]" + } + ], + "name": "updateWeights", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "conicLpAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minUnderlyingReceived", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/conic-finance/index.js b/src/adaptors/conic-finance/index.js new file mode 100755 index 0000000000..cf593e6a30 --- /dev/null +++ b/src/adaptors/conic-finance/index.js @@ -0,0 +1,222 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const controllerAbi = require('./abis/conic-controller-abi.json'); +const poolAbi = require('./abis/conic-pool-abi.json'); +const inflationManagerAbi = require('./abis/conic-inflation-manager-abi.json'); + +const BLOCKS_PER_YEAR = 2580032; + +const CONTROLLER = '0x2790EC478f150a98F5D96755601a26403DF57EaE'; +const INFLATION_MANAGER = '0x05F494E6554fab539873dcF92A4D2F6930105B16'; +const CRV = '0xD533a949740bb3306d119CC777fa900bA034cd52'; +const CVX = '0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B'; +const CNC = '0x9aE380F0272E2162340a5bB646c354271c0F5cFC'; + +const PRICE_API = 'https://coins.llama.fi/prices/current'; +const CURVE_APY_API = 'https://www.convexfinance.com/api/curve-apys'; +const CURVE_POOL_API = 'https://api.curve.finance/api/getPools/ethereum/main'; + +const deployedAtBlock = { + "0x3367070ed152e2b715eef48D157685Cf496f3543": 19083793, + "0x89dc3E9d493512F6CFb923E15369ebFddE591988": 19070921, + "0x80a3604977270B7Ef2e637f9Eb78cE1c3FA64316": 19083785, + "0x40293380F5292Bb13905608b35a936c332f07f94": 16734615, + "0xAbb735648a076d570AfF2A61D8D141099823EAe9": 16734603, + "0xf432110e5206356CD6448dA16b05394a89B44CeF": 17025759, + "0xBb787d6243a8D450659E09ea6fD82F1C859691e9": 17642186, + "0x369cBC5C6f139B1132D3B91B87241B37Fc5B971f": 17441732, + "0x07b577f10d4e00f3018542d08a87F255a49175A5": 16734568, + "0xb083AD0933fADF12761450a4FD45775B9Fb6Df77": 19569203, + "0x72c23c94f68669C7B6A5B6e8c87aa9B70c263140": 15509203, +}; + +const CURVE_POOL_DATA = { + // USDC+crvUSD + '0x4DEcE678ceceb27446b35C672dC7d61F30bAD69E': { + convexId: 'factory-crvusd-0', + }, + // USDT+crvUSD + '0x390f3595bCa2Df7d23783dFd126427CCeb997BF4': { + convexId: 'factory-crvusd-1', + }, + // USDP+crvUSD + '0xCa978A0528116DDA3cbA9ACD3e68bc6191CA53D0': { + convexId: 'factory-crvusd-2', + }, + // TUSD+crvUSD + '0x34D655069F4cAc1547E4C8cA284FfFF5ad4A8db0': { + convexId: 'factory-crvusd-3', + }, +}; + +const bnToNum = (bn, dec = 18) => Number(bn.toString()) / 10 ** dec; + +const curvePoolId = (poolData, poolAddress) => { + const override = CURVE_POOL_DATA[poolAddress]; + if (override) return override.convexId; + const data = poolData.find((p) => p.address === poolAddress); + if (!data) return null; + return data.id; +}; + +const poolApy = ( + weights_, + apyData, + poolData, + blockNumber_, + deployedAtBlock_, + exchangeRate_ +) => { + const scale = BLOCKS_PER_YEAR / (blockNumber_ - deployedAtBlock_); + let positiveSlippageApr = (bnToNum(exchangeRate_) ** scale - 1) * 100; + + // Handle edge cases when the pool is first deployed + if (positiveSlippageApr < 0) positiveSlippageApr = 0; + + const base = + weights_.reduce((total, weight) => { + const id = curvePoolId(poolData, weight.poolAddress); + if (!id) return total; + const apy = apyData[id]; + return apy.baseApy * bnToNum(weight.weight) + total; + }, 0) + positiveSlippageApr; + const crv = weights_.reduce((total, weight) => { + const id = curvePoolId(poolData, weight.poolAddress); + if (!id) return total; + const apy = apyData[id]; + return apy.crvApy * bnToNum(weight.weight) + total; + }, 0); + return { + base, + crv: crv, + }; +}; + +const apy = async () => { + const addresses_ = ( + await sdk.api.abi.call({ + target: CONTROLLER, + abi: controllerAbi.find((m) => m.name === 'listPools'), + }) + ).output; + + const inflationRate_ = ( + await sdk.api.abi.call({ + target: INFLATION_MANAGER, + abi: inflationManagerAbi.find((m) => m.name === 'currentInflationRate'), + }) + ).output; + + const underlying = ( + await sdk.api.abi.multiCall({ + calls: addresses_.map((i) => ({ + target: i, + })), + abi: poolAbi.find((m) => m.name === 'underlying'), + }) + ).output.map((o) => o.output); + + const priceKeys = [...underlying, CNC].map((i) => `ethereum:${i}`).join(','); + const prices = (await utils.getData(`${PRICE_API}/${priceKeys}`)).coins; + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: underlying.map((i) => ({ + target: i, + })), + abi: 'erc20:symbol', + }) + ).output.map((o) => o.output); + + const decimals = ( + await sdk.api.abi.multiCall({ + calls: underlying.map((i) => ({ + target: i, + })), + abi: 'erc20:decimals', + }) + ).output.map((o) => o.output); + + const totalUnderlying = ( + await sdk.api.abi.multiCall({ + calls: addresses_.map((i) => ({ + target: i, + })), + abi: poolAbi.find((m) => m.name === 'totalUnderlying'), + }) + ).output.map((o) => o.output); + + const weights = ( + await sdk.api.abi.multiCall({ + calls: addresses_.map((i) => ({ + target: i, + })), + abi: poolAbi.find((m) => m.name === 'getWeights'), + }) + ).output.map((o) => o.output); + + const exchangeRate = ( + await sdk.api.abi.multiCall({ + calls: addresses_.map((i) => ({ + target: i, + })), + abi: poolAbi.find((m) => m.name === 'exchangeRate'), + }) + ).output.map((o) => o.output); + + const blockNumber = (await sdk.util.blocks.getBlock('ethereum')).block; + + const cncUsdPerYear = + bnToNum(inflationRate_) * prices[`ethereum:${CNC}`].price * 365 * 86400; + + const apyData = (await utils.getData(CURVE_APY_API)).apys; + const poolData = (await utils.getData(CURVE_POOL_API)).data.poolData; + + const pools_ = addresses_.map((address, i) => { + const apr = poolApy( + weights[i], + apyData, + poolData, + blockNumber, + deployedAtBlock[address], + exchangeRate[i] + ); + + return { + underlying: underlying[i], + symbol: symbols[i], + decimals: decimals[i], + totalUnderlying: bnToNum(totalUnderlying[i], decimals[i]), + price: prices[`ethereum:${underlying[i]}`]?.price, + baseApy: apr.base, + crvApy: apr.crv, + }; + }); + + const totalTvl = pools_.reduce((total, pool_) => { + return total + pool_.totalUnderlying * pool_.price; + }, 0); + const cncApy = (cncUsdPerYear / totalTvl) * 100; + + return pools_.map((pool_) => { + const tvlUsd = pool_.totalUnderlying * pool_.price; + return { + pool: `conic-${pool_.symbol}-ethereum`.toLowerCase(), + chain: 'Ethereum', + project: 'conic-finance', + symbol: pool_.symbol === 'WETH' ? 'ETH' : pool_.symbol, + tvlUsd, + rewardTokens: [CNC, CRV, CVX], + underlyingTokens: [pool_.underlying], + apyBase: pool_.baseApy, + apyReward: pool_.crvApy + cncApy, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://conic.finance/', +}; diff --git a/src/adaptors/connext/index.js b/src/adaptors/connext/index.js new file mode 100644 index 0000000000..89f746fd10 --- /dev/null +++ b/src/adaptors/connext/index.js @@ -0,0 +1,281 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const API_URL = 'https://sdk-server.mainnet.connext.ninja'; + +const CHAIN_DOMAINS = { + arbitrum: '1634886255', + bsc: '6450786', + polygon: '1886350457', + gnosis: '6778479', + optimism: '1869640809', + linea: '1818848877', + metis: '1835365481', + base: '1650553709', + mode: '1836016741', +}; + +const POOL_TOKEN_SYMBOLS = { + 'WETH-nextWETH': 'eth', + 'USDC-nextUSDC': 'usdc', + 'USDT-nextUSDT': 'usdt', + 'DAI-nextDAI': 'dai', + 'METIS-nextMETIS': 'metis', +} + +const POOLS_META = [ + { + poolName: 'WETH-nextWETH', + adopted: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + local: '0x2983bf5c334743Aa6657AD70A55041d720d225dB', + chain: 'arbitrum' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + local: '0xA9CB51C666D2AF451d87442Be50747B31BB7d805', + chain: 'bsc' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + local: '0x4b8BaC8Dd1CAA52E32C07755c17eFadeD6A0bbD0', + chain: 'polygon' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1', + local: '0x538E2dDbfDf476D24cCb1477A518A82C9EA81326', + chain: 'gnosis' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x4200000000000000000000000000000000000006', + local: '0xbAD5B3c68F855EaEcE68203312Fd88AD3D365e50', + chain: 'optimism' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f', + local: '0x0573AD07cA4f74757e5B2417Bf225BEbeBcF66D9', + chain: 'linea' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x420000000000000000000000000000000000000a', + local: '0x3883B5Bdd61BA1b687de69eE50c9738D5ec501E9', + chain: 'metis' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x4200000000000000000000000000000000000006', + local: '0xE08D4907b2C7aa5458aC86596b6D17B1feA03F7E', + chain: 'base' + }, + { + poolName: 'WETH-nextWETH', + adopted: '0x4200000000000000000000000000000000000006', + local: '0x609aEfb9FB2Ee8f2FDAd5dc48efb8fA4EE0e80fB', + chain: 'mode' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + local: '0x5e7D83dA751F4C9694b13aF351B30aC108f32C38', + chain: 'bsc' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + local: '0x8c556cF37faa0eeDAC7aE665f1Bb0FbD4b2eae36', + chain: 'arbitrum' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + local: '0xF96C6d2537e1af1a9503852eB2A4AF264272a5B6', + chain: 'polygon' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83', + local: '0x44CF74238d840a5fEBB0eAa089D05b763B73faB8', + chain: 'gnosis' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607', + local: '0x67E51f46e8e14D4E4cab9dF48c59ad8F512486DD', + chain: 'optimism' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0x176211869cA2b568f2A7D4EE941E073a821EE1ff', + local: '0x331152ca43B50B39F3a9f203685B98dbb9b42342', + chain: 'linea' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0xEA32A96608495e54156Ae48931A7c20f0dcc1a21', + local: '0x9ac9aD5A82Ccd0Ab7584a037A7A2334Dc3715Be2', + chain: 'metis' + }, + { + poolName: 'USDC-nextUSDC', + adopted: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + local: '0x1ede59e0d39B14c038698B1036BDE9a4819C86D4', + chain: 'base' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0x55d398326f99059fF775485246999027B3197955', + local: '0xD609f26B5547d5E31562B29150769Cb7c774B97a', + chain: 'bsc' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + local: '0x2fD7E61033b3904c65AA9A9B83DCd344Fa19Ffd2', + chain: 'arbitrum' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + local: '0xE221C5A2a8348f12dcb2b0e88693522EbAD2690f', + chain: 'polygon' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0x4ECaBa5870353805a9F068101A40E0f32ed605C6', + local: '0xF4d944883D6FddC56d3534986feF82105CaDbfA1', + chain: 'gnosis' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', + local: '0x4cBB28FA12264cD8E87C62F4E1d9f5955Ce67D20', + chain: 'optimism' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0xA219439258ca9da29E9Cc4cE5596924745e12B93', + local: '0xbD7eAEd30936670C931B718F5D9014AFf82fC767', + chain: 'linea' + }, + { + poolName: 'USDT-nextUSDT', + adopted: '0xbB06DCA3AE6887fAbF931640f67cab3e3a16F4dC', + local: '0xa6A8d22D5da43C9f6E5cF7b4e50941784e70F688', + chain: 'metis' + }, + { + poolName: 'DAI-nextDAI', + adopted: '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3', + local: '0x86a343BCF17D79C475d300eed35F0145F137D0c9', + chain: 'bsc' + }, + { + poolName: 'DAI-nextDAI', + adopted: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + local: '0xfDe99b3B3fbB69553D7DaE105EF34Ba4FE971190', + chain: 'arbitrum' + }, + { + poolName: 'DAI-nextDAI', + adopted: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063', + local: '0xaDCe87b14d570665222C1172D18a221BF7690d5a', + chain: 'polygon' + }, + { + poolName: 'DAI-nextDAI', + adopted: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', + local: '0x0e1D5Bcd2Ac5CF2f71841A9667afC1E995CaAf4F', + chain: 'gnosis' + }, + { + poolName: 'DAI-nextDAI', + adopted: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + local: '0xd64Bd028b560bbFc732eA18f282c64B86F3468e0', + chain: 'optimism' + }, + { + poolName: 'METIS-nextMETIS', + adopted: '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000', + local: '0x1a1162304654A79B4b6A3aF0D564CA1E3cC7cc1B', + chain: 'metis' + }, +]; + +const URL_FORMATTED_CHAINS = { + arbitrum: 'arbitrum', + bsc: 'binance', + polygon: 'polygon', + gnosis: 'gnosis', + optimism: 'optimism', + linea: 'linea', + metis: 'metis', + base: 'base', + mode: 'mode', +}; + + +const constructPoolUrl = (poolName, chain) => { + const symbol = POOL_TOKEN_SYMBOLS[poolName].toUpperCase(); + const urlFormattedChain = URL_FORMATTED_CHAINS[chain]; + return `https://bridge.connext.network/pool/${symbol}-on-${urlFormattedChain}`; +} + +const getApy = async () => { + const priceData = await Promise.all([ + utils.getPrices(['ethereum'], ['coingecko']), + utils.getPrices([ + // USDC + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + // USDT + "0xdAC17F958D2ee523a2206206994597C13D831ec7", + // DAI + "0x6B175474E89094C44Da98b954EedeAC495271d0F", + // METIS + "0x9e32b13ce7f2e80a01932b42553652e053d6ed8e" + ], "ethereum") + ]) + + const pools = []; + const promises = []; + for (const meta of POOLS_META) { + const poolTokenSymbol = POOL_TOKEN_SYMBOLS[meta.poolName] + const price = priceData.find((p) => poolTokenSymbol in p.pricesBySymbol).pricesBySymbol[poolTokenSymbol] + + const promise = axios.post(`${API_URL}/getYieldData`, { + domainId: CHAIN_DOMAINS[meta.chain], + tokenAddress: meta.adopted, + days: 7, + }).then((yieldStats) => { + pools.push({ + pool: `${meta.local}-${meta.chain}`, + chain: utils.formatChain(meta.chain), + project: 'connext', + symbol: meta.poolName, + apyBase: yieldStats.data.apy * 100, + apyReward: 0, + rewardTokens: [], + underlyingTokens: [meta.adopted, meta.local], + tvlUsd: yieldStats.data.liquidity * price, + url: constructPoolUrl(meta.poolName, meta.chain) + }); + }); + + promises.push(promise); + } + + await Promise.all(promises); + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/convex-finance/abi.json b/src/adaptors/convex-finance/abi.json index ec7074b758..6b8711e997 100644 --- a/src/adaptors/convex-finance/abi.json +++ b/src/adaptors/convex-finance/abi.json @@ -538,193 +538,5 @@ "type": "function" } ], - "Pool": [ - { - "inputs": [ - { "internalType": "address", "name": "_operator", "type": "address" }, - { "internalType": "address", "name": "_lptoken", "type": "address" } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { "internalType": "address", "name": "owner", "type": "address" }, - { "internalType": "address", "name": "spender", "type": "address" } - ], - "name": "allowance", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "approve", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "account", "type": "address" } - ], - "name": "balanceOf", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_from", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" } - ], - "name": "burn", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender", "type": "address" }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "spender", "type": "address" }, - { "internalType": "uint256", "name": "addedValue", "type": "uint256" } - ], - "name": "increaseAllowance", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "_to", "type": "address" }, - { "internalType": "uint256", "name": "_amount", "type": "uint256" } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "operator", - "outputs": [{ "internalType": "address", "name": "", "type": "address" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [{ "internalType": "string", "name": "", "type": "string" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "transfer", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "address", "name": "sender", "type": "address" }, - { "internalType": "address", "name": "recipient", "type": "address" }, - { "internalType": "uint256", "name": "amount", "type": "uint256" } - ], - "name": "transferFrom", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "nonpayable", - "type": "function" - } - ] + "Pool": [{"name":"Transfer","inputs":[{"name":"_from","type":"address","indexed":true},{"name":"_to","type":"address","indexed":true},{"name":"_value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"_owner","type":"address","indexed":true},{"name":"_spender","type":"address","indexed":true},{"name":"_value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":288},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":78640},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":116582},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":39121},{"stateMutability":"nonpayable","type":"function","name":"increaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_added_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":41665},{"stateMutability":"nonpayable","type":"function","name":"decreaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_subtracted_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":41689},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":80879},{"stateMutability":"nonpayable","type":"function","name":"burnFrom","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":80897},{"stateMutability":"nonpayable","type":"function","name":"set_minter","inputs":[{"name":"_minter","type":"address"}],"outputs":[],"gas":37785},{"stateMutability":"nonpayable","type":"function","name":"set_name","inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"outputs":[],"gas":181462},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":12918},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":10671},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":2963},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3208},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2808},{"stateMutability":"view","type":"function","name":"minter","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2838}] } diff --git a/src/adaptors/convex-finance/baseRewardPoolAbi.json b/src/adaptors/convex-finance/baseRewardPoolAbi.json new file mode 100644 index 0000000000..174fc8f1d8 --- /dev/null +++ b/src/adaptors/convex-finance/baseRewardPoolAbi.json @@ -0,0 +1,363 @@ +[ + { + "inputs": [ + { "internalType": "uint256", "name": "pid_", "type": "uint256" }, + { "internalType": "address", "name": "stakingToken_", "type": "address" }, + { "internalType": "address", "name": "rewardToken_", "type": "address" }, + { "internalType": "address", "name": "operator_", "type": "address" }, + { "internalType": "address", "name": "rewardManager_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "_reward", "type": "address" } + ], + "name": "addExtraReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clearExtraRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "donate", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "extraRewards", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "extraRewardsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "bool", "name": "_claimExtras", "type": "bool" } + ], + "name": "getReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "historicalRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newRewardRatio", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_rewards", "type": "uint256" } + ], + "name": "queueNewRewards", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "queuedRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakeAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_for", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "stakeFor", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bool", "name": "claim", "type": "bool" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "claim", "type": "bool" }], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "claim", "type": "bool" }], + "name": "withdrawAllAndUnwrap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bool", "name": "claim", "type": "bool" } + ], + "name": "withdrawAndUnwrap", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/convex-finance/cvxCrvUtilitiesAbi.json b/src/adaptors/convex-finance/cvxCrvUtilitiesAbi.json new file mode 100644 index 0000000000..501f32d409 --- /dev/null +++ b/src/adaptors/convex-finance/cvxCrvUtilitiesAbi.json @@ -0,0 +1,261 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_stkcvxcrv", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "accountExtraRewardRates", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rates", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "groups", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "accountRewardRates", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rates", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "groups", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_priceOfReward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_priceOfDeposit", + "type": "uint256" + } + ], + "name": "apr", + "outputs": [ + { + "internalType": "uint256", + "name": "_apr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crv", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvx", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvxCrvStaking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvxMining", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "externalRewardContracts", + "outputs": [ + { + "internalType": "address[]", + "name": "rewardContracts", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "extraRewardRates", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rates", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "groups", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mainRewardRates", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rates", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "groups", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardContract", + "type": "address" + } + ], + "name": "singleRewardRate", + "outputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stkcvxcrv", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/convex-finance/data/cvxcrv-apr.js b/src/adaptors/convex-finance/data/cvxcrv-apr.js new file mode 100644 index 0000000000..3776c79c9b --- /dev/null +++ b/src/adaptors/convex-finance/data/cvxcrv-apr.js @@ -0,0 +1,101 @@ +const sdk = require('@defillama/sdk'); +const cvxCrvUtilitiesAbi = require('../cvxCrvUtilitiesAbi.json'); +const abi = require('../abi.json'); +const BN = require('bignumber.js'); +const { getTokensPrices } = require('./token-prices'); + +const tricrvAddress = '0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490'; +const cvxCrvAddress = '0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7'; +const cvxCrvUtilitiesAddress = '0xadd2F542f9FF06405Fabf8CaE4A74bD0FE29c673'; + +const getCvxCrvAprData = async () => { + const [ + { output: mainRewardRates }, + { output: extraRewardRates }, + ] = await Promise.all([ + 'mainRewardRates', + 'extraRewardRates', + ].map((methodName) => ( + sdk.api.abi.call({ + target: cvxCrvUtilitiesAddress, + abi: cvxCrvUtilitiesAbi.find((x) => x.name === methodName), + chain: 'ethereum', + })) + )); + + const rewardRates = { + groups: [ + ...mainRewardRates.groups, + ...extraRewardRates.groups, + ], + rates: [ + ...mainRewardRates.rates, + ...extraRewardRates.rates, + ], + tokens: [ + ...mainRewardRates.tokens, + ...extraRewardRates.tokens, + ], + }; + + const mergedRewardRates = rewardRates.tokens.reduce((accu, tokenAddress, i) => { + // CvxCrvUtilities doesn't look at periodFinish: 3crv distrib is finished + if (tokenAddress.toLowerCase() === tricrvAddress.toLowerCase()) return accu; + + const indexOfToken = accu.tokens.indexOf(tokenAddress); + const tokenAlreadyExists = indexOfToken !== -1; + + if (tokenAlreadyExists) { + accu.rates[indexOfToken] = accu.rates[indexOfToken].plus(BN(rewardRates.rates[i])); + } else { + accu.groups.push(Number(rewardRates.groups[i])); + accu.rates.push(BN(rewardRates.rates[i])); + accu.tokens.push(rewardRates.tokens[i]); + } + + return accu; + }, { + groups: [], + rates: [], + tokens: [], + }); + + const rewardsTokensDecimals = (await sdk.api.abi.multiCall({ + calls: mergedRewardRates.tokens.map((address) => ({ + target: address, + params: null, + })), + abi: abi.Pool.find(({ name }) => name === 'decimals'), + chain: 'ethereum', + })).output.map(({ output }) => Number(output)); + + const tokensPrices = await getTokensPrices([...mergedRewardRates.tokens, cvxCrvAddress]); + const cvxCrvPrice = tokensPrices[cvxCrvAddress.toLowerCase()]; + + const mainRewards = mergedRewardRates.tokens.map((tokenAddress, i) => { + const rewardCoinDecimals = rewardsTokensDecimals[i]; + const rateBN = mergedRewardRates.rates[i].div(10 ** rewardCoinDecimals); + const rewardCoinPrice = tokensPrices[tokenAddress.toLowerCase()]; + + const apr = rateBN + .times(rewardCoinPrice) + .div(cvxCrvPrice) + .times(86400 * 365) + .times(100); + + return { + token: tokenAddress, + apr, + group: mergedRewardRates.groups[i], + }; + }); + + const totalGroup0Apr = BN.sum(...mainRewards.filter(({ group }) => group === 0).map(({ apr }) => apr)).dp(2).toNumber(); + const totalGroup1Apr = BN.sum(...mainRewards.filter(({ group }) => group === 1).map(({ apr }) => apr)).dp(2).toNumber(); + + return Math.max(totalGroup0Apr, totalGroup1Apr); +}; + +module.exports = { + getCvxCrvAprData, +}; diff --git a/src/adaptors/convex-finance/data/token-prices.js b/src/adaptors/convex-finance/data/token-prices.js new file mode 100644 index 0000000000..463e8de8bb --- /dev/null +++ b/src/adaptors/convex-finance/data/token-prices.js @@ -0,0 +1,18 @@ +const fetch = require('node-fetch') + +// [['a', '1'], ['b', 2], …] -> { a: 1, b: 2, … } +const arrayToHashmap = (array) => ( + Object.assign({}, ...array.map(([key, val]) => ({ [key]: val }))) +); + +const getTokensPrices = async (addresses, platform = 'ethereum') => ( + (await fetch(`https://coins.llama.fi/prices/current/${addresses.map((a) => `${platform}:${a}`).join(',')}`)).json() + .then(({ coins: prices }) => arrayToHashmap(Object.entries(prices).map(([platformAndAddress, { price: usdPrice }]) => [ + platformAndAddress.split(':')[1].toLowerCase(), + usdPrice, + ]))) +); + +module.exports = { + getTokensPrices, +}; diff --git a/src/adaptors/convex-finance/index.js b/src/adaptors/convex-finance/index.js index 802b24493b..a6f740bd4a 100755 --- a/src/adaptors/convex-finance/index.js +++ b/src/adaptors/convex-finance/index.js @@ -1,485 +1,444 @@ const superagent = require('superagent'); -const Web3 = require('web3'); +const sdk = require('@defillama/sdk'); +require('dotenv').config({ path: './config.env' }); const utils = require('../utils'); -const curve = require('../curve/index'); const abi = require('./abi.json'); - -// https://etherscan.io/address/0xF403C135812408BFbE8713b5A23a04b3D48AAE31#readContract -// check poolInfo method (input are the below id's) -// the swap contract address can be found here: https://curve.fi/contracts -const pools = require('./pools.json'); - -const ETHERSCAN_KEY = process.env.ETHERSCAN; +const baseRewardPoolAbi = require('./baseRewardPoolAbi.json'); +const virtualBalanceRewardPoolAbi = require('./virtualBalanceRewardPoolAbi.json'); +const { getCvxCrvAprData } = require('./data/cvxcrv-apr'); +const { getTokensPrices } = require('./data/token-prices'); const crvAddress = '0xD533a949740bb3306d119CC777fa900bA034cd52'; const cvxAddress = '0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B'; +const crvUsdAddress = '0xf939e0a03fb07f59a73314e73794be0e57ac1b4e'; +const convexBoosterAddress = '0xF403C135812408BFbE8713b5A23a04b3D48AAE31'; const cliffSize = 100000; // * 1e18; //new cliff every 100,000 tokens const cliffCount = 1000; // 1,000 cliffs const maxSupply = 100000000; // * 1e18; //100 mil max supply +const projectedAprTvlThr = 1e6; -const getKeyByValue = (object, value) => { - return Object.keys(object).find((key) => object[key] === value); -}; - -const getCvxTvl = async (poolStatsCrv) => { - // main deposit contract - const convexBoosterAddress = '0xF403C135812408BFbE8713b5A23a04b3D48AAE31'; +let extraRewardsPrices = {}; - const web3 = new Web3(process.env.INFURA_CONNECTION); - const convexBoosterContract = new web3.eth.Contract( - abi.Booster, - convexBoosterAddress +const main = async () => { + const [ + { apys: curveApys }, + { data: gauges }, + { lendingVaults }, + ] = await Promise.all([ + utils.getData('https://curve.convexfinance.com/api/curve-apys'), + utils.getData('https://api.curve.finance/api/getAllGauges'), + utils.getData('https://curve.convexfinance.com/api/curve/lending-vaults'), + ]); + + const { + [crvAddress.toLowerCase()]: crvPrice, + [cvxAddress.toLowerCase()]: cvxPrice, + } = await getTokensPrices([crvAddress, cvxAddress]); + + const poolsList = (await utils.getData('https://api.curve.finance/api/getPools/all/ethereum')).data.poolData + .filter((i) => i?.address !== undefined); + + Object.keys(gauges).forEach((key) => { + if (gauges[key].isPool && gauges[key].swap_token === undefined) { + delete gauges[key]; + } + }); + + const mappedGauges = Object.values(gauges).reduce( + (acc, gauge) => ({ + ...acc, + ...(gauge.blockchainId !== 'ethereum' + ? {} + : { [(gauge.isPool ? gauge.swap_token : gauge.lendingVaultAddress).toLowerCase()]: { ...gauge } }), + }), + {} ); - const liquidityData = []; - // this is the part we need to loop (there are 39 pools) pass this in as an arg - const tokenIds = pools.map((el) => el.id); - - // price data - const pricesUSD = await utils.getCGpriceData( - 'ethereum,bitcoin,chainlink,stasis-eurs,tether-eurt', - true + const poolLength = ( + await sdk.api.abi.call({ + target: convexBoosterAddress, + abi: abi.Booster.find(({ name }) => name === 'poolLength'), + chain: 'ethereum', + }) + ).output; + const pools = ( + await sdk.api.abi.multiCall({ + requery: true, + abi: abi.Booster.find(({ name }) => name === 'poolInfo'), + calls: [...Array.from({ length: poolLength }).keys()].map((i) => ({ + target: convexBoosterAddress, + params: i, + })), + }) + ).output.map(({ output }) => output); + + let enrichedPools = pools.map((pool) => ({ + ...pool, + ...poolsList.find( + ({ address, lpTokenAddress, gaugeAddress }) => + address.toLowerCase() === pool.lptoken.toLowerCase() || + pool.lptoken.toLowerCase() === (lpTokenAddress || '').toLowerCase() || + (gaugeAddress || '').toLowerCase() === pool.gauge.toLowerCase() + ), + ...lendingVaults.find(({ address }) => address.toLowerCase() === pool.lptoken.toLowerCase()), + })).map((data) => ({ + ...data, + isLendingVault: data.lendingVaultUrls !== undefined, + isPool: data.lendingVaultUrls === undefined, + })).map((data) => ({ + ...data, + coinsAddresses: ( + data.isPool ? data.coinsAddresses : [data.assets.borrowed.address] + ), + })); + // remove dupes on lptoken + enrichedPools = enrichedPools.filter( + (v, i, a) => a.findIndex((v2) => v2.lptoken === v.lptoken) === i ); - for (const i of tokenIds) { - const result = await convexBoosterContract.methods.poolInfo(i).call(); - // this is the lp token we receive by depositing the curve lp token into convex - const tokenAddress = result.token; - - // now we take that info, and go to that token contract, - // from which we call the totalSupply method - const tokenContract = new web3.eth.Contract(abi.Pool, tokenAddress); - const decimals = await tokenContract.methods.decimals().call(); - let name = await tokenContract.methods.name().call(); - - // I change the names so they match what I have in the mapping - const crv3 = 'DAI-USDC-USDT'; - // first case is tricrypto - if (name.includes('USD-BTC-ETH')) { - name = 'USDT-wBTC-WETH'; - } else if (name.includes('TrueUSD')) { - name = curve.tokenMapping['tusd']; - } else if (name.includes('Frax')) { - name = curve.tokenMapping['frax']; - } else if (name.includes('Liquity')) { - name = curve.tokenMapping['lusd']; - } else if (name.includes('Alchemix')) { - name = curve.tokenMapping['alusd']; - } else if (name.includes('PAX')) { - name = curve.tokenMapping['pax']; - } else if (name.includes('renBTC-wBTC-sBTC')) { - name = curve.tokenMapping['rens']; - } else if (name.includes('hBTC')) { - name = curve.tokenMapping['hbtc']; - } else if (name.includes('bBTC')) { - name = curve.tokenMapping['bbtc']; - } else if (name.includes('aETH')) { - name = curve.tokenMapping['ankreth']; - } else if (name.includes('Binance')) { - name = curve.tokenMapping['busdv2']; - } else if (name.includes('MUSD')) { - name = curve.tokenMapping['musd']; - } else if (name.includes('pBTC')) { - name = curve.tokenMapping['pbtc']; - } else if (name.includes('oBTC')) { - name = curve.tokenMapping['obtc']; - } else if (name.includes('EURS/sEUR')) { - name = curve.tokenMapping['eurs']; - } else if (name.includes('Magic Internet Money')) { - name = curve.tokenMapping['mim']; - } else if (name.includes('RAI3CRV')) { - name = curve.tokenMapping['rai']; - } else if (name.includes('XAUT-3Crv')) { - name = curve.tokenMapping['xautusd']; - } else if (name.includes('Euro Tether')) { - name = curve.tokenMapping['eurt']; - } else if (name.includes('EURS-USDC')) { - name = curve.tokenMapping['eursusd']; - } else if (name.includes('EURT-3Crv')) { - name = curve.tokenMapping['eurtusd']; - } else { - name = name.split(' ')[1].split('/').join('-'); - } - name = name.replace('3Crv', crv3); - - // for tricrypto we check the full symbol - // and set the price to 1, which wont modify the total supply - // we will do this in a sep func - let price = 1; - if (name === 'USDT-wBTC-WETH') { - if (i === 37) { - pos = poolStatsCrv.find((el) => el.pool === 'tricrypto'); - } else if (i === 38) { - pos = poolStatsCrv.find((el) => el.pool === 'tricrypto2'); + const [totalSupplyRes, decimalsRes] = await Promise.all( + ['totalSupply', 'decimals'].map((method) => + sdk.api.abi.multiCall({ + calls: enrichedPools.map((pool) => ({ + target: pool.token, + params: null, + })), + abi: abi.Pool.find(({ name }) => name === method), + chain: 'ethereum', + }) + ) + ); + const totalSupply = totalSupplyRes.output.map(({ output }) => output); + const decimals = decimalsRes.output.map(({ output }) => output); + + const z = [ + '0x453D92C7d4263201C69aACfaf589Ed14202d83a4', // yCrv + '0x5b6C539b224014A09B3388e51CaAA8e354c959C8', // cbETH + '0x051d7e5609917Bd9b73f04BAc0DED8Dd46a74301', // wbtc-sBTC + '0x9848482da3Ee3076165ce6497eDA906E66bB85C5', // eth-peth + ]; + let withCvxTvl = enrichedPools + .map((pool, i) => { + const gauge = mappedGauges[pool.lptoken.toLowerCase()]; + if (!gauge && !z.includes(pool.lptoken)) return; + const virtualPrice = z.includes(pool.lptoken) + ? pool.virtualPrice + : gauge.swap_data?.virtual_price / 10 ** 18; + if (!pool.coinsAddresses) return null; + let v2PoolUsd; + if (pool.totalSupply == 0) { + const usdValue = pool.coins.reduce( + (acc, coin) => + acc + + (Number(coin.poolBalance) / 10 ** coin.decimals) * coin.usdPrice, + 0 + ); + let supply = pool.coins.reduce( + (acc, coin) => acc + Number(coin.poolBalance) / 10 ** coin.decimals, + 0 + ); + + if (pool.assetTypeName === 'usd') supply = usdValue / virtualPrice; + + v2PoolUsd = (totalSupply[i] / 10 ** decimals[i] / supply) * usdValue; } - price = pos.tvl / pos.totalSupply; - } else if (name.includes('SPELL-ETH')) { - pos = poolStatsCrv.find((el) => el.pool === 'spelleth'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('CVX-ETH')) { - pos = poolStatsCrv.find((el) => el.pool === 'cvxeth'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('CRV-ETH')) { - pos = poolStatsCrv.find((el) => el.pool === 'crveth'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('XAU')) { - pos = poolStatsCrv.find((el) => el.pool === 'xautusd'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('T-ETH')) { - pos = poolStatsCrv.find((el) => el.pool === 'teth'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('EURs-USDC')) { - pos = poolStatsCrv.find((el) => el.pool === 'eursusd'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('EURT-DAI')) { - pos = poolStatsCrv.find((el) => el.pool === 'eurtusd'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('EURT-sEUR')) { - pos = poolStatsCrv.find((el) => el.pool === 'eurt'); - price = pos.tvl / pos.totalSupply; - } else if (name.includes('ETH')) { - price = pricesUSD.ethereum.usd; - } else if (name.includes('BTC')) { - price = pricesUSD.bitcoin.usd; - } else if (name.includes('LINK')) { - price = pricesUSD.chainlink.usd; - } else if (name.includes('EUR')) { - price = pricesUSD['stasis-eurs'].usd; - } - let totalSupply = await tokenContract.methods.totalSupply().call(); - totalSupply = (price * totalSupply) / 10 ** decimals; - - let pool = getKeyByValue(curve.tokenMapping, name); - const o = { - idx: i, - pool: i === 38 ? 'tricrypto2' : pool, - symbol: name, - tvl_usd: totalSupply, - }; - liquidityData.push(o); - } - return liquidityData; -}; - -const getPoolStatsCvx = async () => { - // calculate convex apr/apy values (based on the hardcoded pools info on the btm) - const currentApys = await getCurrentApys(); - - // this is the curve apy data (based on the convex api) - let dataApy = await utils.getData( - 'https://www.convexfinance.com/api/curve-apys' + return { + ...pool, + coinsAddresses: pool.coinsAddresses.filter( + (address) => address !== '0x0000000000000000000000000000000000000000' + ), + cvxTvl: ( + pool.isLendingVault ? pool.convexPoolData.usdTotal : ( + v2PoolUsd + ? v2PoolUsd + : ((totalSupply[i] * virtualPrice) / + (pool.totalSupply * virtualPrice || + pool.usdTotal * 10 ** decimals[i])) * + pool.usdTotal + )), + currency: 'USD', + }; + }) + .filter(Boolean); + + // --- add cvxCRV & CVX staking pools + const cvxCRVRewards = '0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e'; + const cvxCRV = '0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7'; + const cvxRewards = '0xCF50b810E57Ac33B91dCF525C6ddd9881B139332'; + const stakingTvl = await Promise.all( + [cvxCRVRewards, cvxRewards].map( + async (c) => + ( + await sdk.api.abi.call({ + target: c, + abi: baseRewardPoolAbi.find((x) => x.name === 'totalSupply'), + chain: 'ethereum', + }) + ).output / 1e18 + ) ); - // this is the curve stuff before buildPool - const poolStatsCrv = await curve.curvePoolStats(); - - // this is convex tvl stuff - const poolStatsCvx = await getCvxTvl(poolStatsCrv); - - let poolStats = []; - const pools = poolStatsCrv.map((el) => el.pool); - for (const pool of pools) { - // i remove some of the pools (such as tricrypto 1 and eurt (as it has 0 apy)) - if (pool === 'eurt' || pool === 'tricrypto') continue; - // unfort these two endpoints have different keys for some pools - searchKey = pool; - if (pool === 'y') { - searchKey = 'iearn'; - } else if (pool === 'susd') { - searchKey = 'susdv2'; - } else if (pool === 'ren2') { - searchKey = 'ren'; - } - - // calc virtual tvl - const virtual_price = poolStatsCrv.find( - (el) => el.pool === pool - ).virtual_price; - const tvl_usd = - poolStatsCvx.find((el) => el.pool === pool)?.tvl_usd * virtual_price; - - // fee is already deducted - const apyBase = Number(dataApy.apys[searchKey].baseApy); - - const apySum = - apyBase + currentApys.find((el) => el.pool === pool)?.aprCurrentExBase; - - poolStats.push({ - lptoken: currentApys.find((el) => el.pool === pool).lptoken, - pool, - symbol: curve.tokenMapping[pool], - apySum, - tvl_usd, - }); - } - - return poolStats; -}; - -const buildPool = (entry, chainString) => { - const newObj = { - pool: entry.lptoken, - chain: utils.formatChain(chainString), - project: 'convex-finance', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.tvl_usd, - apy: entry.apySum, - }; - return newObj; -}; - -const getCurrentApys = async () => { - const res = []; - - // calc cvx and crv token price in supplied currencies from pools.json - const uniqueCurrencies = [...new Set(pools.map((p) => p.currency))]; - const cvxPrices = {}; - const crvPrices = {}; - for (c of uniqueCurrencies) { - cvxPrices[c] = await getPrice(cvxAddress, c); - crvPrices[c] = await getPrice(crvAddress, c); - } - - for (const pool of pools) { - console.log(pool.name); - let apr = await getCurrentApy(pool.name, cvxPrices, crvPrices); - res.push({ - pool: pool.name, - aprCurrentExBase: apr, - lptoken: pool.lptoken, - }); - } - return res; -}; - -// the below is from here -// https://github.com/convex-eth/utilities/blob/main/sheetScripts/convex.gs -const getCurrentApy = async (poolName, cvxPrices, crvPrices) => { - // this is quite confusing, - // the value it returns is the total current apy excluding the base APR (as seen under the projected tab) - // so we will have to add that back - const pool = pools.find((pool) => pool.name == poolName); - const curveSwap = pool.swap; - - // get reward rate - const rate = await rewardRate(pool.crvRewards); - - // get supply - let supply = await supplyOf(pool.crvRewards); - - // get virtual price - let virtualPrice = 1; - if (pool.isV2 == undefined || pool.isV2 == false) { - virtualPrice = await curveLpValue(1, curveSwap); - } else { - virtualPrice = await curveV2LpValue(pool, pool.currency); - } - - // virtual supply - supply = supply * virtualPrice; - - // crv per underlying per second - const crvPerUnderlying = rate / supply; - - // crv per year - const crvPerYear = crvPerUnderlying * 86400 * 365; - const cvxPerYear = await getCVXMintAmount(crvPerYear); - - const cvxPrice = cvxPrices[pool.currency]; - const crvPrice = crvPrices[pool.currency]; - - let apr = crvPerYear * crvPrice; - apr += cvxPerYear * cvxPrice; - if (pool.extras != undefined && pool.extras.length > 0) { - for (const i in pool.extras) { - const ex = pool.extras[i]; - const exrate = await rewardRate(ex.contract); - const perUnderlying = exrate / supply; - const perYear = perUnderlying * 86400 * 365; - const price = await getPrice(ex.token, pool.currency); - apr += perYear * price; - } - } - - // scale to pct - apr *= 100; - - return apr; -}; - -const getCVXMintAmount = async (crvEarned) => { - // first get total supply - const cvxSupply = await supplyOf(cvxAddress); - // get current cliff - const currentCliff = cvxSupply / cliffSize; - // if current cliff is under the max - if (currentCliff < cliffCount) { - // get remaining cliffs - const remaining = cliffCount - currentCliff; - - // multiply ratio of remaining cliffs to total cliffs against amount CRV received - const cvxEarned = (crvEarned * remaining) / cliffCount; - - // double check we have not gone over the max supply - const amountTillMax = maxSupply - cvxSupply; - if (cvxEarned > amountTillMax) { - cvxEarned = amountTillMax; - } - return cvxEarned; - } - return 0; -}; - -const supplyOf = async (contract) => { - const totalSupply = '18160ddd'; - const url = - 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=' + - contract + - '&data=0x' + - totalSupply + - '&tag=latest&apikey=' + - ETHERSCAN_KEY; - const response = await superagent.get(url); - - const hexValue = response.body.result; - const decimal = Math.pow(10, 18); - const supply = parseInt(hexValue, 16) / decimal; - return supply; -}; - -const curveLpValue = async (amount, swapAddress) => { - const virtualPriceHash = 'bb7b8b80'; - - const swapurl = - 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=' + - swapAddress + - '&data=0x' + - virtualPriceHash + - '&tag=latest&apikey=' + - ETHERSCAN_KEY; - const response = await superagent(swapurl); - const data = response.body; - const hexValue = data.result.slice(0, 66); - const priceDecimal = Math.pow(10, 18); - const pricePerShare = parseInt(hexValue, 16) / priceDecimal; - - return amount * pricePerShare; -}; - -const curveV2LpValue = async (pool, currencyType) => { - // get amount of tokens - const supply = await supplyOf(pool.lptoken); - let total = 0; - for (let i = 0; i < pool.coins.length; i++) { - if (pool.cryptoPool === true) { - bal = await balances(pool.swap, i, pool.coinDecimals[i]); - } else { - bal = await balanceOf(pool.swap, pool.coins[i], pool.coinDecimals[i]); - } - const price = await getPrice(pool.coins[i], currencyType); - total += bal * price; - } - const value = total / supply; - return value; -}; - -const rewardRate = async (contract) => { - const rewardRate = '7b0a47ee'; - const url = - 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=' + - contract + - '&data=0x' + - rewardRate + - '&tag=latest&apikey=' + - ETHERSCAN_KEY; - const response = await superagent.get(url); - const data = response.body; - const hexValue = data.result; - const decimal = Math.pow(10, 18); - const rate = parseInt(hexValue, 16) / decimal; - return rate; -}; - -const balanceOf = async (address, contract, decimals) => { - const balanceOfHex = '70a08231'; - address = padHex(address); - const url = - 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=' + - contract + - '&data=0x' + - balanceOfHex + - address + - '&tag=latest&apikey=' + - ETHERSCAN_KEY; - const response = await superagent.get(url); - const data = response.body; - const balance = Number(data.result) / Math.pow(10, decimals); - - return balance; -}; - -// I had to add this cause for the newer v2 crypto pools such as -// cvxeth the swap address has weth in the coins balance -// at index 0, even though it has actual eth in there -const balances = async (contract, idx, decimals) => { - const balancesHex = '4903b0d1'; - idx = padHex(String(idx)); - const url = - 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=' + - contract + - '&data=0x' + - balancesHex + - idx + - '&tag=latest&apikey=' + - ETHERSCAN_KEY; - const response = await superagent.get(url); - const data = response.body; - const balance = Number(data.result) / Math.pow(10, decimals); - - return balance; -}; - -const getPrice = async (contract_address, vsCoin) => { - const url = - 'https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses=' + - contract_address + - '&vs_currencies=' + - vsCoin; - - const response = await superagent.get(url); - const data = response.body; - return data[contract_address.toLowerCase()][vsCoin.toLowerCase()]; -}; - -const padHex = (hexstring, intSize = 256) => { - hexstring = hexstring.replace('0x', ''); - - const length = intSize / 4 - hexstring.length; - for (let i = 0; i < length; i++) { - hexstring = '0' + hexstring; - } - return hexstring; -}; + const prices = (await utils.getPrices([cvxCRV, cvxAddress], 'ethereum')) + .pricesByAddress; + + const stakingPools = [ + { + // cvxCRV pool + crvRewards: cvxCRVRewards, + cvxTvl: stakingTvl[0] * prices[cvxCRV.toLowerCase()], + lptoken: cvxCRV, + coins: [ + { + address: crvAddress, + symbol: 'cvxCRV', + }, + ], + }, + { + // CVX pool + crvRewards: cvxRewards, + cvxTvl: stakingTvl[1] * prices[cvxAddress.toLowerCase()], + lptoken: cvxAddress, + coins: [ + { + address: cvxAddress, + symbol: 'CVX', + }, + ], + }, + ]; + withCvxTvl = [...withCvxTvl, ...stakingPools]; + + // reward rates + const rewardRates = ( + await sdk.api.abi.multiCall({ + calls: withCvxTvl.map((pool) => ({ target: pool.crvRewards })), + abi: baseRewardPoolAbi.find((x) => x.name === 'rewardRate'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const periodFinish = ( + await sdk.api.abi.multiCall({ + calls: withCvxTvl.map((pool) => ({ target: pool.crvRewards })), + abi: baseRewardPoolAbi.find((x) => x.name === 'periodFinish'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const extraRewardsLength = ( + await sdk.api.abi.multiCall({ + calls: withCvxTvl.map((pool) => ({ target: pool.crvRewards })), + abi: baseRewardPoolAbi.find((x) => x.name === 'extraRewardsLength'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const cvxSupply = + ( + await sdk.api.abi.call({ + target: cvxAddress, + abi: baseRewardPoolAbi.find((x) => x.name === 'totalSupply'), + chain: 'ethereum', + }) + ).output / 1e18; + + const poolsWithApr = await Promise.all( + withCvxTvl.map(async (pool, idx) => { + if (pool.lptoken === cvxCRV) { + return { + ...pool, + apr: (await getCvxCrvAprData()), + crvApr: 0, + extrApr: 0, + extraTokens: [crvUsdAddress], // It’ll show CRV+CVX+crvUSD as rewards + }; + } -const topLvl = async (chainString) => { - // pull data - let data = await getPoolStatsCvx(); + const isFinished = new Date() > periodFinish[idx] * 1000; + const rate = rewardRates[idx] / 10 ** 18; + + const extraRewards = []; + for (let i = 0; i < extraRewardsLength[idx]; i++) { + const extraRewardPoolAddress = ( + await sdk.api.abi.call({ + target: pool.crvRewards, + abi: baseRewardPoolAbi.find((x) => x.name === 'extraRewards'), + params: [i], + chain: 'ethereum', + }) + ).output; + const periodFinish = ( + await sdk.api.abi.call({ + target: extraRewardPoolAddress, + abi: baseRewardPoolAbi.find((x) => x.name === 'periodFinish'), + chain: 'ethereum', + }) + ).output; + const isFinished = new Date() > periodFinish * 1000; + // stETH rewards contract address + if ( + isFinished && + pool.crvRewards !== '0x0A760466E1B4621579a82a39CB56Dda2F4E70f03' + ) + continue; + const extraRewardRate = + ( + await sdk.api.abi.call({ + target: extraRewardPoolAddress, + abi: baseRewardPoolAbi.find((x) => x.name === 'rewardRate'), + chain: 'ethereum', + }) + ).output / 1e18; + const token = ( + await sdk.api.abi.call({ + target: extraRewardPoolAddress, + abi: baseRewardPoolAbi.find((x) => x.name === 'rewardToken'), + chain: 'ethereum', + }) + ).output; + if (!extraRewardsPrices[token.toLowerCase()]) { + try { + const price = ( + await utils.getData( + `https://coins.llama.fi/prices/current/ethereum:${token.toLowerCase()}` + ) + ).coins; + extraRewardsPrices[token.toLowerCase()] = + price[`ethereum:${token.toLowerCase()}`].price; + } catch { + extraRewardsPrices[token.toLowerCase()] = 0; + } + } + extraRewards.push({ extraRewardRate, token }); + } - // build pool objects - data = data.map((el) => buildPool(el, chainString)); + const extraRewardsApr = extraRewards.map((extra) => { + const usdPerYear = + Number(extra.extraRewardRate) * + Number(extraRewardsPrices[extra.token.toLowerCase()]) * + 86400 * + 365 * + 100; + const apy = usdPerYear / pool.cvxTvl; + return apy; + }); + // note(!) for CVX staking pool, the rate will be for cvxCRV not for curve + // hence why we use a different price below for `crvApr` which in that + // case is actually the cvxCRV apr for the CVX staking pool + const crvPerUnderlying = rate; + const crvPerYear = crvPerUnderlying * 86400 * 365; + let cvxPerYear; + + // get current cliff + const currentCliff = cvxSupply / cliffSize; + // if current cliff is under the max + if (currentCliff < cliffCount) { + // get remaining cliffs + let remaining = cliffCount - currentCliff; + + // multiply ratio of remaining cliffs to total cliffs against amount CRV received + let cvxEarned = (crvPerYear * remaining) / cliffCount; + + // double check we have not gone over the max supply + let amountTillMax = maxSupply - cvxSupply; + if (cvxEarned > amountTillMax) { + cvxEarned = amountTillMax; + } + cvxPerYear = cvxEarned; + } else { + cvxPerYear = 0; + } - return data; -}; + const apr = (cvxPerYear * cvxPrice * 100) / pool.cvxTvl; + const crvApr = + pool.lptoken === cvxAddress + ? (crvPerYear * prices[cvxCRV.toLowerCase()] * 100) / pool.cvxTvl + : (crvPerYear * crvPrice * 100) / pool.cvxTvl; + const extrApr = extraRewardsApr.reduce((acc, val) => acc + val, 0) || 0; + // we set 'CVX vAPR' and 'CRV vAPR' to 0 if both isFinished and tvl < THR; + // reason: sometimes even for very large pools rewards aren't streaming and require + // a harvest call. most often, for large pools the current apr (for CVX vAPR and CRV vAPR) + // thus drops to 0 because isFinished is true. for cvxTvl >= THR we use projected apr instead + // so we avoid cases where eg LDO rewards are 0 just because rewards haven't been harvested yet + return { + ...pool, + apr: isFinished && pool.cvxTvl < projectedAprTvlThr ? 0 : apr, + crvApr: isFinished && pool.cvxTvl < projectedAprTvlThr ? 0 : crvApr, + extrApr, + extraTokens: extraRewards.map(({ token }) => token), + }; + }) + ); -const main = async () => { - const data = await Promise.all([topLvl('ethereum')]); - return data.flat(); + const res = poolsWithApr + .map((pool) => { + let poolObj = poolsList.filter( + (p) => p.address?.toLowerCase() === pool.address?.toLowerCase() + ); + // for some pools (i saw it with ~5) poolsList has + // duplicated objects with exact same address but different id's. + // in that case, we remove the one with factory in the id string + poolObj = + poolObj?.length > 1 + ? poolObj.find((p) => !p.id.includes('factory')) + : poolObj[0]; + + const poolId = pool.isLendingVault ? pool.id : poolObj?.id; + const baseApy = poolId ? curveApys[poolId]?.baseApy : undefined; + + return { + pool: pool.lptoken, + chain: utils.formatChain('ethereum'), + project: 'convex-finance', + symbol: ( // Symbol of the supplied token + pool.isLendingVault ? + utils.formatSymbol(pool.assets.borrowed.symbol) : + pool.coins.map((coin) => coin.symbol).join('-') + ), + poolMeta: ( // Displayed in parens next to `symbol` + pool.isLendingVault ? + `Curve Lend – ${pool.assets.collateral.symbol} collateral` : + undefined + ), + tvlUsd: ( + pool.isLendingVault ? + pool.convexPoolData.usdTotal : + pool.cvxTvl + ), + apyBase: [cvxAddress, cvxCRV].includes(pool.lptoken) ? null : baseApy, + apyReward: + // for CVX staking only need crvApr (which is actually cvxCRV reward) + pool.lptoken === cvxAddress + ? pool.crvApr + : pool.lptoken === '0xfffAE954601cFF1195a8E20342db7EE66d56436B' + ? null + : pool.crvApr + pool.apr + pool.extrApr, + underlyingTokens: ( + pool.isLendingVault ? + [pool.assets.borrowed.address] : + pool.coins.map(({ address }) => address) + ), + rewardTokens: + pool.lptoken === cvxAddress + ? [cvxCRV] + : [ + '0xd533a949740bb3306d119cc777fa900ba034cd52', // crv + '0x4e3fbd56cd56c3e72c1403e103b45db9da5b9d2b', // cvx + ...pool.extraTokens, + ], + }; + }) + .filter((pool) => !pool.symbol.toLowerCase().includes('ust')); + + return res.filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: false, apy: main, + url: 'https://curve.convexfinance.com/stake', }; diff --git a/src/adaptors/convex-finance/pools.json b/src/adaptors/convex-finance/pools.json deleted file mode 100644 index 83196d615f..0000000000 --- a/src/adaptors/convex-finance/pools.json +++ /dev/null @@ -1,561 +0,0 @@ -[ - { - "lptoken": "0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2", - "crvRewards": "0xf34DFF761145FF0B05e917811d488B441F33a968", - "swap": "0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56", - "currency": "USD", - "name": "compound", - "id": 0 - }, - { - "lptoken": "0x9fC689CCaDa600B6DF723D9E47D84d76664a1F23", - "crvRewards": "0x8B55351ea358e5Eda371575B031ee24F462d503e", - "swap": "0x52EA46506B9CC5Ef470C5bf89f17Dc28bB35D85C", - "currency": "USD", - "name": "usdt", - "id": 1 - }, - { - "lptoken": "0xdF5e0e81Dff6FAF3A7e52BA697820c5e32D806A8", - "crvRewards": "0xd802a8351A76ED5eCd89A7502Ca615F2225A585d", - "swap": "0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51", - "currency": "USD", - "name": "y", - "id": 2 - }, - { - "lptoken": "0x3B3Ac5386837Dc563660FB6a0937DFAa5924333B", - "crvRewards": "0x602c4cD53a715D8a7cf648540FAb0d3a2d546560", - "swap": "0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27", - "currency": "USD", - "name": "busd", - "id": 3 - }, - { - "lptoken": "0xC25a3A3b969415c80451098fa907EC722572917F", - "crvRewards": "0x22eE18aca7F3Ee920D01F25dA85840D12d98E8Ca", - "swap": "0xA5407eAE9Ba41422680e2e00537571bcC53efBfD", - "currency": "USD", - "name": "susd", - "extras": [ - { - "contract": "0x81fCe3E10D12Da6c7266a1A169c4C96813435263", - "token": "0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f", - "name": "SNX" - } - ], - "id": 4 - }, - { - "lptoken": "0xD905e2eaeBe188fc92179b6350807D8bd91Db0D8", - "crvRewards": "0xe3DaafC8C14147d5B4A7a56F0BfdED240158e51e", - "swap": "0x06364f10B501e868329afBc005b3492902d6C763", - "currency": "USD", - "name": "pax", - "id": 5 - }, - { - "lptoken": "0x49849C98ae39Fff122806C06791Fa73784FB3675", - "crvRewards": "0x8E299C62EeD737a5d5a53539dF37b5356a27b07D", - "swap": "0x93054188d876f558f4a66B2EF1d97d16eDf0895B", - "currency": "BTC", - "name": "ren2", - "id": 6 - }, - { - "lptoken": "0x075b1bb99792c9E1041bA13afEf80C91a1e70fB3", - "crvRewards": "0xd727A5A6D1C7b31Ff9Db4Db4d24045B7dF0CFF93", - "swap": "0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714", - "currency": "BTC", - "name": "sbtc", - "id": 7 - }, - { - "lptoken": "0xb19059ebb43466C323583928285a49f558E572Fd", - "crvRewards": "0x618BD6cBA676a46958c63700C04318c84a7b7c0A", - "swap": "0x4CA9b3063Ec5866A4B82E437059D2C43d1be596F", - "currency": "BTC", - "name": "hbtc", - "id": 8 - }, - { - "lptoken": "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490", - "crvRewards": "0x689440f2Ff927E1f24c72F1087E1FAF471eCe1c8", - "swap": "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7", - "currency": "USD", - "name": "3pool", - "id": 9 - }, - { - "lptoken": "0xD2967f45c4f384DEEa880F807Be904762a3DeA07", - "crvRewards": "0x7A7bBf95C44b144979360C3300B54A7D34b44985", - "swap": "0x4f062658EaAF2C1ccf8C8e36D6824CDf41167956", - "currency": "USD", - "name": "gusd", - "id": 10 - }, - { - "lptoken": "0x5B5CFE992AdAC0C9D48E05854B2d91C73a003858", - "crvRewards": "0x353e489311b21355461353fEC2d02B73EF0eDe7f", - "swap": "0x3eF6A01A0f81D6046290f3e2A8c5b843e738E604", - "currency": "USD", - "name": "husd", - "id": 11 - }, - { - "lptoken": "0x97E2768e8E73511cA874545DC5Ff8067eB19B787", - "crvRewards": "0xa50e9071aCaD20b31cd2bbe4dAa816882De82BBe", - "swap": "0x3E01dD8a5E1fb3481F0F589056b428Fc308AF0Fb", - "currency": "USD", - "name": "usdk", - "id": 12 - }, - { - "lptoken": "0x4f3E8F405CF5aFC05D68142F3783bDfE13811522", - "crvRewards": "0x4a2631d090e8b40bBDe245e687BF09e5e534A239", - "swap": "0x0f9cb53Ebe405d49A0bbdBD291A65Ff571bC83e1", - "currency": "USD", - "name": "usdn", - "id": 13 - }, - { - "lptoken": "0x1AEf73d49Dedc4b1778d0706583995958Dc862e6", - "crvRewards": "0xDBFa6187C79f4fE4Cda20609E75760C5AaE88e52", - "swap": "0x8474DdbE98F5aA3179B3B3F5942D724aFcdec9f6", - "currency": "USD", - "name": "musd", - "id": 14 - }, - { - "lptoken": "0xC2Ee6b0334C261ED60C72f6054450b61B8f18E35", - "crvRewards": "0xedfCCF611D7c40F43e77a1340cE2C29EEEC27205", - "swap": "0xC18cC39da8b11dA8c3541C598eE022258F9744da", - "currency": "USD", - "name": "rsv", - "extras": [ - { - "contract": "0x94C259DC4C6dF248B0b5D23C055CB7574A587d67", - "token": "0x320623b8e4ff03373931769a31fc52a4e78b5d70", - "name": "rsr" - } - ], - "id": 15 - }, - { - "lptoken": "0x64eda51d3Ad40D56b9dFc5554E06F94e1Dd786Fd", - "crvRewards": "0x081A6672f07B615B402e7558a867C97FA080Ce35", - "swap": "0xC25099792E9349C7DD09759744ea681C7de2cb66", - "currency": "BTC", - "name": "tbtc", - "id": 16 - }, - { - "lptoken": "0x3a664Ab939FD8482048609f652f9a0B0677337B9", - "crvRewards": "0x1992b82A8cCFC8f89785129D6403b13925d6226E", - "swap": "0x8038C01A0390a8c547446a0b2c18fc9aEFEcc10c", - "currency": "USD", - "name": "dusd", - "extras": [ - { - "contract": "0x666F8eEE6FD6839853993977CC86a7A51425673C", - "token": "0x20c36f062a31865bED8a5B1e512D9a1A20AA333A", - "name": "dfd" - } - ], - "id": 17 - }, - { - "lptoken": "0xDE5331AC4B3630f94853Ff322B66407e0D6331E8", - "crvRewards": "0x2d3C90AEB11D1393CA839Afc9587515B1325D77A", - "swap": "0x7F55DDe206dbAD629C080068923b36fe9D6bDBeF", - "currency": "BTC", - "name": "pbtc", - "extras": [ - { - "contract": "0xAF138B29205c2246B069Ed8f0b213b205FBc14E0", - "token": "0x89Ab32156e46F46D02ade3FEcbe5Fc4243B9AAeD", - "name": "PNT" - } - ], - "id": 18 - }, - { - "lptoken": "0x410e3E86ef427e30B9235497143881f717d93c2A", - "crvRewards": "0x61D741045cCAA5a215cF4E5e55f20E1199B4B843", - "swap": "0x071c661B4DeefB59E2a3DdB20Db036821eeE8F4b", - "currency": "BTC", - "name": "bbtc", - "id": 19 - }, - { - "lptoken": "0x2fE94ea3d5d4a175184081439753DE15AeF9d614", - "crvRewards": "0xeeeCE77e0bc5e59c77fc408789A9A172A504bD2f", - "swap": "0xd81dA8D904b52208541Bade1bD6595D8a251F8dd", - "currency": "BTC", - "name": "obtc", - "extras": [ - { - "contract": "0xAE97D3766924526084dA88ba9B2bd7aF989Bf6fC", - "token": "0x3c9d6c1C73b31c837832c72E04D3152f051fc1A9", - "name": "BOR" - } - ], - "id": 20 - }, - { - "lptoken": "0x94e131324b6054c0D789b190b2dAC504e4361b53", - "crvRewards": "0xd4Be1911F8a0df178d6e7fF5cE39919c273E2B7B", - "swap": "0x890f4e345B1dAED0367A877a1612f86A1f86985f", - "currency": "USD", - "name": "ust", - "id": 21 - }, - { - "lptoken": "0x194eBd173F6cDacE046C53eACcE9B953F28411d1", - "crvRewards": "0xcB8F69E0064d8cdD29cbEb45A14cf771D904BcD3", - "swap": "0x0Ce6a5fF5217e38315f87032CF90686C96627CAA", - "currency": "EUR", - "name": "eurs", - "id": 22 - }, - { - "lptoken": "0xA3D87FffcE63B53E0d54fAa1cc983B7eB0b74A9c", - "crvRewards": "0x192469CadE297D6B21F418cFA8c366b63FFC9f9b", - "swap": "0xc5424B857f758E906013F3555Dad202e4bdB4567", - "currency": "ETH", - "name": "seth", - "id": 23 - }, - { - "lptoken": "0xFd2a8fA60Abd58Efe3EeE34dd494cD491dC14900", - "crvRewards": "0xE82c1eB4BC6F92f85BF7EB6421ab3b882C3F5a7B", - "swap": "0xDeBF20617708857ebe4F679508E7b7863a8A8EeE", - "currency": "USD", - "name": "aave", - "extras": [ - { - "contract": "0x00469d388b06127221D6310843A43D079eb2bB18", - "token": "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9", - "name": "stkAave" - } - ], - "id": 24 - }, - { - "lptoken": "0x06325440D014e39736583c165C2963BA99fAf14E", - "crvRewards": "0x0A760466E1B4621579a82a39CB56Dda2F4E70f03", - "swap": "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022", - "currency": "ETH", - "name": "steth", - "extras": [ - { - "contract": "0x008aEa5036b819B4FEAEd10b2190FBb3954981E8", - "token": "0x5a98fcbea516cf06857215779fd812ca3bef1b32", - "name": "LDO" - } - ], - "id": 25 - }, - { - "lptoken": "0x02d341CcB60fAaf662bC0554d13778015d1b285C", - "crvRewards": "0xF86AE6790654b70727dbE58BF1a863B270317fD0", - "swap": "0xEB16Ae0052ed37f479f7fe63849198Df1765a733", - "currency": "USD", - "name": "saave", - "extras": [ - { - "contract": "0x20165075174b51a2f9Efbf7d6D8F3c72BBc63064", - "token": "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9", - "name": "stkAave" - } - ], - "id": 26 - }, - { - "lptoken": "0xaA17A236F2bAdc98DDc0Cf999AbB47D47Fc0A6Cf", - "crvRewards": "0x8798b81b0261934aa850C8de8622472bfdc143F4", - "swap": "0xA96A65c051bF88B4095Ee1f2451C2A9d43F53Ae2", - "currency": "ETH", - "name": "ankreth", - "extras": [ - { - "contract": "0x177252Ac74f1D77513971aA85AF7009C43EcdEe2", - "token": "0xe0ad1806fd3e7edf6ff52fdb822432e847411033", - "name": "onx" - }, - { - "contract": "0xc095Cec98a9f8Ad6D2baA282A8e6bE246f98BD25", - "token": "0x8290333cef9e6d528dd5618fb97a76f268f3edd4", - "name": "ankr" - } - ], - "id": 27 - }, - { - "lptoken": "0x7Eb40E450b9655f4B3cC4259BCC731c63ff55ae6", - "crvRewards": "0x24DfFd1949F888F91A0c8341Fc98a3F280a782a8", - "swap": "0x42d7025938bEc20B69cBae5A77421082407f053A", - "currency": "USD", - "name": "usdp", - "id": 28 - }, - { - "lptoken": "0x5282a4eF67D9C33135340fB3289cc1711c13638C", - "crvRewards": "0x3E03fFF82F77073cc590b656D42FceB12E4910A8", - "swap": "0x2dded6Da1BF5DBdF597C45fcFaa3194e53EcfeAF", - "currency": "USD", - "name": "ib", - "id": 29 - }, - { - "lptoken": "0xcee60cFa923170e4f8204AE08B4fA6A3F5656F3a", - "crvRewards": "0x9700152175dc22E7d1f3245fE3c1D2cfa3602548", - "swap": "0xF178C0b5Bb7e7aBF4e12A4838C7b7c5bA2C623c0", - "currency": "LINK", - "name": "link", - "id": 30 - }, - { - "lptoken": "0xEcd5e75AFb02eFa118AF914515D6521aaBd189F1", - "crvRewards": "0x308b48F037AAa75406426dACFACA864ebd88eDbA", - "swap": "0xEcd5e75AFb02eFa118AF914515D6521aaBd189F1", - "currency": "USD", - "name": "tusd", - "id": 31 - }, - { - "lptoken": "0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B", - "crvRewards": "0xB900EF131301B307dB5eFcbed9DBb50A3e209B2e", - "swap": "0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B", - "currency": "USD", - "name": "frax", - "extras": [ - { - "contract": "0xcDEC6714eB482f28f4889A0c122868450CDBF0b0", - "token": "0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0", - "name": "FXS" - } - ], - "id": 32 - }, - { - "lptoken": "0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA", - "crvRewards": "0x2ad92A7aE036a038ff02B96c88de868ddf3f8190", - "swap": "0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA", - "currency": "USD", - "extras": [ - { - "contract": "0x55d59b791f06dc519B176791c4E037E8Cf2f6361", - "token": "0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D", - "name": "LQTY" - } - ], - "name": "lusd", - "id": 33 - }, - { - "lptoken": "0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a", - "crvRewards": "0xbD223812d360C9587921292D0644D18aDb6a2ad0", - "swap": "0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a", - "currency": "USD", - "name": "busdv2", - "id": 34 - }, - { - "lptoken": "0x53a901d48795C58f485cBB38df08FA96a24669D5", - "crvRewards": "0x61dB6c2321f784c8fAb8d5eF80f58F27C831dCc8", - "swap": "0xF9440930043eb3997fc70e1339dBb11F341de7A8", - "currency": "ETH", - "extras": [ - { - "contract": "0x681A790debE586A64eea055BF0983CD6629d8359", - "token": "0xef3A930e1FfFFAcd2fc13434aC81bD278B0ecC8d", - "name": "FIS" - } - ], - "name": "reth", - "id": 35 - }, - { - "lptoken": "0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c", - "crvRewards": "0x02E2151D4F351881017ABdF2DD2b51150841d5B3", - "swap": "0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c", - "currency": "USD", - "extras": [ - { - "contract": "0xd731495bb78a4250bC094686788F3fF890dEe0f4", - "token": "0xdbdb4d16eda451d0503b854cf79d55697f90c8df", - "name": "ALCX" - } - ], - "name": "alusd", - "id": 36 - }, - { - "lptoken": "0xcA3d75aC011BF5aD07a98d02f18225F9bD9A6BDF", - "crvRewards": "0x5Edced358e6C0B435D53CC30fbE6f5f0833F404F", - "swap": "0x80466c64868E1ab14a1Ddf27A676C3fcBE638Fe5", - "currency": "USD", - "name": "tricrypto", - "isV2": true, - "coins": [ - "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - ], - "coinDecimals": [6, 8, 18], - "id": 37 - }, - { - "lptoken": "0xc4AD29ba4B3c580e6D59105FFf484999997675Ff", - "crvRewards": "0x9D5C5E364D81DaB193b72db9E9BE9D8ee669B652", - "swap": "0xD51a44d3FaE010294C616388b506AcdA1bfAAE46", - "currency": "USD", - "name": "tricrypto2", - "isV2": true, - "coins": [ - "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - ], - "coinDecimals": [6, 8, 18], - "id": 38 - }, - { - "lptoken": "0x5a6A4D54456819380173272A5E8E9B9904BdF41B", - "crvRewards": "0xFd5AbF66b003881b88567EB9Ed9c651F14Dc4771", - "swap": "0x5a6A4D54456819380173272A5E8E9B9904BdF41B", - "currency": "USD", - "name": "mim", - "coins": [ - "0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3", - "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490" - ], - "coinDecimals": [18, 18], - "id": 40 - }, - { - "lptoken": "0xFD5dB7463a3aB53fD211b4af195c5BCCC1A03890", - "crvRewards": "0xD814BFC091111E1417a669672144aFFAA081c3CE", - "swap": "0xFD5dB7463a3aB53fD211b4af195c5BCCC1A03890", - "currency": "EUR", - "name": "eurt", - "coins": [ - "0xd71ecff9342a5ced620049e616c5035f1db98620", - "0xC581b735A1688071A1746c968e0798D642EDE491" - ], - "coinDecimals": [18, 6], - "isV2": false, - "id": 39 - }, - { - "lptoken": "0x3b6831c0077a1e44ED0a21841C3bC4dC11bCE833", - "crvRewards": "0xD2B756Af4E345A8657C0656C148aDCD3000C97A4", - "swap": "0x9838eCcC42659FA8AA7daF2aD134b53984c9427b", - "currency": "USD", - "name": "eurtusd", - "coins": [ - "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490", - "0xC581b735A1688071A1746c968e0798D642EDE491" - ], - "coinDecimals": [18, 6], - "isV2": true, - "id": 55 - }, - { - "lptoken": "0x3D229E1B4faab62F621eF2F6A610961f7BD7b23B", - "crvRewards": "0xb0c1B7b83Baae51284B8BbBa02Ec37742440199d", - "swap": "0x98a7F18d4E56Cfe84E3D081B40001B3d5bD3eB8B", - "currency": "USD", - "name": "eursusd", - "coins": [ - "0xdb25f211ab05b1c97d595516f45794528a807ad8", - "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" - ], - "coinDecimals": [2, 6], - "isV2": true, - "id": 54 - }, - { - "lptoken": "0xEd4064f376cB8d68F770FB1Ff088a3d0F3FF5c4d", - "crvRewards": "0x085A2054c51eA5c91dbF7f90d65e728c0f2A270f", - "swap": "0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511", - "currency": "USD", - "name": "crveth", - "isV2": true, - "coins": [ - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "0xD533a949740bb3306d119CC777fa900bA034cd52" - ], - "coinDecimals": [18, 18], - "id": 61, - "cryptoPool": true - }, - { - "lptoken": "0x6BA5b4e438FA0aAf7C1bD179285aF65d13bD3D90", - "crvRewards": "0x29B91c6CEC4F43aFdb6f6d71FAf1C03d6b712f55", - "swap": "0x618788357D0EBd8A37e763ADab3bc575D54c2C7d", - "currency": "USD", - "name": "rai", - "id": 63 - }, - { - "lptoken": "0x3A283D9c08E8b55966afb64C515f5143cf907611", - "crvRewards": "0xb1Fb0BA0676A1fFA83882c7F4805408bA232C1fA", - "swap": "0xB576491F1E6e5E62f1d8F26062Ee822B40B0E0d4", - "currency": "USD", - "name": "cvxeth", - "coins": [ - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B" - ], - "coinDecimals": [18, 18], - "isV2": true, - "id": 64, - "cryptoPool": true - }, - { - "lptoken": "0x8484673cA7BfF40F82B041916881aeA15ee84834", - "crvRewards": "0x6cb1933E49C48AE8ec12d39aD7D85695b247deDB", - "swap": "0xAdCFcf9894335dC340f6Cd182aFA45999F45Fc44", - "currency": "USD", - "name": "xautusd", - "coins": [ - "0x68749665FF8D2d112Fa859AA293F07A622782F38", - "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490" - ], - "coinDecimals": [6, 18], - "isV2": true, - "id": 65 - }, - { - "lptoken": "0x8282BD15dcA2EA2bDf24163E8f2781B30C43A2ef", - "crvRewards": "0xb2f0bB6352417c1Bf017862aC165E67623611aF3", - "swap": "0x98638FAcf9a3865cd033F36548713183f6996122", - "currency": "USD", - "name": "spelleth", - "coins": [ - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "0x090185f2135308BaD17527004364eBcC2D37e5F6" - ], - "coinDecimals": [18, 18], - "isV2": true, - "id": 66, - "cryptoPool": true - }, - { - "lptoken": "0xCb08717451aaE9EF950a2524E33B6DCaBA60147B", - "crvRewards": "0x3E91E7c822AC8b4b7905d108c3faCF22A3ee5d2c", - "swap": "0x752eBeb79963cf0732E9c0fec72a49FD1DEfAEAC", - "currency": "USD", - "name": "teth", - "coins": [ - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - "0xCdF7028ceAB81fA0C6971208e83fa7872994beE5" - ], - "coinDecimals": [18, 18], - "isV2": true, - "id": 67, - "cryptoPool": true - } -] diff --git a/src/adaptors/convex-finance/virtualBalanceRewardPoolAbi.json b/src/adaptors/convex-finance/virtualBalanceRewardPoolAbi.json new file mode 100644 index 0000000000..86e0820979 --- /dev/null +++ b/src/adaptors/convex-finance/virtualBalanceRewardPoolAbi.json @@ -0,0 +1,276 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "deposit_", "type": "address" }, + { "internalType": "address", "name": "reward_", "type": "address" }, + { "internalType": "address", "name": "op_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposits", + "outputs": [ + { "internalType": "contract IDeposit", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "donate", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "historicalRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newRewardRatio", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_rewards", "type": "uint256" } + ], + "name": "queueNewRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "queuedRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/corepound/index.js b/src/adaptors/corepound/index.js new file mode 100644 index 0000000000..32d3e2684c --- /dev/null +++ b/src/adaptors/corepound/index.js @@ -0,0 +1,98 @@ +const { api } = require('@defillama/sdk'); +const utils = require('../utils'); +const { ethers } = require('ethers'); + +const FARM_INFO_ADDRESS = '0xbF0E495DDC51B9f25D1Dc14643831Ee249017507'; +const CHAIN = 'CORE'; + +async function apy() { + let { output: farmAddresses } = await api.abi.call({ + target: FARM_INFO_ADDRESS, + abi: abiInfo.getAllFarmAddress, + chain: CHAIN, + }); + + let { output: poolTvlsOut } = await api.abi.multiCall({ + calls: farmAddresses.map((address) => ({ target: address })), + abi: abiInfo.getTotalTvl, + chain: CHAIN, + }); + let tvlMap = poolTvlsOut.reduce(function (prevData, poolTvls) { + prevData[poolTvls.input.target] = poolTvls.output; + return prevData; + }, {}); + + let { output: poolInfos } = await api.abi.call({ + target: FARM_INFO_ADDRESS, + abi: abiInfo.getPoolInfos, + chain: CHAIN, + }); + + let priceInfo = poolInfos + .map((pool) => { + return `${CHAIN}:${pool.asset}`; + }) + .join(','); + + let { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceInfo}` + ); + + let { tokenPrices } = await utils.getData( + 'https://corepound.xyz/farmData.json' + ); + let rewardPrice = tokenPrices['CORP']; + + let apyInfos = poolInfos + .map((poolInfo) => { + if (tvlMap[poolInfo.farmAddress] === undefined) { + return undefined; + } + let target = tvlMap[poolInfo.farmAddress].find( + (item) => item.pid === poolInfo.pid + ); + + if ( + target === undefined || + coins[`${CHAIN}:${poolInfo.asset}`] === undefined + ) { + return undefined; + } + + let tvl = target.tvl / Math.pow(10, poolInfo.decimals); + let apy = + tvl === 0 + ? 0 + : ((rewardPrice * poolInfo.rewardAmount * 365) / + (tvl * coins[`${CHAIN}:${poolInfo.asset}`].price)) * + 100; + + return { + chain: CHAIN, + pool: poolInfo.farmAddress, + symbol: poolInfo.symbol, + underlyingTokens: [poolInfo.asset], + tvlUsd: tvl * coins[`${CHAIN}:${poolInfo.asset}`].price, + apyBase: apy, + url: `https://corepound.xyz/vault`, + project: 'corepound', + }; + }) + .filter((item) => item !== undefined && item.tvlUsd >= 10000); + + return utils.removeDuplicates(apyInfos); +} + +let abiInfo = { + getAllFarmAddress: 'function getAllFarmAddresses() view returns(address[])', + getTotalTvl: + 'function getTotalTvl() view returns (tuple(uint256 pid, address assets, uint256 tvl)[])', + getPoolInfos: + 'function getAllPoolInfo() view returns (tuple(uint256 pid, address farmAddress, address asset, uint8 decimals, string symbol, uint256 rewardAmount)[])', + slot0: + 'function slot0() external view returns (uint160 sqrtPriceX96,int24 tick,uint16 observationIndex,uint16 observationCardinality,uint16 observationCardinalityNext,uint8 feeProtocol,bool unlocked)', +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/cove-boosties/index.js b/src/adaptors/cove-boosties/index.js new file mode 100644 index 0000000000..8203310026 --- /dev/null +++ b/src/adaptors/cove-boosties/index.js @@ -0,0 +1,127 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const chains = { + Ethereum: 1, +}; + +const getAssetSymbolAbi = + 'function symbol() public view returns (string memory)'; +const getAssetTotalSupplyAbi = + 'function totalSupply() public view returns (uint256)'; + +const getApy = async () => { + const data = await Promise.all( + Object.entries(chains).map(async (chain) => { + // instantiate the sdk api for the chain + const api = new sdk.ChainApi({ chain: chain[0].toLowerCase() }); + // Get yearn vaults data + const yearnVaults = await utils.getData( + `https://boosties.cove.finance/api/v1/yearn-vaults?chainId=${chain[1]}` + ); + + // Get Cove's boosties data + const boostiesData = await utils.getData( + `https://boosties.cove.finance/api/v1/cove-vaults` + ); + const boostiesVaults = boostiesData.vaults; + + // Create a map of yearn vaults by address for easy lookup + const yearnVaultsMap = {}; + yearnVaults.forEach((vault) => { + yearnVaultsMap[vault.address.toLowerCase()] = vault; + }); + + // Fetch asset symbols for all boosties vaults + const assetSymbols = await api.multiCall({ + abi: getAssetSymbolAbi, + calls: boostiesVaults.map((vault) => ({ + target: vault.coveYearnStrategy, + })), + }); + + // Enrich boosties vaults with their strategy symbols + boostiesVaults.forEach((vault, i) => { + vault.coveYearnStrategySymbol = assetSymbols[i]; + }); + + // Fetch the total supply of each coveYearnStrategy + const coveYearnStrategyTotalSupply = await api.multiCall({ + abi: getAssetTotalSupplyAbi, + calls: boostiesVaults.map((vault) => ({ + target: vault.coveYearnStrategy, + })), + }); + + // Multiply by the vault.coveYearnStrategyPricePerShare and divide by 1e18 + // Multiply by the underlying asset price, which is tvl.price of matching yearn vault + const coveYearnStrategyTVL = coveYearnStrategyTotalSupply.map( + (totalSupply, i) => { + return parseFloat( + Number( + (((totalSupply * + boostiesVaults[i].coveYearnStrategyPricePerShare) / + 1e18) * + yearnVaultsMap[boostiesVaults[i].yearnVault.toLowerCase()].tvl + .price) / + 1e18 + ).toFixed(2) + ); + } + ); + + // Enrich boosties vaults with their coveYearnStrategyTVL + boostiesVaults.forEach((vault, i) => { + vault.coveYearnStrategyTVL = coveYearnStrategyTVL[i]; + }); + + return boostiesVaults + .filter((boostie) => { + // Find matching yearn vault + const yearnVault = yearnVaultsMap[boostie.yearnVault.toLowerCase()]; + + // Skip if no matching yearn vault found + if (!yearnVault) return false; + + // Skip retired vaults + if (yearnVault.info?.isRetired) return false; + + // Only include vaults with TVL > 0 + if (!yearnVault.tvl?.tvl || yearnVault.tvl.tvl <= 0) return false; + + return true; + }) + .map((boostie) => { + // Get the matching yearn vault + const yearnVault = yearnVaultsMap[boostie.yearnVault.toLowerCase()]; + + // Multiply coveYearnStrategy1DayAPR by yearnVault.apr.netAPR to get the net base APY for + // the boosties vault + const apyBase = + (boostie.coveYearnStrategy1DayAPR + 100) * + (((yearnVault.apr.netAPR + 1) * 100) / 100) - + 100; + + return { + pool: `${boostie.coveYearnStrategy}-${chain[0]}`.toLowerCase(), + chain: chain[0], + project: 'cove-boosties', + symbol: boostie.coveYearnStrategySymbol, + tvlUsd: boostie.coveYearnStrategyTVL, + apyBase, + apyReward: null, + rewardTokens: [], + url: `https://boosties.cove.finance/boosties`, + underlyingTokens: [boostie.vaultAsset], + }; + }); + }) + ); + + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/cove-protocol/index.js b/src/adaptors/cove-protocol/index.js new file mode 100644 index 0000000000..a6fa985c5b --- /dev/null +++ b/src/adaptors/cove-protocol/index.js @@ -0,0 +1,106 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const API_URL = 'https://app.cove.finance/api/v1/apys?chainId=1'; +const basketManager = '0x716c39658Ba56Ce34bdeCDC1426e8768E61912f8'; +const basketTokensAbi = 'function basketTokens() view returns (address[])'; +const assetAbi = 'function asset() view returns (address)'; + +const getApy = async () => { + try { + // Fetch basket tokens from on-chain + const basketTokensCall = await sdk.api.abi.call({ + target: basketManager, + abi: basketTokensAbi, + chain: 'ethereum', + }); + + const basketTokens = basketTokensCall.output; + + // Fetch APY data from Cove API + const res = await fetch(API_URL); + const apiResponse = await res.json(); + const apyData = apiResponse.data; + + // Get totalSupply for all basket tokens + const totalSupplyCalls = await sdk.api.abi.multiCall({ + calls: basketTokens.map((token) => ({ + target: token, + })), + abi: 'erc20:totalSupply', + chain: 'ethereum', + }); + + // Get decimals for all basket tokens + const decimalsCalls = await sdk.api.abi.multiCall({ + calls: basketTokens.map((token) => ({ + target: token, + })), + abi: 'erc20:decimals', + chain: 'ethereum', + }); + + const assetCalls = await sdk.api.abi.multiCall({ + calls: basketTokens.map((token) => ({ + target: token, + })), + abi: assetAbi, + chain: 'ethereum', + }); + + const pools = []; + + for (let i = 0; i < basketTokens.length; i++) { + const tokenAddress = basketTokens[i]; + const tokenData = apyData[basketTokens[i]]; + + if (!tokenData) { + console.log(`No APY data found for basket token: ${basketTokens[i]}`); + continue; + } + + const totalSupply = totalSupplyCalls.output[i].output; + const decimals = decimalsCalls.output[i].output; + const asset = assetCalls.output[i].output; + + if (!totalSupply || !decimals) { + console.log( + `Missing supply/decimals data for token: ${basketTokens[i]}`, + ); + continue; + } + + // Calculate TVL + const totalSupplyFormatted = + Number(totalSupply) / Math.pow(10, Number(decimals)); + const price = parseFloat(tokenData.price); + const tvlUsd = totalSupplyFormatted * price; + + // Use 24h USDC APY + const apyBase = tokenData['24h'] ? parseFloat(tokenData['24h'].usdcApy) : 0; + + const pool = { + pool: `${tokenAddress}-ethereum`.toLowerCase(), + chain: 'Ethereum', + project: 'cove-protocol', + symbol: tokenData.symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + url: `https://app.cove.finance/vaults/${tokenAddress.toLowerCase()}`, + underlyingTokens: [asset], + }; + + pools.push(pool); + } + + return pools.filter((p) => utils.keepFinite(p) && p.tvlUsd > 0); + } catch (error) { + console.error('Error fetching Cove data:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/covo-v1/abis/abi.json b/src/adaptors/covo-v1/abis/abi.json new file mode 100644 index 0000000000..a142fe5f3d --- /dev/null +++ b/src/adaptors/covo-v1/abis/abi.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/covo-v1/index.js b/src/adaptors/covo-v1/index.js new file mode 100644 index 0000000000..3d27611bbf --- /dev/null +++ b/src/adaptors/covo-v1/index.js @@ -0,0 +1,303 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js'); + +const baseUrl = sdk.graph.modifyEndpoint('FLWnk6nG7NDSTJWEh7UE2FBiYpUT6sspurmLzacNkGYr'); + +const arbitrumGmxAddress = '0x681D3e1b54B3E1a338feB5B076cebf53a697d51F'; +const arbitrumGlpManagerAddress = '0x8d5398E5f97554334DDdc8ec4b9855652c887802'; +const arbitrumFeeGmxTrackerAddress = + '0x93bCfA19C135685b8029F85110Be38c1F8652dF1'; +const arbitrumInflationGmxTrackerAddress = + '0x8D084d359aEC7e9C810E4Ce3fe5434750a230FD1'; +const arbitrumFeeGlpTrackerAddress = + '0x16240E94B7F4A34aDc5e8407fb34d72530eE6c4A'; +const arbitrumInflationGlpTrackerAddress = + '0xffCC76DeE7221E1a19421920e1fc3B5eAd4C23a0'; + +const avalacheGmxAddress = '0x62edc0692BD897D2295872a9FFCac5425011c661'; +const avalancheGlpManagerAddress = '0xe1ae4d4b06A5Fe1fc288f6B4CD72f9F8323B107F'; +const avalancheFeeGmxTrackerAddress = + '0x4d268a7d4C16ceB5a606c173Bd974984343fea13'; +const avalancheInflationGmxTrackerAddress = + '0x2bD10f8E93B3669b6d42E74eEedC65dd1B0a1342'; +const avalancheFeeGlpTrackerAddress = + '0xd2D1162512F927a7e282Ef43a362659E4F2a728F'; +const avalancheInflationGlpTrackerAddress = + '0x9e295B5B976a184B14aD8cd72413aD846C299660'; + +const secondsPerYear = 31536000; + +async function getAdjustedAmount(pTarget, pChain, pAbi, pParams = []) { + let decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: pChain, + }); + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * secondsPerYear + : supply.output * 10 ** -decimals.output; +} + +async function getGlpTvl(pChain) { + let tvl = await sdk.api.abi.call({ + target: + pChain == 'polygon' + ? arbitrumGlpManagerAddress + : avalancheGlpManagerAddress, + abi: abi['getAumInUsdg'], + chain: pChain, + params: [false], + }); + + return tvl.output * 10 ** -18; +} + +async function getPoolGmx( + pChain, + pInflationTrackerAddress, + pStakedGmx, + pStakedEsGmx, + pFeeGmx, + pInflationGmx, + pPriceData +) { + const gmxPrice = pPriceData['coingecko:gmx'].price; + const tvlGmx = + gmxPrice * + (await getAdjustedAmount( + pChain == 'polygon' ? arbitrumGmxAddress : avalacheGmxAddress, + pChain, + 'erc20:balanceOf', + pChain == 'polygon' + ? [arbitrumInflationGmxTrackerAddress] + : [avalancheInflationGmxTrackerAddress] + )); + const tvsGmx = pStakedGmx * gmxPrice; + const tvsEsGmx = pStakedEsGmx * gmxPrice; + const yearlyFeeGmx = + pChain == 'polygon' + ? pFeeGmx * pPriceData['coingecko:wmatic'].price + : pFeeGmx * pPriceData['coingecko:avalanche-2'].price; + const yearlyInflationGmx = pInflationGmx * gmxPrice; + const apyFee = (yearlyFeeGmx / tvsGmx) * 100; + const apyInflation = (yearlyInflationGmx / tvsEsGmx) * 100; + const chainString = pChain === 'avax' ? 'avalanche' : pChain; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(chainString), + project: 'covo-v1', + symbol: utils.formatSymbol('COVO'), + tvlUsd: tvlGmx, + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + chainString === 'polygon' ? [arbitrumGmxAddress] : [avalacheGmxAddress], + underlyingTokens: [ + chainString === 'polygon' ? arbitrumGmxAddress : avalacheGmxAddress, + ], + }; +} + +async function getPoolGlp( + pChain, + pTvl, + pInflationTrackerAddress, + pFeeGlp, + pInflationGlp, + pPriceData +) { + const yearlyFeeGlp = + pChain == 'polygon' + ? pFeeGlp * pPriceData['coingecko:wmatic'].price + : pFeeGlp * pPriceData['coingecko:avalanche-2'].price; + const yearlyInflationGlp = pInflationGlp * pPriceData['coingecko:gmx'].price; + const apyFee = (yearlyFeeGlp / pTvl) * 100; + const apyInflation = (yearlyInflationGlp / pTvl) * 100; + const chainString = pChain === 'avax' ? 'avalanche' : pChain; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(chainString), + project: 'covo-v1', + symbol: utils.formatSymbol('COVOLP'), + tvlUsd: parseFloat(pTvl), + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + chainString === 'polygon' ? [arbitrumGmxAddress] : [avalacheGmxAddress], + + underlyingTokens: [ + chainString === 'polygon' ? arbitrumGmxAddress : avalacheGmxAddress, + ], + underlyingTokens: [ + chainString === 'polygon' + ? '0x4277f8F2c384827B5273592FF7CeBd9f2C1ac258' + : '0x01234181085565ed162a948b6a5e88758CD7c7b8', + ], + }; +} + +const query = gql` + { + uniswapPrice(id: "0x681D3e1b54B3E1a338feB5B076cebf53a697d51F") { + token + value + timestamp + } + } +`; +function divideStrings(dividend, divisor) { + let quotient = ''; + let remainder = ''; + let idx = 0; + + while (idx < dividend.length) { + let currentDigit = Number(dividend[idx]); + remainder = remainder.concat(currentDigit.toString()); + while (remainder.length > 1 && remainder[0] === '0') { + remainder = remainder.slice(1); + } + if (Number(remainder) < Number(divisor)) { + quotient = quotient.concat('0'); + } else { + let count = 0; + while (Number(remainder) >= Number(divisor)) { + remainder = (Number(remainder) - Number(divisor)).toString(); + count++; + } + quotient = quotient.concat(count.toString()); + } + idx++; + } + + while (quotient.length > 1 && quotient[0] === '0') { + quotient = quotient.slice(1); + } + + return quotient; +} + +const getPools = async () => { + let pools = []; + + const priceKeys = ['gmx', 'wmatic', 'avalanche-2'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + let queryC = query; + let covographprice = await request(baseUrl, queryC); + covographprice = new BigNumber(covographprice.uniswapPrice.value); + decimal = new BigNumber(1000000000000000000000000000000); + + const covopricedecstring = covographprice.dividedBy(decimal); + + const covoprice = parseFloat(covopricedecstring.toString()); + priceData['coingecko:gmx'].price = covoprice; + + const arbitrumStakedGmx = await getAdjustedAmount( + arbitrumFeeGmxTrackerAddress, + 'polygon', + 'erc20:totalSupply' + ); + const arbitrumStakedEsGmx = await getAdjustedAmount( + arbitrumInflationGmxTrackerAddress, + 'polygon', + 'erc20:totalSupply' + ); + const arbitrumFeeGmx = await getAdjustedAmount( + arbitrumFeeGmxTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + const arbitrumInflationGmx = await getAdjustedAmount( + arbitrumInflationGmxTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolGmx( + 'polygon', + arbitrumInflationGmxTrackerAddress, + arbitrumStakedGmx, + arbitrumStakedEsGmx, + arbitrumFeeGmx, + arbitrumInflationGmx, + priceData + ) + ); + + const arbitrumFeeGlp = await getAdjustedAmount( + arbitrumFeeGlpTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + const arbitrumInflationGlp = await getAdjustedAmount( + arbitrumInflationGlpTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolGlp( + 'polygon', + await getGlpTvl('polygon'), + arbitrumInflationGlpTrackerAddress, + arbitrumFeeGlp, + arbitrumInflationGlp, + priceData + ) + ); + + const avalancheStakedGmx = await getAdjustedAmount( + avalancheFeeGmxTrackerAddress, + 'avax', + 'erc20:totalSupply' + ); + const avalancheStakedEsGmx = await getAdjustedAmount( + avalancheInflationGmxTrackerAddress, + 'avax', + 'erc20:totalSupply' + ); + const avalancheFeeGmx = await getAdjustedAmount( + avalancheFeeGmxTrackerAddress, + 'avax', + abi['tokensPerInterval'] + ); + const avalancheInflationGmx = await getAdjustedAmount( + avalancheInflationGmxTrackerAddress, + 'avax', + abi['tokensPerInterval'] + ); + + const avalancheFeeGlp = await getAdjustedAmount( + avalancheFeeGlpTrackerAddress, + 'avax', + abi['tokensPerInterval'] + ); + const avalancheInflationGlp = await getAdjustedAmount( + avalancheInflationGlpTrackerAddress, + 'avax', + abi['tokensPerInterval'] + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.covo.finance/#/earn', +}; diff --git a/src/adaptors/covo-v2/abis/abi.json b/src/adaptors/covo-v2/abis/abi.json new file mode 100644 index 0000000000..f232253971 --- /dev/null +++ b/src/adaptors/covo-v2/abis/abi.json @@ -0,0 +1,104 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getRewardPerTokenSum": { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardPerTokenSum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getPendingReward": { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPendingReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getBalance": { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getTotalSupply": { + "inputs": [], + "name": "getTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/covo-v2/index.js b/src/adaptors/covo-v2/index.js new file mode 100644 index 0000000000..df6b5e6f1a --- /dev/null +++ b/src/adaptors/covo-v2/index.js @@ -0,0 +1,236 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js'); + +const baseUrl = sdk.graph.modifyEndpoint('FLWnk6nG7NDSTJWEh7UE2FBiYpUT6sspurmLzacNkGYr'); + +const covoaddress = '0x681D3e1b54B3E1a338feB5B076cebf53a697d51F'; +const stakingstore = '0x8aBeAA1578024B85084A09Ca2fa46f0a0dfE9c0F'; +const poolstore = '0x4c3028bdddbf20D2482f34b7E4151337eAAE45B5'; +const covorewardsdistributor = '0x5E0Ca4ED0c910c81315D180F334406140C99295C'; + +const usdcaddress = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'; + +const polygonusdcstakingtracker = '0xED29cB1b164dd7EA1c5065E79a15dA31EC34327B'; + +const polygoncovostakingtracker = '0x569629f42c79752436dba855ba7eb577a56e478c'; + +const secondsPerYear = 31536000; + +async function getAdjustedAmountusdc(pTarget, pChain, pAbi, pParams = []) { + const decimals = 10 ** 6; + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + }); + return supply.output; +} + +async function getAdjustedAmountcovo(pTarget, pChain, pAbi, pParams = []) { + let decimals = 10 ** 18; + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] ? supply.output : supply.output; +} + +async function getPoolCovo( + pChain, + pInflationTrackerAddress, + pPriceData, + stakedCovoclaimedUSDC, + stakedCovoPendingUSDC, + PolygonStakedCovo, + RewardsdistributorCovo +) { + let stakedCovoclaimedUSDC1 = parseFloat(stakedCovoclaimedUSDC); + let stakedCovoPendingUSDC2 = parseFloat(stakedCovoPendingUSDC); + let RewardsdistributorCovo1 = new BigNumber(RewardsdistributorCovo); + let decimal3 = new BigNumber(1000000000000000000); + + const RewardsdistributorCovo2 = parseFloat( + RewardsdistributorCovo1.dividedBy(decimal3) + ); + + let PolygonStakedCovo1 = new BigNumber(PolygonStakedCovo); + + const PolygonStakedCovo2 = parseFloat(PolygonStakedCovo1.dividedBy(decimal3)); + + const totalRewardsInUSDC = + (stakedCovoclaimedUSDC1 + stakedCovoPendingUSDC2) / 100000; + + const tvlstakedcovo = pPriceData.gmx.usd * PolygonStakedCovo2; + + const apy = calculateApy(totalRewardsInUSDC, tvlstakedcovo); + + const yearlyInflationcovo = + RewardsdistributorCovo2 * secondsPerYear * pPriceData.gmx.usd; + + const apycovoInflation = (yearlyInflationcovo / tvlstakedcovo) * 100; + + const chainString = pChain === 'avax' ? 'avalanche' : pChain; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(chainString), + project: 'covo-v2', + symbol: utils.formatSymbol('COVO'), + tvlUsd: tvlstakedcovo, + apyBase: apy, + apyReward: apycovoInflation, + rewardTokens: [usdcaddress, covoaddress], + underlyingTokens: [covoaddress], + }; +} + +function calculateApy(totalRewardsInUSDC, tvlcovo, daysInYear = 365) { + const currentDateTimestamp = Date.now(); + const V2deploytimestamp = 1680052706000; + const timeDiffInMilliseconds = currentDateTimestamp - V2deploytimestamp; + const rewardDays = timeDiffInMilliseconds / (1000 * 60 * 60 * 24); + + const dailyYield = totalRewardsInUSDC / rewardDays; + const dailyYieldRate = dailyYield / tvlcovo; + const annualYieldRate = (1 + dailyYieldRate) ** daysInYear - 1; + return annualYieldRate * 100; +} + +async function getPoolUsdc( + pChain, + pTvl, + pInflationTrackerAddress, + pPriceData, + stakedCovoclaimedUSDC, + stakedCovoPendingUSDC, + PolygonUSDCPoolBalance +) { + let stakedCovoclaimedUSDC1 = parseFloat(stakedCovoclaimedUSDC); + let stakedCovoPendingUSDC2 = parseFloat(stakedCovoPendingUSDC); + let PolygonUSDCPoolBalance2 = parseFloat(PolygonUSDCPoolBalance); + + const totalRewardsInUSDC = + (stakedCovoclaimedUSDC1 + stakedCovoPendingUSDC2) / 1000000; + console.log({ totalRewardsInUSDC2: totalRewardsInUSDC }); + const tvlcovo = PolygonUSDCPoolBalance2 / 10 ** 6; + console.log({ tvlcovo2: tvlcovo }); + const apy = calculateApy(totalRewardsInUSDC, tvlcovo); + console.log({ apy2: apy }); + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project: 'covo-v2', + symbol: utils.formatSymbol('USDC'), + tvlUsd: tvlcovo, + apyBase: apy, + apyReward: 0, + rewardTokens: (chainString = [usdcaddress]), + underlyingTokens: [usdcaddress], + }; +} + +const getDayTimestamp = () => { + const date = new Date(); + date.setHours(0, 0, 0, 0); + return Math.floor(date.getTime() / 1000); +}; + +const dayTimestamp = getDayTimestamp(); + +const query = gql` + { + uniswapPrice(id: "0x681D3e1b54B3E1a338feB5B076cebf53a697d51F") { + token + value + timestamp + } + } +`; + +const getPools = async () => { + let pools = []; + + const priceData = await utils.getData( + 'https://api.coingecko.com/api/v3/simple/price?ids=gmx%2Cwmatic%2Cavalanche-2&vs_currencies=usd' + ); + + let queryC = query; + let covographprice = await request(baseUrl, queryC); + covographprice = new BigNumber(covographprice.uniswapPrice.value); + let decimal = new BigNumber(1000000000000000000000000000000); + + const covopricedecstring = covographprice.dividedBy(decimal); + + const covoprice = parseFloat(covopricedecstring.toString()); + + priceData.gmx.usd = covoprice; + + const PolygonUSDCPoolBalance = await getAdjustedAmountusdc( + poolstore, + 'polygon', + abi['getBalance'] + ); + + const PolygonStakedCovo = await getAdjustedAmountcovo( + stakingstore, + 'polygon', + abi['getTotalSupply'] + ); + + const stakedCovoclaimedUSDC = await getAdjustedAmountusdc( + stakingstore, + 'polygon', + abi['getRewardPerTokenSum'] + ); + + const stakedCovoPendingUSDC = await getAdjustedAmountusdc( + stakingstore, + 'polygon', + abi['getPendingReward'] + ); + + const RewardsdistributorCovo = await getAdjustedAmountcovo( + covorewardsdistributor, + 'polygon', + abi['tokensPerInterval'] + ); + + pools.push( + await getPoolCovo( + 'polygon', + polygoncovostakingtracker, + priceData, + stakedCovoclaimedUSDC, + stakedCovoPendingUSDC, + PolygonStakedCovo, + RewardsdistributorCovo + ) + ); + + pools.push( + await getPoolUsdc( + 'polygon', + PolygonUSDCPoolBalance, + polygonusdcstakingtracker, + priceData, + stakedCovoclaimedUSDC, + stakedCovoPendingUSDC, + PolygonUSDCPoolBalance + ) + ); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.covo.finance/pool', +}; diff --git a/src/adaptors/cream-lending/abi.js b/src/adaptors/cream-lending/abi.js new file mode 100644 index 0000000000..48e34a6ed9 --- /dev/null +++ b/src/adaptors/cream-lending/abi.js @@ -0,0 +1,3290 @@ +module.exports = { + ctoken: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reservesFee', + type: 'uint256', + }, + ], + name: 'Flashloan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCap', + type: 'uint256', + }, + ], + name: 'NewCollateralCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralTokens', + type: 'uint256', + }, + ], + name: 'UserCollateralChanged', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + ], + name: '_addReserves', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + ], + name: '_reduceReserves', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCollateralCap', + type: 'uint256', + }, + ], + name: '_setCollateralCap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'accountCollateralTokens', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [ + { + internalType: 'address payable', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'balanceOfUnderlying', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + ], + name: 'borrow', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'borrowBalanceCurrent', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'borrowBalanceStored', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'collateralCap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: 'change', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'repay', + type: 'bool', + }, + ], + name: 'estimateBorrowRatePerBlockAfterChange', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: 'change', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'repay', + type: 'bool', + }, + ], + name: 'estimateSupplyRatePerBlockAfterChange', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'flashFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'flashFeeBips', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ERC3156FlashBorrowerInterface', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'flashLoan', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getAccountSnapshot', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'gulp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'underlying_', + type: 'address', + }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { + internalType: 'string', + name: 'name_', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol_', + type: 'string', + }, + { + internalType: 'uint8', + name: 'decimals_', + type: 'uint8', + }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { + internalType: 'string', + name: 'name_', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol_', + type: 'string', + }, + { + internalType: 'uint8', + name: 'decimals_', + type: 'uint8', + }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'internalCash', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'isCollateralTokenInit', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + internalType: 'contract CTokenInterface', + name: 'cTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'maxFlashLoan', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + ], + name: 'mint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [ + { + internalType: 'address payable', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'redeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + ], + name: 'redeemUnderlying', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'registerCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + ], + name: 'repayBorrow', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + ], + name: 'repayBorrowBehalf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'seize', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalCollateralTokens', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'dst', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'src', + type: 'address', + }, + { + internalType: 'address', + name: 'dst', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'unregisterCollateral', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/cream-lending/index.js b/src/adaptors/cream-lending/index.js new file mode 100644 index 0000000000..c7277939a6 --- /dev/null +++ b/src/adaptors/cream-lending/index.js @@ -0,0 +1,104 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { ctoken } = require('./abi'); + +const BLOCKS_PER_DAY = 86400 / 12; + +const CR_USDT = '0x19b3bDe6F02Fc2C985947dcC1Dc2A4cDDfd43eE8'; +const CR_USDC = '0xC42D8F3D791C107C458b2FeA025A36669B51fC5f'; + +const calculateApy = (ratesPerBlock) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow( + (parseFloat(ratesPerBlock) / 10 ** 18) * blocksPerDay + 1, + daysPerYear + ) - + 1) * + 100 + ); +}; + +const getPrices = async (addresses) => { + const queires = addresses.map((address) => 'ethereum:' + address).join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${queires}`) + ).data.coins; + + return Object.values(prices).map((o) => o.price); +}; + +const apy = async () => { + const markets = [CR_USDT, CR_USDC].map((address) => ({ target: address })); + + let supplyRates = await sdk.api.abi.multiCall({ + calls: markets, + abi: ctoken.find((m) => m.name === 'supplyRatePerBlock'), + }); + supplyRates = supplyRates.output.map((o) => o.output); + + let cashes = await sdk.api.abi.multiCall({ + calls: markets, + abi: ctoken.find((m) => m.name === 'getCash'), + }); + cashes = cashes.output.map((o) => o.output); + + let totalBorrows = await sdk.api.abi.multiCall({ + calls: markets, + abi: ctoken.find((m) => m.name === 'totalBorrows'), + }); + totalBorrows = totalBorrows.output.map((o) => o.output); + + let totalSupplies = await sdk.api.abi.multiCall({ + calls: markets, + abi: ctoken.find((m) => m.name === 'totalSupply'), + }); + totalSupplies = totalSupplies.output.map((o) => o.output); + + let exchangeRates = await sdk.api.abi.multiCall({ + calls: markets, + abi: ctoken.find((m) => m.name === 'exchangeRateStored'), + }); + exchangeRates = exchangeRates.output.map((o) => o.output); + + const underlying_addresses = [ + '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC + ]; + const prices = await getPrices(underlying_addresses); + + return [ + { + pool: CR_USDT.toLowerCase(), + chain: 'ethereum', + project: 'cream-lending', + symbol: 'USDT', + tvlUsd: (parseFloat(cashes[0]) / 10 ** 6) * prices[0], + apyBase: calculateApy(supplyRates[0]), + totalSupplyUsd: + (parseFloat(totalSupplies[0] * exchangeRates[0]) / 10 ** 24) * + prices[0], + totalBorrowUsd: (parseFloat(totalBorrows[0]) / 10 ** 6) * prices[0], + }, + { + pool: CR_USDC.toLowerCase(), + chain: 'ethereum', + project: 'cream-lending', + symbol: 'USDC', + tvlUsd: (parseFloat(cashes[1]) / 10 ** 6) * prices[1], + apyBase: calculateApy(supplyRates[1]), + totalSupplyUsd: + (parseFloat(totalSupplies[1] * exchangeRates[1]) / 10 ** 24) * + prices[1], + totalBorrowUsd: (parseFloat(totalBorrows[1]) / 10 ** 6) * prices[1], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.cream.finance/', +}; diff --git a/src/adaptors/credix/index.js b/src/adaptors/credix/index.js new file mode 100644 index 0000000000..2273301533 --- /dev/null +++ b/src/adaptors/credix/index.js @@ -0,0 +1,35 @@ +const axios = require('axios'); +const utils = require('../utils'); + +async function apy() { + const credixMarketStatsResponse = await axios.get( + 'https://credix-market-stats.credix.workers.dev/?cached=True' + ); + const credixApyResponse = await axios.get( + 'https://credix-trailing-apy.credix.workers.dev/' + ); + const credixMarketStats = credixMarketStatsResponse.data; + const credixApy = + credixApyResponse.data['credix-marketplace']['apy_90_d_trailing']; + const tvl = credixMarketStats.TVL; + const poolObj = { + pool: '66v9TQq1P7JKMiKjUZ4xxZRoZh7zyqVdEwuaEAHuE1Bx-solana', + chain: utils.formatChain('solana'), + project: 'credix', + symbol: 'USDC', + tvlUsd: tvl, + apyBase: credixApy * 100, + underlyingTokens: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'], + // borrow fields + ltv: 0, // permissioned + }; + const pool = [poolObj]; + + return pool; +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.credix.finance', +}; diff --git a/src/adaptors/crosscurve/index.js b/src/adaptors/crosscurve/index.js new file mode 100644 index 0000000000..2e7cfe35c1 --- /dev/null +++ b/src/adaptors/crosscurve/index.js @@ -0,0 +1,218 @@ +const fetch = require('node-fetch'); +const curve = require('../curve-dex'); +const { default: BigNumber } = require('bignumber.js'); + +const chainIdMap = { + 146: 'Sonic', + 250: 'Fantom', + 42161: 'Arbitrum', +}; + +const chainNameToKey = { + Sonic: 'sonic', + Fantom: 'fantom', + Arbitrum: 'arbitrum', +}; + +const getGauges = async () => { + try { + const response = await fetch( + 'https://eywa-bot-api-service.eywa.fi/gauges/0x0000000000000000000000000000000000000000', + { + timeout: 5000, + } + ); + + if (!response.ok) { + throw new Error(response.status); + } + + const jsonData = await response.json(); + + if (!jsonData.data) { + return []; + } + + return jsonData.data; + } catch (error) { + console.error(error); + return []; + } +}; + +const getConfig = async () => { + try { + const response = await fetch('https://api.crosscurve.fi/networks', { + timeout: 10000, + }); + + if (!response.ok) { + throw new Error(response.status); + } + + const configData = await response.json(); + + return configData; + } catch (error) { + console.error(error); + return {}; + } +}; + +const merkl = async () => { + try { + const response = await fetch( + 'https://api.merkl.xyz/v4/opportunities?mainProtocolId=crosscurve', + { + timeout: 10000, + } + ); + + if (!response.ok) { + throw new Error(response.status); + } + + const merklData = await response.json(); + + return Object.values(merklData); + } catch (error) { + console.error(error); + return []; + } +}; + +const resolveMerklPool = (merklData, address) => { + const data = merklData.find( + (pool) => + pool.campaigns.active[0]?.campaignParameters?.targetToken?.toLowerCase() === + address && pool.status === 'live' + ); + + if (!data) return; + + // if (data.status === 'live') { + return data; + // } + + // return merklData.find((pool) => pool.platform === data.platform && pool.status === 'live'); +}; + +// Main Function +const main = async () => { + try { + const config = await getConfig(); + + const gauges = await getGauges(); + const addresses = Object.keys(gauges).map((address) => + address.toLowerCase() + ); + const curveData = await curve.apy(); + const merklData = await merkl(); + + const pools = await Promise.all( + addresses.map(async (address) => { + const curvePool = curveData.find( + (pool) => pool.pool.split('-').at(0).toLowerCase() === address + ); + const merklPool = merklData.find( + (data) => data.explorerAddress.toLowerCase() === address + ); + const gauge = gauges[address]; + const rewardTokens = []; + + if (Array.isArray(curvePool?.rewardTokens)) { + rewardTokens.push(...curvePool.rewardTokens); + } + + if (merklPool?.rewardsRecord?.breakdowns.length) { + rewardTokens.push( + ...merklPool.rewardsRecord.breakdowns.map((reward) => + reward.token.address.toLowerCase() + ) + ); + } + + const underlyingTokens = []; + + if (Array.isArray(curvePool?.underlyingTokens)) { + underlyingTokens.push(...curvePool.underlyingTokens); + } + if (merklPool?.tokens) { + underlyingTokens.push( + ...merklPool.tokens.map((token) => token.address.toLowerCase()) + ); + } + + let tvlUsd; + + if (address === '0x38dd6b3c096c8cbe649fa0039cc144f333be8e61') { + const req = await fetch( + 'https://eywa-bot-api-service.eywa.fi/pools-data' + ); + const res = await req.json(); + tvlUsd = res.data.pools.find( + (pool) => + pool.address === '0x38dd6b3c096c8cbe649fa0039cc144f333be8e61' + ).tvl; + if (merklPool?.platform) { + merklPool.platform = 'xCRV'; + } + } else { + tvlUsd = new BigNumber(curvePool?.tvlUsd || 0) + .plus(merklPool?.tvlUsd || 0) + .toNumber(); + } + + const apyBase = curvePool?.apyBase || 0; + const apyReward = new BigNumber(curvePool?.apyReward || 0) + .plus( + new BigNumber(1) + .div(gauge.totalDeposited.boosted) + .multipliedBy(merklPool?.dailyRewards || 0) + .multipliedBy(365) + .multipliedBy(100) + ) + .toNumber(); + + const chain = curvePool?.chain || chainIdMap[merklPool?.chainId]; + const chainKey = chainNameToKey[chain]; + const pools = config[chainKey]?.pools || []; + const tokens = config[chainKey]?.tokens || []; + const pool = pools.find( + (p) => p.address.toLowerCase() === address.toLowerCase() + ); + const lp = pool + ? tokens.find( + (t) => t.address.toLowerCase() === pool.lp.address.toLowerCase() + ) + : null; + + return { + pool: address, + chain: curvePool?.chain || chainIdMap[merklPool?.chainId], + project: 'crosscurve', + symbol: curvePool?.symbol || merklPool?.platform, + apyBase, + apyReward, + tvlUsd, + rewardTokens: Array.from( + new Set(rewardTokens.map((address) => address.toLowerCase())) + ), + underlyingTokens: Array.from( + new Set(underlyingTokens.map((address) => address.toLowerCase())) + ), + poolMeta: lp?.symbol || pool?.label, + }; + }) + ); + return pools.filter((i) => i.symbol); + } catch (error) { + console.log(error); + } +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.crosscurve.fi/farm', +}; diff --git a/src/adaptors/crowdswap/farms.js b/src/adaptors/crowdswap/farms.js new file mode 100644 index 0000000000..b42259570f --- /dev/null +++ b/src/adaptors/crowdswap/farms.js @@ -0,0 +1,170 @@ +exports.Farms = { + polygon: [ + { + farmAddress: '0x1901b3133b5797f4A5a9d0A07dd57f718596ca4d', + pairAddress: '0x90891A7c7D3e26a015b69D1D377da7ADcE780e8A', + chainString: 'polygon', + chainId:137, + assets: 'MATIC/CROWD', + tokenB:{ + chainId: 137, + address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', + name: 'Wrapped Matic', + symbol: 'WMATIC', + decimals: 18, + }, + rewardToken: { + chainId: 137, + address: '0x483dd3425278C1f79F377f1034d9d2CaE55648B6', + name: 'Crowd Token', + symbol: 'CROWD', + decimals: 18, + }, + multiplier: 0 + }, + { + farmAddress: '0xDC311A12D70Ab2Fae9A34AD2d577edf95c747cDe', + pairAddress: '0xc34F686947Df1e91e9709777CB70BC8a5584cE92', + chainString: 'polygon', + chainId:137, + assets: 'USDT/CROWD', + tokenB:{ + chainId: 137, + address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + name: 'USDT-Tether USD (PoS)', + symbol: 'USDT', + decimals: 6, + }, + rewardToken: { + chainId: 137, + address: '0x483dd3425278C1f79F377f1034d9d2CaE55648B6', + name: 'Crowd Token', + symbol: 'CROWD', + decimals: 18, + }, + multiplier: 0 + }, + { + farmAddress: '0x2a45D84824759c9171F15AE7F514f96ccA8F471c', + pairAddress: '0x7a1CcFaA8D636063c95Cb122523bD46924c19ee6', + chainString: 'polygon', + chainId:137, + assets: 'USDC/CROWD', + tokenB: { + chainId: 137, + address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + name: 'USDC-USD Coin', + symbol: 'USDC', + decimals: 6, + }, + rewardToken: { + chainId: 137, + address: '0x483dd3425278C1f79F377f1034d9d2CaE55648B6', + name: 'Crowd Token', + symbol: 'CROWD', + decimals: 18, + }, + multiplier: 0 + }, + { + farmAddress: '0xf35a69232Af34d5ad1B02e76A47e6c7D306bFA02', + pairAddress: '0x424fb8C7AE0489BAFE70403b76a75892bB5B1BE1', + chainString: 'polygon', + chainId:137, + assets: 'USDC/EDAT', + tokenB: { + chainId: 137, + address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + name: 'USDC-USD Coin', + symbol: 'USDC', + decimals: 6, + }, + rewardToken: { + chainId: 137, + address: '0x483dd3425278C1f79F377f1034d9d2CaE55648B6', + name: 'Crowd Token', + symbol: 'CROWD', + decimals: 18, + }, + multiplier: 0 + }, + { + farmAddress: '0x42c633DFD2D04fEFd64e717FFF1aEaBC1B735C46', + pairAddress: '0x3BfF8725219504D31F544b55480bA00B0d4CB173', + chainString: 'polygon', + chainId:137, + assets: 'MATIC/USDC', + tokenB: { + chainId: 137, + address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', + name: 'Wrapped Matic', + symbol: 'WMATIC', + decimals: 18, + }, + rewardToken: { + chainId: 137, + address: '0x483dd3425278C1f79F377f1034d9d2CaE55648B6', + name: 'Crowd Token', + symbol: 'CROWD', + decimals: 18, + }, + multiplier: 6 + }, + ], + // arbitrum: [ + // { + // farmAddress: '0xA1157eb747Ebf867369989F5488E8d21b6BF371C', + // pairAddress: '0xC74D1E72546B55eAD65c29Cf597d5d6eF82a5e69', + // chainString: 'arbitrum', + // chainId:42161, + // assets: 'ARB/CROWD', + // }, + // { + // farmAddress: '0x422AF8a12373b1f9c0BD0540E50c474C63b50Bad', + // pairAddress: '0xA0D518c5f4828a6e6574625301f3A45623138224', + // chainString: 'arbitrum', + // chainId:42161, + // assets: 'ETH/ARB', + // }, + // ], + // bsc: [ + // { + // farmAddress: '0xA319fC1D39F8f8834a29908B0a19ccB644cE1e30', + // pairAddress: '0xc32DeF1b04E642198458D4EAA4470F0Dc2066926', + // chainString: 'bsc', + // chainId:56, + // assets: 'BNB/WSI', + // }, + // ], + + // avalanche: [ + // { + // farmAddress: '0xf360109D07785c6718fC31B5f1303bBEd757e857', + // pairAddress: '0x4CBC64E90Cd6DA0a408b0A217631701b03D37f3B', + // chainString: 'avalanche', + // chainId:43114, + // assets: 'AVAX/CROWD', + // }, + // ], + + // zkSync: [ + // { + // farmAddress: '0x6Bfc439005f37C53148e84007392eE1D7a8D01CB', + // pairAddress: '0x9B64d744d3776190bDcA5Ca52B5e5285f4a343A1', + // chainString: 'zkSync Era', + // chainId:324, + // assets: 'ETH/CROWD', + // }, + // ], + + // ethereum: [ + // { + // farmAddress: '0x635C8dE67c93B3f8140182B7c9af6d4F58859416', + // pairAddress: '0x40B63883989198db4Ac8EdFb19a43F4C5499CF56', + // chainString: 'ethereum', + // chainId:1, + // assets: 'ETH/CROWD', + // }, + // ], + }; + \ No newline at end of file diff --git a/src/adaptors/crowdswap/index.js b/src/adaptors/crowdswap/index.js new file mode 100644 index 0000000000..0209ddd2bd --- /dev/null +++ b/src/adaptors/crowdswap/index.js @@ -0,0 +1,109 @@ +const utils = require('../utils'); +const data = require('./farms'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const BigNumber = require('bignumber.js'); + +const abi = [{ + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +}, +{ + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +}, +]; + +async function getTvl(pair,liquidity, baseTokenPrice ,tokenB, chainString){ + const totalSupply = (await sdk.api.erc20.totalSupply({ target: pair, chain: chainString })).output; + const balance = (await sdk.api.erc20.balanceOf({ + target: tokenB.address, + owner: pair, + chain: chainString + })).output; + const baseTokenAmount = BigNumber(liquidity).times(balance).div(totalSupply).div(10 ** tokenB.decimals); + return baseTokenAmount * baseTokenPrice * 2; +} + +function getApy(rewardRate, rewardPrice,tvl,multiplier) { + const dailyReward = (+rewardRate / 10 ** 18 / 10 ** multiplier) * 24 * 3600; + const apr = ((dailyReward * rewardPrice) / (tvl / 100)) * 365; + return utils.aprToApy(apr); +} + +const main = async () => { + let poolList; + + for(const item of Object.values(data.Farms)){ + const balanceOfAbi = abi.find((abi) => abi.name === 'balanceOf'); + const farmLiquidity = (await sdk.api.abi.multiCall({ + abi:balanceOfAbi, + calls:item.map(a=>{return {target: a.pairAddress, params : a.farmAddress}}), + chain:item[0].chainString, + })).output; + + const baseTokenPrices = await utils.getPrices(item.map(a=>{return a.tokenB.address}),item[0].chainString); + + const promises = []; + + for (let i = 0; i < farmLiquidity.length; i++) { + const promise = getTvl(item[i].pairAddress,farmLiquidity[i].output,baseTokenPrices.pricesByAddress[item[i].tokenB.address.toLowerCase()],item[i].tokenB,item[0].chainString) + .then(response => response); + promises.push(promise); + } + + await Promise.all(promises).then(results => { + poolList = results.map(item=>{ return {tvlUsd:item}}) + }); + + const rewardTokenPrices = await utils.getPrices(item.map(a=>{return a.rewardToken.address}),item[0].chainString); + + + const rewardRateAbi = abi.find((abi) => abi.name === 'rewardRate'); + const rewardRate = (await sdk.api.abi.multiCall({ + abi:rewardRateAbi, + calls:item.map(a=>{return {target: a.farmAddress}}), + chain:item[0].chainString, + })).output; + + for (let i = 0; i < rewardRate.length; i++) { + poolList[i]['apyReward'] = getApy(rewardRate[i].output,rewardTokenPrices.pricesByAddress[item[i].rewardToken.address.toLowerCase()],poolList[i].tvlUsd,item[i].multiplier); + poolList[i]['symbol'] = item[i].assets; + poolList[i]['chain'] = item[i].chainString; + poolList[i]['project'] = 'crowdswap'; + poolList[i]['pool'] = item[i].farmAddress; + poolList[i]['rewardTokens'] = [item[i].rewardToken.address]; + } + } + return poolList; + }; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.crowdswap.org/opportunity' + }; \ No newline at end of file diff --git a/src/adaptors/crvusd/abiControllers.json b/src/adaptors/crvusd/abiControllers.json new file mode 100644 index 0000000000..fef7feb3b4 --- /dev/null +++ b/src/adaptors/crvusd/abiControllers.json @@ -0,0 +1,576 @@ +[ + { + "name": "UserState", + "inputs": [ + { "name": "user", "type": "address", "indexed": true }, + { "name": "collateral", "type": "uint256", "indexed": false }, + { "name": "debt", "type": "uint256", "indexed": false }, + { "name": "n1", "type": "int256", "indexed": false }, + { "name": "n2", "type": "int256", "indexed": false }, + { "name": "liquidation_discount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Borrow", + "inputs": [ + { "name": "user", "type": "address", "indexed": true }, + { "name": "collateral_increase", "type": "uint256", "indexed": false }, + { "name": "loan_increase", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Repay", + "inputs": [ + { "name": "user", "type": "address", "indexed": true }, + { "name": "collateral_decrease", "type": "uint256", "indexed": false }, + { "name": "loan_decrease", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RemoveCollateral", + "inputs": [ + { "name": "user", "type": "address", "indexed": true }, + { "name": "collateral_decrease", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Liquidate", + "inputs": [ + { "name": "liquidator", "type": "address", "indexed": true }, + { "name": "user", "type": "address", "indexed": true }, + { "name": "collateral_received", "type": "uint256", "indexed": false }, + { "name": "stablecoin_received", "type": "uint256", "indexed": false }, + { "name": "debt", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetMonetaryPolicy", + "inputs": [ + { "name": "monetary_policy", "type": "address", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetBorrowingDiscounts", + "inputs": [ + { "name": "loan_discount", "type": "uint256", "indexed": false }, + { "name": "liquidation_discount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "CollectFees", + "inputs": [ + { "name": "amount", "type": "uint256", "indexed": false }, + { "name": "new_supply", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "collateral_token", "type": "address" }, + { "name": "monetary_policy", "type": "address" }, + { "name": "loan_discount", "type": "uint256" }, + { "name": "liquidation_discount", "type": "uint256" }, + { "name": "amm", "type": "address" } + ], + "outputs": [] + }, + { "stateMutability": "payable", "type": "fallback" }, + { + "stateMutability": "view", + "type": "function", + "name": "factory", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "amm", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "collateral_token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debt", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "loan_exists", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "total_debt", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "max_borrowable", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "N", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "min_collateral", + "inputs": [ + { "name": "debt", "type": "uint256" }, + { "name": "N", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "calculate_debt_n1", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "N", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "create_loan", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "N", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "create_loan_extended", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "N", "type": "uint256" }, + { "name": "callbacker", "type": "address" }, + { "name": "callback_args", "type": "uint256[]" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "add_collateral", + "inputs": [{ "name": "collateral", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "add_collateral", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "_for", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "remove_collateral", + "inputs": [{ "name": "collateral", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "remove_collateral", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "use_eth", "type": "bool" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "borrow_more", + "inputs": [ + { "name": "collateral", "type": "uint256" }, + { "name": "debt", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "repay", + "inputs": [{ "name": "_d_debt", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "repay", + "inputs": [ + { "name": "_d_debt", "type": "uint256" }, + { "name": "_for", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "repay", + "inputs": [ + { "name": "_d_debt", "type": "uint256" }, + { "name": "_for", "type": "address" }, + { "name": "max_active_band", "type": "int256" } + ], + "outputs": [] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "repay", + "inputs": [ + { "name": "_d_debt", "type": "uint256" }, + { "name": "_for", "type": "address" }, + { "name": "max_active_band", "type": "int256" }, + { "name": "use_eth", "type": "bool" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "repay_extended", + "inputs": [ + { "name": "callbacker", "type": "address" }, + { "name": "callback_args", "type": "uint256[]" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "health_calculator", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "d_collateral", "type": "int256" }, + { "name": "d_debt", "type": "int256" }, + { "name": "full", "type": "bool" } + ], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "health_calculator", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "d_collateral", "type": "int256" }, + { "name": "d_debt", "type": "int256" }, + { "name": "full", "type": "bool" }, + { "name": "N", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "liquidate", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "min_x", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "liquidate", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "min_x", "type": "uint256" }, + { "name": "use_eth", "type": "bool" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "liquidate_extended", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "min_x", "type": "uint256" }, + { "name": "frac", "type": "uint256" }, + { "name": "use_eth", "type": "bool" }, + { "name": "callbacker", "type": "address" }, + { "name": "callback_args", "type": "uint256[]" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokens_to_liquidate", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokens_to_liquidate", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "frac", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "health", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "health", + "inputs": [ + { "name": "user", "type": "address" }, + { "name": "full", "type": "bool" } + ], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "users_to_liquidate", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { "name": "user", "type": "address" }, + { "name": "x", "type": "uint256" }, + { "name": "y", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "health", "type": "int256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "users_to_liquidate", + "inputs": [{ "name": "_from", "type": "uint256" }], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { "name": "user", "type": "address" }, + { "name": "x", "type": "uint256" }, + { "name": "y", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "health", "type": "int256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "users_to_liquidate", + "inputs": [ + { "name": "_from", "type": "uint256" }, + { "name": "_limit", "type": "uint256" } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { "name": "user", "type": "address" }, + { "name": "x", "type": "uint256" }, + { "name": "y", "type": "uint256" }, + { "name": "debt", "type": "uint256" }, + { "name": "health", "type": "int256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "amm_price", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "user_prices", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[2]" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "user_state", + "inputs": [{ "name": "user", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[4]" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_amm_fee", + "inputs": [{ "name": "fee", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_amm_admin_fee", + "inputs": [{ "name": "fee", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_monetary_policy", + "inputs": [{ "name": "monetary_policy", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_borrowing_discounts", + "inputs": [ + { "name": "loan_discount", "type": "uint256" }, + { "name": "liquidation_discount", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_callback", + "inputs": [{ "name": "cb", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin_fees", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "collect_fees", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "liquidation_discounts", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "loans", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "loan_ix", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_loans", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "minted", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "redeemed", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "monetary_policy", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "liquidation_discount", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "loan_discount", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + } +] diff --git a/src/adaptors/crvusd/abiFactory.json b/src/adaptors/crvusd/abiFactory.json new file mode 100644 index 0000000000..b571b14c53 --- /dev/null +++ b/src/adaptors/crvusd/abiFactory.json @@ -0,0 +1,273 @@ +[ + { + "name": "AddMarket", + "inputs": [ + { "name": "collateral", "type": "address", "indexed": true }, + { "name": "controller", "type": "address", "indexed": false }, + { "name": "amm", "type": "address", "indexed": false }, + { "name": "monetary_policy", "type": "address", "indexed": false }, + { "name": "ix", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetDebtCeiling", + "inputs": [ + { "name": "addr", "type": "address", "indexed": true }, + { "name": "debt_ceiling", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "MintForMarket", + "inputs": [ + { "name": "addr", "type": "address", "indexed": true }, + { "name": "amount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RemoveFromMarket", + "inputs": [ + { "name": "addr", "type": "address", "indexed": true }, + { "name": "amount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetImplementations", + "inputs": [ + { "name": "amm", "type": "address", "indexed": false }, + { "name": "controller", "type": "address", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "SetAdmin", + "inputs": [{ "name": "admin", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "SetFeeReceiver", + "inputs": [{ "name": "fee_receiver", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "stablecoin", "type": "address" }, + { "name": "admin", "type": "address" }, + { "name": "fee_receiver", "type": "address" }, + { "name": "weth", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "stablecoin", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_market", + "inputs": [ + { "name": "token", "type": "address" }, + { "name": "A", "type": "uint256" }, + { "name": "fee", "type": "uint256" }, + { "name": "admin_fee", "type": "uint256" }, + { "name": "_price_oracle_contract", "type": "address" }, + { "name": "monetary_policy", "type": "address" }, + { "name": "loan_discount", "type": "uint256" }, + { "name": "liquidation_discount", "type": "uint256" }, + { "name": "debt_ceiling", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address[2]" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "total_debt", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_controller", + "inputs": [{ "name": "collateral", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_controller", + "inputs": [ + { "name": "collateral", "type": "address" }, + { "name": "i", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_amm", + "inputs": [{ "name": "collateral", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_amm", + "inputs": [ + { "name": "collateral", "type": "address" }, + { "name": "i", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_implementations", + "inputs": [ + { "name": "controller", "type": "address" }, + { "name": "amm", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_admin", + "inputs": [{ "name": "admin", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_fee_receiver", + "inputs": [{ "name": "fee_receiver", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_debt_ceiling", + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "debt_ceiling", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "rug_debt_ceiling", + "inputs": [{ "name": "_to", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "collect_fees_above_ceiling", + "inputs": [{ "name": "_to", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "controllers", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "amms", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "fee_receiver", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "controller_implementation", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "amm_implementation", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_collaterals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "collaterals", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "collaterals_index", + "inputs": [ + { "name": "arg0", "type": "address" }, + { "name": "arg1", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debt_ceiling", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debt_ceiling_residual", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "WETH", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + } +] diff --git a/src/adaptors/crvusd/abiPolicies.json b/src/adaptors/crvusd/abiPolicies.json new file mode 100644 index 0000000000..ccc7b4790d --- /dev/null +++ b/src/adaptors/crvusd/abiPolicies.json @@ -0,0 +1,159 @@ +[ + { + "name": "SetAdmin", + "inputs": [{ "name": "admin", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "AddPegKeeper", + "inputs": [{ "name": "peg_keeper", "type": "address", "indexed": true }], + "anonymous": false, + "type": "event" + }, + { + "name": "RemovePegKeeper", + "inputs": [{ "name": "peg_keeper", "type": "address", "indexed": true }], + "anonymous": false, + "type": "event" + }, + { + "name": "SetRate", + "inputs": [{ "name": "rate", "type": "uint256", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "SetSigma", + "inputs": [{ "name": "sigma", "type": "uint256", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "SetTargetDebtFraction", + "inputs": [ + { "name": "target_debt_fraction", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "admin", "type": "address" }, + { "name": "price_oracle", "type": "address" }, + { "name": "controller_factory", "type": "address" }, + { "name": "peg_keepers", "type": "address[5]" }, + { "name": "rate", "type": "uint256" }, + { "name": "sigma", "type": "uint256" }, + { "name": "target_debt_fraction", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_admin", + "inputs": [{ "name": "admin", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_peg_keeper", + "inputs": [{ "name": "pk", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "remove_peg_keeper", + "inputs": [{ "name": "pk", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rate", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "rate_write", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rate", + "inputs": [{ "name": "rate", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_sigma", + "inputs": [{ "name": "sigma", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_target_debt_fraction", + "inputs": [{ "name": "target_debt_fraction", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rate0", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "sigma", + "inputs": [], + "outputs": [{ "name": "", "type": "int256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "target_debt_fraction", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "peg_keepers", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "PRICE_ORACLE", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "CONTROLLER_FACTORY", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + } +] diff --git a/src/adaptors/crvusd/index.js b/src/adaptors/crvusd/index.js new file mode 100644 index 0000000000..85d583e3a4 --- /dev/null +++ b/src/adaptors/crvusd/index.js @@ -0,0 +1,178 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abiFactory = require('./abiFactory.json'); +const abiControllers = require('./abiControllers.json'); +const abiPolicies = require('./abiPolicies.json'); +const { getERC4626Info } = require('../utils'); + +const factory = '0xC9332fdCB1C491Dcc683bAe86Fe3cb70360738BC'; +const crvUsd = '0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E'; + +const apy = async () => { + const nCollaterals = ( + await sdk.api.abi.call({ + target: factory, + abi: abiFactory.find((m) => m.name === 'n_collaterals'), + }) + ).output; + + const controllers = ( + await sdk.api.abi.multiCall({ + calls: [...Array.from({ length: nCollaterals }).keys()].map((i) => ({ + target: factory, + params: i, + })), + abi: abiFactory.find((m) => m.name === 'controllers'), + }) + ).output.map((o) => o.output); + + const amms = ( + await sdk.api.abi.multiCall({ + calls: [...Array.from({ length: nCollaterals }).keys()].map((i) => ({ + target: factory, + params: i, + })), + abi: abiFactory.find((m) => m.name === 'amms'), + }) + ).output.map((o) => o.output); + + const collateralTokens = ( + await sdk.api.abi.multiCall({ + calls: controllers.map((i) => ({ + target: i, + })), + abi: abiControllers.find((m) => m.name === 'collateral_token'), + }) + ).output.map((o) => o.output); + + const monetaryPolicies = ( + await sdk.api.abi.multiCall({ + calls: controllers.map((i) => ({ + target: i, + })), + abi: abiControllers.find((m) => m.name === 'monetary_policy'), + }) + ).output.map((o) => o.output); + + const rates = ( + await sdk.api.abi.multiCall({ + calls: monetaryPolicies.map((i) => ({ + target: i, + })), + abi: abiPolicies.find((m) => m.name === 'rate'), + }) + ).output.map((o) => o.output); + + const maxBorrowable = ( + await sdk.api.abi.multiCall({ + calls: controllers.map((i) => ({ + target: i, + params: [ + // wbtc + i === '0x4e59541306910aD6dC1daC0AC9dFB29bD9F15c67' + ? 100000000n + : 1000000000000000000n, + 4, + ], + })), + abi: abiControllers.find((m) => m.name === 'max_borrowable'), + }) + ).output.map((o) => o.output); + + const collateralBalance = ( + await sdk.api.abi.multiCall({ + calls: collateralTokens.map((t, i) => ({ + target: t, + params: amms[i], + })), + abi: 'erc20:balanceOf', + }) + ).output.map((o) => o.output); + + const totalDebt = ( + await sdk.api.abi.multiCall({ + calls: controllers.map((i) => ({ + target: i, + })), + abi: abiControllers.find((m) => m.name === 'total_debt'), + }) + ).output.map((o) => o.output); + + const debtCeiling = ( + await sdk.api.abi.multiCall({ + calls: controllers.map((t) => ({ + target: factory, + params: t, + })), + abi: abiFactory.find((m) => m.name === 'debt_ceiling'), + }) + ).output.map((o) => o.output); + + const coins = [...collateralTokens, crvUsd].map((t) => `ethereum:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${coins}`) + ).data.coins; + + const crvUsdPrice = prices[`ethereum:${crvUsd}`].price; + + const pools = collateralTokens.map((t, i) => { + const token = prices[`ethereum:${t}`]; + const price = token.price; + const decimals = token.decimals; + const symbol = token.symbol; + + const totalSupplyUsd = (collateralBalance[i] * price) / 10 ** decimals; + const totalBorrowUsd = totalDebt[i] / 1e18; + // cdp + const tvlUsd = totalSupplyUsd; + const debtCeilingUsd = debtCeiling[i] / 1e18; + + // https://docs.curve.fi/crvUSD/monetarypolicy/#interest-rates + const apyBaseBorrow = + ((1 + rates[i] / 1e18) ** (365 * 24 * 60 * 60) - 1) * 100; + + const ltv = ((maxBorrowable[i] / 1e18) * crvUsdPrice) / price; + + return { + pool: `${amms[i]}-crvusd`, + symbol, + project: 'crvusd', + chain: 'ethereum', + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd, + apyBase: 0, + apyBaseBorrow, + underlyingTokens: [collateralTokens[i]], + mintedCoin: 'crvusd', + ltv, + }; + }); + + const scrvusd = await getERC4626Info( + '0x0655977FEb2f289A4aB78af67BAB0d17aAb84367', + 'ethereum' + ); + + return pools + .concat([ + { + symbol: 'scrvUSD', + pool: `${scrvusd.pool}-crvusd`, + project: 'crvusd', + chain: 'ethereum', + tvlUsd: scrvusd.tvl / 1e18, + apyBase: scrvusd.apyBase, + }, + ]) + .filter( + (i) => i.pool !== '0x136e783846ef68C8Bd00a3369F787dF8d683a696-crvusd' + ); +}; + +module.exports = { + apy, + url: 'https://crvusd.curve.fi/#/ethereum/markets', +}; diff --git a/src/adaptors/crypto.com-liquid-staking/index.js b/src/adaptors/crypto.com-liquid-staking/index.js new file mode 100644 index 0000000000..29e6dfcb9b --- /dev/null +++ b/src/adaptors/crypto.com-liquid-staking/index.js @@ -0,0 +1,79 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const cdceth = { + ethereum: '0xfe18aE03741a5b84e39C295Ac9C856eD7991C38e', + cronos: '0x7a7c9db510aB29A2FC362a4c34260BEcB5cE3446', +}; + +const abi = 'function exchangeRate() external view returns (uint256)'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: cdceth.cronos, + abi: 'erc20:totalSupply', + chain: 'cronos', + }) + ).output / 1e18; + + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: cdceth.ethereum, + abi: abi, + }), + sdk.api.abi.call({ + target: cdceth.ethereum, + abi: abi, + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: cdceth.ethereum, + abi: abi, + block: block7dayAgo, + }), + ]); + + const apr1d = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18) * 365 * 100; + + const apr7d = + ((exchangeRates[0].output - exchangeRates[2].output) / 1e18) * 52 * 100; + + const priceKey = `ethereum:${weth}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: cdceth.cronos, + chain: 'cronos', + project: 'crypto.com-liquid-staking', + symbol: 'cdcETH', + tvlUsd: totalSupply * price, + apyBase: apr7d, + apyBase7d: apr7d, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://crypto.com/staking', +}; diff --git a/src/adaptors/csigma-finance/index.js b/src/adaptors/csigma-finance/index.js new file mode 100644 index 0000000000..129da204ed --- /dev/null +++ b/src/adaptors/csigma-finance/index.js @@ -0,0 +1,181 @@ +const sdk = require('@defillama/sdk'); + +async function getChainIdToNameMap() { + const url = 'https://api.llama.fi/chains'; + + try { + const response = await fetch(url); + const data = await response.json(); + + const chainIdMap = {}; + data.forEach(chain => { + if (chain.chainId) { + chainIdMap[parseInt(chain.chainId)] = chain.name; + } + }); + + return chainIdMap; + } catch (error) { + return {}; + } +} + +const apy = async function () { + const response = await fetch('https://edgeapi.csigma.finance/api/v1/external/pools/apr'); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const chainIdToName = await getChainIdToNameMap(); + + let pools = []; + for (const pool of data.data.pools) { + const { address, networkId, apr } = pool; + const chain = (chainIdToName[networkId] || 'unknown').toLowerCase(); + const [ + { output: poolToken }, + { output: tvl } + ] = await Promise.all([ + sdk.api.abi.call({ + target: address, + abi: "address:poolToken", + chain, + }), + sdk.api.abi.call({ + target: address, + abi: { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + chain, + }) + ]) + + const [ + { output: tokenSymbol }, + { output: tokenDecimals } + ] = await Promise.all([ + sdk.api.abi.call({ + target: poolToken, + abi: "erc20:symbol", + chain, + }), + sdk.api.abi.call({ + target: poolToken, + abi: "erc20:decimals", + chain, + }), + ]); + + + pools.push({ + pool: `${address}-${chain}`, // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase() + chain, // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) + project: 'csigma-finance', // protocol (using the slug again) + symbol: tokenSymbol, // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP + tvlUsd: (tvl * 1.0) / Math.pow(10, tokenDecimals), // TVL in USD, can be a single value or an array of values if pool is multi-sided + apyBase: apr, // APY from pool fees/supplying in % + rewardTokens: pool.stakingContractAddress ? ['0x53162ec0adae49f21515bb8ca91534dd3872c8db'] : [], // Array of reward token addresses (you can omit this field if a pool doesn't have rewards) + underlyingTokens: [poolToken], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: pool.name, // A string value which can stand for any specific details of a pool position, market, fee tier, lock duration, specific strategy etc + }); + } + + if (data.data.yieldBearingTokens && data.data.yieldBearingTokens.length > 0) { + for (const ybt of data.data.yieldBearingTokens) { + const { address, networkId, apr, vaults, assetOracleAddress } = ybt; + const chain = (chainIdToName[networkId] || 'unknown').toLowerCase(); + + const [ + { output: tvl }, + { output: decimals }, + { output: tokenSymbol }, + { output: tokenName }, + ] = await Promise.all([ + sdk.api.abi.call({ + target: assetOracleAddress, + abi: { + "inputs": [], + "name": "totalAssetsUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "totalValue", + "type": "uint256" + }, + ], + "stateMutability": "view", + "type": "function" + }, + chain, + }), + sdk.api.abi.call({ + target: assetOracleAddress, + abi: { + "inputs": [], + "name": "DECIMALS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + ], + "stateMutability": "view", + "type": "function" + }, + chain, + }), + sdk.api.abi.call({ + target: address, + abi: 'erc20:symbol', + chain, + }), + sdk.api.abi.call({ + target: address, + abi: { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + chain, + }), + ]); + pools.push({ + pool: `${address}-${chain}`, + chain, + project: 'csigma-finance', + symbol: tokenSymbol, + tvlUsd: (tvl * 1.0) / decimals, + apyBase: apr, + rewardTokens: [], + underlyingTokens: vaults, + poolMeta: tokenName, + }); + } + } + + return pools; +} +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.csigma.finance', +}; \ No newline at end of file diff --git a/src/adaptors/curve-dex/config.js b/src/adaptors/curve-dex/config.js new file mode 100644 index 0000000000..26d2ea6ab8 --- /dev/null +++ b/src/adaptors/curve-dex/config.js @@ -0,0 +1,83 @@ +exports.CRV_API_BASE_URL = 'https://api.curve.finance/api'; +exports.CRV_API_BASE_URL_V1 = 'https://api.curve.finance/v1'; +exports.BLOCKCHAINIDS = [ + 'ethereum', + 'polygon', + 'fantom', + 'arbitrum', + 'avalanche', + 'optimism', + 'xdai', + 'moonbeam', + 'kava', + 'base', + 'fraxtal', + 'sonic', + // 'celo', +]; +// https://github.com/curvefi/curve-api/blob/main/endpoints.md#getpools +REGISTRY_TYPES = [ + 'main', + 'crypto', + 'factory', + 'factory-crypto', + 'optimism', + 'factory-crvusd', + 'factory-twocrypto', + 'factory-tricrypto', + 'factory-stable-ng', +]; +exports.BLOCKCHAINID_TO_REGISTRIES = {}; +exports.BLOCKCHAINIDS.forEach((blockchainId) => { + switch (blockchainId) { + case 'ethereum': + case 'arbitrum': + case 'fraxtal': + case 'fantom': + case 'optimism': + case 'sonic': + blockchainRegistries = REGISTRY_TYPES; + break; + case 'xdai': + blockchainRegistries = REGISTRY_TYPES.slice(0, 3); + break; + default: + blockchainRegistries = REGISTRY_TYPES.slice(0, -1); + break; + } + exports.BLOCKCHAINID_TO_REGISTRIES[blockchainId] = blockchainRegistries; +}); +exports.OVERRIDE_DATA = { + fantom: { + '0x3f833Ed02629545DD78AFc3D585f7F3918a3De62': { + symbol: 'xSTABLE', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-24/deposit', + }, + '0xA3a63276b8668583E1B47b979d1093D9Aaf431ee': { + symbol: 'xSTABLE2', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-43/deposit', + }, + '0x15ee0d5f92FD869c2fbf26Ea785E9D150353568D': { + symbol: 'xSTABLE3', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-54/deposit', + }, + '0x3C2fCf53f742345c5c1b3dcb2612a1949BC1F18d': { + symbol: 'xWETH', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-37/deposit', + }, + '0xaBBA40f628F055149f1C7415C4388363392279C3': { + symbol: 'xWETH2', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-49/deposit', + }, + '0x37F5dae6039C8eC4c32ad7D3e2a07aCaa55C08f9': { + symbol: 'xBTC', + url: 'https://curve.finance/#/fantom/pools/factory-stable-ng-39/deposit', + }, + }, + arbitrum: { + '0x6579758e9E85434450D638cFBEA0F2fe79856ddA': { + symbol: 'USDT-EYWA', + url: 'https://curve.finance/#/arbitrum/pools/factory-twocrypto-57/deposit', + }, + }, +}; diff --git a/src/adaptors/curve-dex/index.js b/src/adaptors/curve-dex/index.js new file mode 100644 index 0000000000..e6f6ea6dc0 --- /dev/null +++ b/src/adaptors/curve-dex/index.js @@ -0,0 +1,457 @@ +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const { + CRV_API_BASE_URL, + CRV_API_BASE_URL_V1, + BLOCKCHAINIDS, + BLOCKCHAINID_TO_REGISTRIES, + OVERRIDE_DATA, +} = require('./config'); + +const assetTypeMapping = { + btc: 'ethereum:0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + eth: 'ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', +}; + +const THREE_CRV_ADDRESS = '0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490'; + +const crv = { + ethereum: '0xD533a949740bb3306d119CC777fa900bA034cd52', + arbitrum: '0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978', + optimism: '0x0994206dfE8De6Ec6920FF4D779B0d950605Fb53', + polygon: '0x172370d5Cd63279eFa6d502DAB29171933a610AF', + avax: '0x249848BeCA43aC405b8102Ec90Dd5F22CA513c06', + gnosis: '0x712b3d230F3C1c19db860d80619288b1F0BDd0Bd', + kava: '0x965f84D915a9eFa2dD81b653e3AE736555d945f4', + fantom: '0x1E4F97b9f9F913c46F1632781732927B9019C68b', + base: '0x8Ee73c484A26e0A5df2Ee2a4960B789967dd0415', + fraxtal: '0x331B9182088e2A7d6D3Fe4742AbA1fB231aEcc56', +}; + +const getPools = async (blockchainId) => { + const poolsByAddress = {}; + for (const registry of BLOCKCHAINID_TO_REGISTRIES[blockchainId]) { + const uri = `/getPools/${blockchainId}/${registry}`; + let response; + try { + response = await utils.getData(CRV_API_BASE_URL + uri); + } catch (error) { + continue; + } + if (response?.success && response?.data?.poolData?.length) { + const poolsByAddressForRegistry = Object.fromEntries( + response.data.poolData.map((pool) => [pool.address, pool]) + ); + Object.assign(poolsByAddress, poolsByAddressForRegistry); + } + } + return poolsByAddress; +}; + +const getPoolsVolumes = async (blockchainId) => { + const poolsByAddress = {}; + for (const registry of BLOCKCHAINID_TO_REGISTRIES[blockchainId]) { + const uri = `/getVolumes/${blockchainId}`; + let response; + try { + response = await utils.getData(CRV_API_BASE_URL_V1 + uri); + } catch (error) { + continue; + } + if (response?.success && response?.data?.pools?.length) { + for (const pool of response.data.pools) { + poolsByAddress[String(pool.address).toLowerCase()] = pool; + } + } + } + return poolsByAddress; +}; + +const getSubGraphData = async (blockchainId) => { + const uri = `/getSubgraphData/${blockchainId}`; + let response; + try { + response = await utils.getData(CRV_API_BASE_URL + uri); + } catch (error) { + return {}; + } + if (response?.success) { + if (!response.data?.poolList?.length) return {}; + const poolSubgraphsByAddress = Object.fromEntries( + response.data.poolList.map((pool) => [pool.address, pool]) + ); + return poolSubgraphsByAddress; + } else { + return {}; + } +}; + +const getGaugesByChain = async () => { + const gaugeUri = '/getAllGauges'; + let gaugeResponse; + try { + gaugeResponse = await utils.getData(CRV_API_BASE_URL + gaugeUri); + } catch (error) { + return {}; + } + + const blockchainRegExps = BLOCKCHAINIDS.filter( + (blockchainId) => blockchainId !== 'ethereum' + ).map((blockchainId) => new RegExp(`^(${blockchainId})-(.+)`)); + + const gaugesDataByChain = Object.fromEntries( + BLOCKCHAINIDS.map((blockchainId) => [blockchainId, {}]) + ); + + for (const [gaugeName, gaugeDatum] of Object.entries(gaugeResponse.data)) { + let match = null; + for (const re of blockchainRegExps) { + match = gaugeName.match(re); + if (match) { + break; + } + } + // if no match, it's an ethereum gauge + let blockchainId; + let _gaugeName; + if (!match) { + _gaugeName = gaugeName; + blockchainId = 'ethereum'; + } else { + blockchainId = match[1]; + _gaugeName = match[2]; + } + const _gaugeDatum = Object.assign( + { + gaugeName: _gaugeName, + }, + gaugeDatum + ); + // gauge address on pools crv API is lowercase + gaugesDataByChain[blockchainId][_gaugeDatum.gauge.toLowerCase()] = + _gaugeDatum; + } + + return gaugesDataByChain; +}; + +const getMainPoolGaugeRewards = async () => { + const uri = '/getMainPoolsGaugeRewards'; + let response; + try { + response = await utils.getData(CRV_API_BASE_URL + uri); + if (!response.success) { + throw "call to '/getMainPoolsGaugeRewards' didn't succeed"; + } + return response.data.mainPoolsGaugeRewards; + } catch (error) { + return {}; + } +}; + +const getPoolAPR = (pool, subgraph, gauge, crvPrice, underlyingPrices) => { + if (gauge.is_killed) return 0; + const crvPriceBN = BigNumber(crvPrice); + const decimals = BigNumber(1e18); + const workingSupply = BigNumber(gauge.gauge_data.working_supply).div( + decimals + ); + const inflationRate = BigNumber(gauge.gauge_data.inflation_rate).div( + decimals + ); + const relativeWeight = BigNumber( + gauge.gauge_controller.gauge_relative_weight + ).div(decimals); + const totalSupply = BigNumber(pool.totalSupply).div(decimals); + const virtualPrice = BigNumber(subgraph.virtualPrice).div(decimals); + let poolAPR; + try { + if ( + pool.totalSupply && + !pool.coinsAddresses.includes(THREE_CRV_ADDRESS) && + pool.implementation !== 'metausd-fraxusdc' + ) { + poolAPR = inflationRate + .times(relativeWeight) + .times(31536000) + .times(0.4) + .div(workingSupply) + .times(totalSupply) + .div(pool.usdTotalExcludingBasePool) + .times(crvPrice) + .times(100); + } else { + assetPrice = + pool.assetTypeName === 'usd' + ? 1 + : underlyingPrices[assetTypeMapping[pool.assetTypeName]].price; + poolAPR = crvPriceBN + .times(inflationRate) + .times(relativeWeight) + .times(12614400) + .div(workingSupply) + .div(assetPrice) + .div(virtualPrice) + .times(100); + } + } catch (error) { + return 0; + } + + poolAPR = poolAPR.toNumber(); + + return Number.isFinite(poolAPR) ? poolAPR : 0; +}; + +const getPriceCrv = (pools) => { + //parse through pool coins and return price of crv dao token + for (const coin of pools.map((pool) => pool.coins).flat()) { + if (coin.address === '0xD533a949740bb3306d119CC777fa900bA034cd52') { + return coin.usdPrice; + } + } +}; + +const main = async () => { + // request promises + const gaugePromise = getGaugesByChain(); + const extraRewardPromise = getMainPoolGaugeRewards(); + const blockchainToPoolSubgraphPromise = Object.fromEntries( + BLOCKCHAINIDS.map((blockchainId) => [ + blockchainId, + getSubGraphData(blockchainId), + ]) + ); + const blockchainToPoolPromise = Object.fromEntries( + BLOCKCHAINIDS.map((blockchainId) => [blockchainId, getPools(blockchainId)]) + ); + const blockchainToPoolsVolumesPromise = Object.fromEntries( + BLOCKCHAINIDS.map((blockchainId) => [blockchainId, getPoolsVolumes(blockchainId)]) + ); + + // we need the ethereum data first for the crv prive and await extra query to CG + const ethereumPools = await blockchainToPoolPromise.ethereum; + const priceCrv = getPriceCrv(Object.values(ethereumPools)); + + // get wbtc and weth price which we use for reward APR in case totalSupply field = 0 + const coins = Object.values(assetTypeMapping).join(',').toLowerCase(); + const underlyingPrices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + // const celoApy = ( + // await utils.getData('https://api.curve.fiance/api/getFactoryAPYs-celo') + // ).data.poolDetails; + + const baseApy = ( + await utils.getData('https://api.curve.finance/api/getFactoryAPYs-base') + ).data.poolDetails; + + // create feeder closure to fill defillamaPooldata asynchroniously + const defillamaPooldata = []; + const feedLlama = async (poolData, blockchainId) => { + const [ + addressToPool, + addressToPoolSubgraph, + addressToPoolVolumes, + addressToGauge, + gaugeAddressToExtraRewards, + ] = poolData; + + let factoryAprData; + if (['optimism', 'celo', 'kava', 'base'].includes(blockchainId)) { + factoryAprData = ( + await utils.getData( + `https://api.curve.finance/api/getFactoGauges/${blockchainId}` + ) + ).data.gauges; + } + + const stETHPools = [ + '0xDC24316b9AE028F1497c275EB9192a3Ea0f67022', + '0x6eB2dc694eB516B16Dc9FBc678C60052BbdD7d80', + ]; + for (const [address, pool] of Object.entries(addressToPool)) { + const subgraph = addressToPoolSubgraph[address]; + const gauge = addressToGauge[blockchainId][pool.gaugeAddress]; + // one gauge can have multiple (different) extra rewards + const extraRewards = gaugeAddressToExtraRewards + ? gaugeAddressToExtraRewards[pool.gaugeAddress] + : null; + + const apyBase = subgraph + ? parseFloat(subgraph.latestDailyApy) + : blockchainId === 'celo' + ? celoApy.find((i) => i.poolAddress === address)?.apy + : blockchainId === 'base' + ? baseApy.find((i) => i.poolAddress === address)?.apy + : 0; + + const aprCrv = gauge?.is_killed + ? 0 + : pool?.gaugeCrvApy?.length > 0 + ? pool?.gaugeCrvApy[0] + : 0; + // const aprCrv = + // (blockchainId === 'optimism' && pool?.gaugeCrvApy?.length > 0) || + // [ + // '0xa1F8A6807c402E4A15ef4EBa36528A3FED24E577', + // '0x960ea3e3C7FB317332d990873d354E18d7645590', + // '0x7f90122BF0700F9E7e1F688fe926940E8839F353', + // '0x326290A1B0004eeE78fa6ED4F1d8f4b2523ab669', + // '0x6a6283aB6e31C2AeC3fA08697A8F806b740660b2', + // '0x13B876C26Ad6d21cb87AE459EaF6d7A1b788A113', + // '0x66E335622ad7a6C9c72c98dbfCCE684996a20Ef9', + // '0x3e3C6c7db23cdDEF80B694679aaF1bCd9517D0Ae', + // '0xFc1e8bf3E81383Ef07Be24c3FD146745719DE48D', + // '0x84C333e94AEA4a51a21F6cf0C7F528C50Dc7592C', + // '0xB755B949C126C04e0348DD881a5cF55d424742B2', + // '0xa138341185a9D0429B0021A11FB717B225e13e1F', + // '0x9848482da3Ee3076165ce6497eDA906E66bB85C5', + // ].includes(address) + // ? pool?.gaugeCrvApy[0] + // : gauge && subgraph + // ? getPoolAPR(pool, subgraph, gauge, priceCrv, underlyingPrices) + // : 0; + let aprExtra = extraRewards + ? extraRewards.map((reward) => reward.apy).reduce((a, b) => a + b) + : stETHPools.includes(address) || + address === '0xFF6DD348e6eecEa2d81D4194b60c5157CD9e64f4' || // pool on moonbeam + address === '0xe9123CBC5d1EA65301D417193c40A72Ac8D53501' || // lvusd + address === '0x056C6C5e684CeC248635eD86033378Cc444459B0' || // eur pool gnosis + pool.gaugeRewards?.length + ? pool.gaugeRewards.slice(-1)[0]?.apy + : 0; + + // tokens are listed using their contract addresses + // https://github.com/DefiLlama/yield-server#adaptors + const underlyingTokens = pool.coins.map((coin) => coin.address); + const rewardTokens = extraRewards + ? extraRewards.map((reward) => reward.tokenAddress) + : stETHPools.includes(address) + ? ['0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32'] // LDO + : address === '0xFF6DD348e6eecEa2d81D4194b60c5157CD9e64f4' // pool on moonbeam + ? ['0xacc15dc74880c9944775448304b263d191c6077f'] // wglmr + : address === '0xe9123CBC5d1EA65301D417193c40A72Ac8D53501' + ? ['0x73C69d24ad28e2d43D03CBf35F79fE26EBDE1011'] + : address === '0x056C6C5e684CeC248635eD86033378Cc444459B0' + ? ['0x6810e776880c02933d47db1b9fc05908e5386b96'] + : pool.gaugeRewards?.length + ? [pool.gaugeRewards.slice(-1)[0]?.tokenAddress] + : []; + if (aprCrv) { + rewardTokens.push( + crv[blockchainId === 'avalanche' ? 'avax' : blockchainId] || + '0xD533a949740bb3306d119CC777fa900bA034cd52' + ); // CRV + } + + // note(!) curve api uses coingecko prices and am3CRV is wrongly priced + // this leads to pool.usdTotal to be inflated, going to hardcode temporarly hardcode this + // to 1usd + // am3CRV + const am3CRV = '0xE7a24EF0C5e95Ffb0f6684b813A78F2a3AD7D171'; + const x = pool.coins.find((c) => c.address === am3CRV && c.usdPrice > 2); + + let tvlUsd; + if (x) { + tvlUsd = pool.coins + .map((c) => + c.address === am3CRV + ? (c.poolBalance / `1e${c.decimals}`) * 1 + : (c.poolBalance / `1e${c.decimals}`) * c.usdPrice + ) + .reduce((a, b) => a + b, 0); + } else { + tvlUsd = pool.usdTotal; + } + + if (tvlUsd < 1) { + continue; + } + + const overrideData = OVERRIDE_DATA?.[blockchainId]?.[address]; + const symbol = + overrideData?.symbol || pool.coins.map((coin) => coin.symbol).join('-'); + const url = + overrideData?.url || `https://curve.finance/#/${blockchainId}/pools`; + + const yieldPool = { + pool: address + '-' + blockchainId, + chain: utils.formatChain(blockchainId), + project: 'curve-dex', + symbol, + tvlUsd, + apyBase, + apyReward: + // isolated pool for which the aprCrv is wrong + ['0xBaaa1F5DbA42C3389bDbc2c9D2dE134F5cD0Dc89'].includes(address) + ? null + : [ + '0x9F2fE3500B1a7E285FDc337acacE94c480e00130', + '0x29A3d66B30Bc4AD674A4FDAF27578B64f6afbFe7', + ].includes(address) + ? aprExtra + : aprCrv + aprExtra, + rewardTokens: rewardTokens + .flat() + .filter((i) => i !== '0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32'), + underlyingTokens, + url, + } + + if (addressToPoolVolumes) { + const normalAddress = String(address).toLowerCase(); + if (addressToPoolVolumes[normalAddress]) { + yieldPool.volumeUsd1d = addressToPoolVolumes[normalAddress].volumeUSD + yieldPool.volumeUsd7d = yieldPool.volumeUsd1d * 7 * Number(addressToPoolVolumes[normalAddress].latestWeeklyApyPcent) / Number(addressToPoolVolumes[normalAddress].latestDailyApyPcent); + } + } + + defillamaPooldata.push(yieldPool); + } + }; + + // group Promises by blockchain and feed the llama array + const responses = []; + for (const [blockchainId, poolPromise] of Object.entries( + blockchainToPoolPromise + )) { + responses.push( + Promise.all([ + poolPromise, + blockchainToPoolSubgraphPromise[blockchainId], + blockchainToPoolsVolumesPromise[blockchainId], + gaugePromise, + extraRewardPromise, + ]).then((poolData) => feedLlama(poolData, blockchainId)) + ); + } + + // wait for all Group promises to resolve + try { + await Promise.all(responses); + } catch (error) { + console.error(error); + } + + // correct these pools reward Apy + const correct = [ + '0x7f90122BF0700F9E7e1F688fe926940E8839F353-avalanche', + '0x0f9cb53Ebe405d49A0bbdBD291A65Ff571bC83e1-ethereum', + '0x7f90122BF0700F9E7e1F688fe926940E8839F353-xdai', + ]; + return defillamaPooldata.map((p) => ({ + ...p, + apyReward: correct.includes(p.pool) ? null : p.apyReward, + rewardTokens: correct.includes(p.pool) ? [] : p.rewardTokens, + })); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/curve-llamalend/index.js b/src/adaptors/curve-llamalend/index.js new file mode 100644 index 0000000000..e2ad6f2560 --- /dev/null +++ b/src/adaptors/curve-llamalend/index.js @@ -0,0 +1,76 @@ +const utils = require('../utils'); + +const getLendingPoolData = async () => { + try { + const response = await utils.getData('https://api.curve.finance/v1/getLendingVaults/all'); + if (response.success) { + return response.data.lendingVaultData.map(vault =>({ + pool: vault.address + '-' + vault.blockchainId, + chain: utils.formatChain(vault.blockchainId), + project: 'curve-llamalend', + symbol: vault.assets.borrowed.symbol + '-' + vault.assets.collateral.symbol, + tvlUsd: vault.usdTotal, + underlyingTokens: [vault.assets.collateral.address], + url: vault.lendingVaultUrls.deposit, + apyBase: vault.rates.lendApyPcent, + apyBaseBorrow: vault.rates.borrowApyPcent, + totalSupplyUsd: vault.totalSupplied.usdTotal + })) + } else { + console.error('Failed to fetch lending pool data'); + return []; + } + } catch (error) { + console.error('Error fetching lending pool data:', error); + return []; + } +}; + +const getGaugesData = async () => { + try { + const response = await utils.getData('https://api.curve.finance/v1/getAllGauges'); + if (response.success) { + const gaugesByAddress = {}; + Object.entries(response.data).forEach(([key, gauge]) => { + if (gauge.lendingVaultAddress) { + gaugesByAddress[gauge.lendingVaultAddress.toLowerCase()] = { + crvApy: gauge.gaugeCrvApy ? gauge.gaugeCrvApy[0] : null, + rewardTokens: gauge.gaugeCrvApy ? ['0xD533a949740bb3306d119CC777fa900bA034cd52'] : null + }; + } + }); + return gaugesByAddress; + } else { + console.error('Failed to fetch gauges data'); + return {}; + } + } catch (error) { + console.error('Error fetching gauges data:', error); + return {}; + } +}; + +const fullLendingPoolDataWithGauges = async () => { + const [lendingPools, gaugesByAddress] = await Promise.all([ + getLendingPoolData(), + getGaugesData() + ]); + + return lendingPools.map(pool => { + const gaugeInfo = gaugesByAddress[pool.pool.split('-')[0].toLowerCase()] || {}; + return { + ...pool, + apyReward: gaugeInfo.crvApy, + rewardTokens: gaugeInfo.rewardTokens + }; + }); +}; + +const main = async () => { + return await fullLendingPoolDataWithGauges(); +}; + + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/curve/index.js b/src/adaptors/curve/index.js deleted file mode 100755 index 9d19e23848..0000000000 --- a/src/adaptors/curve/index.js +++ /dev/null @@ -1,269 +0,0 @@ -const utils = require('../utils'); -const pools = require('./pools'); - -// comes from different locations, merging func -const mergeBaseApy = async () => { - // this is the base apy data, split up into 2 different json files - let dataBaseApy = await utils.getData( - 'https://stats.curve.fi/raw-stats/apys.json' - ); - dataBaseApy = dataBaseApy.apy.day; - - let dataBaseApyOther = await utils.getData( - 'https://stats.curve.fi/raw-stats-crypto/apys.json' - ); - dataBaseApyOther = dataBaseApyOther.apy.week; - - const keys = Object.keys(dataBaseApyOther); - - for (const i of keys) { - dataBaseApy[i] = dataBaseApyOther[i]; - } - - return [dataBaseApy, keys]; -}; - -const getDataEth = async () => { - const poolStats = []; - - // 1) get price data - const pricesUSD = await utils.getCGpriceData( - 'ethereum,bitcoin,chainlink,stasis-eurs', - true - ); - - // 2) get complete base apy data (this does not include any of the factory pool data...) - const [dataBaseApy, keysExtra] = await mergeBaseApy(); - - // 3) pull curve pool stats data and prepare the individual pool data - for (const [pool, apy] of Object.entries(dataBaseApy)) { - // there are few pools in the data which are actually not - // displayed on the frontend, I remove them - // here, probably not the best idea hardcoding this... - if ('rens,linkusd,idle'.includes(pool)) { - continue; - } - - if (keysExtra.includes(pool)) { - url = `https://stats.curve.fi/raw-stats-crypto/${pool}-1440m.json`; - } else { - url = `https://stats.curve.fi/raw-stats/${pool}-1440m.json`; - } - let poolData = await utils.getData(url); - const maxTimestamp = Math.max(...poolData.map((el) => el.timestamp), 0); - poolData = poolData.find((el) => el.timestamp === maxTimestamp); - - // the price will be different depending on pool type - // usd pools are 1, btc pools need to be multiplied by the btc price etc - // cause total supply is in the native unit, like balance - if (pool.includes('eth')) { - price = pricesUSD.ethereum.usd; - } else if (pool.includes('btc')) { - price = pricesUSD.bitcoin.usd; - } else if (pool.includes('link')) { - price = pricesUSD.chainlink.usd; - } else if (pool.includes('eur')) { - price = pricesUSD['stasis-eurs'].usd; - } else { - price = 1; - } - - // for tricrypto pools i use the balances and prices cause - // supply cant just be multiplied by a single price - const scalingFactor = 1e18; - poolData.virtual_price /= scalingFactor; - poolData.supply /= scalingFactor; - - if (keysExtra.includes(pool)) { - if (pool.includes('tricrypto')) { - decimals = [1e6, 1e8, 1e18]; // usdt, btc, eth - } else if (pool.includes('eurtusd')) { - decimals = [1e6, 1e18]; - } else if (pool.includes('eursusd')) { - decimals = [1e6, 1e2]; - } else if (pool.includes('crveth')) { - decimals = [1e18, 1e18]; - } else if (pool.includes('cvxeth')) { - decimals = [1e18, 1e18]; - } else if (pool.includes('xautusd')) { - decimals = [1e6, 1e18]; - } else if (pool.includes('spelleth')) { - decimals = [1e18, 1e18]; - } else if (pool.includes('teth')) { - decimals = [1e18, 1e18]; - } - - if (pool === 'eurtusd') { - tvl = (poolData.balances[0] / decimals[0]) * poolData.price_scale; - tvl += poolData.balances[1] / decimals[1]; - } else if (pool === 'eursusd') { - tvl = (poolData.balances[0] / decimals[0]) * poolData.price_scale; - tvl += poolData.balances[1] / decimals[1]; - } else if (pool === 'xautusd') { - tvl = (poolData.balances[0] / decimals[0]) * poolData.price_scale; - tvl += poolData.balances[1] / decimals[1]; - } else { - tvl = 0; - poolData.balances.forEach((el, i) => { - tvl += (el / decimals[i]) * poolData.crypto_prices[i]; - }); - } - } else { - // for all else - tvl = poolData.supply * price; - } - - // scale by virtual price - tvl *= poolData.virtual_price; - - let apyBase = apy * 100; - // some of the values are negative, set to 0 - apyBase = apyBase < 0 ? 0 : apyBase; - - // 4) get crv+reward apr data - let dataCrvApy = await utils.getData( - 'https://www.convexfinance.com/api/curve-apys' - ); - let dataRewardApy = await utils.getData('https://api.curve.fi/api/getApys'); - dataCrvApy = dataCrvApy.apys; - dataRewardApy = dataRewardApy.data; - - // unfort these two endpoints have different keys for some pools - let searchKey = pool; - if (pool === 'y') { - searchKey = 'iearn'; - } else if (pool === 'susd') { - searchKey = 'susdv2'; - } else if (pool === 'ren2') { - searchKey = 'ren'; - } - - const apyCrv = dataCrvApy[searchKey]?.crvApy; - - // need to sum up the potential rewards apys - const apyRewardsArray = dataRewardApy[searchKey]?.additionalRewards; - let apyRewardsSum = 0; - if (apyRewardsArray?.length > 0) { - apyRewardsSum = apyRewardsArray - .map((el) => el.apy) - .reduce((accumulator, curr) => accumulator + curr); - } - const apySum = - apyRewardsSum === undefined - ? apyBase + apyCrv - : apyBase + apyCrv + apyRewardsSum; - - // 6) append output to object - poolStats.push({ - pool, - virtual_price: poolData.virtual_price, - totalSupply: poolData.supply, - tvl, - apyBase, - apyCrv, - apyRewardsArray, - apyRewardsSum, - apy: apySum, - }); - } - - // note(temporary only, investiage 4pool and 2pool apy) - return poolStats.filter((el) => el.pool !== '4pool' && el.pool !== '2pool'); -}; - -const getDataEVM = async (chainString) => { - let tvl = await utils.getData( - `https://api.curve.fi/api/getTVL${ - chainString.charAt(0).toUpperCase() + chainString.slice(1) - }` - ); - tvl = tvl.data.pools; - - const poolNames = Object.keys(tvl); - let dataTvl = []; - for (const p of poolNames) { - const obj = tvl[p]; - obj['pool'] = p; - dataTvl.push(obj); - } - - if (chainString === 'fantom') { - dataApy = await utils.getData( - `https://stats.curve.fi/raw-stats-ftm/apys.json` - ); - } else { - dataApy = await utils.getData( - `https://stats.curve.fi/raw-stats-${chainString}/apys.json` - ); - } - for (const el of dataTvl) { - el.apy = dataApy.apy.day[el.pool]; - } - - dataTvl = dataTvl.filter((el) => - Object.keys(pools.tokenMapping[chainString]).includes(el.pool) - ); - - return dataTvl; -}; - -const buildPool = (entry, chainString) => { - const token = pools.tokenMapping[chainString][entry.pool]; - const id = pools.pools[chainString].find( - (el) => el.name === entry.pool - )?.swap; - let apy = entry.apy < 0 ? 0 : entry.apy; - apy = chainString === 'ethereum' ? apy : apy * 100; - - const newObj = { - // ugly, but some swap pools have same address on diff networks - pool: `${id}-${chainString}`, - chain: utils.formatChain(chainString), - project: 'curve', - symbol: utils.formatSymbol(token), - tvlUsd: entry.tvl, - apy: apy, - }; - return newObj; -}; - -const topLvl = async (chainString) => { - if (chainString === 'ethereum') { - // pull data - poolStats = await getDataEth(); - } else { - // pull data - poolStats = await getDataEVM(chainString); - } - // build pool objects - let data = poolStats.map((el) => { - if (pools.tokenMapping[chainString][el.pool] === undefined) { - return null; - } - return buildPool(el, chainString); - }); - - data = data.filter((el) => el !== null); - return data; -}; - -const main = async () => { - let data = await Promise.all([ - topLvl('ethereum'), - topLvl('arbitrum'), - topLvl('avalanche'), - topLvl('fantom'), - topLvl('harmony'), - topLvl('optimism'), - topLvl('polygon'), - ]); - - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, - curvePoolStats: getDataEth, - tokenMapping: pools.tokenMapping['ethereum'], -}; diff --git a/src/adaptors/curve/pools.js b/src/adaptors/curve/pools.js deleted file mode 100644 index aab3544aad..0000000000 --- a/src/adaptors/curve/pools.js +++ /dev/null @@ -1,210 +0,0 @@ -exports.tokenMapping = { - arbitrum: { - '2pool': 'USDC-USDT', - ren: 'WBTC-renBTC', - tricrypto: 'USDT-wBTC-WETH', - eursusd: 'EURs-USDC-USDT', - }, - avalanche: { - aave: 'aDAI-aUSDC-aUSDT', - ren: 'aaWBTC-renBTC.e', - atricrypto: 'DAI.e-USDC.e-USDT.e-wBTC.e-WETH', - }, - fantom: { - '2pool': 'DAI-USDC', - fusdt: 'fUSDT-DAI-USDC', - ren: 'WBTC-renBTC', - tricrypto: 'fUSDT-wBTC-WETH', - geist: 'gDAI-gUSDC-gUSDT', - ib: 'cyDAI-cyUSDC-cyUSDT', - }, - harmony: { - '3pool': 'DAI-USDC-USDT', - tricrypto: 'DAI-USDC-USDT-WBTC-WETH', - }, - optimism: { - '3pool': 'DAI-USDC-USDT', - }, - polygon: { - aave: 'aDAI-aUSDC-aUSDT', - ren: 'amWBTC-renBTC', - atricrypto3: 'DAI-USDC-USDT-wBTC-WETH', - eurtusd: 'EURt-DAI-USDC-USDT', - }, - ethereum: { - compound: 'cDAI-cUSDC', - usdt: 'cDAI-cUSDC-USDT', - y: 'yDAI-yUSDC-yUSDT-yTUSD', - busd: 'yDAI-yUSDC-yUSDT-yBUSD', - susd: 'DAI-USDC-USDT-sUSD', - pax: 'ycDAI-ycUSDC-ycUSDT-PAX', - ren2: 'renBTC-wBTC', - rens: 'renBTC-wBTC-sBTC', - hbtc: 'HBTC-wBTC', - '3pool': 'DAI-USDC-USDT', - gusd: 'GUSD-DAI-USDC-USDT', - husd: 'HUSD-DAI-USDC-USDT', - usdn: 'USDN-DAI-USDC-USDT', - usdk: 'USDK-DAI-USDC-USDT', - musd: 'mUSD-DAI-USDC-USDT', - rsv: 'RSV-DAI-USDC-USDT', - tbtc: 'tBTC-sbtcCrv', - dusd: 'DUSD-DAI-USDC-USDT', - pbtc: 'pBTC-sbtcCrv', - bbtc: 'BBTC-sbtcCrv', - obtc: 'oBTC-sbtcCrv', - ust: 'UST-DAI-USDC-USDT', - eurs: 'EURs-sEUR', - seth: 'ETH-sETH', - aave: 'aDAI-aUSDC-aUSDT', - steth: 'ETH-stETH', - saave: 'aDAI-aSUSD', - ankreth: 'ETH-ankrETH', - ib: 'cyDAI-cyUSDC-cyUSDT', - link: 'LINK-sLINK', - usdp: 'USDP-DAI-USDC-USDT', - tusd: 'TUSD-DAI-USDC-USDT', - frax: 'FRAX-DAI-USDC-USDT', - lusd: 'LUSD-DAI-USDC-USDT', - busdv2: 'BUSD-DAI-USDC-USDT', - alusd: 'alUSD-DAI-USDC-USDT', - reth: 'ETH-rETH', - mim: 'MIM-DAI-USDC-USDT', - eurt: 'EURT-sEUR', - rai: 'RAI-DAI-USDC-USDT', - tricrypto: 'USDT-wBTC-WETH', - tricrypto2: 'USDT-wBTC-WETH', - eurtusd: 'EURT-DAI-USDC-USDT', - eursusd: 'EURs-USDC', - crveth: 'CRV-ETH', - cvxeth: 'CVX-ETH', - xautusd: 'XAUt-DAI-USDC-USDT', - spelleth: 'SPELL-ETH', - teth: 'T-ETH', - // '2pool': 'USDC-USDT', - // '4pool': 'USDC-USDT-UST-FRAX', - }, -}; - -// https://curve.fi/contracts (need only name and swap) -exports.pools = { - arbitrum: [ - { swap: '0x7f90122BF0700F9E7e1F688fe926940E8839F353', name: '2pool' }, - { swap: '0x960ea3e3C7FB317332d990873d354E18d7645590', name: 'tricrypto' }, - { swap: '0x3E01dD8a5E1fb3481F0F589056b428Fc308AF0Fb', name: 'ren' }, - { swap: '0xA827a652Ead76c6B0b3D19dba05452E06e25c27e', name: 'eursusd' }, - ], - avalanche: [ - { swap: '0x7f90122BF0700F9E7e1F688fe926940E8839F353', name: 'aave' }, - { swap: '0x16a7DA911A4DD1d83F3fF066fE28F3C792C50d90', name: 'ren' }, - { swap: '0xB755B949C126C04e0348DD881a5cF55d424742B2', name: 'atricrypto' }, - ], - fantom: [ - { swap: '0x27E611FD27b276ACbd5Ffd632E5eAEBEC9761E40', name: '2pool' }, - { swap: '0x92D5ebF3593a92888C25C0AbEF126583d4b5312E', name: 'fusdt' }, - { swap: '0x3eF6A01A0f81D6046290f3e2A8c5b843e738E604', name: 'ren' }, - { swap: '0x3a1659ddcf2339be3aea159ca010979fb49155ff', name: 'tricrypto' }, - { swap: '0x0fa949783947Bf6c1b171DB13AEACBB488845B3f', name: 'geist' }, - { swap: '0x4FC8D635c3cB1d0aa123859e2B2587d0FF2707b1', name: 'ib' }, - ], - harmony: [ - { swap: 'one1ch86m2zwjq4djtw5qx20pzp66jtrnvprjk78us', name: '3pool' }, - { swap: 'one1pc7u909la2zqw2sv099hv57nmvmyz48qm26t6r', name: 'tricrypto' }, - ], - optimism: [ - { swap: '0x1337BedC9D22ecbe766dF105c9623922A27963EC', name: '3pool' }, - ], - polygon: [ - { swap: '0x445FE580eF8d70FF569aB36e80c647af338db351', name: 'aave' }, - { swap: '0xC2d95EEF97Ec6C17551d45e77B590dc1F9117C67', name: 'ren' }, - { swap: '0x751B1e21756bDbc307CBcC5085c042a0e9AaEf36', name: 'atricrypto3' }, - { swap: '0xB446BF7b8D6D4276d0c75eC0e3ee8dD7Fe15783A', name: 'eurtusd' }, - ], - ethereum: [ - { - swap: '0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56', - name: 'compound', - }, - { swap: '0x52EA46506B9CC5Ef470C5bf89f17Dc28bB35D85C', name: 'usdt' }, - { swap: '0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51', name: 'y' }, - { swap: '0x79a8C46DeA5aDa233ABaFFD40F3A0A2B1e5A4F27', name: 'busd' }, - { swap: '0xA5407eAE9Ba41422680e2e00537571bcC53efBfD', name: 'susd' }, - { swap: '0x06364f10B501e868329afBc005b3492902d6C763', name: 'pax' }, - { swap: '0x93054188d876f558f4a66B2EF1d97d16eDf0895B', name: 'ren2' }, - { swap: '0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714', name: 'sbtc' }, - { swap: '0x4CA9b3063Ec5866A4B82E437059D2C43d1be596F', name: 'hbtc' }, - { swap: '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7', name: '3pool' }, - { swap: '0x4f062658EaAF2C1ccf8C8e36D6824CDf41167956', name: 'gusd' }, - { swap: '0x3eF6A01A0f81D6046290f3e2A8c5b843e738E604', name: 'husd' }, - { swap: '0x3E01dD8a5E1fb3481F0F589056b428Fc308AF0Fb', name: 'usdk' }, - { swap: '0x0f9cb53Ebe405d49A0bbdBD291A65Ff571bC83e1', name: 'usdn' }, - { swap: '0x8474DdbE98F5aA3179B3B3F5942D724aFcdec9f6', name: 'musd' }, - { swap: '0xC18cC39da8b11dA8c3541C598eE022258F9744da', name: 'rsv' }, - { swap: '0xC25099792E9349C7DD09759744ea681C7de2cb66', name: 'tbtc' }, - { swap: '0x8038C01A0390a8c547446a0b2c18fc9aEFEcc10c', name: 'dusd' }, - { swap: '0x7F55DDe206dbAD629C080068923b36fe9D6bDBeF', name: 'pbtc' }, - { swap: '0x071c661B4DeefB59E2a3DdB20Db036821eeE8F4b', name: 'bbtc' }, - { swap: '0xd81dA8D904b52208541Bade1bD6595D8a251F8dd', name: 'obtc' }, - { swap: '0x890f4e345B1dAED0367A877a1612f86A1f86985f', name: 'ust' }, - { swap: '0x0Ce6a5fF5217e38315f87032CF90686C96627CAA', name: 'eurs' }, - { swap: '0xc5424B857f758E906013F3555Dad202e4bdB4567', name: 'seth' }, - { swap: '0xDeBF20617708857ebe4F679508E7b7863a8A8EeE', name: 'aave' }, - { swap: '0xDC24316b9AE028F1497c275EB9192a3Ea0f67022', name: 'steth' }, - { swap: '0xEB16Ae0052ed37f479f7fe63849198Df1765a733', name: 'saave' }, - { - swap: '0xA96A65c051bF88B4095Ee1f2451C2A9d43F53Ae2', - name: 'ankreth', - }, - { swap: '0x42d7025938bEc20B69cBae5A77421082407f053A', name: 'usdp' }, - { swap: '0x2dded6Da1BF5DBdF597C45fcFaa3194e53EcfeAF', name: 'ib' }, - { swap: '0xF178C0b5Bb7e7aBF4e12A4838C7b7c5bA2C623c0', name: 'link' }, - { swap: '0xEcd5e75AFb02eFa118AF914515D6521aaBd189F1', name: 'tusd' }, - { swap: '0xd632f22692FaC7611d2AA1C0D552930D43CAEd3B', name: 'frax' }, - { swap: '0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA', name: 'lusd' }, - { - swap: '0x4807862AA8b2bF68830e4C8dc86D0e9A998e085a', - name: 'busdv2', - }, - { swap: '0xF9440930043eb3997fc70e1339dBb11F341de7A8', name: 'reth' }, - { swap: '0x43b4FdFD4Ff969587185cDB6f0BD875c5Fc83f8c', name: 'alusd' }, - { - swap: '0x80466c64868E1ab14a1Ddf27A676C3fcBE638Fe5', - name: 'tricrypto', - }, - { - swap: '0xD51a44d3FaE010294C616388b506AcdA1bfAAE46', - name: 'tricrypto2', - }, - { swap: '0x5a6A4D54456819380173272A5E8E9B9904BdF41B', name: 'mim' }, - { swap: '0xFD5dB7463a3aB53fD211b4af195c5BCCC1A03890', name: 'eurt' }, - { - swap: '0x9838eCcC42659FA8AA7daF2aD134b53984c9427b', - name: 'eurtusd', - }, - { - swap: '0x98a7F18d4E56Cfe84E3D081B40001B3d5bD3eB8B', - name: 'eursusd', - }, - { - swap: '0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511', - name: 'crveth', - }, - { swap: '0x618788357D0EBd8A37e763ADab3bc575D54c2C7d', name: 'rai' }, - { - swap: '0xB576491F1E6e5E62f1d8F26062Ee822B40B0E0d4', - name: 'cvxeth', - }, - { - swap: '0xAdCFcf9894335dC340f6Cd182aFA45999F45Fc44', - name: 'xautusd', - }, - { - swap: '0x98638FAcf9a3865cd033F36548713183f6996122', - name: 'spelleth', - }, - { swap: '0x752eBeb79963cf0732E9c0fec72a49FD1DEfAEAC', name: 'teth' }, - // excluding them cause null apy, need to check why - // { swap: '0x1005F7406f32a61BD760CfA14aCCd2737913d546', name: '2pool' }, - // { swap: '0x4e0915C88bC70750D68C481540F081fEFaF22273', name: '4pool' }, - ], -}; diff --git a/src/adaptors/d2-finance/index.js b/src/adaptors/d2-finance/index.js new file mode 100644 index 0000000000..820755874a --- /dev/null +++ b/src/adaptors/d2-finance/index.js @@ -0,0 +1,238 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { gql, GraphQLClient } = require('graphql-request'); +const BigNumber = require('bignumber.js'); +const { differenceInDays } = require('date-fns'); + +const erc4626TotalAssetsAbi = { + inputs: [], + name: 'totalAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const poolAddresses = [ + { + address: '0x27D22Eb71f00495Eccc89Bb02c2B68E6988C6A42', + symbol: 'ETH++', + underlyingAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, + { + address: '0xD1D64dAeED7504Ef3Eb056aa2D973bD064843A84', + symbol: 'd2USDC', + underlyingAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, + { + address: '0xaB2743a3A2e06d457368E901F5f927F271fa1374', + symbol: 'GMX++', + underlyingAsset: '0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a', + }, + { + address: '0x0F76De33a3679a6065D14780618b54584a3907D4', + symbol: 'dgnETHv2', + underlyingAsset: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + { + address: '0xB0730AA7d6e880F901B5d71A971096dB56895a0f', + symbol: 'iARB', + underlyingAsset: '0x912CE59144191C1204E64559FE8253a0e49E6548', + }, + { + address: '0x291344FBaaC4fE14632061E4c336Fe3B94c52320', + symbol: 'ARB++', + underlyingAsset: '0x912CE59144191C1204E64559FE8253a0e49E6548', + }, + { + address: '0x5f44A7DD0a016A5Ec9682df36899A781442CAa43', + symbol: 'dgnARB', + underlyingAsset: '0x912CE59144191C1204E64559FE8253a0e49E6548', + }, + { + address: '0x36b1939ADf539a4AC94b57DBAd32FaEcd5bcF4d0', + symbol: 'PlsDAOPlusv2', + underlyingAsset: '0x912CE59144191C1204E64559FE8253a0e49E6548', + }, + { + address: '0x34F0FdD80A51dfd8bA42343c20F89217280d760E', + symbol: 'Dewhalesv2', + underlyingAsset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, + { + address: '0x195A9E0f29F96d4ab2139ee1272380A4aa352890', + symbol: 'd2ETH', + underlyingAsset: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, +]; + +const formatSecondsToDay = (seconds) => { + const days = differenceInDays(new Date(seconds * 1000), new Date(0)); + return days; +}; + +const fetchVaultData = async (address) => { + const client = new GraphQLClient('https://d2.finance/subgraphs/name/d2'); + const req = gql` + query getVaultData($address: String!) { + epochStarteds( + where: { contract_contains_nocase: $address } + orderBy: blockTimestamp + orderDirection: desc + ) { + epoch + epochEnd + epochStart + fundingStart + } + fundsReturneds( + where: { contract_contains_nocase: $address } + orderBy: blockTimestamp + orderDirection: desc + ) { + amount + epoch + blockTimestamp + } + fundsCustodieds( + where: { contract_contains_nocase: $address } + orderBy: blockTimestamp + orderDirection: desc + ) { + amount + epoch + blockTimestamp + } + } + `; + const response = await client.request(req, { address }); + + return response; +}; + +const getPoolApy = async (pools) => { + const poolPromises = pools.map(async (pool) => { + const { epochStarteds, fundsReturneds, fundsCustodieds } = + await fetchVaultData(pool.address); + const epochAPYs = epochStarteds.map((epoch) => { + const epochStart = Number(epoch.epochStart); + const epochEnd = Number(epoch.epochEnd); + const fundCustody = fundsCustodieds.find((fund) => { + const blockTimestamp = Number(fund.blockTimestamp); + return blockTimestamp > epochStart && blockTimestamp < epochEnd; + }); + if (!fundCustody) { + return 0; + } + const fundReturn = fundsReturneds.find( + (fund) => Number(fund.epoch) === Number(fundCustody.epoch) + ); + if (!fundReturn) { + return 0; + } + const duration = formatSecondsToDay(epochEnd - epochStart); + const APY = BigNumber(fundReturn.amount) + .minus(fundCustody.amount) + .div(fundCustody.amount) + .times(365) + .div(duration); + + return APY.isPositive() ? APY.toNumber() : 0; + }); + + const totalApy = epochAPYs.reduce((sum, epochAPY) => sum + epochAPY, 0); + return { + ...pool, + apy: + (totalApy * 100) / + (fundsReturneds.length === 0 ? 1 : fundsReturneds.length), + }; + }); + return Promise.all(poolPromises); +}; + +const getPoolTvl = async (pools, prices) => { + const { output: outputBalances } = await sdk.api.abi.multiCall({ + abi: erc4626TotalAssetsAbi, + calls: pools.map((pool) => ({ + target: pool.address, + })), + chain: 'arbitrum', + }); + const balances = outputBalances.map((output) => output.output); + return pools.map((pool, index) => { + const priceData = prices.find( + (price) => + price.address.toLowerCase() === pool.underlyingAsset.toLowerCase() + ); + return { + ...pool, + tvlUsd: BigNumber(balances[index]) + .div(BigNumber(10).pow(priceData.decimals)) + .times(priceData.price) + .toNumber(), + }; + }); +}; + +const getUnderlyingAssetData = async () => { + const underlyingAssetAddresses = [ + ...new Set(poolAddresses.map((pool) => pool.underlyingAsset)), + ]; + const { pricesByAddress: prices } = await utils.getPrices( + underlyingAssetAddresses, + 'arbitrum' + ); + const { output: decimalsOutput } = await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: underlyingAssetAddresses.map((address) => ({ + target: address, + })), + chain: 'arbitrum', + }); + const decimals = decimalsOutput.map((output) => output.output); + + const underlyingAsset = underlyingAssetAddresses.map( + (assetAddress, index) => { + return { + address: assetAddress, + price: prices[assetAddress.toLowerCase()], + decimals: decimals[index], + }; + } + ); + return underlyingAsset; +}; + +const poolsFunction = async () => { + const underlyingAssetPrices = await getUnderlyingAssetData(); + const poolsWithBalances = await getPoolTvl( + poolAddresses, + underlyingAssetPrices + ); + const poolsWithApy = await getPoolApy(poolsWithBalances); + const result = poolsWithApy.map(({ address, symbol, tvlUsd, apy }) => { + return { + pool: `${address}-arbitrum`.toLowerCase(), + chain: 'Arbitrum', + project: 'd2-finance', + symbol, + tvlUsd, + apy, + poolMeta: + "Strategy's lock duration is aligned with market opportunities, verifable onchain.", + }; + }); + return result; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://d2.finance', +}; diff --git a/src/adaptors/damm-finance/abis.json b/src/adaptors/damm-finance/abis.json new file mode 100644 index 0000000000..3d0ebd58bd --- /dev/null +++ b/src/adaptors/damm-finance/abis.json @@ -0,0 +1,167 @@ +{ + "getAllMarkets": { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "markets": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + "compSpeeds": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getCash": { + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalBorrows": { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalReserves": { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "borrowRatePerBlock": { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "supplyRatePerBlock": { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "underlying": { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/damm-finance/index.js b/src/adaptors/damm-finance/index.js new file mode 100644 index 0000000000..5a34d9c6e7 --- /dev/null +++ b/src/adaptors/damm-finance/index.js @@ -0,0 +1,231 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const abi = require('./abis.json'); +const utils = require('../utils') + +const unitroller = '0x4F96AB61520a6636331a48A11eaFBA8FB51f74e4'; +const bdAMM = '0xfa372fF1547fa1a283B5112a4685F1358CE5574d'; +const dAMM = '0xb3207935ff56120f3499e8ad08461dd403bf16b8'; + +const poolInfo = async (chain) => { + const allMarkets = await sdk.api.abi.call({ + target: unitroller, + chain, + abi: abi.getAllMarkets, + }); + + const yieldMarkets = allMarkets.output.map((pool) => { + return { pool }; + }); + + const getOutput = ({ output }) => output.map(({ output }) => output); + const [markets, compSpeeds] = await Promise.all( + ['markets', 'compSpeeds'].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + target: unitroller, + calls: yieldMarkets.map((pool) => ({ + params: pool.pool, + })), + chain, + }) + ) + ).then((data) => data.map(getOutput)); + const collateralFactor = markets.map((data) => data.collateralFactorMantissa); + + const [ + borrowRatePerBlock, + supplyRatePerBlock, + getCash, + totalBorrows, + totalReserves, + underlyingToken, + tokenSymbol, + ] = await Promise.all( + [ + 'borrowRatePerBlock', + 'supplyRatePerBlock', + 'getCash', + 'totalBorrows', + 'totalReserves', + 'underlying', + 'symbol', + ].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: yieldMarkets.map((address) => ({ + target: address.pool, + })), + chain, + }) + ) + ).then((data) => data.map(getOutput)); + + const underlyingTokenDecimals = ( + await sdk.api.abi.multiCall({ + abi: abi.decimals, + calls: underlyingToken.map((token) => ({ + target: token, + })), + chain, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + const price = await getPrices('ethereum', underlyingToken); + + yieldMarkets.map((data, i) => { + data.collateralFactor = collateralFactor[i]; + data.borrowRate = borrowRatePerBlock[i]; + data.supplyRate = supplyRatePerBlock[i]; + data.compSpeeds = compSpeeds[i]; + data.getCash = getCash[i]; + data.totalBorrows = totalBorrows[i]; + data.totalReserves = totalReserves[i]; + data.underlyingToken = underlyingToken[i]; + data.tokenSymbol = tokenSymbol[i]; + data.price = price[underlyingToken[i].toLowerCase()]; + data.underlyingTokenDecimals = underlyingTokenDecimals[i]; + }); + + return { yieldMarkets }; +}; + +const getPrices = async (chain, addresses) => { + const uri = `${addresses.map((address) => `${chain}:${address}`)}`; + const prices = ( + await superagent.get('https://coins.llama.fi/prices/current/' + uri) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +function calculateApy(rate, price = 1, tvl = 1) { + // supply rate per block * number of blocks per year + const BLOCK_TIME = 12; + const YEARLY_BLOCKS = (365 * 24 * 60 * 60) / BLOCK_TIME; + const safeTvl = tvl === 0 ? 1 : tvl; + const apy = (((rate / 1e18) * YEARLY_BLOCKS * price) / safeTvl) * 100; + return apy; +} + +function calculateTvl(cash, borrows, reserves, price, decimals) { + // ( cash + totalBorrows - reserve value ) * underlying price = balance + const tvl = + ((parseFloat(cash) + parseFloat(borrows) - parseFloat(reserves)) / + decimals) * + price; + return tvl; +} + +const getApy = async () => { + const prices = await getPrices(['ethereum'], [bdAMM, dAMM]); + + const bdammPrice = prices[bdAMM.toLowerCase()]; + const dammPrice = prices[dAMM.toLowerCase()]; + + // const discountRatio = bdammPrice / dammPrice + // hardcoding this. need to see how they derive their bdammPrices... + const discountRate = 0.05; + + const yieldMarkets = (await poolInfo('ethereum')).yieldMarkets; + + const symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: yieldMarkets.map((p) => ({ target: p.underlyingToken })), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const yieldPools = yieldMarkets.map((pool, i) => { + const totalSupplyUsd = calculateTvl( + pool.getCash, + pool.totalBorrows, + pool.totalReserves, + pool.price, + pool.underlyingTokenDecimals + ); + const totalBorrowUsd = calculateTvl( + 0, + pool.totalBorrows, + 0, + pool.price, + pool.underlyingTokenDecimals + ); + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + const apyBase = calculateApy(pool.supplyRate); + const apyReward = calculateApy(pool.compSpeeds, bdammPrice, totalSupplyUsd); + const apyBaseBorrow = calculateApy(pool.borrowRate); + const apyRewardBorrow = calculateApy( + pool.compSpeeds, + bdammPrice, + totalBorrowUsd + ); + const ltv = parseInt(pool.collateralFactor) / 1e18; + const readyToExport = exportFormatter( + pool.pool, + 'Ethereum', + symbol[i], + tvlUsd, + apyBase, + apyReward * discountRate, + pool.underlyingToken, + [bdAMM], + apyBaseBorrow, + apyRewardBorrow * discountRate, + totalSupplyUsd, + totalBorrowUsd, + ltv + ); + return readyToExport; + }); + + return yieldPools.filter(i => utils.keepFinite(i)); +}; + +function exportFormatter( + pool, + chain, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv +) { + return { + pool: `${pool}-${chain}`.toLowerCase(), + chain, + project: 'damm-finance', + symbol, + tvlUsd, + apyBase, + // apyReward, + underlyingTokens: [underlyingTokens], + // rewardTokens, + // apyBaseBorrow, + // apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + }; +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.damm.finance/dashboard', +}; diff --git a/src/adaptors/daolama/index.js b/src/adaptors/daolama/index.js new file mode 100644 index 0000000000..8a05c32822 --- /dev/null +++ b/src/adaptors/daolama/index.js @@ -0,0 +1,145 @@ +const { TonClient } = require('@ton/ton'); +const { Address, Cell, Slice, Dictionary, beginCell } = require('@ton/core'); +const utils = require('../utils'); +const PROTOCOL_FEE_BITS = 16; +const PROTOCOL_FEE_BASE = 1000; + +function parseAssetConfig(assetConfigCell) { + const assetConfigSlice = assetConfigCell.beginParse(); + + return { + supplyAmountMax: assetConfigSlice.loadCoins(), + protocolFee: assetConfigSlice.loadUint(PROTOCOL_FEE_BITS) / PROTOCOL_FEE_BASE, + } +} + +function parsePoolData(dataBOC) { + const dataSlice = Cell.fromBase64(dataBOC).beginParse(); + + dataSlice.loadRef() + const { protocolFee: protocolFeeRate, supplyAmountMax } = parseAssetConfig(dataSlice.loadRef()); + const halted = dataSlice.loadBit(); + const balance = dataSlice.loadCoins(); + const borrowed = dataSlice.loadCoins(); + const lpJettonSupply = dataSlice.loadCoins(); + return { + halted, + balance, + borrowed, + lpJettonSupply, + protocolFeeRate, + supplyAmountMax, + } +} + +async function getContractStateWithRetry(client, address, maxRetries = 3, initialDelay = 500) { + let attempts = 0; + + while (attempts < maxRetries) { + try { + return await client.getContractState(address); + } catch (err) { + if (err.message?.includes('429') || err.code === 429) { + attempts++; + const delay = initialDelay * 2 ** (attempts - 1); + console.warn( + `Rate limit (429) encountered. Retrying in ${delay} ms... (attempt ${attempts} of ${maxRetries})` + ); + await new Promise((resolve) => setTimeout(resolve, delay)); + } else { + throw err; + } + } + } + + throw new Error(`Max retries (${maxRetries}) exceeded while getting contract state for address ${address}.`); +} + +async function getPoolData( + client, + poolAddress, + token, + tokenSymbol, + price, + scale, + poolName, + borrowRate +) { + let data; + try { + const result = await getContractStateWithRetry( + client, + Address.parse(poolAddress), + 5, // maxRetries + 500 // initialDelay in ms + ); + if (!result?.data) { + throw new Error('Master data not found'); + } + + data = parsePoolData(result.data.toString('base64')); + } catch (error) { + console.error('getPoolData error:', error); + return; + } + + const totalSupply = Number(data.balance + data.borrowed) / scale; + const totalBorrow = Number(data.borrowed) / scale; + const totalSupplyUsd = (totalSupply * price); + const totalBorrowUsd = (totalBorrow * price); + const utilization = totalSupply > 0 ? totalBorrow / totalSupply : 0; + const supplyRate = borrowRate * utilization * (1 - data.protocolFeeRate); + const supplyApy = (1 + supplyRate) ** 365 - 1; + const borrowApy = (1 + borrowRate) ** 365 - 1; + + console.log(poolName, tokenSymbol, 'totalSupplyInUsd', totalSupplyUsd); + console.log(poolName, tokenSymbol, 'totalBorrowInUsd', totalBorrowUsd); + console.log(poolName, tokenSymbol, 'supplyApy', supplyApy * 100); + console.log(poolName, tokenSymbol, 'borrowApy', borrowApy * 100); + + return { + pool: `daolama-${poolAddress}-${poolName}-ton`.toLowerCase(), + chain: 'Ton', + project: 'daolama', + symbol: tokenSymbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyApy * 100, + apyBaseBorrow: borrowApy * 100, + underlyingTokens: [token], + totalSupplyUsd, + totalBorrowUsd, + poolMeta: poolName, + url: `https://app.daolama.co/yield`, + }; +} + +async function getApy() { + const TON = 'ton:EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c'; + const price = async (token) => (await utils.getData(`https://coins.llama.fi/prices/current/${token}`)).coins[token].price; + const tonPrice = await price(TON); + const borrowRate = (await utils.getData('https://api.daolama.co/api/v1/analytics/borrowed/rate')).value; + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + }); + + const poolData = await Promise.all([ + getPoolData( + client, + 'EQCkeTvOSTBwBtP06X2BX7THj_dlX67PhgYRGuKfjWtB9FVb', + 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', + 'TON', + tonPrice, + 1e9, + 'Main', + borrowRate, + ), + ]); + + return poolData.filter((pool) => pool !== undefined); +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://daolama.co/', +}; \ No newline at end of file diff --git a/src/adaptors/davos-protocol/index.js b/src/adaptors/davos-protocol/index.js new file mode 100644 index 0000000000..2a9b8879b8 --- /dev/null +++ b/src/adaptors/davos-protocol/index.js @@ -0,0 +1,206 @@ +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; +const RAY_PRECISION = 27; +const RAY = new BigNumber(10).pow(RAY_PRECISION); + +const WMATIC = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270'; +const ANKRMATIC = `0x0E9b89007eEE9c958c0EDA24eF70723C2C93dD58`; +const ceaaMATICcAddress = '0xa6aE8F29e0031340eA5dBE11c2DA4466cDe34464'; +const DAVOSJoin = '0x8FCD9542a6Ee0F05f470230da5B8cB41033da6Df'; +const DAVOS = '0xEC38621e72D86775a89C7422746de1f52bbA5320'; +const sDAVOS = '0xE69a1876bdACfa7A7a4F6D531BE2FDE843D2165C'; + +const pool = + '0x63654d4154494300000000000000000000000000000000000000000000000000'; +const JUG = { + address: '0xc5a7344461EEc05e174aa8AC4e4030b24aA02EBD', + abis: { + ilks: { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'ilks', + outputs: [ + { + internalType: 'uint256', + name: 'duty', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rho', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const SPOT = { + address: '0xF97680e99Be42daCCEA9fe6f9F9aa385ccf97a62', + abis: { + ilks: { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'ilks', + outputs: [ + { + internalType: 'contract PipLike', + name: 'pip', + type: 'address', + }, + { + internalType: 'uint256', + name: 'mat', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const JAR = { + address: sDAVOS, + abis: { + rate: { + inputs: [], + name: 'rate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const getApy = async () => { + const baseRataCall = ( + await sdk.api.abi.call({ + target: JUG.address, + params: pool, + abi: JUG.abis.ilks, + chain: 'polygon', + }) + ).output; + + const spot = ( + await sdk.api.abi.call({ + target: SPOT.address, + params: pool, + abi: SPOT.abis.ilks, + chain: 'polygon', + }) + ).output; + + const davosTotalSupply = ( + await sdk.api.abi.call({ + target: DAVOS, + abi: 'erc20:totalSupply', + chain: 'polygon', + }) + ).output; + + const davosRate = ( + await sdk.api.abi.call({ + target: sDAVOS, + abi: JAR.abis.rate, + chain: 'polygon', + }) + ).output; + + const dMATICTotalSupply = ( + await sdk.api.abi.call({ + target: sDAVOS, + abi: 'erc20:totalSupply', + chain: 'polygon', + }) + ).output; + + const collateral = ( + await sdk.api.abi.call({ + target: ceaaMATICcAddress, + abi: 'erc20:balanceOf', + params: ['0x29Ded4C99690968562f2D067968aA72b7d46A65D'], + chain: 'polygon', + }) + ).output; + + const coins = [ + `polygon:${DAVOS}`, + `polygon:${WMATIC}`, + `polygon:${ANKRMATIC}`, + ] + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const davosPrice = prices[`polygon:${DAVOS.toLowerCase()}`]?.price; + const wmaticPrice = prices[`polygon:${WMATIC.toLowerCase()}`]?.price; + + if (!davosPrice || !wmaticPrice) { + console.warn('Missing prices for davos-protocol:', { davosPrice, wmaticPrice }); + return []; + } + + const baseRata = baseRataCall.duty; + const normalizRate = new BigNumber(baseRata).dividedBy(RAY); + BigNumber.config({ POW_PRECISION: 100 }); + const stabilityFee = normalizRate.pow(SECONDS_PER_YEAR).minus(1); + const totalSupplyUsd = + (Number(davosTotalSupply) / 1e18) * davosPrice; + const liquidationRatio = new BigNumber(spot.mat).div(1e27); + return [ + { + pool: ceaaMATICcAddress, + project: 'davos-protocol', + symbol: 'MATIC', + chain: 'polygon', + apy: 0, + tvlUsd: + (Number(collateral) / 1e18) * wmaticPrice, + apyBaseBorrow: stabilityFee.toNumber() * 100, + totalSupplyUsd: + (Number(collateral) / 1e18) * wmaticPrice, + totalBorrowUsd: totalSupplyUsd, + ltv: 1 / Number(liquidationRatio.toNumber()), + mintedCoin: 'DUSD', + }, + { + pool: sDAVOS, + project: 'davos-protocol', + symbol: 'DUSD', + chain: 'polygon', + apy: new BigNumber(davosRate) + .times(SECONDS_PER_YEAR) + .div(dMATICTotalSupply) + .times(100) + .toNumber(), + tvlUsd: + (Number(dMATICTotalSupply) / 1e18) * davosPrice, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://davos.xyz/', +}; diff --git a/src/adaptors/dedust/index.js b/src/adaptors/dedust/index.js new file mode 100644 index 0000000000..c0e82c990e --- /dev/null +++ b/src/adaptors/dedust/index.js @@ -0,0 +1,226 @@ +const utils = require('../utils'); + +// ignore pools with TVL below the threshold +const MIN_TVL_USD = 100000; +// LPs get 80% of fees +const FEES_PERCENT_TO_LP = 0.8; +const GRAPHQL_ENDPOINT = 'https://api.dedust.io/v3/graphql'; +const BOOSTS_QUERY = ` +query GetBoosts { + boosts { + asset + budget + endAt + liquidityPool + rewardPerDay + startAt + } + } +`; + +const POOLS_QUERY = ` +query GetPools($filter: PoolsFiltersInput) { + pools(filter: $filter) { + address + totalSupply + type + tradeFee + assets + reserves + fees + volume + } + } + +`; + +const ASSETS_QUERY = ` +query GetAssets { + assets { + type + address + name + symbol + image + decimals + aliased + price + source { + chain + address + bridge + symbol + name + } + } + } + +`; + +const formatAddress = (addr) => { + if (addr == 'native') { + return '0x0000000000000000000000000000000000000000'; + } else if (addr.startsWith('jetton:')) { + return addr.slice(7); + } else { + return addr; + } +} + +const getApy = async () => { + // console.log("Requesting pools list") + // const pool_list = (await utils.getData('https://api.ston.fi/v1/pools')).pool_list; + console.log("Requesting assets list") + const assetsList = (await utils.getData(GRAPHQL_ENDPOINT, { + query: ASSETS_QUERY, + operationName: 'GetAssets' + })).data.assets; + + const assetInfo = {}; + for (const asset of assetsList) { + const address = asset.type == 'native' ? 'native' : 'jetton:' + asset.address; + assetInfo[address] = { + decimals: asset.decimals, + price: Number(asset.price), + symbol: asset.symbol + } + } + console.log(`Inited ${Object.keys(assetInfo).length} assets`); + + console.log("Requesting pools list") + const poolsList = (await utils.getData(GRAPHQL_ENDPOINT, { + query: POOLS_QUERY, + operationName: 'GetPools' + })).data.pools; + + const poolsInfo = {}; + for (const pool of poolsList) { + const address = pool.address; + const leftAddr = pool.assets[0]; + const rightAddr = pool.assets[1]; + if (!(leftAddr in assetInfo && rightAddr in assetInfo)) { + console.warn("No assets info for pool", pool); + continue; + } + const left = assetInfo[leftAddr]; + const right = assetInfo[rightAddr]; + + const tvl = left.price * Number(pool.reserves[0]) / Math.pow(10, left.decimals) + + right.price * Number(pool.reserves[1]) / Math.pow(10, right.decimals); + if (tvl < MIN_TVL_USD) { + continue + } + + // use apropriate base-quote order + let symbol = ''; + if (left.symbol == 'USDT') { + symbol = `${right.symbol}-${left.symbol}` + } else if (right.symbol == 'USDT') { + symbol = `${left.symbol}-${right.symbol}` + } else if (left.symbol == 'TON') { + symbol = `${right.symbol}-${left.symbol}` + } else { + symbol = `${left.symbol}-${right.symbol}` + } + + // estimate daily feees based on the token prices + const feesDaily = (left.price * Number(pool.fees[0]) / Math.pow(10, left.decimals) + + right.price * Number(pool.fees[1]) / Math.pow(10, right.decimals)) / 2; + + // FEES_PERCENT_TO_LP is a share of fees to LP, so estimate APY based on in + const apyBase = Math.pow((1 + FEES_PERCENT_TO_LP * feesDaily / tvl), 365) - 1; + + poolsInfo[pool.address] = { + symbol: symbol, + tvl: tvl, + apyBase: apyBase, + underlyingTokens: [formatAddress(leftAddr), formatAddress(rightAddr)] + } + } + console.log(`Inited ${Object.keys(poolsInfo).length} pools`); + + console.log("Requesting boosts list"); + const boostsList = (await utils.getData(GRAPHQL_ENDPOINT, { + query: BOOSTS_QUERY, + operationName: 'GetBoosts' + })).data.boosts; + + // rewards in USD per pool for each token + const rewardsPerPool = {}; + for (const boost of boostsList) { + // console.log(boost) + if (!(boost.asset in assetInfo)) { + console.warn("Boosted asset not in assets list", boost); + continue; + } + const asset = assetInfo[boost.asset]; + // estimate daily rewards in USD + const rewardDaily = asset.price * Number(boost.rewardPerDay) / Math.pow(10, asset.decimals); + if (!(boost.liquidityPool in rewardsPerPool)) { + rewardsPerPool[boost.liquidityPool] = {} + } + if (!(boost.asset in rewardsPerPool[boost.liquidityPool])) { + rewardsPerPool[boost.liquidityPool][boost.asset] = 0; + } + rewardsPerPool[boost.liquidityPool][boost.asset] += rewardDaily; + } + + // boosted APY dictionary, includes reward APY(actually it is APR) and rewards tokens + const boostedApy = {}; + + for (const address in rewardsPerPool) { + if (!(address in poolsInfo)) { + console.warn("No pool data for boosted pool", address); + continue; + } + + const pool = rewardsPerPool[address]; + // console.log(pool) + let totalRewards = 0; + let rewardTokens = []; + for (const reward of Object.values(pool)) { + totalRewards += reward; + } + + // filter out tokens without significant impact + for (const token of Object.keys(pool)) { + const impact = pool[token]; + if (impact > totalRewards * 0.2) { + rewardTokens.push(formatAddress(token)) + } + } + // using APR formula because it is not auto-compounding + const apyReward = 365 * totalRewards / poolsInfo[address].tvl; + boostedApy[address] = { + apyReward: 100 * apyReward, + rewardTokens: rewardTokens + } + console.log(rewardTokens) + } + // console.log(boostedApy) + + const pools = Object.keys(poolsInfo) + .map((pool_address) => { + const pool = poolsInfo[pool_address]; + const boost = boostedApy[pool_address]; + return { + pool: `${pool_address}-ton`.toLowerCase(), + chain: 'Ton', + project: 'dedust', + symbol: pool.symbol, + tvlUsd: pool.tvl, + apyBase: 100 * pool.apyBase, + apyReward: boost?.apyReward, + rewardTokens: boost?.rewardTokens, + underlyingTokens: pool.underlyingTokens, + url: `https://dedust.io/pools/${pool_address}` + }; + }).filter((pool) => pool != null); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://dedust.io/', +}; diff --git a/src/adaptors/defi.money/index.js b/src/adaptors/defi.money/index.js new file mode 100644 index 0000000000..f941b6561d --- /dev/null +++ b/src/adaptors/defi.money/index.js @@ -0,0 +1,95 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); + +const SMONEY_CONTRACT = '0x4626C0D31c52991573DDd4dF8F2bB1Bc5101284F'; +const MONEY_CONTRACT = '0x69420f9E38a4e60a62224C489be4BF7a94402496'; + +const abi = { + rewardsPerSecond: { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + totalStoredAssets: { + "inputs": [], + "name": "totalStoredAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + totalStoredAssets: { + "inputs": [], + "name": "totalStoredAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + totalCooldownAssets: { + "inputs": [], + "name": "totalCooldownAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, +}; + +const fetchSmoneyAPI = async () => { + const chain = 'optimism'; + + const [ + rewardsPerSecond, + totalStoredAssets, + totalCooldownAssets, + ] = await Promise.all([ + sdk.api.abi.call({ + target: SMONEY_CONTRACT, + abi: abi.rewardsPerSecond, + chain: chain, + }), + sdk.api.abi.call({ + target: SMONEY_CONTRACT, + abi: abi.totalStoredAssets, + chain: chain, + }), + sdk.api.abi.call({ + target: SMONEY_CONTRACT, + abi: abi.totalCooldownAssets, + chain: chain, + }), + ]); + + const apy = BigNumber(rewardsPerSecond.output) + .times(86400) + .times(365) + .div(totalStoredAssets.output) + .times(100) + .toNumber() + + const tvlUsd = BigNumber(totalStoredAssets.output) + .plus(totalCooldownAssets.output) + .div(1e18) + .toNumber(); + + const sMoneyPool = { + pool: `${SMONEY_CONTRACT}-${chain}`, + chain: utils.formatChain(chain), + project: 'defi.money', + symbol: utils.formatSymbol('sMONEY'), + tvlUsd, + apyBase: apy, + underlyingTokens: [MONEY_CONTRACT], + poolMeta: '7 day withdrawal cooldown', + url: `https://app.defi.money/earn/${chain}`, + }; + + return [sMoneyPool]; +}; + +module.exports = { + timetravel: false, + apy: fetchSmoneyAPI, + url: 'https://app.defi.money/earn/optimism', +}; \ No newline at end of file diff --git a/src/adaptors/defichain-dex/index.js b/src/adaptors/defichain-dex/index.js new file mode 100644 index 0000000000..48bad6b157 --- /dev/null +++ b/src/adaptors/defichain-dex/index.js @@ -0,0 +1,26 @@ +const utils = require('../utils'); + +const API_URL = 'https://ocean.defichain.com/v0/mainnet/poolpairs?size=200'; + +const getApy = async () => { + const poolsData = await utils.getData(API_URL); + + const pools = poolsData.data.map((pool) => ({ + pool: `${pool.symbol}-defichain`, + chain: utils.formatChain('defichain'), + project: 'defichain-dex', + symbol: pool.symbol, + tvlUsd: Number(pool.totalLiquidity.usd) || 0, + apyBase: pool.apr.commission * 100, + apyReward: pool.apr.reward * 100, + rewardTokens: ['DFI'], + })); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://defichain.com/dex', +}; diff --git a/src/adaptors/deficurrent/abi.json b/src/adaptors/deficurrent/abi.json new file mode 100644 index 0000000000..5e5ca15be8 --- /dev/null +++ b/src/adaptors/deficurrent/abi.json @@ -0,0 +1,28 @@ +{ + "balance": { + "name": "balance", + "type": "function", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + "want": { + "name": "want", + "type": "function", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + } +} diff --git a/src/adaptors/deficurrent/index.js b/src/adaptors/deficurrent/index.js new file mode 100644 index 0000000000..b307919017 --- /dev/null +++ b/src/adaptors/deficurrent/index.js @@ -0,0 +1,87 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const axios = require('axios'); + +const url = 'https://api.shipyard.finance'; +const urlVaults = `${url}/vaults`; + +const DIC_CHAIN_ID_AND_NAME = { + 43114: 'avax', +}; + +const getChainName = (chainId, chainName) => { + return DIC_CHAIN_ID_AND_NAME[chainId] || chainName; +}; + +const getVaultTvl = async (vaults) => { + const dicVaultIdAndResult = {}; + const coins = []; + + for (const vault of vaults) { + const chain = getChainName(vault.chainId, vault.chain); + coins.push(`${chain}:${vault.tokenAddress}`.toLowerCase()); + } + + const coinsData = ( + await axios.get(`https://coins.llama.fi/prices/current/${coins}`) + ).data.coins; + + for (const vault of vaults) { + const want = vault.tokenAddress; + const chain = getChainName(vault.chainId, vault.chain); + + const vaultBalance = ( + await sdk.api.abi.call({ + target: vault.vaultAddress, + abi: abi.balance, + chain, + }) + ).output; + + const coinId = `${chain}:${want}`.toLowerCase(); + + const coinDecimals = coinsData[coinId].decimals; + const coinPrice = coinsData[coinId].price; + + dicVaultIdAndResult[vault.id] = + vaultBalance * (coinPrice / 10 ** coinDecimals); + } + + return dicVaultIdAndResult; +}; + +const main = async () => { + const vaults = (await axios.get(urlVaults)).data; + + const dicVaultAndTvl = await getVaultTvl(vaults); + + const promised = vaults + + .map(async (vault) => { + const chain = vault.chain; + const platform = vault.platform; + + return { + apy: vault.status === 'active' ? 100 * vault.totalApy : 0, + chain: utils.formatChain(chain), + pool: `${vault.shipTokenAddress}-${chain}`.toLowerCase(), + poolMeta: platform === undefined ? null : utils.formatChain(platform), + project: 'deficurrent', + symbol: utils.formatSymbol(vault.id.split('-').slice(1).join('-')), + tvlUsd: dicVaultAndTvl[vault.id], + }; + }) + + .filter((item) => item !== null) + + .flatMap((item) => item); + + return Promise.all(promised); +}; + +module.exports = { + timetravel: false, + apy: main, + url, +}; diff --git a/src/adaptors/degenprime/index.js b/src/adaptors/degenprime/index.js new file mode 100644 index 0000000000..adbae78d84 --- /dev/null +++ b/src/adaptors/degenprime/index.js @@ -0,0 +1,293 @@ +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); + +const utils = require('../utils'); +const getPoolDepositRateAbi = { + inputs: [], + name: 'getDepositRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getPoolTotalSupplyAbi = { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getPoolBoostRateAbi = { + inputs: [], + name: 'rewardRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getBoostRewardTokenAbi = { + inputs: [], + name: 'rewardToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +// Base Chain Pools +const USDC_POOL_TUP_CONTRACT = '0x2Fc7641F6A569d0e678C473B95C2Fc56A88aDF75'; +const AERO_POOL_TUP_CONTRACT = '0x4524D39Ca5b32527E7AF6c288Ad3E2871B9f343B'; +const BTC_POOL_TUP_CONTRACT = '0xCA8C954073054551B99EDee4e1F20c3d08778329'; +const ETH_POOL_TUP_CONTRACT = '0x81b0b59C7967479EC5Ce55cF6588bf314C3E4852'; +const BRETT_POOL_TUP_CONTRACT = '0x6c307F792FfDA3f63D467416C9AEdfeE2DD27ECF'; +const KAITO_POOL_TUP_CONTRACT = '0x293E41F1405Dde427B41c0074dee0aC55D064825'; +const DOGE_POOL_TUP_CONTRACT = '0xAf61B10BDB78e31fdbC5Da4e57d60e32aFe468B9'; +const XRP_POOL_TUP_CONTRACT = '0x056076e717332403Bc23B2D4F6D87683ceF582B9'; + +// Token Addresses +const AERO_TOKEN_ADDRESS = '0x940181a94A35A4569E4529A3CDfB74e38FD98631'; +const USDC_TOKEN_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; +const BRETT_TOKEN_ADDRESS = '0x532f27101965dd16442E59d40670FaF5eBB142E4'; +const BTC_TOKEN_ADDRESS = '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf'; +const ETH_TOKEN_ADDRESS = '0x4200000000000000000000000000000000000006'; +const DEGEN_TOKEN_ADDRESS = '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed'; +const KAITO_TOKEN_ADDRESS = '0x98d0baa52b2D063E780DE12F615f963Fe8537553'; +const DOGE_TOKEN_ADDRESS = '0xcbD06E5A2B0C65597161de254AA074E489dEb510'; +const XRP_TOKEN_ADDRESS = '0xcb585250f852C6c6bf90434AB21A00f02833a4af'; + + +const getPoolTVL = async (poolAddress, chain = 'base') => { + return ( + await sdk.api.abi.call({ + abi: getPoolTotalSupplyAbi, + chain: chain, + target: poolAddress, + params: [], + }) + ).output; +}; + +const getTokenPrice = async (tokenAddress, chain = 'base') => { + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${chain}:${tokenAddress}` + ); + return data.coins[Object.keys(data.coins)[0]].price; +}; + +const getPoolDepositRate = async (poolAddress, chain = 'base') => { + return ( + await sdk.api.abi.call({ + abi: getPoolDepositRateAbi, + chain: chain, + target: poolAddress, + params: [], + }) + ).output; +}; + +const getDogePoolDepositRate = async () => { + return (await getPoolDepositRate(DOGE_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getXrpPoolDepositRate = async () => { + return (await getPoolDepositRate(XRP_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getBtcPoolDepositRate = async () => { + return (await getPoolDepositRate(BTC_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getEthPoolDepositRate = async () => { + return (await getPoolDepositRate(ETH_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getUsdcPoolDepositRate = async () => { + return (await getPoolDepositRate(USDC_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getBrettPoolDepositRate = async () => { + return (await getPoolDepositRate(BRETT_POOL_TUP_CONTRACT)) / 1e16; +}; +const getAeroPoolDepositRate = async () => { + return (await getPoolDepositRate(AERO_POOL_TUP_CONTRACT)) / 1e16; +}; +const getKaitoPoolDepositRate = async () => { + return (await getPoolDepositRate(KAITO_POOL_TUP_CONTRACT)) / 1e16; +}; + +const getDogePoolTVL = async () => { + const supply = await getPoolTVL(DOGE_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(DOGE_TOKEN_ADDRESS); + return (supply * price) / 1e8; +}; + +const getXrpPoolTVL = async () => { + const supply = await getPoolTVL(XRP_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(XRP_TOKEN_ADDRESS); + return (supply * price) / 1e6; +}; + +const getBtcPoolTVL = async () => { + const supply = await getPoolTVL(BTC_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(BTC_TOKEN_ADDRESS); + return (supply * price) / 1e8; +}; + +const getEthPoolTVL = async () => { + const supply = await getPoolTVL(ETH_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(ETH_TOKEN_ADDRESS); + return (supply * price) / 1e18; +}; + +const getKaitoPoolTVL = async () => { + const supply = await getPoolTVL(KAITO_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(KAITO_TOKEN_ADDRESS); + return (supply * price) / 1e18; +}; + +const getBrettPoolTVL = async () => { + const supply = await getPoolTVL(BRETT_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(BRETT_TOKEN_ADDRESS); + return (supply * price) / 1e18; +}; + +const getUsdcPoolTVL = async () => { + const supply = await getPoolTVL(USDC_POOL_TUP_CONTRACT); + const price = await getTokenPrice(USDC_TOKEN_ADDRESS); + return (supply * price) / 1e6; +}; + +const getAeroPoolTVL = async () => { + const supply = await getPoolTVL(AERO_POOL_TUP_CONTRACT); + const price = await getTokenPrice(AERO_TOKEN_ADDRESS); + return (supply * price) / 1e18; +}; + +const getPoolsAPYs = async () => { + const dogePoolTvl = await getDogePoolTVL(); + const dogePool = { + pool: `dgp-${DOGE_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('cbDOGE'), + tvlUsd: dogePoolTvl, + apyBase: await getDogePoolDepositRate(), + underlyingTokens: [DOGE_TOKEN_ADDRESS], + }; + + const xrpPoolTvl = await getXrpPoolTVL(); + const xrpPool = { + pool: `dgp-${XRP_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('cbXRP'), + tvlUsd: xrpPoolTvl, + apyBase: await getXrpPoolDepositRate(), + underlyingTokens: [XRP_TOKEN_ADDRESS], + }; + + const usdcPoolTvl = await getUsdcPoolTVL(); + const usdcPool = { + pool: `dgp-${USDC_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('USDC'), + tvlUsd: usdcPoolTvl, + apyBase: await getUsdcPoolDepositRate(), + underlyingTokens: [USDC_TOKEN_ADDRESS], + }; + + const aeroPoolTvl = await getAeroPoolTVL(); + const aeroPool = { + pool: `dgp-${AERO_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('AERO'), + tvlUsd: aeroPoolTvl, + apyBase: await getAeroPoolDepositRate(), + underlyingTokens: [AERO_TOKEN_ADDRESS], + }; + + const brettPoolTvl = await getBrettPoolTVL(); + const brettPool = { + pool: `dgp-${BRETT_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('BRETT'), + tvlUsd: brettPoolTvl, + apyBase: await getBrettPoolDepositRate(), + underlyingTokens: [BRETT_TOKEN_ADDRESS], + }; + + const btcPoolTvl = await getBtcPoolTVL(); + const btcPool = { + pool: `dgp-${BTC_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('cbBTC'), + tvlUsd: btcPoolTvl, + apyBase: await getBtcPoolDepositRate(), + underlyingTokens: [BTC_TOKEN_ADDRESS], + }; + + const ethPoolTvl = await getEthPoolTVL(); + const ethPool = { + pool: `dgp-${ETH_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('WETH'), + tvlUsd: ethPoolTvl, + apyBase: await getEthPoolDepositRate(), + underlyingTokens: [ETH_TOKEN_ADDRESS], + }; + + const kaitoPoolTvl = await getKaitoPoolTVL(); + const kaitoPool = { + pool: `dgp-${KAITO_TOKEN_ADDRESS}-base`, + chain: utils.formatChain('base'), + project: 'degenprime', + symbol: utils.formatSymbol('KAITO'), + tvlUsd: kaitoPoolTvl, + apyBase: await getKaitoPoolDepositRate(), + underlyingTokens: [KAITO_TOKEN_ADDRESS], + }; + + return [usdcPool, brettPool, aeroPool, btcPool, ethPool, kaitoPool, dogePool, xrpPool]; +}; + +module.exports = { + timetravel: false, + start: 27707209, + apy: getPoolsAPYs, + url: 'https://app.degenprime.io/#/pools', +}; diff --git a/src/adaptors/deltaprime/index.js b/src/adaptors/deltaprime/index.js new file mode 100644 index 0000000000..3bce20c821 --- /dev/null +++ b/src/adaptors/deltaprime/index.js @@ -0,0 +1,348 @@ +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch') + +const utils = require('../utils'); +const getPoolDepositRateAbi = { + "inputs": [], + "name": "getDepositRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +} + +const getPoolTotalSupplyAbi = { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +} + +const getPoolBoostRateAbi = { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +} + +const getBoostRewardTokenAbi = { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" +} + +// Avalanche +const USDC_POOL_TUP_CONTRACT = '0x8027e004d80274FB320e9b8f882C92196d779CE8'; +const USDT_POOL_TUP_CONTRACT = '0x1b6D7A6044fB68163D8E249Bce86F3eFbb12368e'; +const WAVAX_POOL_TUP_CONTRACT = '0xaa39f39802F8C44e48d4cc42E088C09EDF4daad4'; +const BTC_POOL_TUP_CONTRACT = '0x70e80001bDbeC5b9e932cEe2FEcC8F123c98F738'; +const ETH_POOL_TUP_CONTRACT = '0x2A84c101F3d45610595050a622684d5412bdf510'; + +const WAVAX_TOKEN_ADDRESS = '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'; +const USDC_TOKEN_ADDRESS = '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'; +const USDT_TOKEN_ADDRESS = '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7'; +const BTC_TOKEN_ADDRESS = '0x152b9d0FdC40C096757F570A51E494bd4b943E50'; +const ETH_TOKEN_ADDRESS = '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab'; + +const GGAVAX_TOKEN_ADDRESS = '0xA25EaF2906FA1a3a13EdAc9B9657108Af7B703e3'; +const SAVAX_TOKEN_ADDRESS = '0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE'; + +// Arbitrum +const USDC_POOL_TUP_ARBI_CONTRACT = '0x8Ac9Dc27a6174a1CC30873B367A60AcdFAb965cc'; +const ETH_POOL_TUP_ARBI_CONTRACT = '0x788A8324943beb1a7A47B76959E6C1e6B87eD360'; +const ARB_POOL_TUP_ARBI_CONTRACT = '0xC629E8889350F1BBBf6eD1955095C2198dDC41c2'; +const BTC_POOL_TUP_ARBI_CONTRACT = '0x0ed7B42B74F039eda928E1AE6F44Eed5EF195Fb5'; +const DAI_POOL_TUP_ARBI_CONTRACT = '0xFA354E4289db87bEB81034A3ABD6D465328378f1'; + +const USDC_TOKEN_ARBI_ADDRESS = '0xaf88d065e77c8cc2239327c5edb3a432268e5831'; +const ETH_TOKEN_ARBI_ADDRESS = '0x82af49447d8a07e3bd95bd0d56f35241523fbab1'; +const ARB_TOKEN_ARBI_ADDRESS = '0x912CE59144191C1204E64559FE8253a0e49E6548'; +const BTC_TOKEN_ARBI_ADDRESS = '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f'; +const DAI_TOKEN_ARBI_ADDRESS = '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1'; + +const getPoolTVL = async (poolAddress, chain = 'avax') => { + return (await sdk.api.abi.call({ + abi: getPoolTotalSupplyAbi, + chain: chain, + target: poolAddress, + params: [], + })).output; +} + +const getTokenPrice = async (tokenAddress, chain='avax') => { + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${chain}:${tokenAddress}` + ); + return data.coins[Object.keys(data.coins)[0]].price +} + +const getPoolDepositRate = async (poolAddress, chain = 'avax') => { + return (await sdk.api.abi.call({ + abi: getPoolDepositRateAbi, + chain: chain, + target: poolAddress, + params: [], + })).output; +} + +const getBtcPoolDepositRate = async () => { + return await getPoolDepositRate(BTC_POOL_TUP_CONTRACT) / 1e16; +} + +const getEthPoolDepositRate = async () => { + return await getPoolDepositRate(ETH_POOL_TUP_CONTRACT) / 1e16; +} + +const getUsdcPoolDepositRate = async () => { + return await getPoolDepositRate(USDC_POOL_TUP_CONTRACT) / 1e16; +} + +const getUsdtPoolDepositRate = async () => { + return await getPoolDepositRate(USDT_POOL_TUP_CONTRACT) / 1e16; +} + +const getWavaxPoolDepositRate = async () => { + return await getPoolDepositRate(WAVAX_POOL_TUP_CONTRACT) / 1e16; +} + +const getUsdcPoolArbiDepositRate = async () => { + return await getPoolDepositRate(USDC_POOL_TUP_ARBI_CONTRACT, 'arbitrum') / 1e16; +} + +const getEthPoolArbiDepositRate = async () => { + return await getPoolDepositRate(ETH_POOL_TUP_ARBI_CONTRACT, 'arbitrum') / 1e16; +} + +const getArbPoolArbiDepositRate = async () => { + return await getPoolDepositRate(ARB_POOL_TUP_ARBI_CONTRACT, 'arbitrum') / 1e16; +} + +const getBtcPoolArbiDepositRate = async () => { + return await getPoolDepositRate(BTC_POOL_TUP_ARBI_CONTRACT, 'arbitrum') / 1e16; +} + +const getDaiPoolArbiDepositRate = async () => { + return await getPoolDepositRate(DAI_POOL_TUP_ARBI_CONTRACT, 'arbitrum') / 1e16; +} + +const getBtcPoolTVL = async() => { + const supply = await getPoolTVL(BTC_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(BTC_TOKEN_ADDRESS); + return supply * price / 1e8; +} + +const getEthPoolTVL = async() => { + const supply = await getPoolTVL(ETH_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(ETH_TOKEN_ADDRESS); + return supply * price / 1e18; +} + +const getEthPoolArbiTVL = async() => { + const supply = await getPoolTVL(ETH_POOL_TUP_ARBI_CONTRACT, 'arbitrum'); + + const price = await getTokenPrice(ETH_TOKEN_ARBI_ADDRESS, 'arbitrum'); + return supply * price / 1e18; +} + +const getArbPoolArbiTVL = async() => { + const supply = await getPoolTVL(ARB_POOL_TUP_ARBI_CONTRACT, 'arbitrum'); + + const price = await getTokenPrice(ARB_TOKEN_ARBI_ADDRESS, 'arbitrum'); + return supply * price / 1e18; +} + +const getBtcPoolArbiTVL = async() => { + const supply = await getPoolTVL(BTC_POOL_TUP_ARBI_CONTRACT, 'arbitrum'); + + const price = await getTokenPrice(BTC_TOKEN_ARBI_ADDRESS, 'arbitrum'); + return supply * price / 1e8; +} + + +const getDaiPoolArbiTVL = async() => { + const supply = await getPoolTVL(DAI_POOL_TUP_ARBI_CONTRACT, 'arbitrum'); + + const price = await getTokenPrice(DAI_TOKEN_ARBI_ADDRESS, 'arbitrum'); + return supply * price / 1e18; +} + +const getUsdcPoolArbiTVL = async() => { + const supply = await getPoolTVL(USDC_POOL_TUP_ARBI_CONTRACT, 'arbitrum'); + + const price = await getTokenPrice(USDC_TOKEN_ARBI_ADDRESS, 'arbitrum'); + return supply * price / 1e6; +} + +const getWavaxPoolTVL = async() => { + const supply = await getPoolTVL(WAVAX_POOL_TUP_CONTRACT); + + const price = await getTokenPrice(WAVAX_TOKEN_ADDRESS); + return supply * price / 1e18; +} + +const getUsdcPoolTVL = async() => { + const supply = await getPoolTVL(USDC_POOL_TUP_CONTRACT); + const price = await getTokenPrice(USDC_TOKEN_ADDRESS); + return supply * price / 1e6; +} + +const getUsdtPoolTVL = async() => { + const supply = await getPoolTVL(USDT_POOL_TUP_CONTRACT); + const price = await getTokenPrice(USDT_TOKEN_ADDRESS); + return supply * price / 1e6; +} + +const getPoolsAPYs = async () => { + const usdcPoolTvl = await getUsdcPoolTVL(); + const usdcPool = { + pool: `dp-${USDC_TOKEN_ADDRESS}-avalanche`, + chain: utils.formatChain('avalanche'), + project: 'deltaprime', + symbol: utils.formatSymbol('USDC'), + tvlUsd: usdcPoolTvl, + apyBase: await getUsdcPoolDepositRate(), + underlyingTokens: [USDC_TOKEN_ADDRESS] + }; + + const usdtPoolTvl = await getUsdtPoolTVL(); + const usdtPool = { + pool: `dp-${USDT_TOKEN_ADDRESS}-avalanche`, + chain: utils.formatChain('avalanche'), + project: 'deltaprime', + symbol: utils.formatSymbol('USDt'), + tvlUsd: usdtPoolTvl, + apyBase: await getUsdtPoolDepositRate(), + underlyingTokens: [USDT_TOKEN_ADDRESS] + }; + + const wavaxPoolTvl = await getWavaxPoolTVL(); + const wavaxPool = { + pool: `dp-${WAVAX_TOKEN_ADDRESS}-avalanche`, + chain: utils.formatChain('avalanche'), + project: 'deltaprime', + symbol: utils.formatSymbol('WAVAX'), + tvlUsd: wavaxPoolTvl, + apyBase: await getWavaxPoolDepositRate(), + underlyingTokens: [WAVAX_TOKEN_ADDRESS], + }; + + const btcPoolTvl = await getBtcPoolTVL(); + const btcPool = { + pool: `dp-${BTC_TOKEN_ADDRESS}-avalanche`, + chain: utils.formatChain('avalanche'), + project: 'deltaprime', + symbol: utils.formatSymbol('BTC.b'), + tvlUsd: btcPoolTvl, + apyBase: await getBtcPoolDepositRate(), + underlyingTokens: [BTC_TOKEN_ADDRESS] + }; + + const ethPoolTvl = await getEthPoolTVL(); + const ethPool = { + pool: `dp-${ETH_TOKEN_ADDRESS}-avalanche`, + chain: utils.formatChain('avalanche'), + project: 'deltaprime', + symbol: utils.formatSymbol('WETH.e'), + tvlUsd: ethPoolTvl, + apyBase: await getEthPoolDepositRate(), + underlyingTokens: [ETH_TOKEN_ADDRESS], + }; + + const ethPoolArbiTvl = await getEthPoolArbiTVL(); + const ethPoolArbi = { + pool: `dp-${ETH_TOKEN_ARBI_ADDRESS}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'deltaprime', + symbol: utils.formatSymbol('WETH'), + tvlUsd: ethPoolArbiTvl, + apyBase: await getEthPoolArbiDepositRate(), + underlyingTokens: [ETH_TOKEN_ARBI_ADDRESS], + }; + + const usdcPoolArbiTvl = await getUsdcPoolArbiTVL(); + const usdcPoolArbi = { + pool: `dp-${USDC_TOKEN_ARBI_ADDRESS}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'deltaprime', + symbol: utils.formatSymbol('USDC'), + tvlUsd: usdcPoolArbiTvl, + apyBase: await getUsdcPoolArbiDepositRate(), + underlyingTokens: [USDC_TOKEN_ARBI_ADDRESS], + }; + + const arbPoolArbiTvl = await getArbPoolArbiTVL(); + const arbPoolArbi = { + pool: `dp-${ARB_TOKEN_ARBI_ADDRESS}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'deltaprime', + symbol: utils.formatSymbol('ARB'), + tvlUsd: arbPoolArbiTvl, + apyBase: await getArbPoolArbiDepositRate(), + underlyingTokens: [ARB_TOKEN_ARBI_ADDRESS], + }; + + const btcPoolArbiTvl = await getBtcPoolArbiTVL(); + const btcPoolArbi = { + pool: `dp-${BTC_TOKEN_ARBI_ADDRESS}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'deltaprime', + symbol: utils.formatSymbol('WBTC'), + tvlUsd: btcPoolArbiTvl, + apyBase: await getBtcPoolArbiDepositRate(), + underlyingTokens: [BTC_TOKEN_ARBI_ADDRESS], + }; + + const daiPoolArbiTvl = await getDaiPoolArbiTVL(); + const daiPoolArbi = { + pool: `dp-${DAI_TOKEN_ARBI_ADDRESS}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'deltaprime', + symbol: utils.formatSymbol('DAI'), + tvlUsd: daiPoolArbiTvl, + apyBase: await getDaiPoolArbiDepositRate(), + underlyingTokens: [DAI_TOKEN_ARBI_ADDRESS], + }; + + + + + return [usdcPool, usdtPool, wavaxPool, btcPool, ethPool, + ethPoolArbi, usdcPoolArbi, arbPoolArbi, btcPoolArbi, daiPoolArbi + ]; +}; + +module.exports = { + timetravel: false, + start: 1673346953, + apy: getPoolsAPYs, + url: 'https://app.deltaprime.io/#/pools', +}; diff --git a/src/adaptors/demex-perp/index.js b/src/adaptors/demex-perp/index.js new file mode 100644 index 0000000000..e5faebe64a --- /dev/null +++ b/src/adaptors/demex-perp/index.js @@ -0,0 +1,51 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: axios } = require('axios'); + +const getPoolsTvl = async (balances) => { + const allPoolsTVLRaw = await ( + await axios.get('https://api-insights.carbon.network/pool/liquidity') + ).data; + const lastIndex = allPoolsTVLRaw?.result?.entries?.length - 1; + return allPoolsTVLRaw?.result?.entries[lastIndex]?.pools ?? []; +}; + +const apr = async () => { + const poolsRaw = await utils.getData( + 'https://api-insights.carbon.network/pool/apy' + ); + const tokens = await ( + await utils.getData( + 'https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000' + ) + ).tokens; + const pools = poolsRaw?.result?.entries; + const result = []; + + const balances = {}; + const poolsTVL = await getPoolsTvl(balances); + + for (const pool of pools) { + const tokenAInfo = tokens.find((o) => o.denom === pool.denomA); + const tokenBInfo = tokens.find((o) => o.denom === pool.denomB); + const symbol = `${tokenAInfo.symbol.toUpperCase()}-${tokenBInfo.symbol.toUpperCase()}`; + const poolTVL = poolsTVL.find((o) => o.poolId === pool.id)?.amountValue; + result.push({ + pool: pool.denom.toString(), + chain: utils.formatChain('Carbon'), + project: 'demex-perp', + symbol: symbol, + tvlUsd: poolTVL ?? 0, + apy: Number(pool.apy), + rewardTokens: ['swth'], + underlyingTokens: [pool.denomA, pool.denomB], + }); + } + return result; +}; + +module.exports = { + timetravel: false, + apy: apr, + url: 'https://app.dem.exchange/pools', +}; diff --git a/src/adaptors/deri-protocol/abi.js b/src/adaptors/deri-protocol/abi.js new file mode 100644 index 0000000000..1aedf9887c --- /dev/null +++ b/src/adaptors/deri-protocol/abi.js @@ -0,0 +1 @@ +module.exports = [{ "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "newAdmin", "type": "address" }], "name": "NewAdmin", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "newImplementation", "type": "address" }], "name": "NewImplementation", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "newProtocolFeeCollector", "type": "address" }], "name": "NewProtocolFeeCollector", "type": "event" }, { "stateMutability": "payable", "type": "fallback" }, { "inputs": [], "name": "admin", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "cumulativePnlPerLiquidity", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "implementation", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "liquidity", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "lpInfos", "outputs": [{ "internalType": "address", "name": "vault", "type": "address" }, { "internalType": "int256", "name": "amountB0", "type": "int256" }, { "internalType": "int256", "name": "liquidity", "type": "int256" }, { "internalType": "int256", "name": "cumulativePnlPerLiquidity", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "lpsPnl", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "", "type": "address" }], "name": "markets", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "protocolFeeAccrued", "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "protocolFeeCollector", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newAdmin", "type": "address" }], "name": "setAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newImplementation", "type": "address" }], "name": "setImplementation", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "newProtocolFeeCollector", "type": "address" }], "name": "setProtocolFeeCollector", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "tdInfos", "outputs": [{ "internalType": "address", "name": "vault", "type": "address" }, { "internalType": "int256", "name": "amountB0", "type": "int256" }], "stateMutability": "view", "type": "function" }, { "stateMutability": "payable", "type": "receive" }] \ No newline at end of file diff --git a/src/adaptors/deri-protocol/index.js b/src/adaptors/deri-protocol/index.js new file mode 100644 index 0000000000..2292b3ae89 --- /dev/null +++ b/src/adaptors/deri-protocol/index.js @@ -0,0 +1,71 @@ +const utils = require('../utils'); +const abi = require('./abi.js'); +const sdk = require('@defillama/sdk'); + +const pools = [ + { + pool: "0x243681B8Cd79E3823fF574e07B2378B8Ab292c1E", + project: "deri-protocol", + chain: "bsc", + chainId: "56", + btoken: "BUSD", + }, + { + pool: "0xDE3447Eb47EcDf9B5F90E7A6960a14663916CeE8", + project: "deri-protocol", + chain: "arbitrum", + chainId: "42161", + btoken: "USDC", + } +] +const poolsFunction = async () => { + let apyData = pools.map(async (item) => { + let url = `https://api.deri.io/pool_mining_info/${item.chainId}/${item.pool}` + let res = await utils.getData(url) + let data = [] + let obj = res.data.bTokens.map((token) => { + if (token.bTokenSymbol === item.btoken) { + let apy = Number(token.apy) + Number(token.supplyApy) + Number(token.xvsApy) + data.push({ + pool: item.pool, + chain: item.chain, + project: item.project, + apyReward: apy * 100, + symbol: token.bTokenSymbol, + }) + } + }) + return data + }) + apyData = await Promise.all(apyData) + + let Pool = [] + for (let index = 0; index < apyData.length; index++) { + let obj = apyData[index].map(async (apyItem) => { + let tvl = await sdk.api.abi.call({ + target: apyItem.pool, + abi: abi.find((m) => m.name === 'liquidity'), + chain: apyItem.chain + }) + let pool = `${apyItem.pool}-${apyItem.chain}` + let poolObj = { + "pool": pool.toLowerCase(), + "chain": utils.formatChain(apyItem.chain), + "project": apyItem.project, + "tvlUsd": Number(tvl.output) / 10 ** 18, + "symbol": apyItem.symbol, + "apyReward": apyItem.apyReward, + "rewardTokens":["0xa487bf43cf3b10dffc97a9a744cbb7036965d3b9"] + } + return poolObj + }) + let tvl = await Promise.all(obj) + Pool.push(tvl[0]) + } + return Pool +} +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://deri.io', +}; \ No newline at end of file diff --git a/src/adaptors/dexswap/abi/FARM.js b/src/adaptors/dexswap/abi/FARM.js new file mode 100644 index 0000000000..8c4906f6e3 --- /dev/null +++ b/src/adaptors/dexswap/abi/FARM.js @@ -0,0 +1,25 @@ +const FARM = [ + { + 'inputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address' + } + ], + 'name': 'sharePerTimeUnit', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' + } + ], + 'stateMutability': 'view', + 'type': 'function' + }, +] + +module.exports = { + FARM +} \ No newline at end of file diff --git a/src/adaptors/dexswap/abi/LP.js b/src/adaptors/dexswap/abi/LP.js new file mode 100644 index 0000000000..d1a0bac251 --- /dev/null +++ b/src/adaptors/dexswap/abi/LP.js @@ -0,0 +1,46 @@ +const LP_ABI = [ + { + 'constant': true, + 'inputs': [], + 'name': 'getReserves', + 'outputs': [ + { + 'internalType': 'uint112', + 'name': '_reserve0', + 'type': 'uint112' + }, + { + 'internalType': 'uint112', + 'name': '_reserve1', + 'type': 'uint112' + }, + { + 'internalType': 'uint32', + 'name': '_blockTimestampLast', + 'type': 'uint32' + } + ], + 'payable': false, + 'stateMutability': 'view', + 'type': 'function' + }, + { + 'constant': true, + 'inputs': [], + 'name': 'totalSupply', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' + } + ], + 'payable': false, + 'stateMutability': 'view', + 'type': 'function' + } +] + +module.exports = { + LP_ABI, +} \ No newline at end of file diff --git a/src/adaptors/dexswap/index.js b/src/adaptors/dexswap/index.js new file mode 100644 index 0000000000..2edbe11359 --- /dev/null +++ b/src/adaptors/dexswap/index.js @@ -0,0 +1,160 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const { LP_ABI } = require('./abi/LP'); +const { FARM } = require('./abi/FARM'); +const utils = require('../utils'); + +const TOKENS = { + GDEX: '0x92a212d9f5eef0b262ac7d84aea64a0d0758b94f', + USDEX: '0x4117ec0a779448872d3820f37ba2060ae0b7c34b', +}; +const SECONDS_IN_YEAR = 24 * 60 * 60 * 365; +const pairsDexswap = [ + { + name: 'USDEX+/USDC', + address: '0x24129a6c5b700435cc0d1bd3500796f3fb9ebd49', + }, + { + name: 'USDEX+/gDEX', + address: '0x0e75ca30b075aa0df8c360e30cd0ed26ed62432a', + }, +]; + +const originFarms = [ + { + symbol: 'GDEX', + origin: '0xde1e437e0be59b596e69ff58e2bda9209a72ce8b', + stakingToken: '0x92a212d9f5eef0b262ac7d84aea64a0d0758b94f', + connector: '0x0b8905bb2ab1bae7b081d5b8cc9d906f01dd3b82', + rewardToken: '0x4117ec0a779448872d3820f37ba2060ae0b7c34b', + }, + { + symbol: 'USDEX+/GDEX', + origin: '0x74337fb8381ce8c323110cef2e041d0f2220a2ce', + stakingToken: '0x0e75ca30b075aa0df8c360e30cd0ed26ed62432a', + connector: '0xa7fbbdf114f1f2218825a500515b6bf7d49c1b2c', + rewardToken: '0x4117ec0a779448872d3820f37ba2060ae0b7c34b', + }, + { + symbol: 'USDEX+/USDC', + origin: '0x74337fb8381ce8c323110cef2e041d0f2220a2ce', + stakingToken: '0x24129a6c5b700435cc0d1bd3500796f3fb9ebd49', + connector: '0xc5a0676cc593f7b4a5253510bae3bad475f2c441', + rewardToken: '0x4117ec0a779448872d3820f37ba2060ae0b7c34b', + }, +]; + +PROJECT_SLUG = 'dexswap'; + +async function getDexSwapPrices() { + const lpInfo = []; + for (const pair of pairsDexswap) { + const { output: reserves } = await sdk.api.abi.call({ + target: pair.address, + abi: LP_ABI[0], + chain: 'arbitrum', + }); + const { output: totalSupply } = await sdk.api.abi.call({ + target: pair.address, + abi: LP_ABI[1], + chain: 'arbitrum', + }); + lpInfo.push({ ...reserves, totalSupply }); + } + const [lpInfo0, lpInfo1] = lpInfo; + const usdcWithoutDecimalsBN = new BigNumber(lpInfo0['1']).div(10 ** 6); + const usdexPair0PlusWithoutDecimalsBN = new BigNumber(lpInfo0['0']).div( + 10 ** 18 + ); + const gdexWithoutDecimalsBN = new BigNumber(lpInfo1['1']).div(10 ** 18); + const usdexPair1PlusWithoutDecimalsBN = new BigNumber(lpInfo1['0']).div( + 10 ** 18 + ); + const usdexPriceUsd = usdcWithoutDecimalsBN + .div(usdexPair0PlusWithoutDecimalsBN) + .toString(); + const totalPriceToGdexPairBN = gdexWithoutDecimalsBN.times(usdexPriceUsd); + const priceGdexBN = usdexPair1PlusWithoutDecimalsBN.div( + totalPriceToGdexPairBN + ); + + const totalSupply0BN = new BigNumber(lpInfo1.totalSupply).div(10 ** 18); + const totalSupply1BN = new BigNumber(lpInfo1.totalSupply).div(10 ** 18); + const priceLpGdexUsdex = usdexPair1PlusWithoutDecimalsBN + .times(usdexPriceUsd) + .plus(priceGdexBN.times(gdexWithoutDecimalsBN)) + .div(totalSupply1BN) + .toString(); + const priceLpUsdcUsdexBN = usdcWithoutDecimalsBN.plus( + usdexPair0PlusWithoutDecimalsBN.times(usdexPriceUsd) + ); + return { + [TOKENS.GDEX]: priceGdexBN.toString(), + [TOKENS.USDEX]: usdexPriceUsd, + [pairsDexswap[1].address]: priceLpGdexUsdex, + stablePairTvl: priceLpUsdcUsdexBN.toNumber(), + }; +} + +async function getGdexFarmsApy() { + const prices = await getDexSwapPrices(); + const res = []; + for (const origin of originFarms) { + const { output: balance } = await sdk.api.abi.call({ + chain: 'arbitrum', + abi: 'erc20:balanceOf', + target: origin.stakingToken, + params: origin.origin, + }); + const isStable = origin.stakingToken === pairsDexswap[0].address; + let tvlUsd; + if (isStable) { + tvlUsd = prices.stablePairTvl; + } else { + tvlUsd = new BigNumber(balance) + .div(10 ** 18) + .times(prices[origin.stakingToken]) + .toNumber(); + } + const { output: sharePerTimeUnit } = await sdk.api.abi.call({ + target: origin.connector, + chain: 'arbitrum', + abi: FARM[0], + params: [origin.rewardToken], + }); + const rewardsPerSecondUsdBN = new BigNumber( + isStable ? new BigNumber(sharePerTimeUnit).div(0.1) : sharePerTimeUnit + ) + .div(10 ** 18) + .times(prices[origin.rewardToken]) + .times(100); + const rewardPerYearUsdBN = rewardsPerSecondUsdBN.times(SECONDS_IN_YEAR); + const apy = rewardPerYearUsdBN.div(tvlUsd).toNumber(); + if (isStable) { + res.push({ + pool: pairsDexswap[0].address, + chain: utils.formatChain('arbitrum'), + project: PROJECT_SLUG, + symbol: pairsDexswap[0].name, + tvlUsd, + apy, + url: 'https://www.dexfinance.com/', + }); + } else { + res.push({ + pool: origin.origin, + chain: utils.formatChain('arbitrum'), + project: PROJECT_SLUG, + symbol: origin.symbol, + tvlUsd, + apy, + url: 'https://www.dexfinance.com/', + }); + } + } + return res; +} + +module.exports = { + apy: getGdexFarmsApy, +}; diff --git a/src/adaptors/dforce/abi.json b/src/adaptors/dforce/abi.json new file mode 100644 index 0000000000..579e0459ee --- /dev/null +++ b/src/adaptors/dforce/abi.json @@ -0,0 +1,1292 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "BorrowPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "BorrowedAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "BorrowedRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateralFactor", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supplyCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "distributionFactor", + "type": "uint256" + } + ], + "name": "MarketAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "MintPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldBorrowCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCapacity", + "type": "uint256" + } + ], + "name": "NewBorrowCapacity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldBorrowFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowFactorMantissa", + "type": "uint256" + } + ], + "name": "NewBorrowFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "NewOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPendingOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "NewPendingOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldRewardDistributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_newRewardDistributor", + "type": "address" + } + ], + "name": "NewRewardDistributor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldSupplyCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSupplyCapacity", + "type": "uint256" + } + ], + "name": "NewSupplyCapacity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "RedeemPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "SeizePaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "TransferPaused", + "type": "event" + }, + { + "inputs": [], + "name": "_acceptOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_collateralFactor", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_borrowFactor", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_supplyCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_distributionFactor", + "type": "uint256" + } + ], + "name": "_addMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllBorrowPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllMintPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllRedeemPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newBorrowCapacity", + "type": "uint256" + } + ], + "name": "_setBorrowCapacity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newBorrowFactorMantissa", + "type": "uint256" + } + ], + "name": "_setBorrowFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setBorrowPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setMintPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "_setPendingOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newOracle", "type": "address" } + ], + "name": "_setPriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setProtocolPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setRedeemPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newRewardDistributor", + "type": "address" + } + ], + "name": "_setRewardDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setSeizePaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newSupplyCapacity", + "type": "uint256" + } + ], + "name": "_setSupplyCapacity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setTransferPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setiTokenPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "_borrowedAmount", + "type": "uint256" + } + ], + "name": "afterBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "afterFlashloan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repaidAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_seizedAmount", "type": "uint256" } + ], + "name": "afterLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "uint256", "name": "_mintAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_mintedAmount", "type": "uint256" } + ], + "name": "afterMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_redeemer", "type": "address" }, + { "internalType": "uint256", "name": "_redeemAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_redeemedUnderlying", + "type": "uint256" + } + ], + "name": "afterRedeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_payer", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "afterRepayBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_seizedAmount", "type": "uint256" } + ], + "name": "afterSeize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "afterTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_borrowAmount", "type": "uint256" } + ], + "name": "beforeBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "beforeFlashloan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "beforeLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "uint256", "name": "_mintAmount", "type": "uint256" } + ], + "name": "beforeMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_redeemer", "type": "address" }, + { "internalType": "uint256", "name": "_redeemAmount", "type": "uint256" } + ], + "name": "beforeRedeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_payer", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "beforeRepayBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_seizeAmount", "type": "uint256" } + ], + "name": "beforeSeize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "beforeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "calcAccountEquity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_market", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "enterMarketFromiToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_iTokens", "type": "address[]" } + ], + "name": "enterMarkets", + "outputs": [ + { "internalType": "bool[]", "name": "_results", "type": "bool[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_iTokens", "type": "address[]" } + ], + "name": "exitMarkets", + "outputs": [ + { "internalType": "bool[]", "name": "_results", "type": "bool[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAlliTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "_alliTokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getBorrowedAssets", + "outputs": [ + { + "internalType": "address[]", + "name": "_borrowedAssets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getEnteredMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "_accountCollaterals", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasBorrowed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasEnteredMarket", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasiToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isController", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "_seizedTokenCollateral", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCapacity", + "type": "uint256" + }, + { "internalType": "bool", "name": "mintPaused", "type": "bool" }, + { "internalType": "bool", "name": "redeemPaused", "type": "bool" }, + { "internalType": "bool", "name": "borrowPaused", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceOracle", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardDistributor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "seizePaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_BASE_TOKEN_", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_QUOTE_TOKEN_", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "view", + "type": "function", + "name": "coins", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "contract IiTokenHelper", + "name": "_asset", + "type": "address" + } + ], + "name": "getDistributionSupplyApy", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IiTokenHelper", + "name": "_iMSD", + "type": "address" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "_supplyValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowValue", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/dforce/index.js b/src/adaptors/dforce/index.js new file mode 100644 index 0000000000..51bf1042dd --- /dev/null +++ b/src/adaptors/dforce/index.js @@ -0,0 +1,279 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const abi = require('./abi.json'); + +const getApiUrl = (chain) => +`https://app.dforce.network/general/markets?network=${chain}`; + +const NETWORKS = { + ethereum: { + name: 'mainnet', + controller: '0x8B53Ab2c0Df3230EA327017C91Eb909f815Ad113', + }, + binance: { + name: 'bsc', + controller: '0x0b53E608bD058Bb54748C35148484fD627E6dc0A', + }, + polygon: { + name: 'Polygon', + controller: '0x52eaCd19E38D501D006D2023C813d7E37F025f37', + }, + arbitrum: { + name: 'ArbitrumOne', + controller: '0x8E7e9eA9023B81457Ae7E6D2a51b003D421E5408', + }, + optimism: { + name: 'Optimism', + controller: '0xA300A84D8970718Dac32f54F61Bd568142d8BCF4', + }, +}; + +const getStakingApiUrl = (chain) => + `https://app.dforce.network/staking/getRoi?network=${chain}`; + +const VAULT_CONTRACTS = { + ethereum: { + vaultPools: [ + { + symbol: "USX-3CRV", + address: "0xd8d07A8ab4F6a1cC4cF86b3cB11b78A7C1e701ad", + underlyingTokens: [ + "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490", // 3CRV + "0x0a5E677a6A24b2F1A2Bf4F3bFfC443231d2fDEc8", // USX + ], + vMUSX: "0x53BF3c82f62B152800E0152DB743451849F1aFF9", + rewardTokens: ["0x431ad2ff6a9C365805eBaD47Ee021148d6f7DBe0"], + }, + ], + vaultData: "0x4779f4b09C74b9Ed31aBe60E1cfC3B1b4832F128", + }, + arbitrum: { + vaultPools: [ + { + symbol: "USX-2CRV", + address: "0x3EA2c9daa2aB26dbc0852ea653f99110c335f10a", + underlyingTokens: [ + "0xbF7E49483881C76487b0989CD7d9A8239B20CA41", // 2CRV + "0x641441c631e2F909700d2f41FD87F0aA6A6b4EDb", // USX + ], + vMUSX: "0x8A49dbE58CE2D047D3453a3ee4f0F245b7195f67", + rewardTokens: ["0xaE6aab43C4f3E0cea4Ab83752C278f8dEbabA689"], + }, + ], + vaultData: "0x3Fc9F017fbF4251f006163B7CAd6601fC1A8Aa71", + }, +} + +const STAKING_CONTRACTS = { + binance: { + name: 'bsc', + stakingPools: [ + { + symbol: "USX-BUSD", + address: "0x8d61b71958dD9Df6eAA670c0476CcE7e25e98707", + underlyingTokens: [ + "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", // BUSD + "0xB5102CeE1528Ce2C760893034A4603663495fD72", // USX + ], + }, + ], + }, + arbitrum: { + name: 'ArbitrumOne', + stakingPools: [ + { + symbol: "USX-USDC", + address: "0x2Ca5B28B9F348f652b46210C75F528ee094b15cf", + underlyingTokens: [ + "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", // USDC + "0x641441c631e2F909700d2f41FD87F0aA6A6b4EDb", // USX + ], + }, + ], + } +} + +const getStakingApy = async () => { + const stakingDetails = await Promise.all( + Object.keys(STAKING_CONTRACTS).map(async (network) => { + return { + network, + apyData: await utils.getData(getStakingApiUrl(STAKING_CONTRACTS[network].name)), + poolData: STAKING_CONTRACTS[network] + }; + }) + ); + + let stakingData = []; + stakingDetails.map( + async ({ network, apyData, poolData }) => { + poolData.stakingPools.map(stakingPool => { + let underlying0, underlying1; + apyData.map(async (apy) => { + if (apy.asset == stakingPool.address) { + let allRewardTokens = []; + apy.APY.map( + element => { + Object.keys(element).map(rewardToken => { + allRewardTokens.push(rewardToken); + }) + }) + stakingData.push({ + pool: `${stakingPool.address}-${network}`, + chain: utils.formatChain(network), + project: 'dforce', + symbol: stakingPool.symbol, + tvlUsd: Number(apy.totalStaking) / 1e18, + // 1e16 = apy / 1e18 * 100% + apyReward: Number(apy.totalApy) / 1e16, + underlyingTokens: stakingPool.underlyingTokens, + rewardTokens: allRewardTokens, + url: `https://app.dforce.network/#/Liquidity?AssetsType=Lend¤tPool=general`, + }) + } + }) + }) + }) + + return stakingData.flat(); +} + +const getVaultApy = async () => { + const vaultDetails = await Promise.all( + Object.keys(VAULT_CONTRACTS).map(async (network) => { + return { + network, + poolData: VAULT_CONTRACTS[network] + }; + }) + ); + + const vaultData = await Promise.all(vaultDetails.map( + async ({ network, poolData }) => { + return await Promise.all( + poolData.vaultPools.map(async (vaultPool) => { + let apyResult = await ( + await sdk.api.abi.call({ + target: poolData.vaultData, + chain: network, + abi: abi.find(({ name }) => name === "getDistributionSupplyApy"), + params: [vaultPool.address] + }) + ).output + + let poolInfoResult = await ( + await sdk.api.abi.call({ + target: poolData.vaultData, + chain: network, + abi: abi.find(({ name }) => name === "getPoolInfo"), + params: [vaultPool.vMUSX] + }) + ).output + + let rawTvlUsd = Number(poolInfoResult._supplyValue) - Number(poolInfoResult._borrowValue); + + return { + pool: `${vaultPool.address}-${network}`, + chain: utils.formatChain(network), + project: 'dforce', + symbol: vaultPool.symbol, + tvlUsd: Number(rawTvlUsd) / 1e18, + // 1e16 = apy / 1e18 * 100% + apyReward: Number(apyResult) / 1e16, + underlyingTokens: vaultPool.underlyingTokens, + rewardTokens: vaultPool.rewardTokens, + url: `https://app.dforce.network/#/Liquidity?AssetsType=Lend¤tPool=general`, + } + }) + ) + } + )); + + return vaultData.flat(); +} + +const getLendingApy = async () => { + const markets = await Promise.all( + Object.keys(NETWORKS).map(async (network) => { + return { + network, + data: await utils.getData(getApiUrl(NETWORKS[network].name)), + }; + }) + ); + + const pools = await Promise.all( + markets.map( + async ({ network, data: { supplyMarkets, underlyingToken } }) => { + // get iTokens + const iTokens = ( + await sdk.api.abi.call({ + chain: network === 'binance' ? 'bsc' : network, + target: NETWORKS[network].controller, + abi: abi.find((n) => n.name === 'getAlliTokens'), + }) + ).output; + + // get LTV per iToken + const markets = ( + await sdk.api.abi.multiCall({ + chain: network === 'binance' ? 'bsc' : network, + abi: abi.find((n) => n.name === 'markets'), + calls: iTokens.map((t) => ({ + target: NETWORKS[network].controller, + params: [t], + })), + }) + ).output.map((o) => o.output); + + const ltvs = markets.map((m, i) => ({ + iToken: iTokens[i], + ltv: m.collateralFactorMantissa, + })); + + return supplyMarkets.map((market) => ({ + pool: `${market.address}-${network}`, + chain: utils.formatChain(network), + project: 'dforce', + symbol: market.underlying_symbol, + tvlUsd: + (Number(market.supplyValue) - Number(market.borrowValue)) / 1e18, + // 1e16 = apy / 1e18 * 100% + apyBase: Number(market.supplyAPY) / 1e16, + apyReward: Number(market.rewardSupplyApy) / 1e16, + rewardTokens: ['0x431ad2ff6a9c365805ebad47ee021148d6f7dbe0'], + underlyingTokens: [ + underlyingToken.find((x) => x.symbol === market.underlying_symbol) + .underlying, + ], + // borrow fields + apyBaseBorrow: Number(market.borrowAPY) / 1e16, + apyRewardBorrow: Number(market.rewardBorrowApy) / 1e16, + totalSupplyUsd: Number(market.supplyValue) / 1e18, + totalBorrowUsd: Number(market.borrowValue) / 1e18, + ltv: + Number(ltvs.find((m) => m.iToken === market.address)?.ltv) / 1e18, + url: 'https://app.dforce.network/#/lending?AssetsType=Lend¤tPool=general', + })); + } + ) + ); + + return pools.flat(); +}; + +const main = async () => { + let data = await Promise.all([ + getStakingApy(), + getVaultApy(), + getLendingApy(), + ]); + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/dfx-v2/abis/abiStakingRewardsMulti.json b/src/adaptors/dfx-v2/abis/abiStakingRewardsMulti.json new file mode 100644 index 0000000000..2c2c496975 --- /dev/null +++ b/src/adaptors/dfx-v2/abis/abiStakingRewardsMulti.json @@ -0,0 +1,398 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20Metadata[]", + "name": "_rewardsTokens", + "type": "address[]" + }, + { + "internalType": "contract IERC20Metadata", + "name": "_stakingToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256[]", + "name": "reward", + "type": "uint256[]" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardForDuration", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_rewards", "type": "uint256[]" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenAddress", "type": "address" }, + { "internalType": "uint256", "name": "tokenAmount", "type": "uint256" } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardRates", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerToken", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardsPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardsTokens", + "outputs": [ + { + "internalType": "contract IERC20Metadata", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20Metadata", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/dfx-v2/config.js b/src/adaptors/dfx-v2/config.js new file mode 100644 index 0000000000..213b533ab0 --- /dev/null +++ b/src/adaptors/dfx-v2/config.js @@ -0,0 +1,112 @@ +const chains = { + ethereum: { + url: 'https://api.goldsky.com/api/public/project_clasdk93949ub0h10a9lf9pkq/subgraphs/dfx-v2/latest/gn', + rewardToken: '0x888888435FDe8e7d4c54cAb67f206e4199454c60', + usesGauges: true, + stakingPools: [ + { + name: 'dfx-cadc-usdc-v2', + asssimilatorAddress: '0x7611f64BDB95077C9e9e6f9ad9A1E7AbfBD2B4A7', + curveAddress: '0xDA9dcc7fd51F0D9Aa069a82647A5F3ba594edAED', + stakingAddress: '0xBE5869c78668B2c49C571005f3754a92472D9E1b', + }, + { + name: 'dfx-euroc-usdc-v2', + asssimilatorAddress: '0xf8053A18bd7A608e54E3694fe042702CA560D1a3', + curveAddress: '0x8cd86fbC94BeBFD910CaaE7aE4CE374886132c48', + stakingAddress: '0x1e07D4dad0614A811A12BDCD66016f48c6942A60', + }, + { + name: 'dfx-xsgd-usdc-v2', + asssimilatorAddress: '0xF866ACa6DC860e088045CbB5ee9ea48744eE2b48', + curveAddress: '0xACC5Dca0B684f444bC6b4be30B95Ca7D928A4B9c', + stakingAddress: '0xE7006808E855F3707Ec58bDfb66A096A7a6155e1', + }, + { + name: 'dfx-nzds-usdc-v2', + asssimilatorAddress: '0xAb44c9482Db0FE517705D6dF72f949d5EeA91C3F', + curveAddress: '0xc147cee0F6BB0e56240868c9f53aE916D3b86073', + stakingAddress: '0x45C38b5126eB70e8B0A2c2e9FE934625641bF063', + }, + { + name: 'dfx-tryb-usdc-v2', + asssimilatorAddress: '0x978E49F33E2c07A4D1918E95B58aC13F61ee8aa4', + curveAddress: '0x38F818fCd57F8A1782bBCC1C90CB0FD03e7f0bd1', + stakingAddress: '0xb0de1886dD949b5DBFB9feBF7ba283f5Ff87c7EB', + }, + { + name: 'dfx-gyen-usdc-v2', + asssimilatorAddress: '0x4b0d7530F5Ab428abac06fa92163F00de89f7D27', + curveAddress: '0x9aFD65013770525E43a84e49c87B3015C2C32517', + stakingAddress: '0xA2Bc5552A5A083E78ec820A91e97933133255572', + }, + { + name: 'dfx-xidr-usdc-v2', + asssimilatorAddress: '0xEe499d42a88aF0AE665347d3e797515A56a4E799', + curveAddress: '0xb7dB2F8d25C51A26799bE6765720c3C6D84CD2f2', + stakingAddress: '0x520B0284bCD3Fb0BA427Df1fCd1DE444c7c676A5', + }, + { + name: 'dfx-gbpt-usdc-v2', + asssimilatorAddress: '0xf10D0EAEA98Bd5aed3654848a2C0EF7D837C114b', + curveAddress: '0x7d1bA2c18CbDE0D790Cc1d626F0c70b3c13C9eec', + stakingAddress: '0xB41ab47a724fB24f1DC0e57380411C7FC5cDD00B', + }, + ], + }, + polygon: { + url: 'https://api.goldsky.com/api/public/project_clasdk93949ub0h10a9lf9pkq/subgraphs/dfx-v2-polygon/latest/gn', + usesGauges: false, + stakingPools: [ + { + name: 'dfx-cadc-usdc-v2', + curveAddress: '0x6691FA63aa1d7E422Dc5D19C9B04F25909fdE966', + stakingAddress: '0xBA6F70c3dBcf712FA946A0C527c57eF7B654E2D5', + }, + { + name: 'dfx-eurs-usdc-v2', + curveAddress: '0x2385D7aB31F5a470B1723675846cb074988531da', + stakingAddress: '0xa1fcb23ce4f0aAEA0DE82B2a34c86fcC17D259Fd', + }, + { + name: 'dfx-ngnc-usdc-v2', + curveAddress: '0x7B95c61f05E9720b778e81d8794F0F5dCa704d1a', + stakingAddress: '0x210B640328D7089F67fdaa2CC0bad944fb8328F4', + }, + { + name: 'dfx-xsgd-usdc-v2', + curveAddress: '0xBc408da6A7237682c8672eF7a66AFF09a9069b15', + stakingAddress: '0x6f1b9BbD779286B39A19BB6aFBA914354365169c', + }, + { + name: 'dfx-tryb-usdc-v2', + curveAddress: '0xAAb708fBd208Ac262821E229ded16234277b2B13', + stakingAddress: '0x6E87a3B9E0A9de58b3C5FA81c93461E82Ee04e7b', + }, + ], + }, + arbitrum: { + url: 'https://api.goldsky.com/api/public/project_clasdk93949ub0h10a9lf9pkq/subgraphs/dfx-v2-arbi/latest/gn', + usesGauges: false, + stakingPools: [ + { + name: 'dfx-cadc-usdc-v2', + curveAddress: '0xcd8a5ea5c44a231cb42f13056f55c65af32cb565', + stakingAddress: '0x4c8411c5bba98223297388798d6d04ea6da7728a', + }, + { + name: 'dfx-gyen-usdc-v2', + curveAddress: '0x3c3BAdFBF97EC7CaEBFf761694DD642F2C8B11E8', + stakingAddress: '0xc63C6Bfe1E7EfCcfADcb2Eb4a0FD3B1b0e659e55', + }, + ], + }, +}; + +const gaugesUrl = + 'https://api.goldsky.com/api/public/project_clasdk93949ub0h10a9lf9pkq/subgraphs/dfx-ve/0.0.6/gn'; + +module.exports = { + chains, + gaugesUrl, +}; diff --git a/src/adaptors/dfx-v2/index.js b/src/adaptors/dfx-v2/index.js new file mode 100644 index 0000000000..cac976f5c0 --- /dev/null +++ b/src/adaptors/dfx-v2/index.js @@ -0,0 +1,332 @@ +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); +const { Web3 } = require('web3'); +const { chains, gaugesUrl } = require('./config'); +const StakingABI = require('./abis/abiStakingRewardsMulti.json'); + +const SECONDS_IN_YEAR = 3153600; +const UNBOOSTED_REWARD_RATIO = 0.4; + +//set up queries +const getBlockNumberQuery = gql` + query BlockNumSubgraph { + _meta { + block { + number + } + } + } +`; + +const getGaugesQuery = gql` + query DfxGauges_GetDfxGauges($blockNum: Int) { + gauges(where: { active: true }, block: { number: $blockNum }) { + id + decimals + symbol + lpt + lptAmount + workingSupply + totalSupply + dfxBalance + rewardCount + rewardsAvailable { + amount + token { + id + name + symbol + decimals + } + } + weight + proportionalWeight + startProportionalWeight + weightDelta + active + blockNum + } + } +`; + +const getTokenPairsQuery = gql` + query DfxCurvesStats_GetDfxPairs($blockNum: Int) { + pairs(block: { number: $blockNum }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + name + } + token1 { + symbol + id + name + } + } + } +`; + +//set up web3 providers +const web3_Poly = new Web3(process.env.ALCHEMY_CONNECTION_POLYGON); +const web3_Arb = new Web3(process.env.ALCHEMY_CONNECTION_ARBITRUM); + +//functional code starts here +const buildPool = (entry, chainString) => { + const symbol = utils.formatSymbol( + `${entry.token0.symbol}-${entry.token1.symbol}` + ); + + const newPool = { + pool: entry.id, + chain: utils.formatChain(chainString), + project: 'dfx-v2', + symbol, + tvlUsd: entry.totalValueLockedUSD, + rewardTokens: entry.rewardsTokens, + apyReward: entry.apyReward, + apyBase: entry.apy1d, + apyBase7d: entry.apy7d, + underlyingTokens: [entry.token0.id, entry.token1.id], + volumeUsd1d: entry.volumeUSD1d, + volumeUsd7d: entry.volumeUSD7d, + }; + + return newPool; +}; + +const calculateRewardsFromContracts = async ( + chainString, + entry, + stakingAddress +) => { + const web3 = chainString === 'polygon' ? web3_Poly : web3_Arb; + const stakingContract = new web3.eth.Contract(StakingABI, stakingAddress); + + const rewardsDuration = await stakingContract.methods + .rewardsDuration() + .call(); + + const rewardForDuration = await stakingContract.methods + .getRewardForDuration() + .call(); + + const rewardsAvailable = []; + + for (let i = 0; i < rewardForDuration.length; i++) { + const rewardToken = await stakingContract.methods.rewardsTokens(i).call(); + + rewardsAvailable.push({ + token: rewardToken, + amount: rewardForDuration[i], + }); + } + + entry.rewardsTokens = rewardsAvailable.map((reward) => + reward.token.toLowerCase() + ); + + const { pricesByAddress } = await utils.getPrices( + entry.rewardsTokens, + chainString + ); + + const rewardsAmountUSDForDuration = rewardsAvailable.reduce((acc, reward) => { + return ( + acc + + (pricesByAddress[reward.token.toLowerCase()] * Number(reward.amount)) / + 1e18 + ); + }, 0); + + //reward amounts are based on duration which is in seconds so we divide by seconds in a year + entry.apyReward = + (rewardsAmountUSDForDuration / entry.totalValueLockedUSD) * + (SECONDS_IN_YEAR / Number(rewardsDuration)) * + 100; + + return entry; +}; + +const calculateRewardsFromGauges = async ( + chainString, + entry, + gauges, + stakingAddress +) => { + const gauge = gauges.find( + (gauge) => gauge.id == stakingAddress.toLowerCase() + ); + + entry.rewardsTokens = gauge.rewardsAvailable.map((reward) => + reward.token.id.toLowerCase() + ); + + const { pricesByAddress } = await utils.getPrices( + entry.rewardsTokens, + chainString + ); + + const gaugeProporationalWeight = + (UNBOOSTED_REWARD_RATIO * gauge.totalSupply) / gauge.workingSupply; + + const rewardsAmountUSDForWeek = gauge.rewardsAvailable.reduce( + (acc, reward) => { + return ( + acc + + pricesByAddress[reward.token.id.toLowerCase()] * + (reward.amount * gaugeProporationalWeight) + ); + }, + 0 + ); + + //rewards amounts are per week, so we multiply by 52 + entry.apyReward = + (rewardsAmountUSDForWeek / entry.totalValueLockedUSD) * 52 * 100; + + return entry; +}; + +const calculateRewardsApy = async (chainString, entry, gauges, chain) => { + entry.rewardsTokens = []; + entry.apyReward = 0; + + const pool = chain.stakingPools.find( + (f) => f.curveAddress.toLowerCase() === entry.id.toLowerCase() + ); + + if (!pool) { + return entry; + } + const stakingAddress = pool.stakingAddress; + + if (chainString != 'ethereum') { + entry = await calculateRewardsFromContracts( + chainString, + entry, + stakingAddress + ); + } else { + entry = await calculateRewardsFromGauges( + chainString, + entry, + gauges, + stakingAddress + ); + } + + return entry; +}; + +const processPoolsOnChain = async (chainString, chain, timestamp, version) => { + const url = chain.url; + + //determine starting blocks + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let data = ( + await request(url, getTokenPairsQuery, { + blockNum: block, + }) + ).pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, getTokenPairsQuery, { + blockNum: blockPrior, + }) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, getTokenPairsQuery, { + blockNum: blockPrior7d, + }) + ).pairs; + + let gauges = []; + + if (chainString === 'ethereum') { + gauges = ( + await request(gaugesUrl, getGaugesQuery, { + blockNum: block, + }) + ).gauges; + } + + // calculate tvl + data = await utils.tvl(data, chainString); + + // calculate apy + data = data.map((entity) => + utils.apy(entity, dataPrior, dataPrior7d, version) + ); + + //ensure we have staking pool address and if not then filter out + data = data.map((entity) => { + const pool = chain.stakingPools.find( + (f) => f.curveAddress.toLowerCase() === entity.id.toLowerCase() + ); + + if (!pool) { + entity.stakingAddress = null; + return entity; + } + entity.stakingAddress = pool.stakingAddress; + return entity; + }); + + data = data.filter((entity) => entity.stakingAddress != null); + + data = await Promise.all( + data.map( + async (entity) => + await calculateRewardsApy(chainString, entity, gauges, chain) + ) + ); + + // build pool objects + data = data.map((entity) => buildPool(entity, chainString)); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all( + Object.keys(chains).map(async (chainString) => { + const chain = chains[chainString]; + + return await processPoolsOnChain( + chainString, + chain, + timestamp, + 'arbidex' + ); + }) + ); + + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://exchange.dfx.finance/pools', +}; diff --git a/src/adaptors/dinero-(pxeth)/index.js b/src/adaptors/dinero-(pxeth)/index.js new file mode 100644 index 0000000000..8ce7271b93 --- /dev/null +++ b/src/adaptors/dinero-(pxeth)/index.js @@ -0,0 +1,34 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const token = '0x9ba021b0a9b958b5e75ce9f6dff97c7ee52cb3e6'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const apyData = (await axios.get('https://dinero.xyz/api/apr')).data; + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'dinero-(pxeth)', + symbol: 'apxeth', + tvlUsd: tvl * ethPrice, + apyBase: Number(apyData.apxEth), + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://dineroismoney.com/pxeth/deposit', +}; diff --git a/src/adaptors/dogium-farm/abis/lp.json b/src/adaptors/dogium-farm/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/dogium-farm/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/dogium-farm/abis/masterchef.json b/src/adaptors/dogium-farm/abis/masterchef.json new file mode 100644 index 0000000000..6403e477a4 --- /dev/null +++ b/src/adaptors/dogium-farm/abis/masterchef.json @@ -0,0 +1,644 @@ +[ + { + "type": "constructor", + "stateMutability": "nonpayable", + "inputs": [ + { + "type": "address", + "name": "_dogium", + "internalType": "contract DogiumToken" + }, + { + "type": "address", + "name": "_feeAddress", + "internalType": "address" + }, + { + "type": "uint256", + "name": "_dogiumPerSecond", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_startTimestamp", + "internalType": "uint256" + } + ] + }, + { + "type": "event", + "name": "Deposit", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyWithdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetFeeAddress", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newAddress", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "UpdateStartTimestamp", + "inputs": [ + { + "type": "uint256", + "name": "newStartTimestamp", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Withdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "addPool", + "inputs": [ + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "address", + "name": "lpToken", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "allocPoint", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "depositFeeBP", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "setPool", + "inputs": [ + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "address", + "name": "lpToken", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "allocPoint", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "depositFeeBP", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "add", + "inputs": [ + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + }, + { + "type": "bool", + "name": "_withUpdate", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "deposit", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract DogiumToken" + } + ], + "name": "dogium", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "dogiumMaximumSupply", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "dogiumPerSecond", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "emergencyWithdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "emmissionEndTimestamp", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "feeAddress", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "getMultiplier", + "inputs": [ + { + "type": "uint256", + "name": "_from", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_to", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "massUpdatePools", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "pendingDogium", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_user", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "bool", + "name": "", + "internalType": "bool" + } + ], + "name": "poolExistence", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IERC20" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint256", + "name": "allocPoint", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "lastRewardTimestamp", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accDogiumPerShare", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "depositFeeBP", + "internalType": "uint16" + }, + { + "type": "uint256", + "name": "lpSupply", + "internalType": "uint256" + } + ], + "name": "poolInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "poolLength", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "set", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + }, + { + "type": "bool", + "name": "_withUpdate", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setFeeAddress", + "inputs": [ + { + "type": "address", + "name": "_feeAddress", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setStartTimestamp", + "inputs": [ + { + "type": "uint256", + "name": "_newStartTimestamp", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "startTimestamp", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "totalAllocPoint", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { + "type": "address", + "name": "newOwner", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updatePool", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "amount", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "rewardDebt", + "internalType": "uint256" + } + ], + "name": "userInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + }, + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "withdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/dogium-farm/index.js b/src/adaptors/dogium-farm/index.js new file mode 100644 index 0000000000..353ba9e9ea --- /dev/null +++ b/src/adaptors/dogium-farm/index.js @@ -0,0 +1,269 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const DogiumToken = '0x55bd2a3904c09547c3a5899704f1207ee61878be'; +const DogiumUSDCLP = '0x6E08Bcb7c2289E6Aa0BD17d0dDED2D788ab2e8D5'; +const MASTERCHEF_ADDRESS = '0x579BACCd9DdF3D9e652174c0714DBC0CD4700dF2'; +const BLOCK_TIME = 2; +const SECOND_IN_YEAR = 86400 * 365; + +const mapTokenDogeChaintoBSC = { + '0x765277EebeCA2e31912C9946eAe1021199B39C61': + '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // USDC + '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101': + '0xba2ae424d960c26247dd6c32edc70b295c744c43', // WWDOGE + '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D': + '0x55d398326f99059fF775485246999027B3197955', // usdt, + '0x332730a4F6E03D9C55829435f10360E13cfA41Ff': + '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', // busd, + '0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F': + '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', // bnb +}; + +const mapTokenBSCtoDogeChain = { + '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d': + '0x765277EebeCA2e31912C9946eAe1021199B39C61', + '0xba2ae424d960c26247dd6c32edc70b295c744c43': + '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101', + '0x55d398326f99059ff775485246999027b3197955': + '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', + '0xe9e7cea3dedca5984780bafc599bd69add087d56': + '0x332730a4F6E03D9C55829435f10360E13cfA41Ff', + '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c': + '0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F', +}; + +const EXCLUDE = [ + '0x55BD2a3904C09547c3A5899704f1207eE61878Be', + '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101', + '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', + '0x765277EebeCA2e31912C9946eAe1021199B39C61', + '0x7B4328c127B85369D9f82ca0503B000D09CF9180', + '0xB44a9B6905aF7c801311e8F4E76932ee959c663C', +]; + +const getPriceByReserves = async (lpAddress) => { + const reserves = await sdk.api.abi.call({ + target: lpAddress, + chain: 'dogechain', + abi: lpABI.find((e) => e.name === 'getReserves'), + }); + return reserves.output[1] / reserves.output[0]; +}; + +const getPairInfo = async (pair, tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'dogechain', + requery: true, + }) + ) + ); + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${mapTokenDogeChaintoBSC[address]}`) + .join(',') + .toLowerCase(); + + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [mapTokenBSCtoDogeChain[address.split(':')[1]].toLowerCase()]: + price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + dogiumPerSecond, + dogiumPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const dogiumPerYear = BigNumber(dogiumPerSecond) + .times(SECOND_IN_YEAR) + .times(poolWeight); + const apy = dogiumPerYear.times(dogiumPrice).div(reserveUSD).times(100); + return apy.toNumber(); +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const dogiumPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'dogiumPerSecond'), + }); + const normalizeddogiumPerBlock = dogiumPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'dogechain', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter((k) => !EXCLUDE.includes(k.lpToken)); + + const lpTokens = pools.map(({ lpToken }) => lpToken); + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'dogechain', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'dogechain', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + + const gogium = await getPriceByReserves(DogiumUSDCLP); + tokensPrices[DogiumToken.toLowerCase()] = gogium * 10 ** 12; + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairInfos[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizeddogiumPerBlock, + tokensPrices[DogiumToken.toLowerCase()], + masterChefReservesUsd + ); + + return { + pool: pool.lpToken + '-dogechain', + chain: utils.formatChain('dogechain'), + project: 'dogium-farm', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [DogiumToken], + }; + }); + + return res.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://lithium.dog/', +}; diff --git a/src/adaptors/dolomite/dolomite-margin-abi.js b/src/adaptors/dolomite/dolomite-margin-abi.js new file mode 100644 index 0000000000..5f0a57f300 --- /dev/null +++ b/src/adaptors/dolomite/dolomite-margin-abi.js @@ -0,0 +1,1130 @@ +module.exports = [{ + "inputs": [{ + "components": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginRatio", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "liquidationSpread", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "earningsRate", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "minBorrowedValue", + "type": "tuple" + }, { "internalType": "uint256", "name": "accountMaxNumberOfMarketsWithBalances", "type": "uint256" }], + "internalType": "struct Storage.RiskParams", + "name": "riskParams", + "type": "tuple" + }, { + "components": [{ + "internalType": "uint64", + "name": "marginRatioMax", + "type": "uint64" + }, { "internalType": "uint64", "name": "liquidationSpreadMax", "type": "uint64" }, { + "internalType": "uint64", + "name": "earningsRateMax", + "type": "uint64" + }, { "internalType": "uint64", "name": "marginPremiumMax", "type": "uint64" }, { + "internalType": "uint64", + "name": "spreadPremiumMax", + "type": "uint64" + }, { "internalType": "uint128", "name": "minBorrowedValueMax", "type": "uint128" }], + "internalType": "struct Storage.RiskLimits", + "name": "riskLimits", + "type": "tuple" + }], "payable": false, "stateMutability": "nonpayable", "type": "constructor" +}, { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + }, { "indexed": false, "internalType": "bool", "name": "trusted", "type": "bool" }], + "name": "LogOperatorSet", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "OwnershipTransferred", + "type": "event" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountBalances", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }, { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, { + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint128", + "name": "value", + "type": "uint128" + }], "internalType": "struct Types.Par[]", "name": "", "type": "tuple[]" + }, { + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei[]", "name": "", "type": "tuple[]" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }, { "internalType": "uint256", "name": "index", "type": "uint256" }], + "name": "getAccountMarketWithBalanceAtIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountMarketsWithBalances", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getAccountMaxNumberOfMarketsWithBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountNumberOfMarketsWithBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountNumberOfMarketsWithDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }, { "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getAccountPar", + "outputs": [{ + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint128", + "name": "value", + "type": "uint128" + }], "internalType": "struct Types.Par", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }, { "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getAccountParNoMarketCheck", + "outputs": [{ + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint128", + "name": "value", + "type": "uint128" + }], "internalType": "struct Types.Par", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountStatus", + "outputs": [{ "internalType": "enum Account.Status", "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAccountValues", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }, { "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getAccountWei", + "outputs": [{ + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info", + "name": "account", + "type": "tuple" + }], + "name": "getAdjustedAccountValues", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getEarningsRate", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "address", "name": "autoTrader", "type": "address" }], + "name": "getIsAutoTraderSpecial", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "address", "name": "operator", "type": "address" }], + "name": "getIsGlobalOperator", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }, { + "internalType": "address", + "name": "operator", + "type": "address" + }], + "name": "getIsLocalOperator", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getLiquidationSpread", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "heldMarketId", "type": "uint256" }, { + "internalType": "uint256", + "name": "owedMarketId", + "type": "uint256" + }], + "name": "getLiquidationSpreadForPair", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getMarginRatio", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarket", + "outputs": [{ + "components": [{ "internalType": "address", "name": "token", "type": "address" }, { + "internalType": "bool", + "name": "isClosing", + "type": "bool" + }, { "internalType": "bool", "name": "isRecyclable", "type": "bool" }, { + "components": [{ + "internalType": "uint128", + "name": "borrow", + "type": "uint128" + }, { "internalType": "uint128", "name": "supply", "type": "uint128" }], + "internalType": "struct Types.TotalPar", + "name": "totalPar", + "type": "tuple" + }, { + "components": [{ "internalType": "uint96", "name": "borrow", "type": "uint96" }, { + "internalType": "uint96", + "name": "supply", + "type": "uint96" + }, { "internalType": "uint32", "name": "lastUpdate", "type": "uint32" }], + "internalType": "struct Interest.Index", + "name": "index", + "type": "tuple" + }, { + "internalType": "contract IPriceOracle", + "name": "priceOracle", + "type": "address" + }, { + "internalType": "contract IInterestSetter", + "name": "interestSetter", + "type": "address" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginPremium", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "spreadPremium", + "type": "tuple" + }, { + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei", "name": "maxWei", "type": "tuple" + }], "internalType": "struct Storage.Market", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketCachedIndex", + "outputs": [{ + "components": [{ + "internalType": "uint96", + "name": "borrow", + "type": "uint96" + }, { "internalType": "uint96", "name": "supply", "type": "uint96" }, { + "internalType": "uint32", + "name": "lastUpdate", + "type": "uint32" + }], "internalType": "struct Interest.Index", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketCurrentIndex", + "outputs": [{ + "components": [{ + "internalType": "uint96", + "name": "borrow", + "type": "uint96" + }, { "internalType": "uint96", "name": "supply", "type": "uint96" }, { + "internalType": "uint32", + "name": "lastUpdate", + "type": "uint32" + }], "internalType": "struct Interest.Index", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "address", "name": "token", "type": "address" }], + "name": "getMarketIdByTokenAddress", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketInterestRate", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Interest.Rate", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketInterestSetter", + "outputs": [{ "internalType": "contract IInterestSetter", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketIsClosing", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketIsRecyclable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketMarginPremium", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketMaxWei", + "outputs": [{ + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketPrice", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Price", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketPriceOracle", + "outputs": [{ "internalType": "contract IPriceOracle", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketSpreadPremium", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketTokenAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketTotalPar", + "outputs": [{ + "components": [{ + "internalType": "uint128", + "name": "borrow", + "type": "uint128" + }, { "internalType": "uint128", "name": "supply", "type": "uint128" }], + "internalType": "struct Types.TotalPar", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getMarketWithInfo", + "outputs": [{ + "components": [{ "internalType": "address", "name": "token", "type": "address" }, { + "internalType": "bool", + "name": "isClosing", + "type": "bool" + }, { "internalType": "bool", "name": "isRecyclable", "type": "bool" }, { + "components": [{ + "internalType": "uint128", + "name": "borrow", + "type": "uint128" + }, { "internalType": "uint128", "name": "supply", "type": "uint128" }], + "internalType": "struct Types.TotalPar", + "name": "totalPar", + "type": "tuple" + }, { + "components": [{ "internalType": "uint96", "name": "borrow", "type": "uint96" }, { + "internalType": "uint96", + "name": "supply", + "type": "uint96" + }, { "internalType": "uint32", "name": "lastUpdate", "type": "uint32" }], + "internalType": "struct Interest.Index", + "name": "index", + "type": "tuple" + }, { + "internalType": "contract IPriceOracle", + "name": "priceOracle", + "type": "address" + }, { + "internalType": "contract IInterestSetter", + "name": "interestSetter", + "type": "address" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginPremium", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "spreadPremium", + "type": "tuple" + }, { + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei", "name": "maxWei", "type": "tuple" + }], "internalType": "struct Storage.Market", "name": "", "type": "tuple" + }, { + "components": [{ "internalType": "uint96", "name": "borrow", "type": "uint96" }, { + "internalType": "uint96", + "name": "supply", + "type": "uint96" + }, { "internalType": "uint32", "name": "lastUpdate", "type": "uint32" }], + "internalType": "struct Interest.Index", + "name": "", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Price", + "name": "", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Interest.Rate", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getMinBorrowedValue", + "outputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }], + "name": "getNumExcessTokens", + "outputs": [{ + "components": [{ "internalType": "bool", "name": "sign", "type": "bool" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.Wei", "name": "", "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getNumMarkets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [{ "internalType": "uint256", "name": "n", "type": "uint256" }], + "name": "getRecyclableMarkets", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getRiskLimits", + "outputs": [{ + "components": [{ + "internalType": "uint64", + "name": "marginRatioMax", + "type": "uint64" + }, { "internalType": "uint64", "name": "liquidationSpreadMax", "type": "uint64" }, { + "internalType": "uint64", + "name": "earningsRateMax", + "type": "uint64" + }, { "internalType": "uint64", "name": "marginPremiumMax", "type": "uint64" }, { + "internalType": "uint64", + "name": "spreadPremiumMax", + "type": "uint64" + }, { "internalType": "uint128", "name": "minBorrowedValueMax", "type": "uint128" }], + "internalType": "struct Storage.RiskLimits", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "getRiskParams", + "outputs": [{ + "components": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginRatio", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "liquidationSpread", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "earningsRate", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "minBorrowedValue", + "type": "tuple" + }, { "internalType": "uint256", "name": "accountMaxNumberOfMarketsWithBalances", "type": "uint256" }], + "internalType": "struct Storage.RiskParams", + "name": "", + "type": "tuple" + }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "isOwner", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "owner", + "type": "address" + }, { "internalType": "uint256", "name": "number", "type": "uint256" }], + "internalType": "struct Account.Info[]", + "name": "accounts", + "type": "tuple[]" + }, { + "components": [{ + "internalType": "enum Actions.ActionType", + "name": "actionType", + "type": "uint8" + }, { "internalType": "uint256", "name": "accountId", "type": "uint256" }, { + "components": [{ + "internalType": "bool", + "name": "sign", + "type": "bool" + }, { + "internalType": "enum Types.AssetDenomination", + "name": "denomination", + "type": "uint8" + }, { "internalType": "enum Types.AssetReference", "name": "ref", "type": "uint8" }, { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], "internalType": "struct Types.AssetAmount", "name": "amount", "type": "tuple" + }, { "internalType": "uint256", "name": "primaryMarketId", "type": "uint256" }, { + "internalType": "uint256", + "name": "secondaryMarketId", + "type": "uint256" + }, { "internalType": "address", "name": "otherAddress", "type": "address" }, { + "internalType": "uint256", + "name": "otherAccountId", + "type": "uint256" + }, { "internalType": "bytes", "name": "data", "type": "bytes" }], + "internalType": "struct Actions.ActionArgs[]", + "name": "actions", + "type": "tuple[]" + }], + "name": "operate", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "internalType": "address", + "name": "token", + "type": "address" + }, { + "internalType": "contract IPriceOracle", + "name": "priceOracle", + "type": "address" + }, { + "internalType": "contract IInterestSetter", + "name": "interestSetter", + "type": "address" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginPremium", + "type": "tuple" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "spreadPremium", + "type": "tuple" + }, { "internalType": "uint256", "name": "maxWei", "type": "uint256" }, { + "internalType": "bool", + "name": "isClosing", + "type": "bool" + }, { "internalType": "bool", "name": "isRecyclable", "type": "bool" }], + "name": "ownerAddMarket", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "uint256[]", "name": "marketIds", "type": "uint256[]" }, { + "internalType": "address", + "name": "salvager", + "type": "address" + }], + "name": "ownerRemoveMarkets", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "uint256", "name": "accountMaxNumberOfMarketsWithBalances", "type": "uint256" }], + "name": "ownerSetAccountMaxNumberOfMarketsWithBalances", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "address", "name": "autoTrader", "type": "address" }, { + "internalType": "bool", + "name": "special", + "type": "bool" + }], + "name": "ownerSetAutoTraderSpecial", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "earningsRate", + "type": "tuple" + }], + "name": "ownerSetEarningsRate", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "address", "name": "operator", "type": "address" }, { + "internalType": "bool", + "name": "approved", + "type": "bool" + }], + "name": "ownerSetGlobalOperator", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "internalType": "uint256", + "name": "marketId", + "type": "uint256" + }, { "internalType": "contract IInterestSetter", "name": "interestSetter", "type": "address" }], + "name": "ownerSetInterestSetter", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }, { + "internalType": "bool", + "name": "isClosing", + "type": "bool" + }], + "name": "ownerSetIsClosing", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "spread", + "type": "tuple" + }], + "name": "ownerSetLiquidationSpread", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "internalType": "uint256", + "name": "marketId", + "type": "uint256" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "marginPremium", + "type": "tuple" + }], + "name": "ownerSetMarginPremium", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "ratio", + "type": "tuple" + }], + "name": "ownerSetMarginRatio", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }, { + "internalType": "uint256", + "name": "maxWei", + "type": "uint256" + }], + "name": "ownerSetMaxWei", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Monetary.Value", + "name": "minBorrowedValue", + "type": "tuple" + }], + "name": "ownerSetMinBorrowedValue", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "internalType": "uint256", + "name": "marketId", + "type": "uint256" + }, { "internalType": "contract IPriceOracle", "name": "priceOracle", "type": "address" }], + "name": "ownerSetPriceOracle", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "internalType": "uint256", + "name": "marketId", + "type": "uint256" + }, { + "components": [{ "internalType": "uint256", "name": "value", "type": "uint256" }], + "internalType": "struct Decimal.D256", + "name": "spreadPremium", + "type": "tuple" + }], + "name": "ownerSetSpreadPremium", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "uint256", "name": "marketId", "type": "uint256" }, { + "internalType": "address", + "name": "recipient", + "type": "address" + }], + "name": "ownerWithdrawExcessTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "address", "name": "token", "type": "address" }, { + "internalType": "address", + "name": "recipient", + "type": "address" + }], + "name": "ownerWithdrawUnsupportedTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "operator", + "type": "address" + }, { "internalType": "bool", "name": "trusted", "type": "bool" }], + "internalType": "struct Types.OperatorArg[]", + "name": "args", + "type": "tuple[]" + }], + "name": "setOperators", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}, { + "constant": false, + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" +}]; diff --git a/src/adaptors/dolomite/index.js b/src/adaptors/dolomite/index.js new file mode 100644 index 0000000000..7a8cb85334 --- /dev/null +++ b/src/adaptors/dolomite/index.js @@ -0,0 +1,237 @@ +const dolomiteMarginAbi = require('./dolomite-margin-abi.js'); +const isolationModeAbi = require('./isolation-mode-token-abi.js'); +const sdk = require('@defillama/sdk'); + +const DOLOMITE_MARGIN_ADDRESS_MAP = { + arbitrum: '0x6Bd780E7fDf01D77e4d475c821f1e7AE05409072', + berachain: '0x003Ca23Fd5F0ca87D01F6eC6CD14A8AE60c2b97D', + ethereum: '0x003Ca23Fd5F0ca87D01F6eC6CD14A8AE60c2b97D', +}; + +async function apy() { + const allPools = await Promise.all( + Object.entries(DOLOMITE_MARGIN_ADDRESS_MAP).map( + async ([chain, dolomiteMargin]) => { + const marginRatio = + Number( + ( + await sdk.api.abi.call({ + target: dolomiteMargin, + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarginRatio'), + chain: chain, + permitFailure: true, + }) + ).output + ) / 1e18; + + const earningsRate = + Number( + ( + await sdk.api.abi.call({ + target: dolomiteMargin, + abi: dolomiteMarginAbi.find((i) => i.name === 'getEarningsRate'), + chain: chain, + permitFailure: true, + }) + ).output + ) / 1e18; + + const numMarkets = Number( + ( + await sdk.api.abi.call({ + target: dolomiteMargin, + abi: dolomiteMarginAbi.find((i) => i.name === 'getNumMarkets'), + chain: chain, + permitFailure: true, + }) + ).output + ); + const range = [...Array(numMarkets).keys()]; + + // contains token addresses and c-factors + const tokensRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketTokenAddress'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const tokens = tokensRes.output.map((o) => o.output); + + const borrowablesRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketIsClosing'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const borrowables = borrowablesRes.output.map((o) => !o.output); + + const totalParsRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketTotalPar'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const totalPars = totalParsRes.output.map((o) => o.output); + + const indicesRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketCurrentIndex'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const indices = indicesRes.output.map((o) => o.output); + + const pricesRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketPrice'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const prices = pricesRes.output.map((o) => o.output); + + const interestRatesRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketInterestRate'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const interestRates = interestRatesRes.output.map((o) => o.output); + + const marginPremiumsRes = await sdk.api.abi.multiCall({ + abi: dolomiteMarginAbi.find((i) => i.name === 'getMarketMarginPremium'), + calls: range.map((i) => ({ + target: dolomiteMargin, + params: i, + })), + chain: chain, + permitFailure: true, + }); + const marginPremiums = marginPremiumsRes.output.map( + (o) => Number(o.output) / 1e18 + ); + + const symbolsRes = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((t) => ({ + target: t, + })), + chain: chain, + permitFailure: true, + }); + const symbols = symbolsRes.output.map((o) => o.output); + + const namesRes = await sdk.api.abi.multiCall({ + abi: isolationModeAbi.find((i) => i.name === 'name'), + calls: tokens.map((t) => ({ + target: t, + })), + chain: chain, + permitFailure: true, + }); + const names = namesRes.output.map((o) => o.output); + + for (let i = 0; i < names.length; i++) { + if (names[i] === 'Dolomite Isolation: Arbitrum' || names[i] === 'GMX' || names[i] === 'Infrared BGT') { + tokens[i] = undefined; + symbols[i] = undefined; + } else if ( + names[i] === 'Dolomite: Fee + Staked GLP' || + names[i].includes('Dolomite Isolation:') + ) { + const underlyingToken = await sdk.api.abi.call({ + abi: isolationModeAbi.find((i) => i.name === 'UNDERLYING_TOKEN'), + target: tokens[i], + chain: chain, + }); + tokens[i] = underlyingToken.output; + symbols[i] = symbols[i].substring(1); // strip the 'd' from the symbol + } + } + + const supplyWeis = totalPars.map( + (totalPar, i) => + (Number(totalPar.supply) * Number(indices[i].supply)) / 1e18 + ); + const borrowWeis = totalPars.map( + (totalPar, i) => + (Number(totalPar.borrow) * Number(indices[i].borrow)) / 1e18 + ); + const supplyUsds = supplyWeis.map( + (supplyWei, i) => (supplyWei * prices[i]) / 1e36 + ); + const borrowUsds = borrowWeis.map( + (borrowWei, i) => (borrowWei * prices[i]) / 1e36 + ); + + const secondsInYear = 31_536_000; + const borrowInterestRateApys = interestRates.map((interestRate) => { + const apr = (Number(interestRate) * secondsInYear) / 1e18; + return (Math.pow(1 + apr / 365, 365) - 1) * 100; + }); + const supplyInterestRateApys = borrowInterestRateApys.map( + (interestRate, i) => { + if (interestRate === 0) { + return 0; + } else { + return ( + (interestRate * earningsRate * borrowWeis[i]) / supplyWeis[i] + ); + } + } + ); + + return range.reduce((acc, i) => { + if (tokens[i]) { + acc.push({ + pool: `${tokens[i]}-dolomite-${chain}`.toLowerCase(), + symbol: symbols[i], + chain: chain.charAt(0).toUpperCase() + chain.slice(1), + project: 'dolomite', + tvlUsd: supplyUsds[i] - borrowUsds[i], + apyBase: supplyInterestRateApys[i], + apyReward: 0, + underlyingTokens: [tokens[i]], + rewardTokens: [], + apyBaseBorrow: borrowInterestRateApys[i], + apyRewardBorrow: 0, + totalSupplyUsd: supplyUsds[i], + totalBorrowUsd: borrowUsds[i], + ltv: 1 / (1 + marginRatio + (1 + marginRatio) * marginPremiums[i]), + poolMeta: 'Dolomite Balance', + url: `https://app.dolomite.io/stats/token/${tokens[ + i + ].toLowerCase()}`, + borrowable: borrowables[i], + }); + } + return acc; + }, []); + }) + ); + + return allPools.flat(); +} + +module.exports = { + timetravel: true, + apy, + url: 'https://app.dolomite.io/stats', +}; diff --git a/src/adaptors/dolomite/isolation-mode-token-abi.js b/src/adaptors/dolomite/isolation-mode-token-abi.js new file mode 100644 index 0000000000..9da63fe766 --- /dev/null +++ b/src/adaptors/dolomite/isolation-mode-token-abi.js @@ -0,0 +1,388 @@ +module.exports = [{ + "inputs": [{ + "internalType": "address", + "name": "_plutusVaultRegistry", + "type": "address" + }, { "internalType": "address", "name": "_plvGlp", "type": "address" }, { + "internalType": "address", + "name": "_borrowPositionProxy", + "type": "address" + }, { "internalType": "address", "name": "_userVaultImplementation", "type": "address" }, { + "internalType": "address", + "name": "_dolomiteMargin", + "type": "address" + }], "stateMutability": "nonpayable", "type": "constructor" +}, { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], + "name": "Approval", + "type": "event" +}, { "anonymous": false, "inputs": [], "name": "Initialized", "type": "event" }, { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "_plutusVaultRegistry", "type": "address" }], + "name": "PlutusVaultRegistrySet", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "address", + "name": "tokenConverter", + "type": "address" + }, { "indexed": false, "internalType": "bool", "name": "isTrusted", "type": "bool" }], + "name": "TokenConverterSet", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }], + "name": "Transfer", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "uint256", + "name": "transferCursor", + "type": "uint256" + }, { "indexed": false, "internalType": "address", "name": "from", "type": "address" }, { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, { "indexed": false, "internalType": "uint256", "name": "amountWei", "type": "uint256" }, { + "indexed": false, + "internalType": "address", + "name": "vault", + "type": "address" + }], + "name": "TransferQueued", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "address", + "name": "previousUserVaultImplementation", + "type": "address" + }, { "indexed": true, "internalType": "address", "name": "newUserVaultImplementation", "type": "address" }], + "name": "UserVaultImplementationSet", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { + "indexed": false, + "internalType": "address", + "name": "vault", + "type": "address" + }], + "name": "VaultCreated", + "type": "event" +}, { + "inputs": [], + "name": "BORROW_POSITION_PROXY", + "outputs": [{ "internalType": "contract IBorrowPositionProxyV2", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "DOLOMITE_MARGIN", + "outputs": [{ "internalType": "contract IDolomiteMargin", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "NONE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "allowableCollateralMarketIds", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [], + "name": "allowableDebtMarketIds", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }, { + "internalType": "address", + "name": "spender", + "type": "address" + }], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "name": "calculateVaultByAccount", + "outputs": [{ "internalType": "address", "name": "_vault", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "name": "createVault", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "_toAccountNumber", + "type": "uint256" + }, { "internalType": "uint256", "name": "_amountWei", "type": "uint256" }], + "name": "createVaultAndDepositIntoDolomiteMargin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + }], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "_toAccountNumber", + "type": "uint256" + }, { "internalType": "uint256", "name": "_amountWei", "type": "uint256" }], + "name": "depositIntoDolomiteMargin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "_toAccountNumber", + "type": "uint256" + }, { "internalType": "uint256", "name": "_otherMarketId", "type": "uint256" }, { + "internalType": "uint256", + "name": "_amountWei", + "type": "uint256" + }], + "name": "depositOtherTokenIntoDolomiteMarginForVaultOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_vault", "type": "address" }, { + "internalType": "uint256", + "name": "_amountWei", + "type": "uint256" + }], "name": "enqueueTransferFromDolomiteMargin", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_vault", "type": "address" }, { + "internalType": "uint256", + "name": "_amountWei", + "type": "uint256" + }], "name": "enqueueTransferIntoDolomiteMargin", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_vault", "type": "address" }], + "name": "getAccountByVault", + "outputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getProxyVaultInitCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [{ "internalType": "uint256", "name": "_transferCursor", "type": "uint256" }], + "name": "getQueuedTransferByCursor", + "outputs": [{ + "components": [{ + "internalType": "address", + "name": "from", + "type": "address" + }, { "internalType": "address", "name": "to", "type": "address" }, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, { "internalType": "address", "name": "vault", "type": "address" }, { + "internalType": "bool", + "name": "isExecuted", + "type": "bool" + }], "internalType": "struct IWrappedTokenUserVaultFactory.QueuedTransfer", "name": "", "type": "tuple" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_account", "type": "address" }], + "name": "getVaultByAccount", + "outputs": [{ "internalType": "address", "name": "_vault", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "spender", "type": "address" }, { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + }], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "isInitialized", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "isIsolationAsset", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_tokenConverter", "type": "address" }], + "name": "isTokenConverterTrusted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "marketId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address[]", "name": "_tokenConverters", "type": "address[]" }], + "name": "ownerInitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_tokenConverter", "type": "address" }, { + "internalType": "bool", + "name": "_isTrusted", + "type": "bool" + }], "name": "ownerSetIsTokenConverterTrusted", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_plutusVaultRegistry", "type": "address" }], + "name": "ownerSetPlutusVaultRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "_userVaultImplementation", "type": "address" }], + "name": "ownerSetUserVaultImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "plutusVaultRegistry", + "outputs": [{ "internalType": "contract IPlutusVaultRegistry", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "transferCursor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ "internalType": "address", "name": "from", "type": "address" }, { + "internalType": "address", + "name": "to", + "type": "address" + }, { "internalType": "uint256", "name": "amount", "type": "uint256" }], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "userVaultImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "_fromAccountNumber", + "type": "uint256" + }, { "internalType": "uint256", "name": "_amountWei", "type": "uint256" }], + "name": "withdrawFromDolomiteMargin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}]; diff --git a/src/adaptors/dot-dot-finance/index.ts b/src/adaptors/dot-dot-finance/index.ts new file mode 100644 index 0000000000..b073ad0b6d --- /dev/null +++ b/src/adaptors/dot-dot-finance/index.ts @@ -0,0 +1,80 @@ +const utils = require('../utils'); + +const API_URL: string = 'https://api.dotdot.finance/api/lpDetails'; +const STAKING_URL = 'https://api.dotdot.finance/api/pool2'; + +interface Pool { + pool: string; + token: string; + symbol: string; + dddAPR: number; + epxAPR: number; + extraRewardsTotalApr: number; + dddTvlUSD: number; + baseApr?: number; + extraRewards: Array<{ address: string }>; +} + +interface Staking { + data: { + token0: string; + token1: string; + symbol0: string; + symbol1: string; + totalLpStakedUSD: number; + apr: number; + }; +} + +interface Response { + data: { tokens: Array }; +} + +const getApy = async () => { + const { + data: { tokens }, + }: Response = await utils.getData(API_URL); + const { data: staking }: Staking = await utils.getData(STAKING_URL); + + const stakingPool = { + pool: `${staking.token0}-dot-dot-finance`, + chain: utils.formatChain('binance'), + project: 'dot-dot-finance', + symbol: `${staking.symbol0}-${staking.symbol1}`, + tvlUsd: staking.totalLpStakedUSD, + apyReward: staking.apr, + underlyingTokens: [staking.token0, staking.token1], + rewardTokens: [staking.token0], + }; + + const pools = tokens.map((pool) => { + const apyReward = + pool.dddAPR + pool.epxAPR + (pool.extraRewardsTotalApr || 0); + return { + pool: `${pool.pool}-dot-dot-finance`, + chain: utils.formatChain('binance'), + project: 'dot-dot-finance', + symbol: utils.formatSymbol( + pool.symbol.replace('val3EPS', 'valBUSD/valUSDC/valUSDT') + ), + tvlUsd: pool.dddTvlUSD, + apyReward, + apyBase: pool.baseApr || 0, + underlyingTokens: [pool.token], + rewardTokens: [ + '0xaf41054c1487b0e5e2b9250c0332ecbce6ce9d71', // EPX + '0x84c97300a190676a19D1E13115629A11f8482Bd1', // DDD, + ...pool.extraRewards.map(({ address }) => address), + ], + }; + }); + const res = [...pools, stakingPool].filter((p) => utils.keepFinite(p)); + + return res; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://dotdot.finance/#/stake', +}; diff --git a/src/adaptors/double-club/index.js b/src/adaptors/double-club/index.js new file mode 100644 index 0000000000..af34d27532 --- /dev/null +++ b/src/adaptors/double-club/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils'); +const URL = 'https://api.double.club/api/v1/getLPDetails'; +const DDDX = '0x4B6ee8188d6Df169E1071a7c96929640D61f144f'; +const DOU = '0x15330196e88a09637Bd2A8D206c7C85Fe99594D0'; +const main = async () => { + const { data } = await utils.getData(URL); + const pools = data.filter((e) => e.DoubleTVL); + + return pools + .map((pool) => { + const apy = + Number(pool.DoubleTVL.realdddxAPR || 0) + + Number(pool.DoubleTVL.realdouAPR || 0); + console.log(pool.symbol); + return { + pool: pool.poolAddress, + chain: utils.formatChain('binance'), + project: 'double-club', + symbol: utils.formatSymbol(pool.symbol.split('-')[1]), + tvlUsd: Number(pool.DoubleTVL.usdBalance), + apy: apy, + underlyingTokens: [pool.token0, pool.token1], + rewardTokens: [DDDX, DOU], + }; + }) + .filter((e) => e.tvlUsd !== 0) + .filter((k) => k.apy !== 0); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://double.club/', +}; diff --git a/src/adaptors/drift-staked-sol/index.js b/src/adaptors/drift-staked-sol/index.js new file mode 100644 index 0000000000..c20b008abe --- /dev/null +++ b/src/adaptors/drift-staked-sol/index.js @@ -0,0 +1,34 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); +const utils = require('../utils'); + +const DSOL_ADDRESS = 'Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ' +const priceKey = `solana:${DSOL_ADDRESS}`; + +const apy = async () => { + const totalSupply = await getTotalSupply(DSOL_ADDRESS); + + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const currentPrice = priceResponse.data.coins[priceKey].price; + + const driftResponse = await axios.get( + 'https://extra-api.sanctum.so/v1/apy/latest?lst=dSOL' + ); + const apy = driftResponse.data.apys.dSOL; + + return [ + { + pool: DSOL_ADDRESS, + chain: utils.formatChain('solana'), + project: 'drift-staked-sol', + symbol: 'dSOL', + tvlUsd: totalSupply * currentPrice, + apyBase: apy * 100, + underlyingTokens: [DSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://app.drift.trade/earn/dsol-liquid-staking' }; diff --git a/src/adaptors/drops/abi.js b/src/adaptors/drops/abi.js new file mode 100644 index 0000000000..6925649f98 --- /dev/null +++ b/src/adaptors/drops/abi.js @@ -0,0 +1,3582 @@ +module.exports = { + ercDelegator: [ + { + "inputs": [ + { + "internalType": "address", + "name": "underlying_", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "address payable", + "name": "admin_", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "becomeImplementationData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "NewImplementation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + } + ], + "name": "_addReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowResign", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "becomeImplementationData", + "type": "bytes" + } + ], + "name": "_setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "migration_", + "type": "address" + } + ], + "name": "_setMigration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "delegateToImplementation", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "delegateToViewImplementation", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract CTokenInterface", + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "migrate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "migration", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + } + ], + "name": "mints", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "redeemTokenIds", + "type": "uint256[]" + } + ], + "name": "redeems", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract EIP20NonStandardInterface", + "name": "token", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + comptrollerAbi: [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CompGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorCompSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setBorrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_comp", + "type": "address" + } + ], + "name": "_setCompAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cToken", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "_setCompSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setMintPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setSeizePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setTransferPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_upgradeSplitCompRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comp", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCompAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLiquidationExtraRepayAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLiquidationSeizeIndexes", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenExCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokensEx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], +}; diff --git a/src/adaptors/drops/index.js b/src/adaptors/drops/index.js new file mode 100755 index 0000000000..4a9b5076e4 --- /dev/null +++ b/src/adaptors/drops/index.js @@ -0,0 +1,274 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = { + P0: '0x79b56CB219901DBF42bB5951a0eDF27465F96206', + P1: '0xB70FB69a522ed8D4613C4C720F91F93a836EE2f5', + P2: '0x9dEb56b9DD04822924B90ad15d01EE50415f8bC7', + P3: '0x7312a3BC8733B068989Ef44bAC6344F07cFcDE7F', + P4: '0x3903E6EcD8bc610D5a01061B1Dc31affD21F81C6', +}; + +const CHAIN = 'ethereum'; +const GET_ALL_MARKETS = 'getAllMarkets'; + +const REWARD_SPEED_OG = 'compSpeeds'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const GET_CASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'drops'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'DOP', + address: '0x6bB61215298F296C55b19Ad842D3Df69021DA2ef'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (comptrollerAddress, markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: comptrollerAddress, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const getDropsPoolResult = async (dropsPool, comptrollerAddress) => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: comptrollerAddress, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + let allMarkets = Object.values(allMarketsRes); + + const marketsDecimal = await multiCallMarkets( + allMarkets, + 'decimals', + ercDelegator + ); + + allMarkets = allMarkets.filter((m, i) => Number(marketsDecimal[i])); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: comptrollerAddress, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards( + comptrollerAddress, + allMarkets, + comptrollerAddress == '0x79b56CB219901DBF42bB5951a0eDF27465F96206' + ? REWARD_SPEED_OG + : REWARD_SPEED + ); + const extraRewardsBorrow = await getRewards( + comptrollerAddress, + allMarkets, + comptrollerAddress == '0x79b56CB219901DBF42bB5951a0eDF27465F96206' + ? REWARD_SPEED_OG + : REWARD_SPEED_BORROW + ); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CASH, + ercDelegator + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const priceKey = 'coingecko:drops-ownership-power'; + const protocolTokenPrice = ( + await utils.getData(`https://coins.llama.fi/prices/current/${priceKey}`) + ).coins[priceKey]?.price; + + prices[PROTOCOL_TOKEN.address] = protocolTokenPrice; + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const tvlUsd = (marketsCash[i] / 10 ** decimals) * price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = totalSupplyUsd + ? calcRewardApy(extraRewards, totalSupplyUsd) + : 0; + const apyRewardBorrow = totalBorrowUsd + ? calcRewardApy(extraRewardsBorrow, totalBorrowUsd) + : 0; + + return { + pool: `${comptrollerAddress}-${market.toLowerCase()}`, + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + poolMeta: dropsPool, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter( + Boolean + ), + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return pools; + }; + + const dropsPoolsResult = []; + const proms = []; + Object.keys(COMPTROLLER_ADDRESS).forEach(async (dropsPool) => { + proms.push(getDropsPoolResult(dropsPool, COMPTROLLER_ADDRESS[dropsPool])); + }); + + (await Promise.all(proms)).map((pools) => { + dropsPoolsResult.push(...pools); + }); + + return dropsPoolsResult; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://drops.co/', +}; diff --git a/src/adaptors/dsf.finance/index.js b/src/adaptors/dsf.finance/index.js new file mode 100644 index 0000000000..5995f51a33 --- /dev/null +++ b/src/adaptors/dsf.finance/index.js @@ -0,0 +1,69 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const dsfPoolStables = '0x22586ea4fdaa9ef012581109b336f0124530ae69'; + +const abi = { + totalHoldings: "uint256:totalHoldings" +}; + +const collectPools = async () => { + + const tvl = await getTVL(dsfPoolStables); + const apyData = await getAPYFromAPI(); + + const currentDate = new Date(); + const cutoffDate = new Date('2024-12-01'); + const multiplier = currentDate < cutoffDate ? 0.85 : 0.8; + const adjustedApy = apyData.apy * multiplier; + + return [ + { + pool: `${dsfPoolStables}-ethereum`, + chain: utils.formatChain('ethereum'), + project: 'dsf.finance', + symbol: 'USDT-USDC-DAI', + tvlUsd: tvl / 1e18, + apy: adjustedApy, + rewardTokens: null, + underlyingTokens: [ + '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT + '0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC + '0x6B175474e89094C44Da98b954EedeAC495271d0F' // DAI + ], + poolMeta: 'Stablecoin Yield Strategy (Curve & Convex)', + url: 'https://app.dsf.finance/', + } + ]; +}; + +async function getTVL(contractAddress) { + const tvlResponse = await sdk.api.abi.call({ + target: contractAddress, + abi: abi.totalHoldings, + chain: 'ethereum', + }); + const totalHoldings = tvlResponse.output; + return totalHoldings; +} + +async function getAPYFromAPI() { + try { + const response = await utils.getData('https://yields.llama.fi/chart/8a20c472-142c-4442-b724-40f2183c073e'); + if (response && response.status === 'success' && response.data && response.data.length > 0) { + const latestData = response.data[response.data.length - 1]; + return { apy: latestData.apy }; + } else { + throw new Error('API response is empty or undefined'); + } + } catch (error) { + console.error('Error fetching APY data:', error); + return { apy: 0 }; + } +} + +module.exports = { + timetravel: false, + apy: collectPools, + url: 'https://dsf.finance/', +}; diff --git a/src/adaptors/dtrinity-dusd/index.js b/src/adaptors/dtrinity-dusd/index.js new file mode 100644 index 0000000000..1c7fe4fc27 --- /dev/null +++ b/src/adaptors/dtrinity-dusd/index.js @@ -0,0 +1,41 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +const apy = async (timestamp) => { + const sdusdSonic = await utils.getERC4626Info( + '0x41a5477364BF60d8936b90310FecFDa79593304E', + 'sonic', + timestamp + ); + const { tvl: sdusdSonicTVL, ...restSdusdSonic } = sdusdSonic; + const sdusdSonicVault = { + ...restSdusdSonic, + project: 'dtrinity-dusd', + symbol: `sDUSD`, + tvlUsd: sdusdSonicTVL / 1e18, + underlyingTokens: ['0x53a6aBb52B2F968fA80dF6A894e4f1b1020DA975'], + }; + + const sdusdFraxtal = await utils.getERC4626Info( + '0x58AcC2600835211Dcb5847c5Fa422791Fd492409', + 'fraxtal', + timestamp + ); + const { tvl: sdusdFraxtalTVL, ...restSdusdFraxtal } = sdusdFraxtal; + const sdusdFraxtalVault = { + ...restSdusdFraxtal, + project: 'dtrinity-dusd', + symbol: `sDUSD`, + tvlUsd: sdusdFraxtalTVL / 1e6, + underlyingTokens: ['0x788D96f655735f52c676A133f4dFC53cEC614d4A'], + }; + + return [sdusdSonicVault].concat([sdusdFraxtalVault]); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.dtrinity.org/dstake/vault/', +}; diff --git a/src/adaptors/dyson/index.js b/src/adaptors/dyson/index.js new file mode 100644 index 0000000000..b67b569ef7 --- /dev/null +++ b/src/adaptors/dyson/index.js @@ -0,0 +1,126 @@ +const { + formatChain, + formatSymbol, + getData, + removeDuplicates, +} = require('../utils'); + +const vaultsURL = `https://api2.dyson.money/vaults/compounders`; +const appURL = 'https://app.dyson.money/all' + +const dysonToLlama = { + polygon: 'polygon', + arbitrum: 'arbitrum', + optimism: 'optimism', + kava: 'kava', + avalanche: 'avalanche', + base: 'base', +}; + +const main = async () => { + try { + const vaults = await getData(vaultsURL); + + const formatted = vaults + .map((vault) => { + try { + /** check if vault is valid */ + if (!vault) { + console.debug(`empty vault`); + return null; + } + + // deconstruct vault object + const { + id, + address: vaultAddress, + underlying, + platform, + composition, + network: dysonNetwork, + metrics, + } = vault; + + /** + * NETWORK + */ + const network = dysonToLlama[dysonNetwork]; + if (!network) { + const networkOptions = Object.keys(dysonToLlama).join(', '); + console.debug( + `Ignore vault ${id}, not valid network. Current options ${networkOptions}` + ); + return null; + } + + /** + * UNDERLYING + */ + const underlyingTokens = underlying + .sort((a, b) => a.index - b.index) + .map((token) => token.address); + + /** check if underlying tokens are valid */ + if (!underlyingTokens || underlyingTokens.length === 0) { + console.debug(`Ignore vault ${id}, no underlying tokens`); + } + + /** + * SYMBOL + */ + const symbols = composition + .sort((a, b) => a.index - b.index) + .map((token) => token.symbol); + + /** check if symbols are valid */ + if (!symbols || symbols.length === 0) { + console.debug(`Ignore vault ${id}, no symbols`); + } + + /** + * TVL & APY + */ + // deconstruct metrics object + const { tvl: tvlMetric, rewardRate: rewardRateMetric } = metrics; + + // format tvl & apy + const tvlUsd = Number(tvlMetric.vault.USDBalance); + const apy = Number(rewardRateMetric.rewardRate) * 100; // apy post performance fees + + /** check if TVL & APY is valid */ + if (!tvlUsd || !apy) { + console.debug(`Ignore vault ${id}, no TVL or apy`); + return null; + } + + return { + pool: `${vaultAddress}-${network}`.toLowerCase(), + chain: formatChain(network), + project: 'dyson', + symbol: formatSymbol(symbols.join('-')), + tvlUsd, + apy, + poolMeta: formatChain(platform), // provide base platform + underlyingTokens, + url: `${appURL}?id=${encodeURIComponent(id)}` // replace special characters with browser safe characted for exceptions like: USD+,USDC+, etc. + }; + } catch (e) { + console.debug(e); + return null; + } + }) + // remove any failed vaults + .filter((vault) => vault !== null); + + return removeDuplicates(formatted); + } catch (e) { + console.error(e); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.dyson.money/all', +}; diff --git a/src/adaptors/dystopia/index.js b/src/adaptors/dystopia/index.js index 60d0eceb7e..d5cbebea5f 100644 --- a/src/adaptors/dystopia/index.js +++ b/src/adaptors/dystopia/index.js @@ -1,8 +1,9 @@ +const sdk = require('@defillama/sdk'); const { request, gql } = require('graphql-request'); const utils = require('../utils'); -const url = 'https://api.thegraph.com/subgraphs/name/dystopia-exchange/dystopia-v2'; +const url = sdk.graph.modifyEndpoint('89e9ZAHs7mJvpckEaSmpTtRXUsYcc1mesE7Czp1Hrqxa'); const query = gql` { @@ -34,7 +35,7 @@ const queryPrior = gql` const buildPool = (entry, chainString) => { const symbol = utils.formatSymbol( - `${entry.token0.symbol}-${entry.token1.symbol}` + `${entry.token0.symbol}-${entry.token1.symbol}` ); const newObj = { pool: entry.id, @@ -42,30 +43,45 @@ const buildPool = (entry, chainString) => { project: 'dystopia', symbol, tvlUsd: entry.totalValueLockedUSD, - apy: entry.apy, + apyBase: entry.apy1d, + apyBase7d: entry.apy7d, + underlyingTokens: [entry.token0.id, entry.token1.id], + volumeUsd1d: entry.volumeUSD1d, + volumeUsd7d: entry.volumeUSD7d, }; return newObj; }; const topLvl = async (chainString, timestamp, url) => { - const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ - url, - ]); + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); - dataNow = await request(url, query.replace('', block)); + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pairs; // pull 24h offset data to calculate fees from swap volume - let dataPrior = await request( - url, - queryPrior.replace('', blockPrior) - ); + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; // calculate tvl - dataNow = await utils.tvl(dataNow.pairs, 'polygon'); + data = await utils.tvl(data, 'polygon'); // calculate apy - let data = dataNow.map((el) => utils.apy(el, dataPrior.pairs, 'v2')); + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v2')); // build pool objects data = data.map((el) => buildPool(el, chainString)); @@ -75,10 +91,11 @@ const topLvl = async (chainString, timestamp, url) => { const main = async (timestamp = null) => { const data = await Promise.all([topLvl('polygon', timestamp, url)]); - return data.flat(); + return data.flat().filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: true, apy: main, + url: 'https://www.dystopia.exchange/liquidity', }; diff --git a/src/adaptors/earnmos/index.js b/src/adaptors/earnmos/index.js index 9a09318a6b..4d5f19a429 100644 --- a/src/adaptors/earnmos/index.js +++ b/src/adaptors/earnmos/index.js @@ -2,20 +2,25 @@ const utils = require('../utils'); const poolsFunction = async () => { const poolData = await utils.getData( - 'https://app.earnmos.fi/em-api/tvl/getTvlAndApy' + 'https://app.earnmos.fi/defi-llama/yields' ); - return poolData?.data?.map(poolInfo => ({ - pool: poolInfo.pool, - chain: utils.formatChain(poolInfo.chain), - project: 'earnmos', - symbol: utils.formatSymbol(poolInfo.symbol), - tvlUsd: Number(poolInfo.totalValueLock), - apy: poolInfo.apy * 100 - })); + return poolData?.data?.map((poolInfo) => { + const name = poolInfo.symbol.split(' ').slice(1).join('').split('('); + return { + pool: poolInfo.pool, + chain: utils.formatChain(poolInfo.chain), + project: 'earnmos', + symbol: utils.formatSymbol(name[0]), + poolMeta: name[1].replace(')', ''), + tvlUsd: Number(poolInfo.totalValueLock), + apy: poolInfo.apy * 100, + }; + }); }; module.exports = { timetravel: false, - apy: poolsFunction + apy: poolsFunction, + url: 'https://app.earnmos.fi/deposit', }; diff --git a/src/adaptors/ease.org/bribePotAbi.json b/src/adaptors/ease.org/bribePotAbi.json new file mode 100644 index 0000000000..a6a8c55e51 --- /dev/null +++ b/src/adaptors/ease.org/bribePotAbi.json @@ -0,0 +1,492 @@ +[ + { + "inputs": [], + "name": "bribePerWeek", + "outputs": [ + { + "internalType": "uint256", + "name": "bribeRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bribes", + "outputs": [ + { + "internalType": "uint112", + "name": "rate", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "startWeek", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "endWeek", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "cancelBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "earnable", + "outputs": [ + { + "internalType": "uint256", + "name": "rewardAmt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "gvAmt", + "type": "uint256" + } + ], + "name": "earningsPerWeek", + "outputs": [ + { + "internalType": "uint256", + "name": "rewardAmt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "bribeRate", + "type": "uint256" + } + ], + "name": "expectedGvAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "gvAmt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "genesis", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "toUser", + "type": "bool" + } + ], + "name": "getReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "gvToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gvToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_rcaController", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastBribeUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rcaController", + "outputs": [ + { + "internalType": "contract IRcaController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsToken", + "outputs": [ + { + "internalType": "contract IERC20Permit", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ease.org/index.js b/src/adaptors/ease.org/index.js new file mode 100644 index 0000000000..b1530e6424 --- /dev/null +++ b/src/adaptors/ease.org/index.js @@ -0,0 +1,91 @@ +const utils = require('../utils'); +const { Web3 } = require('web3'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +require('dotenv').config({ path: './config.env' }); +const bribePotAbi = require('./bribePotAbi.json'); +const web3 = new Web3('https://rpc.ankr.com/eth'); + +const bribePotAddress = '0xEA5EdeF17C9be57228389962ba50b98397f1E28C'; +const easeTokenAddress = '0xEa5eDef1287AfDF9Eb8A46f9773AbFc10820c61c'; + +const gvEase = async () => { + const bribePotContract = new web3.eth.Contract(bribePotAbi, bribePotAddress); + + const totalSupply = await bribePotContract.methods.totalSupply().call(); + + const genesis = await bribePotContract.methods.genesis().call(); + const currentTimeStamp = (await web3.eth.getBlock('latest')).timestamp; + const currentWeek = Math.floor( + (currentTimeStamp - genesis) / (60 * 60 * 24 * 7) + ); + const nextWeek = currentWeek + 1; + + // 212 is the slot for the bribeRates mapping + const mappingKey = web3.utils.soliditySha3( + { type: 'uint256', value: nextWeek }, + { type: 'uint256', value: 212 } + ); + const bribeRates = await web3.eth.getStorageAt(bribePotAddress, mappingKey); + // splice StartAmt and ExpireAmt from bribeRates response + const rateStartAmtHex = web3.utils.padLeft(bribeRates.slice(0, 34), 64); + const rateStartAmt = web3.eth.abi.decodeParameter('uint256', rateStartAmtHex); + const rateExpireAmtHex = web3.utils.padLeft( + '0x' + bribeRates.slice(34, 67), + 64 + ); + const rateExpireAmt = web3.eth.abi.decodeParameter( + 'uint256', + rateExpireAmtHex + ); + + // calc how many bribes will be distributed next week + const bribePerCurrWeek = await bribePotContract.methods.bribePerWeek().call(); + let bribePerNextWeek = parseInt(bribePerCurrWeek); + bribePerNextWeek = bribePerNextWeek - parseInt(rateStartAmt); + bribePerNextWeek = bribePerNextWeek + parseInt(rateExpireAmt); + + const weeklyYield = bribePerNextWeek / totalSupply; + const x = 1 + weeklyYield; + const estApy = (Math.pow(x, 52) - 1) * 100; + + const defillamaPooldata = []; + + // calc tvl of gvEase lease + const priceKey = 'coingecko:ease'; + const easePrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).body.coins[priceKey]?.price; + + // This is an approximation. Currently, tvlUsd represents the lowest possible TVL with the given gvEase stake. + const leaseTvlUsd = (web3.utils.fromWei(totalSupply) / 2) * easePrice; + const bribeTvl = web3.utils.fromWei( + ( + await sdk.api.erc20.balanceOf({ + target: easeTokenAddress, + owner: bribePotAddress, + }) + ).output + ); + const bribeTvlUsd = bribeTvl * easePrice; + const tvlUsd = leaseTvlUsd + bribeTvlUsd; + + defillamaPooldata.push({ + pool: (bribePotAddress + '-ethereum').toLowerCase(), + chain: 'Ethereum', + project: 'ease.org', + symbol: 'gvEase', + tvlUsd, + apyBase: estApy, + apyReward: 0, + rewardTokens: ['0xEa5eDef1287AfDF9Eb8A46f9773AbFc10820c61c'], + underlyingTokens: ['0xEa5eDef1287AfDF9Eb8A46f9773AbFc10820c61c'], + }); + return defillamaPooldata; +}; + +module.exports = { + timetravel: false, + apy: gvEase, + url: 'https://app.ease.org/gv-dashboard', +}; diff --git a/src/adaptors/echelon-market/index.js b/src/adaptors/echelon-market/index.js new file mode 100644 index 0000000000..348c03256a --- /dev/null +++ b/src/adaptors/echelon-market/index.js @@ -0,0 +1,266 @@ +const utils = require('../utils'); + +const ECHELON_DAPP_URL = 'https://app.echelon.market'; +const ECHELON_MARKETS_API_URL = `${ECHELON_DAPP_URL}/api/markets?network=`; + +const SEC_PER_YEAR = 365 * 24 * 60 * 60; + +/** + * Calculate APRs for farming pools + * @param {Object} farmingData - The farming data containing rewards and pools + * @param {Object} coins - Map of coin information by market address + * @returns {Object} - Object with supply and borrow APRs by market + */ +function calculateFarmingAprsMove(farmingData, coins) { + try { + // Convert rewards array to a Map for easier lookup + const rewardsMap = new Map(); + if (Array.isArray(farmingData.rewards)) { + farmingData.rewards.forEach(([key, value]) => { + rewardsMap.set(key, value); + }); + } + + // Process both supply and borrow pools + const result = { + supply: {}, + borrow: {} + }; + + // Process supply pools + if (farmingData.pools && Array.isArray(farmingData.pools.supply)) { + for (const poolData of farmingData.pools.supply) { + if (!Array.isArray(poolData) || poolData.length < 2) continue; + + const [market, pool] = poolData; + const aprs = []; + const coinInfo = coins[market]; + + if (!coinInfo || !coinInfo.price || !pool.stakeAmount || pool.stakeAmount <= 0) { + continue; + } + + const stakedValue = coinInfo.price * pool.stakeAmount; + + if (Array.isArray(pool.rewards)) { + for (const reward of pool.rewards) { + if (!reward || !reward.rewardKey || reward.allocPoint <= 0) { + continue; + } + + const rewardData = rewardsMap.get(reward.rewardKey); + if (!rewardData || !rewardData.rewardCoin || !rewardData.rewardCoin.price) { + continue; + } + + const now = Date.now() / 1000; + if (rewardData.startTime > now || rewardData.endTime < now) { + continue; + } + + const apr = + ((rewardData.rewardPerSec / rewardData.totalAllocPoint) * + reward.allocPoint * + rewardData.rewardCoin.price * + SEC_PER_YEAR) / + stakedValue; + + aprs.push({ + coin: rewardData.rewardCoin, + apr: apr + }); + } + } + + if (aprs.length > 0) { + result.supply[market] = aprs; + } + } + } + + // Process borrow pools + if (farmingData.pools && Array.isArray(farmingData.pools.borrow)) { + for (const poolData of farmingData.pools.borrow) { + if (!Array.isArray(poolData) || poolData.length < 2) continue; + + const [market, pool] = poolData; + const aprs = []; + const coinInfo = coins[market]; + + if (!coinInfo || !coinInfo.price || !pool.stakeAmount || pool.stakeAmount <= 0) { + continue; + } + + const stakedValue = coinInfo.price * pool.stakeAmount; + + if (Array.isArray(pool.rewards)) { + for (const reward of pool.rewards) { + if (!reward || !reward.rewardKey || reward.allocPoint <= 0) { + continue; + } + + const rewardData = rewardsMap.get(reward.rewardKey); + if (!rewardData || !rewardData.rewardCoin || !rewardData.rewardCoin.price) { + continue; + } + + const now = Date.now() / 1000; + if (rewardData.startTime > now || rewardData.endTime < now) { + continue; + } + + const apr = + ((rewardData.rewardPerSec / rewardData.totalAllocPoint) * + reward.allocPoint * + rewardData.rewardCoin.price * + SEC_PER_YEAR) / + stakedValue; + + aprs.push({ + coin: rewardData.rewardCoin, + apr: apr + }); + } + } + + if (aprs.length > 0) { + result.borrow[market] = aprs; + } + } + } + + return result; + } catch (e) { + return { supply: {}, borrow: {} }; + } + } + +async function main() { + const netTVLArr = []; + const chains = ['aptos', 'move', 'echelon_initia']; + for (const chain of chains) { + const chainTVLArr = await fetchEchelonForChain(chain); + netTVLArr.push(...chainTVLArr); + } + + return netTVLArr; +} + +async function fetchEchelonForChain(chain) { + // We use Echelon's API and not resources on chain as there are too many pools to parse and query + // for TVL, APR, etc. metrics. This way we fetch all our pools with TVL attached, then can filter. + const chainNameForRequest = chain === 'aptos' ? 'aptos_mainnet' : chain === 'move' ? 'movement_mainnet' : 'initia_mainnet'; + const response = (await utils.getData(`${ECHELON_MARKETS_API_URL}${chainNameForRequest}`)) + ?.data; + const markets = response?.assets; + const marketStats = response?.marketStats; + const farming = response?.farming; + + const coinInfoByMarket = {}; + for (const market of markets) { + coinInfoByMarket[market.market] = { + symbol: market.symbol, + price: market.price, + address: market.address || market.faAddress + }; + } + + const farmingAprs = calculateFarmingAprsMove(farming, coinInfoByMarket); + + if (chain === 'echelon_initia') { + const vipFarmingPools = response?.vipFarming?.pools; + vipFarmingPools.supply.map((entry) =>{ + const key = entry[0]; + const value = { + coin: "esINIT", + apr: entry[1] + }; + if (farmingAprs.supply[key]) { + farmingAprs.supply[key].push(value); + } else { + farmingAprs.supply[key] = [value]; + } + }); + vipFarmingPools.borrow.map((entry) =>{ + const key = entry[0]; + const value = { + coin: "esINIT", + apr: entry[1] + }; + if (farmingAprs.borrow[key]) { + farmingAprs.borrow[key].push(value); + } else { + farmingAprs.borrow[key] = [value]; + } + }); + } + + const tvlArr = []; + for (const market of markets) { + const marketAddress = market.market; + const assetAddress = market.address || market.faAddress; + const marketSpecificStats = marketStats.find(item => item[0] === assetAddress)[1]; + // Total supply is the sum of cash, reserve, and liability + const totalSupply = marketSpecificStats?.totalCash + marketSpecificStats?.totalLiability - marketSpecificStats?.totalReserve; + // Total borrow is the sum of cash, reserve, and liability + const totalBorrow = marketSpecificStats?.totalLiability; + const totalSupplyUsd = totalSupply * market.price; + const totalBorrowUsd = totalBorrow * market.price; + + const lendingSupplyApr = market.supplyApr; + const lendingBorrowApr = market.borrowApr; + const stakingSupplyApr = market.stakingApr; + const farmingAPTApr = farmingAprs.supply[marketAddress]?.find(item => item.coin.address === '0x1::aptos_coin::AptosCoin')?.apr; + const farmingAPTAprBorrow = farmingAprs.borrow[marketAddress]?.find(item => item.coin.address === '0x1::aptos_coin::AptosCoin')?.apr; + const farmingTHAPTApr = farmingAprs.supply[marketAddress]?.find(item => item.coin.address === '0xfaf4e633ae9eb31366c9ca24214231760926576c7b625313b3688b5e900731f6::staking::ThalaAPT')?.apr; + const farmingTHAPTAprBorrow = farmingAprs.borrow[marketAddress]?.find(item => item.coin.address === '0xfaf4e633ae9eb31366c9ca24214231760926576c7b625313b3688b5e900731f6::staking::ThalaAPT')?.apr; + const farmingEsINITApr = farmingAprs.supply[marketAddress]?.find(item => item.coin === 'esINIT')?.apr; + const farmingEsINITBorrowApr = farmingAprs.borrow[marketAddress]?.find(item => item.coin === 'esINIT')?.apr; + const rewardTokens = []; + + // Check and push for APT OR MOVE + if (farmingAPTApr > 0 || farmingAPTAprBorrow > 0) { + rewardTokens.push('0x1::aptos_coin::AptosCoin'); + } + // Check and push for thAPT + if ((farmingTHAPTApr > 0 || farmingTHAPTAprBorrow > 0) && chain === 'aptos') { + rewardTokens.push('0xfaf4e633ae9eb31366c9ca24214231760926576c7b625313b3688b5e900731f6::staking::ThalaAPT'); + } + + if ((farmingEsINITApr > 0 || farmingEsINITBorrowApr > 0) && chain === 'echelon_initia') { + rewardTokens.push('esINIT'); + } + + if (stakingSupplyApr > 0) { + // TODO: handle susde on move when its live + rewardTokens.push(chain === 'aptos' ? '0xb30a694a344edee467d9f82330bbe7c3b89f440a1ecd2da1f3bca266560fce69' : undefined); + } + + tvlArr.push({ + pool: + `${marketAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'echelon-market', + apyBase: ((lendingSupplyApr) ?? 0) * 100, + // exclude intrinsic yield from susde + apyReward: ((farmingAPTApr ?? 0) + (farmingTHAPTApr ?? 0) + (farmingEsINITApr ?? 0) + (market.symbol.toLowerCase() === 'susde' ? 0 : stakingSupplyApr ?? 0)) * 100, + apyBaseBorrow: (lendingBorrowApr ?? 0) * 100, + apyRewardBorrow: ((farmingEsINITBorrowApr ?? 0) + (farmingAPTAprBorrow ?? 0) + (farmingTHAPTAprBorrow ?? 0)) * 100, + totalSupplyUsd, + totalBorrowUsd, + rewardTokens: rewardTokens.filter(token => token !== undefined), + symbol: market.symbol, + tvlUsd: (totalSupplyUsd - totalBorrowUsd), + underlyingTokens: [assetAddress], + url: `${ECHELON_DAPP_URL}/markets`, + }); + } + + return tvlArr; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.echelon.market/markets', +}; diff --git a/src/adaptors/ekubo/index.js b/src/adaptors/ekubo/index.js new file mode 100644 index 0000000000..8fd8e856e0 --- /dev/null +++ b/src/adaptors/ekubo/index.js @@ -0,0 +1,118 @@ +const utils = require('../utils'); + +const API_URL = 'https://starknet-mainnet-api.ekubo.org'; + +function getPrice({ + t, + pricesUSDC, + pricesETH, + pricesSTRK, + priceOfEth, + priceOfStrk, +}) { + let p = pricesUSDC.prices.find(({ token }) => BigInt(token) === t); + if (p) return Number(p.price); + p = pricesETH.prices.find(({ token }) => BigInt(token) === t); + if (p && priceOfEth) { + return Number(p.price) * Number(priceOfEth.price); + } + p = pricesSTRK.prices.find(({ token }) => BigInt(token) === t); + if (p && priceOfStrk) { + return Number(p.price) * Number(priceOfStrk); + } +} + +async function apy() { + const [ + tokens, + defiSpringData, + pairData, + pricesETH, + pricesSTRK, + pricesUSDC, + priceOfStrk, + priceOfEth, + ] = await Promise.all([ + utils.getData(`${API_URL}/tokens`), + utils.getData(`${API_URL}/defi-spring-incentives`), + utils.getData(`${API_URL}/overview/pairs`), + utils.getData(`${API_URL}/price/ETH?period=21600`), + utils.getData(`${API_URL}/price/STRK?period=21600`), + utils.getData(`${API_URL}/price/USDC?period=21600`), + utils.getData(`${API_URL}/price/STRK/USDC?period=21600`), + utils.getData(`${API_URL}/price/ETH/USDC?period=21600`), + ]); + + const strkToken = tokens.find((t) => t.symbol === 'STRK'); + + return pairData.topPairs + .map((p) => { + const t0 = BigInt(p.token0); + const t1 = BigInt(p.token1); + const token0 = tokens.find((t) => BigInt(t.l2_token_address) === t0); + if (!token0 || token0.hidden) return; + const token1 = tokens.find((t) => BigInt(t.l2_token_address) === t1); + if (!token1 || token1.hidden) return; + + const springPair = defiSpringData.pairs.find( + (pair) => + BigInt(pair.token0.l2_token_address) === t0 && + BigInt(pair.token1.l2_token_address) === t1 + ); + + const price0 = + token0.symbol === 'USDC' + ? 1 + : getPrice({ + t: t0, + pricesETH, + pricesUSDC, + pricesSTRK, + priceOfEth, + priceOfStrk, + }); + const price1 = + token1.symbol === 'USDC' + ? 1 + : getPrice({ + t: t1, + pricesETH, + pricesUSDC, + pricesSTRK, + priceOfEth, + priceOfStrk, + }); + const tvlUsd = + ((price0 ?? 0) * Number(p.tvl0_total)) / Math.pow(10, token0.decimals) + + ((price1 ?? 0) * Number(p.tvl1_total)) / Math.pow(10, token1.decimals); + + if (tvlUsd < 10000) return; + const feesUsd = + ((price0 ?? 0) * Number(p.fees0_24h)) / Math.pow(10, token0.decimals) + + ((price1 ?? 0) * Number(p.fees1_24h)) / Math.pow(10, token1.decimals); + + const apyBase = (feesUsd * 100 * 365) / tvlUsd; + const apyReward = springPair ? springPair.currentApr * 100 : undefined; + + return { + pool: `ekubo-${token0.symbol}-${token1.symbol}`, + chain: 'Starknet', + project: 'ekubo', + symbol: `${token0.symbol}-${token1.symbol}`, + rewardTokens: apyReward ? [strkToken.l2_token_address] : [], + underlyingTokens: [token0.l2_token_address, token1.l2_token_address], + tvlUsd, + apyBase, + apyReward, + url: `https://app.ekubo.org/charts/${token0.symbol}/${token1.symbol}`, + }; + }) + .filter((p) => !!p) + .sort((a, b) => b.tvlUsd - a.tvlUsd); +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.ekubo.org/charts', +}; diff --git a/src/adaptors/el-dorado-exchange/abis/ElpManager_arb.json b/src/adaptors/el-dorado-exchange/abis/ElpManager_arb.json new file mode 100644 index 0000000000..da4c22fd3c --- /dev/null +++ b/src/adaptors/el-dorado-exchange/abis/ElpManager_arb.json @@ -0,0 +1,15 @@ +{ + "getPoolInfo": { + "inputs": [], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/el-dorado-exchange/abis/Elp_arb.json b/src/adaptors/el-dorado-exchange/abis/Elp_arb.json new file mode 100644 index 0000000000..77b6019fb0 --- /dev/null +++ b/src/adaptors/el-dorado-exchange/abis/Elp_arb.json @@ -0,0 +1,26 @@ +{ + "getFeeAmount": { + "inputs": [ + { + "internalType": "uint64", + "name": "_stasticDays", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "_shiftDays", + "type": "uint64" + } + ], + "name": "getFeeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/el-dorado-exchange/abis/RewardRouter.json b/src/adaptors/el-dorado-exchange/abis/RewardRouter.json new file mode 100644 index 0000000000..f4c1417778 --- /dev/null +++ b/src/adaptors/el-dorado-exchange/abis/RewardRouter.json @@ -0,0 +1,1402 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "BuyEUSD", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimAmount", + "type": "uint256" + } + ], + "name": "ClaimESBTEUSD", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "SellEUSD", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakeElp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "UnstakeElp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "UserStakeElp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "UserUnstakeElp", + "type": "event" + }, + { + "inputs": [], + "name": "EUSDCirculation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LVT_MINFEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LVT_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_TO_EUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SWAP_THRESHOLD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "base_fee_point", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "buyEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "buyEUSDNative", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "claimAll", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimAllForAccount", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimEDE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimEDEForAccount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_ELPlist", + "type": "address[]" + } + ], + "name": "claimEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimESBTEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimEUSDForAccount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "claimGeneratedFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimableEDE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableEDEForAccount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimableEDEList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableEDEListForAccount", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableESBTEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimableEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableEUSDForAccount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimableEUSDList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableEUSDListForAccount", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + } + ], + "name": "clearELPn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cooldownDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + } + ], + "name": "delToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "esbt", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eusd", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeAUM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEUSDCollateralDetail", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEUSDPoolInfo", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_eusd", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "address", + "name": "_pricefeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_base_fee_point", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isStable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "latestOperationTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lvt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pricefeed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardELPnWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_EUSDamount", + "type": "uint256" + } + ], + "name": "sellEUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_EUSDamount", + "type": "uint256" + } + ], + "name": "sellEUSDNative", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_base_fee_point", + "type": "uint256" + } + ], + "name": "setBaseFeePoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_setCooldownDuration", + "type": "uint256" + } + ], + "name": "setCooldownDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_elp_n_weight", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stakedELPnVault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_elp_n_decimal", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stakedElpTracker", + "type": "address" + } + ], + "name": "setELPn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_esbt", + "type": "address" + } + ], + "name": "setESBT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_status", + "type": "bool" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pricefeed", + "type": "address" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_status", + "type": "bool" + } + ], + "name": "setSwapToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_token_decimal", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isStable", + "type": "bool" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_elpAmount", + "type": "uint256" + } + ], + "name": "stakeELPn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakedELPnAmount", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakedELPnTracker", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakedELPnVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "swapCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "swapStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "swapToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalELPnWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_elp_n", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenInAmount", + "type": "uint256" + } + ], + "name": "unstakeELPn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "whitelistedELPn", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawToEDEPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] +} diff --git a/src/adaptors/el-dorado-exchange/abis/RwardRouter_arb.json b/src/adaptors/el-dorado-exchange/abis/RwardRouter_arb.json new file mode 100644 index 0000000000..64a34f27e1 --- /dev/null +++ b/src/adaptors/el-dorado-exchange/abis/RwardRouter_arb.json @@ -0,0 +1,25 @@ +{ + "stakedELPnAmount": { + "inputs": [], + "name": "stakedELPnAmount", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/el-dorado-exchange/abis/abi.json b/src/adaptors/el-dorado-exchange/abis/abi.json new file mode 100644 index 0000000000..fc9a4e2422 --- /dev/null +++ b/src/adaptors/el-dorado-exchange/abis/abi.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdm": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/el-dorado-exchange/index.js b/src/adaptors/el-dorado-exchange/index.js new file mode 100644 index 0000000000..6eb8633d95 --- /dev/null +++ b/src/adaptors/el-dorado-exchange/index.js @@ -0,0 +1,248 @@ +const helperUtils = require("../../helper/utils"); + +const { ethers } = require('ethers'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi_rewardrouter_arb = require('./abis/RwardRouter_arb.json'); +const abi_Elp_arb = require('./abis/Elp_arb.json'); +const abi_ElpManager_arb = require('./abis/ElpManager_arb.json'); + +const AEDE = "0x5566d132324181427eD4f46989121030BC6689C7" +const EUSD = "0xB00885eef0610C1A9D0f4c125Abe959B63F6B2BF" +const reward_tracker_arbitrum_elp1 = "0x2108397905f6d3a9b277c545948c6d6e1ca22d06" +const reward_router_arbitrum_elp1 = "0x86af1e551c081ec2269f62708c291af1627fa4ed" +const elp1_arbitrum = "0xec08b5a75473fd581be6628d4e2ed08b49078df0" +const elpManangere_arbitrum_elp1 = "0x26aa71be9ccd794a4c9043be026c68496b45aa73" +const vault_arbitrum_elp1 = "0xfc36be177868b05f966e57bfc01617501b1f6926" +const vault_tokens_arbitrum_elp1 = [ + "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", //USDC + "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f", //WBTC + "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", //WETH + "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", //USDT + "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", //DAI +] +const token_map_arbirtrum_elp1 = { + "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8": "USDCUSDT", + "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f": "BTCUSDT", + "0x82af49447d8a07e3bd95bd0d56f35241523fbab1": "ETHUSDT", + "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9": "USDTUSDT", + "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1": "DAIUSDT" +} + +//------------------------------BSC CHAIN--------------------------------------- +const AEDE_BSC = "0x43F649919f4ac48874D7f65D361702E4447Dec0c" +const EUSD_BSC = "0x691390b8505821e9f62f7F848dD7C20d5205a58F" +const reward_tracker_bsc_elp1 = "0x43c1FcC7F4E604F7DA57bA58Bb2A8E7d9cc48B21" +const reward_router_bsc_elp1 = "0x2108397905F6d3A9b277c545948C6d6E1Ca22D06" +const elpManangere_bsc_elp1 = "0xFaF4bc3791B7B2133564155482abd190d971f055" +const vault_bsc_elp1 = "0xF1D7e3f06aF6EE68E22baFd37E6a67b1757c35a9" +const vault_tokens_bsc_elp1 = [ + "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", //WBNB + "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", //WBTC + "0x2170ed0880ac9a755fd29b2688956bd959f933f8", //WETH + "0x55d398326f99059ff775485246999027b3197955", //USDT +] +const token_map_bsc_elp1 = { + "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c": "BNBUSDT", + "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c": "BTCUSDT", + "0x2170ed0880ac9a755fd29b2688956bd959f933f8": "ETHUSDT", + "0x55d398326f99059ff775485246999027b3197955": "USDTUSDT", +} + + +async function getVaultTvl(vault, vault_tokens, pChain, priceDataRes) { + let tvl = 0; + for (let i = 0; i < vault_tokens.length; i++) { + let token = vault_tokens[i]; + let decimals = await sdk.api.abi.call({ + target: token, + abi: 'erc20:decimals', + chain: pChain, + }); + let vault_balance = await sdk.api.abi.call({ + target: token, + abi: 'erc20:balanceOf', + chain: pChain, + params: [vault], + }); + // console.log("vault_balance::", vault_balance.output / (18 ** decimals.output)) + + tvl = tvl + (priceDataRes[token_map_arbirtrum_elp1[token]] / 10 ** 30) * (vault_balance.output / (10 ** decimals.output)); + } + // console.log("tvl::", tvl) + + return tvl +} + +async function getVaultTvl_bsc(vault, vault_tokens, pChain, priceDataRes) { + let tvl = 0; + for (let i = 0; i < vault_tokens.length; i++) { + let token = vault_tokens[i]; + let decimals = await sdk.api.abi.call({ + target: token, + abi: 'erc20:decimals', + chain: pChain, + }); + let vault_balance = await sdk.api.abi.call({ + target: token, + abi: 'erc20:balanceOf', + chain: pChain, + params: [vault], + }); + // console.log("vault_balance::", vault_balance.output / (18 ** decimals.output)) + + tvl = tvl + (priceDataRes[token_map_bsc_elp1[token]] / 10 ** 30) * (vault_balance.output / (10 ** decimals.output)); + } + // console.log("tvl::", tvl) + + return tvl +} +const getPools = async () => { + let edePrice = (await utils.getData( + 'https://data.ede.finance/arb/edekline' + )).data[0].price; + let elpPrice = 1; + + let arb_info = await sdk.api.abi.call({ + target: reward_router_arbitrum_elp1, + abi: abi_rewardrouter_arb["stakedELPnAmount"], + chain: "arbitrum", + }); + // console.log("arb_info::", arb_info.output); + const totalStaked_elp1 = Number(ethers.utils.formatUnits(arb_info.output[1][0], 18)); + const stakingPool_elp1 = Number(ethers.utils.formatUnits(arb_info.output[2][0], 18)); + // console.log("totalStaked_elp1::", totalStaked_elp1) + // console.log("stakingPool_elp1::", stakingPool_elp1) + + const apr_ede_elp = (stakingPool_elp1 * 3600 * 24 * 365 * edePrice) / (totalStaked_elp1 * elpPrice); + // console.log("apr_ede_elp::", apr_ede_elp) + + + let feeAmount_arb = await sdk.api.abi.call({ + target: elp1_arbitrum, + abi: abi_Elp_arb["getFeeAmount"], + chain: "arbitrum", + params: [1,1] + }); + // console.log("feeAmount_arb::", feeAmount_arb.output); + + + let elpManager_info = await sdk.api.abi.call({ + target: elpManangere_arbitrum_elp1, + abi: abi_ElpManager_arb["getPoolInfo"], + chain: "arbitrum" + }); + + const elpManager_totalSupply = Number(ethers.utils.formatUnits(elpManager_info.output[2], 18)); + + + // console.log("elpManager_info::", elpManager_info.output); + + + const apr_eusd_elp = (Number(ethers.utils.formatUnits(feeAmount_arb.output, 18)) / 1 * 365) / (1 * elpManager_totalSupply * elpPrice) * 0.6; + + // console.log("apr_eusd_elp::", apr_eusd_elp) + + + + + + + + let pools = []; + + const priceDataRes = await utils.getData( + 'https://api.ede.finance/prices' + ); + + // console.log("priceDataRes::", priceDataRes) + + let tvl_arbitrum_elp1 = await getVaultTvl(vault_arbitrum_elp1, vault_tokens_arbitrum_elp1, 'arbitrum', priceDataRes); + + + pools.push({ + pool: reward_tracker_arbitrum_elp1, + chain: utils.formatChain('arbitrum'), + project: 'el-dorado-exchange', + symbol: 'WETH-WBTC-USDC-USDT-DAI', + tvlUsd: parseFloat(tvl_arbitrum_elp1), + apyBase: apr_eusd_elp * 100, + apyReward: apr_ede_elp * 100, + rewardTokens: [EUSD, AEDE], + poolMeta: "ELP-1", + underlyingTokens: vault_tokens_arbitrum_elp1 + }) + + //======================================BSC CHAIN====================================== + + let bsc_info = await sdk.api.abi.call({ + target: reward_router_bsc_elp1, + abi: abi_rewardrouter_arb["stakedELPnAmount"], + chain: "bsc", + }); + console.log("bsc_info::", bsc_info.output); + + const totalStaked_elp1_bsc = Number(ethers.utils.formatUnits(bsc_info.output[1][2], 18)); + const stakingPool_elp1_bsc = Number(ethers.utils.formatUnits(bsc_info.output[2][2], 18)); + console.log("totalStaked_elp1_bsc::", totalStaked_elp1_bsc) + console.log("stakingPool_elp1_bsc::", stakingPool_elp1_bsc) + + edePrice = (await utils.getData( + 'https://data.ede.finance/bsc/edekline' + )).data[0].price; + + elpPrice = 0.92 + const apr_ede_elp_bsc = (stakingPool_elp1_bsc * 3600 * 24 * 365 * edePrice) / (totalStaked_elp1_bsc * elpPrice); + console.log("apr_ede_elp_bsc::", apr_ede_elp_bsc) + + + const feeAmount_bsc = ( + await helperUtils.fetchURL("https://data.ede.finance/api/ede/dalyFee") + ).data.elp1; + console.log("feeAmount_bsc::", feeAmount_bsc); + + + let elpManager_info_bsc = await sdk.api.abi.call({ + target: elpManangere_bsc_elp1, + abi: abi_ElpManager_arb["getPoolInfo"], + chain: "bsc" + }); + + console.log("elpManager_info_bsc::", elpManager_info_bsc.output); + + const elpManager_totalSupply_bsc = Number(ethers.utils.formatUnits(elpManager_info_bsc.output[2], 18)); + + console.log("elpManager_totalSupply_bsc::", elpManager_totalSupply_bsc); + + const apr_eusd_elp_bsc = (Number(ethers.utils.formatUnits(feeAmount_bsc, 18)) / 1 * 365) / (1 * elpManager_totalSupply_bsc * elpPrice) * 0.6; + + console.log("apr_eusd_elp_bsc::", apr_eusd_elp_bsc) + + + let tvl_bsc_elp1 = await getVaultTvl_bsc(vault_bsc_elp1, vault_tokens_bsc_elp1, 'bsc', priceDataRes); + + + pools.push({ + pool: reward_tracker_bsc_elp1, + chain: utils.formatChain('bsc'), + project: 'el-dorado-exchange', + symbol: 'WETH-WBTC-WBNB-USDT', + tvlUsd: parseFloat(tvl_bsc_elp1), + apyBase: apr_eusd_elp_bsc * 100, + apyReward: apr_ede_elp_bsc * 100, + rewardTokens: [EUSD_BSC, AEDE_BSC], + poolMeta: "ELP1p", + underlyingTokens: vault_tokens_bsc_elp1 + }) + + + + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.ede.finance/#/Earn', +}; \ No newline at end of file diff --git a/src/adaptors/ellipsis-finance/index.js b/src/adaptors/ellipsis-finance/index.js index 5a6aac9b2e..a5a649afe2 100755 --- a/src/adaptors/ellipsis-finance/index.js +++ b/src/adaptors/ellipsis-finance/index.js @@ -2,25 +2,25 @@ const utils = require('../utils'); const poolsFunction = async () => { const get = await utils.getData('https://api.ellipsis.finance/api/getAPRs'); - const dataAPRs = get.data; - const pools = [] - for(const i in dataAPRs) { - const obj = dataAPRs[i] - if(parseInt(obj.tvl) > 0) - pools.push({ - pool: obj.address, - chain: utils.formatChain('binance'), - project: 'ellipsis-finance', - symbol: obj.assets, - tvlUsd: parseFloat(obj.tvl), - apy: parseFloat(obj.totalApr), - }) - + const dataAPRs = get.data; + const pools = []; + for (const i in dataAPRs) { + const obj = dataAPRs[i]; + if (parseInt(obj.tvl) > 0) + pools.push({ + pool: obj.address, + chain: utils.formatChain('binance'), + project: 'ellipsis-finance', + symbol: obj.assets, + tvlUsd: parseFloat(obj.tvl), + apy: parseFloat(obj.totalApr), + url: `https://ellipsis.finance/pool/${obj.address}`, + }); } - return pools + return pools; }; module.exports = { timetravel: false, apy: poolsFunction, -}; \ No newline at end of file +}; diff --git a/src/adaptors/enclabs/index.js b/src/adaptors/enclabs/index.js new file mode 100644 index 0000000000..d2fd5a45e7 --- /dev/null +++ b/src/adaptors/enclabs/index.js @@ -0,0 +1,148 @@ +const sdk = require("@defillama/sdk"); + +const CORE_SONIC_POOL = { + name: "Core Sonic Pool", + comptroller: "0xccAdFCFaa71407707fb3dC93D7d83950171aA2c9", + oracle: "0xd05b05590609c3610161e60eb41eC317c7562408", +}; + +const CORE_PLASMA_POOL = { + name: "Core Plasma Pool", + comptroller: "0xA3F48548562A30A33257A752d396A20B4413E8E3", + oracle: "0xd05b05590609c3610161e60eb41eC317c7562408", +}; + +const abi = { + getAllMarkets: "function getAllMarkets() view returns (address[])", + symbol: "function symbol() view returns (string)", + decimals: "function decimals() view returns (uint8)", + totalSupply: "function totalSupply() view returns (uint256)", + exchangeRateStored: "function exchangeRateStored() view returns (uint256)", + totalBorrows: "function totalBorrows() view returns (uint256)", + supplyRatePerBlock: "function supplyRatePerBlock() view returns (uint256)", + borrowRatePerBlock: "function borrowRatePerBlock() view returns (uint256)", + getUnderlyingPrice: "function getUnderlyingPrice(address cToken) view returns (uint256)", + underlying: "function underlying() view returns (address)", + markets: "function markets(address) view returns (bool, uint256, bool)", +}; + +const BLOCKS_PER_YEAR = 31_536_000; + +function round(n) { + return Math.round(n * 100) / 100; +} + +async function getPoolsData(poolConfig, chain) { + const { output: markets } = await sdk.api.abi.call({ + target: poolConfig.comptroller, + abi: abi.getAllMarkets, + chain, + }); + + const pools = []; + + for (const market of markets) { + const { output: cTokenSymbol } = await sdk.api.abi.call({ + target: market, + abi: abi.symbol, + chain, + }); + + let underlying = market; + try { + const { output } = await sdk.api.abi.call({ + target: market, + abi: abi.underlying, + chain, + }); + underlying = output; + } catch {} + + let underlyingSymbol = cTokenSymbol; + try { + const { output: symbol } = await sdk.api.abi.call({ + target: underlying, + abi: abi.symbol, + chain, + }); + underlyingSymbol = symbol; + } catch {} + + let decimals = 18; + try { + const { output: d } = await sdk.api.abi.call({ + target: underlying, + abi: abi.decimals, + chain, + }); + decimals = Number(d); + } catch {} + + const [ + { output: totalSupplyRaw }, + { output: exchangeRateRaw }, + { output: totalBorrowsRaw }, + { output: supplyRateRaw }, + { output: borrowRateRaw }, + { output: priceRaw }, + { output: marketData }, + ] = await Promise.all([ + sdk.api.abi.call({ target: market, abi: abi.totalSupply, chain }), + sdk.api.abi.call({ target: market, abi: abi.exchangeRateStored, chain }), + sdk.api.abi.call({ target: market, abi: abi.totalBorrows, chain }), + sdk.api.abi.call({ target: market, abi: abi.supplyRatePerBlock, chain }), + sdk.api.abi.call({ target: market, abi: abi.borrowRatePerBlock, chain }), + sdk.api.abi.call({ target: poolConfig.oracle, abi: abi.getUnderlyingPrice, params: [market], chain }), + sdk.api.abi.call({ target: poolConfig.comptroller, abi: abi.markets, params: [market], chain }), + ]); + + const exchangeRate = Number(exchangeRateRaw) / 1e18; + const totalSupplyUnderlying = (Number(totalSupplyRaw) / 10 ** decimals) * exchangeRate; + const totalBorrowsUnderlying = Number(totalBorrowsRaw) / 10 ** decimals; + const price = Number(priceRaw) / 10 ** (36 - decimals); + + const totalSupplyUsd = totalSupplyUnderlying * price; + const totalBorrowUsd = totalBorrowsUnderlying * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const supplyRatePerBlock = Number(supplyRateRaw) / 1e18; + const borrowRatePerBlock = Number(borrowRateRaw) / 1e18; + + const apyBase = (Math.pow(1 + supplyRatePerBlock, BLOCKS_PER_YEAR) - 1) * 100; + const apyBaseBorrow = borrowRatePerBlock * BLOCKS_PER_YEAR * 100; + + let ltv = 0; + try { + ltv = Number(marketData[1]) / 1e18; + } catch {} + + pools.push({ + pool: `${market}-${chain}`.toLowerCase(), + chain: chain.charAt(0).toUpperCase() + chain.slice(1), + project: "enclabs", + symbol: underlyingSymbol, + tvlUsd: round(tvlUsd), + apyBase: Number(apyBase), + apyBaseBorrow: Number(apyBaseBorrow), + totalSupplyUsd: round(totalSupplyUsd), + totalBorrowUsd: round(totalBorrowUsd), + ltv: round(ltv), + underlyingTokens: [underlying], + poolMeta: poolConfig.name, + }); + } + + return pools; +} + +async function main() { + const sonicPools = await getPoolsData(CORE_SONIC_POOL, "sonic"); + const plasmaPools = await getPoolsData(CORE_PLASMA_POOL, "plasma"); + return [...sonicPools, ...plasmaPools]; +} + +module.exports = { + timetravel: false, + apy: main, + url: "https://www.enclabs.finance", +} diff --git a/src/adaptors/endur/index.js b/src/adaptors/endur/index.js new file mode 100644 index 0000000000..003007f759 --- /dev/null +++ b/src/adaptors/endur/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils') +const STRK = "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" + +const apy = async () => { + const apyData = await utils.getData( + 'https://staging.endur.fi/api/lst/stats' + ); + return apyData + .filter(lst => parseFloat(lst.tvlUsd) > 10000) + .map((lst) => { + const currTvlUsd = parseFloat(lst.tvlUsd); + const currPool = lst.asset; + const baseApy = (lst.apy || 0) * 100; + const underlyingToken = lst.assetAddress; + + return { + pool: `endur-${currPool}`, + chain: 'Starknet', + project: 'endur', + symbol: currPool, + underlyingTokens: [underlyingToken], + tvlUsd: currTvlUsd, + apyBase: baseApy, + url: `https://app.endur.fi/`, + poolMeta: currPool, + } + }) +}; + +module.exports = { + timetravel: false, + apy: apy, + url : 'https://app.endur.fi' +}; \ No newline at end of file diff --git a/src/adaptors/ensuro/index.js b/src/adaptors/ensuro/index.js new file mode 100644 index 0000000000..25a1559710 --- /dev/null +++ b/src/adaptors/ensuro/index.js @@ -0,0 +1,85 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const axios = require('axios'); + +// Idea of using alchemyKey copied from ../mellow-yield/index.js, but now with better code +const alchemy_url_regex = /https:[/][/].*alchemy[.]com[/]v2[/]([^/]+)/g; + +const extractKey = (alchemy_full_url) => { + const match = alchemy_url_regex.exec(alchemy_full_url); + if (match === null) return null; + return match[1]; +}; + +const addressBook = { + polygon: { + usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + eTokens: [ + // eTokens + { + name: 'Senior Pool', + address: '0xF383eF2D31E1d4a19B3e04ca2937DB6A8DA9f229', + symbol: 'eUSDCBMASr', + }, + ], + }, +}; + +const abiGetCurrentScale = + 'function getCurrentScale(bool updated) public view returns (uint256)'; + +const getApy = async () => { + const timestamp1dayAgo = Math.floor(Date.now() / 1000) - 86400; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/polygon/${timestamp1dayAgo}`) + ).data.height; + + const alchemyKey = extractKey(process.env.ALCHEMY_CONNECTION_ETHEREUM || ''); + + if (alchemyKey === null) + throw new Error( + 'Environment variable ALCHEMY_CONNECTION_ETHEREUM not defined or not in the expected format' + ); + const provider = new ethers.providers.AlchemyProvider('matic', alchemyKey); + + return await Promise.all( + addressBook.polygon.eTokens.map(async (etk) => { + const [tsNow, csNow, csOneDayAgo] = await Promise.all([ + sdk.api.erc20.totalSupply({ target: etk.address, chain: 'polygon' }), + sdk.api.abi.call({ + target: etk.address, + chain: 'polygon', + params: [true], + abi: abiGetCurrentScale, + }), + sdk.api.abi.call({ + target: etk.address, + chain: 'polygon', + abi: abiGetCurrentScale, + params: [true], + block: block1dayAgo, + }), + ]); + + const dailyApr = csNow.output / csOneDayAgo.output - 1; + // Using apr to apy formula from https://www.aprtoapy.com/ + const apy = (Math.pow(1 + dailyApr, 365) - 1) * 100; + return { + pool: etk.address, + chain: 'polygon', + project: 'ensuro', + symbol: 'USDC', + poolMeta: etk.name, + tvlUsd: tsNow.output / 1e6, + apyBase: apy, + url: `https://app.ensuro.co/eTokens/${etk.address}`, + underlyingTokens: [addressBook.polygon.usdc], + }; + }) + ); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/enzo-finance/cerc20.json b/src/adaptors/enzo-finance/cerc20.json new file mode 100644 index 0000000000..683fb81f7a --- /dev/null +++ b/src/adaptors/enzo-finance/cerc20.json @@ -0,0 +1,1615 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "underlying_", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "address payable", + "name": "admin_", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "becomeImplementationData", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event", + "signature": "0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event", + "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event", + "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event", + "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event", + "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event", + "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldImplementation", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "NewImplementation", + "type": "event", + "signature": "0xd604de94d45953f9138079ec1b82d533cb2160c906d1076d1f7ed54befbca97a" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event", + "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event", + "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event", + "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event", + "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event", + "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event", + "signature": "0xa91e67c5ea634cd43a12c5a482724b03de01e85ca68702a53d0c2f45cb7c1dc5" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event", + "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9c714f2" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + } + ], + "name": "_addReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3e941010" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x601a0bf1" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4576b5db" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowResign", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "becomeImplementationData", + "type": "bytes" + } + ], + "name": "_setImplementation", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x555bcc40" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf2b3abbd" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb71d1a0c" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xfca7820b" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6c540baf" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa6afed95" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdd62ed3e" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x095ea7b3" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x70a08231" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3af9e669" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc5ebeaec" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x17bfdfbc" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95dd9193" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa5af0fd" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf8f9da28" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5fe3b567" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x313ce567" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "delegateToImplementation", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x0933c1ed" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "delegateToViewImplementation", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x4487152f" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbd6d894d" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x182df0f5" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc37f68e2" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x3b1d21a2" + }, + { + "constant": true, + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5c60da1b" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf3fdb15a" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xfe9c44ae" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract CTokenInterface", + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf5e3c462" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa0712d68" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x06fdde03" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xdb006a75" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x852a12e3" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x0e752702" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x2608f818" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x173b9904" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb2a02ff1" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xae9d70b0" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95d89b41" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x47bd3718" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x73acee98" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8f840ddd" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x18160ddd" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa9059cbb" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x23b872dd" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6f307dc3" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "maxFlashLoan", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract IERC3156FlashBorrower", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flashLoan", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "flashFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/enzo-finance/ceth.json b/src/adaptors/enzo-finance/ceth.json new file mode 100644 index 0000000000..4b5353625e --- /dev/null +++ b/src/adaptors/enzo-finance/ceth.json @@ -0,0 +1,1281 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x06fdde03" + }, + { + "constant": false, + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x095ea7b3" + }, + { + "constant": false, + "inputs": [], + "name": "mint", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + "signature": "0x1249c58b" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x173b9904" + }, + { + "constant": false, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x17bfdfbc" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x18160ddd" + }, + { + "constant": true, + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x182df0f5" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x23b872dd" + }, + { + "constant": true, + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x26782247" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x313ce567" + }, + { + "constant": false, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x3af9e669" + }, + { + "constant": true, + "inputs": [], + "name": "getCash", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x3b1d21a2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newComptroller", + "type": "address" + } + ], + "name": "_setComptroller", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x4576b5db" + }, + { + "constant": true, + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x47bd3718" + }, + { + "constant": false, + "inputs": [], + "name": "repayBorrow", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + "signature": "0x4e4d9fea" + }, + { + "constant": true, + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x5fe3b567" + }, + { + "constant": false, + "inputs": [ + { + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x601a0bf1" + }, + { + "constant": true, + "inputs": [], + "name": "initialExchangeRateMantissa", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x675d972c" + }, + { + "constant": true, + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x6c540baf" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x70a08231" + }, + { + "constant": false, + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x73acee98" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x852a12e3" + }, + { + "constant": true, + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x8f840ddd" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95d89b41" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x95dd9193" + }, + { + "constant": false, + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa6afed95" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xa9059cbb" + }, + { + "constant": true, + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xaa5af0fd" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + }, + { + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + "signature": "0xaae40a2a" + }, + { + "constant": true, + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xae9d70b0" + }, + { + "constant": false, + "inputs": [ + { + "name": "liquidator", + "type": "address" + }, + { + "name": "borrower", + "type": "address" + }, + { + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb2a02ff1" + }, + { + "constant": false, + "inputs": [ + { + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "_setPendingAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xb71d1a0c" + }, + { + "constant": false, + "inputs": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xbd6d894d" + }, + { + "constant": true, + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xc37f68e2" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xc5ebeaec" + }, + { + "constant": false, + "inputs": [ + { + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xdb006a75" + }, + { + "constant": true, + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xdd62ed3e" + }, + { + "constant": false, + "inputs": [ + { + "name": "borrower", + "type": "address" + } + ], + "name": "repayBorrowBehalf", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + "signature": "0xe5974619" + }, + { + "constant": false, + "inputs": [], + "name": "_acceptAdmin", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xe9c714f2" + }, + { + "constant": false, + "inputs": [ + { + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xf2b3abbd" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf3fdb15a" + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf851a440" + }, + { + "constant": true, + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xf8f9da28" + }, + { + "constant": false, + "inputs": [ + { + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "_setReserveFactor", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0xfca7820b" + }, + { + "constant": true, + "inputs": [], + "name": "isCToken", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0xfe9c44ae" + }, + { + "inputs": [ + { + "name": "comptroller_", + "type": "address" + }, + { + "name": "interestRateModel_", + "type": "address" + }, + { + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "name": "name_", + "type": "string" + }, + { + "name": "symbol_", + "type": "string" + }, + { + "name": "decimals_", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + "signature": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event", + "signature": "0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event", + "signature": "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event", + "signature": "0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event", + "signature": "0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event", + "signature": "0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event", + "signature": "0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event", + "signature": "0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": false, + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event", + "signature": "0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": false, + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event", + "signature": "0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event", + "signature": "0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event", + "signature": "0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event", + "signature": "0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event", + "signature": "0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event", + "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event", + "signature": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "maxFlashLoan", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract IERC3156FlashBorrower", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flashLoan", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "flashFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/enzo-finance/index.js b/src/adaptors/enzo-finance/index.js new file mode 100644 index 0000000000..02e542fc9e --- /dev/null +++ b/src/adaptors/enzo-finance/index.js @@ -0,0 +1,117 @@ +const ethers = require('ethers'); +const cEthABI = require('./ceth.json'); +const cERC20ABI = require('./cerc20.json'); +const { default: BigNumber } = require('bignumber.js'); +const { getPrices } = require('../utils'); + +const blockInterval = 3; +const blocksPerMinute = 60 / blockInterval; +const blocksPerDay = blocksPerMinute * 60 * 24; +const daysPerYear = 365; +const chain = 'Bitlayer'; +const markets = [ + { + pool: '0xe277Aed3fF3Eb9824EdC52Fe7703DF0c5ED8B313', + decimals: 18, + isCurrency: true, + symbol: 'BTC', + underlyingToken: '0xfF204e2681A6fA0e2C3FaDe68a1B28fb90E4Fc5F', + }, + { + pool: '0xF6Fa83E30c7d3978F86141016ee9471d77f48aE0', + decimals: 6, + symbol: 'USDT', + underlyingToken: '0xfe9f969faf8Ad72a83b761138bF25dE87eFF9DD2', + }, + { + pool: '0xBb0CB5C5e49d5C3903932d07831fB8c1bB1651d2', + decimals: 6, + symbol: 'USDC', + underlyingToken: '0xf8c374ce88a3be3d374e8888349c7768b607c755', + }, + { + pool: '0xAb7f136BBb18808F0C981D0307D3360cA92AD171', + decimals: 18, + symbol: 'ETH', + underlyingToken: '0xEf63d4E178b3180BeEc9B0E143e0f37F4c93f4C2', + }, +]; + +const getContractWithCToken = (cToken, provider) => { + if (!cToken.poolContract) { + cToken.poolContract = new ethers.Contract( + cToken.pool, + cToken.isCurrency ? cEthABI : cERC20ABI, + provider + ); + } + + return cToken.poolContract; +}; + +const getMarketsPrice = async () => { + const prices = await getPrices( + markets.map((market) => market.underlyingToken), + 'btr' + ); + markets.forEach((market) => { + market.price = prices.pricesByAddress[market.underlyingToken.toLowerCase()]; + }); +}; + +const getDataByMarket = async (cToken, provider) => { + const c = getContractWithCToken(cToken, provider); + + // const totalBorrowsCurrent = await c.callStatic.totalBorrowsCurrent(); + // const totalBorrowed = BigNumber(totalBorrowsCurrent._hex).shiftedBy(-cToken.decimals); + // const totalBorrowedFiat = totalBorrowed.multipliedBy(cToken.price).toNumber(); + + const cash = await c.getCash(); + const cashDecimals = BigNumber(cash._hex).shiftedBy(-cToken.decimals); + const cashFiat = cashDecimals.multipliedBy(cToken.price).toNumber(); + + const supplyRatePerBlock = await c.supplyRatePerBlock(); + const supplyRatePerBlockDecimals = BigNumber(supplyRatePerBlock._hex); + const supplyApy = + supplyRatePerBlockDecimals + .shiftedBy(-18) + .multipliedBy(blocksPerDay) + .plus(1) + .pow(daysPerYear - 1) + .minus(1) + .toNumber() * 100; + + return { cashFiat, supplyApy }; +}; + +const apy = async () => { + await getMarketsPrice(); + + const provider = new ethers.providers.JsonRpcProvider( + 'https://rpc.bitlayer.org' + ); + const pools = []; + + for (let i = 0; i < markets.length; i++) { + const market = markets[i]; + const { cashFiat, supplyApy } = await getDataByMarket(market, provider); + + pools.push({ + pool: market.pool, + chain, + project: 'enzo-finance', + symbol: market.symbol, + tvlUsd: cashFiat, // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apy: supplyApy, + underlyingTokens: [market.underlyingToken], + }); + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://enzo.finance/', +}; diff --git a/src/adaptors/equalizer-exchange/abiGauge.json b/src/adaptors/equalizer-exchange/abiGauge.json new file mode 100644 index 0000000000..73b1030685 --- /dev/null +++ b/src/adaptors/equalizer-exchange/abiGauge.json @@ -0,0 +1,727 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_stake", "type": "address" }, + { "internalType": "address", "name": "_ebribe", "type": "address" }, + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "bool", "name": "_forPair", "type": "bool" }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "BribeTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "notifier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_t", "type": "address" }], + "name": "addBribeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tks", "type": "address[]" } + ], + "name": "addBribeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "address", + "name": "_rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "addReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribe", + "outputs": [ + { "internalType": "contract IBribe", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "bribeTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribesListLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "depositAllFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "earnedBy", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "earnings", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeTaker", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "getRewardForDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isBribeToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { "internalType": "uint256", "name": "_reward", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "payouts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "payoutsNotified", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_t", "type": "address" }], + "name": "removeBribeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tks", "type": "address[]" } + ], + "name": "removeBribeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amt", "type": "uint256" }, + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "rescue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardData", + "outputs": [ + { + "internalType": "address", + "name": "rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardsDuration", + "type": "uint256" + }, + { "internalType": "uint256", "name": "periodFinish", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_b", "type": "address" }], + "name": "setBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_ft", "type": "address" }], + "name": "setFeeTaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_b", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "address", + "name": "_rewardsDistributor", + "type": "address" + } + ], + "name": "setRewardsDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "totalFeesPayouts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [ + { + "internalType": "contract IVotingEscrow", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { "internalType": "contract IVoter", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/equalizer-exchange/abiPair.json b/src/adaptors/equalizer-exchange/abiPair.json new file mode 100644 index 0000000000..6d9b89a18a --- /dev/null +++ b/src/adaptors/equalizer-exchange/abiPair.json @@ -0,0 +1,684 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/equalizer-exchange/abiPairFactory.json b/src/adaptors/equalizer-exchange/abiPairFactory.json new file mode 100644 index 0000000000..a6f8cccc23 --- /dev/null +++ b/src/adaptors/equalizer-exchange/abiPairFactory.json @@ -0,0 +1,274 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE_NEW", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "feesOverrides", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_stable", "type": "bool" }], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" } + ], + "name": "getRealFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hotload", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_stable", "type": "bool" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFeesOverrides", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pauser", "type": "address" } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/equalizer-exchange/abiVoter.json b/src/adaptors/equalizer-exchange/abiVoter.json new file mode 100644 index 0000000000..24d50d75e6 --- /dev/null +++ b/src/adaptors/equalizer-exchange/abiVoter.json @@ -0,0 +1,989 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "gaugeRewards", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "allowedRewards", + "type": "address[]" + } + ], + "name": "GaugeAndBribeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pooladdr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_gtokens", + "type": "address[][]" + }, + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_btokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimEverything", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" } + ], + "name": "createGaugeMultiple", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "initialSetup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_gauges", "type": "address" }, + { "internalType": "address", "name": "_bribes", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ms", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "pausedGauges", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pokable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeesPerMillion", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeesTaker", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_ids", "type": "uint256[]" } + ], + "name": "resetOverride", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "resetOverride", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" }, + { "internalType": "address", "name": "_nb", "type": "address" } + ], + "name": "setBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setGaugable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_ms", "type": "address" }], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_g", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setPausedGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_b", "type": "bool" }], + "name": "setPokable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_pf", "type": "uint256" }], + "name": "setProtocolFeesPerMillion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pft", "type": "address" } + ], + "name": "setProtocolFeesTaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setUnvotablePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "unvotable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/equalizer-exchange/index.js b/src/adaptors/equalizer-exchange/index.js new file mode 100644 index 0000000000..942b9a2350 --- /dev/null +++ b/src/adaptors/equalizer-exchange/index.js @@ -0,0 +1,171 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const CHAINS = { + fantom: { + pairFactory: '0xc6366EFD0AF1d09171fe0EBF32c7943BB310832a', + voter: '0xE3D1A117dF7DCaC2eB0AC8219341bAd92f18dAC1', + EQUAL: '0x3Fd3A0c85B70754eFc07aC9Ac0cbBDCe664865A6', + }, + sonic: { + pairFactory: '0xDDD9845Ba0D8f38d3045f804f67A1a8B9A528FcC', + voter: '0x17fa9dA6e01aD59513707F92033a6eb03CcB10B4', + EQUAL: '0xddf26b42c1d903de8962d3f79a74a501420d5f19', + }, +}; + +const getApy = async (chain) => { + const pairFactory = CHAINS[chain].pairFactory; + const voter = CHAINS[chain].voter; + const EQUAL = CHAINS[chain].EQUAL; + + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain, + permitFailure: true, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [EQUAL], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(EQUAL) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let keys = ''; + for (const p of [...Array(pages).keys()]) { + keys = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `${chain}:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${keys}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA) { + prices = { ...prices, ...p }; + } + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`${chain}:${poolMeta.t0}`]?.price; + const p1 = prices[`${chain}:${poolMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const rewardPerSec = + (rewardRate[i] / 1e18) * prices[`${chain}:${EQUAL}`]?.price; + const apyReward = ((rewardPerSec * 86400 * 365) / tvlUsd) * 100; + + return { + pool: p, + chain: utils.formatChain(chain), + project: 'equalizer-exchange', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [EQUAL] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +const apy = async () => { + const pools = ( + await Promise.all( + Object.keys(CHAINS).map(async (chain) => { + return await getApy(chain); + }) + ) + ).flat(); + return pools; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://equalizer.exchange/liquidity', +}; diff --git a/src/adaptors/equilibre/abiGauge.json b/src/adaptors/equilibre/abiGauge.json new file mode 100644 index 0000000000..996f717d7e --- /dev/null +++ b/src/adaptors/equilibre/abiGauge.json @@ -0,0 +1,553 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_stake", "type": "address" }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "bool", "name": "_forPair", "type": "bool" }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "maxRuns", "type": "uint256" } + ], + "name": "batchRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "maxRuns", "type": "uint256" } + ], + "name": "batchUpdateRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "checkpoints", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { "internalType": "uint256", "name": "balanceOf", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "derivedBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "derivedBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "derivedSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "getPriorBalanceIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "getPriorRewardPerToken", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "getPriorSupplyIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "lastEarn", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "numCheckpoints", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "rewardPerTokenCheckpoints", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardPerToken", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardPerTokenNumCheckpoints", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewards", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "supplyCheckpoints", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { "internalType": "uint256", "name": "supply", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyNumCheckpoints", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "i", "type": "uint256" }, + { "internalType": "address", "name": "oldToken", "type": "address" }, + { "internalType": "address", "name": "newToken", "type": "address" } + ], + "name": "swapOutRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "tokenIds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userRewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/equilibre/abiPair.json b/src/adaptors/equilibre/abiPair.json new file mode 100644 index 0000000000..273abdcbe9 --- /dev/null +++ b/src/adaptors/equilibre/abiPair.json @@ -0,0 +1,658 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/equilibre/abiPairFactory.json b/src/adaptors/equilibre/abiPairFactory.json new file mode 100644 index 0000000000..e8ad711040 --- /dev/null +++ b/src/adaptors/equilibre/abiPairFactory.json @@ -0,0 +1,215 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "PairCreated", + "inputs": [ + { + "type": "address", + "name": "token0", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "token1", + "internalType": "address", + "indexed": true + }, + { + "type": "bool", + "name": "stable", + "internalType": "bool", + "indexed": false + }, + { + "type": "address", + "name": "pair", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "MAX_FEE", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "acceptFeeManager", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "acceptPauser", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "allPairs", + "inputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "allPairsLength", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [ + { "type": "address", "name": "pair", "internalType": "address" } + ], + "name": "createPair", + "inputs": [ + { "type": "address", "name": "tokenA", "internalType": "address" }, + { "type": "address", "name": "tokenB", "internalType": "address" }, + { "type": "bool", "name": "stable", "internalType": "bool" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "feeManager", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getFee", + "inputs": [{ "type": "bool", "name": "_stable", "internalType": "bool" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address", "name": "", "internalType": "address" }, + { "type": "address", "name": "", "internalType": "address" }, + { "type": "bool", "name": "", "internalType": "bool" } + ], + "name": "getInitializable", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "getPair", + "inputs": [ + { "type": "address", "name": "", "internalType": "address" }, + { "type": "address", "name": "", "internalType": "address" }, + { "type": "bool", "name": "", "internalType": "bool" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "isPair", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "isPaused", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "pure", + "outputs": [{ "type": "bytes32", "name": "", "internalType": "bytes32" }], + "name": "pairCodeHash", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "pauser", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "pendingFeeManager", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "pendingPauser", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setFee", + "inputs": [ + { "type": "bool", "name": "_stable", "internalType": "bool" }, + { "type": "uint256", "name": "_fee", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setFeeManager", + "inputs": [ + { "type": "address", "name": "_feeManager", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setPause", + "inputs": [{ "type": "bool", "name": "_state", "internalType": "bool" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setPauser", + "inputs": [ + { "type": "address", "name": "_pauser", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "stableFee", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "volatileFee", + "inputs": [] + } +] diff --git a/src/adaptors/equilibre/abiVoter.json b/src/adaptors/equilibre/abiVoter.json new file mode 100644 index 0000000000..4cff3ac7ea --- /dev/null +++ b/src/adaptors/equilibre/abiVoter.json @@ -0,0 +1,741 @@ +[ + { + "type": "constructor", + "stateMutability": "nonpayable", + "inputs": [ + { "type": "address", "name": "__ve", "internalType": "address" }, + { "type": "address", "name": "_factory", "internalType": "address" }, + { "type": "address", "name": "_gauges", "internalType": "address" }, + { "type": "address", "name": "_bribes", "internalType": "address" } + ] + }, + { + "type": "event", + "name": "Abstained", + "inputs": [ + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "weight", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Attach", + "inputs": [ + { + "type": "address", + "name": "owner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Deposit", + "inputs": [ + { + "type": "address", + "name": "lp", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Detach", + "inputs": [ + { + "type": "address", + "name": "owner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DistributeReward", + "inputs": [ + { + "type": "address", + "name": "sender", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "GaugeCreated", + "inputs": [ + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "creator", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "internal_bribe", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "external_bribe", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "pool", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "GaugeKilled", + "inputs": [ + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "GaugeRevived", + "inputs": [ + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NotifyReward", + "inputs": [ + { + "type": "address", + "name": "sender", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "reward", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Voted", + "inputs": [ + { + "type": "address", + "name": "voter", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "weight", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Whitelisted", + "inputs": [ + { + "type": "address", + "name": "whitelister", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "token", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Withdraw", + "inputs": [ + { + "type": "address", + "name": "lp", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "gauge", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "tokenId", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "_ve", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "attachTokenToGauge", + "inputs": [ + { "type": "uint256", "name": "tokenId", "internalType": "uint256" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "bribefactory", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimBribes", + "inputs": [ + { "type": "address[]", "name": "_bribes", "internalType": "address[]" }, + { + "type": "address[][]", + "name": "_tokens", + "internalType": "address[][]" + }, + { "type": "uint256", "name": "_tokenId", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimFees", + "inputs": [ + { "type": "address[]", "name": "_fees", "internalType": "address[]" }, + { + "type": "address[][]", + "name": "_tokens", + "internalType": "address[][]" + }, + { "type": "uint256", "name": "_tokenId", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimRewards", + "inputs": [ + { "type": "address[]", "name": "_gauges", "internalType": "address[]" }, + { + "type": "address[][]", + "name": "_tokens", + "internalType": "address[][]" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "claimable", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "createGauge", + "inputs": [ + { "type": "address", "name": "_pool", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "detachTokenFromGauge", + "inputs": [ + { "type": "uint256", "name": "tokenId", "internalType": "uint256" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distribute", + "inputs": [ + { "type": "address[]", "name": "_gauges", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distribute", + "inputs": [ + { "type": "address", "name": "_gauge", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distribute", + "inputs": [ + { "type": "uint256", "name": "start", "internalType": "uint256" }, + { "type": "uint256", "name": "finish", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distribute", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distributeFees", + "inputs": [ + { "type": "address[]", "name": "_gauges", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "distro", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "emergencyCouncil", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "emitDeposit", + "inputs": [ + { "type": "uint256", "name": "tokenId", "internalType": "uint256" }, + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "emitWithdraw", + "inputs": [ + { "type": "uint256", "name": "tokenId", "internalType": "uint256" }, + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "external_bribes", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "factory", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "gaugefactory", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "gauges", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "governor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "initialize", + "inputs": [ + { "type": "address[]", "name": "_tokens", "internalType": "address[]" }, + { "type": "address", "name": "_minter", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "internal_bribes", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "isAlive", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "isGauge", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "isWhitelisted", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "killGauge", + "inputs": [ + { "type": "address", "name": "_gauge", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "lastVoted", + "inputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "length", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "minter", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "notifyRewardAmount", + "inputs": [ + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "poke", + "inputs": [ + { "type": "uint256", "name": "_tokenId", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "poolForGauge", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "poolVote", + "inputs": [ + { "type": "uint256", "name": "", "internalType": "uint256" }, + { "type": "uint256", "name": "", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "pools", + "inputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "reset", + "inputs": [ + { "type": "uint256", "name": "_tokenId", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "reviveGauge", + "inputs": [ + { "type": "address", "name": "_gauge", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setEmergencyCouncil", + "inputs": [ + { "type": "address", "name": "_council", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setGovernor", + "inputs": [ + { "type": "address", "name": "_governor", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "totalWeight", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateAll", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateFor", + "inputs": [ + { "type": "address[]", "name": "_gauges", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateForRange", + "inputs": [ + { "type": "uint256", "name": "start", "internalType": "uint256" }, + { "type": "uint256", "name": "end", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateGauge", + "inputs": [ + { "type": "address", "name": "_gauge", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "usedWeights", + "inputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "vote", + "inputs": [ + { "type": "uint256", "name": "tokenId", "internalType": "uint256" }, + { "type": "address[]", "name": "_poolVote", "internalType": "address[]" }, + { "type": "uint256[]", "name": "_weights", "internalType": "uint256[]" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "votes", + "inputs": [ + { "type": "uint256", "name": "", "internalType": "uint256" }, + { "type": "address", "name": "", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "weights", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "whitelist", + "inputs": [ + { "type": "address", "name": "_token", "internalType": "address" } + ] + } +] diff --git a/src/adaptors/equilibre/index.js b/src/adaptors/equilibre/index.js new file mode 100644 index 0000000000..fc4ec2fafe --- /dev/null +++ b/src/adaptors/equilibre/index.js @@ -0,0 +1,165 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xA138FAFc30f6Ec6980aAd22656F2F11C38B56a95'; +const voter = '0x4eB2B9768da9Ea26E3aBe605c9040bC12F236a59'; +const VARA = '0xe1da44c0da55b075ae8e2e4b6986adc76ac77d73'; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: 'kava', + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [VARA], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const derivedSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'derivedSupply'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'totalSupply'), + chain: 'kava', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(VARA) + ), + ]; + + const priceKeys = tokens.map((i) => `kava:${i}`).join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`kava:${poolMeta.t0}`]?.price; + const p1 = prices[`kava:${poolMeta.t1}`]?.price; + + // we don't have price data for some of the tokens + let tvlUsd; + if (p0 && p1) { + tvlUsd = r0 * p0 + r1 * p1; + } else if (p0 && !p1) { + tvlUsd = r0 * p0 * 2; + } else if (!p0 && p1) { + tvlUsd = r1 * p1 * 2; + } else return {}; + + const s = symbols[i]; + + const pairPrice = (tvlUsd * 1e18) / totalSupply[i]; + const totalRewardPerDay = + ((rewardRate[i] * 86400) / 1e18) * prices[`kava:${VARA}`]?.price; + + const apyReward = + (totalRewardPerDay * 36500) / ((derivedSupply[i] * pairPrice) / 1e18); + + return { + pool: p.toLowerCase(), + chain: utils.formatChain('kava'), + project: 'equilibre', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [VARA] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://equilibrefinance.com/liquidity', +}; diff --git a/src/adaptors/eternal-finance/index.js b/src/adaptors/eternal-finance/index.js new file mode 100644 index 0000000000..db06ae10f9 --- /dev/null +++ b/src/adaptors/eternal-finance/index.js @@ -0,0 +1,126 @@ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + +const MODULE_ADDRESS = '0x25a64579760a4c64be0d692327786a6375ec80740152851490cfd0b53604cf95'; +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const RESOURCE_URL = `${NODE_URL}/accounts/${MODULE_ADDRESS}/resources`; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; +const VAULT_MODULE_ADDRESS = `${MODULE_ADDRESS}::vault::Vaults`; +const VAULT_CONFIG_MODULE_ADDRESS = `${MODULE_ADDRESS}::vault_config::VaultConfigStore`; +const METADATA_MODULE_ADDRESS = `${MODULE_ADDRESS}::bank::MetaData`; +const IB_TOKEN_PREFIX = `0x1::coin::CoinInfo<${MODULE_ADDRESS}::vault::IbToken<` +const INTEREST_RATE_DENOM = new BigNumber(1000000000000); + +function simpleMapToObj(simpleMap,) { + return Object.fromEntries(simpleMap.map((obj) => [obj.key, obj.value])); +} + +async function getAllResources() { + const accountResources = await utils.getData(RESOURCE_URL); + + let vaultConfigs = {}; + let vaults = {}; + let ibTokenBalance = {}; + let metadata; + + accountResources.forEach(({ type, data }) => { + if (type === VAULT_CONFIG_MODULE_ADDRESS) { + vaultConfigs = simpleMapToObj(data.configs.data); + } else if (type === VAULT_MODULE_ADDRESS) { + vaults = simpleMapToObj(data.vaults.data); + } else if (type.slice(0, IB_TOKEN_PREFIX.length) === IB_TOKEN_PREFIX) { + let tokenStruct = type.split('<').pop().split('>>')[0]; + ibTokenBalance[tokenStruct] = data.supply.vec[0].integer.vec[0].value; + } else if (type === METADATA_MODULE_ADDRESS) { + metadata = data; + } + }) + + return { + vaultConfigs, + vaults, + ibTokenBalance, + metadata, + } +} + +// find interest per sec +function getBorrowingInterest(balance, vaultDebtVal, vaultConfig) { + const { interest_model: model } = vaultConfig; + + if (vaultDebtVal.eq(0) && balance.eq(0)) return new BigNumber(0); + + let total = vaultDebtVal.plus(balance); + let utilization = vaultDebtVal.times(100).times(INTEREST_RATE_DENOM).div(total); + if (utilization.lt(model.ceil_slope_1)) { + let p1 = utilization.times(model.max_interest_slope_1).div(model.ceil_slope_1); + return p1; + } else if (utilization.lt(model.ceil_slope_2)) { + return (new BigNumber(model.max_interest_slope_1) + .plus( + (utilization.minus(model.ceil_slope_1)) + .times(new BigNumber(model.max_interest_slope_2).minus(model.max_interest_slope_1)) + .div(new BigNumber(model.ceil_slope_2).minus(model.ceil_slope_1)) + ) + ); + } else if (utilization < model.ceil_slope_3) { + return (new BigNumber(model.max_interest_slope_2) + .plus( + (utilization.minus(model.ceil_slope_2)) + .times(new BigNumber(model.max_interest_slope_3).minus(model.max_interest_slope_2)) + .div(new BigNumber(model.ceil_slope_3).minus(model.ceil_slope_2)) + ) + ); + } else { + return new BigNumber(model.max_interest_slope_3); + } +} + +async function main() { + const { + vaultConfigs, + vaults, + ibTokenBalance, + metadata, + } = await getAllResources(); + + const tokenPrices = await Promise.all(metadata.banks_arr.map((tokenAddr) => { + return utils.getData(`${COINS_LLAMA_PRICE_URL}aptos:${tokenAddr}`) + })) + + const apy = metadata.banks_arr.map((lendingToken, idx) => { + const tokenPrice = tokenPrices[idx]?.coins?.[`aptos:${lendingToken}`]; + if (!tokenPrice) return undefined; + const ibTokenSupply = ibTokenBalance[lendingToken]; + const vaultInfo = vaults[lendingToken]; + const vaultConfig = vaultConfigs[lendingToken]; + const totalBalance = new BigNumber(vaultInfo.balance); + const totalBorrowed = new BigNumber(vaultInfo.vault_debt_val); + const totalSupply = totalBorrowed.plus(totalBalance) + const utilization = totalBorrowed.div(totalSupply); + const borrowingInterest = getBorrowingInterest(totalBalance, totalBorrowed, vaultConfig).div(INTEREST_RATE_DENOM).toNumber() * 100; + const lendingApy = borrowingInterest * utilization.toNumber() * (1 - 0.18); + const priceConversionFactor = new BigNumber(1).shiftedBy(-tokenPrice.decimals).times(tokenPrice.price); + return { + pool: `${lendingToken}-aptos`.toLowerCase(), + chain: utils.formatChain('aptos'), + project: 'eternal-finance', + symbol: utils.formatSymbol(tokenPrice.symbol), + tvlUsd: new BigNumber(vaultInfo.balance).multipliedBy(priceConversionFactor).toNumber(), + apyBase: lendingApy, + underlyingTokens: [lendingToken], + apyBaseBorrow: borrowingInterest, + totalSupplyUsd: totalSupply.multipliedBy(priceConversionFactor).toNumber(), + totalBorrowUsd: totalBorrowed.multipliedBy(priceConversionFactor).toNumber(), + ltv: 0, + poolMeta: '2x leverage' + }; + }).filter(v => v); + return apy; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.eternalfinance.io/lend', +}; diff --git a/src/adaptors/ethena-usde/index.js b/src/adaptors/ethena-usde/index.js new file mode 100644 index 0000000000..0b55d4d448 --- /dev/null +++ b/src/adaptors/ethena-usde/index.js @@ -0,0 +1,60 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); + +const sUSDe = '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: sUSDe, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const priceKey = `ethereum:${sUSDe}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const tvlUsd = totalSupply * price; + + const currentBlock = await sdk.api.util.getLatestBlock('ethereum'); + const toBlock = currentBlock.number; + const topic = + '0xbb28dd7cd6be6f61828ea9158a04c5182c716a946a6d2f31f4864edb87471aa6'; + const logs = ( + await sdk.api.util.getLogs({ + target: '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497', + topic: '', + toBlock, + fromBlock: 19026137, + keys: [], + topics: [topic], + chain: 'ethereum', + }) + ).output.sort((a, b) => b.blockNumber - a.blockNumber); + + // rewards are now beeing streamed every 8hours, which we scale up to a year + const rewardsReceived = parseInt(logs[0].data / 1e18); + const aprBase = ((rewardsReceived * 3 * 365) / tvlUsd) * 100; + // weekly compoounding + const apyBase = utils.aprToApy(aprBase, 52); + return [ + { + pool: sUSDe, + symbol: 'sUSDe', + project: 'ethena-usde', + chain: 'Ethereum', + tvlUsd, + apyBase, + poolMeta: '7 days unstaking', + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.ethena.fi/', +}; diff --git a/src/adaptors/ether.fi-stake/index.js b/src/adaptors/ether.fi-stake/index.js new file mode 100644 index 0000000000..4c42391f70 --- /dev/null +++ b/src/adaptors/ether.fi-stake/index.js @@ -0,0 +1,106 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const weETH = '0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee'; +const eETH = '0x35fA164735182de50811E8e2E824cFb9B6118ac2' +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const eigen = '0xec53bf9167f50cdeb3ae105f56099aaab9061f83'; +const lrt2 = '0x8F08B70456eb22f6109F57b8fafE862ED28E6040'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: weETH, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const totalSupplyEETH = + ( + await sdk.api.abi.call({ + target: eETH, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const abi = 'function getRate() external view returns (uint256)'; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: weETH, + abi: abi, + }), + sdk.api.abi.call({ + target: weETH, + abi: abi, + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: weETH, + abi: abi, + block: block7dayAgo, + }), + ]); + + const apr1d = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18) * 365 * 100; + + const apr7d = + ((exchangeRates[0].output - exchangeRates[2].output) / 1e18 / 7) * + 365 * + 100; + + + const optimismApi = new sdk.ChainApi({ chain: 'optimism' }); + const restakingWeeklyEigen = Number(await optimismApi.call({ + target: '0xAB7590CeE3Ef1A863E9A5877fBB82D9bE11504da', + abi: 'function categoryTVL(string _category) view returns (uint256)', + params: [eigen] + })) / 1e18; + + const priceKey = `ethereum:${weETH}`; + const priceKeyEigen = `ethereum:${eigen}`; + const priceKeyEETH = `ethereum:${eETH}`; + const eigenPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:${eigen}`) + ).data.coins[`ethereum:${eigen}`]?.price; + const eethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:${eETH}`) + ).data.coins[`ethereum:${eETH}`]?.price; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + const restakingApy = (restakingWeeklyEigen * eigenPrice) / 7 / (totalSupplyEETH * eethPrice) * 365 * 100; + + return [ + { + pool: weETH, + chain: 'ethereum', + project: 'ether.fi-stake', + symbol: 'weETH', + tvlUsd: totalSupply * price, + apyBase: apr1d, + apyBase7d: apr7d, + apyReward: restakingApy, + underlyingTokens: [weth], + rewardTokens: [lrt2], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://app.ether.fi/', +}; diff --git a/src/adaptors/etherex-cl/index.js b/src/adaptors/etherex-cl/index.js new file mode 100644 index 0000000000..05f0defc74 --- /dev/null +++ b/src/adaptors/etherex-cl/index.js @@ -0,0 +1,150 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const REX = '0xEfD81eeC32B9A8222D1842ec3d99c7532C31e348'; +const PROJECT = 'etherex-cl'; +const CHAIN = 'linea'; +const SUBGRAPH = 'https://linea.kingdomsubgraph.com/subgraphs/name/etherex-pruned'; + +const poolsQuery = gql` + query getPools($first: Int!, $skip: Int!) { + clPools( + first: $first + skip: $skip + orderBy: totalValueLockedUSD + orderDirection: desc + where: { gauge_not: null } + ) { + id + token0 { + id + symbol + } + token1 { + id + symbol + } + feeTier + tickSpacing + totalValueLockedUSD + gauge { + id + } + poolDayData(first: 7, orderBy: startOfDay, orderDirection: desc) { + volumeUSD + } + } + } +`; + +async function fetchAllPools() { + let allPools = []; + let skip = 0; + const first = 1000; + + while (true) { + const poolsData = await request(SUBGRAPH, poolsQuery, { first, skip }); + const pools = poolsData.clPools; + + if (pools.length === 0) break; + + allPools = allPools.concat(pools); + + if (pools.length < first) break; + + skip += first; + } + + return allPools; +} + +async function apy() { + try { + const pools = await fetchAllPools(); + + let etherexPools = []; + try { + const etherexApiData = await axios.get('https://etherex-api-production.up.railway.app/mixed-pairs?includeTokens=False'); + if (etherexApiData.data && Array.isArray(etherexApiData.data.pairs)) { + etherexPools = etherexApiData.data.pairs; + } + } catch (error) { + console.error('Failed to fetch Etherex API data:', error.message); + } + + const aprMap = {}; + for (const pool of etherexPools) { + if (pool.id) { + aprMap[pool.id.toLowerCase()] = { + lpApr: Number(pool.lpApr) || 0 + }; + } + } + + const results = []; + + for (const pool of pools) { + const tvlUsd = Number(pool.totalValueLockedUSD) || 0; + + if (!pool.gauge?.id) continue; + + const poolAddress = pool.id.toLowerCase(); + const apiData = aprMap[poolAddress]; + + if (!apiData) continue; + + const apyBase = 0; + let apyReward = 0; + const tickSpacing = parseInt(pool.tickSpacing); + + const apiPool = etherexPools.find(p => p.id.toLowerCase() === poolAddress); + if (apiPool && apiPool.recommendedRangesNew) { + if (tickSpacing === 1 || tickSpacing === 5) { + const wideRange = apiPool.recommendedRangesNew.find(range => range.name === 'Wide'); + apyReward = wideRange ? wideRange.lpApr : apiData.lpApr || 0; + } else { + const narrowRange = apiPool.recommendedRangesNew.find(range => range.name === 'Narrow'); + apyReward = narrowRange ? narrowRange.lpApr : apiData.lpApr || 0; + } + } else { + apyReward = apiData.lpApr || 0; + } + + results.push({ + pool: `${poolAddress}-${utils.formatChain(CHAIN)}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT, + poolMeta: `CL ${(Number(pool.feeTier) / 10000).toFixed(2)}%`, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd, + apyBase, + apyBase7d: 0, + apyReward, + rewardTokens: apyReward > 0 ? [REX] : [], + underlyingTokens: [ + pool.token0.id.toLowerCase(), + pool.token1.id.toLowerCase() + ], + url: `https://www.etherex.finance/liquidity/${poolAddress}`, + volumeUsd1d: pool.poolDayData?.[0]?.volumeUSD + ? Number(pool.poolDayData[0].volumeUSD) + : 0, + volumeUsd7d: pool.poolDayData + ? pool.poolDayData.reduce((sum, day) => sum + Number(day.volumeUSD || 0), 0) + : 0, + }); + } + + return results.filter((p) => utils.keepFinite(p)); + + } catch (error) { + console.error('Error fetching Etherex CL data:', error); + return []; + } +} + +module.exports = { + timetravel: false, + apy: apy, +}; \ No newline at end of file diff --git a/src/adaptors/euler-v2/factory.abi.json b/src/adaptors/euler-v2/factory.abi.json new file mode 100644 index 0000000000..6fc3409317 --- /dev/null +++ b/src/adaptors/euler-v2/factory.abi.json @@ -0,0 +1,298 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "admin", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createProxy", + "inputs": [ + { + "name": "desiredImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "upgradeable", + "type": "bool", + "internalType": "bool" + }, + { + "name": "trailingData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getProxyConfig", + "inputs": [ + { + "name": "proxy", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct GenericFactory.ProxyConfig", + "components": [ + { + "name": "upgradeable", + "type": "bool", + "internalType": "bool" + }, + { + "name": "implementation", + "type": "address", + "internalType": "address" + }, + { + "name": "trailingData", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getProxyListLength", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getProxyListSlice", + "inputs": [ + { + "name": "start", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "end", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "list", + "type": "address[]", + "internalType": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "implementation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isProxy", + "inputs": [ + { + "name": "proxy", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxyList", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setImplementation", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setUpgradeAdmin", + "inputs": [ + { + "name": "newUpgradeAdmin", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeAdmin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Genesis", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "ProxyCreated", + "inputs": [ + { + "name": "proxy", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "upgradeable", + "type": "bool", + "indexed": false, + "internalType": "bool" + }, + { + "name": "implementation", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "trailingData", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetImplementation", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetUpgradeAdmin", + "inputs": [ + { + "name": "newUpgradeAdmin", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "E_BadAddress", + "inputs": [] + }, + { + "type": "error", + "name": "E_BadQuery", + "inputs": [] + }, + { + "type": "error", + "name": "E_DeploymentFailed", + "inputs": [] + }, + { + "type": "error", + "name": "E_Implementation", + "inputs": [] + }, + { + "type": "error", + "name": "E_Reentrancy", + "inputs": [] + }, + { + "type": "error", + "name": "E_Unauthorized", + "inputs": [] + } + ] \ No newline at end of file diff --git a/src/adaptors/euler-v2/index.js b/src/adaptors/euler-v2/index.js new file mode 100644 index 0000000000..74a30cc2cf --- /dev/null +++ b/src/adaptors/euler-v2/index.js @@ -0,0 +1,213 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); + +const { addMerklRewardApy } = require('../merkl/merkl-additional-reward'); + +const lensAbi = require('./lens.abi.json'); +const factoryAbi = require('./factory.abi.json'); + +const chains = { + ethereum: { + factory: '0x29a56a1b8214D9Cf7c5561811750D5cBDb45CC8e', + vaultLens: '0x83801C7BbeEFa54B91F8A07E36D81515a0Fc5b60', + fromBlock: 20529225, + }, + bob: { + factory: '0x046a9837A61d6b6263f54F4E27EE072bA4bdC7e4', + vaultLens: '0xC6B56a52e5823659d90F3020164b92D1c2de03CE', + fromBlock: 12266832, + }, + sonic: { + factory: '0xF075cC8660B51D0b8a4474e3f47eDAC5fA034cFB', + vaultLens: '0x4c7BA548032FE3eA11b7D6BeaF736B3B74F69248', + fromBlock: 5324454, + }, + avax: { + factory: '0xaf4B4c18B17F6a2B32F6c398a3910bdCD7f26181', + vaultLens: '0xcC5F7593a4D5974F84A30B28Bd3fdb374319a254', + fromBlock: 56805794, + }, + berachain: { + factory: '0x5C13fb43ae9BAe8470f646ea647784534E9543AF', + vaultLens: '0x2ffd260BAd257C08516B649c93Ea3eb6b63a5639', + fromBlock: 786314, + }, + bsc: { + factory: '0x7F53E2755eB3c43824E162F7F6F087832B9C9Df6', + vaultLens: '0x84641751808f85F54344369036594E1a7301a414', + fromBlock: 46370655, + }, + base: { + factory: '0x7F321498A801A191a93C840750ed637149dDf8D0', + vaultLens: '0x3530dA02ceC2818477888FdC77e777b566B6db4C', + fromBlock: 22282408, + }, + swellchain: { + factory: '0x238bF86bb451ec3CA69BB855f91BDA001aB118b9', + vaultLens: '0x94Dd6A076838D6Fc5031e32138b95d810793DB1c', + fromBlock: 2350701, + }, + unichain: { + factory: '0xbAd8b5BDFB2bcbcd78Cc9f1573D3Aad6E865e752', + vaultLens: '0xd40DD19eD88a949436f784877A1BB59660ee8DE3', + fromBlock: 8541544, + }, + arbitrum: { + factory: '0x78Df1CF5bf06a7f27f2ACc580B934238C1b80D50', + vaultLens: '0x59d28aF1fC4A52EE402C9099BeCEf333366184Df', + fromBlock: 300690953, + }, + linea: { + factory: '0x84711986Fd3BF0bFe4a8e6d7f4E22E67f7f27F04', + vaultLens: '0xd20E9D6cfa0431aC306cC9906896a7BC0BE0Db64', + fromBlock: 17915340, + }, + tac: { + factory: '0x2b21621b8Ef1406699a99071ce04ec14cCd50677', + vaultLens: '0x70d9bc0aBd4EF6Ceb7C88875b9cf4013db3D780A', + fromBlock: 555116, + }, +}; + +// Chain name mapping for URL construction +const chainNameMapping = { + ethereum: 'ethereum', + bob: 'bob', + sonic: 'sonic', + avax: 'avalanche', + berachain: 'berachain', + bsc: 'bnbsmartchain', + base: 'base', + swellchain: 'swellchain', + unichain: 'unichain', + arbitrum: 'arbitrumone', + linea: 'lineamainnet', + tac: 'tac', +}; + +const CHAIN_TIMEOUT_MS = 120_000; + +const getLogsWithTimeout = (params, chain) => { + let timer; + const timeoutPromise = new Promise((_, reject) => { + timer = setTimeout( + () => reject(new Error(`Timed out fetching logs for ${chain}`)), + CHAIN_TIMEOUT_MS + ); + }); + + return Promise.race([sdk.api.util.getLogs(params), timeoutPromise]).finally( + () => clearTimeout(timer) + ); +}; + +const getApys = async () => { + const factoryIFace = new ethers.utils.Interface(factoryAbi); + + const chainResults = await Promise.all( + Object.entries(chains).map(async ([chain, config]) => { + try { + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + + // Fetch all pools from factory events + const poolDeployEvents = await getLogsWithTimeout( + { + fromBlock: config.fromBlock, + toBlock: toBlock, + target: config.factory, + chain: chain, + topic: '', + keys: [], + topics: [factoryIFace.getEventTopic('ProxyCreated')], + entireLog: true, + }, + chain + ); + + const vaultAddresses = poolDeployEvents.output.map((event) => { + const decoded = factoryIFace.decodeEventLog( + 'ProxyCreated', + event.data, + event.topics + ); + return decoded['proxy']; + }); + + const vaultInfos = ( + await sdk.api.abi.multiCall({ + calls: vaultAddresses.map((address) => ({ + target: config.vaultLens, + params: [address], + })), + abi: lensAbi.find((m) => m.name === 'getVaultInfoFull'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + // keep only pools with interest rate data + const vaultInfosFilterted = vaultInfos.filter( + (i) => i?.irmInfo?.interestRateInfo[0]?.supplyAPY > 0 + ); + + const priceKeys = vaultInfosFilterted + .map((i) => `${chain}:${i.asset}`) + .join(','); + + const { data: prices } = await axios.get( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const pools = vaultInfosFilterted.map((i) => { + const price = prices.coins[`${chain}:${i.asset}`]?.price; + + const totalSupplied = i.totalAssets; + const totalBorrowed = i.totalBorrowed; + + const totalSuppliedUSD = + ethers.utils.formatUnits(totalSupplied, i.assetDecimals) * price; + const totalBorrowedUSD = + ethers.utils.formatUnits(totalBorrowed, i.assetDecimals) * price; + + return { + pool: i.vault, + chain, + project: 'euler-v2', + symbol: i.assetSymbol, + poolMeta: i.vaultName, + tvlUsd: totalSuppliedUSD - totalBorrowedUSD, + totalSupplyUsd: totalSuppliedUSD, + totalBorrowUsd: totalBorrowedUSD, + apyBase: Number( + ethers.utils.formatUnits( + i.irmInfo.interestRateInfo[0].supplyAPY, + 25 + ) + ), + apyBaseBorrow: Number( + ethers.utils.formatUnits( + i.irmInfo.interestRateInfo[0].borrowAPY, + 25 + ) + ), + underlyingTokens: [i.asset], + url: `https://app.euler.finance/vault/${i.vault}?network=${chainNameMapping[chain]}`, + }; + }); + return pools; + } catch (err) { + console.error(`Error processing chain ${chain}:`, err); + return []; + } + }) + ); + + return await addMerklRewardApy(chainResults.flat(), 'euler'); +}; + +module.exports = { + timetravel: false, + apy: getApys, +}; diff --git a/src/adaptors/euler-v2/lens.abi.json b/src/adaptors/euler-v2/lens.abi.json new file mode 100644 index 0000000000..c9908e75aa --- /dev/null +++ b/src/adaptors/euler-v2/lens.abi.json @@ -0,0 +1,1059 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_oracleLens", + "type": "address" + }, + { + "internalType": "address", + "name": "_utilsLens", + "type": "address" + }, + { + "internalType": "address", + "name": "_irmLens", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "TTL_ERROR", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TTL_INFINITY", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TTL_LIQUIDATION", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TTL_MORE_THAN_ONE_YEAR", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "getRecognizedCollateralsLTVInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "collateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialLiquidationLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rampDuration", + "type": "uint256" + } + ], + "internalType": "struct LTVInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "internalType": "uint256", + "name": "numberOfEpochs", + "type": "uint256" + } + ], + "name": "getRewardVaultInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "internalType": "string", + "name": "rewardName", + "type": "string" + }, + { + "internalType": "string", + "name": "rewardSymbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "rewardDecimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "balanceTracker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "epochDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentEpoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewardedEligible", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewardRegistered", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewardClaimed", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEnd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + } + ], + "internalType": "struct RewardAmountInfo[]", + "name": "epochInfoPrevious", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEnd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + } + ], + "internalType": "struct RewardAmountInfo[]", + "name": "epochInfoUpcoming", + "type": "tuple[]" + } + ], + "internalType": "struct VaultRewardInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "getVaultInfoFull", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "string", + "name": "vaultName", + "type": "string" + }, + { + "internalType": "string", + "name": "vaultSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "vaultDecimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "string", + "name": "assetName", + "type": "string" + }, + { + "internalType": "string", + "name": "assetSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "assetDecimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "unitOfAccount", + "type": "address" + }, + { + "internalType": "string", + "name": "unitOfAccountName", + "type": "string" + }, + { + "internalType": "string", + "name": "unitOfAccountSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "unitOfAccountDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accumulatedFeesShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accumulatedFeesAssets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "governorFeeReceiver", + "type": "address" + }, + { + "internalType": "address", + "name": "protocolFeeReceiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "protocolFeeShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hookedOperations", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "configFlags", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxLiquidationDiscount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationCoolOffTime", + "type": "uint256" + }, + { + "internalType": "address", + "name": "dToken", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "internalType": "address", + "name": "hookTarget", + "type": "address" + }, + { + "internalType": "address", + "name": "evc", + "type": "address" + }, + { + "internalType": "address", + "name": "protocolConfig", + "type": "address" + }, + { + "internalType": "address", + "name": "balanceTracker", + "type": "address" + }, + { + "internalType": "address", + "name": "permit2", + "type": "address" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "address", + "name": "governorAdmin", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowSPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyAPY", + "type": "uint256" + } + ], + "internalType": "struct InterestRateInfo[]", + "name": "interestRateInfo", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "internalType": "enum InterestRateModelType", + "name": "interestRateModelType", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "interestRateModelParams", + "type": "bytes" + } + ], + "internalType": "struct InterestRateModelDetailedInfo", + "name": "interestRateModelInfo", + "type": "tuple" + } + ], + "internalType": "struct VaultInterestRateModelInfo", + "name": "irmInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "collateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialLiquidationLTV", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "targetTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rampDuration", + "type": "uint256" + } + ], + "internalType": "struct LTVInfo[]", + "name": "collateralLTVInfo", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "unitOfAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutBid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutAsk", + "type": "uint256" + } + ], + "internalType": "struct AssetPriceInfo", + "name": "liabilityPriceInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "unitOfAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutBid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutAsk", + "type": "uint256" + } + ], + "internalType": "struct AssetPriceInfo[]", + "name": "collateralPriceInfo", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "bytes", + "name": "oracleInfo", + "type": "bytes" + } + ], + "internalType": "struct OracleDetailedInfo", + "name": "oracleInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "unitOfAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutBid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutAsk", + "type": "uint256" + } + ], + "internalType": "struct AssetPriceInfo", + "name": "backupAssetPriceInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "bytes", + "name": "oracleInfo", + "type": "bytes" + } + ], + "internalType": "struct OracleDetailedInfo", + "name": "backupAssetOracleInfo", + "type": "tuple" + } + ], + "internalType": "struct VaultInfoFull", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "cash", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrows", + "type": "uint256[]" + } + ], + "name": "getVaultInterestRateModelInfo", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowSPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyAPY", + "type": "uint256" + } + ], + "internalType": "struct InterestRateInfo[]", + "name": "interestRateInfo", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "internalType": "enum InterestRateModelType", + "name": "interestRateModelType", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "interestRateModelParams", + "type": "bytes" + } + ], + "internalType": "struct InterestRateModelDetailedInfo", + "name": "interestRateModelInfo", + "type": "tuple" + } + ], + "internalType": "struct VaultInterestRateModelInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "getVaultKinkInterestRateModelInfo", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "queryFailure", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "queryFailureReason", + "type": "bytes" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowSPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAPY", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyAPY", + "type": "uint256" + } + ], + "internalType": "struct InterestRateInfo[]", + "name": "interestRateInfo", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "interestRateModel", + "type": "address" + }, + { + "internalType": "enum InterestRateModelType", + "name": "interestRateModelType", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "interestRateModelParams", + "type": "bytes" + } + ], + "internalType": "struct InterestRateModelDetailedInfo", + "name": "interestRateModelInfo", + "type": "tuple" + } + ], + "internalType": "struct VaultInterestRateModelInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "irmLens", + "outputs": [ + { + "internalType": "contract IRMLens", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracleLens", + "outputs": [ + { + "internalType": "contract OracleLens", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "utilsLens", + "outputs": [ + { + "internalType": "contract UtilsLens", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/euler/EulerToolsClient.js b/src/adaptors/euler/EulerToolsClient.js new file mode 100644 index 0000000000..dcbfdf5680 --- /dev/null +++ b/src/adaptors/euler/EulerToolsClient.js @@ -0,0 +1,173 @@ +const initialReconnectTimeout = 500; +const reconnectTimeCeiling = 8000; + +class EulerToolClient { + constructor(opts) { + this.opts = opts; + + if (!this.opts.version) throw `must provide version to EulerToolClient`; + + this.nextId = 1; + this.cbs = {}; + this.timeoutHandles = {}; + this.subs = {}; + this.pendingMessagesToSend = []; + this.reconnectTimeout = initialReconnectTimeout; + + this.heartBeatInterval = setInterval(() => { + if (this.ws === undefined || this.ws.readyState !== 1) return; + this.send('ping', {}, () => {}); + }, this.opts.pingFreqMilliseconds || 55000); + } + + connect() { + if (this.ws) { + this.ws.close(); + } + this.ws = new this.opts.WebSocket(this.opts.endpoint); + + this.ws.onopen = () => { + this.reconnectTimeout = initialReconnectTimeout; + + this.send( + 'hello', + { version: this.opts.version }, + (err, helloResponse) => { + if (err) { + console.error('Connection error: ', err); + return; + } + + if (this.opts.onConnect) this.opts.onConnect(helloResponse); + } + ); + + for (let msg of this.pendingMessagesToSend) { + this.ws.send(msg); + } + + this.pendingMessagesToSend = []; + + for (let subId of Object.keys(this.subs)) { + this.send('sub', this.subs[subId], this.cbs[subId], subId); + } + }; + + this.ws.onmessage = (msgStr) => { + let msg = JSON.parse(msgStr.data); + + let cb = this.cbs[msg.id]; + if (!cb) return; // probably already unsubscribed + + if (msg.fin) this.clearId(msg.id); + + cb(null, msg); + }; + + this.ws.onclose = () => { + if (this.shuttingDown) return; + this.ws = undefined; + + if (this.timeoutWatcher) { + clearTimeout(this.timeoutWatcher); + } + this.timeoutWatcher = setTimeout( + () => this.connect(), + this.reconnectTimeout + ); + + this.reconnectTimeout *= 2; + if (this.reconnectTimeout > reconnectTimeCeiling) + this.reconnectTimeout = reconnectTimeCeiling; + + if (this.opts.onDisconnect) this.opts.onDisconnect(this); + }; + + this.ws.onerror = (e) => { + let ws = this.ws; + delete this.ws; + ws.close(); + }; + } + + send(cmd, body, cb, idOverride, timeout) { + let id = idOverride || this.nextId++; + + let msg = JSON.stringify({ id: parseInt(id), cmd, ...body }); + + if (cb) { + this.cbs[id] = cb; + if (timeout) { + this.timeoutHandles[id] = setTimeout(() => { + this.clearId(id); + cb(`timeout after ${timeout}ms`, null); + }, timeout); + } + } + + if (this.ws === undefined || this.ws.readyState !== 1) { + if (cmd !== 'sub' && cmd !== 'unsub') + this.pendingMessagesToSend.push(msg); + } else { + this.ws.send(msg); + } + + return id; + } + + async sendAsync(cmd, body, timeout) { + if (!timeout) timeout = 5000; + + let response = await new Promise((resolve, reject) => { + let subId; + subId = this.send( + cmd, + body, + (err, result) => { + if (cmd === 'sub' && subId !== undefined) this.unsubscribe(subId); + if (err) reject(err); + else resolve(result); + }, + undefined, + timeout + ); + }); + + return response; + } + + sub(sub, cb) { + let id = this.send('sub', sub, cb); + this.subs[id] = sub; + return id; + } + + unsubscribe(id) { + let msg = JSON.stringify({ id: parseInt(id), cmd: 'unsub' }); + + if (this.ws !== undefined && this.ws.readyState === 1) { + this.ws.send(msg); + } + + this.clearId(id); + } + + clearId(id) { + delete this.cbs[id]; + if (this.timeoutHandles[id]) { + clearTimeout(this.timeoutHandles[id]); + delete this.timeoutHandles[id]; + } + delete this.subs[id]; + } + + shutdown() { + this.shuttingDown = true; + if (this.ws) this.ws.close(); + this.ws = undefined; + if (this.heartBeatInterval) clearInterval(this.heartBeatInterval); + this.heartBeatInterval = undefined; + } +} + +module.exports = EulerToolClient; diff --git a/src/adaptors/euler/abiEtoken.js b/src/adaptors/euler/abiEtoken.js new file mode 100644 index 0000000000..c61a559285 --- /dev/null +++ b/src/adaptors/euler/abiEtoken.js @@ -0,0 +1,1120 @@ +module.exports = [ + { + inputs: [ + { internalType: 'bytes32', name: 'moduleGitCommit_', type: 'bytes32' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBalances', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint96', + name: 'reserveBalance', + type: 'uint96', + }, + { + indexed: false, + internalType: 'uint256', + name: 'poolSize', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulator', + type: 'uint256', + }, + { + indexed: false, + internalType: 'int96', + name: 'interestRate', + type: 'int96', + }, + { + indexed: false, + internalType: 'uint256', + name: 'timestamp', + type: 'uint256', + }, + ], + name: 'AssetStatus', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'delegate', + type: 'address', + }, + ], + name: 'DelegateAverageLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'EnterMarket', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'ExitMarket', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Genesis', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'GovConvertReserves', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + components: [ + { internalType: 'address', name: 'eTokenAddress', type: 'address' }, + { internalType: 'bool', name: 'borrowIsolated', type: 'bool' }, + { internalType: 'uint32', name: 'collateralFactor', type: 'uint32' }, + { internalType: 'uint32', name: 'borrowFactor', type: 'uint32' }, + { internalType: 'uint24', name: 'twapWindow', type: 'uint24' }, + ], + indexed: false, + internalType: 'struct Storage.AssetConfig', + name: 'newConfig', + type: 'tuple', + }, + ], + name: 'GovSetAssetConfig', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'chainlinkAggregator', + type: 'address', + }, + ], + name: 'GovSetChainlinkPriceFeed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestRateModel', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes', + name: 'resetParams', + type: 'bytes', + }, + ], + name: 'GovSetIRM', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'uint16', + name: 'newPricingType', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint32', + name: 'newPricingParameter', + type: 'uint32', + }, + ], + name: 'GovSetPricingConfig', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'uint32', + name: 'newReserveFee', + type: 'uint32', + }, + ], + name: 'GovSetReserveFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'moduleId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'moduleImpl', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'moduleGitCommit', + type: 'bytes32', + }, + ], + name: 'InstallerInstallModule', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newGovernorAdmin', + type: 'address', + }, + ], + name: 'InstallerSetGovernorAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'newUpgradeAdmin', + type: 'address', + }, + ], + name: 'InstallerSetUpgradeAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'violator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repay', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'yield', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'healthScore', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseDiscount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'discount', + type: 'uint256', + }, + ], + name: 'Liquidation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'eToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'dToken', + type: 'address', + }, + ], + name: 'MarketActivated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'pToken', + type: 'address', + }, + ], + name: 'PTokenActivated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'PTokenUnWrap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'PTokenWrap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'proxy', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'moduleId', + type: 'uint256', + }, + ], + name: 'ProxyCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestBurn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestDeposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestDonate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'violator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repay', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'minYield', + type: 'uint256', + }, + ], + name: 'RequestLiquidate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestMint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestRepay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'accountIn', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'accountOut', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'underlyingIn', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'underlyingOut', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'swapType', + type: 'uint256', + }, + ], + name: 'RequestSwap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestTransferDToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestTransferEToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RequestWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'TrackAverageLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'UnTrackAverageLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approveSubAccount', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'balance', type: 'uint256' }], + name: 'convertBalanceToUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'underlyingAmount', type: 'uint256' }, + ], + name: 'convertUnderlyingToBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'donateToReserves', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'moduleGitCommit', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'moduleId', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'reserveBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'reserveBalanceUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupplyUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'touch', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'transferFromMax', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'underlyingAsset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/euler/abiEulerSimpleLens.js b/src/adaptors/euler/abiEulerSimpleLens.js new file mode 100644 index 0000000000..9ed31d33a7 --- /dev/null +++ b/src/adaptors/euler/abiEulerSimpleLens.js @@ -0,0 +1,246 @@ +module.exports = [ + { + inputs: [ + { internalType: 'bytes32', name: 'moduleGitCommit_', type: 'bytes32' }, + { internalType: 'address', name: 'euler_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'euler', + outputs: [{ internalType: 'contract Euler', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'exec', + outputs: [{ internalType: 'contract Exec', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountStatus', + outputs: [ + { internalType: 'uint256', name: 'collateralValue', type: 'uint256' }, + { internalType: 'uint256', name: 'liabilityValue', type: 'uint256' }, + { internalType: 'uint256', name: 'healthScore', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'getDTokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'getETokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getEnteredMarkets', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'getEulerAccountAllowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'getPTokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'getPriceFull', + outputs: [ + { internalType: 'uint256', name: 'twap', type: 'uint256' }, + { internalType: 'uint256', name: 'twapPeriod', type: 'uint256' }, + { internalType: 'uint256', name: 'currPrice', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'getPricingConfig', + outputs: [ + { internalType: 'uint16', name: 'pricingType', type: 'uint16' }, + { internalType: 'uint32', name: 'pricingParameters', type: 'uint32' }, + { internalType: 'address', name: 'pricingForwarded', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'getTokenInfo', + outputs: [ + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'getTotalSupplyAndDebts', + outputs: [ + { internalType: 'uint256', name: 'poolSize', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBalances', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrows', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveBalance', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'interestAccumulator', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'interestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'interestRates', + outputs: [ + { internalType: 'uint256', name: 'borrowSPY', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyAPY', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'irmSettings', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'kink', type: 'uint256' }, + { internalType: 'uint256', name: 'baseAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'kinkAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'maxAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'baseSupplyAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'kinkSupplyAPY', type: 'uint256' }, + { internalType: 'uint256', name: 'maxSupplyAPY', type: 'uint256' }, + ], + internalType: 'struct EulerSimpleLens.ResponseIRM', + name: 'r', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'markets', + outputs: [{ internalType: 'contract Markets', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'moduleGitCommit', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'reserveFee', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'underlyingToAssetConfig', + outputs: [ + { + components: [ + { internalType: 'address', name: 'eTokenAddress', type: 'address' }, + { internalType: 'bool', name: 'borrowIsolated', type: 'bool' }, + { internalType: 'uint32', name: 'collateralFactor', type: 'uint32' }, + { internalType: 'uint32', name: 'borrowFactor', type: 'uint32' }, + { internalType: 'uint24', name: 'twapWindow', type: 'uint24' }, + ], + internalType: 'struct Storage.AssetConfig', + name: 'config', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'underlyingToDToken', + outputs: [{ internalType: 'address', name: 'dToken', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'underlyingToEToken', + outputs: [{ internalType: 'address', name: 'eToken', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'underlyingToInternalTokens', + outputs: [ + { internalType: 'address', name: 'eToken', type: 'address' }, + { internalType: 'address', name: 'dToken', type: 'address' }, + { internalType: 'address', name: 'pToken', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'underlying', type: 'address' }], + name: 'underlyingToPToken', + outputs: [{ internalType: 'address', name: 'pToken', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/euler/abiRewardDistribution.js b/src/adaptors/euler/abiRewardDistribution.js new file mode 100644 index 0000000000..bcddc30d03 --- /dev/null +++ b/src/adaptors/euler/abiRewardDistribution.js @@ -0,0 +1,191 @@ +module.exports = [ + { + inputs: [ + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'address', name: '_authority', type: 'address' }, + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'destination', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RewardDistributionAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'RewardsDistributed', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'addRewardDistribution', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'authority', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'distributeRewards', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'distributions', + outputs: [ + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'distributionsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'index', type: 'uint256' }, + { internalType: 'address', name: 'destination', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'editRewardDistribution', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'nominateNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'nominatedOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'removeRewardDistribution', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardsToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_authority', type: 'address' }], + name: 'setAuthority', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + ], + name: 'setRewardToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/euler/abiStakingRewards.js b/src/adaptors/euler/abiStakingRewards.js new file mode 100644 index 0000000000..06a9524737 --- /dev/null +++ b/src/adaptors/euler/abiStakingRewards.js @@ -0,0 +1,400 @@ +module.exports = [ + { + inputs: [ + { internalType: 'address', name: '_owner', type: 'address' }, + { + internalType: 'address', + name: '_rewardsDistribution', + type: 'address', + }, + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'address', name: '_stakingToken', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'bool', name: 'isPaused', type: 'bool' }, + ], + name: 'PauseChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Recovered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardPaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newDuration', + type: 'uint256', + }, + ], + name: 'RewardsDurationUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Staked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdrawn', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'earned', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + ], + name: 'exit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'exit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getRewardForDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastPauseTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastTimeRewardApplicable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastUpdateTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'nominateNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'nominatedOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'reward', type: 'uint256' }], + name: 'notifyRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'periodFinish', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerTokenStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsDistribution', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_paused', type: 'bool' }], + name: 'setPaused', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rewardsDistribution', + type: 'address', + }, + ], + name: 'setRewardsDistribution', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_rewardsDuration', type: 'uint256' }, + ], + name: 'setRewardsDuration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stakingToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userRewardPerTokenPaid', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'subAccountId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/euler/index.js b/src/adaptors/euler/index.js index 0bc864eb04..99dd1bd601 100644 --- a/src/adaptors/euler/index.js +++ b/src/adaptors/euler/index.js @@ -1,42 +1,267 @@ +const WebSocket = require('ws'); const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const EulerToolsClient = require('./EulerToolsClient'); const utils = require('../utils'); +const abiRewardDistribution = require('./abiRewardDistribution'); +const abiStakingRewards = require('./abiStakingRewards'); +const abiEtoken = require('./abiEtoken'); +const abiEulerSimpleLens = require('./abiEulerSimpleLens'); -const url = 'https://api.thegraph.com/subgraphs/name/euler-xyz/euler-mainnet'; +const url = sdk.graph.modifyEndpoint('EQBXhrF4ppZy9cBYnhPdrMCRaVas6seNpqviih5VRGmU'); +const EULERSCAN_ENDPOINT = 'wss://escan-mainnet.euler.finance'; +const EULER = '0xd9fcd98c322942075a5c3860693e9f4f03aae07b'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const rewardsDistribution = '0xA9839D52E964d0ed0d6D546c27D2248Fac610c43'; +const EulerSimpleLens = '0x5077B7642abF198b4a5b7C4BdCE4f03016C7089C'; + +// see: https://gist.github.com/kasperpawlowski/1fb2c0a70a57f845cc7b462aa3ebdca6 +const eulerClient = new EulerToolsClient({ + version: 'example script', + endpoint: EULERSCAN_ENDPOINT, + WebSocket, + onConnect: () => console.log('Euler History Client connected'), + onDisconnect: () => console.log('Euler History Client disconnected'), +}); + +const getGaugeData = () => { + return new Promise((resolve, reject) => { + eulerClient.connect(); + + const id = eulerClient.sub( + { cmd: 'sub', query: { topic: 'rewardsIssuance' } }, + (err, data) => { + if (err) return reject(err); + eulerClient.unsubscribe(id); + resolve(data); + } + ); + }); +}; const query = gql` { - assets { + assets(first: 1000) { id symbol - supplyAPY - totalBalancesUsd - totalBorrowsUsd + decimals + eTokenAddress } } `; -const buildPool = (pool, chainString) => { - return { - pool: `${pool.id}-euler`, - chain: utils.formatChain(chainString), - project: 'euler', - symbol: utils.formatSymbol(pool.symbol), - tvlUsd: (pool.totalBalancesUsd - pool.totalBorrowsUsd) / 1e18, - apy: pool.supplyAPY / 1e25, - }; -}; +const main = async () => { + // pool data + const data = (await request(url, query)).assets; -const topLvl = async (chainString) => { - const data = await request(url, query); - // build pool objects - return data.assets.map((pool) => buildPool(pool, chainString)); -}; + // unique markets (id === underlying) + const markets = data.map((pool) => pool.id); -const main = async () => { - const data = await Promise.all([topLvl('ethereum')]); + // via EulerSimpleLens we pull supply/borrow/available & interest rates + const [TotalSupplyAndDebtsRes, interestRatesRes, underlyingToAssetConfigRes] = + await Promise.all( + [ + 'getTotalSupplyAndDebts', + 'interestRates', + 'underlyingToAssetConfig', + ].map((method) => + sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ + target: EulerSimpleLens, + params: [m], + })), + abi: abiEulerSimpleLens.find((x) => x.name === method), + chain: 'ethereum', + }) + ) + ); + + const TotalSupplyAndDebts = TotalSupplyAndDebtsRes.output.map( + (o) => o.output + ); + const interestRates = interestRatesRes.output.map((o) => o.output); + const underlyingToAssetConfig = underlyingToAssetConfigRes.output.map( + (o) => o.output + ); + + // gauge data (for EUL borrow rewrads) + const gaugeData = (await getGaugeData()).result[0].value; + + // price data + const priceKey = markets + .concat([EULER, WETH]) + .map((m) => `ethereum:${m}`) + .join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).body.coins; + + const eulPrice = prices[`ethereum:${EULER}`].price; + const nbSecYear = 60 * 60 * 24 * 365; + const avgBlockTime = 12; + const nbEpochsYear = + nbSecYear / + avgBlockTime / + (gaugeData.epoch.endBlock - gaugeData.epoch.startBlock); + + const pools = markets + .map((m, i) => { + const decimals = 10 ** data[i]?.decimals; + const underlyingPrice = prices[`ethereum:${m}`]?.price; + const totalSupplyUsd = + (TotalSupplyAndDebts[i]?.totalBalances / decimals) * underlyingPrice; + const totalBorrowUsd = + (TotalSupplyAndDebts[i]?.totalBorrows / decimals) * underlyingPrice; + + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const interestRateDecimals = 1e25; + const apyBase = interestRates[i]?.supplyAPY / interestRateDecimals; + const apyBaseBorrow = interestRates[i]?.borrowAPY / interestRateDecimals; + + const borrowFactor = underlyingToAssetConfig[i]?.borrowFactor / 4e9; + const ltv = + (underlyingToAssetConfig[i]?.collateralFactor / 4e9) * borrowFactor; + + const eulDist = gaugeData.tokens[m] / 1e18; + const apyRewardBorrow = + ((nbEpochsYear * eulDist * eulPrice) / totalBorrowUsd) * 100; + + return { + pool: `${m}-euler`, + chain: 'Ethereum', + project: 'euler', + symbol: utils.formatSymbol(data[i].symbol), + tvlUsd, + apyBase, + apyBaseBorrow, + apyRewardBorrow: Number.isFinite(apyRewardBorrow) + ? apyRewardBorrow + : null, + totalSupplyUsd, + totalBorrowUsd, + underlyingTokens: [m], + rewardTokens: [EULER], + ltv: Number.isFinite(ltv) ? ltv : null, + url: `https://app.euler.finance/market/${m}`, + borrowFactor, + }; + }) + .filter((p) => utils.keepFinite(p)); + + // sUSD pool + const lendingPools = pools.filter( + (p) => p.pool !== '0x57ab1ec28d129707052df4df418d58a2d46d5f51-euler' + ); + + // add new staking pools + const distributionsLength = ( + await sdk.api.abi.call({ + target: rewardsDistribution, + abi: abiRewardDistribution.find((m) => m.name === 'distributionsLength'), + chain: 'ethereum', + }) + ).output; + + // staking pools + const distributions = ( + await sdk.api.abi.multiCall({ + calls: Array.from(Array(Number(distributionsLength)).keys()).map((i) => ({ + target: rewardsDistribution, + params: [i], + })), + abi: abiRewardDistribution.find((m) => m.name === 'distributions'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: distributions.map((i) => ({ + target: i.destination, + })), + abi: abiStakingRewards.find((m) => m.name === 'totalSupply'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: distributions.map((i) => ({ + target: i.destination, + })), + abi: abiStakingRewards.find((m) => m.name === 'rewardRate'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const stakingToken = ( + await sdk.api.abi.multiCall({ + calls: distributions.map((i) => ({ + target: i.destination, + })), + abi: abiStakingRewards.find((m) => m.name === 'stakingToken'), + chain: 'ethereum', + }) + ).output.map((o) => o.output); + + const stakingPools = await Promise.all( + stakingToken.map(async (p, i) => { + const ePool = data.find( + (pool) => pool.eTokenAddress.toLowerCase() === p.toLowerCase() + ); + + const priceKey = `ethereum:${ePool.id}`; + const underlyingPrice = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ) + ).body.coins[priceKey].price; + + // contracts return eToken balances, which need to be converted to underlying balance + // at current exchange rate + const underlyingBalance = + ( + await sdk.api.abi.call({ + target: stakingToken[i], + params: [ + ethers.utils.parseEther((totalSupply[i] / 1e18).toString()), + ], + abi: abiEtoken.find((m) => m.name === 'convertBalanceToUnderlying'), + chain: 'ethereum', + }) + ).output / + 10 ** ePool.decimals; + + const tvlUsd = underlyingBalance * underlyingPrice; + + const eulerPerDay = (rewardRate[i] / 1e18) * 3600 * 24; + const apyReward = ((eulerPerDay * 365 * eulPrice) / tvlUsd) * 100; + + const apyBase = lendingPools.find((lp) => + lp.pool.toLowerCase().includes(ePool.id.toLowerCase()) + )?.apyBase; + + return { + pool: distributions[i].destination, + chain: 'Ethereum', + project: 'euler', + symbol: `e${ePool.symbol}`, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [ePool.id], + rewardTokens: [EULER], + url: 'https://app.euler.finance/staking', + poolMeta: 'Staking', + }; + }) + ); - return data.flat(); + return lendingPools.concat(stakingPools); }; module.exports = { diff --git a/src/adaptors/evaa-protocol/getPrices.js b/src/adaptors/evaa-protocol/getPrices.js new file mode 100644 index 0000000000..a999c91a7c --- /dev/null +++ b/src/adaptors/evaa-protocol/getPrices.js @@ -0,0 +1,400 @@ +const fetch = require('node-fetch'); +const { Cell, Slice, Dictionary, beginCell } = require('@ton/core'); +const { signVerify } = require('@ton/crypto'); + +const ORACLES = [ + { + id: 0, + address: + '0xd3a8c0b9fd44fd25a49289c631e3ac45689281f2f8cf0744400b4c65bed38e5d', + pubkey: Buffer.from( + 'b404f4a2ebb62f2623b370c89189748a0276c071965b1646b996407f10d72eb9', + 'hex' + ), + }, + { + id: 1, + address: + '0x2c21cabdaa89739de16bde7bc44e86401fac334a3c7e55305fe5e7563043e191', + pubkey: Buffer.from( + '9ad115087520d91b6b45d6a8521eb4616ee6914af07fabdc2e9d1826dbb17078', + 'hex' + ), + }, + { + id: 2, + address: + '0x2eb258ce7b5d02466ab8a178ad8b0ba6ffa7b58ef21de3dc3b6dd359a1e16af0', + pubkey: Buffer.from( + 'e503e02e8a9226b34e7c9deb463cbf7f19bce589362eb448a69a8ee7b2fca631', + 'hex' + ), + }, + { + id: 3, + address: + '0xf9a0769954b4430bca95149fb3d876deb7799d8f74852e0ad4ccc5778ce68b52', + pubkey: Buffer.from( + '9cbf8374cf1f2cf17110134871d580198416e101683f4a61f54cf2a3e4e32070', + 'hex' + ), + }, +]; + +const TTL_ORACLE_DATA_SEC = 120; +const MINIMAL_ORACLES = 3; + +function verifyPricesTimestamp(priceData) { + const timestamp = Date.now() / 1000; + const pricesTime = priceData.timestamp; + return timestamp - pricesTime < TTL_ORACLE_DATA_SEC; +} + +function verifyPricesSign(priceData) { + const message = priceData.dataCell.refs[0].hash(); + const signature = priceData.signature; + const publicKey = priceData.pubkey; + + return signVerify(message, signature, publicKey); +} + +function getMedianPrice(pricesData, assetId) { + try { + const usingPrices = pricesData.filter((x) => x.dict.has(assetId)); + const sorted = usingPrices + .map((x) => x.dict.get(assetId)) + .sort((a, b) => Number(a) - Number(b)); + + if (sorted.length === 0) { + return null; + } + + const mid = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 0) { + return (sorted[mid - 1] + sorted[mid]) / 2n; + } else { + return sorted[mid]; + } + } catch { + return null; + } +} + +function packAssetsData(assetsData) { + if (assetsData.length === 0) { + throw new Error('No assets data to pack'); + } + return assetsData.reduceRight( + (acc, { assetId, medianPrice }) => + beginCell() + .storeUint(assetId, 256) + .storeCoins(medianPrice) + .storeMaybeRef(acc) + .endCell(), + null + ); +} + +function packPrices(assetsDataCell, oraclesDataCell) { + return beginCell() + .storeRef(assetsDataCell) + .storeRef(oraclesDataCell) + .endCell(); +} + +function readUnaryLength(slice) { + let res = 0; + while (slice.loadBit()) { + res++; + } + return res; +} + +function doGenerateMerkleProof(prefix, slice, n, keys) { + // Reading label + const originalCell = slice.asCell(); + + if (keys.length == 0) { + // no keys to prove, prune the whole subdict + return convertToPrunedBranch(originalCell); + } + + let lb0 = slice.loadBit() ? 1 : 0; + let prefixLength = 0; + let pp = prefix; + + if (lb0 === 0) { + // Short label detected + + // Read + prefixLength = readUnaryLength(slice); + + // Read prefix + for (let i = 0; i < prefixLength; i++) { + pp += slice.loadBit() ? '1' : '0'; + } + } else { + let lb1 = slice.loadBit() ? 1 : 0; + if (lb1 === 0) { + // Long label detected + prefixLength = slice.loadUint(Math.ceil(Math.log2(n + 1))); + for (let i = 0; i < prefixLength; i++) { + pp += slice.loadBit() ? '1' : '0'; + } + } else { + // Same label detected + let bit = slice.loadBit() ? '1' : '0'; + prefixLength = slice.loadUint(Math.ceil(Math.log2(n + 1))); + for (let i = 0; i < prefixLength; i++) { + pp += bit; + } + } + } + + if (n - prefixLength === 0) { + return originalCell; + } else { + let sl = originalCell.beginParse(); + let left = sl.loadRef(); + let right = sl.loadRef(); + // NOTE: Left and right branches are implicitly contain prefixes '0' and '1' + if (!left.isExotic) { + const leftKeys = keys.filter((key) => { + return pp + '0' === key.slice(0, pp.length + 1); + }); + left = doGenerateMerkleProof( + pp + '0', + left.beginParse(), + n - prefixLength - 1, + leftKeys + ); + } + if (!right.isExotic) { + const rightKeys = keys.filter((key) => { + return pp + '1' === key.slice(0, pp.length + 1); + }); + right = doGenerateMerkleProof( + pp + '1', + right.beginParse(), + n - prefixLength - 1, + rightKeys + ); + } + + return beginCell().storeSlice(sl).storeRef(left).storeRef(right).endCell(); + } +} + +function generateMerkleProofDirect(dict, keys, keyObject) { + keys.forEach((key) => { + if (!dict.has(key)) { + throw new Error( + `Trying to generate merkle proof for a missing key "${key}"` + ); + } + }); + const s = beginCell().storeDictDirect(dict).asSlice(); + return doGenerateMerkleProof( + '', + s, + keyObject.bits, + keys.map((key) => + keyObject.serialize(key).toString(2).padStart(keyObject.bits, '0') + ) + ); +} + +function endExoticCell(b) { + let c = b.endCell(); + return new Cell({ exotic: true, bits: c.bits, refs: c.refs }); +} + +function convertToMerkleProof(c) { + return endExoticCell( + beginCell() + .storeUint(3, 8) + .storeBuffer(c.hash(0)) + .storeUint(c.depth(0), 16) + .storeRef(c) + ); +} + +function createOracleDataProof(oracle, data, signature, assets) { + let prunedDict = generateMerkleProofDirect( + data.prices, + assets, + Dictionary.Keys.BigUint(256) + ); + let prunedData = beginCell() + .storeUint(data.timestamp, 32) + .storeMaybeRef(prunedDict) + .endCell(); + let merkleProof = convertToMerkleProof(prunedData); + let oracleDataProof = beginCell() + .storeUint(oracle.id, 32) + .storeRef(merkleProof) + .storeBuffer(signature) + .asSlice(); + return oracleDataProof; +} + +function packOraclesData(oraclesData, assets) { + if (oraclesData.length == 0) { + throw new Error('no oracles data to pack'); + } + let proofs = oraclesData + .sort((d1, d2) => d1.oracle.id - d2.oracle.id) + .map(({ oracle, data, signature }) => + createOracleDataProof(oracle, data, signature, assets) + ); + return proofs.reduceRight( + (acc, val) => beginCell().storeSlice(val).storeMaybeRef(acc).endCell(), + null + ); +} + +async function getPrices(endpoint = 'api.evaa.space') { + let allPricesData; + try { + const primaryUrl = `https://${endpoint}/api/prices`; + const fallbackUrl = + 'https://6khmc-aiaaa-aaaap-ansfq-cai.raw.icp0.io/prices'; + let allPricesResponse; + + try { + allPricesResponse = await fetch(primaryUrl, { + headers: { accept: 'application/json' }, + signal: AbortSignal.timeout(5000), + }); + if (!allPricesResponse.ok) { + throw new Error( + `Failed to fetch prices from primary EVAA API: ${allPricesResponse.status} ${allPricesResponse.statusText}` + ); + } + } catch (primaryError) { + console.warn( + `Primary API fetch failed: ${primaryError.message}. Trying fallback...` + ); + allPricesResponse = await fetch(fallbackUrl, { + headers: { accept: 'application/json' }, + signal: AbortSignal.timeout(5000), + }); + if (!allPricesResponse.ok) { + throw new Error( + `Failed to fetch prices from fallback EVAA API: ${allPricesResponse.status} ${allPricesResponse.statusText}` + ); + } + } + allPricesData = await allPricesResponse.json(); + } catch (error) { + console.error('Error fetching prices from all sources:', error); + return undefined; + } + + try { + const prices = ORACLES.map((oracle) => { + try { + const packedDataString = allPricesData[oracle.address]; + if (!packedDataString) { + console.warn( + `No data found for oracle ${oracle.id} (address: ${oracle.address}) in EVAA API response.` + ); + return null; + } + + const data = JSON.parse( + decodeURIComponent( + packedDataString.replace('0x', '').replace(/[0-9a-f]{2}/g, '%$&') + ) + ); + + const pricesCell = Cell.fromBoc( + Buffer.from(data.packedPrices, 'hex') + )[0]; + const signature = Buffer.from(data.signature, 'hex'); + const publicKeyFromApi = Buffer.from(data.publicKey, 'hex'); + const timestamp = Number(data.timestamp); + + return { + dict: pricesCell + .beginParse() + .loadRef() + .beginParse() + .loadDictDirect( + Dictionary.Keys.BigUint(256), + Dictionary.Values.BigVarUint(4) + ), + dataCell: beginCell() + .storeRef(pricesCell) + .storeBuffer(signature) + .endCell(), + oracleId: oracle.id, + signature: signature, + pubkey: publicKeyFromApi, + timestamp: timestamp, + }; + } catch (error) { + console.error( + `Error processing prices for oracle ${oracle.id} (address: ${oracle.address}):`, + error + ); + return null; + } + }); + + const validPrices = prices.filter( + (price) => + price && verifyPricesTimestamp(price) && verifyPricesSign(price) + ); + + if (validPrices.length < MINIMAL_ORACLES) { + throw new Error('Not enough valid price data'); + } + + const sortedByTimestamp = validPrices + .slice() + .sort((a, b) => b.timestamp - a.timestamp); + const newerPrices = sortedByTimestamp + .slice(0, MINIMAL_ORACLES) + .sort((a, b) => a.oracleId - b.oracleId); + + const allAssetIds = new Set( + newerPrices.flatMap((p) => Array.from(p.dict.keys())) + ); + + const medianData = Array.from(allAssetIds) + .map((assetId) => ({ + assetId, + medianPrice: getMedianPrice(newerPrices, assetId), + })) + .filter((x) => x.medianPrice !== null); + + const packedMedianData = packAssetsData(medianData); + + const oraclesData = newerPrices.map((x) => ({ + oracle: { id: x.oracleId, pubkey: x.pubkey }, + data: { timestamp: x.timestamp, prices: x.dict }, + signature: x.signature, + })); + + const packedOracleData = packOraclesData( + oraclesData, + medianData.map((x) => x.assetId) + ); + + const dict = Dictionary.empty(); + for (const { assetId, medianPrice } of medianData) { + dict.set(assetId, medianPrice); + } + + return { + dict, + dataCell: packPrices(packedMedianData, packedOracleData), + }; + } catch (processingError) { + console.error('Error processing prices:', processingError); + return undefined; + } +} + +module.exports = getPrices; diff --git a/src/adaptors/evaa-protocol/index.js b/src/adaptors/evaa-protocol/index.js new file mode 100644 index 0000000000..16cca22258 --- /dev/null +++ b/src/adaptors/evaa-protocol/index.js @@ -0,0 +1,704 @@ +const utils = require('../utils'); + +const fetch = require('node-fetch'); +const { TonClient } = require('@ton/ton'); +const { Address, Cell, Slice, Dictionary, beginCell } = require('@ton/core'); +const { signVerify } = require('@ton/crypto'); +const crypto = require('crypto'); +const getPrices = require('./getPrices'); +const { getDistributions, calculateRewardApy } = require('./rewardApy'); +const { tokens } = require('../across/constants') + +function sha256Hash(input) { + const hash = crypto.createHash('sha256'); + hash.update(input); + const hashBuffer = hash.digest(); + const hashHex = hashBuffer.toString('hex'); + return BigInt('0x' + hashHex); +} + +function bufferToBigInt(buffer, start = 0, end = buffer.length) { + console.log(buffer); + const bufferAsHexString = buffer.subarray(start, end).toString('hex'); + return BigInt(`0x${bufferAsHexString}`); +} + +const assetsMAIN = { + TON: { + assetId: sha256Hash('TON'), + token: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', + }, + jUSDT: { + assetId: sha256Hash('jUSDT'), + token: 'EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA', + }, + USDT: { + assetId: sha256Hash('USDT'), + token: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', + }, + jUSDC: { + assetId: sha256Hash('jUSDC'), + token: 'EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728', + }, + stTON: { + assetId: sha256Hash('stTON'), + token: 'EQDNhy-nxYFgUqzfUzImBEP67JqsyMIcyk2S5_RwNNEYku0k', + }, + tsTON: { + assetId: sha256Hash('tsTON'), + token: 'EQC98_qAmNEptUtPc7W6xdHh_ZHrBUFpw5Ft_IzNU20QAJav', + }, + USDe: { + assetId: sha256Hash('USDe'), + token: 'EQAIb6KmdfdDR7CN1GBqVJuP25iCnLKCvBlJ07Evuu2dzP5f', + }, + tsUSDe: { + assetId: sha256Hash('tsUSDe'), + token: 'EQDQ5UUyPHrLcQJlPAczd_fjxn8SLrlNQwolBznxCdSlfQwr', + }, +}; + +const assetsLP = { + TON: { + assetId: sha256Hash('TON'), + token: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', + }, + USDT: { + assetId: sha256Hash('USDT'), + token: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', + }, + 'USDT_STORM': { + assetId: sha256Hash('USDT_STORM'), + token: 'EQCup4xxCulCcNwmOocM9HtDYPU8xe0449tQLp6a-5BLEegW', + }, + 'TONUSDT_DEDUST': { + assetId: sha256Hash('TONUSDT_DEDUST'), + token: 'EQA-X_yo3fzzbDbJ_0bzFWKqtRuZFIRa1sJsveZJ1YpViO3r', + }, + 'TON_STORM': { + assetId: sha256Hash('TON_STORM'), + token: 'EQCNY2AQ3ZDYwJAqx_nzl9i9Xhd_Ex7izKJM6JTxXRnO6n1F', + }, +}; + +const assetsALTS = { + TON: { + assetId: sha256Hash('TON'), + token: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', + }, + USDT: { + assetId: sha256Hash('USDT'), + token: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', + }, + NOT: { + assetId: sha256Hash('NOT'), + token: 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT', + }, + DOGS: { + assetId: sha256Hash('DOGS'), + token: 'EQCvxJy4eG8hyHBFsZ7eePxrRsUQSFE_jpptRAYBmcG_DOGS', + }, + CATI: { + assetId: sha256Hash('CATI'), + token: 'EQD-cvR0Nz6XAyRBvbhz-abTrRC6sI5tvHvvpeQraV9UAAD7', + }, +}; + +const assetsSTABLE = { + USDT: { + assetId: sha256Hash('USDT'), + token: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', + }, + USDe: { + assetId: sha256Hash('USDe'), + token: 'EQAIb6KmdfdDR7CN1GBqVJuP25iCnLKCvBlJ07Evuu2dzP5f', + }, + tsUSDe: { + assetId: sha256Hash('tsUSDe'), + token: 'EQDQ5UUyPHrLcQJlPAczd_fjxn8SLrlNQwolBznxCdSlfQwr', + }, + PT_tsUSDe_01Sep2025: { + assetId: sha256Hash('PT_tsUSDe_01Sep2025'), + token: 'EQDb90Bss5FnIyq7VMmnG2UeZIzZomQsILw9Hjo1wxaF1df3', + }, +}; + +function findAssetKeyByBigIntId(searchAssetId, assets) { + return Object.entries(assets).find(([key, value]) => + BigInt(value.assetId) === searchAssetId + )?.[0]; +} + +const MASTER_CONSTANTS = { + FACTOR_SCALE: BigInt(1e12), + ASSET_COEFFICIENT_SCALE: 10000n, + ASSET_PRICE_SCALE: BigInt(1e8), + ASSET_RESERVE_FACTOR_SCALE: 10000n, + ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: 10000n, + ASSET_ORIGINATION_FEE_SCALE: BigInt(1e9), +}; + +function createAssetsIdDict(assets) { + const ASSETS_ID = {}; + for (const key in assets) { + ASSETS_ID[key] = assets[key].assetId; + } + return ASSETS_ID; +} + +class MyCell extends Cell { + toString() { + return this.hashBigInt().toString(); + } + + hashBigInt() { + return BigInt('0x' + this.hash().toString('hex')); + } +} + +function mulFactor(decimal, a, b) { + return (a * b) / decimal; +} + +function mulDiv(x, y, z) { + return (x * y) / z; +} + +function createAssetData() { + return { + serialize: (src, builder) => { + builder.storeUint(src.sRate, 64); + builder.storeUint(src.bRate, 64); + builder.storeUint(src.totalSupply, 64); + builder.storeUint(src.totalBorrow, 64); + builder.storeUint(src.lastAccural, 32); + builder.storeUint(src.balance, 64); + }, + parse: (src) => { + const sRate = BigInt(src.loadInt(64)); + const bRate = BigInt(src.loadInt(64)); + const totalSupply = BigInt(src.loadInt(64)); + const totalBorrow = BigInt(src.loadInt(64)); + const lastAccural = BigInt(src.loadInt(32)); + const balance = BigInt(src.loadInt(64)); + + return { + sRate, + bRate, + totalSupply, + totalBorrow, + lastAccural, + balance + }; + }, + }; +} + +function createAssetConfig() { + return { + serialize: (src, builder) => { + builder.storeUint(src.oracle, 256); + builder.storeUint(src.decimals, 8); + const refBuild = beginCell(); + refBuild.storeUint(src.collateralFactor, 16); + refBuild.storeUint(src.liquidationThreshold, 16); + refBuild.storeUint(src.liquidationBonus, 16); + refBuild.storeUint(src.baseBorrowRate, 64); + refBuild.storeUint(src.borrowRateSlopeLow, 64); + refBuild.storeUint(src.borrowRateSlopeHigh, 64); + refBuild.storeUint(src.supplyRateSlopeLow, 64); + refBuild.storeUint(src.supplyRateSlopeHigh, 64); + refBuild.storeUint(src.targetUtilization, 64); + refBuild.storeUint(src.originationFee, 64); + refBuild.storeUint(src.dust, 64); + refBuild.storeUint(src.maxTotalSupply, 64); + refBuild.storeUint(src.reserveFactor, 16); + refBuild.storeUint(src.liquidationReserveFactor, 16); + builder.storeRef(refBuild.endCell()); + }, + parse: (src) => { + const oracle = src.loadUintBig(256); + const decimals = BigInt(src.loadUint(8)); + const ref = src.loadRef().beginParse(); + const collateralFactor = ref.loadUintBig(16); + const liquidationThreshold = ref.loadUintBig(16); + const liquidationBonus = ref.loadUintBig(16); + const baseBorrowRate = ref.loadUintBig(64); + const borrowRateSlopeLow = ref.loadUintBig(64); + const borrowRateSlopeHigh = ref.loadUintBig(64); + const supplyRateSlopeLow = ref.loadUintBig(64); + const supplyRateSlopeHigh = ref.loadUintBig(64); + const targetUtilization = ref.loadUintBig(64); + const originationFee = ref.loadUintBig(64); + const dust = ref.loadUintBig(64); + const maxTotalSupply = ref.loadUintBig(64); + const reserveFactor = ref.loadUintBig(16); + const liquidationReserveFactor = ref.loadUintBig(16); + + return { + oracle, + decimals, + collateralFactor, + liquidationThreshold, + liquidationBonus, + baseBorrowRate, + borrowRateSlopeLow, + borrowRateSlopeHigh, + supplyRateSlopeLow, + supplyRateSlopeHigh, + targetUtilization, + originationFee, + dust, + maxTotalSupply, + reserveFactor, + liquidationReserveFactor, + }; + }, + }; +} + +function loadMaybeMyRef(slice) { + const cell = slice.loadMaybeRef(); + if (cell === null) { + return null; + } + return new MyCell({ + exotic: cell.isExotic, + bits: cell.bits, + refs: cell.refs, + }); +} + +function loadMyRef(slice) { + const cell = slice.loadRef(); + return new MyCell({ + exotic: cell.isExotic, + bits: cell.bits, + refs: cell.refs, + }); +} + +function parseMasterData(masterDataBOC, assets) { + const ASSETS_ID = createAssetsIdDict(assets); + const masterSlice = Cell.fromBase64(masterDataBOC).beginParse(); + const meta = masterSlice.loadRef().beginParse().loadStringTail(); + const upgradeConfigParser = masterSlice.loadRef().beginParse(); + + const upgradeConfig = { + masterCodeVersion: Number(upgradeConfigParser.loadCoins()), + userCodeVersion: Number(upgradeConfigParser.loadCoins()), + timeout: upgradeConfigParser.loadUint(32), + updateTime: upgradeConfigParser.loadUint(64), + freezeTime: upgradeConfigParser.loadUint(64), + userCode: loadMyRef(upgradeConfigParser), + newMasterCode: loadMaybeMyRef(upgradeConfigParser), + newUserCode: loadMaybeMyRef(upgradeConfigParser), + }; + + const masterConfigSlice = masterSlice.loadRef().beginParse(); + const assetsConfigDict = masterConfigSlice.loadDict(Dictionary.Keys.BigUint(256), createAssetConfig()); + const assetsDataDict = masterSlice.loadDict(Dictionary.Keys.BigUint(256), createAssetData()); + + const assetsExtendedData = Dictionary.empty(); + const assetsReserves = Dictionary.empty(); + const apy = { + supply: Dictionary.empty(), + borrow: Dictionary.empty(), + }; + + for (const [_, assetId] of Object.entries(ASSETS_ID)) { + const assetData = calculateAssetData( + assetsConfigDict, + assetsDataDict, + assetId, + MASTER_CONSTANTS + ); + assetsExtendedData.set(assetId, assetData); + } + const masterConfig = { + ifActive: masterConfigSlice.loadInt(8), + admin: masterConfigSlice.loadAddress(), + oraclesInfo: { + numOracles: masterConfigSlice.loadUint(16), + threshold: masterConfigSlice.loadUint(16), + oracles: loadMaybeMyRef(masterConfigSlice) + }, + tokenKeys: loadMaybeMyRef(masterConfigSlice), + }; + // dont call endParse() here: contract may append fields later + // only parse the fields we need and ignore any trailing data + + for (const [_, assetId] of Object.entries(ASSETS_ID)) { + const assetData = assetsExtendedData.get(assetId); + const totalSupply = calculatePresentValue( + assetData.sRate, + assetData.totalSupply, + MASTER_CONSTANTS + ); + const totalBorrow = calculatePresentValue( + assetData.bRate, + assetData.totalBorrow, + MASTER_CONSTANTS + ); + assetsReserves.set(assetId, assetData.balance - totalSupply + totalBorrow); + + apy.supply.set( + assetId, + (1 + (Number(assetData.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1 + ); + apy.borrow.set( + assetId, + (1 + (Number(assetData.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1 + ); + } + + return { + assetsConfig: assetsConfigDict, + assetsData: assetsExtendedData, + assetsReserves: assetsReserves, + apy: apy, + }; +} + +function calculateAssetData(assetsConfigDict, assetsDataDict, assetId) { + const config = assetsConfigDict.get(assetId); + const data = assetsDataDict.get(assetId); + + if (!data || !config) { + throw new Error('Asset Data or Config is not accessible'); + } + + const { sRate, bRate, supplyInterest, borrowInterest, now } = + calculateCurrentRates(config, data); + data.sRate = sRate || 0n; + data.bRate = bRate || 0n; + data.lastAccural = now; + + const supplyApy = + (1 + (Number(supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1; + const borrowApy = + (1 + (Number(borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1; + + return { + ...data, + ...{ supplyInterest, borrowInterest }, + ...{ supplyApy, borrowApy }, + }; +} + +function calculateAssetInterest(assetConfig, assetData) { + const totalSupply = calculatePresentValue( + assetData.sRate, + assetData.totalSupply + ); + const totalBorrow = calculatePresentValue( + assetData.bRate, + assetData.totalBorrow + ); + let utilization = 0n; + let supplyInterest = 0n; + let borrowInterest = 0n; + + if (totalSupply !== 0n) { + utilization = (totalBorrow * MASTER_CONSTANTS.FACTOR_SCALE) / totalSupply; + } + + if (utilization <= assetConfig.targetUtilization) { + borrowInterest = + assetConfig.baseBorrowRate + + mulFactor( + MASTER_CONSTANTS.FACTOR_SCALE, + assetConfig.borrowRateSlopeLow, + utilization + ); + } else { + borrowInterest = + assetConfig.baseBorrowRate + + mulFactor( + MASTER_CONSTANTS.FACTOR_SCALE, + assetConfig.borrowRateSlopeLow, + assetConfig.targetUtilization + ) + + mulFactor( + MASTER_CONSTANTS.FACTOR_SCALE, + assetConfig.borrowRateSlopeHigh, + utilization - assetConfig.targetUtilization + ); + } + + supplyInterest = mulDiv( + mulDiv(borrowInterest, utilization, MASTER_CONSTANTS.FACTOR_SCALE), + MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor, + MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE + ); + + return { + supplyInterest, + borrowInterest, + }; +} + +function calculateCurrentRates(assetConfig, assetData) { + const now = BigInt(Math.floor(Date.now() / 1000)); + const timeElapsed = now - assetData.lastAccural; + const { supplyInterest, borrowInterest } = calculateAssetInterest( + assetConfig, + assetData + ); + + if (timeElapsed > 0) { + const updatedSRate = + assetData.sRate + + mulFactor( + MASTER_CONSTANTS.FACTOR_SCALE, + assetData.sRate, + supplyInterest * timeElapsed + ); + const updatedBRate = + assetData.bRate + + mulFactor( + MASTER_CONSTANTS.FACTOR_SCALE, + assetData.bRate, + borrowInterest * timeElapsed + ); + return { + sRate: updatedSRate, + bRate: updatedBRate, + supplyInterest, + borrowInterest, + now, + }; + } + + return { + sRate: assetData.sRate, + bRate: assetData.bRate, + supplyInterest, + borrowInterest, + now, + }; +} + + +const priceScaleFactor = BigInt(1e9); + +function calculatePresentValue(index, principalValue) { + return (principalValue * index) / MASTER_CONSTANTS.FACTOR_SCALE; +} + +async function getContractStateWithRetry(client, address, maxRetries = 3, initialDelay = 500) { + let attempts = 0; + + while (attempts < maxRetries) { + try { + return await client.getContractState(address); + } catch (err) { + if (err.message?.includes('429') || err.code === 429) { + attempts++; + const delay = initialDelay * 2 ** (attempts - 1); + console.warn( + `Rate limit (429) encountered. Retrying in ${delay} ms... (attempt ${attempts} of ${maxRetries})` + ); + await new Promise((resolve) => setTimeout(resolve, delay)); + } else { + throw err; + } + } + } + + throw new Error(`Max retries (${maxRetries}) exceeded while getting contract state for address ${address}.`); +} + + +const getApy = async () => { + console.log('Requesting prices'); + let prices = await getPrices(); + let distributions = await getDistributions(); + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + }); + + const poolData = await Promise.all([ + getPoolData( + 'EQC8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr', + assetsMAIN, + 'Main', + prices, + distributions, + client + ), + getPoolData( + 'EQBIlZX2URWkXCSg3QF2MJZU-wC5XkBoLww-hdWk2G37Jc6N', + assetsLP, + 'LP', + prices, + distributions, + client + ), + getPoolData( + 'EQANURVS3fhBO9bivig34iyJQi97FhMbpivo1aUEAS2GYSu-', + assetsALTS, + 'Alts', + prices, + distributions, + client + ), + getPoolData( + 'EQCdIdXf1kA_2Hd9mbGzSFDEPA-Px-et8qTWHEXgRGo0K3zd', + assetsSTABLE, + 'Stable', + prices, + distributions, + client + ), + ]); + + return poolData.flat().filter((pool) => pool !== undefined); +}; + +async function getPoolData( + masterAddress, + assets, + poolName, + prices, + distributions, + client +) { + let data; + try { + const result = await getContractStateWithRetry( + client, + Address.parse(masterAddress), + 5, // maxRetries + 500 // initialDelay in ms + ); + if (!result?.data) { + throw new Error('Master data not found'); + } + + data = parseMasterData(result.data.toString('base64'), assets); + } catch (error) { + console.error('getPoolData error:', error); + return []; + } + + const rewardApys = calculateRewardApy(distributions, poolName, data, prices); + + return Object.entries(assets).map(([tokenSymbol, asset]) => { + const { assetId, token } = asset; + + console.log(poolName, 'Process symbol', tokenSymbol, asset, assetId, token); + + const priceData = prices.dict.get(assetId); + if (!priceData) { + console.warn(`No price data available for ${tokenSymbol}, skipping...`); + return undefined; + } + + const assetConfig = data.assetsConfig.get(assetId); + const assetData = data.assetsData.get(assetId); + if (!assetConfig || !assetData) { + console.warn(`Missing config or data for ${tokenSymbol}, skipping...`); + return undefined; + } + + const price = Number(priceData) / Number(priceScaleFactor); + if (!price) { + console.warn(`Invalid price for ${tokenSymbol}, skipping...`); + return undefined; + } + + const scaleFactor = 10 ** Number(assetConfig.decimals); + const totalSupplyNum = Number( + calculatePresentValue(assetData.sRate, assetData.totalSupply) + ); + const totalBorrowNum = Number( + calculatePresentValue(assetData.bRate, assetData.totalBorrow) + ); + + const totalSupplyUsd = (totalSupplyNum * price) / scaleFactor; + const totalBorrowUsd = (totalBorrowNum * price) / scaleFactor; + + console.log(poolName, tokenSymbol, 'totalSupplyInUsd', totalSupplyUsd); + console.log(poolName, tokenSymbol, 'totalBorrowInUsd', totalBorrowUsd); + + const supplyApy = (1 + (Number(assetData.supplyInterest) / 1e12) * 86400) ** 365 - 1; + const borrowApy = (1 + (Number(assetData.borrowInterest) / 1e12) * 86400) ** 365 - 1; + + console.log(poolName, tokenSymbol, 'supplyApy', supplyApy * 100); + console.log(poolName, tokenSymbol, 'borrowApy', borrowApy * 100); + + const apyRewardData = rewardApys.find( + (r) => + BigInt(r.rewardingAssetId) === BigInt(assetId) && + r.rewardType.toLowerCase() === 'supply' + ); + const apyReward = apyRewardData?.apy; + const rewardTokensSupply = apyRewardData + ? [ + assets[findAssetKeyByBigIntId(apyRewardData.rewardsAssetId, assets)] + ?.token, + ].filter(Boolean) + : []; + + console.log( + poolName, + tokenSymbol, + 'apyReward', + apyReward, + 'rewardTokensSupply', + rewardTokensSupply + ); + + const apyRewardBorrowData = rewardApys.find( + (r) => + BigInt(r.rewardingAssetId) === BigInt(assetId) && + r.rewardType.toLowerCase() === 'borrow' + ); + const apyRewardBorrow = apyRewardBorrowData?.apy; + const rewardTokensBorrow = apyRewardBorrowData + ? [ + assets[ + findAssetKeyByBigIntId(apyRewardBorrowData.rewardsAssetId, assets) + ]?.token, + ].filter(Boolean) + : []; + + console.log( + poolName, + tokenSymbol, + 'apyRewardBorrow', + apyRewardBorrow, + 'rewardTokensBorrow', + rewardTokensBorrow + ); + + return { + pool: `evaa-${assetId}-${poolName}-ton`.toLowerCase(), + chain: 'Ton', + project: 'evaa-protocol', + symbol: tokenSymbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyApy * 100, + apyReward, + rewardTokens: [ + ...new Set([...rewardTokensSupply, ...rewardTokensBorrow]), + ], + apyBaseBorrow: borrowApy * 100, + apyRewardBorrow, + underlyingTokens: [token], + url: `https://app.evaa.finance/token/${tokenSymbol}?pool=${poolName}`, + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: borrowApy * 100, + ltv: Number(assetConfig.collateralFactor) / 10000, + poolMeta: poolName + }; + }); +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://evaa.finance/', +}; diff --git a/src/adaptors/evaa-protocol/rewardApy.js b/src/adaptors/evaa-protocol/rewardApy.js new file mode 100644 index 0000000000..dcdaef55d0 --- /dev/null +++ b/src/adaptors/evaa-protocol/rewardApy.js @@ -0,0 +1,204 @@ +const fetch = require('node-fetch'); + +function isLeapYear(year) { + return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; +} + +async function getDistributions(endpoint = 'evaa.space') { + try { + let result = await fetch(`https://${endpoint}/query/distributions/list`, { + headers: { accept: 'application/json' }, + }); + let resData = await result.json(); + return resData; + } catch (error) { + console.error(error); + return undefined; + } +} +const isLeap = isLeapYear(new Date().getFullYear()); +const totalSecsInYear = (isLeap ? 366 : 365) * 24 * 60 * 60; +const SCALE_FACTOR = BigInt(1e12); + +function calcApy( + rewardAmount, + totalAmount, + rewardingAssetPrice, + rewardsAssetPrice, + rewardingScaleFactor, + rewardsScaleFactor, + totalSecsInCurrentSeason +) { + const totalValueLockedUsd = + (Number(totalAmount) / rewardingScaleFactor) * (rewardingAssetPrice || 0); + + if (!totalValueLockedUsd) { + return 0; + } + + const rewardAmountUsd = + (Number(rewardAmount) / rewardsScaleFactor) * (rewardsAssetPrice || 0); + + const rewardsPerSecUsd = rewardAmountUsd / totalSecsInCurrentSeason; + return (rewardsPerSecUsd / totalValueLockedUsd) * totalSecsInYear * 100; +} + +function calculateRewardApy(distributionsResp, pool, data, prices) { + try { + if ( + !distributionsResp?.distributions || + distributionsResp.distributions.length === 0 + ) { + console.log('Invalid distributions data:', distributionsResp); + return []; + } + + const activeCampaigns = distributionsResp.distributions.filter( + (campaign) => campaign.started && !campaign.expired + ); + if (!activeCampaigns.length) { + return []; + } + + const activeSeasons = activeCampaigns + .flatMap((campaign) => campaign.seasons || []) + .filter( + (season) => season.started && !season.expired && season.pool === pool + ); + + if (!activeSeasons.length) { + return []; + } + + const seasonsApy = activeSeasons.map((season) => { + const rewardingAssetId = BigInt(season?.rewarding_asset_id ?? 0); + const rewardsAssetId = BigInt(season?.rewards_asset_id ?? 0); + + const rewardingAssetData = data.assetsData.get(rewardingAssetId); + const rewardsAssetData = data.assetsData.get(rewardsAssetId); + + if (!rewardingAssetData || !rewardsAssetData) { + return []; + } + + const rewardType = season?.reward_type?.toLowerCase(); + + let rewardAmount = Number(season?.rewards_amount) || 0; + + if (rewardType === 'borrow' && season?.borrow_budget) { + rewardAmount = season.borrow_budget; + } else if (rewardType === 'supply' && season?.supply_budget) { + rewardAmount = season.supply_budget; + } + + const totalAmountSupply = + (rewardingAssetData.totalSupply * rewardingAssetData.sRate) / + SCALE_FACTOR; + const totalAmountBorrow = + (rewardingAssetData.totalBorrow * rewardingAssetData.bRate) / + SCALE_FACTOR; + + const totalAmount = + rewardType === 'borrow' ? totalAmountBorrow : totalAmountSupply; + + if (!totalAmount || totalAmount === '0') { + return []; + } + + const rewardingAssetConfig = data.assetsConfig.get(rewardingAssetId); + const rewardsAssetConfig = data.assetsConfig.get(rewardsAssetId); + + const rewardingScaleFactor = + 10 ** Number(rewardingAssetConfig?.decimals ?? 0); + const rewardsScaleFactor = + 10 ** Number(rewardsAssetConfig?.decimals ?? 0); + + const rewardingPriceData = prices.dict.get(rewardingAssetId); + const rewardsPriceData = prices.dict.get(rewardsAssetId); + + const rewardingAssetPrice = Number(rewardingPriceData); + const rewardsAssetPrice = Number(rewardsPriceData); + + const seasonStart = new Date(season?.campaign_start ?? 0); + const seasonEnd = new Date(season?.campaign_end ?? 0); + const totalSecsInCurrentSeason = (seasonEnd - seasonStart) / 1000; + + if (totalSecsInCurrentSeason <= 0) { + return []; + } + + const baseApy = calcApy( + rewardAmount, + totalAmount, + rewardingAssetPrice, + rewardsAssetPrice, + rewardingScaleFactor, + rewardsScaleFactor, + totalSecsInCurrentSeason + ); + + const result = [ + { + apy: baseApy, + rewardType, + rewardingAssetId, + rewardsAssetId, + }, + ]; + + if ( + rewardType === 'borrow' && + season?.supply_budget && + season.supply_budget > 0 + ) { + const supplyApy = calcApy( + season.supply_budget, + totalAmountSupply, + rewardingAssetPrice, + rewardsAssetPrice, + rewardingScaleFactor, + rewardsScaleFactor, + totalSecsInCurrentSeason + ); + result.push({ + apy: supplyApy, + rewardType: 'supply', + rewardingAssetId, + rewardsAssetId, + }); + } else if ( + rewardType === 'supply' && + season?.borrow_budget && + season.borrow_budget > 0 + ) { + const borrowApy = calcApy( + season.borrow_budget, + totalAmountBorrow, + rewardingAssetPrice, + rewardsAssetPrice, + rewardingScaleFactor, + rewardsScaleFactor, + totalSecsInCurrentSeason + ); + result.push({ + apy: borrowApy, + rewardType: 'borrow', + rewardingAssetId, + rewardsAssetId, + }); + } + + return result; + }); + + return seasonsApy.flat(); + } catch (error) { + console.error(error); + return []; + } +} + +module.exports = { + getDistributions, + calculateRewardApy, +}; diff --git a/src/adaptors/exactly/.prettierrc b/src/adaptors/exactly/.prettierrc new file mode 100644 index 0000000000..963354f231 --- /dev/null +++ b/src/adaptors/exactly/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 120 +} diff --git a/src/adaptors/exactly/index.js b/src/adaptors/exactly/index.js new file mode 100644 index 0000000000..3351f8a3c8 --- /dev/null +++ b/src/adaptors/exactly/index.js @@ -0,0 +1,301 @@ +const { api2 } = require("@defillama/sdk"); +const { AddressZero } = require("@ethersproject/constants"); +const { aprToApy, getBlocksByTime, getPrices } = require("../utils"); + +const config = { + ethereum: { + auditor: "0x310A2694521f75C7B2b64b5937C16CE65C3EFE01", + }, + optimism: { + auditor: "0xaEb62e6F27BC103702E7BC879AE98bceA56f027E", + }, +}; +const url = "https://app.exact.ly"; +const INTERVAL = 86_400 * 7 * 4; +const WAD = 10n ** 18n; + +const apy = async () => + Promise.all( + Object.entries(config).map(async ([chain, { auditor }]) => { + const timestampNow = Math.floor(Date.now() / 1_000); + const timestamp24hsAgo = timestampNow - 86_400; + /** @type {[number, number]} */ + const [startBlock, block] = await getBlocksByTime([timestamp24hsAgo, timestampNow], chain); + /** @type {string[]} */ + const markets = await api2.abi.call({ target: auditor, abi: abis.allMarkets, block: startBlock, chain }); + + /** @type number[] */ + const adjustFactors = ( + await api2.abi.multiCall({ + abi: abis.marketsData, + calls: markets.map((market) => ({ target: auditor, params: [market] })), + chain, + block, + }) + ).map(([adjustFactor]) => adjustFactor); + + /** @type [assets: string[], decimals: number[], maxFuturePools: number[], prevTotalAssets: string[], prevTotalSupply: string[], prevTotalFloatingBorrowAssets: string[], prevTotalFloatingBorrowShares: string[], totalAssets: string[], totalSupply: string[], totalFloatingBorrowAssets: string[], totalFloatingBorrowShares: string[], previewFloatingAssetsAverages: string[], backupFeeRates: bigint[], interestRateModels: number[], reserveFactors: string[] ] */ + const [ + assets, + decimals, + maxFuturePools, + prevTotalAssets, + prevTotalSupply, + prevTotalFloatingBorrowAssets, + prevTotalFloatingBorrowShares, + totalAssets, + totalSupply, + totalFloatingBorrowAssets, + totalFloatingBorrowShares, + previewFloatingAssetsAverages, + backupFeeRates, + interestRateModels, + reserveFactors, + ] = await Promise.all([ + ...[ + "asset", + "decimals", + "maxFuturePools", + "totalAssets", + "totalSupply", + "totalFloatingBorrowAssets", + "totalFloatingBorrowShares", + ].map((key) => api2.abi.multiCall({ abi: abis[key], calls: markets, chain, block: startBlock })), + ...[ + "totalAssets", + "totalSupply", + "totalFloatingBorrowAssets", + "totalFloatingBorrowShares", + "previewFloatingAssetsAverage", + "backupFeeRate", + "interestRateModel", + "reserveFactor", + ].map((key) => api2.abi.multiCall({ abi: abis[key], calls: markets, chain, block })), + ]); + + /** @type string[] */ + const symbols = await api2.abi.multiCall({ abi: abis.symbol, calls: assets, chain, block }); + + const { pricesByAddress } = await getPrices(assets, chain); + const minMaturity = timestampNow - (timestampNow % INTERVAL) + INTERVAL; + + return Promise.all( + markets.map(async (market, i) => { + /** @type {number} */ + const usdUnitPrice = pricesByAddress[assets[i].toLowerCase()]; + const poolMetadata = { + chain, + project: "exactly", + /** @type {string} */ + symbol: symbols[i], + tvlUsd: ((totalAssets[i] - totalFloatingBorrowAssets[i]) * usdUnitPrice) / 10 ** decimals[i], + /** @type {string[]} */ + underlyingTokens: [assets[i]], + url: `${url}/${symbols[i]}`, + ltv: (adjustFactors[i] / 1e18) ** 2, + }; + const shareValue = (totalAssets[i] * 1e18) / totalSupply[i]; + const prevShareValue = (prevTotalAssets[i] * 1e18) / prevTotalSupply[i]; + const proportion = (shareValue * 1e18) / prevShareValue; + const apr = (proportion / 1e18 - 1) * 365 * 100; + const borrowShareValue = (totalFloatingBorrowAssets[i] * 1e18) / totalFloatingBorrowShares[i]; + const prevBorrowShareValue = (prevTotalFloatingBorrowAssets[i] * 1e18) / prevTotalFloatingBorrowShares[i]; + const borrowProportion = (borrowShareValue * 1e18) / prevBorrowShareValue; + const borrowAPR = (borrowProportion / 1e18 - 1) * 365 * 100; + const baseUnit = 10 ** decimals[i]; + + let aprReward, aprRewardBorrow, rewardTokens; + const controller = await api2.abi.call({ target: market, abi: abis.rewardsController, block, chain }); + if (controller !== AddressZero) { + rewardTokens = await api2.abi.call({ target: controller, abi: abis.allRewards, block, chain }); + const { pricesByAddress: rewardsPrices } = await getPrices(rewardTokens, chain); + /** @type [{deposit: number, borrow: number}] */ + const rates = await Promise.all( + rewardTokens.map(async (reward) => { + const [{ start: configStart }, { borrowIndex, depositIndex, lastUndistributed }, { start }] = + await Promise.all( + ["rewardConfig", "rewardIndexes", "distributionTime"].map((key) => + api2.abi.call({ target: controller, abi: abis[key], params: [market, reward], block, chain }) + ) + ); + /** @type {{borrowIndex: string, depositIndex: string}} */ + const { borrowIndex: projectedBorrowIndex, depositIndex: projectedDepositIndex } = await api2.abi.call({ + target: controller, + abi: abis.previewAllocation, + params: [market, reward, timestampNow > configStart ? 3_600 : 0], + block, + chain, + }); + /** @type number */ + const rewardUSD = rewardsPrices[reward.toLowerCase()] ?? 0; + const firstMaturity = configStart - (configStart % INTERVAL) + INTERVAL; + const maxMaturity = timestampNow - (timestampNow % INTERVAL) + INTERVAL + maxFuturePools[i] * INTERVAL; + const rewardMaturities = Array.from( + { length: (maxMaturity - firstMaturity) / INTERVAL }, + (_, j) => firstMaturity + j * INTERVAL + ); + /** @type {{borrowed: string, deposited: string}[]} */ + const fixedBalances = await api2.abi.multiCall({ + abi: abis.fixedPoolBalance, + calls: rewardMaturities.map((maturity) => ({ target: market, params: [maturity] })), + chain, + block, + }); + const fixedDebt = fixedBalances.reduce((total, { borrowed }) => total + BigInt(borrowed), 0n); + const previewRepay = await api2.abi.call({ + target: market, + abi: abis.previewRepay, + params: [String(fixedDebt)], + block, + chain, + }); + return { + borrow: + totalFloatingBorrowAssets[i] + fixedDebt > 0 + ? (projectedBorrowIndex - borrowIndex) * + ((totalFloatingBorrowShares[i] + previewRepay) / baseUnit) * + (rewardUSD / 1e18) * + (baseUnit / (((totalFloatingBorrowAssets[i] + fixedDebt) * usdUnitPrice) / 1e18)) * + (365 * 24) + : 0, + deposit: + totalAssets[i] > 0 + ? (projectedDepositIndex - depositIndex) * + (totalSupply[i] / baseUnit) * + (rewardUSD / 1e18) * + (baseUnit / ((totalAssets[i] * usdUnitPrice) / 1e18)) * + (365 * 24) + : 0, + }; + }) + ); + aprReward = rates.reduce((sum, { deposit }) => sum + deposit, 0) / 1e16; + aprRewardBorrow = rates.reduce((sum, { borrow }) => sum + borrow, 0) / 1e16; + } + + /** @type {Pool} */ + const floating = Number.isFinite(apr) && + Number.isFinite(borrowAPR) && { + ...poolMetadata, + pool: `${market}-${chain}`.toLowerCase(), + apyBase: aprToApy(apr), + apyBaseBorrow: aprToApy(borrowAPR), + totalSupplyUsd: (totalSupply[i] * usdUnitPrice) / baseUnit, + totalBorrowUsd: (totalFloatingBorrowAssets[i] * usdUnitPrice) / baseUnit, + rewardTokens, + apyReward: aprReward ? aprToApy(aprReward) : undefined, + apyRewardBorrow: aprRewardBorrow ? aprToApy(aprRewardBorrow) : undefined, + }; + + const maturities = Array.from({ length: maxFuturePools[i] }, (_, j) => minMaturity + INTERVAL * j); + /** @type FixedPool[] */ + const fixedPools = await api2.abi.multiCall({ + abi: abis.fixedPools, + calls: maturities.map((maturity) => ({ target: market, params: [maturity] })), + chain, + block, + }); + + /** @type {Pool[]} */ + const fixed = await Promise.all( + maturities.map(async (maturity, j) => { + const { borrowed, supplied, unassignedEarnings, lastAccrual } = fixedPools[j]; + + const fixBorrowed = BigInt(borrowed), + fixSupplied = BigInt(supplied), + fixUnassignedEarnings = BigInt(unassignedEarnings); + + if (fixSupplied + BigInt(previewFloatingAssetsAverages[i]) === 0n) return; + + const { rate: minFixedRate } = await api2.abi.call({ + target: interestRateModels[i], + abi: abis.minFixedRate, + params: [borrowed, supplied, previewFloatingAssetsAverages[i]], + block, + chain, + }); + const unassignedEarning = + fixUnassignedEarnings - + (fixUnassignedEarnings * BigInt(timestampNow - lastAccrual)) / + BigInt(timestampNow - (timestampNow % INTERVAL) + INTERVAL * (j + 1) - lastAccrual); + const optimalDeposit = fixBorrowed - (fixBorrowed > fixSupplied ? fixSupplied : fixBorrowed); + + const fixedDepositAPR = + optimalDeposit > 0n + ? Number( + (31_536_000n * (((unassignedEarning * (WAD - BigInt(backupFeeRates[i]))) / WAD) * WAD)) / + optimalDeposit / + BigInt(INTERVAL * (j + 1) - (timestampNow % INTERVAL)) + ) / 1e16 + : 0; + + const secsToMaturity = maturity - timestampNow; + const poolMeta = new Date(maturity * 1_000).toISOString().slice(0, 10); + + /** @type {Pool} */ + return { + ...poolMetadata, + pool: `${market}-${chain}-${poolMeta}`.toLowerCase(), + poolMeta, + apyBase: aprToApy(fixedDepositAPR, secsToMaturity / 86_400), + apyBaseBorrow: aprToApy(minFixedRate / 1e16, secsToMaturity / 86_400), + totalSupplyUsd: + (Number( + BigInt(supplied) + + (BigInt(totalSupply[i]) * (WAD - BigInt(reserveFactors[i]))) / WAD - + BigInt(totalFloatingBorrowAssets[i]) + ) * + usdUnitPrice) / + baseUnit, + totalBorrowUsd: (borrowed * usdUnitPrice) / baseUnit, + rewardTokens, + apyRewardBorrow: aprRewardBorrow ? aprToApy(aprRewardBorrow, secsToMaturity / 86_400) : undefined, + }; + }) + ); + + return [floating, ...fixed].filter(Boolean); + }) + ); + }) + ).then((pools) => pools.flat(2)); + +module.exports = { + apy, + url, +}; + +const abis = { + allMarkets: "function allMarkets() view returns (address[])", + allRewards: "function allRewards() view returns (address[])", + asset: "function asset() view returns (address)", + decimals: "function decimals() view returns (uint256)", + symbol: "function symbol() view returns (string)", + totalAssets: "function totalAssets() view returns (uint256)", + totalFloatingBorrowAssets: "function totalFloatingBorrowAssets() view returns (uint256)", + totalFloatingBorrowShares: "function totalFloatingBorrowShares() view returns (uint256)", + totalSupply: "function totalSupply() view returns (uint256)", + maxFuturePools: "function maxFuturePools() view returns (uint8)", + fixedPools: + "function fixedPools(uint256) view returns (uint256 borrowed, uint256 supplied, uint256 unassignedEarnings, uint256 lastAccrual)", + previewFloatingAssetsAverage: "function previewFloatingAssetsAverage() view returns (uint256)", + backupFeeRate: "function backupFeeRate() view returns (uint256)", + interestRateModel: "function interestRateModel() view returns (address)", + minFixedRate: "function minFixedRate(uint256, uint256, uint256) view returns (uint256 rate, uint256)", + marketsData: "function markets(address) view returns (uint128, uint8, uint8, bool, address)", + rewardsController: "function rewardsController() view returns (address)", + rewardConfig: + "function rewardConfig(address market, address reward) external view returns (address market, address reward, address priceFeed, uint32 start, uint256 distributionPeriod, uint256 targetDebt, uint256 totalDistribution, uint256 undistributedFactor, int128 flipSpeed, uint64 compensationFactor, uint64 transitionFactor, uint64 borrowAllocationWeightFactor, uint64 depositAllocationWeightAddend, uint64 depositAllocationWeightFactor)", + rewardIndexes: + "function rewardIndexes(address market, address reward) external view returns (uint256 borrowIndex, uint256 depositIndex, uint256 lastUndistributed)", + previewAllocation: + "function previewAllocation(address market, address reward, uint256 deltaTime) external view returns (uint256 borrowIndex, uint256 depositIndex, uint256 newUndistributed)", + distributionTime: + "function distributionTime(address market, address reward) external view returns (uint32 start, uint32 end, uint32 lastUpdate)", + fixedPoolBalance: "function fixedPoolBalance(uint256 maturity) external view returns (uint256 borrowed, uint256)", + previewRepay: "function previewRepay(uint256 assets) external view returns (uint256)", + reserveFactor: "function reserveFactor() view returns (uint128)", +}; + +/** @typedef {{ pool: string, chain: string, project: string, symbol: string, tvlUsd: number, apyBase?: number, apyReward?: number, rewardTokens?: Array, underlyingTokens?: Array, poolMeta?: string, url?: string, apyBaseBorrow?: number, apyRewardBorrow?: number, totalSupplyUsd?: number, totalBorrowUsd?: number, ltv?: number }} Pool */ +/** @typedef {{ borrowed: string, supplied: string, unassignedEarnings: string, lastAccrual: number }} FixedPool */ diff --git a/src/adaptors/extra-finance-leverage-farming/abis/veloPairsSugarV2.json b/src/adaptors/extra-finance-leverage-farming/abis/veloPairsSugarV2.json new file mode 100644 index 0000000000..92a313e41c --- /dev/null +++ b/src/adaptors/extra-finance-leverage-farming/abis/veloPairsSugarV2.json @@ -0,0 +1,356 @@ +[ + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" } + ], + "name": "forSwaps", + "outputs": [ + { + "components": [ + { "name": "lp", "type": "address" }, + { "name": "type", "type": "int24" }, + { "name": "token0", "type": "address" }, + { "name": "token1", "type": "address" }, + { "name": "factory", "type": "address" }, + { "name": "pool_fee", "type": "uint256" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" }, + { "name": "_account", "type": "address" }, + { "name": "_addresses", "type": "address[]" } + ], + "name": "tokens", + "outputs": [ + { + "components": [ + { "name": "token_address", "type": "address" }, + { "name": "symbol", "type": "string" }, + { "name": "decimals", "type": "uint8" }, + { "name": "account_balance", "type": "uint256" }, + { "name": "listed", "type": "bool" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" } + ], + "name": "all", + "outputs": [ + { + "components": [ + { "name": "lp", "type": "address" }, + { "name": "symbol", "type": "string" }, + { "name": "decimals", "type": "uint8" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "type", "type": "int24" }, + { "name": "tick", "type": "int24" }, + { "name": "sqrt_ratio", "type": "uint160" }, + { "name": "token0", "type": "address" }, + { "name": "reserve0", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "token1", "type": "address" }, + { "name": "reserve1", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "gauge", "type": "address" }, + { "name": "gauge_liquidity", "type": "uint256" }, + { "name": "gauge_alive", "type": "bool" }, + { "name": "fee", "type": "address" }, + { "name": "bribe", "type": "address" }, + { "name": "factory", "type": "address" }, + { "name": "emissions", "type": "uint256" }, + { "name": "emissions_token", "type": "address" }, + { "name": "pool_fee", "type": "uint256" }, + { "name": "unstaked_fee", "type": "uint256" }, + { "name": "token0_fees", "type": "uint256" }, + { "name": "token1_fees", "type": "uint256" }, + { "name": "nfpm", "type": "address" }, + { "name": "alm", "type": "address" }, + { "name": "root", "type": "address" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "name": "_address", "type": "address" }], + "name": "byAddress", + "outputs": [ + { + "components": [ + { "name": "lp", "type": "address" }, + { "name": "symbol", "type": "string" }, + { "name": "decimals", "type": "uint8" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "type", "type": "int24" }, + { "name": "tick", "type": "int24" }, + { "name": "sqrt_ratio", "type": "uint160" }, + { "name": "token0", "type": "address" }, + { "name": "reserve0", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "token1", "type": "address" }, + { "name": "reserve1", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "gauge", "type": "address" }, + { "name": "gauge_liquidity", "type": "uint256" }, + { "name": "gauge_alive", "type": "bool" }, + { "name": "fee", "type": "address" }, + { "name": "bribe", "type": "address" }, + { "name": "factory", "type": "address" }, + { "name": "emissions", "type": "uint256" }, + { "name": "emissions_token", "type": "address" }, + { "name": "pool_fee", "type": "uint256" }, + { "name": "unstaked_fee", "type": "uint256" }, + { "name": "token0_fees", "type": "uint256" }, + { "name": "token1_fees", "type": "uint256" }, + { "name": "nfpm", "type": "address" }, + { "name": "alm", "type": "address" }, + { "name": "root", "type": "address" } + ], + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "name": "_index", "type": "uint256" }], + "name": "byIndex", + "outputs": [ + { + "components": [ + { "name": "lp", "type": "address" }, + { "name": "symbol", "type": "string" }, + { "name": "decimals", "type": "uint8" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "type", "type": "int24" }, + { "name": "tick", "type": "int24" }, + { "name": "sqrt_ratio", "type": "uint160" }, + { "name": "token0", "type": "address" }, + { "name": "reserve0", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "token1", "type": "address" }, + { "name": "reserve1", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "gauge", "type": "address" }, + { "name": "gauge_liquidity", "type": "uint256" }, + { "name": "gauge_alive", "type": "bool" }, + { "name": "fee", "type": "address" }, + { "name": "bribe", "type": "address" }, + { "name": "factory", "type": "address" }, + { "name": "emissions", "type": "uint256" }, + { "name": "emissions_token", "type": "address" }, + { "name": "pool_fee", "type": "uint256" }, + { "name": "unstaked_fee", "type": "uint256" }, + { "name": "token0_fees", "type": "uint256" }, + { "name": "token1_fees", "type": "uint256" }, + { "name": "nfpm", "type": "address" }, + { "name": "alm", "type": "address" }, + { "name": "root", "type": "address" } + ], + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" }, + { "name": "_account", "type": "address" } + ], + "name": "positions", + "outputs": [ + { + "components": [ + { "name": "id", "type": "uint256" }, + { "name": "lp", "type": "address" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "staked", "type": "uint256" }, + { "name": "amount0", "type": "uint256" }, + { "name": "amount1", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "unstaked_earned0", "type": "uint256" }, + { "name": "unstaked_earned1", "type": "uint256" }, + { "name": "emissions_earned", "type": "uint256" }, + { "name": "tick_lower", "type": "int24" }, + { "name": "tick_upper", "type": "int24" }, + { "name": "sqrt_ratio_lower", "type": "uint160" }, + { "name": "sqrt_ratio_upper", "type": "uint160" }, + { "name": "alm", "type": "address" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" }, + { "name": "_account", "type": "address" }, + { "name": "_factory", "type": "address" } + ], + "name": "positionsByFactory", + "outputs": [ + { + "components": [ + { "name": "id", "type": "uint256" }, + { "name": "lp", "type": "address" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "staked", "type": "uint256" }, + { "name": "amount0", "type": "uint256" }, + { "name": "amount1", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "unstaked_earned0", "type": "uint256" }, + { "name": "unstaked_earned1", "type": "uint256" }, + { "name": "emissions_earned", "type": "uint256" }, + { "name": "tick_lower", "type": "int24" }, + { "name": "tick_upper", "type": "int24" }, + { "name": "sqrt_ratio_lower", "type": "uint160" }, + { "name": "sqrt_ratio_upper", "type": "uint160" }, + { "name": "alm", "type": "address" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_limit", "type": "uint256" }, + { "name": "_offset", "type": "uint256" }, + { "name": "_account", "type": "address" } + ], + "name": "positionsUnstakedConcentrated", + "outputs": [ + { + "components": [ + { "name": "id", "type": "uint256" }, + { "name": "lp", "type": "address" }, + { "name": "liquidity", "type": "uint256" }, + { "name": "staked", "type": "uint256" }, + { "name": "amount0", "type": "uint256" }, + { "name": "amount1", "type": "uint256" }, + { "name": "staked0", "type": "uint256" }, + { "name": "staked1", "type": "uint256" }, + { "name": "unstaked_earned0", "type": "uint256" }, + { "name": "unstaked_earned1", "type": "uint256" }, + { "name": "emissions_earned", "type": "uint256" }, + { "name": "tick_lower", "type": "int24" }, + { "name": "tick_upper", "type": "int24" }, + { "name": "sqrt_ratio_lower", "type": "uint160" }, + { "name": "sqrt_ratio_upper", "type": "uint160" }, + { "name": "alm", "type": "address" } + ], + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_wrapper", "type": "address" }, + { "name": "_amount0", "type": "uint256" }, + { "name": "_amount1", "type": "uint256" } + ], + "name": "almEstimateAmounts", + "outputs": [{ "name": "", "type": "uint256[3]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKENS", + "outputs": [{ "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LPS", + "outputs": [{ "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_POSITIONS", + "outputs": [{ "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKEN_SYMBOL_LEN", + "outputs": [{ "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cl_helper", + "outputs": [{ "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "alm_factory", + "outputs": [{ "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "arg0", "type": "uint256" }, + { "name": "arg1", "type": "address" } + ], + "name": "alm_map", + "outputs": [{ "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "name": "_voter", "type": "address" }, + { "name": "_registry", "type": "address" }, + { "name": "_convertor", "type": "address" }, + { "name": "_slipstream_helper", "type": "address" }, + { "name": "_alm_factory", "type": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + } +] diff --git a/src/adaptors/extra-finance-leverage-farming/compute.js b/src/adaptors/extra-finance-leverage-farming/compute.js new file mode 100644 index 0000000000..cdb389059f --- /dev/null +++ b/src/adaptors/extra-finance-leverage-farming/compute.js @@ -0,0 +1,169 @@ +const { request } = require('graphql-request'); +const superagent = require('superagent'); +const BigNumber = require("bignumber.js"); +const utils = require('../utils'); +const { getAllVeloPools } = require('./contract') + +function toDecimals(bn, decimals = 18) { + return new BigNumber(bn.toString()).div(new BigNumber(`1e+${decimals}`)).toNumber() +} + +function getTokenInfo(chain, address, prices) { + const coinKey = `${chain}:${address.toLowerCase()}`; + return prices[coinKey]|| {}; +} + +exports.getTokenInfo = getTokenInfo + +exports.getLendPoolTvl = function(poolInfo, tokenInfo) { + const { totalLiquidity, totalBorrows } = poolInfo + const remainAmount = toDecimals(new BigNumber(totalLiquidity).minus(new BigNumber(totalBorrows)), tokenInfo.decimals); + return remainAmount * tokenInfo?.price +} + +exports.getLendPoolApy = function (poolInfo) { + const { borrowingRate, totalLiquidity, totalBorrows } = poolInfo + const borrowingRateNum = toDecimals(borrowingRate) + const utilizationRate = new BigNumber(totalBorrows).dividedBy(new BigNumber(totalLiquidity)).toNumber() || 0 + const apr = borrowingRateNum * utilizationRate + return utils.aprToApy(apr * 100) +} + +exports.getLendPoolRewardInfo = function(pool, chain, prices) { + const token = getTokenInfo(chain, pool.underlyingTokenAddress, prices) + const amount = toDecimals(pool.totalLiquidity, token.decimals) + const value = amount * token.price + if (!pool.rewards?.length) { + return { + rewardTokens: [], + } + } + const rewardApys = pool.rewards.map(rewardItem => { + const rewardTokenInfo = getTokenInfo(chain, rewardItem.rewardToken, prices) + const rewardAmount = toDecimals(new BigNumber(rewardItem.totalRewards || '0'), rewardTokenInfo?.decimals) + const rewardValue = rewardAmount * rewardTokenInfo?.price + + const yearTimes = (365 * 24 * 3600 * 1000) / rewardItem.rewardDuration + + const yearlyValue = yearTimes * rewardValue + + const rewardApr = yearlyValue / value + const rewardApy = utils.aprToApy(rewardApr * 100) + return rewardApy + }) + + return { + rewardTokens: pool.rewards.map(item => item.rewardToken), + rewardApy: rewardApys.reduce((cur, item) => cur + item, 0) + } +} + +exports.formatLendingPoolwithRewards = function(lendingPools, rewardsList) { + return lendingPools.map((i) => { + const targetRewards = rewardsList.filter(rewardsItem => i.stakingAddress?.toLowerCase() === rewardsItem.stakingAddress?.toLowerCase()) + if (targetRewards.length) { + const rewards = targetRewards.map((rewardItem) => { + return { + rewardToken: rewardItem.rewardsToken, + totalRewards: rewardItem.total, + rewardDuration: Number(rewardItem.end) * 1000 - Number(rewardItem.start) * 1000, + isRewardActive: Date.now() <= Number(rewardItem.end) * 1000 && Date.now() >= Number(rewardItem.start) * 1000, + } + }).filter(rewardItem => rewardItem.isRewardActive); + + return { + ...i, + rewards, + } + } + return i + }) +} + +exports.getAllVeloPoolInfo = async function(vaults, chain, prices, lendingPools) { + const parsedPoolsInfo = [] + function getToken(address) { + return getTokenInfo(chain, address, prices) + } + const veloPoolsInfo = await getAllVeloPools(chain, vaults) + + for(let index = 0; index < vaults.length; index++) { + const item = vaults[index] + const { + pair, + token0, + token1, + maxLeverage, + totalLp, + } = item + const { + decimals: token0_decimals, + symbol: token0_symbol, + price: token0price, + } = getToken(token0) + const { + decimals: token1_decimals, + symbol: token1_symbol, + price: token1price, + } = getToken(token1) + + const poolInfo = veloPoolsInfo.find(veloPool => veloPool.lp.toLowerCase() === pair.toLowerCase() && + veloPool.token1.toLowerCase() === token1.toLowerCase() && + veloPool.token0.toLowerCase() === token0.toLowerCase() + ) + if (!poolInfo) { + continue + } + const { + reserve0, + reserve1, + liquidity, + symbol, + emissions, + emissions_token, + } = poolInfo + const { + decimals: emissions_token_decimals, + price: emissionsPrice, + } = getToken(emissions_token) + + // const floorMaxLeverage = Math.floor(maxLeverage / 100) + const reserve0usd = toDecimals(reserve0, token0_decimals) * token0price + const reserve1usd = toDecimals(reserve1, token1_decimals) * token1price + const totalPoolTvlUsd = reserve0usd + reserve1usd + + function getPoolBaseApr() { + const yearlyEmissionAmount = 365 * 24 * 3600 * toDecimals(emissions, emissions_token_decimals) + const yearlyEmissionValue = emissionsPrice * yearlyEmissionAmount + const apr = yearlyEmissionValue / totalPoolTvlUsd * 100 + return apr + } + const baseApr = getPoolBaseApr() + + // function getBorrowApr() { + // const lendingPoolToken0 = lendingPools.find(item => item.underlyingTokenAddress.toLowerCase() === token0.toLowerCase()) + // const lendingPoolToken1 = lendingPools.find(item => item.underlyingTokenAddress.toLowerCase() === token1.toLowerCase()) + // const borrowApr = Math.min(toDecimals(lendingPoolToken0.borrowingRate), toDecimals(lendingPoolToken1.borrowingRate)) + // return borrowApr + // } + + // const leveragedApy = getFarmApy({ + // leverage: floorMaxLeverage, + // baseApr, + // borrowApr: getBorrowApr() * 100, + // }) + + parsedPoolsInfo.push({ + ...item, + symbol, + token0_symbol, + token1_symbol, + reserve0usd, + reserve1usd, + tvlUsd: toDecimals(totalLp) / toDecimals(liquidity) * totalPoolTvlUsd, + baseApy: utils.aprToApy(baseApr), + // leveragedApy, + }) + } + return parsedPoolsInfo +} diff --git a/src/adaptors/extra-finance-leverage-farming/contract.js b/src/adaptors/extra-finance-leverage-farming/contract.js new file mode 100644 index 0000000000..7ab06fb795 --- /dev/null +++ b/src/adaptors/extra-finance-leverage-farming/contract.js @@ -0,0 +1,68 @@ +const sdk = require('@defillama/sdk'); +const pairsSugarContractAbi = require("./abis/veloPairsSugarV2.json"); + +const veloPairAddress = { + optimism: '0xC8229d65581afE8f04344A6706FF45faECC426f9', + base: '0x27fc745390d1f4BaF8D184FBd97748340f786634' +} + +exports.getAllVeloPools = async function (chain, vaults) { + const poolInfoLists = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((item) => ({ + target: veloPairAddress[chain], + params: item.pair, + })), + abi: pairsSugarContractAbi.find((m) => m.name === 'byAddress'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + const poolInfoList = poolInfoLists.map(pool => { + if (!pool) { + return null + } + const [ + lp, + symbol, + decimals, + liquidity, + type, + tick, + sqrt_ratio, + token0, + reserve0, + staked0, + token1, + reserve1, + staked1, + gauge, + gauge_liquidity, + gauge_alive, + fee, + bribe, + factory, + emissions, + emissions_token, + pool_fee, + unstaked_fee, + token0_fees, + token1_fees, + nfpm, + alm, + root, + ] = pool + return { + lp, + token0, + token1, + reserve0, + reserve1, + liquidity, + symbol, + emissions, + emissions_token, + } + }) + return poolInfoList.filter(pool => !!pool) +} diff --git a/src/adaptors/extra-finance-leverage-farming/index.js b/src/adaptors/extra-finance-leverage-farming/index.js new file mode 100644 index 0000000000..5410ca9e7d --- /dev/null +++ b/src/adaptors/extra-finance-leverage-farming/index.js @@ -0,0 +1,191 @@ +const { request } = require('graphql-request'); +const superagent = require('superagent'); +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); +const { + getTokenInfo, + getLendPoolTvl, + getLendPoolApy, + formatLendingPoolwithRewards, + getLendPoolRewardInfo, + getAllVeloPoolInfo, +} = require('./compute'); + +const project = 'extra-finance-leverage-farming'; + +const chains = ['optimism', 'base']; +const subgraphUrls = { + optimism: + 'https://gateway.thegraph.com/api/a4998f968b8ad324eb3e47ed20c00220/deployments/id/QmXYvc82BmDKdPbhi6i6kgYCnPpA1uHifdWVoMEMBKuRa1', + base: 'https://gateway.thegraph.com/api/a4998f968b8ad324eb3e47ed20c00220/deployments/id/QmT6s8gNmKrshbuHz3636UgCLp9RkBKQmRh2zt4wzpnDpL', +}; + +async function getPoolsData() { + const pools = []; + + const graphQuery = `{ + vaults { + id + vaultId + blockNumber + blockTimestamp + pair + token0 + token1 + stable + paused + frozen + borrowingEnabled + maxLeverage + totalLp + debtPositionId0 + debtPositionId1 + }, + lendingReservePools { + id + reserveId + underlyingTokenAddress + stakingAddress + eTokenAddress + totalLiquidity + totalBorrows + borrowingRate + } + latestRewardsSets { + stakingAddress + rewardsToken + id + end + blockTimestamp + blockNumber + start + total + transactionHash + } + }`; + + async function getPoolsByChain(chain) { + const queryResult = await request(subgraphUrls[chain], graphQuery); + + const filteredLendingPools = queryResult.lendingReservePools.filter( + (item) => { + return new BigNumber(item.totalLiquidity).gt(0); + } + ); + const filteredFarmingPools = queryResult.vaults.filter((item) => { + return new BigNumber(item.totalLp).gt(0); + }); + + function getTokenAddresses() { + const lendingTokenAddresses = filteredLendingPools.map( + (item) => item.underlyingTokenAddress + ); + const result = [...lendingTokenAddresses]; + // add reward token + queryResult.latestRewardsSets.forEach((item) => { + if (!result.includes(item.rewardsToken)) { + result.push(item.rewardsToken); + } + }); + queryResult.vaults.forEach((item) => { + if (!result.includes(item.token0)) { + result.push(item.token0); + } + if (!result.includes(item.token1)) { + result.push(item.token1); + } + }); + return result; + } + const tokenAddresses = getTokenAddresses(); + + const coins = chain + ? tokenAddresses.map((address) => `${chain}:${address}`) + : tokenAddresses; + + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + function addLendPools() { + const formattedLendingPools = formatLendingPoolwithRewards( + filteredLendingPools, + queryResult.latestRewardsSets || [] + ); + formattedLendingPools.forEach((poolInfo) => { + const tokenInfo = getTokenInfo( + chain, + poolInfo.underlyingTokenAddress, + prices + ); + const rewardsInfo = getLendPoolRewardInfo(poolInfo, chain, prices); + pools.push({ + pool: `${poolInfo.eTokenAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project, + symbol: tokenInfo?.symbol, + underlyingTokens: [poolInfo.underlyingTokenAddress], + tvlUsd: getLendPoolTvl(poolInfo, tokenInfo), + apyBase: getLendPoolApy(poolInfo), + apyReward: rewardsInfo?.rewardApy || undefined, + rewardTokens: rewardsInfo?.rewardTokens, + url: 'https://app.extrafi.io/lend', + }); + }); + } + + async function addFarmPools() { + const parsedFarmPoolsInfo = await getAllVeloPoolInfo( + filteredFarmingPools.filter((item) => !item.paused && !item.frozen), + chain, + prices, + queryResult.lendingReservePools + ); + + parsedFarmPoolsInfo.forEach(async (poolInfo) => { + const pool = `${poolInfo.pair}-${chain}`.toLowerCase(); + const existPool = pools.find((item) => item.pool === pool); + if (existPool && existPool.tvlUsd > poolInfo.tvlUsd) { + return; + } + pools.push({ + pool, + chain: utils.formatChain(chain), + project, + symbol: `${poolInfo.token0_symbol}-${poolInfo.token1_symbol}`, + underlyingTokens: [poolInfo.token0, poolInfo.token1], + tvlUsd: poolInfo.tvlUsd, + apyBase: poolInfo.baseApy, + url: 'https://app.extrafi.io/farm', + }); + }); + } + + try { + addLendPools() + } catch (err) { + console.error('get lend pools error: ', err) + } + + try { + await addFarmPools() + } catch (err) { + console.error('get farm pools error: ', err) + } + } + + for (const chain of Object.keys(subgraphUrls)) { + try { + await getPoolsByChain(chain); + } catch (err) { + console.log(err); + } + } + + return pools.filter((p) => utils.keepFinite(p)); +} + +module.exports = { + apy: getPoolsData, +}; diff --git a/src/adaptors/extra-finance-xlend/index.js b/src/adaptors/extra-finance-xlend/index.js new file mode 100755 index 0000000000..68d8a9804d --- /dev/null +++ b/src/adaptors/extra-finance-xlend/index.js @@ -0,0 +1,244 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); + +const protocolDataProviders = { + optimism: '0xCC61E9470B5f0CE21a3F6255c73032B47AaeA9C0', + base: '0x1566DA4640b6a0b32fF309b07b8df6Ade40fd98D', +}; + +function getRewardInfo(merklRewards, reserve) { + let apyReward = 0; + let apyRewardBorrow = 0; + const rewardTokens = []; + + // get supply reward + let targetRewardItem = merklRewards.find((rewardItem) => { + return ( + rewardItem.action?.toLowerCase() === 'lend' && + rewardItem.identifier?.toLowerCase() === + reserve.aTokenAddress?.toLowerCase() + ); + }); + // type = MULTILOG_DUTCH + if (!targetRewardItem) { + targetRewardItem = merklRewards.find((rewardItem) => { + const tokensHasAtoken = rewardItem?.tokens?.find((tokenItem) => { + return ( + tokenItem?.address?.toLowerCase() === + reserve.aTokenAddress?.toLowerCase() + ); + }); + return ( + rewardItem.action?.toLowerCase() === 'lend' && + rewardItem.type === 'MULTILOG_DUTCH' && + !!tokensHasAtoken + ); + }); + } + if (targetRewardItem) { + let incentiveAPR = String(targetRewardItem.apr / 100); + if (targetRewardItem.type === 'MULTILOG_DUTCH') { + if ( + targetRewardItem?.effective && + targetRewardItem?.effective?.userEffectiveUSD + ) { + incentiveAPR = String( + (targetRewardItem?.dailyRewards * 365) / + targetRewardItem?.effective?.userEffectiveUSD + ); + } + } + apyReward = incentiveAPR * 100; + const rewardTk =targetRewardItem.rewardsRecord?.breakdowns?.[0]?.token?.address.toLowerCase() + if (!rewardTokens.includes(rewardTk)) { + rewardTokens.push(rewardTk); + } + } + + // get borrow reward + const targetBorrowRewardItem = merklRewards.find((rewardItem) => { + return ( + rewardItem.action?.toLowerCase() === 'borrow' && + rewardItem.identifier?.toLowerCase() === + reserve.variableDebtTokenAddress?.toLowerCase() + ); + }); + if (targetBorrowRewardItem) { + apyRewardBorrow = + ((targetBorrowRewardItem.rewardsRecord?.breakdowns?.[0]?.value * 365) / + targetBorrowRewardItem?.tvlRecord?.total) * + 100 || 0; + + const rewardTk = targetBorrowRewardItem.rewardsRecord?.breakdowns?.[0]?.token?.address.toLowerCase() + if (!rewardTokens.includes(rewardTk)) { + rewardTokens.push(rewardTk); + } + } + + return { + apyReward, + apyRewardBorrow, + rewardTokens, + }; +} + +const getApy = async (market) => { + const chain = market; + + const protocolDataProvider = protocolDataProviders[market]; + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const reserveTokenAddresses = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveTokensAddresses'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: reserveTokenAddresses.map((t) => ({ + target: t.aTokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: reserveTokenAddresses.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.aTokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: reserveTokenAddresses.map((t) => ({ + target: t.aTokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).body.coins; + + let merklRewards = []; + try { + merklRewards = ( + await superagent.get( + `https://api.merkl.xyz/v4/opportunities?mainProtocolId=xlend` + ) + ).body.filter((i) => (i.status || '').toLowerCase() === 'live'); + } catch (err) { + console.warn('get merkl rewards error'); + } + + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + totalBorrowUsd = totalSupplyUsd - tvlUsd; + + const url = `https://xlend.extrafi.io/?underlyingAsset=${pool.tokenAddress.toLowerCase()}&marketName=${market}`; + + const { apyReward, apyRewardBorrow, rewardTokens } = getRewardInfo( + merklRewards || [], + reserveTokenAddresses[i] + ); + + return { + pool: `${reserveTokenAddresses[i].aTokenAddress}-${market}-extrafi-xlend`.toLowerCase(), + chain, + project: 'extra-finance-xlend', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd: null, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + apyReward, + apyRewardBorrow, + rewardTokens, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + url, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + mintedCoin: null, + poolMeta: null, + }; + }) + .filter((i) => Boolean(i)); +}; + +const apy = async () => { + const pools = await Promise.allSettled( + Object.keys(protocolDataProviders).map(async (market) => getApy(market)) + ); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/extra-finance-xlend/poolAbi.js b/src/adaptors/extra-finance-xlend/poolAbi.js new file mode 100644 index 0000000000..bba1c9dc38 --- /dev/null +++ b/src/adaptors/extra-finance-xlend/poolAbi.js @@ -0,0 +1,242 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/factor-v2/index.js b/src/adaptors/factor-v2/index.js new file mode 100644 index 0000000000..25a223f7ea --- /dev/null +++ b/src/adaptors/factor-v2/index.js @@ -0,0 +1,39 @@ +const vaults = require('./vaults'); +const { getTvl, getApr } = require('./shared'); + +async function getSingleYieldVaultAPY() { + const poolData = await Promise.all( + vaults.map(async (vault) => { + const project = 'factor-v2'; + const chain = 'arbitrum'; + const pool = `${vault.poolAddress}-${chain}`.toLowerCase(); + const url = `https://app.factor.fi/vault/${vault.poolAddress}`; + const symbol = vault.symbol; + + const [tvlUsd, apyBase] = await Promise.all([ + getTvl(vault.poolAddress, vault.underlyingToken, vault.strategy), + getApr(vault.poolAddress, vault.underlyingToken, vault.strategy), + ]); + + const data = { + pool, + chain, + project, + symbol, + tvlUsd, + apyBase, + underlyingTokens: [vault.underlyingToken], + url, + }; + + return data; + }) + ); + + return poolData; +} + +module.exports = { + timetravel: false, + apy: getSingleYieldVaultAPY, +}; diff --git a/src/adaptors/factor-v2/shared.js b/src/adaptors/factor-v2/shared.js new file mode 100644 index 0000000000..0ea2e4625e --- /dev/null +++ b/src/adaptors/factor-v2/shared.js @@ -0,0 +1,104 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { + getMuxLpApr, + getGlpApr, + getVlpApr, + getLodestarApr, + getLodestarTokenPriceInUSD, + getPendleApr, + getSJoeApr, + getSiloApr, + getTenderApr, + getOliveApr, + getPxGMXApr, + getPenpieApr, +} = require('./strategy-adapter'); +const { getCoinDataFromDefillamaAPI } = require('./strategy-adapter/utils'); + +async function getApr(poolAddress, underlyingTokenAddress, strategy) { + let apr = 0; + switch (strategy) { + case 'GLPStrategy': + apr = await getGlpApr(); + break; + case 'MuxStrategy': + apr = await getMuxLpApr(); + break; + case 'VelaStrategy': + apr = await getVlpApr(); + break; + case 'LodestarStrategy': + apr = await getLodestarApr(underlyingTokenAddress); + break; + case 'PenpieStrategy': + apr = await getPenpieApr(underlyingTokenAddress); + break; + case 'PendleStrategy': + apr = await getPendleApr(underlyingTokenAddress); + break; + case 'TraderJoeStrategy': + apr = await getSJoeApr(underlyingTokenAddress); + break; + case 'SiloStrategy': + apr = await getSiloApr(underlyingTokenAddress); + break; + case 'TenderStrategy': + apr = await getTenderApr(underlyingTokenAddress); + break; + case 'OliveStrategy': + apr = await getOliveApr(); + break; + case 'RedactedStrategy': + apr = await getPxGMXApr(); + break; + default: + apr = 0; + } + + const harvestCountPerDay = 3; + const apyBase = utils.aprToApy(apr, harvestCountPerDay * 365); + + return apyBase; +} + +async function getTvl(poolAddress, underlyingTokenAddress, strategy) { + let underlyingTokenPrice = 0; + + if (strategy == 'LodestarStrategy') { + underlyingTokenPrice = await getLodestarTokenPriceInUSD( + underlyingTokenAddress + ); + } else if (strategy == 'RedactedStrategy') { + const gmxCoin = await getCoinDataFromDefillamaAPI( + 'arbitrum', + '0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a' + ); + underlyingTokenPrice = gmxCoin.price; + } else { + underlyingTokenPrice = ( + await utils.getPrices([underlyingTokenAddress], 'arbitrum') + ).pricesByAddress[underlyingTokenAddress.toLowerCase()]; + } + + const [{ output: assetBalance }, { output: assetDecimals }] = + await Promise.all([ + sdk.api.abi.call({ + target: poolAddress, + abi: 'uint256:assetBalance', + chain: 'arbitrum', + }), + sdk.api.abi.call({ + target: underlyingTokenAddress, + abi: 'erc20:decimals', + chain: 'arbitrum', + }), + ]); + + const tvlUsd = (assetBalance / 10 ** assetDecimals) * underlyingTokenPrice; + + return tvlUsd; +} + +module.exports = { getTvl, getApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/glp-adapter.js b/src/adaptors/factor-v2/strategy-adapter/glp-adapter.js new file mode 100644 index 0000000000..3a950aacae --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/glp-adapter.js @@ -0,0 +1,16 @@ +const { getDefiLLamaPools } = require('./utils'); + +/*////////////////////////////////////////////////////////////////////////////// + GLP APR +//////////////////////////////////////////////////////////////////////////////*/ + +async function getGlpApr() { + const pool = await getDefiLLamaPools( + '825688c0-c694-4a6b-8497-177e425b7348' + ); + const apr = pool.apyBase + pool.apyReward; + + return apr; +} + +module.exports = { getGlpApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/index.js b/src/adaptors/factor-v2/strategy-adapter/index.js new file mode 100644 index 0000000000..f8cd5e36d3 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/index.js @@ -0,0 +1,13 @@ +module.exports = { + ...require('./lodestar-adapter'), + ...require('./mux-adapter'), + ...require('./glp-adapter'), + ...require('./vela-adapter'), + ...require('./pendle-adapter'), + ...require('./sjoe-adapter'), + ...require('./silo-adapter'), + ...require('./tender-adapter'), + ...require('./olive-adapter'), + ...require('./redacted-adapter'), + ...require('./penpie-adapter'), +}; diff --git a/src/adaptors/factor-v2/strategy-adapter/lodestar-adapter.js b/src/adaptors/factor-v2/strategy-adapter/lodestar-adapter.js new file mode 100644 index 0000000000..697d3da208 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/lodestar-adapter.js @@ -0,0 +1,59 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../../utils'); +const { makeReadable } = require('./utils'); + +async function getSupplyRatePerBlock(assetAddress) { + const { output } = await sdk.api.abi.call({ + target: assetAddress, + abi: 'uint256:supplyRatePerBlock', + chain: 'arbitrum', + }); + return { + supplyRatePerBlock: makeReadable(output), + }; +} + +async function getLodestarApr(assetAddress) { + const { supplyRatePerBlock } = await getSupplyRatePerBlock(assetAddress); + const blocksPerYear = 7200 * 365; + const apr = (1 + supplyRatePerBlock) ** blocksPerYear - 1; + return apr * 100; +} + +async function getExchangeRateStored(assetAddress) { + const { output } = await sdk.api.abi.call({ + target: assetAddress, + abi: 'uint256:exchangeRateStored', + chain: 'arbitrum', + }); + return { + exchangeRateStored: makeReadable(output, 16), + }; +} + +async function getLodestarUnderlyingTokenPriceInUSD(lToken) { + const { output: underlyingTokenAddress } = await sdk.api.abi.call({ + target: lToken, + abi: 'address:underlying', + chain: 'arbitrum', + }); + const underlyingLodestarTokenPriceInUSD = ( + await utils.getPrices([underlyingTokenAddress], 'arbitrum') + ).pricesByAddress[underlyingTokenAddress.toLowerCase()]; + + return { underlyingLodestarTokenPriceInUSD }; +} + +async function getLodestarTokenPriceInUSD(lToken) { + const [{ exchangeRateStored }, { underlyingLodestarTokenPriceInUSD }] = + await Promise.all([ + getExchangeRateStored(lToken), + getLodestarUnderlyingTokenPriceInUSD(lToken), + ]); + + const lTokenPriceInUSD = + underlyingLodestarTokenPriceInUSD * exchangeRateStored; + return lTokenPriceInUSD; +} + +module.exports = { getLodestarApr, getLodestarTokenPriceInUSD }; diff --git a/src/adaptors/factor-v2/strategy-adapter/mux-adapter.js b/src/adaptors/factor-v2/strategy-adapter/mux-adapter.js new file mode 100644 index 0000000000..3ec1af55bc --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/mux-adapter.js @@ -0,0 +1,108 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../../utils'); +const { makeReadable } = require('./utils'); + +/*////////////////////////////////////////////////////////////////////////////// + Mux Reward Router +//////////////////////////////////////////////////////////////////////////////*/ + +async function getDataFromRewardRouter() { + const REWARD_ROUTER_ADDRESS = '0xaf9C4F6A0ceB02d4217Ff73f3C95BbC8c7320ceE'; + + const rewardRouterABIs = [ + 'uint256:feeRewardRate', + 'uint256:muxRewardRate', + 'uint256:poolOwnedRate', + 'uint256:votingEscrowedRate', + ]; + + const [feeRewardRate, muxRewardRate, poolOwnedRate, votingEscrowedRate] = + await Promise.all( + rewardRouterABIs.map(async (abi) => { + const { output } = await sdk.api.abi.call({ + target: REWARD_ROUTER_ADDRESS, + abi: abi, + chain: 'arbitrum', + }); + return output; + }) + ); + return { + feeRewardRate: makeReadable(feeRewardRate), + muxRewardRate: makeReadable(muxRewardRate), + poolOwnedRate: makeReadable(poolOwnedRate), + votingEscrowedRate: makeReadable(votingEscrowedRate), + }; +} + +/*////////////////////////////////////////////////////////////////////////////// + Mux Pool Owned Liquidity +//////////////////////////////////////////////////////////////////////////////*/ + +async function getDataFromPOL() { + const MLP_ADDRESS = '0x7CbaF5a14D953fF896E5B3312031515c858737C8'; + const POL_ADDRESS = '0x18891480b9dd2aC5eF03220C45713d780b5CFdeF'; + + const { output: mlpPolBalance } = await sdk.api.abi.call({ + target: MLP_ADDRESS, + abi: 'erc20:balanceOf', + params: [POL_ADDRESS], + chain: 'arbitrum', + }); + + return { + mlpPolBalance: makeReadable(mlpPolBalance), + }; +} + +/*////////////////////////////////////////////////////////////////////////////// + Token Prices +//////////////////////////////////////////////////////////////////////////////*/ + +async function getTokenPrices() { + const tokenAddresses = [ + '0x7CbaF5a14D953fF896E5B3312031515c858737C8', // MuxLP + '0x4e352cf164e64adcbad318c3a1e222e9eba4ce42', // MCB + '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', // WETH + ]; + + const tokenPrices = await utils.getPrices(tokenAddresses, 'arbitrum'); + + const mlpPrice = tokenPrices.pricesByAddress[tokenAddresses[0].toLowerCase()]; + const mcbPrice = tokenPrices.pricesByAddress[tokenAddresses[1].toLowerCase()]; + const ethPrice = tokenPrices.pricesByAddress[tokenAddresses[2].toLowerCase()]; + + return { mlpPrice, mcbPrice, ethPrice }; +} + +/*////////////////////////////////////////////////////////////////////////////// + Mux LP APR +//////////////////////////////////////////////////////////////////////////////*/ + +async function getMuxLpApr() { + const [ + { mlpPolBalance }, + { feeRewardRate, muxRewardRate, poolOwnedRate, votingEscrowedRate }, + { mlpPrice, mcbPrice, ethPrice }, + ] = await Promise.all([ + getDataFromPOL(), + getDataFromRewardRouter(), + getTokenPrices(), + ]); + + const mlpCirculatingSupply = mlpPolBalance / poolOwnedRate; + + const muxAPR = + (muxRewardRate * mcbPrice * 86400 * 365 * (1 - votingEscrowedRate)) / + (mlpCirculatingSupply * mlpPrice); + + const ethAPR = + (feeRewardRate * ethPrice * 86400 * 365 * 0.7) / + (mlpCirculatingSupply * mlpPrice); + + const totalAPR = (muxAPR + ethAPR) * 100; + + return totalAPR; +} + +module.exports = { getMuxLpApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/olive-adapter.js b/src/adaptors/factor-v2/strategy-adapter/olive-adapter.js new file mode 100644 index 0000000000..6fee17b3f8 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/olive-adapter.js @@ -0,0 +1,22 @@ +const { getDefiLLamaPools } = require('./utils'); + +async function getOliveApr() { + const pool = await getDefiLLamaPools( + '79587734-a461-4f4c-b9e2-c85c70484cf8' + ); + + const beefyApr = + pool.apyBase + (isNaN(pool.apyReward) ? 0 : pool.apyReward); + + const ampFactor = 1.33; + const weeksPerYear = 365 / 7; + const oliveBoost = 0.05; + const apr = + (1 + (beefyApr * ampFactor) / weeksPerYear) ** weeksPerYear - + 1 + + oliveBoost; + + return apr * 100; +} + +module.exports = { getOliveApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/pendle-adapter.js b/src/adaptors/factor-v2/strategy-adapter/pendle-adapter.js new file mode 100644 index 0000000000..5356a1b30f --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/pendle-adapter.js @@ -0,0 +1,23 @@ +const { getDefiLLamaPools } = require('./utils'); + +async function getPendleApr(poolAddress) { + const poolAddressToIdMap = { + // wstETH + '0x08a152834de126d2ef83d612ff36e4523fd0017f': + 'f05aa688-f627-4438-89c6-2fef135510c7', + + // rETH + '0x14fbc760efaf36781cb0eb3cb255ad976117b9bd': + '35fe5f76-3b7d-42c8-9e54-3da70fbcb3a9', + }; + + const pool = await getDefiLLamaPools( + poolAddressToIdMap[poolAddress.toLowerCase()] + ); + + const apr = pool.apyBase + pool.apyReward; + + return apr; +} + +module.exports = { getPendleApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/penpie-adapter.js b/src/adaptors/factor-v2/strategy-adapter/penpie-adapter.js new file mode 100644 index 0000000000..5269b94c71 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/penpie-adapter.js @@ -0,0 +1,46 @@ +const sdk = require('@defillama/sdk'); +const { getAprFromDefillamaPool, makeReadable } = require('./utils'); +const utils = require('../../utils'); +const { default: axios } = require('axios'); + +const MASTER_PENPIE_ADDRESS = '0x0776C06907CE6Ff3d9Dbf84bA9B3422d7225942D'; +const PNP_ADDRESS = '0x2Ac2B254Bc18cD4999f64773a966E4f4869c34Ee'; + +async function getPenpieApr(underlyingTokenAddress) { + const tokenPrices = await utils.getPrices( + [PNP_ADDRESS, underlyingTokenAddress], + 'arbitrum' + ); + + const pnpPriceInUSD = tokenPrices.pricesByAddress[PNP_ADDRESS.toLowerCase()]; + const poolPriceInUSD = + tokenPrices.pricesByAddress[underlyingTokenAddress.toLowerCase()]; + + const { output } = await sdk.api.abi.call({ + target: MASTER_PENPIE_ADDRESS, + abi: 'function getPoolInfo(address) public view returns (uint256,uint256,uint256,uint256)', + params: [underlyingTokenAddress], + chain: 'arbitrum', + }); + + const secondsPerYear = 31536000; + const totalStaked = makeReadable(output[2]); + const emissionPerSecondsInPNP = makeReadable(output[0]); + const emissionPerYearInPNP = emissionPerSecondsInPNP * secondsPerYear; + const emissionPerYearInUSD = emissionPerYearInPNP * pnpPriceInUSD; + + const tvlInUSD = totalStaked * poolPriceInUSD; + + const response = await axios.get( + `https://api-v2.pendle.finance/core/v1/42161/markets/${underlyingTokenAddress}` + ); + + const apr = + (emissionPerYearInUSD * 100) / tvlInUSD + + response.data.maxBoostedApy * 100 * 0.83 + + response.data.swapFeeApy; + + return apr; +} + +module.exports = { getPenpieApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/redacted-adapter.js b/src/adaptors/factor-v2/strategy-adapter/redacted-adapter.js new file mode 100644 index 0000000000..516a072719 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/redacted-adapter.js @@ -0,0 +1,14 @@ +const { default: axios } = require('axios'); + +async function getPxGMXApr() { + const response = await axios.get( + 'https://pirex.io/_next/data/33VnMjJ28usC4n5WCEd0z/vaults.json', + + ); + const apr = parseFloat(response.data.pageProps.apy.pxGMX); + + return apr; +} + +module.exports = { getPxGMXApr }; + diff --git a/src/adaptors/factor-v2/strategy-adapter/silo-adapter.js b/src/adaptors/factor-v2/strategy-adapter/silo-adapter.js new file mode 100644 index 0000000000..111371b93b --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/silo-adapter.js @@ -0,0 +1,48 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +async function getSiloAddress(underlyingTokenAddress) { + const [{ output: underlyingSiloAddress }, { output: siloAddress }] = + await Promise.all([ + sdk.api.abi.call({ + target: underlyingTokenAddress, + abi: 'address:asset', + chain: 'arbitrum', + }), + sdk.api.abi.call({ + target: underlyingTokenAddress, + abi: 'address:silo', + chain: 'arbitrum', + }), + ]); + + return { underlyingSiloAddress, siloAddress }; +} + +async function getSiloApr(underlyingTokenAddress) { + const { siloAddress, underlyingSiloAddress } = await getSiloAddress( + underlyingTokenAddress + ); + + const subgraphQuery = gql` + query GetInterestRate($interestRateId: String!) { + interestRate(id: $interestRateId) { + rate + } + } + `; + + const response = await request( + sdk.graph.modifyEndpoint('HduBrJQ362TT8LmLscKuYLpQcMffZe3Z43juCuGkLstG'), + subgraphQuery, + { + interestRateId: `LENDER-VARIABLE-${siloAddress.toLowerCase()}-${underlyingSiloAddress.toLowerCase()}`, + } + ); + + const apr = parseFloat(response.interestRate.rate); + + return apr; +} + +module.exports = { getSiloApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/sjoe-adapter.js b/src/adaptors/factor-v2/strategy-adapter/sjoe-adapter.js new file mode 100644 index 0000000000..77251ae25a --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/sjoe-adapter.js @@ -0,0 +1,59 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { getCoinDataFromDefillamaAPI, getCurrentTimestamp } = require('./utils'); + +async function getMonthlyReward() { + const query = gql` + query feeBankDayDatasQuery($first: Int! = 100, $dateAfter: Int!) { + dayDatas( + first: $first + orderBy: date + orderDirection: desc + where: { date_gte: $dateAfter } + ) { + id + date + usdRemitted + } + } + `; + const thirtyDaysAgoRaw = getCurrentTimestamp() - 30 * 86400; + const thirtyDaysAgo = thirtyDaysAgoRaw - (thirtyDaysAgoRaw % 86400); + const variables = { + dateAfter: thirtyDaysAgo, + }; + const { dayDatas } = await request( + sdk.graph.modifyEndpoint('AuX5GL2oSPVcgHUbBow5SU3yoxWFNFdmGLvEX9nb1gUb'), + query, + variables + ); + + const monthlyReward = dayDatas.reduce((acc, dayData) => { + return acc + parseFloat(dayData.usdRemitted); + }, 0); + return monthlyReward; +} + +async function getTVLFromSource(underlyingTokenAddress) { + const [{ output: internalJoeBalance }, coinData] = await Promise.all([ + sdk.api.abi.call({ + target: '0x43646A8e839B2f2766392C1BF8f60F6e587B6960', + abi: 'uint256:internalJoeBalance', + chain: 'arbitrum', + }), + getCoinDataFromDefillamaAPI('arbitrum', underlyingTokenAddress), + ]); + + const { price, decimals } = coinData; + + return (parseInt(internalJoeBalance.toString()) * price) / 10 ** decimals; +} + +async function getSJoeApr(underlyingTokenAddress) { + const monthlyReward = await getMonthlyReward(); + const sJoeTVL = await getTVLFromSource(underlyingTokenAddress); + const apr = ((monthlyReward * 12) / sJoeTVL) * 100; + return apr; +} + +module.exports = { getSJoeApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/tender-adapter.js b/src/adaptors/factor-v2/strategy-adapter/tender-adapter.js new file mode 100644 index 0000000000..e664f4448f --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/tender-adapter.js @@ -0,0 +1,19 @@ +const { getDefiLLamaPools } = require('./utils'); + +async function getTenderApr(poolAddress) { + const poolAddressToIdMap = { + // USDC + '0x068485a0f964b4c3d395059a19a05a8741c48b4e': + 'f152ff88-dd31-4efb-a0a9-ad26b5536cc7', + }; + + const pool = await getDefiLLamaPools( + poolAddressToIdMap[poolAddress.toLowerCase()] + ); + + const apr = pool.apyBase + (isNaN(pool.apyReward) ? 0 : pool.apyReward); + + return apr; +} + +module.exports = { getTenderApr }; diff --git a/src/adaptors/factor-v2/strategy-adapter/utils.js b/src/adaptors/factor-v2/strategy-adapter/utils.js new file mode 100644 index 0000000000..c5c50d9b41 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/utils.js @@ -0,0 +1,50 @@ +const { default: axios } = require('axios'); + +async function getAprFromDefillamaPool(apyFunction, poolId) { + const pools = await apyFunction(); + const pool = pools.filter( + (item) => item.pool.toLowerCase() == poolId.toLowerCase() + ); + + if (!pool.length) return 0; + + const apr = pool[0].apyBase + pool[0].apyReward; + + return apr; +} + +function makeReadable(val, dec = 18) { + return parseInt(val) / 10 ** dec; +} + +async function getCoinDataFromDefillamaAPI(chain, tokenAddress) { + const coinId = `${chain}:${tokenAddress}`; + const response = await axios.get( + 'https://coins.llama.fi/prices/current/' + coinId + ); + const coinData = response.data.coins[coinId]; + + // { decimals, symbol, price, timestamp, confidence } + return coinData; +} + +function getCurrentTimestamp() { + const timestamp = Math.floor(Date.now() / 1000); + return timestamp; +} + +async function getDefiLLamaPools(poolId) { + const response = await axios.get('https://yields.llama.fi/pools'); + const pools = response.data.data; + return pools.find( + (pools) => pools.pool.toLowerCase() == poolId.toLowerCase() + ); +} + +module.exports = { + makeReadable, + getAprFromDefillamaPool, + getCoinDataFromDefillamaAPI, + getDefiLLamaPools, + getCurrentTimestamp, +}; diff --git a/src/adaptors/factor-v2/strategy-adapter/vela-adapter.js b/src/adaptors/factor-v2/strategy-adapter/vela-adapter.js new file mode 100644 index 0000000000..1745528c22 --- /dev/null +++ b/src/adaptors/factor-v2/strategy-adapter/vela-adapter.js @@ -0,0 +1,16 @@ +const { getDefiLLamaPools } = require('./utils'); + +/*////////////////////////////////////////////////////////////////////////////// + VLP APR +//////////////////////////////////////////////////////////////////////////////*/ + +async function getVlpApr() { + const pool = await getDefiLLamaPools( + 'ddafe2fb-757a-45dd-87b5-a2c42dc9e093' + ); + const apr = pool.apyBase + pool.apyReward; + + return apr; +} + +module.exports = { getVlpApr }; diff --git a/src/adaptors/factor-v2/vaults.js b/src/adaptors/factor-v2/vaults.js new file mode 100644 index 0000000000..22d0dd8622 --- /dev/null +++ b/src/adaptors/factor-v2/vaults.js @@ -0,0 +1,94 @@ +const vaults = [ + { + poolAddress: '0x89e06Baa8E09Bf943a767788Cf00C9f9e9a873d9', + strategy: 'GLPStrategy', + symbol: 'factGAC', + underlyingToken: '0x5402B5F40310bDED796c7D0F3FF6683f5C0cFfdf', + }, + { + poolAddress: '0x9F7323E95F9ee9f7Ec295d7545e82Cd93fA13f97', + strategy: 'MuxStrategy', + symbol: 'muxpMAC', + underlyingToken: '0x7CbaF5a14D953fF896E5B3312031515c858737C8', + }, + { + poolAddress: '0x3DAe492145e0631D341617bAA81a4c72C2CD4b99', + strategy: 'TraderJoeStrategy', + symbol: 'factJAC', + underlyingToken: '0x371c7ec6D8039ff7933a2AA28EB827Ffe1F52f07', + }, + { + poolAddress: '0xF45A9E3f2F5984BaB983C9f245204DE23aE3b1A1', + strategy: 'SiloStrategy', + symbol: 'siloSUAC', + underlyingToken: '0x55ADE3B74abef55bF379FF6Ae61CB77a405Eb4A8', + }, + { + poolAddress: '0xdfD0a93a22CAE02C81CCe29A6A6362Bec2D2C282', + strategy: 'SiloStrategy', + symbol: 'siloSGAC', + underlyingToken: '0x96E1301bd2536A3C56EBff8335FD892dD9bD02dC', + }, + { + poolAddress: '0xE990f7269E7BdDa64b947C81D69aed92a68cEBC6', + strategy: 'PendleStrategy', + symbol: 'factWAC', + underlyingToken: '0x08a152834de126d2ef83D612ff36e4523FD0017F', + }, + { + poolAddress: '0xEb6c9C35f2BBeeDd4CECc717a869584f85C17d67', + strategy: 'PendleStrategy', + symbol: 'factRAC', + underlyingToken: '0x14FbC760eFaF36781cB0eb3Cb255aD976117B9Bd', + }, + { + poolAddress: '0xe4a286bCA6026CccC7D240914c34219D074F4020', + strategy: 'VelaStrategy', + symbol: 'factVAC', + underlyingToken: '0xC5b2D9FDa8A82E8DcECD5e9e6e99b78a9188eB05', + }, + { + poolAddress: '0x32d1778be7aF21E956DFA38683a707F5539cFc8c', + strategy: 'OliveStrategy', + symbol: 'olivPPO', + underlyingToken: '0x5402B5F40310bDED796c7D0F3FF6683f5C0cFfdf', + }, + { + poolAddress: '0x9Ae93cb28F8A5e6D31B9F9887d57604B31DcC42E', + strategy: 'LodestarStrategy', + symbol: 'lodePAC', + underlyingToken: '0x1ca530f02DD0487cef4943c674342c5aEa08922F', + }, + { + poolAddress: '0x18dFCCb8EAc64Da10DCc5cbf677314c0125B6C4B', + strategy: 'TenderStrategy', + symbol: 'factTAC', + underlyingToken: '0x068485a0f964B4c3D395059a19A05a8741c48B4E', + }, + // { + // poolAddress: '0x52459E1FA6E71BCB93C84c2e2b438ED797A8F3a8', + // strategy: 'PerennialStrategy', + // symbol: 'pereBCA', + // underlyingToken: '0x5A572B5fBBC43387B5eF8de2C4728A4108ef24a6', + // }, + // { + // poolAddress: '0xc994bC98251E043D4681Af980b1E487CfC88193a', + // strategy: 'RedactedStrategy', + // symbol: 'redaPMY', + // underlyingToken: '0x9A592B4539E22EeB8B2A3Df679d572C7712Ef999', + // }, + { + poolAddress: '0xfc0D36C2781F26377da6b72Ab448F5b2a71e7D14', + strategy: 'PenpieStrategy', + symbol: 'pieWEAC', + underlyingToken: '0x08a152834de126d2ef83D612ff36e4523FD0017F', + }, + { + poolAddress: '0xA92c3927A69cBb48735DE6aBf477ea5281152Ef3', + strategy: 'PenpieStrategy', + symbol: 'pieREAC', + underlyingToken: '0x14FbC760eFaF36781cB0eb3Cb255aD976117B9Bd', + }, +]; + +module.exports = vaults; diff --git a/src/adaptors/fairfi/index.js b/src/adaptors/fairfi/index.js new file mode 100644 index 0000000000..42846b1d06 --- /dev/null +++ b/src/adaptors/fairfi/index.js @@ -0,0 +1,29 @@ +const utils = require('../utils'); + +const url = 'https://backend-api-prod.frfi.io/autofarm?$limit=1000'; + +const ChainMap = { + 56: 'bsc', + 137: 'polygon', + 1: 'ethereum', + 2222: 'kava' +} + +const main = async () => { + const response = await utils.getData(url); + return response?.data?.filter(item => !!ChainMap[item.chainId])?.map((item) => ({ + pool: `${item.vaultAddress}-${item.chainId}`.toLowerCase(), + chain: utils.formatChain(ChainMap[item.chainId]), + project: 'fairfi', + symbol: item.info?.mailInfo?.name ?? '', + tvlUsd: item.strategyTVL, + apy: item.apy, + url: `https://frfi.io/pool/${item._id}`, + })); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://frfi.io/pools', +}; diff --git a/src/adaptors/falcon-finance/index.js b/src/adaptors/falcon-finance/index.js new file mode 100644 index 0000000000..5a1f2b46e2 --- /dev/null +++ b/src/adaptors/falcon-finance/index.js @@ -0,0 +1,122 @@ +const sdk = require('@defillama/sdk') +const axios = require('axios') +const utils = require('../utils') + +const CHAIN = 'ethereum' +const SUSDf = '0xc8CF6D7991f15525488b2A83Df53468D682Ba4B0' // sUSDf (ERC-4626) +const USDf = '0xFa2B947eEc368f42195f24F36d2aF29f7c24CeC2' + +const FF = '0xFA1C09fC8B491B6A4d3Ff53A10CAd29381b3F949' +const sFF = '0x1a0c3ffcbd101c6f2f6650ded9964c4a568c4d72' + +const abi = { + convertToAssets: { "inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function" }, + totalAssets: { "inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"" ,"type":"uint256"}],"stateMutability":"view","type":"function" }, +} + +const DAY = 86_400 +const SHARES = BigInt('1000000000000000000000000') // 1e24 +const SCALE = BigInt('1000000000000') + +async function getBlockAt(ts, chain = CHAIN) { + const { data } = await axios.get(`https://coins.llama.fi/block/${chain}/${ts}`) + return { block: data.height || data.number, ts: data.timestamp || ts } +} + +async function readRate(blockTag, vault) { + const { output } = await sdk.api.abi.call({ + target: vault, + abi: abi.convertToAssets, + params: [SHARES.toString()], + chain: CHAIN, + block: blockTag, + }) + return BigInt(output) +} + +function ratioToDaily(rNow, rPrev, secondsBigOrNum) { + if (rPrev === 0n || rNow === 0n) return 0 + const qFP = (rNow * SCALE) / rPrev + const q = Number(qFP) / Number(SCALE) + if (!(q > 0) || !isFinite(q)) return 0 + const seconds = Number(secondsBigOrNum) || 1 + const exp = DAY / seconds + return Math.pow(q, exp) - 1 +} + +async function computeApyBase(vault) { + const nowTs = Math.floor(Date.now() / 1e3) + const WEEK = 7 * DAY + + const [{ block: bNow, ts: tNow }, { block: bPast, ts: tPast }] = await Promise.all([ + getBlockAt(nowTs), + getBlockAt(nowTs - WEEK), + ]) + + const [rNow, rPast] = await Promise.all([readRate(bNow, vault), readRate(bPast, vault)]) + if (rNow === 0n || rPast === 0n || rNow === rPast) return 0 + + const daily = ratioToDaily(rNow, rPast, Math.max(1, tNow - tPast)) + if (!daily) return 0 + + const aprBase = daily * 365 * 100 + return utils.aprToApy(aprBase, 365) // number +} + +async function getData(vault, underlying) { + const { output: totalAssetsBn } = await sdk.api.abi.call({ + target: vault, + abi: abi.totalAssets, + chain: CHAIN, + }) + + const priceKey = `${CHAIN}:${underlying}` + let price = 1 + try { + const { data } = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + price = data.coins?.[priceKey]?.price ?? 1 + } catch (_) {} + + const tvlUsd = (Number(totalAssetsBn) / 1e18) * price + const apyBase = await computeApyBase(vault) + + return { tvlUsd, apyBase } +} + +async function apy() { + const [sUSDfData, sFFData] = await Promise.all([ + getData(SUSDf, USDf), + getData(sFF, FF), + ]) + + return [ + { + pool: `${SUSDf}-${CHAIN}`, + chain: 'Ethereum', + project: 'falcon-finance', + symbol: 'sUSDf', + tvlUsd: sUSDfData.tvlUsd, + apyBase: sUSDfData.apyBase, + underlyingTokens: [USDf], + poolMeta: 'ERC-4626: USDf → sUSDf', + url: 'https://app.falcon.finance/earn/classic', + }, + { + pool: `${sFF}-${CHAIN}`, + chain: 'Ethereum', + project: 'falcon-finance', + symbol: 'sFF', + tvlUsd: sFFData.tvlUsd, + apyBase: sFFData.apyBase, + underlyingTokens: [FF], + poolMeta: 'ERC-4626: FF → sFF', + url: 'https://app.falcon.finance/earn/classic', + }, + ] +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.falcon.finance/earn/classic', +} diff --git a/src/adaptors/fenix-concentrated-liquidity/index.js b/src/adaptors/fenix-concentrated-liquidity/index.js new file mode 100644 index 0000000000..8e42345af3 --- /dev/null +++ b/src/adaptors/fenix-concentrated-liquidity/index.js @@ -0,0 +1,112 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL = `https://www.fenixfinance.io/api/blaze/liquidity/rewards`; + +const SUBGRAPH_URL = + 'https://api.goldsky.com/api/public/project_clxadvm41bujy01ui2qalezdn/subgraphs/fenix-v3-dex/latest/gn'; + +const FNX_ADDRESS = '0x52f847356b38720B55ee18Cb3e094ca11C85A192'; + +const swapPairsQuery = (skip) => { + return gql` + query MyQuery { + pools(first: 100, skip: ${skip}, where: {totalValueLockedUSD_gt: 10000}) { + totalValueLockedToken0 + totalValueLockedToken1 + totalValueLockedUSD + token1 { + id + symbol + } + token0 { + id + symbol + } + id + } + } + `; +}; + +const getPairs = async () => { + try { + let pools = []; + let index = 0; + let res; + + do { + res = await request(SUBGRAPH_URL, swapPairsQuery(index), {}); + + if (res.pools?.length > 0) { + pools = [...pools, ...res.pools]; + } + index += res.pools?.length || 0; + } while (res.pools?.length > 0); + + return pools; + } catch (error) { + console.error('Error in getPairs:', error); + throw error; + } +}; + +const getApy = async () => { + try { + const pairs = await getPairs(); + + const poolsRes = await axios.get( + `${API_URL}?${pairs.map((pair) => `pools=${pair.id}`).join('&')}` + ); + // console.log('Pools rewards sample:', poolsRes.data); + + const { coins: fnxPrice } = await utils.getData( + `https://coins.llama.fi/prices/current/blast:${FNX_ADDRESS}?searchWidth=4h` + ); + const fnxPriceUsd = fnxPrice[`blast:${FNX_ADDRESS}`]?.price || 0; + + const apyDict = {}; + for (const pool of poolsRes.data) { + const pairData = pairs.find( + (p) => p.id.toLowerCase() === pool.pool.toLowerCase() + ); + + if (pairData) { + const weeklyRewardInFNX = parseFloat(pool.rewardWei) / 1e18; + const annualRewardInFNX = weeklyRewardInFNX * 52; + const annualRewardUSD = annualRewardInFNX * fnxPriceUsd; + const tvl = parseFloat(pairData.totalValueLockedUSD); + apyDict[pool.pool.toLowerCase()] = (annualRewardUSD / tvl) * 100; + } + } + + const pools = pairs.map((pair) => { + let tvl = parseFloat(pair.totalValueLockedUSD); + + const poolData = { + pool: pair.id, + chain: utils.formatChain('blast'), + project: 'fenix-concentrated-liquidity', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: tvl, + apyReward: parseFloat(apyDict[pair.id.toLowerCase()] || 0), + underlyingTokens: [pair.token0.id, pair.token1.id], + rewardTokens: [FNX_ADDRESS], + }; + + return poolData; + }); + return pools; + } catch (error) { + console.error('Error in getApy:', error); + throw error; + } +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.fenixfinance.io/liquidity', +}; diff --git a/src/adaptors/fenix-standard-pools/index.js b/src/adaptors/fenix-standard-pools/index.js new file mode 100644 index 0000000000..0ab7c4f2ae --- /dev/null +++ b/src/adaptors/fenix-standard-pools/index.js @@ -0,0 +1,101 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL = `https://www.fenixfinance.io/api/blaze/liquidity/rewards`; + +const SUBGRAPH_URL = + 'https://api.goldsky.com/api/public/project_clxadvm41bujy01ui2qalezdn/subgraphs/fenix-v2-subgraph/latest/gn'; + +const FNX_ADDRESS = '0x52f847356b38720B55ee18Cb3e094ca11C85A192'; + +const swapPairsQuery = (skip) => { + return gql` + query MyQuery { + pairs(first: 100, skip: ${skip}, where: {reserveUSD_gt: 10000}) { + reserve0 + reserve1 + token1 { + id + symbol + } + token0 { + id + symbol + } + reserveUSD + id + } + } + `; +}; + +const getPairs = async () => { + let pairs = []; + let index = 0; + let res; + do { + res = await request(SUBGRAPH_URL, swapPairsQuery(index), {}); + if (res.pairs.length > 0) { + pairs = [...pairs, ...res.pairs]; + } + index += res.pairs.length; + } while (res.pairs.length > 0); + return pairs; +}; + +const getApy = async () => { + const pairs = await getPairs(); + const poolsRes = await axios.get( + `${API_URL}?${pairs.map((pair) => `pools=${pair.id}`).join('&')}` + ); + + // First get FNX price from DeFiLlama + const { coins: fnxPrice } = await utils.getData( + `https://coins.llama.fi/prices/current/blast:${FNX_ADDRESS}?searchWidth=4h` + ); + + const fnxPriceUsd = fnxPrice[`blast:${FNX_ADDRESS}`]?.price || 0; + + // Create apyDict by calculating (rewards/tvl) * 100 * 52 for each pool + const apyDict = {}; + for (const pool of poolsRes.data) { + const pairData = pairs.find( + (p) => p.id.toLowerCase() === pool.pool.toLowerCase() + ); + + if (pairData) { + // Convert reward to annual value (weekly * 52) and from Wei to FNX + const annualReward = (parseFloat(pool.rewardWei) * 52) / 1e18; + // Convert to USD using FNX price + const annualRewardUSD = annualReward * fnxPriceUsd; + // Get TVL + const tvl = parseFloat(pairData.reserveUSD); + // Calculate APY: (annual reward in USD / TVL) * 100 + apyDict[pool.pool.toLowerCase()] = (annualRewardUSD / tvl) * 100; + } + } + + const pools = pairs.map((pair) => { + tvl = parseFloat(pair.reserveUSD); + return { + pool: pair.id, + chain: utils.formatChain('blast'), + project: 'fenix-standard-pools', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: tvl, + apyReward: parseFloat(apyDict[pair.id.toLowerCase()] || 0), + underlyingTokens: [pair.token0.id, pair.token1.id], + rewardTokens: [FNX_ADDRESS], + }; + }); + + return pools; +}; +getApy(); +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.fenixfinance.io/liquidity', +}; diff --git a/src/adaptors/ferro/index.ts b/src/adaptors/ferro/index.ts new file mode 100644 index 0000000000..c8f638ab33 --- /dev/null +++ b/src/adaptors/ferro/index.ts @@ -0,0 +1,165 @@ +const { gql, request } = require('graphql-request'); + +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +const API_URL_3FER: string = 'https://api.ferroprotocol.com/info/api/getApys'; +const FERR_SUBGRAPH = 'https://graph.cronoslabs.com/subgraphs/name/ferro/bar'; + +const STAKING_ADDRESS = '0x6b82eAce10F782487B61C616B623A78c965Fdd88'; +const FERRO_TOKEN = '0x39bC1e38c842C60775Ce37566D03B41A7A66C782'; + +const SWAP_3FER_ADDRESS = '0xe8d13664a42b338f009812fa5a75199a865da5cd'; +const TOKEN_3FER_ADDRESSES = { + USDT: { address: '0x66e428c3f67a68878562e79A0234c1F83c208770', decimals: 6 }, + USDC: { address: '0xc21223249ca28397b4b6541dffaecc539bff0c59', decimals: 6 }, + DAI: { address: '0xf2001b145b43032aaf5ee2884e456ccd805f677d', decimals: 18 }, +}; + +const SWAP_2FER_ADDRESS = '0xa34c0fe36541fb085677c36b4ff0ccf5fa2b32d6'; +const TOKEN_2FER_ADDRESSES = { + USDC: { address: '0xc21223249ca28397b4b6541dffaecc539bff0c59', decimals: 6 }, + USDT: { address: '0x66e428c3f67a68878562e79A0234c1F83c208770', decimals: 6 }, +}; + +const stakingQuery = gql` + query stakingQuery { + barDailySnapshots(orderBy: date, orderDirection: desc, first: 7) { + id + ratio + } + } +`; + +const CG_NAMES = { + tether: 'USDT', + 'usd-coin': 'USDC', + dai: 'DAI', + ferro: 'FERRO', +}; + +interface FerApyApiResponse { + data: { + '3FER': { baseApr: number; ferroApr: number }; + '2FER': { baseApr: number; ferroApr: number }; + }; +} +type FerApyApiData = FerApyApiResponse['data']; + +interface StakingRatio { + barDailySnapshots: Array<{ ratio: number }>; +} + +const getPoolApy = async ( + swapAddr: string, + symbol: string, + poolMeta: string, + tokenAddresses: Record, + mappedPrices: Record, + apyApiData: FerApyApiData +) => { + const stakeBalance = await Promise.all( + Object.entries(tokenAddresses).map( + async ([_, { address, decimals }]) => + ( + await sdk.api.erc20.balanceOf({ + target: address, + owner: swapAddr, + chain: 'cronos', + }) + ).output / + 10 ** decimals + ) + ); + + const tvlUsd = Object.entries(tokenAddresses).reduce((acc, token, i) => { + return acc + mappedPrices[token[0]] * stakeBalance[i]; + }, 0); + + return { + pool: swapAddr, + symbol, + poolMeta, + chain: utils.formatChain('cronos'), + project: 'ferro', + tvlUsd, + apyBase: apyApiData[poolMeta].baseApr, + apyReward: apyApiData[poolMeta].ferroApr, + underlyingTokens: Object.values(tokenAddresses).map( + ({ address }) => address + ), + rewardTokens: [FERRO_TOKEN], + }; +}; + +const getApy = async () => { + const { data }: FerApyApiResponse = await utils.getData(API_URL_3FER); + + const priceKeys = Object.keys(CG_NAMES) + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + const stakingRatio = await request(FERR_SUBGRAPH, stakingQuery); + const stakingApy = + (1 - + stakingRatio.barDailySnapshots[6].ratio / + stakingRatio.barDailySnapshots[0].ratio) * + 52; + + const mappedPrices = Object.entries(prices).reduce( + (acc, [name, price]: any) => ({ + ...acc, + [CG_NAMES[name.replace('coingecko:', '')]]: price.price, + }), + {} as Record + ); + + const ferroStakeBalance = + ( + await sdk.api.erc20.balanceOf({ + target: FERRO_TOKEN, + owner: STAKING_ADDRESS, + chain: 'cronos', + }) + ).output / 1e18; + + const stakePool = { + pool: STAKING_ADDRESS, + symbol: 'FER', + chain: utils.formatChain('cronos'), + project: 'ferro', + tvlUsd: ferroStakeBalance * mappedPrices.FERRO, + apyReward: stakingApy * 100, + underlyingTokens: [FERRO_TOKEN], + rewardTokens: [FERRO_TOKEN], + }; + + const stable3FerPool = await getPoolApy( + SWAP_3FER_ADDRESS, + 'DAI-USDC-USDT', + '3FER', + TOKEN_3FER_ADDRESSES, + mappedPrices, + data + ); + + const stable2FerPool = await getPoolApy( + SWAP_2FER_ADDRESS, + 'USDC-USDT', + '2FER', + TOKEN_2FER_ADDRESSES, + mappedPrices, + data + ); + + return [stakePool, stable3FerPool, stable2FerPool]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://ferroprotocol.com/#/pools', +}; diff --git a/src/adaptors/filet-finance/index.js b/src/adaptors/filet-finance/index.js new file mode 100644 index 0000000000..703178e40e --- /dev/null +++ b/src/adaptors/filet-finance/index.js @@ -0,0 +1,30 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const apyData = await utils.getData( + 'https://api.filet.finance/pledge/pool/all?source=2' + ); + const poolData = apyData.data.filter((item) => item.expireDays === 360)[0]; + + const tvlData = await utils.getData( + 'https://api.filet.finance/pledge/ext/tx/pledgeTxAll' + ); + + const filPool = { + pool: '0x01502CAE9E6f973EaB687aA99bA1b332AAa1837F-filecoin', + chain: utils.formatChain('filecoin'), + project: 'filet-finance', + symbol: utils.formatSymbol('FIL'), + tvlUsd: tvlData.data.tvl, + apy: Number(poolData.incomeRate), + poolMeta: '360days lockup', + }; + + return [filPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://www.filet.finance', +}; diff --git a/src/adaptors/fiva/index.js b/src/adaptors/fiva/index.js new file mode 100644 index 0000000000..62f76b0b16 --- /dev/null +++ b/src/adaptors/fiva/index.js @@ -0,0 +1,92 @@ +const utils = require('../utils'); +const axios = require('axios'); + +// TON blockchain configuration +const TON_CHAIN = { + chainName: 'ton', + chainSlug: 'ton', +}; + +function expiryToText(dateIso) { + return new Date(dateIso) + .toLocaleDateString('en-GB', { + day: '2-digit', + month: 'short', + year: 'numeric', + }) + .replace(/ /g, '') + .toUpperCase(); +} + +function createLpPools(assets) { + return assets + .filter(asset => asset.pool_liquidity_usd > 0) + .map((asset) => ({ + pool: asset.jettons.lp.master_address.toLowerCase(), + chain: utils.formatChain(TON_CHAIN.chainName), + project: 'fiva', + symbol: asset.jettons.lp.symbol.replace('LP ', ''), + tvlUsd: asset.pool_liquidity_usd, // Use pool liquidity for LP pools + apyBase: asset.pool_apr_7d, // Prefer 7-day APR + apyReward: 0, // No separate reward system visible in API + rewardTokens: [], // No reward tokens in current structure + underlyingTokens: [ + asset.jettons.pt.master_address, + asset.jettons.sy.master_address + ], + poolMeta: `For LP | Maturity ${expiryToText(asset.maturity_date)}`, + url: `${asset.earn_url.replace('/fixed-yield/', '/pools/')}?dir=provide&strategy=auto-mint&access=DLAMA`, + })); +} + +function createPtPools(assets) { + return assets + .filter(asset => asset.pool_liquidity_usd > 0 && asset.pt_price_usd > 0) + .map((asset) => ({ + pool: asset.jettons.pt.master_address.toLowerCase(), + chain: utils.formatChain(TON_CHAIN.chainName), + project: 'fiva', + symbol: asset.jettons.pt.symbol.replace('PT ', ''), + tvlUsd: asset.asset_tvl_usd, + apyBase: asset.fixed_apr, + underlyingTokens: [asset.jettons.underlying_jetton.master_address], + poolMeta: `For buying ${asset.jettons.pt.symbol}-${expiryToText(asset.maturity_date)}`, + url: asset.earn_url + "?access=DLAMA", + })); +} + +async function apy() { + const poolsFiltered = []; + + try { + const response = await axios.get('https://api2.thefiva.com/protocol_metrics'); + const assets = response.data.assets; + + // Create LP pools and PT pools + const ptPools = createPtPools(assets); + const lpPools = createLpPools(assets); + + // Combine all pools + const allPools = [...lpPools, ...ptPools] + .sort((a, b) => b.tvlUsd - a.tvlUsd); + + // Remove duplicates based on pool address + const unique = new Set(); + for (const pool of allPools) { + if (unique.has(pool.pool)) continue; + poolsFiltered.push(pool); + unique.add(pool.pool); + } + } catch (error) { + console.error('Error fetching Fiva data:', error.message); + return []; + } + + return poolsFiltered; +} + +module.exports = { + timetravel: false, + apy, + url: 'https://www.thefiva.com', +}; diff --git a/src/adaptors/flamingo-finance/index.js b/src/adaptors/flamingo-finance/index.js new file mode 100644 index 0000000000..969aa75644 --- /dev/null +++ b/src/adaptors/flamingo-finance/index.js @@ -0,0 +1,20 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const poolsData = await utils.getData( + 'http://api.flamingo.finance/project-info/defillama-yields' + ); + + return poolsData.pools.reduce((acc, p) => { + if (!acc.some((pool) => pool.pool === p.pool)) { + acc.push(p); + } + return acc; + }, []); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://flamingo.finance/earn/overview' +}; \ No newline at end of file diff --git a/src/adaptors/flashstake/index.js b/src/adaptors/flashstake/index.js new file mode 100644 index 0000000000..f3074fa4b6 --- /dev/null +++ b/src/adaptors/flashstake/index.js @@ -0,0 +1,94 @@ +const utils = require('../utils'); + +const API_LATEST = "https://apr.flashstake.io/latest"; +const API_HISTORICAL = "https://apr.flashstake.io/historical"; + +const processItems = async (data) => { + + const pools = Object.keys(data); + + // This is the array we will append to + let returnPayload = []; + + // Iterate over all the pools + for(let slug of pools) { + const poolData = data[slug]; + + // Iterate over all the pool data points + // @dev when "latest" API is used, this will only consist of 1 item + // @dev when "historical" API is used, this can contain many items + for(let poolDataItem of poolData) { + const decimals = parseInt(poolDataItem['principalToken']['decimals']); + const tvlInPrincipal = parseInt(poolDataItem['tvlInPrincipal']) / 10**decimals; + const tvlInUSD = parseFloat(poolDataItem['principalToken']['tokenUSDCPrice']) * tvlInPrincipal; + + /* + Note that this data is available if needed when processing historical + blockNumber: poolDataItem['blockNumber'] + blockTimestamp: poolDataItem['blockTimestamp'] + */ + + returnPayload.push({ + pool: `${poolDataItem['network']}:${poolDataItem['strategyAddress']}`.toLowerCase(), + chain: poolDataItem['network'], + project: 'flashstake', + symbol: poolDataItem['principalToken']['symbol'], + tvlUsd: tvlInUSD, + apy: parseFloat(poolDataItem["apr"]), + poolMeta: "1min lock" + }) + } + } + + return returnPayload.flat(); +}; + +// @dev only returns the latest information +const getLatest = async() => { + // Retrieve the data + const data = await utils.getData(API_LATEST); + + return await processItems(data); +} + +// @dev should be used sparingly to get historical data once +// @dev Leaving this here so you can generate historical data as per slasher125 +/* +const getHistorical = async() => { + const STARTING_POINT = 1659312000; // Protocol deployment + const MAX_INCREMENT = 604800; // 7 days + + // Create an array of promises then resolve them at the same time + let pointer = STARTING_POINT; + let allData = {}; + while(Math.floor(Date.now() / 1000) > pointer) { + const startTs = pointer; + const endTs = pointer + MAX_INCREMENT; + + const endpoint = `${API_HISTORICAL}?startTimestamp=${startTs}&endTimestamp=${endTs}` + const data = await utils.getData(endpoint); + + const pools = Object.keys(data); + + for(let pool of pools) { + // If key does not exist, create it + if(!Object.keys(allData).includes(pool)) { + allData[pool] = []; + } + + allData[pool].push(...data[pool]); + } + + // The API returns inclusive so add 1 + pointer = endTs + 1; + } + + return await processItems(allData); +} + */ + +module.exports = { + timetravel: false, + apy: getLatest, + url: 'https://app.flashstake.io/', +}; diff --git a/src/adaptors/flat-money-v1/index.js b/src/adaptors/flat-money-v1/index.js new file mode 100644 index 0000000000..2562cced03 --- /dev/null +++ b/src/adaptors/flat-money-v1/index.js @@ -0,0 +1,71 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); + +const utils = require('../utils'); + +const UNIT_ADDRESS = '0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2'; + +const FLAT_MONEY_VIEWER_CONTRACT = '0x509b85EEF0df77992b29aeDdD22C7119Db87ce16'; + +const FLAT_MONEY_API_URL = 'https://api.flat.money/graphql'; + +const UNIT_APY_QUERY = gql` + query { + apy { + weekly + } + } +`; + +const chain = 'base'; + +const getUNITTVL = async () => + await sdk.api2.abi.call({ + target: FLAT_MONEY_VIEWER_CONTRACT, + abi: 'function getFlatcoinTVL() view returns (uint256)', + chain, + }); + +const getUNITAPY = async () => + (await request(FLAT_MONEY_API_URL, UNIT_APY_QUERY)).apy.weekly; + +const getCollateralToken = async () => { + const target = await sdk.api2.abi.call({ + target: FLAT_MONEY_VIEWER_CONTRACT, + abi: 'function vault() view returns (address)', + chain, + }); + return ( + await sdk.api.abi.call({ + target, + abi: 'function collateral() view returns (address)', + chain, + }) + ).output; +}; + +const apy = async () => { + const tvlUsd = (await getUNITTVL()) / 1e18; + const apyBase = await getUNITAPY(); + const underlyingToken = await getCollateralToken(); + + return [ + { + pool: `${UNIT_ADDRESS}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'flat-money-v1', + symbol: utils.formatSymbol('UNIT'), + tvlUsd, + apyBase, + apyReward: null, + rewardTokens: [], + underlyingTokens: [underlyingToken], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://flat.money/flatcoin', +}; diff --git a/src/adaptors/flex-perpetuals/abi.js b/src/adaptors/flex-perpetuals/abi.js new file mode 100644 index 0000000000..91a2b4854e --- /dev/null +++ b/src/adaptors/flex-perpetuals/abi.js @@ -0,0 +1,53 @@ +module.exports = { + balanceOf: { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getAumE30: { + inputs: [ + { + internalType: 'bool', + name: '_isMaxPrice', + type: 'bool', + }, + ], + name: 'getAUME30', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; diff --git a/src/adaptors/flex-perpetuals/addresses.json b/src/adaptors/flex-perpetuals/addresses.json new file mode 100644 index 0000000000..880b1574d4 --- /dev/null +++ b/src/adaptors/flex-perpetuals/addresses.json @@ -0,0 +1,15 @@ +{ + "FLP": "0x6304CE3F4eF20EC0AaB3981d0B4428Beeb96c3aC", + "FDX": "0xE248c0bCE837B8dFb21fdfa51Fb31D22fbbB4380", + "ESFDX": "0x915595336Dad62fD1C3600193a16B3F44B44d27E", + "LFDX": "0x8ae234597bf9670aa854e3928a2b016AF2cbA33b", + "AEROLP": "0x789e4612f6c2b1c851493f015de0b32b567c281d", + "STFDXLP": "0x627E812204E5aB4E2d35836621F958a1e556da67", + "WBTC": "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", + "WETH": "0x4200000000000000000000000000000000000006", + "USDC": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + "CALCULATOR": "0x651e03A1A9D1657C870Ee22165C331bebAeAEd97", + "FLP_STAKING": "0x053fa05d34c51afC5cb9f162Fab3fD675Ac06119", + "FDX_STAKING": "0xbD5E6070E1dd19Bd3af24A46caE2634dA9f22e5B", + "STFDXLP_STAKING": "0xF00e53B7F3112834625f5AD5d47dA0e6E427E660" +} diff --git a/src/adaptors/flex-perpetuals/index.js b/src/adaptors/flex-perpetuals/index.js new file mode 100644 index 0000000000..be36e11bba --- /dev/null +++ b/src/adaptors/flex-perpetuals/index.js @@ -0,0 +1,264 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); + +const abi = require('./abi'); +const addresses = require('./addresses.json'); +const utils = require('../utils'); + +const WeiPerEther = BigNumber(1000000000000000000); + +const baseUrl = 'https://gapi.flex.trade/v1/apr-pools'; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const apy = async () => { + const [ + baseResponse, + { pricesBySymbol }, + { output: flpStakingAumE30Base }, + { output: flpTotalSupplyBase }, + { output: flpBalanceInPoolBase }, + { output: esfdxBalanceInPool }, + { output: lfdxBalanceInPool }, + { output: fdxBalanceInLP }, + { output: aerolpBalanceInPool }, + { output: aerolpTotalSupply }, + ] = await Promise.all([ + utils.getData(baseUrl), + getPrices([`base:${addresses.FDX}`]), + sdk.api.abi.call({ + abi: abi.getAumE30, + chain: 'base', + target: addresses.CALCULATOR, + params: [false], + }), + sdk.api.abi.call({ + abi: abi.totalSupply, + chain: 'base', + target: addresses.FLP, + params: [], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'base', + target: addresses.FLP, + params: [addresses.FLP_STAKING], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'base', + target: addresses.ESFDX, + params: [addresses.FDX_STAKING], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'base', + target: addresses.LFDX, + params: [addresses.FDX_STAKING], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'base', + target: addresses.FDX, + params: [addresses.AEROLP], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'base', + target: addresses.AEROLP, + params: [addresses.STFDXLP_STAKING], + }), + sdk.api.abi.call({ + abi: abi.totalSupply, + chain: 'base', + target: addresses.AEROLP, + params: [], + }), + ]); + + // ---------------- Base ---------------- + const { aprPools: baseAprPools } = baseResponse.data; + + const baseFlpApr = baseAprPools.find((p) => p.key === 'flp_staking'); + const baseFlpAprBase = () => { + if (!baseFlpApr || !baseFlpApr.Info) return BigNumber(0); + + const _baseFlpAprBase = baseFlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken == 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseFlpAprBase).dividedBy(WeiPerEther); + }; + + const baseFlpAprReward = () => { + if (!baseFlpApr || !baseFlpApr.Info) return BigNumber(0); + + const _baseFlpAprReward = baseFlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken != 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseFlpAprReward).dividedBy(WeiPerEther); + }; + + const baseStFdxlpApr = baseAprPools.find((p) => p.key === 'stfdxlp_staking'); + const baseStFdxlpAprBase = () => { + if (!baseStFdxlpApr || !baseStFdxlpApr.Info) return BigNumber(0); + + const _baseStFdxlpAprBase = baseStFdxlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken == 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseStFdxlpAprBase).dividedBy(WeiPerEther); + }; + + const baseStFdxlpAprReward = () => { + if (!baseStFdxlpApr || !baseStFdxlpApr.Info) return BigNumber(0); + + const _baseStFdxlpAprReward = baseStFdxlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken != 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseStFdxlpAprReward).dividedBy(WeiPerEther); + }; + + const baseFdxApr = baseAprPools.find((p) => p.key === 'fdx_staking'); + const baseFdxAprBase = () => { + if (!baseFdxApr || !baseFdxApr.Info) return BigNumber(0); + + const _baseFdxAprBase = baseFdxApr.Info.reduce((acc, apr) => { + if (apr.rewardToken == 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseFdxAprBase).dividedBy(WeiPerEther); + }; + + const baseFdxAprReward = () => { + if (!baseFdxApr || !baseFdxApr.Info) return BigNumber(0); + + const _baseFdxAprReward = baseFdxApr.Info.reduce((acc, apr) => { + if (apr.rewardToken != 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_baseFdxAprReward).dividedBy(WeiPerEther); + }; + + // ---------------- FLP ---------------- + const flpPriceInE30Base = BigNumber(flpStakingAumE30Base).dividedBy( + BigNumber(flpTotalSupplyBase) + ); + + const tvlUsdFlpBase = BigNumber(flpBalanceInPoolBase) + .multipliedBy(flpPriceInE30Base) + .dividedBy(1e30); + + const flpStakingPool = { + pool: `${addresses.FLP_STAKING}-base`, + chain: 'base', + project: 'flex-perpetuals', + symbol: 'ETH-BTC-USDC', + tvlUsd: tvlUsdFlpBase.toNumber(), + apyBase: baseFlpAprBase().toNumber(), + apyReward: baseFlpAprReward().toNumber(), + rewardTokens: [addresses.USDC, addresses.ESFDX], + underlyingTokens: [addresses.WETH, addresses.WBTC, addresses.USDC], + poolMeta: 'FLP Staking', + url: 'https://app.flex.trade/base/earn', + }; + + // ---------------- FDX ---------------- + console.log("PRICE =========================================", pricesBySymbol.fdx, esfdxBalanceInPool); + const tvlUsdFdx = BigNumber(esfdxBalanceInPool) + .plus(lfdxBalanceInPool) + .multipliedBy(pricesBySymbol.fdx) + .dividedBy(WeiPerEther); + + const fdxStakingPool = { + pool: `${addresses.FDX_STAKING}-base`, + chain: 'base', + project: 'flex-perpetuals', + symbol: 'FDX-esFDX', + tvlUsd: tvlUsdFdx.toNumber(), + apyBase: baseFdxAprBase().toNumber(), + apyReward: baseFdxAprReward().toNumber(), + rewardTokens: [addresses.USDC, addresses.ESFDX], + underlyingTokens: [addresses.ESFDX, addresses.FDX], + poolMeta: 'FDX Staking - esFDX reward is 1 year linear vested', + url: 'https://app.flex.trade/base/earn', + }; + + + // ---------------- STFDXLP ---------------- + console.log("STFDXLP =========================================", pricesBySymbol.fdx, fdxBalanceInLP, aerolpBalanceInPool, aerolpTotalSupply); + const tvlUsdstfdxlpBase = BigNumber(fdxBalanceInLP) + .multipliedBy(pricesBySymbol.fdx) + .multipliedBy(2) + .multipliedBy(aerolpBalanceInPool) + .dividedBy(aerolpTotalSupply) + .dividedBy(WeiPerEther); + + const stfdxlpStakingPool = { + pool: `${addresses.STFDXLP_STAKING}-base`, + chain: 'base', + project: 'flex-perpetuals', + symbol: 'StFdxLp', + tvlUsd: tvlUsdstfdxlpBase.toNumber(), + apyBase: baseStFdxlpAprBase().toNumber(), + apyReward: baseStFdxlpAprReward().toNumber(), + rewardTokens: [addresses.USDC, addresses.ESFDX], + underlyingTokens: [addresses.STFDXLP], + poolMeta: 'stFdxLP Staking', + url: 'https://app.flex.trade/base/earn', + }; + + return [flpStakingPool, fdxStakingPool, stfdxlpStakingPool]; +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/flowx-v2/index.js b/src/adaptors/flowx-v2/index.js new file mode 100644 index 0000000000..4319f21084 --- /dev/null +++ b/src/adaptors/flowx-v2/index.js @@ -0,0 +1,45 @@ +const axios = require('axios'); + +const chains = { + sui: 'https://api.flowx.finance/flowx-be/api/explore-stats/top-pools', +}; + +const apy = async (chain) => { + if (chain === 'sui') { + let pools = (await axios.get(chains[chain])).data.data.filter( + (it) => it.protocolVersion == 'V2' + ); + return pools + .map((p) => { + return { + pool: p.poolId, + chain: chain, + project: 'flowx-v2', + symbol: `${p.coinX.symbol}/${p.coinY.symbol}`, + underlyingTokens: [p.coinX.coinType, p.coinY.coinType], + rewardTokens: p.stats.combinedApr?.rewardTokens?.map( + (it) => it.coinType + ), + tvlUsd: Number(p.stats.totalLiquidityInUSD), + apyBase: Number(p.stats.combinedApr.lpRewardsApr), + apyReward: Number(p.stats.combinedApr.farmApr), + volumeUsd1d: Number(p?.stats.volume24H), + poolMeta: `${Number(p.feeRate) * 100}%`, + url: `https://flowx.finance/explore/pools/${p.poolId}`, + }; + }) + .filter((i) => i.tvlUsd <= 1e8); + } +}; + +const main = async () => { + const pools = await Promise.all( + Object.keys(chains).map((chain) => apy(chain)) + ); + + return pools.flat(); +}; + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/flowx-v3/index.js b/src/adaptors/flowx-v3/index.js new file mode 100644 index 0000000000..3fe0960544 --- /dev/null +++ b/src/adaptors/flowx-v3/index.js @@ -0,0 +1,43 @@ +const axios = require('axios'); + +const chains = { + sui: 'https://api.flowx.finance/flowx-be/api/explore-stats/top-pools', +}; + +const apy = async (chain) => { + if (chain === 'sui') { + let pools = (await axios.get(chains[chain])).data.data.filter( + (it) => it.protocolVersion == 'V3' + ); + return pools + .map((p) => { + return { + pool: p.poolId, + chain: chain, + project: 'flowx-v3', + symbol: `${p.coinX.symbol}/${p.coinY.symbol}`, + underlyingTokens: [p.coinX.coinType, p.coinY.coinType], + rewardTokens: p.stats.combinedApr?.rewardTokens?.map((it) => it.type), + tvlUsd: Number(p.stats.totalLiquidityInUSD), + apyBase: Number(p.stats.combinedApr.lpRewardsApr), + apyReward: Number(p.stats.combinedApr.farmApr), + volumeUsd1d: Number(p?.stats.volume24H), + poolMeta: `${Number(p.feeRate) * 100}%`, + url: `https://flowx.finance/explore/pools/${p.poolId}`, + }; + }) + .filter((i) => i.tvlUsd <= 1e8); + } +}; + +const main = async () => { + const pools = await Promise.all( + Object.keys(chains).map((chain) => apy(chain)) + ); + + return pools.flat(); +}; + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/fluid-dex/abi.json b/src/adaptors/fluid-dex/abi.json new file mode 100644 index 0000000000..e0e3ba637b --- /dev/null +++ b/src/adaptors/fluid-dex/abi.json @@ -0,0 +1,201 @@ +[ + { + "inputs": [], + "name": "getAllPoolsReserves", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "centerPrice", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "token0RealReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1RealReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token0ImaginaryReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1ImaginaryReserves", + "type": "uint256" + } + ], + "internalType": "struct IFluidDexT1.CollateralReserves", + "name": "collateralReserves", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "token0Debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1Debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token0RealReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1RealReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token0ImaginaryReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1ImaginaryReserves", + "type": "uint256" + } + ], + "internalType": "struct IFluidDexT1.DebtReserves", + "name": "debtReserves", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandsTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandDuration", + "type": "uint256" + } + ], + "internalType": "struct Structs.TokenLimit", + "name": "withdrawableToken0", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandsTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandDuration", + "type": "uint256" + } + ], + "internalType": "struct Structs.TokenLimit", + "name": "withdrawableToken1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandsTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandDuration", + "type": "uint256" + } + ], + "internalType": "struct Structs.TokenLimit", + "name": "borrowableToken0", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandsTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expandDuration", + "type": "uint256" + } + ], + "internalType": "struct Structs.TokenLimit", + "name": "borrowableToken1", + "type": "tuple" + } + ], + "internalType": "struct Structs.DexLimits", + "name": "limits", + "type": "tuple" + } + ], + "internalType": "struct Structs.PoolWithReserves[]", + "name": "poolsReserves_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/fluid-dex/index.js b/src/adaptors/fluid-dex/index.js new file mode 100644 index 0000000000..b154824df0 --- /dev/null +++ b/src/adaptors/fluid-dex/index.js @@ -0,0 +1,192 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const ethers = require('ethers'); +const abis = require('./abi.json'); + +const PROJECT = 'fluid-dex'; + +const DexReservesResolvers = { + ethereum: '0xC93876C0EEd99645DD53937b25433e311881A27C', + arbitrum: '0x666A400b8cDA0Dc9b59D61706B0F982dDdAF2d98', + polygon: '0x18DeDd1cF3Af3537D4e726D2Aa81004D65DA8581', + base: '0x41E6055a282F8b7Abdb8D22Bcd85c2A0eE22e38A', +} + +const EventSwap = 'event Swap(bool swap0to1, uint256 amountIn, uint256 amountOut, address to)'; + +function formatAddress(address) { + return address.toLowerCase(); +} + +function getTokenInfo(chain, address, symbol, decimals) { + if (address === '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') { + return { + address: '0x0000000000000000000000000000000000000000', + symbol: chain === 'polygon' ? 'POL' : 'ETH', + decimals: 18, + } + } else { + return { + address: formatAddress(address), + symbol: symbol, + decimals: Number(decimals), + } + } +} + +function getPoolLink(chain, poolIndex) { + let chainId = 1 + if (chain === 'arbitrum') chainId = 42161; + if (chain === 'polygon') chainId = 137; + if (chain === 'base') chainId = 8453; + + return `https://fluid.io/stats/${chainId}/dex#${poolIndex}`; +} + +const main = async (unixTimestamp) => { + const yieldPools = [] + + const timestamp = unixTimestamp ? unixTimestamp : Math.floor(new Date().getTime() / 1000); + const currentBlocks = await sdk.blocks.getBlocks(timestamp, Object.keys(DexReservesResolvers)) + const last1DaysBlocks = await sdk.blocks.getBlocks(timestamp - 24 * 60 * 60, Object.keys(DexReservesResolvers)) + const last7DaysBlocks = await sdk.blocks.getBlocks(timestamp - 7 * 24 * 60 * 60, Object.keys(DexReservesResolvers)) + + for (const [chain, dexResolver] of Object.entries(DexReservesResolvers)) { + const currentBlock = currentBlocks.chainBlocks[chain]; + const last1DaysBlock = last1DaysBlocks.chainBlocks[chain]; + const last7DaysBlock = last7DaysBlocks.chainBlocks[chain]; + + const rawPoolReserves = (await sdk.api2.abi.call({ + chain: chain, + target: DexReservesResolvers[chain], + abi: abis.find(item => item.name === 'getAllPoolsReserves'), + })) + + const allTokens = {}; + const allDexPools = {}; + for (const pool of rawPoolReserves) { + const [symbols, decimals] = await Promise.all([ + sdk.api2.abi.multiCall({ + chain: chain, + abi: 'string:symbol', + calls: [pool.token0, pool.token1], + permitFailure: true, + }), + sdk.api2.abi.multiCall({ + chain: chain, + abi: 'uint8:decimals', + calls: [pool.token0, pool.token1], + permitFailure: true, + }), + ]); + + const poolAddress = formatAddress(pool.pool); + const token0 = getTokenInfo(chain, pool.token0, symbols[0], decimals[0]); + const token1 = getTokenInfo(chain, pool.token1, symbols[1], decimals[1]); + const feeRate = Number(pool.fee) / 1e6; + + allTokens[token0.address] = token0; + allTokens[token1.address] = token1; + allDexPools[poolAddress] = { + pool: poolAddress, + token0, + token1, + feeRate, + reserve0: Number(pool.collateralReserves.token0RealReserves) + Number(pool.debtReserves.token0RealReserves), + reserve1: Number(pool.collateralReserves.token1RealReserves) + Number(pool.debtReserves.token1RealReserves), + + // will fill below + tvlUsd: 0, + volumeUsd1d: 0, + volumeUsd7d: 0, + } + } + + // get token price from llama coins api + const coinLists = Object.keys(allTokens).map(token => `${chain}:${token}`); + const coinPrices = (await superagent.get(`https://coins.llama.fi/prices/current/${coinLists.toString()}`)).body.coins; + for (const [coinId, coinPrice] of Object.entries(coinPrices)) { + allTokens[formatAddress(coinId.split(':')[1])].price = Number(coinPrice.price); + } + + for (const [address, dexPool] of Object.entries(allDexPools)) { + const token0Price = allTokens[dexPool.token0.address].price ? allTokens[dexPool.token0.address].price : 0; + const token1Price = allTokens[dexPool.token1.address].price ? allTokens[dexPool.token1.address].price : 0; + const token0Reserve = dexPool.reserve0 * token0Price / 10**dexPool.token0.decimals; + const token1Reserve = dexPool.reserve1 * token1Price / 10**dexPool.token1.decimals; + + // update pool tvl USD + allDexPools[address].tvlUsd = token0Reserve + token1Reserve; + } + + const iface = new ethers.utils.Interface([EventSwap]) + const swapLogs = (await sdk.getEventLogs({ + chain: chain, + eventAbi: EventSwap, + targets: Object.keys(allDexPools), + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + })).map(log => { + const event = iface.parseLog({ + topics: log.topics, + data: log.data, + }); + + return { + address: formatAddress(log.address), + blockNumber: Number(log.blockNumber), + args: { + swap0to1: event.args.swap0to1, + amountIn: Number(event.args.amountIn), + amountOut: Number(event.args.amountOut), + } + } + }); + + for (const log of swapLogs) { + let volumeUsd = 0; + const dexPool = allDexPools[log.address]; + if (log.args.swap0to1) { + const tokenPrice = allTokens[dexPool.token0.address].price ? allTokens[dexPool.token0.address].price : 0; + volumeUsd = Number(log.args.amountIn) * tokenPrice / 10**dexPool.token0.decimals; + } else { + const tokenPrice = allTokens[dexPool.token1.address].price ? allTokens[dexPool.token1.address].price : 0; + volumeUsd = Number(log.args.amountIn) * tokenPrice / 10**dexPool.token1.decimals; + } + + if (log.blockNumber >= last1DaysBlock) { + allDexPools[log.address].volumeUsd1d += volumeUsd; + } + allDexPools[log.address].volumeUsd7d += volumeUsd; + } + + for (const p of Object.values(allDexPools).filter(pool => pool.tvlUsd > 0)) { + const feeUsd = p.volumeUsd1d * p.feeRate; + const feeUsd7d = p.volumeUsd7d * p.feeRate; + + yieldPools.push({ + chain: utils.formatChain(chain), + project: PROJECT, + pool: `${chain}-${p.pool}`, // there are same pools addresses + symbol: utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`), + underlyingTokens: [p.token0.address, p.token1.address], + tvlUsd: p.tvlUsd, + apyBase: feeUsd * 100 * 365 / p.tvlUsd, + apyBase7d: feeUsd7d * 100 * 365 / 7 / p.tvlUsd, + volumeUsd1d: p.volumeUsd1d, + volumeUsd7d: p.volumeUsd7d, + url: getPoolLink(chain, Object.keys(allDexPools).indexOf(p.pool) + 1), + }) + } + } + + return yieldPools; +}; + +module.exports = { + timetravel: true, + apy: main, +}; diff --git a/src/adaptors/fluid-lending/abiLendingResolver.js b/src/adaptors/fluid-lending/abiLendingResolver.js new file mode 100644 index 0000000000..a71402a07d --- /dev/null +++ b/src/adaptors/fluid-lending/abiLendingResolver.js @@ -0,0 +1,297 @@ +module.exports = [ + { + inputs: [ + { internalType: 'contract IFluidLendingFactory', name: 'lendingFactory_', type: 'address' }, + { internalType: 'contract IFluidLiquidityResolver', name: 'liquidityResolver_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'FluidLendingResolver__AddressZero', type: 'error' }, + { + inputs: [], + name: 'LENDING_FACTORY', + outputs: [{ internalType: 'contract IFluidLendingFactory', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LIQUIDITY_RESOLVER', + outputs: [{ internalType: 'contract IFluidLiquidityResolver', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset_', type: 'address' }, + { internalType: 'string', name: 'fTokenType_', type: 'string' }, + ], + name: 'computeFToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllFTokenTypes', + outputs: [{ internalType: 'string[]', name: '', type: 'string[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllFTokens', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IFToken', name: 'fToken_', type: 'address' }], + name: 'getFTokenDetails', + outputs: [ + { + components: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'bool', name: 'eip2612Deposits', type: 'bool' }, + { internalType: 'bool', name: 'isNativeUnderlying', type: 'bool' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'totalAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToShares', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardsRate', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyRate', type: 'uint256' }, + { internalType: 'int256', name: 'rebalanceDifference', type: 'int256' }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'lastUpdateTimestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'expandPercent', type: 'uint256' }, + { internalType: 'uint256', name: 'expandDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'baseWithdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawableUntilLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawable', type: 'uint256' }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.FTokenDetails', + name: 'fTokenDetails_', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IFToken', name: 'fToken_', type: 'address' }], + name: 'getFTokenInternalData', + outputs: [ + { internalType: 'contract IFluidLiquidity', name: 'liquidity_', type: 'address' }, + { internalType: 'contract IFluidLendingFactory', name: 'lendingFactory_', type: 'address' }, + { internalType: 'contract IFluidLendingRewardsRateModel', name: 'lendingRewardsRateModel_', type: 'address' }, + { internalType: 'contract IAllowanceTransfer', name: 'permit2_', type: 'address' }, + { internalType: 'address', name: 'rebalancer_', type: 'address' }, + { internalType: 'bool', name: 'rewardsActive_', type: 'bool' }, + { internalType: 'uint256', name: 'liquidityBalance_', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityExchangePrice_', type: 'uint256' }, + { internalType: 'uint256', name: 'tokenExchangePrice_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IFToken', name: 'fToken_', type: 'address' }], + name: 'getFTokenRewards', + outputs: [ + { internalType: 'contract IFluidLendingRewardsRateModel', name: 'rewardsRateModel_', type: 'address' }, + { internalType: 'uint256', name: 'rewardsRate_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IFToken', name: 'fToken_', type: 'address' }], + name: 'getFTokenRewardsRateModelConfig', + outputs: [ + { internalType: 'uint256', name: 'duration_', type: 'uint256' }, + { internalType: 'uint256', name: 'startTime_', type: 'uint256' }, + { internalType: 'uint256', name: 'endTime_', type: 'uint256' }, + { internalType: 'uint256', name: 'startTvl_', type: 'uint256' }, + { internalType: 'uint256', name: 'maxRate_', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardAmount_', type: 'uint256' }, + { internalType: 'address', name: 'initiator_', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getFTokensEntireData', + outputs: [ + { + components: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'bool', name: 'eip2612Deposits', type: 'bool' }, + { internalType: 'bool', name: 'isNativeUnderlying', type: 'bool' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'totalAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToShares', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardsRate', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyRate', type: 'uint256' }, + { internalType: 'int256', name: 'rebalanceDifference', type: 'int256' }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'lastUpdateTimestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'expandPercent', type: 'uint256' }, + { internalType: 'uint256', name: 'expandDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'baseWithdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawableUntilLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawable', type: 'uint256' }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.FTokenDetails[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IFToken', name: 'fToken_', type: 'address' }, + { internalType: 'uint256', name: 'assets_', type: 'uint256' }, + { internalType: 'uint256', name: 'shares_', type: 'uint256' }, + ], + name: 'getPreviews', + outputs: [ + { internalType: 'uint256', name: 'previewDeposit_', type: 'uint256' }, + { internalType: 'uint256', name: 'previewMint_', type: 'uint256' }, + { internalType: 'uint256', name: 'previewWithdraw_', type: 'uint256' }, + { internalType: 'uint256', name: 'previewRedeem_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IFToken', name: 'fToken_', type: 'address' }, + { internalType: 'address', name: 'user_', type: 'address' }, + ], + name: 'getUserPosition', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'fTokenShares', type: 'uint256' }, + { internalType: 'uint256', name: 'underlyingAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'underlyingBalance', type: 'uint256' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + ], + internalType: 'struct Structs.UserPosition', + name: 'userPosition', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user_', type: 'address' }], + name: 'getUserPositions', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'bool', name: 'eip2612Deposits', type: 'bool' }, + { internalType: 'bool', name: 'isNativeUnderlying', type: 'bool' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'totalAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToShares', type: 'uint256' }, + { internalType: 'uint256', name: 'convertToAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardsRate', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyRate', type: 'uint256' }, + { internalType: 'int256', name: 'rebalanceDifference', type: 'int256' }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'lastUpdateTimestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'expandPercent', type: 'uint256' }, + { internalType: 'uint256', name: 'expandDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'baseWithdrawalLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawableUntilLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawable', type: 'uint256' }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.FTokenDetails', + name: 'fTokenDetails', + type: 'tuple', + }, + { + components: [ + { internalType: 'uint256', name: 'fTokenShares', type: 'uint256' }, + { internalType: 'uint256', name: 'underlyingAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'underlyingBalance', type: 'uint256' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + ], + internalType: 'struct Structs.UserPosition', + name: 'userPosition', + type: 'tuple', + }, + ], + internalType: 'struct Structs.FTokenDetailsUserPosition[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'auth_', type: 'address' }], + name: 'isLendingFactoryAuth', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'deployer_', type: 'address' }], + name: 'isLendingFactoryDeployer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + ] + \ No newline at end of file diff --git a/src/adaptors/fluid-lending/abiVaultResolver.js b/src/adaptors/fluid-lending/abiVaultResolver.js new file mode 100644 index 0000000000..bf9167a961 --- /dev/null +++ b/src/adaptors/fluid-lending/abiVaultResolver.js @@ -0,0 +1,2267 @@ +module.exports = [ + { + inputs: [ + { internalType: 'address', name: 'factory_', type: 'address' }, + { internalType: 'address', name: 'liquidityResolver_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'FACTORY', + outputs: [ + { + internalType: 'contract IFluidVaultFactory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LIQUIDITY_RESOLVER', + outputs: [ + { + internalType: 'contract IFluidLiquidityResolver', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'slot_', type: 'uint256' }, + { internalType: 'int256', name: 'key1_', type: 'int256' }, + { internalType: 'uint256', name: 'key2_', type: 'uint256' }, + ], + name: 'calculateDoubleIntUintMapping', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'slot_', type: 'uint256' }, + { internalType: 'int256', name: 'key_', type: 'int256' }, + ], + name: 'calculateStorageSlotIntMapping', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'slot_', type: 'uint256' }, + { internalType: 'uint256', name: 'key_', type: 'uint256' }, + ], + name: 'calculateStorageSlotUintMapping', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getAbsorbedDustDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getAbsorbedLiquidityRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllVaultsAddresses', + outputs: [ + { internalType: 'address[]', name: 'vaults_', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllVaultsLiquidation', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'token0In', type: 'address' }, + { internalType: 'address', name: 'token0Out', type: 'address' }, + { internalType: 'address', name: 'token1In', type: 'address' }, + { internalType: 'address', name: 'token1Out', type: 'address' }, + { internalType: 'uint256', name: 'inAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'outAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'inAmtWithAbsorb', type: 'uint256' }, + { + internalType: 'uint256', + name: 'outAmtWithAbsorb', + type: 'uint256', + }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.LiquidationStruct[]', + name: 'liquidationsData_', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'uint256', name: 'branch_', type: 'uint256' }, + ], + name: 'getBranchDataRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'uint256', name: 'index_', type: 'uint256' }, + ], + name: 'getContractForDeployerIndex', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getDexFromAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'vaults_', type: 'address[]' }, + { internalType: 'uint256[]', name: 'tokensInAmt_', type: 'uint256[]' }, + ], + name: 'getMultipleVaultsLiquidation', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'token0In', type: 'address' }, + { internalType: 'address', name: 'token0Out', type: 'address' }, + { internalType: 'address', name: 'token1In', type: 'address' }, + { internalType: 'address', name: 'token1Out', type: 'address' }, + { internalType: 'uint256', name: 'inAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'outAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'inAmtWithAbsorb', type: 'uint256' }, + { + internalType: 'uint256', + name: 'outAmtWithAbsorb', + type: 'uint256', + }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.LiquidationStruct[]', + name: 'liquidationsData_', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'uint256', name: 'positionId_', type: 'uint256' }, + ], + name: 'getPositionDataRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getRateRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getRebalancer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'int256', name: 'tick_', type: 'int256' }, + ], + name: 'getTickDataRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'int256', name: 'key_', type: 'int256' }, + ], + name: 'getTickHasDebtRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'int256', name: 'tick_', type: 'int256' }, + { internalType: 'uint256', name: 'id_', type: 'uint256' }, + ], + name: 'getTickIdDataRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'nftId_', type: 'uint256' }], + name: 'getTokenConfig', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTotalVaults', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultAbsorb', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.AbsorbStruct', + name: 'absorbData_', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'vaultId_', type: 'uint256' }], + name: 'getVaultAddress', + outputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultEntireData', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'isSmartCol', type: 'bool' }, + { internalType: 'bool', name: 'isSmartDebt', type: 'bool' }, + { + components: [ + { internalType: 'address', name: 'liquidity', type: 'address' }, + { internalType: 'address', name: 'factory', type: 'address' }, + { + internalType: 'address', + name: 'operateImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'adminImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'secondaryImplementation', + type: 'address', + }, + { internalType: 'address', name: 'deployer', type: 'address' }, + { internalType: 'address', name: 'supply', type: 'address' }, + { internalType: 'address', name: 'borrow', type: 'address' }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'supplyToken', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'borrowToken', + type: 'tuple', + }, + { internalType: 'uint256', name: 'vaultId', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultType', type: 'uint256' }, + { + internalType: 'bytes32', + name: 'supplyExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'borrowExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userSupplySlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userBorrowSlot', + type: 'bytes32', + }, + ], + internalType: 'struct IFluidVault.ConstantViews', + name: 'constantVariables', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'supplyRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'borrowRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'collateralFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationThreshold', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationMaxLimit', + type: 'uint16', + }, + { internalType: 'uint16', name: 'withdrawalGap', type: 'uint16' }, + { + internalType: 'uint16', + name: 'liquidationPenalty', + type: 'uint16', + }, + { internalType: 'uint16', name: 'borrowFee', type: 'uint16' }, + { internalType: 'address', name: 'oracle', type: 'address' }, + { + internalType: 'uint256', + name: 'oraclePriceOperate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oraclePriceLiquidate', + type: 'uint256', + }, + { internalType: 'address', name: 'rebalancer', type: 'address' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct Structs.Configs', + name: 'configs', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'lastStoredLiquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredLiquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRateLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRateLiquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'supplyRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'borrowRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateSupply', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateBorrow', + type: 'int256', + }, + ], + internalType: 'struct Structs.ExchangePricesAndRates', + name: 'exchangePricesAndRates', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupplyVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupplyLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedBorrow', + type: 'uint256', + }, + ], + internalType: 'struct Structs.TotalSupplyAndBorrow', + name: 'totalSupplyAndBorrow', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'withdrawLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minimumBorrowing', + type: 'uint256', + }, + ], + internalType: 'struct Structs.LimitsAndAvailability', + name: 'limitsAndAvailability', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalPositions', + type: 'uint256', + }, + { internalType: 'int256', name: 'topTick', type: 'int256' }, + { + internalType: 'uint256', + name: 'currentBranch', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrow', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'status', type: 'uint256' }, + { + internalType: 'int256', + name: 'minimaTick', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'debtFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'partials', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBranchId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'baseBranchMinima', + type: 'int256', + }, + ], + internalType: 'struct Structs.CurrentBranchState', + name: 'currentBranchState', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultState', + name: 'vaultState', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'withdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseWithdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserBorrowData', + name: 'liquidityUserBorrowData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultEntireData', + name: 'vaultData_', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultId', + outputs: [{ internalType: 'uint256', name: 'id_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { internalType: 'uint256', name: 'tokenInAmt_', type: 'uint256' }, + ], + name: 'getVaultLiquidation', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'token0In', type: 'address' }, + { internalType: 'address', name: 'token0Out', type: 'address' }, + { internalType: 'address', name: 'token1In', type: 'address' }, + { internalType: 'address', name: 'token1Out', type: 'address' }, + { internalType: 'uint256', name: 'inAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'outAmt', type: 'uint256' }, + { internalType: 'uint256', name: 'inAmtWithAbsorb', type: 'uint256' }, + { + internalType: 'uint256', + name: 'outAmtWithAbsorb', + type: 'uint256', + }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.LiquidationStruct', + name: 'liquidationData_', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultState', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'totalPositions', type: 'uint256' }, + { internalType: 'int256', name: 'topTick', type: 'int256' }, + { internalType: 'uint256', name: 'currentBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrow', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'status', type: 'uint256' }, + { internalType: 'int256', name: 'minimaTick', type: 'int256' }, + { internalType: 'uint256', name: 'debtFactor', type: 'uint256' }, + { internalType: 'uint256', name: 'partials', type: 'uint256' }, + { + internalType: 'uint256', + name: 'debtLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBranchId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'baseBranchMinima', + type: 'int256', + }, + ], + internalType: 'struct Structs.CurrentBranchState', + name: 'currentBranchState', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultState', + name: 'vaultState_', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultType', + outputs: [{ internalType: 'uint256', name: 'vaultType_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultVariables2Raw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + name: 'getVaultVariablesRaw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVaultsAbsorb', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.AbsorbStruct[]', + name: 'absorbData_', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address[]', name: 'vaults_', type: 'address[]' }], + name: 'getVaultsAbsorb', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'absorbAvailable', type: 'bool' }, + ], + internalType: 'struct Structs.AbsorbStruct[]', + name: 'absorbData_', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getVaultsEntireData', + outputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'isSmartCol', type: 'bool' }, + { internalType: 'bool', name: 'isSmartDebt', type: 'bool' }, + { + components: [ + { internalType: 'address', name: 'liquidity', type: 'address' }, + { internalType: 'address', name: 'factory', type: 'address' }, + { + internalType: 'address', + name: 'operateImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'adminImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'secondaryImplementation', + type: 'address', + }, + { internalType: 'address', name: 'deployer', type: 'address' }, + { internalType: 'address', name: 'supply', type: 'address' }, + { internalType: 'address', name: 'borrow', type: 'address' }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'supplyToken', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'borrowToken', + type: 'tuple', + }, + { internalType: 'uint256', name: 'vaultId', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultType', type: 'uint256' }, + { + internalType: 'bytes32', + name: 'supplyExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'borrowExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userSupplySlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userBorrowSlot', + type: 'bytes32', + }, + ], + internalType: 'struct IFluidVault.ConstantViews', + name: 'constantVariables', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'supplyRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'borrowRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'collateralFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationThreshold', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationMaxLimit', + type: 'uint16', + }, + { internalType: 'uint16', name: 'withdrawalGap', type: 'uint16' }, + { + internalType: 'uint16', + name: 'liquidationPenalty', + type: 'uint16', + }, + { internalType: 'uint16', name: 'borrowFee', type: 'uint16' }, + { internalType: 'address', name: 'oracle', type: 'address' }, + { + internalType: 'uint256', + name: 'oraclePriceOperate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oraclePriceLiquidate', + type: 'uint256', + }, + { internalType: 'address', name: 'rebalancer', type: 'address' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct Structs.Configs', + name: 'configs', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'lastStoredLiquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredLiquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRateLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRateLiquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'supplyRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'borrowRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateSupply', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateBorrow', + type: 'int256', + }, + ], + internalType: 'struct Structs.ExchangePricesAndRates', + name: 'exchangePricesAndRates', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupplyVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupplyLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedBorrow', + type: 'uint256', + }, + ], + internalType: 'struct Structs.TotalSupplyAndBorrow', + name: 'totalSupplyAndBorrow', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'withdrawLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minimumBorrowing', + type: 'uint256', + }, + ], + internalType: 'struct Structs.LimitsAndAvailability', + name: 'limitsAndAvailability', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalPositions', + type: 'uint256', + }, + { internalType: 'int256', name: 'topTick', type: 'int256' }, + { + internalType: 'uint256', + name: 'currentBranch', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrow', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'status', type: 'uint256' }, + { + internalType: 'int256', + name: 'minimaTick', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'debtFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'partials', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBranchId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'baseBranchMinima', + type: 'int256', + }, + ], + internalType: 'struct Structs.CurrentBranchState', + name: 'currentBranchState', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultState', + name: 'vaultState', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'withdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseWithdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserBorrowData', + name: 'liquidityUserBorrowData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultEntireData[]', + name: 'vaultsData_', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'slot_', type: 'uint256' }], + name: 'normalSlot', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'nftId_', type: 'uint256' }], + name: 'positionByNftId', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'nftId', type: 'uint256' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'bool', name: 'isLiquidated', type: 'bool' }, + { internalType: 'bool', name: 'isSupplyPosition', type: 'bool' }, + { internalType: 'int256', name: 'tick', type: 'int256' }, + { internalType: 'uint256', name: 'tickId', type: 'uint256' }, + { internalType: 'uint256', name: 'beforeSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'beforeBorrow', type: 'uint256' }, + { + internalType: 'uint256', + name: 'beforeDustBorrow', + type: 'uint256', + }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'dustBorrow', type: 'uint256' }, + ], + internalType: 'struct Structs.UserPosition', + name: 'userPosition_', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'isSmartCol', type: 'bool' }, + { internalType: 'bool', name: 'isSmartDebt', type: 'bool' }, + { + components: [ + { internalType: 'address', name: 'liquidity', type: 'address' }, + { internalType: 'address', name: 'factory', type: 'address' }, + { + internalType: 'address', + name: 'operateImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'adminImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'secondaryImplementation', + type: 'address', + }, + { internalType: 'address', name: 'deployer', type: 'address' }, + { internalType: 'address', name: 'supply', type: 'address' }, + { internalType: 'address', name: 'borrow', type: 'address' }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'supplyToken', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'borrowToken', + type: 'tuple', + }, + { internalType: 'uint256', name: 'vaultId', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultType', type: 'uint256' }, + { + internalType: 'bytes32', + name: 'supplyExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'borrowExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userSupplySlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userBorrowSlot', + type: 'bytes32', + }, + ], + internalType: 'struct IFluidVault.ConstantViews', + name: 'constantVariables', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'supplyRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'borrowRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'collateralFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationThreshold', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationMaxLimit', + type: 'uint16', + }, + { internalType: 'uint16', name: 'withdrawalGap', type: 'uint16' }, + { + internalType: 'uint16', + name: 'liquidationPenalty', + type: 'uint16', + }, + { internalType: 'uint16', name: 'borrowFee', type: 'uint16' }, + { internalType: 'address', name: 'oracle', type: 'address' }, + { + internalType: 'uint256', + name: 'oraclePriceOperate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oraclePriceLiquidate', + type: 'uint256', + }, + { internalType: 'address', name: 'rebalancer', type: 'address' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct Structs.Configs', + name: 'configs', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'lastStoredLiquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredLiquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRateLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRateLiquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'supplyRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'borrowRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateSupply', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateBorrow', + type: 'int256', + }, + ], + internalType: 'struct Structs.ExchangePricesAndRates', + name: 'exchangePricesAndRates', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupplyVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupplyLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedBorrow', + type: 'uint256', + }, + ], + internalType: 'struct Structs.TotalSupplyAndBorrow', + name: 'totalSupplyAndBorrow', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'withdrawLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minimumBorrowing', + type: 'uint256', + }, + ], + internalType: 'struct Structs.LimitsAndAvailability', + name: 'limitsAndAvailability', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalPositions', + type: 'uint256', + }, + { internalType: 'int256', name: 'topTick', type: 'int256' }, + { + internalType: 'uint256', + name: 'currentBranch', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrow', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'status', type: 'uint256' }, + { + internalType: 'int256', + name: 'minimaTick', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'debtFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'partials', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBranchId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'baseBranchMinima', + type: 'int256', + }, + ], + internalType: 'struct Structs.CurrentBranchState', + name: 'currentBranchState', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultState', + name: 'vaultState', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'withdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseWithdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserBorrowData', + name: 'liquidityUserBorrowData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultEntireData', + name: 'vaultData_', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user_', type: 'address' }], + name: 'positionsByUser', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'nftId', type: 'uint256' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'bool', name: 'isLiquidated', type: 'bool' }, + { internalType: 'bool', name: 'isSupplyPosition', type: 'bool' }, + { internalType: 'int256', name: 'tick', type: 'int256' }, + { internalType: 'uint256', name: 'tickId', type: 'uint256' }, + { internalType: 'uint256', name: 'beforeSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'beforeBorrow', type: 'uint256' }, + { + internalType: 'uint256', + name: 'beforeDustBorrow', + type: 'uint256', + }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'dustBorrow', type: 'uint256' }, + ], + internalType: 'struct Structs.UserPosition[]', + name: 'userPositions_', + type: 'tuple[]', + }, + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'bool', name: 'isSmartCol', type: 'bool' }, + { internalType: 'bool', name: 'isSmartDebt', type: 'bool' }, + { + components: [ + { internalType: 'address', name: 'liquidity', type: 'address' }, + { internalType: 'address', name: 'factory', type: 'address' }, + { + internalType: 'address', + name: 'operateImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'adminImplementation', + type: 'address', + }, + { + internalType: 'address', + name: 'secondaryImplementation', + type: 'address', + }, + { internalType: 'address', name: 'deployer', type: 'address' }, + { internalType: 'address', name: 'supply', type: 'address' }, + { internalType: 'address', name: 'borrow', type: 'address' }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'supplyToken', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'token0', type: 'address' }, + { internalType: 'address', name: 'token1', type: 'address' }, + ], + internalType: 'struct IFluidVault.Tokens', + name: 'borrowToken', + type: 'tuple', + }, + { internalType: 'uint256', name: 'vaultId', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultType', type: 'uint256' }, + { + internalType: 'bytes32', + name: 'supplyExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'borrowExchangePriceSlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userSupplySlot', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'userBorrowSlot', + type: 'bytes32', + }, + ], + internalType: 'struct IFluidVault.ConstantViews', + name: 'constantVariables', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint16', + name: 'supplyRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'borrowRateMagnifier', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'collateralFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationThreshold', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationMaxLimit', + type: 'uint16', + }, + { internalType: 'uint16', name: 'withdrawalGap', type: 'uint16' }, + { + internalType: 'uint16', + name: 'liquidationPenalty', + type: 'uint16', + }, + { internalType: 'uint16', name: 'borrowFee', type: 'uint16' }, + { internalType: 'address', name: 'oracle', type: 'address' }, + { + internalType: 'uint256', + name: 'oraclePriceOperate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oraclePriceLiquidate', + type: 'uint256', + }, + { internalType: 'address', name: 'rebalancer', type: 'address' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct Structs.Configs', + name: 'configs', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'lastStoredLiquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredLiquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastStoredVaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquiditySupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultSupplyExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultBorrowExchangePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRateLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRateLiquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'supplyRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'borrowRateVault', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateSupply', + type: 'int256', + }, + { + internalType: 'int256', + name: 'rewardsOrFeeRateBorrow', + type: 'int256', + }, + ], + internalType: 'struct Structs.ExchangePricesAndRates', + name: 'exchangePricesAndRates', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupplyVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowVault', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupplyLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowLiquidityOrDex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'absorbedBorrow', + type: 'uint256', + }, + ], + internalType: 'struct Structs.TotalSupplyAndBorrow', + name: 'totalSupplyAndBorrow', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'withdrawLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minimumBorrowing', + type: 'uint256', + }, + ], + internalType: 'struct Structs.LimitsAndAvailability', + name: 'limitsAndAvailability', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalPositions', + type: 'uint256', + }, + { internalType: 'int256', name: 'topTick', type: 'int256' }, + { + internalType: 'uint256', + name: 'currentBranch', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalBranch', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBorrow', type: 'uint256' }, + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'status', type: 'uint256' }, + { + internalType: 'int256', + name: 'minimaTick', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'debtFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'partials', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBranchId', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'baseBranchMinima', + type: 'int256', + }, + ], + internalType: 'struct Structs.CurrentBranchState', + name: 'currentBranchState', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultState', + name: 'vaultState', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'supply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'withdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseWithdrawalLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawableUntilLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawable', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserSupplyData', + name: 'liquidityUserSupplyData', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'modeWithInterest', type: 'bool' }, + { internalType: 'uint256', name: 'borrow', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowLimit', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandPercent', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expandDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxBorrowLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowableUntilLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowable', type: 'uint256' }, + { + internalType: 'uint256', + name: 'borrowLimitUtilization', + type: 'uint256', + }, + ], + internalType: 'struct Structs.UserBorrowData', + name: 'liquidityUserBorrowData', + type: 'tuple', + }, + ], + internalType: 'struct Structs.VaultEntireData[]', + name: 'vaultsData_', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user_', type: 'address' }], + name: 'positionsNftIdOfUser', + outputs: [ + { internalType: 'uint256[]', name: 'nftIds_', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tickRaw_', type: 'uint256' }], + name: 'tickHelper', + outputs: [{ internalType: 'int256', name: 'tick', type: 'int256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalPositions', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'nftId_', type: 'uint256' }], + name: 'vaultByNftId', + outputs: [{ internalType: 'address', name: 'vault_', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +] \ No newline at end of file diff --git a/src/adaptors/fluid-lending/index.js b/src/adaptors/fluid-lending/index.js new file mode 100644 index 0000000000..591db973e1 --- /dev/null +++ b/src/adaptors/fluid-lending/index.js @@ -0,0 +1,267 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +// Constants +const CONSTANTS = { + CHAIN_ID_MAPPING: { + ethereum: 1, + arbitrum: 42161, + base: 8453, + polygon: 137, + }, + SUPPORTED_CHAINS: ['ethereum', 'arbitrum', 'base', 'polygon'], + RESOLVERS: { + LENDING: { + ethereum: '0xC215485C572365AE87f908ad35233EC2572A3BEC', + arbitrum: '0xdF4d3272FfAE8036d9a2E1626Df2Db5863b4b302', + base: '0x3aF6FBEc4a2FE517F56E402C65e3f4c3e18C1D86', + polygon: '0x8e72291D5e6f4AAB552cc827fB857a931Fc5CAC1', + }, + VAULT: { + ethereum: '0x814c8C7ceb1411B364c2940c4b9380e739e06686', + arbitrum: '0xD7D455d387d7840F56C65Bb08aD639DE9244E463', + base: '0x79B3102173EB84E6BCa182C7440AfCa5A41aBcF8', + polygon: '0x9edb8D8b6db9A869c3bd913E44fa416Ca7490aCA', + }, + }, +}; + +// Import ABIs +const abiLendingResolver = require('./abiLendingResolver'); +const abiVaultResolver = require('./abiVaultResolver'); + +// Lending Functions +const getLendingApy = async (chain) => { + try { + const fTokensEntireData = ( + await sdk.api.abi.call({ + target: CONSTANTS.RESOLVERS.LENDING[chain], + abi: abiLendingResolver.find((m) => m.name === 'getFTokensEntireData'), + chain, + }) + ).output; + + const underlying = fTokensEntireData.map((d) => d.asset); + + const [symbol, decimals] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: underlying.map((t) => ({ target: t })), + abi: 'erc20:symbol', + chain, + }), + sdk.api.abi.multiCall({ + calls: underlying.map((t) => ({ target: t })), + abi: 'erc20:decimals', + chain, + }), + ]); + + const priceKeys = underlying.map((i) => `${chain}:${i}`).join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const merkleRewardsTokens = (await axios.get(`https://api.fluid.instadapp.io/${CONSTANTS.CHAIN_ID_MAPPING[chain]}/tokens`)).data.data; + + return fTokensEntireData + .map((token, i) => ({ + project: 'fluid-lending', + pool: `${chain}_${token.tokenAddress}`, + tvlUsd: + (token.totalAssets * prices[`${chain}:${underlying[i]}`].price) / + 10 ** decimals.output[i].output, + symbol: symbol.output[i].output, + underlyingTokens: [token.asset], + rewardTokens: [ + token.asset, + ...merkleRewardsTokens + .find(t => t.address.toLowerCase() === token.tokenAddress.toLowerCase()) + ?.rewards?.map(reward => reward?.token?.address) || [] + ], + chain, + apyBase: Number((token.supplyRate / 1e2).toFixed(2)), + apyReward: (() => { + const nativeRewardsRate = Number((token.rewardsRate / 1e12).toFixed(2)); + const fTokenMerkleData = merkleRewardsTokens.find(t => t.address.toLowerCase() === token.tokenAddress.toLowerCase()); + if (!fTokenMerkleData || !fTokenMerkleData.rewards || fTokenMerkleData.rewards.length === 0) { + return nativeRewardsRate; + } + const merkleRewardsSum = fTokenMerkleData.rewards.reduce((sum, reward) => sum + (reward.rate / 1e2), 0); + return Number((nativeRewardsRate + merkleRewardsSum).toFixed(2)); + })(), + url: `https://fluid.io/lending/${CONSTANTS.CHAIN_ID_MAPPING[chain]}/${symbol.output[i].output}`, + })) + .filter((i) => utils.keepFinite(i)); + } catch (error) { + console.error(`Error fetching lending APY for ${chain}:`, error); + return []; + } +}; + +// Vault Functions +const getVaultApy = async (chain) => { + try { + let vaultsEntireData = ( + await sdk.api.abi.call({ + target: CONSTANTS.RESOLVERS.VAULT[chain], + abi: abiVaultResolver.find((m) => m.name === 'getVaultsEntireData'), + chain, + }) + ).output; + + vaultsEntireData = vaultsEntireData.map((vault, index) => ({ + ...vault, + VaultId: index + 1, + })); + + const filteredVaults = vaultsEntireData.filter( + (vault) => vault[1] === false && vault[2] === false + ); + + const vaultDetails = { + pools: filteredVaults.map((vault) => vault[0]), + underlyingTokens: filteredVaults.map((vault) => [ + normalizeAddress(vault[3][8][0]), + normalizeAddress(vault[3][9][0]), + ]), + rewardsRates: filteredVaults.map((vault) => Math.max(0, vault[5][12])), + rewardsRatesBorrow: filteredVaults.map((vault) => + Math.max(0, vault[5][13]) + ), + supplyRates: filteredVaults.map((vault) => Math.max(0, vault[5][8])), + supplyRatesBorrow: filteredVaults.map((vault) => + Math.max(0, vault[5][9]) + ), + suppliedTokens: filteredVaults.map((vault) => vault[8][5]), + borrowedTokens: filteredVaults.map((vault) => vault[8][4]), + supplyTokens: filteredVaults.map((vault) => + normalizeAddress(vault[3][8][0]) + ), + borrowTokens: filteredVaults.map((vault) => + normalizeAddress(vault[3][9][0]) + ), + ltv: filteredVaults.map((vault) => normalizeAddress(vault[4][2])), + }; + + const tokenData = await fetchTokenData(chain, vaultDetails); + + return calculateVaultPoolData( + chain, + filteredVaults, + vaultDetails, + tokenData + ).filter((pool) => utils.keepFinite(pool)); + } catch (error) { + console.error(`Error fetching vault APY for ${chain}:`, error); + return []; + } +}; + +// Helper Functions +const normalizeAddress = (address) => { + const lowercaseAddress = String(address).toLowerCase(); + return lowercaseAddress === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' + ? '0x0000000000000000000000000000000000000000' + : lowercaseAddress; +}; + +const fetchTokenData = async (chain, vaultDetails) => { + const priceKeys = vaultDetails.supplyTokens + .map((token) => `${chain}:${token}`) + .join(','); + const borrowPriceKeys = vaultDetails.underlyingTokens + .map((tokens) => `${chain}:${tokens[1]}`) + .join(','); + + const [prices, borrowPrices] = await Promise.all([ + axios + .get(`https://coins.llama.fi/prices/current/${priceKeys}`) + .then((r) => r.data.coins), + axios + .get(`https://coins.llama.fi/prices/current/${borrowPriceKeys}`) + .then((r) => r.data.coins), + ]); + + return { + symbol: vaultDetails.underlyingTokens.map( + (tokens) => + `${prices[`${chain}:${tokens[0]}`].symbol}/${ + borrowPrices[`${chain}:${tokens[1]}`].symbol + }` + ), + decimals: vaultDetails.supplyTokens.map( + (token) => prices[`${chain}:${token}`].decimals + ), + borrowTokenDecimals: vaultDetails.borrowTokens.map( + (token) => borrowPrices[`${chain}:${token}`].decimals + ), + prices: vaultDetails.supplyTokens.map( + (token) => prices[`${chain}:${token}`].price + ), + borrowTokenPrices: vaultDetails.borrowTokens.map( + (token) => borrowPrices[`${chain}:${token}`].price + ), + }; +}; + +const calculateVaultPoolData = ( + chain, + filteredVaults, + vaultDetails, + tokenData +) => { + const totalSupplyUsd = vaultDetails.suppliedTokens.map( + (suppliedToken, index) => + (suppliedToken * tokenData.prices[index]) / + 10 ** tokenData.decimals[index] + ); + const totalBorrowUsd = vaultDetails.borrowedTokens.map( + (borrowedToken, index) => + (borrowedToken * tokenData.borrowTokenPrices[index]) / + 10 ** tokenData.borrowTokenDecimals[index] + ); + + return filteredVaults.map((vault, index) => { + const s = tokenData.symbol[index].replace('.base', '').split('/'); + const supplySymbol = s[0]; + const borrowSymbol = s[1]; + return { + project: 'fluid-lending', + pool: `${chain}_${vaultDetails.pools[index]}`, + tvlUsd: totalSupplyUsd[index], + totalSupplyUsd: totalSupplyUsd[index], + totalBorrowUsd: totalBorrowUsd[index], + symbol: supplySymbol, + underlyingTokens: vaultDetails.underlyingTokens[index], + rewardTokens: vaultDetails.underlyingTokens[index], + chain, + apyBase: Number((vaultDetails.supplyRates[index] / 1e2).toFixed(2)), + apyBaseBorrow: Number( + (vaultDetails.supplyRatesBorrow[index] / 1e2).toFixed(2) + ), + apyReward: Number((vaultDetails.rewardsRates[index] / 1e12).toFixed(2)), + apyRewardBorrow: Number( + (vaultDetails.rewardsRatesBorrow[index] / 1e12).toFixed(2) + ), + ltv: vaultDetails.ltv[index] / 1e4, + mintedCoin: borrowSymbol, + url: `https://fluid.io/vaults/${CONSTANTS.CHAIN_ID_MAPPING[chain]}/${vault.VaultId}`, + }; + }); +}; + +// Main Function +const apy = async () => { + const [lendingData, vaultData] = await Promise.all([ + Promise.all(CONSTANTS.SUPPORTED_CHAINS.map(getLendingApy)), + Promise.all(CONSTANTS.SUPPORTED_CHAINS.map(getVaultApy)), + ]); + // Combine and flatten both arrays + return [...lendingData.flat(), ...vaultData.flat()]; +}; + +module.exports = { + apy, +}; +// test: npm run test --adapter=fluid-lending diff --git a/src/adaptors/fluid-lite/index.js b/src/adaptors/fluid-lite/index.js new file mode 100644 index 0000000000..2ba8441283 --- /dev/null +++ b/src/adaptors/fluid-lite/index.js @@ -0,0 +1,25 @@ +const utils = require('../utils'); + +const API_URL = + 'https://api.instadapp.io/v2/mainnet/lite/users/0x0000000000000000000000000000000000000000/vaults'; + +const getApy = async () => { + const vaultData = await utils.getData(API_URL); + const pools = vaultData.map((item) => ({ + pool: item.vault, + chain: utils.formatChain('ethereum'), + project: 'fluid-lite', + symbol: item.token.symbol, + tvlUsd: Number(item.vaultTVLInAsset) * item.token.price, + apy: Number(item.apy.apyWithoutFee), + underlyingTokens: [item.tokenAddress], + })); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://lite.instadapp.io/', +}; diff --git a/src/adaptors/flux-finance/abi.js b/src/adaptors/flux-finance/abi.js new file mode 100644 index 0000000000..1a4a4d34cb --- /dev/null +++ b/src/adaptors/flux-finance/abi.js @@ -0,0 +1,2102 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/flux-finance/index.js b/src/adaptors/flux-finance/index.js new file mode 100755 index 0000000000..c10f240e9e --- /dev/null +++ b/src/adaptors/flux-finance/index.js @@ -0,0 +1,213 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x95Af143a021DF745bc78e845b54591C53a8B3A51'; +const CHAIN = 'ethereum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'flux-finance'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => 0; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [], + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + } + return poolReturned; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://fluxfinance.com/markets', +}; diff --git a/src/adaptors/folks-finance-lending/helper/chain/algorand.js b/src/adaptors/folks-finance-lending/helper/chain/algorand.js new file mode 100644 index 0000000000..fcc66da474 --- /dev/null +++ b/src/adaptors/folks-finance-lending/helper/chain/algorand.js @@ -0,0 +1,29 @@ +// documentation: https://developer.algorand.org/docs/get-details/indexer/?from_query=curl#sdk-client-instantiations + +const axios = require('axios'); +const { RateLimiter } = require('limiter'); + +const axiosObj = axios.create({ + baseURL: 'https://mainnet-idx.algonode.cloud', + timeout: 300000, +}); + +const indexerLimiter = new RateLimiter({ + tokensPerInterval: 10, + interval: 'second', +}); + +async function lookupApplications(appId) { + return (await axiosObj.get(`/v2/applications/${appId}`)).data; +} + +const withLimiter = + (fn, tokensToRemove = 1) => + async (...args) => { + await indexerLimiter.removeTokens(tokensToRemove); + return fn(...args); + }; + +module.exports = { + lookupApplications: withLimiter(lookupApplications), +}; diff --git a/src/adaptors/folks-finance-lending/index.js b/src/adaptors/folks-finance-lending/index.js new file mode 100644 index 0000000000..ad10d6e1d2 --- /dev/null +++ b/src/adaptors/folks-finance-lending/index.js @@ -0,0 +1,75 @@ +const constants = require('./v2/constants'); +const { + getStakingProgram, + getPoolsInfo, + getDepositStakingProgramsInfo, + retrieveLoanInfo, +} = require('./v2/index'); +const { interestRateToPercentage, ratioToPercentage } = require('./v2/utils'); +const utils = require('../utils'); + +const { pools } = constants; + +const buildDataSource = async (poolArr, depositsStakingInfo, loanType) => { + const loanAppId = constants.MainnetLoans[loanType]; + const { pools: poolsLoanInfo } = await retrieveLoanInfo(loanAppId); + for (const pool of pools.filter((p) => p.loanType === loanType)) { + const poolInfo = await getPoolsInfo(pool); + const { + depositsUsd, + borrowsUsd, + depositInterestYield, + variableBorrowInterestYield, + } = poolInfo; + const totalSupplyUsd = Number(depositsUsd.toFixed(2)); + const totalBorrowUsd = Number(borrowsUsd.toFixed(2)); + const tvlUsd = Number((depositsUsd - borrowsUsd).toFixed(2)); + const apyBase = interestRateToPercentage(depositInterestYield); + const apyBaseBorrow = interestRateToPercentage(variableBorrowInterestYield); + const ltv = ratioToPercentage(poolsLoanInfo[pool.appId].collateralFactor); + + let dataSource = { + pool: `${pool.appId}-algorand`, + chain: utils.formatChain('algorand'), + project: 'folks-finance-lending', + symbol: utils.formatSymbol(pool.symbol), + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + apyBase, + apyBaseBorrow, + ltv, + }; + + if (pool.hasReward) { + const depositStakingInfo = depositsStakingInfo.find( + (deposit) => deposit.poolAppId === pool.appId + ); + + const dataSourceRewards = await getDepositStakingProgramsInfo( + depositStakingInfo, + poolInfo, + pool + ); + dataSource = { ...dataSource, ...dataSourceRewards }; + } + poolArr.push(dataSource); + } +} + +const poolsFunction = async () => { + let poolArr = []; + + const depositsStakingInfo = await getStakingProgram(); + + await buildDataSource(poolArr, depositsStakingInfo, constants.LoanType.GENERAL); + await buildDataSource(poolArr, depositsStakingInfo, constants.LoanType.ALGORAND_ECOSYSTEM); + + return poolArr; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.folks.finance/', +}; diff --git a/src/adaptors/folks-finance-lending/v2/constants.js b/src/adaptors/folks-finance-lending/v2/constants.js new file mode 100644 index 0000000000..ade6b7e192 --- /dev/null +++ b/src/adaptors/folks-finance-lending/v2/constants.js @@ -0,0 +1,223 @@ + +const LoanType = { + GENERAL: 'GENERAL', + ALGORAND_ECOSYSTEM: 'ALGORAND_ECOSYSTEM', +}; + +const MainnetLoans = { + [LoanType.GENERAL]: 971388781, + [LoanType.ALGORAND_ECOSYSTEM]: 3184333108, +}; + + +const pools = [ + // ALGO + { + appId: 971368268, + assetId: 0, + fAssetId: 971381860, + symbol: 'ALGO', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // gALGO + { + appId: 971370097, + assetId: 793124631, + fAssetId: 971383839, + symbol: 'gALGO', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // xALGO + { + appId: 2611131944, + assetId: 1134696561, + fAssetId: 2611138444, + symbol: 'xALGO', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // tALGO + { + appId: 3073474613, + assetId: 2537013734, + fAssetId: 3073480070, + symbol: 'tALGO', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // USDC + { + appId: 971372237, + assetId: 31566704, + fAssetId: 971384592, + symbol: 'USDC', + hasReward: true, + loanType: LoanType.GENERAL, + }, + // USDt + { + appId: 971372700, + assetId: 312769, + fAssetId: 971385312, + symbol: 'USDt', + hasReward: true, + loanType: LoanType.GENERAL, + }, + // Gard + { + appId: 1060585819, + assetId: 684649988, + fAssetId: 1060587336, + symbol: 'GARD', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // EURS + { + appId: 1247053569, + assetId: 227855942, + fAssetId: 1247054501, + symbol: 'EURS', + hasReward: true, + loanType: LoanType.GENERAL, + }, + // goBTC + { + appId: 971373361, + assetId: 386192725, + fAssetId: 971386173, + symbol: 'goBTC', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // goETH + { + appId: 971373611, + assetId: 386195940, + fAssetId: 971387073, + symbol: 'goETH', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WBTC + { + appId: 1067289273, + assetId: 1058926737, + fAssetId: 1067295154, + symbol: 'WBTC', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WETH + { + appId: 1067289481, + assetId: 887406851, + fAssetId: 1067295558, + symbol: 'WETH', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WAVAX + { + appId: 1166977433, + assetId: 893309613, + fAssetId: 1166979636, + symbol: 'WAVAX', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WSOL + { + appId: 1166980669, + assetId: 887648583, + fAssetId: 1166980820, + symbol: 'WSOL', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WLINK + { + appId: 1216434571, + assetId: 1200094857, + fAssetId: 1216437148, + symbol: 'WLINK', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // GOLD + { + appId: 1258515734, + assetId: 246516580, + fAssetId: 1258524377, + symbol: 'GOLD', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // SILVER + { + appId: 1258524099, + assetId: 246519683, + fAssetId: 1258524381, + symbol: 'SILVER', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // Opul + { + appId: 1044267181, + assetId: 287867876, + fAssetId: 1044269355, + symbol: 'OPUL', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // WMPL + { + appId: 1166982094, + assetId: 1163259470, + fAssetId: 1166982296, + symbol: 'WMPL', + hasReward: false, + loanType: LoanType.GENERAL, + }, + // // ISOLATED_ALGO + { + appId: 3184317016, + assetId: 0, + fAssetId: 3184331013, + symbol: 'ISOLATED_ALGO', + hasReward: false, + loanType: LoanType.ALGORAND_ECOSYSTEM, + }, + // ISOLATED_USDC + { + appId: 3184324594, + assetId: 31566704, + fAssetId: 3184331239, + symbol: 'ISOLATED_USDC', + hasReward: false, + loanType: LoanType.ALGORAND_ECOSYSTEM, + }, + // ISOLATED_TINY + { + appId: 3184325123, + assetId: 2200000000, + fAssetId: 3184331789, + symbol: 'ISOLATED_TINY', + hasReward: true, + loanType: LoanType.ALGORAND_ECOSYSTEM, + }, +]; + +const oracleAppId = 1040271396; +const oracleDecimals = 14; + +module.exports = { + pools, + oracleAppId, + oracleDecimals, + LoanType, + MainnetLoans, +}; diff --git a/src/adaptors/folks-finance-lending/v2/index.js b/src/adaptors/folks-finance-lending/v2/index.js new file mode 100644 index 0000000000..0cafcd3fa4 --- /dev/null +++ b/src/adaptors/folks-finance-lending/v2/index.js @@ -0,0 +1,263 @@ +const { + maximum, + getAppState, + getParsedValueFromState, + calculateInterestYield, + interestRateToPercentage, + calculateVariableBorrowInterestYield, + fromIntToByteHex, + calcDepositInterestIndex, + parseUint64s, + calcWithdrawReturn, + transformPrice, + getRewardInterestRate, +} = require('./utils'); +const { pools } = require('./constants'); +const { getCachedPrices } = require('./prices'); + +const REWARD_APP_ID = 1093729103; + +async function retrievePoolInfo({ poolAppId, poolAssetId }) { + const state = await getAppState(poolAppId); + + if (state === undefined) + return { + depositsUsd: 0, + borrowsUsd: 0, + }; + + const prices = await getCachedPrices(); + const price = prices[poolAssetId]; + if (price === undefined) return { depositsUsd: 0, borrowsUsd: 0 }; + + const varBor = parseUint64s(String(getParsedValueFromState(state, 'v'))); + const stblBor = parseUint64s(String(getParsedValueFromState(state, 's'))); + const interest = parseUint64s(String(getParsedValueFromState(state, 'i'))); + + const variableBorrowAmountUsd = Number(varBor[3]) * transformPrice(price); + const stableBorrowAmountUsd = Number(stblBor[8]) * transformPrice(price); + const borrowsAmountUsd = variableBorrowAmountUsd + stableBorrowAmountUsd; + + const depositsAmountUsd = Number(interest[3]) * transformPrice(price); + + const depositInterestYield = calculateInterestYield(interest[4]); + const depositInterestRate = interest[4]; + + const depositInterestIndex = calcDepositInterestIndex( + interest[4], + interest[5], + interest[6] + ); + + const variableBorrowInterestYield = calculateVariableBorrowInterestYield( + varBor[4] + ); + + // combine + return { + depositsUsd: depositsAmountUsd, + borrowsUsd: borrowsAmountUsd, + depositInterestYield, + depositInterestRate, + depositInterestIndex, + variableBorrowInterestYield, + }; +} + +async function getStakingProgram() { + const state = await getAppState(REWARD_APP_ID); + + if (state === undefined) return; + const stakingPrograms = []; + for (let i = 0; i <= 5; i++) { + const prefix = 'S'.charCodeAt(0).toString(16); + const stakeBase64Value = String( + (0, getParsedValueFromState)( + state, + prefix + (0, fromIntToByteHex)(i), + 'hex' + ) + ); + const stakeValue = Buffer.from(stakeBase64Value, 'base64').toString('hex'); + for (let j = 0; j <= 4; j++) { + const basePos = j * 46; + const rewards = []; + stakingPrograms.push({ + poolAppId: Number('0x' + stakeValue.slice(basePos, basePos + 12)), + totalStaked: BigInt( + '0x' + stakeValue.slice(basePos + 12, basePos + 28) + ), + minTotalStaked: BigInt( + '0x' + stakeValue.slice(basePos + 28, basePos + 44) + ), + stakeIndex: i * 5 + j, + numRewards: Number('0x' + stakeValue.slice(basePos + 44, basePos + 46)), + rewards, + }); + } + } + for (let i = 0; i <= 22; i++) { + const prefix = 'R'.charCodeAt(0).toString(16); + const rewardBase64Value = String( + (0, getParsedValueFromState)( + state, + prefix + (0, fromIntToByteHex)(i), + 'hex' + ) + ); + const rewardValue = Buffer.from(rewardBase64Value, 'base64').toString( + 'hex' + ); + for (let j = 0; j <= (i !== 22 ? 3 : 1); j++) { + const basePos = j * 60; + const stakeIndex = Number(BigInt(i * 4 + j) / BigInt(3)); + const localRewardIndex = Number(BigInt(i * 4 + j) % BigInt(3)); + const { totalStaked, minTotalStaked, rewards, numRewards } = + stakingPrograms[stakeIndex]; + if (localRewardIndex >= numRewards) continue; + const ts = (0, maximum)(totalStaked, minTotalStaked); + const endTimestamp = BigInt( + '0x' + rewardValue.slice(basePos + 12, basePos + 20) + ); + const lu = BigInt('0x' + rewardValue.slice(basePos + 20, basePos + 28)); + const rewardRate = BigInt( + '0x' + rewardValue.slice(basePos + 28, basePos + 44) + ); + const rpt = BigInt('0x' + rewardValue.slice(basePos + 44, basePos + 60)); + const currTime = BigInt((0, Math.floor(Date.now() / 1000))); + const dt = + currTime <= endTimestamp + ? currTime - lu + : lu <= endTimestamp + ? endTimestamp - lu + : BigInt(0); + const rewardPerToken = rpt + (rewardRate * dt) / ts; + + const rewardAssetId = Number( + '0x' + rewardValue.slice(basePos, basePos + 12) + ).toString(); + + rewards.push({ + rewardAssetId, + endTimestamp, + rewardRate, + rewardPerToken, + }); + } + } + + return stakingPrograms.filter((program) => program.poolAppId !== 0); +} + +async function getPoolsInfo(pool) { + const poolInfo = await retrievePoolInfo({ + poolAppId: pool.appId, + poolAssetId: pool.assetId, + }); + return poolInfo; +} + +async function getDepositStakingProgramsInfo( + depositStakingInfo, + poolInfo, + pool +) { + const rewardTokens = []; + let apyReward = 0; + const prices = await getCachedPrices(); + const { poolAppId, totalStaked, minTotalStaked, rewards, stakeIndex } = + depositStakingInfo; + + if (pool === undefined || poolInfo === undefined) + throw Error('Could not find pool ' + poolAppId); + const { assetId, fAssetId } = pool; + const { depositInterestIndex, depositInterestRate, depositInterestYield } = + poolInfo; + + const assetPrice = prices[assetId]; + if (assetPrice === undefined) + throw Error('Could not find asset price ' + assetId); + + const fAssetTotalStakedAmount = maximum(totalStaked, minTotalStaked); + const assetTotalStakedAmount = calcWithdrawReturn( + fAssetTotalStakedAmount, + depositInterestIndex + ); + + rewards.forEach( + ({ rewardAssetId, endTimestamp, rewardRate, rewardPerToken }) => { + const rewardAssetPrice = prices[rewardAssetId]; + if (rewardAssetPrice === undefined) + throw Error('Could not find asset price ' + rewardAssetId); + + const stakedAmountValue = assetTotalStakedAmount * assetPrice; + const rewardInterestRate = getRewardInterestRate( + stakedAmountValue, + rewardRate, + rewardAssetPrice, + endTimestamp + ); + rewardTokens.push(rewardAssetId.toString()); + apyReward += interestRateToPercentage(rewardInterestRate); + } + ); + return { apyReward, rewardTokens }; +} + +async function retrieveLoanInfo(loanAppId = 971388781) { + const state = await getAppState(loanAppId); + if (state === undefined) throw Error('Could not find Loan'); + + const paramsBase64Value = String(getParsedValueFromState(state, 'pa')); + const paramsValue = Buffer.from(paramsBase64Value, 'base64').toString('hex'); + const canSwapCollateral = Boolean(BigInt('0x' + paramsValue.slice(96, 98))); + + const pools = {}; + for (let i = 0; i < 63; i++) { + const poolBase64Value = String( + getParsedValueFromState(state, fromIntToByteHex(i), 'hex') + ); + const poolValue = Buffer.from(poolBase64Value, 'base64').toString('hex'); + + for (let j = 0; j < 3; j++) { + const basePos = j * 84; + const poolAppId = Number('0x' + poolValue.slice(basePos, basePos + 16)); + // add pool + if (poolAppId > 0) { + pools[poolAppId] = { + poolAppId, + assetId: Number('0x' + poolValue.slice(basePos + 16, basePos + 32)), + collateralCap: BigInt( + '0x' + poolValue.slice(basePos + 32, basePos + 48) + ), + collateralUsed: BigInt( + '0x' + poolValue.slice(basePos + 48, basePos + 64) + ), + collateralFactor: BigInt( + '0x' + poolValue.slice(basePos + 64, basePos + 68) + ), + borrowFactor: BigInt( + '0x' + poolValue.slice(basePos + 68, basePos + 72) + ), + liquidationMax: BigInt( + '0x' + poolValue.slice(basePos + 72, basePos + 76) + ), + liquidationBonus: BigInt( + '0x' + poolValue.slice(basePos + 76, basePos + 80) + ), + liquidationFee: BigInt( + '0x' + poolValue.slice(basePos + 80, basePos + 84) + ), + }; + } + } + } + return { canSwapCollateral, pools }; +} + +module.exports = { + getStakingProgram, + getPoolsInfo, + getDepositStakingProgramsInfo, + retrieveLoanInfo, +}; diff --git a/src/adaptors/folks-finance-lending/v2/prices.js b/src/adaptors/folks-finance-lending/v2/prices.js new file mode 100644 index 0000000000..574835e0da --- /dev/null +++ b/src/adaptors/folks-finance-lending/v2/prices.js @@ -0,0 +1,92 @@ +const { oracleAppId, oracleDecimals } = require('./constants'); +const { + getAppState, + getParsedValueFromState, + fromIntToBytes8Hex, + parseOracleValue, +} = require('./utils'); + +function decodeUint64(data, decodingMode = 'safe') { + if ( + decodingMode !== 'safe' && + decodingMode !== 'mixed' && + decodingMode !== 'bigint' + ) { + throw new Error(`Unknown decodingMode option: ${decodingMode}`); + } + + if (data.byteLength === 0 || data.byteLength > 8) { + throw new Error( + `Data has unacceptable length. Expected length is between 1 and 8, got ${data.byteLength}` + ); + } + + // insert 0s at the beginning if data is smaller than 8 bytes + const padding = Buffer.allocUnsafe(8 - data.byteLength); + padding.fill(0); + + const buf = Buffer.concat([padding, Buffer.from(data)]); + + const num = buf.readBigUInt64BE(); + const isBig = num > Number.MAX_SAFE_INTEGER; + + if (decodingMode === 'safe') { + if (isBig) { + throw new Error( + `Integer exceeds maximum safe integer: ${num.toString()}. Try decoding with "mixed" or "safe" decodingMode.` + ); + } + return Number(num); + } + + if (decodingMode === 'mixed' && !isBig) { + return Number(num); + } + + return num; +} + +let pricesCache; + +async function getCachedPrices() { + if (!pricesCache) pricesCache = getPrices(); + return pricesCache; +} + +/* Get prices from oracle */ +async function getPrices() { + const oracleState = await getAppState(oracleAppId); + + const prices = {}; + + // get the assets for which we need to retrieve their prices + const assets = oracleState + .filter(({ key }) => { + // remove non asset ids global state + key = Buffer.from(key, 'base64').toString('utf8'); + return ( + key !== 'updater_addr' && + key !== 'admin' && + key !== 'tinyman_validator_app_id' + ); + }) + .map(({ key }) => { + // convert key to asset id + return decodeUint64(Buffer.from(key, 'base64'), 'safe'); + }); + + // retrieve asset prices + assets.forEach((assetId) => { + const assetPrice = parseOracleValue( + String( + getParsedValueFromState(oracleState, fromIntToBytes8Hex(assetId), 'hex') + ) + ); + + prices[assetId] =assetPrice; + }); + + return prices; +} + +module.exports = { getCachedPrices }; diff --git a/src/adaptors/folks-finance-lending/v2/utils.js b/src/adaptors/folks-finance-lending/v2/utils.js new file mode 100644 index 0000000000..39b0f9d9e9 --- /dev/null +++ b/src/adaptors/folks-finance-lending/v2/utils.js @@ -0,0 +1,178 @@ +const { lookupApplications } = require('../helper/chain/algorand'); +const { oracleDecimals } = require('./constants'); + +const SECONDS_IN_YEAR = BigInt(365 * 24 * 60 * 60); +const HOURS_IN_YEAR = BigInt(365 * 24); + +const ONE_2_DP = BigInt(1e2); +const ONE_4_DP = BigInt(1e4); +const ONE_10_DP = BigInt(1e10); +const ONE_14_DP = BigInt(1e14); +const ONE_16_DP = BigInt(1e16); + +const UINT64 = BigInt(2) << BigInt(63); +const UINT128 = BigInt(2) << BigInt(127); + +function maximum(n1, n2) { + return n1 > n2 ? n1 : n2; +} + +function fromIntToBytes8Hex(num) { + return num.toString(16).padStart(16, '0'); +} + +function fromIntToByteHex(num) { + return num.toString(16).padStart(2, '0'); +} + +function encodeToBase64(str, encoding = 'utf8') { + return Buffer.from(str, encoding).toString('base64'); +} + +function parseOracleValue(base64Value) { + const value = Buffer.from(base64Value, 'base64').toString('hex'); + // first 8 bytes are the price + const price = BigInt('0x' + value.slice(0, 16)); + + return price; +} + +function getParsedValueFromState(state, key, encoding = 'utf8') { + const encodedKey = encoding ? encodeToBase64(key, encoding) : key; + const keyValue = state.find((entry) => entry.key === encodedKey); + if (keyValue === undefined) return; + const { value } = keyValue; + if (value.type === 1) return value.bytes; + if (value.type === 2) return BigInt(value.uint); + return; +} + +async function getAppState(appId) { + const res = await lookupApplications(appId); + return res.application.params['global-state']; +} + +/** + * Calculate the sqrt of a bigint (rounded down to nearest integer) + * @param value value to be square-rooted + * @return bigint sqrt + */ +function sqrt(value) { + if (value < BigInt(0)) + throw Error('square root of negative numbers is not supported'); + + if (value < BigInt(2)) return value; + + function newtonIteration(n, x0) { + const x1 = (n / x0 + x0) >> BigInt(1); + if (x0 === x1 || x0 === x1 - BigInt(1)) return x0; + return newtonIteration(n, x1); + } + + return newtonIteration(value, BigInt(1)); +} + +function mulScale(n1, n2, scale) { + return (n1 * n2) / scale; +} + +function expBySquaring(x, n, scale) { + if (n === BigInt(0)) return scale; + + let y = scale; + while (n > BigInt(1)) { + if (n % BigInt(2)) { + y = mulScale(x, y, scale); + n = (n - BigInt(1)) / BigInt(2); + } else { + n = n / BigInt(2); + } + x = mulScale(x, x, scale); + } + return mulScale(x, y, scale); +} + +function calculateInterestYield(value) { + return ( + expBySquaring(ONE_16_DP + value / HOURS_IN_YEAR, HOURS_IN_YEAR, ONE_16_DP) - + ONE_16_DP + ); +} + +function calculateVariableBorrowInterestYield(value) { + return ( + expBySquaring( + ONE_16_DP + value / SECONDS_IN_YEAR, + SECONDS_IN_YEAR, + ONE_16_DP + ) - ONE_16_DP + ); +} + +function interestRateToPercentage(interestRate, decimals = 2) { + const percentage = Number(interestRate) / Number(ONE_14_DP); + return Number(percentage.toFixed(decimals)); +} + +function ratioToPercentage(ratio) { + const percentage = Number(ratio) / Number(ONE_4_DP); + return Number(percentage.toFixed(2)); +} + +function calcDepositInterestIndex(dirt1, diit1, latestUpdate) { + const dt = BigInt(unixTime()) - latestUpdate; + return mulScale(diit1, ONE_16_DP + (dirt1 * dt) / SECONDS_IN_YEAR, ONE_16_DP); +} + +function unixTime() { + return Math.floor(Date.now() / 1000); +} + +function parseUint64s(base64Value) { + const value = Buffer.from(base64Value, 'base64').toString('hex'); + + // uint64s are 8 bytes each + const uint64s = []; + for (let i = 0; i < value.length; i += 16) { + uint64s.push(BigInt('0x' + value.slice(i, i + 16))); + } + return uint64s; +} + +function calcWithdrawReturn(withdrawAmount, diit) { + return mulScale(withdrawAmount, diit, ONE_14_DP); +} + +function transformPrice(assetPrice) { + return Number(assetPrice) / 10 ** oracleDecimals; +} + +function getRewardInterestRate( + stakedAmountValue, + rewardRate, + rewardAssetPrice, + endTimestamp +) { + return unixTime() < endTimestamp && stakedAmountValue !== BigInt(0) + ? (rewardRate * BigInt(1e6) * rewardAssetPrice * SECONDS_IN_YEAR) / + stakedAmountValue + : BigInt(0); +} + +module.exports = { + maximum, + fromIntToBytes8Hex, + fromIntToByteHex, + parseOracleValue, + getParsedValueFromState, + getAppState, + calculateInterestYield, + calculateVariableBorrowInterestYield, + interestRateToPercentage, + calcDepositInterestIndex, + parseUint64s, + calcWithdrawReturn, + transformPrice, + getRewardInterestRate, + ratioToPercentage, +}; diff --git a/src/adaptors/folks-finance-xchain/abis.ts b/src/adaptors/folks-finance-xchain/abis.ts new file mode 100644 index 0000000000..904ad22312 --- /dev/null +++ b/src/adaptors/folks-finance-xchain/abis.ts @@ -0,0 +1,343 @@ +const LoanManagerAbi = { + getLoanPool: { + inputs: [ + { + internalType: 'uint16', + name: 'loanTypeId', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'poolId', + type: 'uint8', + }, + ], + name: 'getLoanPool', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'collateralUsed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowUsed', + type: 'uint256', + }, + { + internalType: 'uint64', + name: 'collateralCap', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'borrowCap', + type: 'uint64', + }, + { + internalType: 'uint16', + name: 'collateralFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'borrowFactor', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationBonus', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'liquidationFee', + type: 'uint16', + }, + { + internalType: 'bool', + name: 'isAdded', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isDeprecated', + type: 'bool', + }, + { + components: [ + { + internalType: 'uint64', + name: 'lastUpdateTimestamp', + type: 'uint64', + }, + { + internalType: 'uint256', + name: 'minimumAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralSpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowSpeed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralRewardIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRewardIndex', + type: 'uint256', + }, + ], + internalType: 'struct LoanManagerState.LoanPoolReward', + name: 'reward', + type: 'tuple', + }, + ], + internalType: 'struct LoanManagerState.LoanPool', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const HubPoolAbi = { + getDepositData: { + inputs: [], + name: 'getDepositData', + outputs: [ + { + components: [ + { + internalType: 'uint16', + name: 'optimalUtilisationRatio', + type: 'uint16', + }, + { + internalType: 'uint256', + name: 'totalAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestIndex', + type: 'uint256', + }, + ], + internalType: 'struct HubPoolState.DepositData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getVariableBorrowData: { + inputs: [], + name: 'getVariableBorrowData', + outputs: [ + { + components: [ + { + internalType: 'uint32', + name: 'vr0', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'vr1', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'vr2', + type: 'uint32', + }, + { + internalType: 'uint256', + name: 'totalAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestIndex', + type: 'uint256', + }, + ], + internalType: 'struct HubPoolState.VariableBorrowData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getStableBorrowData: { + inputs: [], + name: 'getStableBorrowData', + outputs: [ + { + components: [ + { + internalType: 'uint32', + name: 'sr0', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'sr1', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'sr2', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'sr3', + type: 'uint32', + }, + { + internalType: 'uint16', + name: 'optimalStableToTotalDebtRatio', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'rebalanceUpUtilisationRatio', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'rebalanceUpDepositInterestRate', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'rebalanceDownDelta', + type: 'uint16', + }, + { + internalType: 'uint256', + name: 'totalAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'averageInterestRate', + type: 'uint256', + }, + ], + internalType: 'struct HubPoolState.StableBorrowData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getPoolId: { + inputs: [], + name: 'getPoolId', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const RewardsV2Abi = { + getActivePoolEpoch: { + inputs: [ + { + internalType: 'uint8', + name: 'poolId', + type: 'uint8', + }, + ], + name: 'getActivePoolEpoch', + outputs: [ + { + internalType: 'uint16', + name: 'epochIndex', + type: 'uint16', + }, + { + components: [ + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint8', + name: 'rewardTokenId', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'totalRewards', + type: 'uint256', + }, + ], + internalType: 'struct HubRewardsV2.EpochReward[]', + name: 'rewards', + type: 'tuple[]', + }, + ], + internalType: 'struct HubRewardsV2.Epoch', + name: 'epoch', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +module.exports = { + LoanManagerAbi, + HubPoolAbi, + RewardsV2Abi, +}; diff --git a/src/adaptors/folks-finance-xchain/constants.ts b/src/adaptors/folks-finance-xchain/constants.ts new file mode 100644 index 0000000000..5a440700b8 --- /dev/null +++ b/src/adaptors/folks-finance-xchain/constants.ts @@ -0,0 +1,667 @@ +const PROJECT_SLUG = 'folks-finance-xchain'; + +const ONE_18_DP = BigInt(1e18); +const EVERY_HOUR = BigInt(365 * 24); +const EVERY_SECOND = BigInt(365 * 24 * 60 * 60); + +const GENERAL_LOAN_TYPE = 2; + +const loanManagerAddress = '0xF4c542518320F09943C35Db6773b2f9FeB2F847e'; + +const rewardsV2Address = '0x3E85a56C2202Ec067EB4Ac090db3e8149dA46d19'; + +const HubPools = { + avax: { + name: 'Avalanche', + pools: [ + { + // USDC + id: 1, + underlyingSymbol: 'USDC', + poolAddress: '0x88f15e36308ED060d8543DA8E2a5dA0810Efded2', + tokenAddress: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e', + }, + { + // AVAX + id: 2, + underlyingSymbol: 'AVAX', + poolAddress: '0x0259617bE41aDA4D97deD60dAf848Caa6db3F228', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0xe69e068539Ee627bAb1Ce878843a6C76484CBd2c', + }, + { + // sAVAX + id: 3, + underlyingSymbol: 'sAVAX', + poolAddress: '0x7033105d1a527d342bE618ab1F222BB310C8d70b', + tokenAddress: '0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be', + spokeAddress: '0x23a96D92C80E8b926dA40E574d615d9e806A87F6', + }, + { + // wETH_ava + id: 6, + underlyingSymbol: 'WETH.e', + poolAddress: '0x795CcF6f7601edb41E4b3123c778C56F0F19389A', + tokenAddress: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', + spokeAddress: '0x0e563B9fe6D9EF642bDbA20D53ac5137EB0d78DC', + }, + { + // BTCb_ava + id: 8, + underlyingSymbol: 'BTC.b', + poolAddress: '0x1C51AA1516e1156d98075F2F64e259906051ABa9', + tokenAddress: '0x152b9d0fdc40c096757f570a51e494bd4b943e50', + spokeAddress: '0xef7a6EBEDe2ad558DB8c36Df65365b209E5d57dC', + }, + { + // SolvBTC + id: 15, + underlyingSymbol: 'SolvBTC', + poolAddress: '0x307bCEC89624660Ed06C97033EDb7eF49Ab0EB2D', + tokenAddress: '0xbc78D84Ba0c46dFe32cf2895a19939c86b81a777', + }, + { + // JOE + id: 16, + underlyingSymbol: 'JOE', + poolAddress: '0x5e5a2007a8D613C4C98F425097166095C875e6eE', + tokenAddress: '0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd', + spokeAddress: '0x3b1C2eC8B7cdE241E0890C9742C14dD7867aA812', + }, + { + // ggAVAX + id: 17, + underlyingSymbol: 'ggAVAX', + poolAddress: '0xAdA5Be2A259096fd11D00c2b5c1181843eD008DC', + tokenAddress: '0xA25EaF2906FA1a3a13EdAc9B9657108Af7B703e3', + spokeAddress: '0xe53189D00D1b4F231A2a208a7967E0dCaE8Db073', + }, + { + // SHIB + id: 18, + underlyingSymbol: 'SHIB', + poolAddress: '0x9f59642C6733397dF5c2696D3Ac9ceb431b1b573', + tokenAddress: '0x2f643d728926C20269f0A04931dd7b4b6B650204', + }, + { + // aUSD + id: 22, + underlyingSymbol: 'AUSD', + poolAddress: '0xc7DdB440666c144c2F27a3a5156D636Bacfc769C', + tokenAddress: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a', + spokeAddress: '0x666aea026bC606220ec6eb83a83D81881fA48e0f', + }, + { + // savUSD + id: 23, + underlyingSymbol: 'savUSD', + poolAddress: '0xE6B7713854620076B5716E2743262D315bf8609D', + tokenAddress: '0x06d47F3fb376649c3A9Dafe069B3D6E35572219E', + spokeAddress: '0xe396E1246B7341Eb6EDA05DCfef9EaB9E661f80C', + }, + { + // USDt_ava + id: 44, + underlyingSymbol: 'USDt', + poolAddress: '0xA1E1024c49c77297bA6367F624cFbEFC80E697c6', + tokenAddress: '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7', + spokeAddress: '0x66dD1c6bEAdFFcA88365BAdE7928323672323d11', + }, + { + // YBTCB + id: 53, + underlyingSymbol: 'YBTC.B', + poolAddress: '0x13A21bC65844CD530098Ab15431c57078ea90737', + tokenAddress: '0x2cd3CdB3bd68Eea0d3BE81DA707bC0c8743D7335', + }, + { + // USDe_ava + id: 55, + underlyingSymbol: 'USDe', + poolAddress: '0x5431e7f480C4985e9C3FaAcd3Bd1fc7143eAdEFa', + tokenAddress: '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', + spokeAddress: '0x07C911b5a1657126B14C25e697E3d00f3a134A23', + }, + { + // sUSDe_ava + id: 56, + underlyingSymbol: 'sUSDe', + poolAddress: '0x94307E63eF02Cf9B39894553f14b21378Ef20adB', + tokenAddress: '0x211cc4dd073734da055fbf44a2b4667d5e5fe5d2', + spokeAddress: '0x1C7EC7198F297119D4e9f359d91127c8B2f9A9D2', + }, + { + // EURC_ava + id: 57, + underlyingSymbol: 'EURC', + poolAddress: '0x3F87F3B301f031ba59C479EDF067621DcC72DDca', + tokenAddress: '0xc891eb4cbdeff6e073e859e987815ed1505c2acd', + spokeAddress: '0xe47285cc79A8de62DFaED52Abe919B87973294C8', + }, + { + // tETH + id: 58, + underlyingSymbol: 'tETH', + poolAddress: '0x5FE123B659FC5242f46884C37550F05Ef08C816a', + tokenAddress: '0xd09ACb80C1E8f2291862c4978A008791c9167003', + }, + { + // tAVAX + id: 59, + underlyingSymbol: 'tAVAX', + poolAddress: '0x3F63A6401e6354a486e6a38127409fD16e222B59', + tokenAddress: '0x14A84F1a61cCd7D1BE596A6cc11FE33A36Bc1646', + spokeAddress: '0x0aeE2B84bd3E280CFcc9325917bFA0Bb20F3cdC6', + }, + { + // wstLINK + id: 60, + underlyingSymbol: 'wstLINK', + poolAddress: '0x42Bb92684e72707030F59C48FBe5A222A0d8b387', + tokenAddress: '0x601486C8Fdc3aD22745b01c920037d6c036A38B9', + }, + ], + }, + ethereum: { + name: 'Ethereum', + pools: [ + // excluding USDC because bridged + // excluding SolvBTC because bridged + // excluding SHIB because bridged + // excluding YBTCB because bridged + // excluding tETH because bridged + // excluding wstLINK because bridged + { + // ETH_eth + id: 4, + underlyingSymbol: 'ETH', + poolAddress: '0xB6DF8914C084242A19A4C7fb15368be244Da3c75', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0xe3B0e4Db870aA58A24f87d895c62D3dc5CD05883', + }, + { + // wBTC_eth + id: 7, + underlyingSymbol: 'WBTC', + poolAddress: '0x9936812835476504D6Cf495F4F0C718Ec19B3Aff', + tokenAddress: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + spokeAddress: '0xb39c03297E87032fF69f4D42A6698e4c4A934449', + }, + { + // ATH_eth + id: 32, + underlyingSymbol: 'ATH', + poolAddress: '0x391201cEC4F80e69C87Dee364d599c1FCAE3c363', + tokenAddress: '0xbe0Ed4138121EcFC5c0E56B40517da27E6c5226B', + spokeAddress: '0x91461B9117B3644609EeB0889ecc89Cab4644bb2', + }, + { + // pyUSD_eth + id: 33, + underlyingSymbol: 'pyUSD', + poolAddress: '0x279b3E185F64e99141d4CE363657A5F3B5B32Fb9', + tokenAddress: '0x6c3ea9036406852006290770BEdFcAbA0e23A0e8', + spokeAddress: '0xff785fb7BfBbe03eD09089f73151AE563B211723', + }, + { + // rlUSD_eth + id: 34, + underlyingSymbol: 'rlUSD', + poolAddress: '0x7178bF2a8A50153549e0d95A4C6Cb816448840F0', + tokenAddress: '0x8292bb45bf1ee4d140127049757c2e0ff06317ed', + spokeAddress: '0x7967B0fe720E676f41640855a203B409cEcc8f92', + }, + { + // wstETH_eth + id: 35, + underlyingSymbol: 'wstETH', + poolAddress: '0xe7897052FAC4bfF9EB3ABc073CBC1e17Fce5709C', + tokenAddress: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + spokeAddress: '0xB3ABD8cc35619b907F3f2E974Fe3d43956AA7cda', + }, + { + // weETH_eth + id: 36, + underlyingSymbol: 'weETH', + poolAddress: '0x4E6dD5E35638008cdB1E9004F3E952bCDd920E6D', + tokenAddress: '0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee', + spokeAddress: '0x63BCB60165E7EC30F03883Fcb800AEf304EE7eEa', + }, + { + // USDt_eth + id: 45, + underlyingSymbol: 'USDt', + poolAddress: '0xf51a72b92cB9C16376Da04f48eF071c966B9C50B', + tokenAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7', + spokeAddress: '0x12d4FeDD9cE1b4d7dB90b07366284ac1675a5a90', + }, + { + // SYRUP_eth + id: 54, + underlyingSymbol: 'SYRUP', + poolAddress: '0xD4F87eb6cc8795e727F7DbC1e2C6c3452ad0010c', + tokenAddress: '0x643C4E15d7d62Ad0aBeC4a9BD4b001aA3Ef52d66', + spokeAddress: '0x3aEa5E1f27935Ed59424F35Ea801420d804219E4', + }, + ], + }, + base: { + name: 'Base', + pools: [ + // excluding USDC because bridged + // excluding SolvBTC because bridged + // excluding SHIB because bridged + { + // ETH_base + id: 5, + underlyingSymbol: 'ETH', + poolAddress: '0x51958ed7B96F57142CE63BB223bbd9ce23DA7125', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0xe3B0e4Db870aA58A24f87d895c62D3dc5CD05883', + }, + { + // cbBTC_base + id: 9, + underlyingSymbol: 'cbBTC', + poolAddress: '0x9eD81F0b5b0E9b6dE00F374fFc7f270902576EF7', + tokenAddress: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', + spokeAddress: '0x50d5Bb3Cf57D2fB003b602A6fD10F90baa8567EA', + }, + { + // AERO_base + id: 37, + underlyingSymbol: 'AERO', + poolAddress: '0xb5327c35E083248E3a0f79122FaB3b6018e5584a', + tokenAddress: '0x940181a94a35a4569e4529a3cdfb74e38fd98631', + spokeAddress: '0x7Ace2Bc1C79954B56C65C7B326035C4468ac12BB', + }, + { + // cbETH_base + id: 38, + underlyingSymbol: 'cbETH', + poolAddress: '0x0b09E1Ffd28040654021A85A49284597F3d0e41C', + tokenAddress: '0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22', + spokeAddress: '0x31A324D233AB3E73A6e1039D64907bBb2742606C', + }, + { + // wstETH_base + id: 39, + underlyingSymbol: 'wstETH', + poolAddress: '0xC96820695217c7dd8F696f8892de76F7a48432CB', + tokenAddress: '0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452', + spokeAddress: '0x7c7961E590B7e005540B72238b739ae513B605fB', + }, + { + // weETH_base + id: 40, + underlyingSymbol: 'weETH', + poolAddress: '0xf727EC8D6e565328f2cf0Ff8aC4e7c9e7f8d24B2', + tokenAddress: '0x04c0599ae5a44757c0af6f9ec3b93da8976c150a', + spokeAddress: '0x8D9aad601f384C596B9e2b9124a73b278DB4C51C', + }, + { + // VIRTUAL_base + id: 41, + underlyingSymbol: 'VIRTUAL', + poolAddress: '0x331a1938f94af7bB41d57691119Aee416495202a', + tokenAddress: '0x0b3e328455c4059EEb9e3f84b5543F74E24e7E1b', + spokeAddress: '0x9009c929873f0e68dbc253b16aC4c3E4426E6E35', + }, + { + // KAITO_base + id: 42, + underlyingSymbol: 'KAITO', + poolAddress: '0x04C8B9d8AF87a6D670B646125B2D99740D8eBa5E', + tokenAddress: '0x98d0baa52b2D063E780DE12F615f963Fe8537553', + spokeAddress: '0x123f831a762A165107EE2e07416f4AA713dA9bFD', + }, + ], + }, + bsc: { + name: 'Binance', + pools: [ + // excluding SolvBTC because bridged + // excluding YBTCB because bridged + // excluding SHIB because bridged + { + // BNB + id: 10, + underlyingSymbol: 'BNB', + poolAddress: '0x89970d3662614a5A4C9857Fcc9D9C3FA03824fe3', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x5f2F4771B7dc7e2F7E9c1308B154E1e8957ecAB0', + }, + { + // ETHB_bsc + id: 11, + underlyingSymbol: 'ETH', + poolAddress: '0x18031B374a571F9e060de41De58Abb5957cD5258', + tokenAddress: '0x2170ed0880ac9a755fd29b2688956bd959f933f8', + spokeAddress: '0x4Db12F554623E4B0b3F5bAcF1c8490D4493380A5', + }, + { + // BTCB_bsc + id: 12, + underlyingSymbol: 'BTCB', + poolAddress: '0xC2FD40D9Ec4Ae7e71068652209EB75258809e131', + tokenAddress: '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c', + spokeAddress: '0x12Db9758c4D9902334C523b94e436258EB54156f', + }, + ], + }, + arbitrum: { + name: 'Arbitrum', + pools: [ + // excluding USDC because bridged + // excluding SolvBTC because bridged + // excluding SHIB because bridged + // excluding wstLINK because bridged + { + // ETH_arb + id: 13, + underlyingSymbol: 'ETH', + poolAddress: '0x44E0d0809AF8Ee37BFb1A4e75D5EF5B96F6346A3', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x37d761883a01e9F0B0d7fe59EEC8c21D94393CDD', + }, + { + // ARB + id: 14, + underlyingSymbol: 'ARB', + poolAddress: '0x1177A3c2CccDb9c50D52Fc2D30a13b2c3C40BCF4', + tokenAddress: '0x912ce59144191c1204e64559fe8253a0e49e6548', + spokeAddress: '0x1b2a8d56967d00700DD5C94E27B1a116a1deF8Df', + }, + { + // wBTC_arb + id: 24, + underlyingSymbol: 'WBTC', + poolAddress: '0x3445055F633fEF5A64F852aaCD6dA76143aCA109', + tokenAddress: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + spokeAddress: '0x2d1c07209696456b7901949fdf81037016d541A5', + }, + { + // tBTC_arb + id: 25, + underlyingSymbol: 'tBTC', + poolAddress: '0xdd9eFBf83572f5387381aD3A04b1318221d545A2', + tokenAddress: '0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40', + spokeAddress: '0xDF2da9288C4D0aDF6c52CCbb5062b8C73fb19111', + }, + { + // wstETH_arb + id: 26, + underlyingSymbol: 'wstETH', + poolAddress: '0x9f0c0aDEc9fd4ef946aCe1e2b4F32e49aE45C8F3', + tokenAddress: '0x5979D7b546E38E414F7E9822514be443A4800529', + spokeAddress: '0x74416b0121DAadFeb2A9C2306827CCf80a6EE097', + }, + { + // weETH_arb + id: 27, + underlyingSymbol: 'weETH', + poolAddress: '0x78B4e5cda33C898b546dB7925162879E7bd2A9d1', + tokenAddress: '0x35751007a407ca6FEFfE80b3cB397736D2cf4dbe', + spokeAddress: '0x624363570A6b6Fee5531CcA341b794B286Af091c', + }, + { + // rsETH_arb + id: 28, + underlyingSymbol: 'rsETH', + poolAddress: '0x60f2682Ab38e3C9a51b07fbd69f42Ad2Cfe731db', + tokenAddress: '0x4186BFC76E2E237523CBC30FD220FE055156b41F', + spokeAddress: '0xC0a3536E0b6799014A14664bA4370BBd5D0c7590', + }, + { + // USDT0_arb + id: 47, + underlyingSymbol: 'USD₮0', + poolAddress: '0x1b5a1dCe059E6069Ed33C3656826Ad04bE536465', + tokenAddress: '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + spokeAddress: '0xe69e068539Ee627bAb1Ce878843a6C76484CBd2c', + }, + ], + }, + polygon: { + name: 'Polygon', + pools: [ + // excluding USDC cause bridged + // excluding wstLINK because bridged + { + // POL + id: 19, + underlyingSymbol: 'POL', + poolAddress: '0x481cF0c02BF17a33753CE32f1931ED9990fFB40E', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x4Db12F554623E4B0b3F5bAcF1c8490D4493380A5', + }, + { + // wBTC_pol + id: 20, + underlyingSymbol: 'WBTC', + poolAddress: '0x7054254933279d93D97309745AfbFF9310cdb570', + tokenAddress: '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', + spokeAddress: '0x1A40208E9506E08a6f62DbCCf8de7387743179E9', + }, + { + // wETH_pol + id: 21, + underlyingSymbol: 'WETH', + poolAddress: '0x88Ae56886233C706409c74c3D4EA9A9Ac1D65ab2', + tokenAddress: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', + spokeAddress: '0x2e6e4603536078bd7661338F06FB93cf6F9b7A98', + }, + { + // wstETH_pol + id: 29, + underlyingSymbol: 'wstETH', + poolAddress: '0xD77b920A9c05B3e768FEaE0bcB5839cd224328fE', + tokenAddress: '0x03b54A6e9a984069379fae1a4fC4dBAE93B3bCCD', + spokeAddress: '0xa526f90c0CAab6A0E6085830e75b084cd3c84000', + }, + { + // LINK_pol + id: 30, + underlyingSymbol: 'LINK', + poolAddress: '0x84C420D5e077cF0ed8a20c44d803C380172eD5D5', + tokenAddress: '0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39', + spokeAddress: '0x63ad90A703e95e39be7CB9e460C2b05870c982B8', + }, + { + // MaticX + id: 31, + underlyingSymbol: 'MaticX', + poolAddress: '0x59023eFDB22B9d8b2C7aeD842aC1fd2f6110e5B5', + tokenAddress: '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6', + spokeAddress: '0xCB66564d0cF3D28B26a1b6D4eCb830D6E216a75a', + }, + { + // aUSD_pol + id: 43, + underlyingSymbol: 'aUSD', + poolAddress: '0x34f1BA5808EB5Bf60c9B1C343d86e410466F4860', + tokenAddress: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a', + spokeAddress: '0xaB07AfCf16fecdCC3D83dB7513c7839aEd626322', + }, + { + // USDt_pol + id: 46, + underlyingSymbol: 'USDt', + poolAddress: '0x11f82b5Ea7408Ff257F6031E6A3e29203557A1DD', + tokenAddress: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', + spokeAddress: '0xf2ee689fd3f7A7358bEDA46f83E7968Ad894abF0', + }, + ], + }, + sei: { + name: 'Sei', + pools: [ + { + // SEI + id: 48, + underlyingSymbol: 'SEI', + poolAddress: '0x63EFdA4bf91Ba13D678C58AF47304e6180dD46DF', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x5f2F4771B7dc7e2F7E9c1308B154E1e8957ecAB0', + }, + { + // iSEI + id: 49, + underlyingSymbol: 'iSEI', + poolAddress: '0x2B7995fd223dCf3A660Cc5a514349E3fa7B16168', + tokenAddress: '0x5Cf6826140C1C56Ff49C808A1A75407Cd1DF9423', + spokeAddress: '0x4Db12F554623E4B0b3F5bAcF1c8490D4493380A5', + }, + { + // USDT0_sei + id: 50, + underlyingSymbol: 'USD₮0', + poolAddress: '0x213299AC40Ce76117C2c4B13945D9d935686BB85', + tokenAddress: '0x9151434b16b9763660705744891fA906F660EcC5', + spokeAddress: '0x12Db9758c4D9902334C523b94e436258EB54156f', + }, + { + // wETH_sei + id: 51, + underlyingSymbol: 'WETH', + poolAddress: '0x9A102080970043B96773c15E6520d182565C68Ff', + tokenAddress: '0x160345fc359604fc6e70e3c5facbde5f7a9342d8', + spokeAddress: '0x802063A23E78D0f5D158feaAc605028Ee490b03b', + }, + { + // wBTC_sei + id: 52, + underlyingSymbol: 'WBTC', + poolAddress: '0x7Cd4afD7F4DB51A0bF06Bf4630752A5B28e0B6C1', + tokenAddress: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c', + spokeAddress: '0x7218Bd1050D41A9ECfc517abdd294FB8116aEe81', + }, + ], + }, + monad: { + name: 'Monad', + pools: [ + { + // MON + id: 61, + underlyingSymbol: 'MON', + poolAddress: '0x10a4481F79aAC209aC6c2959B785F2e303912Dc5', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x531490B7674ef239C9FEC39d2Cf3Cc10645d14d4', + }, + { + // wBTC_mon + id: 62, + underlyingSymbol: 'wBTC', + poolAddress: '0xdc887aCFe154BF0048Ae15Cda3693Ab2C237431A', + tokenAddress: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c', + spokeAddress: '0xF4c542518320F09943C35Db6773b2f9FeB2F847e', + }, + { + // wETH_mon + id: 63, + underlyingSymbol: 'wETH', + poolAddress: '0xD7Ff49751DAF42Bf7AFC4fF5C958d4bea48358D3', + tokenAddress: '0xEE8c0E9f1BFFb4Eb878d8f15f368A02a35481242', + spokeAddress: '0xe3B0e4Db870aA58A24f87d895c62D3dc5CD05883', + }, + { + // sMON + id: 64, + underlyingSymbol: 'sMON', + poolAddress: '0x5562d84f9891288fc72aaB1d857797c7275Fcedb', + tokenAddress: '0xA3227C5969757783154C60bF0bC1944180ed81B9', + spokeAddress: '0xb39c03297E87032fF69f4D42A6698e4c4A934449', + }, + { + // aUSD_mon + id: 66, + underlyingSymbol: 'aUSD', + poolAddress: '0x4fb4c3A33cBe855C5d87078c1BbBe5f371417faC', + tokenAddress: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a', + spokeAddress: '0xC30107a8e782E98Fe890f0375afa4185aeEa3356', + }, + { + // USDT0_mon + id: 67, + underlyingSymbol: 'USD₮0', + poolAddress: '0xd9D50D4F73f61A306b47e5BdC825E98cd11139dc', + tokenAddress: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D', + spokeAddress: '0xB1e2939b501B73F4cFEf6a9FB0aa89a75F1774EE', + }, + { + // gMON + id: 68, + underlyingSymbol: 'gMON', + poolAddress: '0x0b4e69C4890a88acA90E7e71dB76619C3AaCD79D', + tokenAddress: '0x8498312A6B3CbD158bf0c93AbdCF29E6e4F55081', + spokeAddress: '0x9105CEEbaf43EF6B80dF1b66BEfFd5F98A036c36', + }, + { + // shMON + id: 69, + underlyingSymbol: 'shMON', + poolAddress: '0x398715A6011391B2B7fD1fF66BB26c126E5d4aAC', + tokenAddress: '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c', + spokeAddress: '0x1A40208E9506E08a6f62DbCCf8de7387743179E9', + }, + ], + }, +}; + +const RewardsTokenV2 = { + // AVAX (Avalanche) + 1: { + chain: 'avax', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x2aa8FeE178A79182C4b7c61EfeB4227Cb8843915', + }, + // GoGoPool (Avalanche) + 2: { + chain: 'avax', + tokenAddress: '0x69260b9483f9871ca57f81a90d91e2f96c2cd11d', + spokeAddress: '0xb14f2576BE100CFE3B274233091A841f1E040604', + }, + // USDC (Arbitrum) + 3: { + chain: 'arbitrum', + tokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + spokeAddress: '0x88f15e36308ED060d8543DA8E2a5dA0810Efded2', + }, + // POL (Polygon) + 4: { + chain: 'polygon', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0xCD7eE494fa616FDbE38Aa0A9355E20b7215108Bf', + }, + // USDT0 (Arbitrum) + 5: { + chain: 'arbitrum', + tokenAddress: '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + spokeAddress: '0x0259617bE41aDA4D97deD60dAf848Caa6db3F228', + }, + // SEI (Sei) + 6: { + chain: 'sei', + tokenAddress: '0x0000000000000000000000000000000000000000', + spokeAddress: '0x531490B7674ef239C9FEC39d2Cf3Cc10645d14d4', + }, + // FOLKS (Monad) + 7: { + chain: 'monad', + tokenAddress: '0xFF7F8F301F7A706E3CfD3D2275f5dc0b9EE8009B', + spokeAddress: '0x7218Bd1050D41A9ECfc517abdd294FB8116aEe81', + }, +}; + +module.exports = { + PROJECT_SLUG, + HubPools, + ONE_18_DP, + EVERY_HOUR, + EVERY_SECOND, + GENERAL_LOAN_TYPE, + loanManagerAddress, + rewardsV2Address, + RewardsTokenV2, +}; diff --git a/src/adaptors/folks-finance-xchain/index.ts b/src/adaptors/folks-finance-xchain/index.ts new file mode 100644 index 0000000000..ff3fbfc2c7 --- /dev/null +++ b/src/adaptors/folks-finance-xchain/index.ts @@ -0,0 +1,258 @@ +const sdk = require('@defillama/sdk'); + +const { + getPrices, + calculateInterestYieldPercentage, + toUsdValue, + overallBorrowInterestRate, + calculateRewardAprPercentage, +} = require('./utils'); +const { + PROJECT_SLUG, + HubPools, + ONE_18_DP, + EVERY_HOUR, + EVERY_SECOND, + GENERAL_LOAN_TYPE, + loanManagerAddress, + rewardsV2Address, + RewardsTokenV2, +} = require('./constants'); +const { LoanManagerAbi, HubPoolAbi, RewardsV2Abi } = require('./abis'); + +async function initPools() { + // Get TVL for each spoke token in each chain + const chainsPoolsTvl = await Promise.all( + Object.keys(HubPools).map(async (chain) => { + const chainApi = new sdk.ChainApi({ + chain: chain, + timestamp: Math.floor(Date.now() / 1000), + }); + const tokensAndOwners = HubPools[chain].pools.map((pool) => [ + pool.tokenAddress, + pool.spokeAddress ?? pool.poolAddress, + ]); + return await chainApi.sumTokens({ tokensAndOwners }); + }) + ); + + // Get prices for each pool token + const tokenPrices = await getPrices(chainsPoolsTvl.map(Object.keys).flat()); + + // Init Pool Info for each pool for each chain + return chainsPoolsTvl.flatMap((chainPoolsTvl) => { + return Object.entries(chainPoolsTvl) + .map(([token, poolTvl]) => { + const priceInfo = tokenPrices[token]; + if (!priceInfo || priceInfo.price === undefined) return null; + + const [chain, tvlTokenAddress] = token.split(':'); + const { price, decimals } = priceInfo; + const { pools, name } = HubPools[chain]; + const pool = pools.find( + ({ tokenAddress }) => tokenAddress.toLowerCase() === tvlTokenAddress + ); + + return { + pool: `${pool.poolAddress}-${chain}`.toLowerCase(), + chain: name, + project: PROJECT_SLUG, + symbol: pool.underlyingSymbol, + tvlUsd: toUsdValue(poolTvl, price, decimals), + underlyingTokens: [pool.tokenAddress], + rewardTokens: [], + apyReward: 0, + meta: { + poolId: pool.id, + pool: pool.poolAddress.toLowerCase(), + chain, + price, + decimals, + }, + }; + }) + .filter(Boolean); + }); +} + +const updateWithLendingData = async (poolsInfo) => { + const chainApi = new sdk.ChainApi({ + chain: 'avax', + timestamp: Math.floor(Date.now() / 1000), + }); + + // Fetch lending data for each pool + const [targets, poolIds] = [ + poolsInfo.map((item) => item.meta.pool), + poolsInfo.map((item) => item.meta.poolId), + ]; + const [depositData, variableBorrowData, stableBorrowData, loanPools] = + await Promise.all([ + await chainApi.multiCall({ + calls: targets, + abi: HubPoolAbi.getDepositData, + }), + await chainApi.multiCall({ + calls: targets, + abi: HubPoolAbi.getVariableBorrowData, + }), + await chainApi.multiCall({ + calls: targets, + abi: HubPoolAbi.getStableBorrowData, + }), + await chainApi.multiCall({ + calls: poolIds.map((poolId) => ({ + target: loanManagerAddress, + params: [GENERAL_LOAN_TYPE, poolId], + })), + abi: LoanManagerAbi.getLoanPool, + }), + ]); + + // Convert data to BigInt + const [depositTotalAmount, depositInterestRate] = [ + depositData.map((item) => BigInt(item.totalAmount)), + depositData.map((item) => BigInt(item.interestRate)), + ]; + const [varBorrTotalAmount, varBorrInterestRate] = [ + variableBorrowData.map((item) => BigInt(item.totalAmount)), + variableBorrowData.map((item) => BigInt(item.interestRate)), + ]; + const [stblBorrTotalAmount, stblBorrInterestRate] = [ + stableBorrowData.map((item) => BigInt(item.totalAmount)), + stableBorrowData.map((item) => BigInt(item.interestRate)), + ]; + const ltvs = loanPools.map( + (item) => (Number(item.collateralFactor) * Number(item.borrowFactor)) / 1e8 + ); + + poolsInfo.forEach((poolInfo, i) => { + const { price, decimals } = poolInfo.meta; + const totalDebt = varBorrTotalAmount[i] + stblBorrTotalAmount[i]; + + // Calculate overall borrow rate + const borrowRate = overallBorrowInterestRate( + varBorrInterestRate[i], + varBorrTotalAmount[i], + stblBorrInterestRate[i], + stblBorrTotalAmount[i] + ); + + // Update pool info + poolInfo.apyBase = calculateInterestYieldPercentage( + depositInterestRate[i], + EVERY_HOUR, + ONE_18_DP + ); + poolInfo.apyBaseBorrow = calculateInterestYieldPercentage( + borrowRate, + EVERY_SECOND, + ONE_18_DP + ); + poolInfo.totalSupplyUsd = toUsdValue( + depositTotalAmount[i], + price, + decimals + ); + poolInfo.totalBorrowUsd = toUsdValue(totalDebt, price, decimals); + poolInfo.ltv = ltvs[i]; + }); + return poolsInfo; +}; + +const updateWithRewardsV2Data = async (poolsInfo) => { + const now = Math.floor(Date.now() / 1000); + const chainApi = new sdk.ChainApi({ + chain: 'avax', + timestamp: now, + }); + + // Fetch active epoch data for each pool + const poolIds = poolsInfo.map((pool) => pool.meta.poolId); + const activeEpochs = await chainApi.multiCall({ + calls: poolIds.map((poolId) => ({ + target: rewardsV2Address, + params: [poolId], + })), + abi: RewardsV2Abi.getActivePoolEpoch, + permitFailure: true, + }); + + // Extract rewards info for each reward token for each pool epoch + + const poolRewardsInfo = activeEpochs.map((activeEpoch) => { + if (activeEpoch === null) return null; + const [start, end, rewards] = [ + BigInt(activeEpoch.epoch.start), + BigInt(activeEpoch.epoch.end), + activeEpoch.epoch.rewards, + ]; + + const remainingTime = end - BigInt(now); + const fullEpochTime = end - start; + return { + remainingTime, + fullEpochTime, + remainingRewards: rewards.map((reward) => [ + reward.rewardTokenId, + (remainingTime * BigInt(reward.totalRewards)) / fullEpochTime, + ]), + }; + }); + const rewardsTokenPriceIds = poolRewardsInfo + .filter(Boolean) + .map((poolRewardInfo) => + poolRewardInfo.remainingRewards.map( + ([rewardTokenId]) => + `${RewardsTokenV2[rewardTokenId].chain}:${RewardsTokenV2[rewardTokenId].tokenAddress}` + ) + ) + .flat(); + + const tokenPrices = await getPrices(rewardsTokenPriceIds); + + poolsInfo.forEach((poolInfo, i) => { + if (poolRewardsInfo[i] === null) return; + const { remainingRewards, remainingTime } = poolRewardsInfo[i]; + remainingRewards.forEach(([rewardTokenId, remainingRewardsAmount]) => { + const rewardTokenInfo = RewardsTokenV2[rewardTokenId]; + const rewardTokenPrice = + tokenPrices[ + `${ + rewardTokenInfo.chain + }:${rewardTokenInfo.tokenAddress.toLowerCase()}` + ]; + + poolInfo.rewardTokens.push(rewardTokenInfo.tokenAddress); + poolInfo.apyReward += calculateRewardAprPercentage( + remainingRewardsAmount, + rewardTokenPrice?.price, + rewardTokenPrice?.decimals, + poolInfo.totalSupplyUsd, + remainingTime + ); + }); + }); + + return poolsInfo; +}; + +const deletePoolsInfoMeta = async (poolsInfo) => { + return poolsInfo.map((pool) => { + delete pool.meta; + return pool; + }); +}; + +const calcYields = async () => { + return await initPools() + .then(updateWithLendingData) + .then(updateWithRewardsV2Data) + .then(deletePoolsInfoMeta); +}; + +module.exports = { + timetravel: true, + apy: calcYields, + url: 'https://xapp.folks.finance/', +}; diff --git a/src/adaptors/folks-finance-xchain/utils.ts b/src/adaptors/folks-finance-xchain/utils.ts new file mode 100644 index 0000000000..1bc57a78b9 --- /dev/null +++ b/src/adaptors/folks-finance-xchain/utils.ts @@ -0,0 +1,87 @@ +const axios = require('axios'); +const { ONE_18_DP, EVERY_SECOND } = require('./constants'); + +const getPrices = async (tokenPriceKeys) => + ( + await axios.get( + `https://coins.llama.fi/prices/current/${tokenPriceKeys + .join(',') + .toLowerCase()}` + ) + ).data.coins; + +const toUsdValue = (value, price, decimals) => { + return (parseFloat(value) * price) / Math.pow(10, decimals); +}; + +const overallBorrowInterestRate = ( + varBorrowInterestRate, + varBorrowTotalAmount, + stblBorrowInterestRate, + stblBorrowTotalAmount +) => { + const totalDebt = varBorrowTotalAmount + stblBorrowTotalAmount; + if (totalDebt === BigInt(0)) return BigInt(0); + return ( + (varBorrowInterestRate * varBorrowTotalAmount + + stblBorrowInterestRate * stblBorrowTotalAmount) / + totalDebt + ); +}; + +function mulScale(n1, n2, scale) { + return (n1 * n2) / scale; +} + +function expBySquaring(x, n, scale) { + if (n === BigInt(0)) return scale; + + let y = scale; + while (n > BigInt(1)) { + if (n % BigInt(2)) { + y = mulScale(x, y, scale); + n = (n - BigInt(1)) / BigInt(2); + } else { + n = n / BigInt(2); + } + x = mulScale(x, x, scale); + } + return mulScale(x, y, scale); +} + +function calculateInterestYield(value, freq, scale) { + return expBySquaring(scale + value / freq, freq, scale) - scale; +} + +function interestRateToPercentage(interestRate, decimals = 5) { + const percentage = Number(interestRate) / Number(ONE_18_DP); + return Number(percentage.toFixed(decimals)) * 100; +} + +function calculateInterestYieldPercentage(value, freq, scale) { + return interestRateToPercentage(calculateInterestYield(value, freq, scale)); +} + +function calculateRewardAprPercentage( + rewardsAmount, + rewardsTokenPrice, + rewardsTokenDecimals, + totalSupplyUsd, + remainingTime +) { + return ( + (toUsdValue(rewardsAmount, rewardsTokenPrice, rewardsTokenDecimals) / + totalSupplyUsd) * + (Number(EVERY_SECOND) / Number(remainingTime)) * + 100 + ); +} +module.exports = { + toUsdValue, + overallBorrowInterestRate, + calculateInterestYield, + calculateInterestYieldPercentage, + interestRateToPercentage, + getPrices, + calculateRewardAprPercentage, +}; diff --git a/src/adaptors/foodcourt/abis/lp.json b/src/adaptors/foodcourt/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/foodcourt/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/foodcourt/abis/masterchef.json b/src/adaptors/foodcourt/abis/masterchef.json new file mode 100644 index 0000000000..05898a1ede --- /dev/null +++ b/src/adaptors/foodcourt/abis/masterchef.json @@ -0,0 +1,704 @@ +[ + { + "type": "constructor", + "stateMutability": "nonpayable", + "inputs": [ + { + "type": "address", + "name": "_coupon", + "internalType": "address" + }, + { + "type": "address", + "name": "_devAddr", + "internalType": "address" + }, + { + "type": "address", + "name": "_feeAddress", + "internalType": "address" + }, + { + "type": "uint256", + "name": "_couponPerSecond", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_startTimestamp", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_reserver", + "internalType": "address" + } + ] + }, + { + "type": "event", + "name": "Deposit", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyWithdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetDevAddress", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newAddress", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetFeeAddress", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newAddress", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "UpdateEmissionRate", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "couponPerSecond", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Withdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "BONUS_MULTIPLIER", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "add", + "inputs": [ + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IMintableERC20" + } + ], + "name": "coupon", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "couponPerSecond", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "deposit", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "devAddr", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "emergencyWithdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "feeAddress", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "getMultiplier", + "inputs": [ + { + "type": "uint256", + "name": "_from", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_to", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "harvestAll", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "massUpdatePools", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "pendingCoupon", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_user", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "bool", + "name": "", + "internalType": "bool" + } + ], + "name": "poolExistence", + "inputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IERC20" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint256", + "name": "allocPoint", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "lastRewardTimestamp", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accCouponPerShare", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "depositFeeBP", + "internalType": "uint16" + } + ], + "name": "poolInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "poolInfoDummyList", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "poolInfoPidList", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "poolLength", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "remove", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "bool", + "name": "emergency", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "reserver", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "set", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setDevAddress", + "inputs": [ + { + "type": "address", + "name": "_devAddr", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setFeeAddress", + "inputs": [ + { + "type": "address", + "name": "_feeAddress", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setStartTimestamp", + "inputs": [ + { + "type": "uint256", + "name": "newTimestamp", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "startTimestamp", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "totalAllocPoint", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { + "type": "address", + "name": "newOwner", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateEmissionRate", + "inputs": [ + { + "type": "uint256", + "name": "_couponPerSecond", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updatePool", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "amount", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "rewardDebt", + "internalType": "uint256" + } + ], + "name": "userInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + }, + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "withdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/foodcourt/index.js b/src/adaptors/foodcourt/index.js new file mode 100644 index 0000000000..e95fa2a7c0 --- /dev/null +++ b/src/adaptors/foodcourt/index.js @@ -0,0 +1,250 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const COUPON_TOKEN = '0xbC09220a8e461880DBE5517ecF53bC1b12cAa05D'; +const REI_TOKEN = '0x7539595ebdA66096e8913a24Cc3C8c0ba1Ec79a0'; +const MASTERCHEF_ADDRESS = '0x7aaA2A556578541067BFE93EE05B962Ee57E21CB'; +const BNB_REI_ADDRESS = '0xf8aB4aaf70cef3F3659d3F466E35Dc7ea10d4A5d'; +const BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = Math.floor((60 / BLOCK_TIME) * 60 * 24 * 365); +const SECOND_IN_YEAR = 86400 * 365; + +const mapTokenREItoBSC = { + '0xf8aB4aaf70cef3F3659d3F466E35Dc7ea10d4A5d': + '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', // BNB + '0xDD2bb4e845Bd97580020d8F9F58Ec95Bf549c3D9': + '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', // BUSD +}; + +const mapTokenBSCtoREI = { + '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c': + '0xf8aB4aaf70cef3F3659d3F466E35Dc7ea10d4A5d', + '0xe9e7cea3dedca5984780bafc599bd69add087d56': + '0xDD2bb4e845Bd97580020d8F9F58Ec95Bf549c3D9', +}; + +const getPriceFromReservesRateBNBBsc = (reserves, bnbPrice) => { + return (reserves[1] / reserves[0]) * bnbPrice; +}; + +const getPairInfo = async (pair, tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'reichain', + requery: true, + }) + ) + ); + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${mapTokenREItoBSC[address]}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [mapTokenBSCtoREI[address.split(':')[1]].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + couponPerSecond, + couponPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const couponPerYear = BigNumber(couponPerSecond) + .times(SECOND_IN_YEAR) + .times(poolWeight); + const apy = couponPerYear.times(couponPrice).div(reserveUSD).times(100); + return apy.toNumber(); +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'reichain', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'reichain', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const couponPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'reichain', + abi: masterChefABI.find((e) => e.name === 'couponPerSecond'), + }); + const normalizedcouponPerBlock = couponPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'reichain', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter((e) => e.lpToken !== '0xbC09220a8e461880DBE5517ecF53bC1b12cAa05D'); + + const lpTokens = pools.map(({ lpToken }) => lpToken); + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'reichain', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'reichain', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const reiPrice = await getPriceFromReservesRateBNBBsc( + reservesData[2], + tokensPrices[BNB_REI_ADDRESS.toLowerCase()] + ); + const couponPrice = await getPriceFromReservesRateBNBBsc( + reservesData[2], + reiPrice + ); + tokensPrices[REI_TOKEN.toLowerCase()] = reiPrice; + tokensPrices[COUPON_TOKEN.toLowerCase()] = couponPrice / 10; + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + const poolsApy = []; + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedcouponPerBlock, + tokensPrices[COUPON_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + poolsApy.push({ + pool: pool.lpToken, + chain: utils.formatChain('reichain'), + project: 'foodcourt', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [COUPON_TOKEN], + }); + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://foodcourt.finance/', +}; diff --git a/src/adaptors/forge/index.js b/src/adaptors/forge/index.js new file mode 100644 index 0000000000..f6a4baf40f --- /dev/null +++ b/src/adaptors/forge/index.js @@ -0,0 +1,236 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('../uniswap-v3/estimateFee'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); + +const baseUrl = + 'https://subgraph.satsuma-prod.com/09c9cf3574cc/orbital-apes/v3-subgraph/api'; +const chains = { + evmos: baseUrl, +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + totalValueLockedUSD + volumeUSD + feeTier + token0Price + token1Price + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + // most evmos tokens aren't available on our api, using the price and tvl data from the subgraph + dataNow = dataNow.map((p) => ({ + ...p, + price0: Number(p.token0Price), + price1: Number(p.token1Price), + totalValueLockedUSD: Number(p.totalValueLockedUSD), + })); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = false; + if (enableV3Apy) { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // split up subgraph tick calls into n-batches + // (tick response can be in the thousands per pool) + const skip = 20; + let start = 0; + let stop = skip; + const pages = Math.floor(dataNow.length / skip); + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + let X = []; + for (let i = 0; i <= pages; i++) { + console.log(i); + let promises = dataNow.slice(start, stop).map((p) => { + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + return EstimatedFees( + p.id, + priceAssumption, + [ + p.token1_in_token0 * (1 - delta), + p.token1_in_token0 * (1 + delta), + ], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + url, + p.volumeUSD7d + ); + }); + X.push(await Promise.all(promises)); + start += skip; + stop += skip; + } + const d = {}; + X.flat().forEach((p) => { + d[p.poolAddress] = p.estimatedFee; + }); + + dataNow = dataNow.map((p) => ({ + ...p, + apy7d: ((d[p.id] * 52) / investmentAmount) * 100, + })); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'forge', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: Number(p.totalValueLockedUSD), + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.forge.trade/#/pools', +}; diff --git a/src/adaptors/fractal-protocol/index.js b/src/adaptors/fractal-protocol/index.js new file mode 100644 index 0000000000..b89990477b --- /dev/null +++ b/src/adaptors/fractal-protocol/index.js @@ -0,0 +1,64 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const vaultAbi = { + inputs: [], + name: 'getTokenPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const usdfAbi = { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const USDF_TOKEN_CONTRACT = '0x51acB1ea45c1EC2512ae4202B9076C13016dc8aA'; +const FRACTAL_VAULT_CONTRACT = '0x3EAa4b3e8967c02cE1304C1EB35e8C5409838DFC'; + +const fractalMetrics = async () => { + //fetch apr from api + const data = await utils.getData( + 'https://api.fractalprotocol.org/vault/ethereum/historical-apr' + ); + const apyData = data.slice(-1)[0].apr; + + const usdfTotalSupply = ( + await sdk.api.abi.call({ + target: USDF_TOKEN_CONTRACT, + abi: usdfAbi, + chain: 'ethereum', + }) + ).output; + + const usdfPrice = ( + await sdk.api.abi.call({ + target: FRACTAL_VAULT_CONTRACT, + abi: vaultAbi, + chain: 'ethereum', + }) + ).output; + + const tvl = (usdfTotalSupply * usdfPrice) / 1e12; + + const fractalVault = { + pool: '0x3eB82f2eD4d992dc0Bed328214A0907250f4Ec82', + chain: utils.formatChain('ethereum'), + project: 'fractal-protocol', + symbol: utils.formatSymbol('USDC'), + tvlUsd: tvl, + apy: Number(apyData), + }; + + return [fractalVault]; // Fractal Protocol only has a single vault with APY +}; + +module.exports = { + timetravel: false, + apy: fractalMetrics, + url: 'https://app.fractalprotocol.org/', +}; diff --git a/src/adaptors/frakt/index.js b/src/adaptors/frakt/index.js new file mode 100644 index 0000000000..4ca2e27724 --- /dev/null +++ b/src/adaptors/frakt/index.js @@ -0,0 +1,29 @@ +const utils = require('../utils'); + +const API_URL = 'https://api.frakt.xyz/liquidity/pools'; +const SOLANA_PRICE_URL = + 'https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd'; + +const apy = async () => { + const { pools } = await utils.getData(API_URL); + + const priceKey = 'coingecko:solana'; + const solana = ( + await utils.getData(`https://coins.llama.fi/prices/current/${priceKey}`) + ).coins[priceKey].price; + + return pools.map((pool) => ({ + pool: pool.liquidityPoolPubkey, + chain: utils.formatChain('solana'), + project: 'frakt', + symbol: pool.name, + tvlUsd: (pool.amountOfStaked / 1e9) * solana, + apyBase: pool.depositApr / 100, + })); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://frakt.xyz/lend', +}; diff --git a/src/adaptors/francium/index.js b/src/adaptors/francium/index.js new file mode 100755 index 0000000000..1996267711 --- /dev/null +++ b/src/adaptors/francium/index.js @@ -0,0 +1,70 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const FARM_FEE = 0.04; +const apiBase = 'https://francium-data.s3-us-west-2.amazonaws.com/'; + +function getFarmPoolAPY(target) { + function aprToApy(apr, n = 365) { + return (1 + apr / n) ** n - 1; + } + function getFarmAPY(yfAPR, tradingFeeAPR, bi) { + return aprToApy(yfAPR * (1 - FARM_FEE) + tradingFeeAPR) - aprToApy(bi); + } + return ( + getFarmAPY( + (3 * target.yieldFarmingAPR) / 100, + (3 * target.tradingFeeAPR) / 100, + (-2 * target.borrowAPR) / 100 + ) * 100 + ); +} + +async function getPoolsData() { + const [{ data: farmPoolData }, { data: lendPoolData }] = await Promise.all([ + axios.get(apiBase + 'pools/latest.json'), + axios.get(apiBase + 'lend/latest.json'), + ]); + + if (!farmPoolData || !lendPoolData) { + // console.log({farmPoolData, lendPoolData}); + throw new Error('Unexpected response from frcPoolsData'); + return; + } + + const pools = []; + + const latestFarmPools = farmPoolData.filter((item) => item.poolId); + const latestLendPools = lendPoolData.filter((item) => item.poolId); + + latestFarmPools.forEach((item) => { + pools.push({ + pool: item.poolId, + chain: utils.formatChain('solana'), + project: 'francium', + symbol: utils.formatSymbol(item.pool), + tvlUsd: Number(item.frTvl), + apyBase: getFarmPoolAPY(item), + url: 'https://francium.io/app/invest/farm', + }); + }); + + latestLendPools.forEach((item) => { + pools.push({ + pool: item.poolId, + chain: utils.formatChain('solana'), + project: 'francium', + symbol: utils.formatSymbol(item.id), + tvlUsd: Number(item.available), + apyBase: item.apy, + url: 'https://francium.io/app/lend', + }); + }); + + return pools; +} + +module.exports = { + timetravel: false, + apy: getPoolsData, +}; diff --git a/src/adaptors/frankencoin/index.js b/src/adaptors/frankencoin/index.js new file mode 100644 index 0000000000..e7dc03e1de --- /dev/null +++ b/src/adaptors/frankencoin/index.js @@ -0,0 +1,176 @@ +const { request, gql } = require('graphql-request'); +const { getPrices } = require('../utils.js'); + +const GRAPH_URL = 'https://ponder.frankencoin.com'; +const CHAINS = { + ethereum: 1, + polygon: 137, + arbitrum: 42161, + optimism: 10, + base: 8453, + avalanche: 43114, + gnosis: 100, + sonic: 146, +}; + +// @dev: all relevant addresses across all supported chains +const ChainAddressMap = { + ethereum: { + frankencoin: '0xB58E61C3098d85632Df34EecfB899A1Ed80921cB', + equity: '0x1bA26788dfDe592fec8bcB0Eaff472a42BE341B2', + savingsV2: '0x3BF301B0e2003E75A3e86AB82bD1EFF6A9dFB2aE', + savingsReferral: '0x27d9AD987BdE08a0d083ef7e0e4043C857A17B38', + }, + polygon: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0xB519BAE359727e69990C27241Bef29b394A0ACbD', + }, + arbitrum: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0xb41715e54e9f0827821A149AE8eC1aF70aa70180', + }, + optimism: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0x6426324Af1b14Df3cd03b2d500529083c5ea61BC', + }, + base: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0x6426324Af1b14Df3cd03b2d500529083c5ea61BC', + }, + avalanche: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0x8e7c2a697751a1cE7a8DB51f01B883A27c5c8325', + }, + gnosis: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0xbF594D0feD79AE56d910Cb01b5dD4f4c57B04402', + }, + sonic: { + bridgedFrankencoin: '0xD4dD9e2F021BB459D5A5f6c24C12fE09c5D45553', + bridgedSavings: '0x4E104918908293cd6A93E1A9bbe06C345d751235', + }, +}; + +const gqlQueries = { + // Query for Lending SavingsReferral - Multichain + lending: gql` + { + savingsStatuss { + items { + chainId + module + balance + rate + } + } + } + `, + // Query for Borrow PositionV2 Positions - Mainnet + borrowing: gql` + { + mintingHubV2PositionV2s(where: { closed: false, denied: false }) { + items { + position + collateral + collateralSymbol + collateralBalance + collateralDecimals + riskPremiumPPM + limitForClones + availableForClones + minted + } + } + } + `, +}; + +const getChainName = (chainId) => { + return Object.keys(CHAINS).find((c) => CHAINS[c] == chainId); +}; + +// apy callback function +const apy = async () => { + const { savingsStatuss } = await request(GRAPH_URL, gqlQueries.lending, {}); + + const defaultFrankencoin = + ChainAddressMap['ethereum'].frankencoin.toLowerCase(); + const leadrateModuleId = + 'savings-0x3bf301b0e2003e75a3e86ab82bd1eff6a9dfb2ae-ethereum'; + + const price = (await getPrices([defaultFrankencoin], 'ethereum')) + .pricesByAddress[defaultFrankencoin]; + + const earnPools = savingsStatuss.items.map((savings) => { + const chain = getChainName(savings.chainId); + const token = ( + chain == 'ethereum' + ? defaultFrankencoin + : ChainAddressMap[chain].bridgedFrankencoin + ).toLowerCase(); + + return { + pool: `savings-${savings.module.toLowerCase()}-${chain}`, + chain, + project: 'frankencoin', + symbol: `ZCHF`, + apyBase: savings.rate / 10000 || 0, // converted from PPM to PCT + tvlUsd: (savings.balance / 1e18) * price || 0, + underlyingTokens: [token], + url: `https://app.frankencoin.com/savings?chain=${chain}`, + poolMeta: `Savings`, + }; + }); + + const queryPositionData = await request(GRAPH_URL, gqlQueries.borrowing, {}); + const positionData = queryPositionData.mintingHubV2PositionV2s.items; + + const collateralAddresses = []; + positionData.forEach((pos) => { + if (collateralAddresses.includes(pos.collateral)) return; + collateralAddresses.push(pos.collateral); + }); + + const collateralPrices = await getPrices(collateralAddresses, 'ethereum'); + const leadratePool = earnPools.find((p) => p.pool == leadrateModuleId); + const leadrate = leadratePool ? leadratePool.apyBase : 0; + + const borrowPools = positionData.map((pos) => { + const chain = 'ethereum'; + + const collateralBalance = + pos.collateralBalance / 10 ** pos.collateralDecimals; + const collateralPrice = collateralPrices.pricesByAddress[pos.collateral]; + const collateralValueUsd = collateralBalance * collateralPrice; + + const loanBalance = pos.minted / 10 ** 18; + const loanValueUsd = loanBalance * price; + + const ltv = loanValueUsd / collateralValueUsd; + + return { + pool: `position-v2-${pos.position.toLowerCase()}-${chain}`, + chain, + project: 'frankencoin', + symbol: pos.collateralSymbol, + apy: 0, + tvlUsd: collateralValueUsd, + underlyingTokens: [pos.collateral], + apyBaseBorrow: leadrate + pos.riskPremiumPPM / 10000, + totalSupplyUsd: (pos.limitForClones / 10 ** 18) * price, + totalBorrowUsd: (pos.minted / 10 ** 18) * price, + debtCeilingUsd: (pos.availableForClones / 10 ** 18) * price, + ltv, + mintedCoin: 'ZCHF', + url: `https://app.frankencoin.com/monitoring/${pos.position}?chain=${chain}`, + poolMeta: `PositionV2`, + }; + }); + + return [...earnPools, ...borrowPools]; +}; + +// export +module.exports = { + apy, +}; diff --git a/src/adaptors/frax-ether/index.js b/src/adaptors/frax-ether/index.js new file mode 100644 index 0000000000..25c52bbc53 --- /dev/null +++ b/src/adaptors/frax-ether/index.js @@ -0,0 +1,36 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const token = '0xac3e018457b222d93114458476f3e3416abbe38f'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const apyData = ( + await axios.get('https://api.frax.finance/v2/frxeth/summary/latest') + ).data; + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'frax-ether', + symbol: 'sfrxeth', + tvlUsd: tvl * ethPrice, + apyBase: apyData.sfrxethApr, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.frax.finance/frxeth/mint', +}; diff --git a/src/adaptors/frax/abi.js b/src/adaptors/frax/abi.js new file mode 100644 index 0000000000..7e3ee60252 --- /dev/null +++ b/src/adaptors/frax/abi.js @@ -0,0 +1,3169 @@ +module.exports = { + pairAbi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'orderId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'sellToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'unsoldAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'buyToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'purchasedAmount', + type: 'uint256', + }, + ], + name: 'CancelLongTermOrder', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'orderId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'numberOfTimeIntervals', + type: 'uint256', + }, + ], + name: 'LongTermSwap0To1', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'orderId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'numberOfTimeIntervals', + type: 'uint256', + }, + ], + name: 'LongTermSwap1To0', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'blocktimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserve0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserve1', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTwammReserve0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTwammReserve1', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'token0Bought', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'token1Bought', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'token0Sold', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'token1Sold', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'expiries', + type: 'uint256', + }, + ], + name: 'VirtualOrderExecution', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'orderId', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'proceedToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'proceeds', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'orderExpired', + type: 'bool', + }, + ], + name: 'WithdrawProceedsFromLongTermOrder', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'TWAPObservationHistory', + outputs: [ + { internalType: 'uint256', name: 'timestamp', type: 'uint256' }, + { + internalType: 'uint256', + name: 'price0CumulativeLast', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'price1CumulativeLast', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + name: 'cancelLongTermSwap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'blockTimestamp', type: 'uint256' }, + ], + name: 'executeVirtualOrders', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'offset', type: 'uint256' }, + { internalType: 'uint256', name: 'limit', type: 'uint256' }, + ], + name: 'getDetailedOrdersForUser', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'id', type: 'uint256' }, + { + internalType: 'uint256', + name: 'expirationTimestamp', + type: 'uint256', + }, + { internalType: 'uint256', name: 'saleRate', type: 'uint256' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'sellTokenAddr', type: 'address' }, + { internalType: 'address', name: 'buyTokenAddr', type: 'address' }, + { internalType: 'bool', name: 'isComplete', type: 'bool' }, + ], + internalType: 'struct LongTermOrdersLib.Order[]', + name: 'detailed_orders', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getNextOrderID', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getOrderIDsForUser', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getOrderIDsForUserLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'blockTimestamp', type: 'uint256' }, + ], + name: 'getReserveAfterTwamm', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { + internalType: 'uint256', + name: 'lastVirtualOrderTimestamp', + type: 'uint256', + }, + { internalType: 'uint112', name: '_twammReserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_twammReserve1', type: 'uint112' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTWAPHistoryLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + name: 'getTwammOrder', + outputs: [ + { internalType: 'uint256', name: 'id', type: 'uint256' }, + { + internalType: 'uint256', + name: 'expirationTimestamp', + type: 'uint256', + }, + { internalType: 'uint256', name: 'saleRate', type: 'uint256' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'sellTokenAddr', type: 'address' }, + { internalType: 'address', name: 'buyTokenAddr', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + name: 'getTwammOrderProceeds', + outputs: [ + { internalType: 'bool', name: 'orderExpired', type: 'bool' }, + { internalType: 'uint256', name: 'totalReward', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'orderId', type: 'uint256' }, + { internalType: 'uint256', name: 'blockTimestamp', type: 'uint256' }, + ], + name: 'getTwammOrderProceedsView', + outputs: [ + { internalType: 'bool', name: 'orderExpired', type: 'bool' }, + { internalType: 'uint256', name: 'totalReward', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTwammReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + { internalType: 'uint112', name: '_twammReserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_twammReserve1', type: 'uint112' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_blockTimestamp', type: 'uint256' }, + ], + name: 'getTwammRewardFactor', + outputs: [ + { + internalType: 'uint256', + name: 'rewardFactorPool0AtTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardFactorPool1AtTimestamp', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_blockTimestamp', type: 'uint256' }, + ], + name: 'getTwammSalesRateEnding', + outputs: [ + { + internalType: 'uint256', + name: 'orderPool0SalesRateEnding', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'orderPool1SalesRateEnding', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTwammState', + outputs: [ + { internalType: 'uint256', name: 'token0Rate', type: 'uint256' }, + { internalType: 'uint256', name: 'token1Rate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lastVirtualOrderTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'orderTimeInterval_rtn', + type: 'uint256', + }, + { internalType: 'uint256', name: 'rewardFactorPool0', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardFactorPool1', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount0In', type: 'uint256' }, + { + internalType: 'uint256', + name: 'numberOfTimeIntervals', + type: 'uint256', + }, + ], + name: 'longTermSwapFrom0To1', + outputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount1In', type: 'uint256' }, + { + internalType: 'uint256', + name: 'numberOfTimeIntervals', + type: 'uint256', + }, + ], + name: 'longTermSwapFrom1To0', + outputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'newSwapsPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'orderIDsForUser', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'orderTimeInterval', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'togglePauseNewSwaps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'twammReserve0', + outputs: [{ internalType: 'uint112', name: '', type: 'uint112' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'twammReserve1', + outputs: [{ internalType: 'uint112', name: '', type: 'uint112' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'twammUpToDate', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'orderId', type: 'uint256' }], + name: 'withdrawProceedsFromLongTermSwap', + outputs: [ + { internalType: 'bool', name: 'is_expired', type: 'bool' }, + { internalType: 'address', name: 'rewardTkn', type: 'address' }, + { internalType: 'uint256', name: 'totalReward', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + farmAbi: [ + { + inputs: [ + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'address[]', name: '_rewardTokens', type: 'address[]' }, + { + internalType: 'address[]', + name: '_rewardManagers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: '_rewardRates', type: 'uint256[]' }, + { + internalType: 'address[]', + name: '_gaugeControllers', + type: 'address[]', + }, + { + internalType: 'address[]', + name: '_rewardDistributors', + type: 'address[]', + }, + { internalType: 'address', name: '_stakingToken', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'LockedAdditional', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'uint256', + name: 'new_secs', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'new_start_ts', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'new_end_ts', + type: 'uint256', + }, + ], + name: 'LockedLonger', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'token_address', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'RewardPaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'secs', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'source_address', + type: 'address', + }, + ], + name: 'StakeLocked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'WithdrawLocked', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'calcCurCombinedWeight', + outputs: [ + { + internalType: 'uint256', + name: 'old_combined_weight', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'new_vefxs_multiplier', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'new_combined_weight', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'stake_idx', type: 'uint256' }, + ], + name: 'calcCurrLockMultiplier', + outputs: [ + { + internalType: 'uint256', + name: 'midpoint_lock_multiplier', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'reward_token_address', + type: 'address', + }, + { + internalType: 'address', + name: 'new_manager_address', + type: 'address', + }, + ], + name: 'changeTokenManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'combinedWeightOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'earned', + outputs: [ + { internalType: 'uint256[]', name: 'new_earned', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'fraxPerLPStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'fraxPerLPToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllRewardTokens', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'addr', type: 'address' }], + name: 'getProxyFor', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'getReward', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + { internalType: 'bool', name: 'claim_extra_too', type: 'bool' }, + ], + name: 'getReward2', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'getRewardExtraLogic', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getRewardForDuration', + outputs: [ + { + internalType: 'uint256[]', + name: 'rewards_per_duration_arr', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'caller_addr', type: 'address' }, + { internalType: 'address', name: 'reward_token_addr', type: 'address' }, + ], + name: 'isTokenManagerFor', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastRewardClaimTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastUpdateTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { internalType: 'uint256', name: 'addl_liq', type: 'uint256' }, + ], + name: 'lockAdditional', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { internalType: 'uint256', name: 'new_ending_ts', type: 'uint256' }, + ], + name: 'lockLonger', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'secs', type: 'uint256' }], + name: 'lockMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_time_for_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_time_min', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'lockedLiquidityOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'lockedStakes', + outputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { internalType: 'uint256', name: 'start_timestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'ending_timestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'lock_multiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'lockedStakesOf', + outputs: [ + { + components: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { + internalType: 'uint256', + name: 'start_timestamp', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { + internalType: 'uint256', + name: 'ending_timestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lock_multiplier', + type: 'uint256', + }, + ], + internalType: 'struct FraxUnifiedFarm_ERC20.LockedStake[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'lockedStakesOfLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'maxLPForMaxBoost', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'minVeFXSForMaxBoost', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'proxy_address', type: 'address' }, + ], + name: 'minVeFXSForMaxBoostProxy', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'nominateNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'nominatedOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'periodFinish', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'proxy_address', type: 'address' }, + ], + name: 'proxyStakedFrax', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'staker_address', type: 'address' }, + ], + name: 'proxyToggleStaker', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'proxy_lp_balances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardManagers', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'token_idx', type: 'uint256' }], + name: 'rewardRates', + outputs: [{ internalType: 'uint256', name: 'rwd_rate', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardTokenAddrToIdx', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsPerToken', + outputs: [ + { + internalType: 'uint256[]', + name: 'newRewardsPerTokenStored', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[6]', name: '_misc_vars', type: 'uint256[6]' }, + ], + name: 'setMiscVariables', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bool', name: '_stakingPaused', type: 'bool' }, + { internalType: 'bool', name: '_withdrawalsPaused', type: 'bool' }, + { + internalType: 'bool', + name: '_rewardsCollectionPaused', + type: 'bool', + }, + ], + name: 'setPauses', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'reward_token_address', + type: 'address', + }, + { internalType: 'uint256', name: '_new_rate', type: 'uint256' }, + { + internalType: 'address', + name: '_gauge_controller_address', + type: 'address', + }, + { + internalType: 'address', + name: '_rewards_distributor_address', + type: 'address', + }, + ], + name: 'setRewardVars', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'secs', type: 'uint256' }, + ], + name: 'stakeLocked', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'proxy_address', type: 'address' }, + ], + name: 'stakerSetVeFXSProxy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'staker_designated_proxies', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakesUnlocked', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakingToken', + outputs: [ + { internalType: 'contract IFraxswapPair', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'force_update', type: 'bool' }], + name: 'sync_gauge_weights', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_proxy_addr', type: 'address' }, + ], + name: 'toggleValidVeFXSProxy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalCombinedWeight', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLiquidityLocked', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unlockStakes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'bool', name: 'sync_too', type: 'bool' }, + ], + name: 'updateRewardAndBalance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'userStakedFrax', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'veFXSMultiplier', + outputs: [ + { internalType: 'uint256', name: 'vefxs_multiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vefxs_boost_scale_factor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vefxs_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vefxs_per_frax_for_max_boost', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'withdrawLocked', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + fraxCrvFarmAbi: [ + { + inputs: [ + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'address', name: '_bridge_token', type: 'address' }, + { internalType: 'address', name: '_rewardsToken0', type: 'address' }, + { internalType: 'address', name: '_rewardsToken1', type: 'address' }, + { internalType: 'address', name: '_stakingToken', type: 'address' }, + { internalType: 'address', name: '_frax_address', type: 'address' }, + { internalType: 'address', name: '_timelock_address', type: 'address' }, + { internalType: 'address', name: '_rewarder_address', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [], + name: 'DefaultInitialization', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'multiplier', + type: 'uint256', + }, + ], + name: 'LockedStakeMaxMultiplierUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'secs', + type: 'uint256', + }, + ], + name: 'LockedStakeMinTime', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'secs', + type: 'uint256', + }, + ], + name: 'LockedStakeTimeForMaxMultiplier', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'multiplier', + type: 'uint256', + }, + ], + name: 'MaxVeFXSMultiplier', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnerNominated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Recovered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'token_address', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'RewardPaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'secs', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'source_address', + type: 'address', + }, + ], + name: 'StakeLocked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'kek_id', + type: 'bytes32', + }, + { + indexed: false, + internalType: 'address', + name: 'destination_address', + type: 'address', + }, + ], + name: 'WithdrawLocked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'scale_factor', + type: 'uint256', + }, + ], + name: 'veFXSPerFraxForMaxBoostUpdated', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'migrator_address', type: 'address' }, + ], + name: 'addMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bridgeFXS', + outputs: [ + { internalType: 'contract IanyFXS', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'calcCurCombinedWeight', + outputs: [ + { + internalType: 'uint256', + name: 'old_combined_weight', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'new_vefxs_multiplier', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'new_combined_weight', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'combinedWeightOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'controller_address', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'earned', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'fraxPerLPToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'frax_address', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReward', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getRewardForDuration', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'initializeDefault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isInitialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastRewardPull', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastUpdateTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { internalType: 'uint256', name: 'addl_liq', type: 'uint256' }, + ], + name: 'lockAdditional', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'secs', type: 'uint256' }], + name: 'lockMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_time_for_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lock_time_min', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'lockedLiquidityOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'lockedStakes', + outputs: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { internalType: 'uint256', name: 'start_timestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'ending_timestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'lock_multiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'lockedStakesOf', + outputs: [ + { + components: [ + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + { + internalType: 'uint256', + name: 'start_timestamp', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { + internalType: 'uint256', + name: 'ending_timestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lock_multiplier', + type: 'uint256', + }, + ], + internalType: 'struct FraxCrossChainFarmV2.LockedStake[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'migrationsOn', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'staker_address', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'secs', type: 'uint256' }, + { internalType: 'uint256', name: 'start_timestamp', type: 'uint256' }, + ], + name: 'migrator_stakeLocked_for', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'staker_address', type: 'address' }, + { internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }, + ], + name: 'migrator_withdraw_locked', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'minVeFXSForMaxBoost', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'nominateNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'nominatedOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'periodFinish', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'migrator_address', type: 'address' }, + ], + name: 'removeMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerToken', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardRate0', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardRate1', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewarder', + outputs: [ + { + internalType: 'contract FraxCrossChainRewarder', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewards0', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewards1', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsCollectionPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsToken0', + outputs: [ + { + internalType: 'contract CrossChainCanonicalFXS', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsToken1', + outputs: [{ internalType: 'contract ERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_controller_address', + type: 'address', + }, + ], + name: 'setController', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_lock_time_for_max_multiplier', + type: 'uint256', + }, + { internalType: 'uint256', name: '_lock_time_min', type: 'uint256' }, + ], + name: 'setLockedStakeTimeForMinAndMaxMultiplier', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_lock_max_multiplier', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_vefxs_max_multiplier', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_vefxs_per_frax_for_max_boost', + type: 'uint256', + }, + ], + name: 'setMultipliers', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_new_timelock', type: 'address' }, + ], + name: 'setTimelock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_vefxs_address', type: 'address' }, + ], + name: 'setVeFXS', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'secs', type: 'uint256' }, + ], + name: 'stakeLocked', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'migrator_address', type: 'address' }, + ], + name: 'stakerAllowMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'migrator_address', type: 'address' }, + ], + name: 'stakerDisallowMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'staker_allowed_migrators', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakesUnlocked', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakingPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakingToken', + outputs: [{ internalType: 'contract I2pool', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sweepBridgeTokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'timelock_address', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'toggleMigrations', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'toggleRewardsCollection', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'toggleStaking', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'toggleWithdrawals', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalCombinedWeight', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLiquidityLocked', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ttlRew0Owed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ttlRew0Paid', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ttlRew1Owed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ttlRew1Paid', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unlockStakes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userRewardPerTokenPaid0', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userRewardPerTokenPaid1', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'userStakedFrax', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'valid_migrators', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'veFXS', + outputs: [{ internalType: 'contract IveFXS', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'veFXSMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vefxs_max_multiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vefxs_per_frax_for_max_boost', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'kek_id', type: 'bytes32' }], + name: 'withdrawLocked', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawalsPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + ], + crvPairAbi: [ + { + name: 'Transfer', + inputs: [ + { name: 'sender', type: 'address', indexed: true }, + { name: 'receiver', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'Approval', + inputs: [ + { name: 'owner', type: 'address', indexed: true }, + { name: 'spender', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'TokenExchange', + inputs: [ + { name: 'buyer', type: 'address', indexed: true }, + { name: 'sold_id', type: 'int128', indexed: false }, + { name: 'tokens_sold', type: 'uint256', indexed: false }, + { name: 'bought_id', type: 'int128', indexed: false }, + { name: 'tokens_bought', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'AddLiquidity', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'token_amounts', type: 'uint256[2]', indexed: false }, + { name: 'fees', type: 'uint256[2]', indexed: false }, + { name: 'invariant', type: 'uint256', indexed: false }, + { name: 'token_supply', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidity', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'token_amounts', type: 'uint256[2]', indexed: false }, + { name: 'fees', type: 'uint256[2]', indexed: false }, + { name: 'token_supply', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidityOne', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'token_amount', type: 'uint256', indexed: false }, + { name: 'coin_amount', type: 'uint256', indexed: false }, + { name: 'token_supply', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RemoveLiquidityImbalance', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'token_amounts', type: 'uint256[2]', indexed: false }, + { name: 'fees', type: 'uint256[2]', indexed: false }, + { name: 'invariant', type: 'uint256', indexed: false }, + { name: 'token_supply', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'RampA', + inputs: [ + { name: 'old_A', type: 'uint256', indexed: false }, + { name: 'new_A', type: 'uint256', indexed: false }, + { name: 'initial_time', type: 'uint256', indexed: false }, + { name: 'future_time', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'StopRampA', + inputs: [ + { name: 'A', type: 'uint256', indexed: false }, + { name: 't', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'initialize', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_rate_multipliers', type: 'uint256[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + ], + outputs: [], + gas: 401588, + }, + { + stateMutability: 'view', + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 318, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'transfer', + inputs: [ + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + gas: 77977, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'transferFrom', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + gas: 115912, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'approve', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + gas: 37851, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_balances', + inputs: [], + outputs: [{ name: '', type: 'uint256[2]' }], + gas: 4707, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin_fee', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 468, + }, + { + stateMutability: 'view', + type: 'function', + name: 'A', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 10764, + }, + { + stateMutability: 'view', + type: 'function', + name: 'A_precise', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 10726, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_virtual_price', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 842281, + }, + { + stateMutability: 'view', + type: 'function', + name: 'calc_token_amount', + inputs: [ + { name: '_amounts', type: 'uint256[2]' }, + { name: '_is_deposit', type: 'bool' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 1668445, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_liquidity', + inputs: [ + { name: '_amounts', type: 'uint256[2]' }, + { name: '_min_mint_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_liquidity', + inputs: [ + { name: '_amounts', type: 'uint256[2]' }, + { name: '_min_mint_amount', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_dy', + inputs: [ + { name: 'i', type: 'int128' }, + { name: 'j', type: 'int128' }, + { name: 'dx', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 2110507, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'exchange', + inputs: [ + { name: 'i', type: 'int128' }, + { name: 'j', type: 'int128' }, + { name: '_dx', type: 'uint256' }, + { name: '_min_dy', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'exchange', + inputs: [ + { name: 'i', type: 'int128' }, + { name: 'j', type: 'int128' }, + { name: '_dx', type: 'uint256' }, + { name: '_min_dy', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: '_min_amounts', type: 'uint256[2]' }, + ], + outputs: [{ name: '', type: 'uint256[2]' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: '_min_amounts', type: 'uint256[2]' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256[2]' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity_imbalance', + inputs: [ + { name: '_amounts', type: 'uint256[2]' }, + { name: '_max_burn_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity_imbalance', + inputs: [ + { name: '_amounts', type: 'uint256[2]' }, + { name: '_max_burn_amount', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'calc_withdraw_one_coin', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: 'i', type: 'int128' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'calc_withdraw_one_coin', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: 'i', type: 'int128' }, + { name: '_previous', type: 'bool' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity_one_coin', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: 'i', type: 'int128' }, + { name: '_min_received', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'remove_liquidity_one_coin', + inputs: [ + { name: '_burn_amount', type: 'uint256' }, + { name: 'i', type: 'int128' }, + { name: '_min_received', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'ramp_A', + inputs: [ + { name: '_future_A', type: 'uint256' }, + { name: '_future_time', type: 'uint256' }, + ], + outputs: [], + gas: 162101, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'stop_ramp_A', + inputs: [], + outputs: [], + gas: 157565, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin_balances', + inputs: [{ name: 'i', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 7740, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'withdraw_admin_fees', + inputs: [], + outputs: [], + gas: 24046, + }, + { + stateMutability: 'view', + type: 'function', + name: 'coins', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3093, + }, + { + stateMutability: 'view', + type: 'function', + name: 'balances', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3123, + }, + { + stateMutability: 'view', + type: 'function', + name: 'fee', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3108, + }, + { + stateMutability: 'view', + type: 'function', + name: 'initial_A', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3138, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_A', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3168, + }, + { + stateMutability: 'view', + type: 'function', + name: 'initial_A_time', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3198, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_A_time', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3228, + }, + { + stateMutability: 'view', + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string' }], + gas: 13488, + }, + { + stateMutability: 'view', + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string' }], + gas: 11241, + }, + { + stateMutability: 'view', + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3533, + }, + { + stateMutability: 'view', + type: 'function', + name: 'allowance', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 3778, + }, + { + stateMutability: 'view', + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3378, + }, + ], +}; diff --git a/src/adaptors/frax/index.js b/src/adaptors/frax/index.js new file mode 100644 index 0000000000..c05dbea6d6 --- /dev/null +++ b/src/adaptors/frax/index.js @@ -0,0 +1,125 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +const { farmAbi, pairAbi } = require('./abi'); +const { vstFraxStaking } = require('./vstFraxStaking'); + +const FRAXSWAP_POOLS_URL = 'https://api.frax.finance/v2/fraxswap/pools'; +const STAKING_URL = 'https://api.frax.finance/v1/pools'; + +const STAKING_CONTRACTS = { + 'Fraxswap FRAX/FPIS': '0x9bDBe31bB011D99c55b17455ACBe71814065E718', + 'Fraxswap FRAX/FXS': '0x06b7C6E8d22ecE102fb282C41075Bcc968b6E046', + 'Fraxswap FRAX/IQ': '0x5e15E40A3AA06bECA711EdE9F3F76E1d80C34490', + 'Fraxswap FRAX/IQ V2': '0xBF33B67F243a4DAbED494Ff5840f113B2E202a0d', + 'Fraxswap FRAX/IQ V3': '0x35678017e1D252dA1CdD6745b147E3e75d1f9C27', + 'Fraxswap FRAX/pitchFXS': '0x9E66E7811fEacf5402B65021475d1A293f7ea797', + 'Fraxswap FRAX/pitchFXS V2': '0x899Aa575E0e46344D18471f69337663C48b76e35', + 'Fraxswap FRAX/pitchFXS V3': '0x24C66Ba25ca2A53bB97B452B9F45DD075b07Cf55', + 'Fraxswap FRAX/SYN': '0xE8453a2e8E97cba69365A1d727Fde3768b18d814', +}; + +const apy = async (timestamp) => { + const sfrax = await utils.getERC4626Info( + '0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32', + 'ethereum', + timestamp + ); + const { tvl: sfraxTvl, ...restSfrax } = sfrax; + const sfraxvault = { + ...restSfrax, + project: 'frax', + symbol: `sFRAX`, + tvlUsd: sfraxTvl / 1e18, + underlyingTokens: ['0x853d955acef822db058eb8505911ed77f175b99e'], + }; + + const sfrxusd = await utils.getERC4626Info( + '0xcf62F905562626CfcDD2261162a51fd02Fc9c5b6', + 'ethereum', + timestamp + ); + const { tvl: sfrxusdTVL, ...restSfrxusd } = sfrxusd; + const sfrxusdvault = { + ...restSfrxusd, + project: 'frax', + symbol: `sfrxUSD`, + tvlUsd: sfrxusdTVL / 1e18, + underlyingTokens: ['0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29'], + }; + + const { pools: fxswapData } = await utils.getData(FRAXSWAP_POOLS_URL); + const stakingData = await utils + .getData(STAKING_URL) + .then((data) => data.filter((el) => el.platform === 'frax')); + + const [underlyingContracts, rewardTokens] = await Promise.all( + ['stakingToken', 'getAllRewardTokens'].map( + async (method) => + await Promise.all( + Object.values(STAKING_CONTRACTS).map( + async (contract) => + ( + await sdk.api.abi.call({ + target: contract, + chain: 'ethereum', + abi: farmAbi.find(({ name }) => name === method), + }) + ).output + ) + ) + ) + ); + const [underlyingTokens0, underlyingTokens1] = await Promise.all( + ['token0', 'token1'].map((method) => + utils.makeMulticall( + pairAbi.find(({ name }) => name === method), + underlyingContracts, + 'ethereum' + ) + ) + ); + const stakingRes = Object.entries(STAKING_CONTRACTS).map(([name, lp], i) => { + const data = stakingData.find(({ identifier }) => identifier === name); + if (!data) return; + + return { + pool: lp, + project: 'frax', + chain: 'ethereum', + symbol: data.pool_tokens.join('-'), + tvlUsd: data.liquidity_locked, + apyReward: data.apy, + underlyingTokens: [underlyingTokens0[i], underlyingTokens1[i]], + rewardTokens: rewardTokens[i], + }; + }); + + const fraxSwapRes = fxswapData.map((pool) => { + return { + pool: pool.poolAddress, + project: 'frax', + chain: utils.formatChain(pool.chain), + symbol: `${pool.token0Symbol}-${pool.token1Symbol}`, + tvlUsd: pool.tvl || 0, + apyBase: (((pool.fees7D / 7) * 365) / (pool.tvl || 1)) * 100, + underlyingTokens: [pool.token0Address, pool.token1Address], + }; + }); + + const vstFraxStakingRes = await vstFraxStaking(); + + return fraxSwapRes + .concat(stakingRes) + .concat(vstFraxStakingRes) + .concat([sfraxvault]) + .concat([sfrxusdvault]) + .filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.frax.finance/staking/overview', +}; diff --git a/src/adaptors/frax/vstFraxStaking.js b/src/adaptors/frax/vstFraxStaking.js new file mode 100644 index 0000000000..1fdc96df4b --- /dev/null +++ b/src/adaptors/frax/vstFraxStaking.js @@ -0,0 +1,69 @@ +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +const { fraxCrvFarmAbi, crvPairAbi } = require('./abi'); + +const STAKING_URL = 'https://api.frax.finance/v1/pools'; + +const STAKING_CONTRACTS = { + 'Curve VSTFRAX-f': '0x127963A74c07f72D862F2Bdc225226c3251BD117', +}; + +const VST = '0x64343594ab9b56e99087bfa6f2335db24c2d1f17'; + +const vstFraxStaking = async () => { + const stakingData = await utils + .getData(STAKING_URL) + .then((data) => data.filter((el) => el.platform === 'curve_arbi_vstfrax')); + + const [underlyingContracts, rewardTokens] = await Promise.all( + ['stakingToken', 'rewardsToken0'].map( + async (method) => + await Promise.all( + Object.values(STAKING_CONTRACTS).map( + async (contract) => + ( + await sdk.api.abi.call({ + target: contract, + chain: 'arbitrum', + abi: fraxCrvFarmAbi.find(({ name }) => name === method), + }) + ).output + ) + ) + ) + ); + + const [underlyingTokens0, underlyingTokens1] = await Promise.all( + [0, 1].map((param) => + utils.makeMulticall( + crvPairAbi.find(({ name }) => name === 'coins'), + underlyingContracts, + 'arbitrum', + param + ) + ) + ); + const stakingRes = Object.entries(STAKING_CONTRACTS).map(([name, lp], i) => { + const data = stakingData.find(({ identifier }) => identifier === name); + if (!data) return; + + return { + pool: STAKING_CONTRACTS['Curve VSTFRAX-f'], + project: 'frax', + chain: 'arbitrum', + symbol: 'VST-FRAX', + tvlUsd: data.liquidity_locked, + apyReward: data.apy, + underlyingTokens: [underlyingTokens0[i], underlyingTokens1[i]], + rewardTokens: [rewardTokens[i], VST], + }; + }); + + return stakingRes; +}; + +module.exports = { + vstFraxStaking, +}; diff --git a/src/adaptors/fraxlend/index.js b/src/adaptors/fraxlend/index.js new file mode 100644 index 0000000000..64685eeb67 --- /dev/null +++ b/src/adaptors/fraxlend/index.js @@ -0,0 +1,317 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const BIG_10 = new BigNumber('10'); +const utils = require('../utils'); + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; + +const FRAX = '0x853d955aCEf822Db058eb8505911ED77F175b99e'; +const PAIR_DEPLOYERS = [ + '0x5d6e79bcf90140585ce88c7119b7e43caaa67044', + '0x38488dE975B77dc1b0D4B8569f596f6FD6ca0B92', + '0x7AB788d0483551428f2291232477F1818952998C', + '0xaa913C26dD7723Fcae9dBD2036d28171a56C6251', +]; +const MKR = '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2'; //Not a standard ERC20. symbol and name are base32 encoded +const HELPER = { + abis: { + getAllPairAddresses: { + inputs: [], + name: 'getAllPairAddresses', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const VAULTS = { + abis: { + collateralContract: { + inputs: [], + name: 'collateralContract', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalCollateral: { + inputs: [], + name: 'totalCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalBorrow: { + inputs: [], + name: 'totalBorrow', + outputs: [ + { + internalType: 'uint128', + name: 'amount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'shares', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + currentRateInfo: { + inputs: [], + name: 'currentRateInfo', + outputs: [ + { + internalType: 'uint64', + name: 'lastBlock', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'feeToProtocolRate', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'lastTimestamp', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'ratePerSec', + type: 'uint64', + }, + ], + stateMutability: 'view', + type: 'function', + }, + maxLTV: { + inputs: [], + name: 'maxLTV', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalAsset: { + inputs: [], + name: 'totalAsset', + outputs: [ + { + internalType: 'uint128', + name: 'amount', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'shares', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const main = async () => { + const vaults = ( + await Promise.all( + PAIR_DEPLOYERS.map( + async (deployerAddress) => + ( + await sdk.api.abi.call({ + target: deployerAddress, + abi: HELPER.abis.getAllPairAddresses, + chain: 'ethereum', + }) + ).output + ) + ) + ).flat(); + + const collateralContracts = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.collateralContract, + requery: true, + }) + ).output.map((x) => x.output); + + const totalCollaterals = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.totalCollateral, + requery: true, + }) + ).output.map((x) => x.output); + + const totalBorrows = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.totalBorrow, + requery: true, + }) + ).output.map((x) => x.output); + + const currentRateInfos = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.currentRateInfo, + requery: true, + }) + ).output.map((x) => x.output); + + const maxLTVs = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.maxLTV, + requery: true, + }) + ).output.map((x) => x.output); + + const totalAssets = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.totalAsset, + requery: true, + }) + ).output.map((x) => x.output); + + const totalSupplys = ( + await sdk.api.abi.multiCall({ + calls: vaults.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: VAULTS.abis.totalSupply, + requery: true, + }) + ).output.map((x) => x.output); + + const underlyingCollaterals = ( + await sdk.api.abi.multiCall({ + calls: collateralContracts.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: 'erc20:symbol', + chain: 'ethereum', + requery: false, + permitFailure: true, + }) + ).output.map((x) => (x.input.target === MKR ? 'MKR' : x.output)); + + const decimalCollaterals = ( + await sdk.api.abi.multiCall({ + calls: collateralContracts.map((vaultAddress) => ({ + target: vaultAddress, + })), + abi: 'erc20:decimals', + requery: true, + }) + ).output.map((x) => x.output); + + const coins = [...collateralContracts, FRAX].map( + (addr) => `ethereum:${addr}` + ); + const prices = (await utils.getPrices(coins)).pricesByAddress; + + return vaults + .map((vaultAddress, index) => { + const tvlUsd = new BigNumber(totalCollaterals[index]) + .dividedBy(BIG_10.pow(decimalCollaterals[index])) + .times(prices[collateralContracts[index].toLowerCase()]); + const totalBorrowUsd = new BigNumber(totalBorrows[index].amount) + .dividedBy(BIG_10.pow(18)) + .times(prices[FRAX.toLowerCase()]); + + const debtCeilingUsd = new BigNumber(totalSupplys[index]) + .dividedBy(BIG_10.pow(18)) + .times(prices[FRAX.toLowerCase()]); + + const apyBaseBorrow = new BigNumber(currentRateInfos[index].ratePerSec) + .multipliedBy(SECONDS_PER_YEAR) + .div(BIG_10.pow(18)) + .multipliedBy(100); + + const apyBase = apyBaseBorrow + .multipliedBy(new BigNumber(totalBorrows[index].amount)) + .div(new BigNumber(totalAssets[index].amount)); + return { + pool: vaultAddress, + project: 'fraxlend', + symbol: underlyingCollaterals[index], + chain: 'ethereum', + apyBase: apyBase.toNumber(), + tvlUsd: tvlUsd.toNumber(), + // borrow fields + apyBaseBorrow: apyBaseBorrow.toNumber(), + totalSupplyUsd: tvlUsd.toNumber(), + totalBorrowUsd: totalBorrowUsd.toNumber(), + debtCeilingUsd: debtCeilingUsd.toNumber(), + mintedCoin: 'FRAX', + ltv: new BigNumber(maxLTVs[index]) + .dividedBy(new BigNumber(100000)) + .toNumber(), + underlyingTokens: [collateralContracts[index]], + }; + }) + .filter((e) => e.tvlUsd); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.frax.finance/fraxlend/available-pairs', +}; diff --git a/src/adaptors/frigg.eco/index.js b/src/adaptors/frigg.eco/index.js new file mode 100755 index 0000000000..927db0eb62 --- /dev/null +++ b/src/adaptors/frigg.eco/index.js @@ -0,0 +1,26 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const dataTvl = await utils.getData( + 'https://api.llama.fi/protocol/frigg.eco' + ); + + const friggPool = { + pool: "0x90D53b872ce6421122B41a290aCdD22a5eD931bd", + chain: "Ethereum", + project: 'frigg.eco', + symbol: 'ATT', + tvlUsd: Number(dataTvl.currentChainTvls['Ethereum']), + apyBase: 4, + underlyingTokens: ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'], + poolMeta: "Frigg Token Pool", + }; + + return [friggPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://agatobwe.eco', +}; \ No newline at end of file diff --git a/src/adaptors/friktion/index.js b/src/adaptors/friktion/index.js new file mode 100755 index 0000000000..abebfa660b --- /dev/null +++ b/src/adaptors/friktion/index.js @@ -0,0 +1,64 @@ +const axios = require('axios'); +const utils = require('../utils'); + +// matches the mapping on the frontend and +// imo is much easier to understand than poolId +const voltTypeMapping = { + 1: 'Covered Call', + 2: 'Cash Secured Put', + 3: 'Crab Strategy', + 4: 'Basis Yield', +}; + +async function tvl() { + const friktionSnapshotResponse = await axios.get( + 'https://raw.githubusercontent.com/Friktion-Labs/mainnet-tvl-snapshots/main/friktionSnapshot.json' + ); + + const friktionSnapshot = friktionSnapshotResponse.data; + const poolsTvl = friktionSnapshot.usdValueByGlobalId; + const volts = friktionSnapshot.allMainnetVolts; + + const pools = []; + + if ( + !( + friktionSnapshot && + volts && + poolsTvl && + typeof friktionSnapshot === 'object' && + typeof volts === 'object' && + typeof poolsTvl === 'object' + ) + ) { + console.log(friktionSnapshot); + throw new Error('Unexpected response from friktionSnapshot'); + } + + for (let i = 0; i < volts.length; i += 1) { + const currentVolt = volts[i]; + const poolId = currentVolt.globalId; + const voltType = currentVolt.voltType; + const poolObj = { + pool: currentVolt.voltVaultId, + chain: utils.formatChain('solana'), + project: 'friktion', + symbol: currentVolt.depositTokenSymbol, + poolMeta: voltTypeMapping[voltType], + tvlUsd: Number(poolsTvl[poolId]), + apyBase: + utils.aprToApy(currentVolt.latestEpochYield * 52, 52) * + (1 - (currentVolt.performanceFeeRate + currentVolt.withdrawalFeeRate)), + il7d: + currentVolt.latestEpochYield < 0 ? currentVolt.latestEpochYield : null, + }; + pools.push(poolObj); + } + return pools.filter((p) => utils.keepFinite(p)); +} + +module.exports = { + timetravel: false, + apy: tvl, + url: 'https://app.friktion.fi/', +}; diff --git a/src/adaptors/fringe-v1/abis/lendingPoolsABI.json b/src/adaptors/fringe-v1/abis/lendingPoolsABI.json new file mode 100644 index 0000000000..fbae7b5a30 --- /dev/null +++ b/src/adaptors/fringe-v1/abis/lendingPoolsABI.json @@ -0,0 +1,1752 @@ +[ + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"cashPrior", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"interestAccumulated", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"borrowIndex", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"totalBorrows", + "type":"uint256" + } + ], + "name":"AccrueInterest", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"owner", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"spender", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"Approval", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"borrowAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"accountBorrows", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"totalBorrows", + "type":"uint256" + } + ], + "name":"Borrow", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"error", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"info", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"detail", + "type":"uint256" + } + ], + "name":"Failure", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"liquidator", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"repayAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"address", + "name":"cTokenCollateral", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"seizeTokens", + "type":"uint256" + } + ], + "name":"LiquidateBorrow", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"minter", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"mintAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"mintTokens", + "type":"uint256" + } + ], + "name":"Mint", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"oldAdmin", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"newAdmin", + "type":"address" + } + ], + "name":"NewAdmin", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"contract Bondtroller", + "name":"oldBondtroller", + "type":"address" + }, + { + "indexed":false, + "internalType":"contract Bondtroller", + "name":"newBondtroller", + "type":"address" + } + ], + "name":"NewBondtroller", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"contract InterestRateModel", + "name":"oldInterestRateModel", + "type":"address" + }, + { + "indexed":false, + "internalType":"contract InterestRateModel", + "name":"newInterestRateModel", + "type":"address" + } + ], + "name":"NewMarketInterestRateModel", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"oldPendingAdmin", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"newPendingAdmin", + "type":"address" + } + ], + "name":"NewPendingAdmin", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"oldReserveFactorMantissa", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"newReserveFactorMantissa", + "type":"uint256" + } + ], + "name":"NewReserveFactor", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"redeemer", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"redeemAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"redeemTokens", + "type":"uint256" + } + ], + "name":"Redeem", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"payer", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"repayAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"accountBorrows", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"totalBorrows", + "type":"uint256" + } + ], + "name":"RepayBorrow", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"benefactor", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"addAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"newTotalReserves", + "type":"uint256" + } + ], + "name":"ReservesAdded", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"address", + "name":"admin", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"reduceAmount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"newTotalReserves", + "type":"uint256" + } + ], + "name":"ReservesReduced", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"previousAdminRole", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"newAdminRole", + "type":"bytes32" + } + ], + "name":"RoleAdminChanged", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleGranted", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleRevoked", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"oldPrimaryIndexToken", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"newPrimaryIndexToken", + "type":"address" + } + ], + "name":"SetPrimaryIndexToken", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"Transfer", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"DEFAULT_ADMIN_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"MODERATOR_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"addAmount", + "type":"uint256" + } + ], + "name":"_addReserves", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"reduceAmount", + "type":"uint256" + } + ], + "name":"_reduceReserves", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"contract Bondtroller", + "name":"newBondtroller", + "type":"address" + } + ], + "name":"_setBondtroller", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"contract InterestRateModel", + "name":"newInterestRateModel", + "type":"address" + } + ], + "name":"_setInterestRateModel", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"newReserveFactorMantissa", + "type":"uint256" + } + ], + "name":"_setReserveFactor", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"accountTokens", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"accrualBlockNumber", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"accrueInterest", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"admin", + "outputs":[ + { + "internalType":"address payable", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + }, + { + "internalType":"address", + "name":"spender", + "type":"address" + } + ], + "name":"allowance", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"spender", + "type":"address" + }, + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"approve", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"balanceOf", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"balanceOfUnderlying", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + } + ], + "name":"balanceOfUnderlyingView", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"bondtroller", + "outputs":[ + { + "internalType":"contract Bondtroller", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"borrowBalanceCurrent", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"borrowBalanceStored", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"borrowIndex", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"borrowRatePerBlock", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "internalType":"uint256", + "name":"borrowAmount", + "type":"uint256" + } + ], + "name":"borrowTo", + "outputs":[ + { + "internalType":"uint256", + "name":"borrowError", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"decimals", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"exchangeRateCurrent", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"exchangeRateStored", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"getAccountSnapshot", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getCash", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"getEstimatedBorrowBalanceStored", + "outputs":[ + { + "internalType":"uint256", + "name":"accrual", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getEstimatedBorrowIndex", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + } + ], + "name":"getRoleAdmin", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"newModerator", + "type":"address" + } + ], + "name":"grandModerator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"grantRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"hasRole", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"underlying_", + "type":"address" + }, + { + "internalType":"contract Bondtroller", + "name":"bondtroller_", + "type":"address" + }, + { + "internalType":"contract InterestRateModel", + "name":"interestRateModel_", + "type":"address" + }, + { + "internalType":"uint256", + "name":"initialExchangeRateMantissa_", + "type":"uint256" + }, + { + "internalType":"string", + "name":"name_", + "type":"string" + }, + { + "internalType":"string", + "name":"symbol_", + "type":"string" + }, + { + "internalType":"uint8", + "name":"decimals_", + "type":"uint8" + }, + { + "internalType":"address", + "name":"admin_", + "type":"address" + } + ], + "name":"init", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"underlying_", + "type":"address" + }, + { + "internalType":"contract Bondtroller", + "name":"comptroller_", + "type":"address" + }, + { + "internalType":"contract InterestRateModel", + "name":"interestRateModel_", + "type":"address" + }, + { + "internalType":"uint256", + "name":"initialExchangeRateMantissa_", + "type":"uint256" + }, + { + "internalType":"string", + "name":"name_", + "type":"string" + }, + { + "internalType":"string", + "name":"symbol_", + "type":"string" + }, + { + "internalType":"uint8", + "name":"decimals_", + "type":"uint8" + } + ], + "name":"initialize", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"contract Bondtroller", + "name":"bondtroller_", + "type":"address" + }, + { + "internalType":"contract InterestRateModel", + "name":"interestRateModel_", + "type":"address" + }, + { + "internalType":"uint256", + "name":"initialExchangeRateMantissa_", + "type":"uint256" + }, + { + "internalType":"string", + "name":"name_", + "type":"string" + }, + { + "internalType":"string", + "name":"symbol_", + "type":"string" + }, + { + "internalType":"uint8", + "name":"decimals_", + "type":"uint8" + } + ], + "name":"initialize", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"interestRateModel", + "outputs":[ + { + "internalType":"contract InterestRateModel", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"isCToken", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"minter", + "type":"address" + }, + { + "internalType":"uint256", + "name":"mintAmount", + "type":"uint256" + } + ], + "name":"mintTo", + "outputs":[ + { + "internalType":"uint256", + "name":"err", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"mintedAmount", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"name", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"pendingAdmin", + "outputs":[ + { + "internalType":"address payable", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"primaryIndexToken", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"protocolSeizeShareMantissa", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"redeemer", + "type":"address" + }, + { + "internalType":"uint256", + "name":"redeemTokens", + "type":"uint256" + } + ], + "name":"redeemTo", + "outputs":[ + { + "internalType":"uint256", + "name":"redeemErr", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"redeemer", + "type":"address" + }, + { + "internalType":"uint256", + "name":"redeemAmount", + "type":"uint256" + } + ], + "name":"redeemUnderlyingTo", + "outputs":[ + { + "internalType":"uint256", + "name":"redeemUnderlyingError", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"renounceRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"payer", + "type":"address" + }, + { + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "internalType":"uint256", + "name":"repayAmount", + "type":"uint256" + } + ], + "name":"repayTo", + "outputs":[ + { + "internalType":"uint256", + "name":"repayBorrowError", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"amountRepayed", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"reserveFactorMantissa", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"moderator", + "type":"address" + } + ], + "name":"revokeModerator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"revokeRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_primaryIndexToken", + "type":"address" + } + ], + "name":"setPrimaryIndexToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"reserveFactorMantissa", + "type":"uint256" + } + ], + "name":"setReserveFactor", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"supplyRatePerBlock", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes4", + "name":"interfaceId", + "type":"bytes4" + } + ], + "name":"supportsInterface", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"contract EIP20NonStandardInterface", + "name":"token", + "type":"address" + } + ], + "name":"sweepToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"symbol", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalBorrows", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalBorrowsCurrent", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalReserves", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalSupply", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"dst", + "type":"address" + }, + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"transfer", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address payable", + "name":"newAdmin", + "type":"address" + } + ], + "name":"transferAdminship", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"src", + "type":"address" + }, + { + "internalType":"address", + "name":"dst", + "type":"address" + }, + { + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"transferFrom", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"underlying", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + } + ] \ No newline at end of file diff --git a/src/adaptors/fringe-v1/abis/protocolContractABI.json b/src/adaptors/fringe-v1/abis/protocolContractABI.json new file mode 100644 index 0000000000..33c01c339b --- /dev/null +++ b/src/adaptors/fringe-v1/abis/protocolContractABI.json @@ -0,0 +1,1696 @@ +[ + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + } + ], + "name":"AddPrjToken", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"borrowToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"borrowAmount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"prjAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"prjAmount", + "type":"uint256" + } + ], + "name":"Borrow", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"prjDepositAmount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"beneficiary", + "type":"address" + } + ], + "name":"Deposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"liquidator", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"borrower", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"prjAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amountPrjLiquidated", + "type":"uint256" + } + ], + "name":"Liquidate", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"ltfNumerator", + "type":"uint8" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"ltfDenominator", + "type":"uint8" + } + ], + "name":"LiquidationIncentiveSet", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"ltfNumerator", + "type":"uint8" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"ltfDenominator", + "type":"uint8" + } + ], + "name":"LiquidationThresholdFactorSet", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"lvrNumerator", + "type":"uint8" + }, + { + "indexed":false, + "internalType":"uint8", + "name":"lvrDenominator", + "type":"uint8" + } + ], + "name":"LoanToValueRatioSet", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"redeemToken", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"redeemBToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"redeemAmount", + "type":"uint256" + } + ], + "name":"Redeem", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"redeemToken", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"redeemBToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"redeemAmountUnderlying", + "type":"uint256" + } + ], + "name":"RedeemUnderlying", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"borrowToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"borrowAmount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"prjAddress", + "type":"address" + }, + { + "indexed":false, + "internalType":"bool", + "name":"isPositionFullyRepaid", + "type":"bool" + } + ], + "name":"RepayBorrow", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"previousAdminRole", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"bytes32", + "name":"newAdminRole", + "type":"bytes32" + } + ], + "name":"RoleAdminChanged", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleGranted", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "indexed":true, + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"sender", + "type":"address" + } + ], + "name":"RoleRevoked", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"supplyToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"supplyAmount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"supplyBToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amountSupplyBTokenReceived", + "type":"uint256" + } + ], + "name":"Supply", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"who", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"tokenPrj", + "type":"address" + }, + { + "indexed":false, + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"prjWithdrawAmount", + "type":"uint256" + }, + { + "indexed":true, + "internalType":"address", + "name":"beneficiary", + "type":"address" + } + ], + "name":"Withdraw", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"DEFAULT_ADMIN_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"MODERATOR_ROLE", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_lendingToken", + "type":"address" + }, + { + "internalType":"address", + "name":"_bLendingToken", + "type":"address" + }, + { + "internalType":"bool", + "name":"_isPaused", + "type":"bool" + } + ], + "name":"addLendingToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_projectToken", + "type":"address" + }, + { + "internalType":"uint8", + "name":"_loanToValueRatioNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_loanToValueRatioDenominator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationThresholdFactorNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationThresholdFactorDenominator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationIncentiveNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationIncentiveDenominator", + "type":"uint8" + } + ], + "name":"addProjectToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"lendingTokenAmount", + "type":"uint256" + } + ], + "name":"borrow", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"borrowLimit", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"borrowPosition", + "outputs":[ + { + "internalType":"uint256", + "name":"loanBody", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"accrual", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"decimals", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"pure", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"projectTokenAmount", + "type":"uint256" + } + ], + "name":"deposit", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"depositPosition", + "outputs":[ + { + "internalType":"uint256", + "name":"depositedProjectTokenAmount", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"getPosition", + "outputs":[ + { + "internalType":"uint256", + "name":"depositedProjectTokenAmount", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"loanBody", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"accrual", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"healthFactorNumerator", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"healthFactorDenominator", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"projectTokenAmount", + "type":"uint256" + } + ], + "name":"getProjectTokenEvaluation", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + } + ], + "name":"getRoleAdmin", + "outputs":[ + { + "internalType":"bytes32", + "name":"", + "type":"bytes32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"newModerator", + "type":"address" + } + ], + "name":"grandModerator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"grantRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"hasRole", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"healthFactor", + "outputs":[ + { + "internalType":"uint256", + "name":"numerator", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"denominator", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"initialize", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"lendingTokenInfo", + "outputs":[ + { + "internalType":"bool", + "name":"isListed", + "type":"bool" + }, + { + "internalType":"bool", + "name":"isPaused", + "type":"bool" + }, + { + "internalType":"contract BLendingToken", + "name":"bLendingToken", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"lendingTokens", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"lendingTokensLength", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"liquidate", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"liquidationThreshold", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"name", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"pit", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"pitRemaining", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"priceOracle", + "outputs":[ + { + "internalType":"contract IPriceProviderAggregator", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"projectTokenInfo", + "outputs":[ + { + "internalType":"bool", + "name":"isListed", + "type":"bool" + }, + { + "internalType":"bool", + "name":"isDepositPaused", + "type":"bool" + }, + { + "internalType":"bool", + "name":"isWithdrawPaused", + "type":"bool" + }, + { + "components":[ + { + "internalType":"uint8", + "name":"numerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"denominator", + "type":"uint8" + } + ], + "internalType":"struct PrimaryIndexToken.Ratio", + "name":"loanToValueRatio", + "type":"tuple" + }, + { + "components":[ + { + "internalType":"uint8", + "name":"numerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"denominator", + "type":"uint8" + } + ], + "internalType":"struct PrimaryIndexToken.Ratio", + "name":"liquidationThresholdFactor", + "type":"tuple" + }, + { + "components":[ + { + "internalType":"uint8", + "name":"numerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"denominator", + "type":"uint8" + } + ], + "internalType":"struct PrimaryIndexToken.Ratio", + "name":"liquidationIncentive", + "type":"tuple" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"projectTokens", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"projectTokensLength", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"bLendingTokenAmount", + "type":"uint256" + } + ], + "name":"redeem", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"lendingTokenAmount", + "type":"uint256" + } + ], + "name":"redeemUnderlying", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_lendingTokenId", + "type":"uint256" + } + ], + "name":"removeLendingToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"_projectTokenId", + "type":"uint256" + } + ], + "name":"removeProjectToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"renounceRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"lendingTokenAmount", + "type":"uint256" + } + ], + "name":"repay", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"moderator", + "type":"address" + } + ], + "name":"revokeModerator", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes32", + "name":"role", + "type":"bytes32" + }, + { + "internalType":"address", + "name":"account", + "type":"address" + } + ], + "name":"revokeRole", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"_borrowLimit", + "type":"uint256" + } + ], + "name":"setBorrowLimit", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_lendingToken", + "type":"address" + }, + { + "internalType":"address", + "name":"_bLendingToken", + "type":"address" + }, + { + "internalType":"bool", + "name":"_isPaused", + "type":"bool" + } + ], + "name":"setLendingTokenInfo", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_lendingToken", + "type":"address" + }, + { + "internalType":"bool", + "name":"_isPaused", + "type":"bool" + } + ], + "name":"setPausedLendingToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_projectToken", + "type":"address" + }, + { + "internalType":"bool", + "name":"_isDepositPaused", + "type":"bool" + }, + { + "internalType":"bool", + "name":"_isWithdrawPaused", + "type":"bool" + } + ], + "name":"setPausedProjectToken", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_priceOracle", + "type":"address" + } + ], + "name":"setPriceOracle", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_projectToken", + "type":"address" + }, + { + "internalType":"uint8", + "name":"_loanToValueRatioNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_loanToValueRatioDenominator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationThresholdFactorNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationThresholdFactorDenominator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationIncentiveNumerator", + "type":"uint8" + }, + { + "internalType":"uint8", + "name":"_liquidationIncentiveDenominator", + "type":"uint8" + } + ], + "name":"setProjectTokenInfo", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"lendingTokenAmount", + "type":"uint256" + } + ], + "name":"supply", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"bytes4", + "name":"interfaceId", + "type":"bytes4" + } + ], + "name":"supportsInterface", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"symbol", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + }, + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"totalBorrow", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"totalDepositedProjectToken", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"totalOutstanding", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"account", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + } + ], + "name":"updateInterestInBorrowPositions", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"projectToken", + "type":"address" + }, + { + "internalType":"address", + "name":"lendingToken", + "type":"address" + }, + { + "internalType":"uint256", + "name":"projectTokenAmount", + "type":"uint256" + } + ], + "name":"withdraw", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + } + ] \ No newline at end of file diff --git a/src/adaptors/fringe-v1/index.js b/src/adaptors/fringe-v1/index.js new file mode 100644 index 0000000000..7edf03b776 --- /dev/null +++ b/src/adaptors/fringe-v1/index.js @@ -0,0 +1,196 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abiProtocol = require('./abis/protocolContractABI.json') +const abiLendingPools = require('./abis/lendingPoolsABI.json'); + +// Fringe's primary contract addy for each chain. +// The primary contract tells us the list of lending pool contracts. +const primaryContractAddys = [ + { + "chain":"ethereum", + "chainSpecificProtocolContractAddy": "0x46558DA82Be1ae1955DE6d6146F8D2c1FE2f9C5E", + "blocksPerDay": 7200 + } +]; + +const getPrices = async (chain, addresses) => { + const uri = `${addresses.map((address) => `${chain}:${address}`)}`; + + try { + const res = await axios.get('https://coins.llama.fi/prices/current/' + uri); + + const prices = res.data.coins; + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; + + } catch (error) { + console.log(error) + } +}; + +const getLenderAPY = async (chain, lendingTokenPoolAddy, blocksPerDay) => { + // Calc lender APY for this lending token. + // Lender APY for lending = (((supplyRatePerBlock / 1e18) * BLOCK_PER_DAY + 1)^DAY_PER_YEAR - 1) * 100 + + let supplyRatePerBlockRes = await sdk.api.abi.call({ + target: lendingTokenPoolAddy, + chain: chain, + abi: abiLendingPools.find((e) => e.name === 'supplyRatePerBlock') + }); + + let supplyRatePerBlock = supplyRatePerBlockRes['output']; + + return (((supplyRatePerBlock / 1e18) * blocksPerDay + 1) ** 365 - 1) * 100; +}; + +const getBorrowAPY = async (chain, lendingTokenPoolAddy, blocksPerDay) => { + // Calc borrow APY for this lending token. + // Borrow APY for lending = (((borrowRatePerBlock / 1e18) * BLOCK_PER_DAY + 1)^DAY_PER_YEAR - 1) * 100 + + + let borrowRatePerBlockRes = await sdk.api.abi.call({ + target: lendingTokenPoolAddy, + chain: chain, + abi: abiLendingPools.find((e) => e.name === 'borrowRatePerBlock') + }); + + let borrowRatePerBlock = borrowRatePerBlockRes['output']; + + return (((borrowRatePerBlock / 1e18) * blocksPerDay + 1) ** 365 - 1) * 100; +}; + +// Notes: lending tokens = our interest-bearing fTokens. + +// Get the list of lending tokens listed by Fringe, chain by chain. +const allLendingTokens = async () => { + + let lendingTokens = []; + + for (let i = 0; i < primaryContractAddys.length; i++) { + + const chainSpecific = primaryContractAddys[i]; + + // Get count of lending tokens for this chain. + let lendingTokensCountRes = await sdk.api.abi.call({ + target: chainSpecific.chainSpecificProtocolContractAddy, + chain: chainSpecific.chain, + abi: abiProtocol.find((e) => e.name === 'lendingTokensLength') + }); + let lendingTokensCount = lendingTokensCountRes['output']; + + // Add lending tokens for this chain to our full list. + for (let i = 0; i < lendingTokensCount; i++) { + + // e.g. USDC addy + let underlyingTokenAddyRes = await sdk.api.abi.call({ + target: chainSpecific.chainSpecificProtocolContractAddy, + chain: chainSpecific.chain, + params: [i], + abi: abiProtocol.find((e) => e.name === 'lendingTokens') + }); + + let underlyingTokenAddy = underlyingTokenAddyRes['output'].toLowerCase(); + + // fToken addy. e.g. fUSDC addy + let lendingTokenPoolAddyRes = await sdk.api.abi.call({ + target: chainSpecific.chainSpecificProtocolContractAddy, + chain: chainSpecific.chain, + params: [underlyingTokenAddy], + abi: abiProtocol.find((e) => e.name === 'lendingTokenInfo') + }); + + let lendingTokenPoolAddy = lendingTokenPoolAddyRes['output']['bLendingToken'].toLowerCase(); + + // e.g. USDC + let underlyingTokenSymbolRes = await sdk.api.abi.call({ + target: underlyingTokenAddy, + chain: chainSpecific.chain, + params: [], + abi: "erc20:symbol" + }); + + let underlyingTokenSymbol = underlyingTokenSymbolRes['output']; + + // Get lend APY and borrow APY for this lending token. + let lenderAPY = await getLenderAPY(chainSpecific.chain, lendingTokenPoolAddy, chainSpecific.blocksPerDay); + let borrowAPY = await getBorrowAPY(chainSpecific.chain, lendingTokenPoolAddy, chainSpecific.blocksPerDay); + + //////////// Calc TVL in USD for the lending token. + // From the lending token, get decimals. + let decimalsOfLendingTokenRes = await sdk.api.abi.call({ + target: underlyingTokenAddy, + chain: chainSpecific.chain, + params: [], + abi: "erc20:decimals" + }); + + let decimalsOfLendingToken = decimalsOfLendingTokenRes['output']; + + // From the lending token, get balance owned by our contract. + let balanceOfLendingTokenRes = await sdk.api.abi.call({ + target: underlyingTokenAddy, + chain: chainSpecific.chain, + params: [lendingTokenPoolAddy], + abi: "erc20:balanceOf" + }); + + let balanceOfLendingToken = balanceOfLendingTokenRes['output'] / 10 ** decimalsOfLendingToken; + + // Get conversion factor to USD. + let priceUSDRes = await getPrices(chainSpecific.chain, [underlyingTokenAddy]); + let priceUSD = priceUSDRes[underlyingTokenAddy]; + + // Calc the USD-equivalent. + let balanceOwnedUSD = balanceOfLendingToken * priceUSD; + + // Get total borrow of this lending token + let totalBorrowRes = await sdk.api.abi.call({ + target: lendingTokenPoolAddy, + chain: chainSpecific.chain, + abi: abiLendingPools.find((e) => e.name === 'totalBorrows') + }); + + let totalBorrow = totalBorrowRes['output'] / 10 ** decimalsOfLendingToken; + + // Calc the USD-equivalent. + let totalBorrowUSD = totalBorrow * priceUSD; + + let totalSupplyUSD = balanceOwnedUSD + totalBorrowUSD; + + // Push it good. + lendingTokens.push({ + pool: lendingTokenPoolAddy, + chain: chainSpecific.chain, + project: 'fringe-v1', + symbol: underlyingTokenSymbol, + tvlUsd: Number(balanceOwnedUSD), + apyBase: Number(lenderAPY), + apyBaseBorrow: Number(borrowAPY), + totalSupplyUsd: Number(totalSupplyUSD), + underlyingTokens: [underlyingTokenAddy], + poolMeta: "V1 markets", + totalBorrowUsd: Number(totalBorrowUSD) + }); + } + } + + // console.log('allLendingTokens\n', lendingTokens); // works all ok. + return lendingTokens; + +}; + +module.exports = { + timetravel: false, + apy: allLendingTokens, + url: 'https://app.fringe.fi/lend' +}; + + diff --git a/src/adaptors/fuel-staking/index.js b/src/adaptors/fuel-staking/index.js new file mode 100644 index 0000000000..28a0d4b201 --- /dev/null +++ b/src/adaptors/fuel-staking/index.js @@ -0,0 +1,31 @@ +const axios = require('axios'); + +const apy = async () => { + const [apyData, supplyData] = await Promise.all( + [ + 'https://mainnet-explorer.fuel.network/staking/apy', + 'https://rest-fuel-seq.simplystaking.xyz/cosmos/staking/v1beta1/pool', + ].map((i) => axios.get(i)) + ); + + const id = 'fuel-network'; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/coingecko:${id}`) + ).data.coins[`coingecko:${id}`].price; + + return [ + { + pool: '0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c', + project: 'fuel-staking', + chain: 'fuel-ignition', + symbol: 'FUEL', + apyBase: Number(apyData.data.amount), + tvlUsd: (supplyData.data.pool.bonded_tokens / 1e9) * price, + url: 'https://app.fuel.network/staking/on-fuel', + }, + ]; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/full-sail/index.js b/src/adaptors/full-sail/index.js new file mode 100644 index 0000000000..22026f4df5 --- /dev/null +++ b/src/adaptors/full-sail/index.js @@ -0,0 +1,13 @@ +const axios = require('axios'); + +const main = async () => { + let pools = await axios.get( + 'https://app.fullsail.finance/api/defi_llama/pools' + ); + + return pools.data.map((i) => ({ ...i, project: 'full-sail' })); +}; + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/fungify/abi.json b/src/adaptors/fungify/abi.json new file mode 100644 index 0000000000..60cb9a0676 --- /dev/null +++ b/src/adaptors/fungify/abi.json @@ -0,0 +1,126 @@ +{ + "getAllMarkets": "function getAllMarkets() view returns (address[])", + "cTokenMetadataAll": { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "cTokenMetadataAll", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "exchangeRateCurrent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCash", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlyingAssetAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "cTokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "compSupplySpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "compBorrowSpeed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "enum CTokenStorage.MarketType", + "name": "marketType", + "type": "uint8" + } + ], + "internalType": "struct CompoundLens.CTokenMetadata[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + "balanceOf": "function balanceOf(address) view returns (uint256)", + "totalSupply": "function totalSupply() view returns (uint256)", + "exchangeRateStored": "function exchangeRateStored() view returns (uint256)", + "underlying": "function underlying() view returns (address)", + "symbol": "function symbol() view returns (string)", + "interestMarket": "function interestMarket() view returns (address)", + "interestRateModel": "function interestRateModel() view returns (address)", + "blocksPerYear": "function blocksPerYear() view returns (uint256)", + "getUnderlyingPrice": "function getUnderlyingPrice(address) view returns (uint256)", + "getCash": "function getCash() view returns (uint256)", + "totalReserves": "function totalReserves() view returns (uint256)", + "totalBorrows": "function totalBorrows() view returns (uint256)" +} \ No newline at end of file diff --git a/src/adaptors/fungify/index.js b/src/adaptors/fungify/index.js new file mode 100644 index 0000000000..e3a2fcd40e --- /dev/null +++ b/src/adaptors/fungify/index.js @@ -0,0 +1,270 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const ABI = require('./abi.json'); + +const CHAIN = 'ethereum'; +const COMPTROLLER = '0xf9c70750bF615dE83fE7FF62D30C7faACD8f8Ba0'; +const LENS = '0x2C4A503Bce0805C357D961e45b55BEEE073188E7'; +const PRICE_ORACLE = '0x9b960808875000AC17dfAE13B72BBDF69DF6e7A7'; +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; +const SCALE = 1e18; + +// Fetch all Markets from comptroller +async function getAllMarkets() { + const cTokenMarkets = ( + await sdk.api.abi.call({ + target: COMPTROLLER, + params: [], + abi: ABI['getAllMarkets'], + chain: CHAIN, + }) + ).output; + return cTokenMarkets; +} + +// Fetch metdata for all markets +async function getCtokenMetadata(markets) { + const cTokenMetadatas = ( + await sdk.api.abi.call({ + target: LENS, + params: [markets], + abi: ABI['cTokenMetadataAll'], + chain: CHAIN, + }) + ).output; + return cTokenMetadatas; +} + +// Fetches balance of an asset for a given address +async function getBalance(assetAddress, subjectAddress) { + const underlyingBalance = ( + await sdk.api.abi.call({ + target: assetAddress, + params: [subjectAddress], + abi: ABI['balanceOf'], + chain: CHAIN, + }) + ).output; + return underlyingBalance; +} + +// Fetches the cash of a cToken +async function getTotalCash(cTokenAddress) { + const totalCash = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['getCash'], + chain: CHAIN, + }) + ).output; + return totalCash; +} + +// Fetches the total reserves of a cToken +async function getTotalReserves(cTokenAddress) { + const totalReserves = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['totalReserves'], + chain: CHAIN, + }) + ).output; + return totalReserves; +} + +// Fetches the total borrows of a cToken +async function getTotalBorrows(cTokenAddress) { + const totalBorrows = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['totalBorrows'], + chain: CHAIN, + }) + ).output; + return totalBorrows; +} + +// Fetches the cToken to underlying exchange rate of the asset +async function getExchangeRate(cTokenAddress) { + const exchangeRate = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['exchangeRateStored'], + chain: CHAIN, + }) + ).output; + return exchangeRate; +} + +// Gets the underlying asset of a cToken +async function getUnderlyingAsset(cTokenAddress) { + const underlyingAddress = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['underlying'], + chain: CHAIN, + }) + ).output; + return underlyingAddress; +} + +// Gets the symbol of the market token +async function getSymbol(cTokenAddress) { + const symbol = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['symbol'], + chain: CHAIN, + }) + ).output; + return symbol; +} + +// Gets the interestMarket for cErc721s +async function getInterestMarket() { + const interestMarket = ( + await sdk.api.abi.call({ + target: COMPTROLLER, + params: [], + abi: ABI['interestMarket'], + chain: CHAIN, + }) + ).output; + return interestMarket; +} + +// Gets the interestRateModel (used for blocksPerYear) +async function getInterestRateModel(cTokenAddress) { + const interestRateModel = ( + await sdk.api.abi.call({ + target: cTokenAddress, + params: [], + abi: ABI['interestRateModel'], + chain: CHAIN, + }) + ).output; + return interestRateModel; +} + +// Gets the blockPerYear for apys +async function getBlocksPerYear(interestRateModel) { + const blocksPerYear = ( + await sdk.api.abi.call({ + target: interestRateModel, + params: [], + abi: ABI['blocksPerYear'], + chain: CHAIN, + }) + ).output; + return blocksPerYear; +} + +async function getUnderlyingPrice(cTokenAddress) { + const underlyingPrice = ( + await sdk.api.abi.call({ + target: PRICE_ORACLE, + params: [cTokenAddress], + abi: ABI['getUnderlyingPrice'], + chain: CHAIN, + }) + ).output; + return underlyingPrice; +} + +// Creates a pool dictionary of the proper format +async function poolStruct( + poolIdentifier, + chain, + symbol, + tvlUsd, + totalBorrowsUsd, + totalSuppliesUsd, + apy, + underlyingTokens, + apyBorrow, + ltv +) { + return { + pool: poolIdentifier, // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase() + chain: chain, // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) + project: 'fungify', // protocol (using the slug again) + symbol: symbol, // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP + tvlUsd: tvlUsd, // number representing current USD free liquidity in pool + totalBorrowUsd: totalBorrowsUsd, // number representing current USD borrows in pool + totalSupplyUsd: totalSuppliesUsd, // number representing current USD supplies in pool + apyBase: apy, // APY from pool fees/supplying in % + underlyingTokens: underlyingTokens, // Array of underlying token addresses from a pool, eg here USDT address on ethereum // Array; + url: 'https://app.fungify.it/pools', // URL for app + apyBaseBorrow: apyBorrow, // Borrow APR + ltv: ltv, // Collateral Factor + }; +} + +// Fetches the apy for all markets +async function poolsAPY() { + const markets = await getAllMarkets(); + const cTokenMetadatas = await getCtokenMetadata(markets); + const interestMarket = await getInterestMarket(); + const interestToken = await getUnderlyingAsset(interestMarket); + let pools = []; + + // Iterates through each market's metadata calculating the APY + for (const cTokenMetaData of cTokenMetadatas) { + const cTokenAddress = cTokenMetaData.cToken; + const symbol = await getSymbol(cTokenAddress); + if (symbol.includes('_NB')) continue; // Excludes no borrow markets since they will always have 0% APY + + let underlyingAsset = cTokenMetaData.underlyingAssetAddress; + const marketType = cTokenMetaData.marketType; + + const interestRateModel = await getInterestRateModel(cTokenAddress); + const supplyRatePerBlock = cTokenMetaData.supplyRatePerBlock; + const borrowRatePerBlock = cTokenMetaData.borrowRatePerBlock; + const blocksPerYear = await getBlocksPerYear(interestRateModel); + const apy = ((supplyRatePerBlock * blocksPerYear) / SCALE) * 100; + const apyBorrow = ((borrowRatePerBlock * blocksPerYear) / SCALE) * 100; + + const ltv = cTokenMetaData.collateralFactorMantissa / SCALE; + const underlyingPrice = await getUnderlyingPrice(cTokenAddress); + const poolIdentifier = `${cTokenAddress}-${CHAIN}`.toLowerCase(); + + const totalCash = Number(await getTotalCash(cTokenAddress)); + const totalBorrows = Number(await getTotalBorrows(cTokenAddress)); + const totalReserves = Number(await getTotalReserves(cTokenAddress)); + + const tvlUsd = + ((totalCash - totalReserves) * underlyingPrice) / SCALE / SCALE; + const totalBorrowsUsd = (totalBorrows * underlyingPrice) / SCALE / SCALE; + const totalSuppliesUsd = + ((totalCash + totalBorrows - totalReserves) * underlyingPrice) / + SCALE / + SCALE; + + let poolInfo = await poolStruct( + poolIdentifier, + CHAIN, + symbol, + tvlUsd, + totalBorrowsUsd, + totalSuppliesUsd, + apy, + [underlyingAsset], + apyBorrow, + ltv + ); + pools.push(poolInfo); + } + return pools; +} + +module.exports = { + timetravel: false, + apy: poolsAPY, + url: 'https://app.fungify.it/pools', +}; diff --git a/src/adaptors/fvm-exchange/abis/Gauge.json b/src/adaptors/fvm-exchange/abis/Gauge.json new file mode 100644 index 0000000000..dee27f85f4 --- /dev/null +++ b/src/adaptors/fvm-exchange/abis/Gauge.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_stake","type":"address"},{"internalType":"address","name":"_external_bribe","type":"address"},{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_oFlow","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"bool","name":"_forPair","type":"bool"},{"internalType":"address[]","name":"_allowedRewardTokens","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oFlow","type":"address"}],"name":"OFlowSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceWithLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchUpdateRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"balanceOf","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_lockDuration","type":"uint256"}],"name":"depositWithLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"derivedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"derivedBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derivedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"external_bribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorBalanceIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorRewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorSupplyIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isForPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"lastEarn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"left","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oFlow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerTokenCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"rewardPerToken","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oFlow","type":"address"}],"name":"setOFlow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supplyCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"},{"internalType":"address","name":"oldToken","type":"address"},{"internalType":"address","name":"newToken","type":"address"}],"name":"swapOutRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/fvm-exchange/abis/Option.json b/src/adaptors/fvm-exchange/abis/Option.json new file mode 100644 index 0000000000..22aa26c27e --- /dev/null +++ b/src/adaptors/fvm-exchange/abis/Option.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"},{"internalType":"address","name":"_underlyingToken","type":"address"},{"internalType":"contract IPair","name":"_pair","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_votingEscrow","type":"address"},{"internalType":"address","name":"_router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"OptionToken_IncorrectPairToken","type":"error"},{"inputs":[],"name":"OptionToken_InvalidDiscount","type":"error"},{"inputs":[],"name":"OptionToken_InvalidLockDuration","type":"error"},{"inputs":[],"name":"OptionToken_InvalidTeamFee","type":"error"},{"inputs":[],"name":"OptionToken_InvalidTwapPoints","type":"error"},{"inputs":[],"name":"OptionToken_NoAdminRole","type":"error"},{"inputs":[],"name":"OptionToken_NoMinterRole","type":"error"},{"inputs":[],"name":"OptionToken_NoPauserRole","type":"error"},{"inputs":[],"name":"OptionToken_PastDeadline","type":"error"},{"inputs":[],"name":"OptionToken_Paused","type":"error"},{"inputs":[],"name":"OptionToken_SlippageTooHigh","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"}],"name":"Exercise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"}],"name":"ExerciseLp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"ExerciseVe","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"discount","type":"uint256"}],"name":"SetDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGauge","type":"address"}],"name":"SetGauge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockDurationForMaxLpDiscount","type":"uint256"}],"name":"SetLockDurationForMaxLpDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockDurationForMinLpDiscount","type":"uint256"}],"name":"SetLockDurationForMinLpDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lpMaxDiscount","type":"uint256"}],"name":"SetMaxLPDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lpMinDiscount","type":"uint256"}],"name":"SetMinLPDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IPair","name":"newPair","type":"address"},{"indexed":true,"internalType":"address","name":"newPaymentToken","type":"address"}],"name":"SetPairAndPaymentToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newRouter","type":"address"}],"name":"SetRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"SetTeamFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"SetTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"twapPoints","type":"uint256"}],"name":"SetTwapPoints","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"veDiscount","type":"uint256"}],"name":"SetVeDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FULL_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DISCOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TEAM_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TWAP_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_DISCOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exercise","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"exercise","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_discount","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exerciseLp","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exerciseVe","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getLockDurationForLpDiscount","outputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getLpDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getPaymentTokenAmountForExerciseLp","outputs":[{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"uint256","name":"paymentAmountToAddLiquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSlopeInterceptForLpDiscount","outputs":[{"internalType":"int256","name":"slope","type":"int256"},{"internalType":"int256","name":"intercept","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getTimeWeightedAveragePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getVeDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDurationForMaxLpDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDurationForMinLpDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLPDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minLPDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"contract IPair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paymentToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"setGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setLockDurationForMaxLpDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setLockDurationForMinLpDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpMaxDiscount","type":"uint256"}],"name":"setMaxLPDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpMinDiscount","type":"uint256"}],"name":"setMinLPDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPair","name":"_pair","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"}],"name":"setPairAndPaymentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setTeamFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_twapPoints","type":"uint256"}],"name":"setTwapPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_veDiscount","type":"uint256"}],"name":"setVeDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlyingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingEscrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/fvm-exchange/abis/Pair.json b/src/adaptors/fvm-exchange/abis/Pair.json new file mode 100644 index 0000000000..831cb3c121 --- /dev/null +++ b/src/adaptors/fvm-exchange/abis/Pair.json @@ -0,0 +1,1041 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/fvm-exchange/abis/PairFactory.json b/src/adaptors/fvm-exchange/abis/PairFactory.json new file mode 100644 index 0000000000..66b19b7628 --- /dev/null +++ b/src/adaptors/fvm-exchange/abis/PairFactory.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pauser","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"tank","type":"address"}],"name":"TankSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"voter","type":"address"}],"name":"VoterSet","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesOverrides","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFeesOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tank","type":"address"}],"name":"setTank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"}],"name":"setVoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tank","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/fvm-exchange/abis/Voter.json b/src/adaptors/fvm-exchange/abis/Voter.json new file mode 100644 index 0000000000..7a6eab7994 --- /dev/null +++ b/src/adaptors/fvm-exchange/abis/Voter.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_gauges","type":"address"},{"internalType":"address","name":"_bribes","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Abstained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Attach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"blacklister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"address","name":"newBribeFatory","type":"address"}],"name":"BribeFactorySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Detach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"externalBribe","type":"address"}],"name":"ExternalBribeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"pairFactory","type":"address"},{"indexed":true,"internalType":"address","name":"gaugeFactory","type":"address"}],"name":"FactoryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"FactoryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"pairFactory","type":"address"},{"indexed":true,"internalType":"address","name":"gaugeFactory","type":"address"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"FactoryReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"external_bribe","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"GaugeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeKilledTotally","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeRestarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_factories","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gaugeFactories","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_killedGauges","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"}],"name":"addFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"attachTokenToGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"blacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribefactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bribes","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimBribes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint256","name":"_gaugeType","type":"uint256"}],"name":"createGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"detachTokenFromGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"finish","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distro","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"external_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"factories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"gaugeFactories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactoriesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_minter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAlive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGaugeFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"killGaugeTotally","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"killedGauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"killedGaugesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastVoted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"pauseGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"poke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolForGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolVote","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pos","type":"uint256"}],"name":"removeFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"uint256","name":"_pos","type":"uint256"}],"name":"replaceFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"reset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"restartGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bribeFactory","type":"address"}],"name":"setBribeFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_council","type":"address"}],"name":"setEmergencyCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_external","type":"address"}],"name":"setExternalBribeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"name":"setGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"updateFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"updateForRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedWeights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"_poolVote","type":"address[]"},{"internalType":"uint256[]","name":"_weights","type":"uint256[]"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/fvm-exchange/index.js b/src/adaptors/fvm-exchange/index.js new file mode 100644 index 0000000000..385791afbb --- /dev/null +++ b/src/adaptors/fvm-exchange/index.js @@ -0,0 +1,259 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const abiPairFactory = require('./abis/PairFactory.json'); +const abiGauge = require('./abis/Gauge.json'); +const abiPair = require('./abis/Pair.json'); +const abiVoter = require('./abis/Voter.json'); +const abiOption = require('./abis/Option.json'); + +const pairFactory = '0x472f3C3c9608fe0aE8d702f3f8A2d12c410C881A'; +const voter = '0xc9Ea7A2337f27935Cd3ccFB2f725B0428e731FBF'; + +const chain = 'fantom'; + +const oFVM = '0xF9EDdca6B1e548B0EC8cDDEc131464F462b8310D'; +const FVM = '0x07BB65fAaC502d4996532F834A1B7ba5dC32Ff96'; + +// option to buy underlying token at a discount +// we'll need to update this if more options are added as there's no way to get the list of options from the contracts +const optionTokenToGovToken = { + [oFVM.toLowerCase()]: FVM.toLowerCase(), // oFVM - fvm + ['0xC5d4E462b96cC73283EB452B15147c17Af413313'.toLowerCase()]: + '0x2A5E4c77F791c0174a717B644A53fc21A29790Cd'.toLowerCase(), // oBLOTR - blotr + ['0x269557D887EaA9C1a756B2129740B3FC2821fD91'.toLowerCase()]: + '0xE5a4c0af6F5f7Ab5d6C1D38254bCf4Cc26d688ed'.toLowerCase(), // oBAY - bay +}; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain, + }) + ).output.map((o) => o.output); + + const tokens = [...new Set(metaData.map((m) => [m.t0, m.t1]).flat())].map( + (t) => t.toLowerCase() + ); + + const priceKeys = tokens.map((i) => `${chain}:${i}`).join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const optionTokens = Object.keys(optionTokenToGovToken); + // get discount for redeeming option token to liquidity token + const discounts = ( + await sdk.api.abi.multiCall({ + calls: optionTokens.map((optionToken) => ({ + target: optionToken, + })), + abi: abiOption.find((m) => m.name === 'discount'), + chain, + }) + ).output + .map((o) => 100 - parseFloat(o.output)) + .map((discount, index) => ({ + [optionTokens[index]]: discount, + })); + + // calculate profit from option token + // oTokenPrice = (underlyingTokenPrice * discount) / 100 + /** + * @type {Object.} + */ + const optionTokenPrices = optionTokens + .map((optionToken, index) => { + const underlyingToken = optionTokenToGovToken[optionToken]; + const underlyingTokenPrice = + prices[`${chain}:${underlyingToken.toLowerCase()}`]?.price; + + const discount = discounts[index][optionToken]; + return (underlyingTokenPrice * discount) / 100; + }) + .reduce((acc, cur, index) => { + acc[optionTokens[index]] = isNaN(cur) ? 0 : cur; + return acc; + }, {}); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardsListLengthForGauges = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewardsListLength'), + calls: gauges.map((i) => ({ + target: i, + })), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + // one gauge might have multiple reward tokens + const rewardTokensAndRates = await Promise.all( + // get all reward tokens for each gauge + rewardsListLengthForGauges.map(async (i, index) => { + const gauge = gauges[index]; + return ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewards'), + calls: [...Array(Number(i ?? 0)).keys()].map((j) => ({ + target: gauge, + params: [j], + })), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + }) + ).then(async (rewardTokensForGauges) => { + // get reward rate of each reward token + return await Promise.all( + rewardTokensForGauges.map(async (rewardTokensOfGauge, index) => { + const rates = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewardRate'), + calls: rewardTokensOfGauge.map((rewardToken) => ({ + target: gauges[index], + params: [rewardToken], + })), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const left = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'left'), + calls: rewardTokensOfGauge.map((rewardToken) => ({ + target: gauges[index], + params: [rewardToken], + })), + chain, + }) + ).output.map((o) => o.output); + + return rates.map((rate, index) => { + // if left is 0, the reward rate will be 0 + if (left[index] === '0') { + return '0'; + } + return rate; + }); + }) + ).then((rewardRatesForGauges) => { + return rewardRatesForGauges.map((rewardRatesOfGauge, index) => { + const rewardTokensOfGauge = rewardTokensForGauges[index]; + return rewardRatesOfGauge.map((rate, index) => { + const rewardToken = rewardTokensOfGauge[index].toLowerCase(); + if (rewardToken === FVM.toLowerCase()) { + // FVM reward will be converted to oFVM when claiming + return [oFVM, rate]; + } + return [rewardToken, rate]; + }); + }); + }); + }); + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`${chain}:${poolMeta.t0.toLowerCase()}`]?.price; + const p1 = prices[`${chain}:${poolMeta.t1.toLowerCase()}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const totalRewardPerDay = rewardTokensAndRates[i].reduce( + (acc, [rewardToken, rewardRate]) => { + let tokenPrice = 0; + if (optionTokenPrices[rewardToken.toLowerCase()]) { + tokenPrice = optionTokenPrices[rewardToken.toLowerCase()]; + } else if (prices[`${chain}:${rewardToken.toLowerCase()}`]) { + tokenPrice = prices[`${chain}:${rewardToken.toLowerCase()}`]?.price; + } + + const reward = ((rewardRate * 60 * 60 * 24) / 1e18) * tokenPrice; + + return acc + reward; + }, + 0 + ); + + // tvlUsd is used here instead of stakedUsd + const apyReward = ((totalRewardPerDay * 365) / tvlUsd) * 100; + + const rewardTokens = rewardTokensAndRates[i] + .filter(([token, rate]) => rate !== '0') + .map(([token]) => token.toLowerCase()); + return { + pool: p, + chain: utils.formatChain(chain), + project: 'fvm-exchange', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [...new Set(rewardTokens)] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + url: `https://www.fvm.exchange/liquidity/${p}`, + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.fvm.exchange/liquidity', +}; diff --git a/src/adaptors/fx-protocol/abis/Common.json b/src/adaptors/fx-protocol/abis/Common.json new file mode 100644 index 0000000000..7f4cffdd96 --- /dev/null +++ b/src/adaptors/fx-protocol/abis/Common.json @@ -0,0 +1,58 @@ +{ + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalSupply": { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + "getCurrentNav": { + "inputs": [], + "name": "getCurrentNav", + "outputs": [ + { + "internalType": "uint256", + "name": "_baseNav", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fNav", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_xNav", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "tokensPerStEth": { + "inputs": [], + "name": "tokensPerStEth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/fx-protocol/abis/reBalance.json b/src/adaptors/fx-protocol/abis/reBalance.json new file mode 100644 index 0000000000..d049275271 --- /dev/null +++ b/src/adaptors/fx-protocol/abis/reBalance.json @@ -0,0 +1,41 @@ +{ + "extraRewardState": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "extraRewardState", + "outputs": [ + { + "internalType": "uint128", + "name": "rate", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "periodLength", + "type": "uint32" + }, + { + "internalType": "uint48", + "name": "lastUpdate", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "finishAt", + "type": "uint48" + }, + { + "internalType": "uint256", + "name": "queued", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/fx-protocol/index.js b/src/adaptors/fx-protocol/index.js new file mode 100644 index 0000000000..6abfd1d653 --- /dev/null +++ b/src/adaptors/fx-protocol/index.js @@ -0,0 +1,65 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const CommonAbi = require('./abis/Common.json'); +const reBalanceAbi = require('./abis/reBalance.json'); + +const ALADDIN_API_BASE_URL = 'https://api.aladdin.club/'; + +const getRebalancePoolData = async () => { + let RebalancePoolData = await utils.getData( + `${ALADDIN_API_BASE_URL}api1/fx_rebalance_tvl_apy` + ); + const newObj = Object.keys(RebalancePoolData.data).map((item) => { + const { name, underlyingTokens, rebalancePoolAddress, apy, tvl } = + RebalancePoolData.data[item]; + + const n = name.split('_'); + const symbol = n[0]; + const poolMeta = n.slice(1).join(' '); + return { + pool: `${rebalancePoolAddress}-f(x)`, + chain: utils.formatChain('ethereum'), + project: 'fx-protocol', + symbol, + poolMeta, + tvlUsd: parseInt(tvl, 10), + apy: parseFloat(apy), + underlyingTokens: underlyingTokens, + }; + }); + return newObj; +}; + +const getGaugePoolData = async () => { + let RebalancePoolData = await utils.getData( + `${ALADDIN_API_BASE_URL}api1/fx_gauge_tvl_apy` + ); + const newObj = RebalancePoolData.data.map((data) => { + const { gauge, name, tvl, apy } = data; + return { + pool: `${gauge}-f(x)`, + chain: utils.formatChain('ethereum'), + project: 'fx-protocol', + symbol: utils.formatSymbol(name), + tvlUsd: parseInt(tvl, 10), + apy: parseFloat(apy), + }; + }); + + return newObj; +}; + +const main = async () => { + const rebalancedata = await getRebalancePoolData(); + const gaugeData = await getGaugePoolData(); + const data = [].concat(rebalancedata).concat(gaugeData); + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://fx.aladdin.club/rebalance-pool/', +}; diff --git a/src/adaptors/gains-network/index.js b/src/adaptors/gains-network/index.js new file mode 100644 index 0000000000..53e3205348 --- /dev/null +++ b/src/adaptors/gains-network/index.js @@ -0,0 +1,131 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const chains = { + polygon: { + gns: '0xE5417Af564e4bFDA1c483642db72007871397896', + staking: '0x8C74B2256fFb6705F14aDA8E86FBd654e0e2BECa', + vaults: [ + { + symbol: 'DAI', + pool: '0x91993f2101cc758D0dEB7279d41e880F7dEFe827', + underlying: '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063', + }, + { + symbol: 'WETH', + pool: '0x1544E1fF1a6f6Bdbfb901622C12bb352a43464Fb', + underlying: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + }, + { + symbol: 'USDC', + pool: '0x29019Fe2e72E8d4D2118E8D0318BeF389ffe2C81', + underlying: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', + }, + ], + }, + arbitrum: { + gns: '0x18c11FD286C5EC11c3b683Caa813B77f5163A122', + staking: '0x7edDE7e5900633F698EaB0Dbc97DE640fC5dC015', + vaults: [ + { + symbol: 'DAI', + pool: '0xd85E038593d7A098614721EaE955EC2022B9B91B', + underlying: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + }, + { + symbol: 'WETH', + pool: '0x5977A9682D7AF81D347CFc338c61692163a2784C', + underlying: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + { + symbol: 'USDC', + pool: '0xd3443ee1e91aF28e5FB858Fbd0D72A63bA8046E0', + underlying: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + }, + ], + }, + base: { + gns: '0xFB1Aaba03c31EA98A3eEC7591808AcB1947ee7Ac', + staking: '0x28efAa11199DAF45AA8fBf95f920e5bc090DCbF3', + vaults: [ + { + symbol: 'USDC', + pool: '0xad20523A7dC37bAbc1CC74897E4977232b3D02e5', + underlying: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + }, + ], + }, +}; + +const getApy = async () => { + const results = await Promise.all( + Object.keys(chains).map(async (chain) => { + try { + const y = chains[chain]; + const data = ( + await axios.get(`https://backend-${chain}.gains.trade/apr`) + ).data; + const priceKeys = [y.gns, ...y.vaults.map((i) => i.underlying)].map( + (i) => `${chain}:${i}` + ); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const balance = + ( + await sdk.api.abi.call({ + target: y.gns, + abi: 'erc20:balanceOf', + params: [y.staking], + chain, + }) + ).output / 1e18; + + const gnsStaking = { + chain, + project: 'gains-network', + pool: y.staking, + symbol: 'GNS', + tvlUsd: balance * prices[`${chain}:${y.gns}`].price, + apyBase: utils.aprToApy(data.sssApr), + underlyingTokens: [y.gns], + }; + + const vaults = data.collateralRewards.flatMap((i) => { + const addresses = y.vaults.find((v) => v.symbol === i.symbol); + if (!addresses) return []; + + const priceData = prices[`${chain}:${addresses.underlying}`]; + const tvlUsd = + Number(i.vaultTvl / 10 ** priceData.decimals) * priceData.price; + + return [ + { + chain, + project: 'gains-network', + pool: addresses.pool, + symbol: i.symbol, + tvlUsd, + apyBase: utils.aprToApy(i.vaultApr), + underlyingTokens: [addresses.underlying], + }, + ]; + }); + + return [gnsStaking, ...vaults]; + } catch (error) { + console.error(`Error fetching APY data for ${chain}:`, error); + return []; + } + }) + ); + + return results.flat(); +}; + +module.exports = { + apy: getApy, + url: 'https://gains.trade/vaults', +}; diff --git a/src/adaptors/gamma/index.js b/src/adaptors/gamma/index.js new file mode 100644 index 0000000000..7941e9ecce --- /dev/null +++ b/src/adaptors/gamma/index.js @@ -0,0 +1,402 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { print } = require('graphql'); + +const EXCHANGES_API = { + uniswapv3: '', + quickswap: 'quickswap/', + zyberswap: 'zyberswap/', + thena: 'thena/', + camelot: 'camelot/', + retro: 'retro/', + stellaswap: 'stellaswap/', + beamswap: 'beamswap/', + spiritswap: 'spiritswap/', + sushiswap: 'sushi/', + ramses: 'ramses/', + fusionx: 'fusionx/', + synthswap: 'synthswap/', + lynex: 'lynex/', + pegasys: 'pegasys/', + basex: 'basex/', + pancakeswap: 'pancakeswap/', + hercules: 'hercules/', + baseswap: 'baseswap/', + swapbased: 'swapbased/', + pharaoh: 'pharaoh/', + swapr: 'swapr/', + thick: 'thick/', + cleopatra: 'cleopatra/', +}; +const EXCHANGES_CHAINS = { + uniswapv3: ["ethereum", "optimism", "polygon", "arbitrum", "celo", "bsc", "moonbeam", "bob"], + quickswap: ["polygon", "polygon_zkevm", "manta"], + zyberswap: ["arbitrum"], + thena: ["bsc"], + camelot: ["arbitrum"], + retro: ["polygon"], + stellaswap: ["moonbeam"], + beamswap: ["moonbeam"], + spiritswap: ["fantom"], + sushiswap: ["polygon", "arbitrum", "base"], + ramses: ["arbitrum"], + fusionx: ["mantle"], + synthswap: ["base"], + lynex: ["linea"], + pegasys: ["rollux"], + basex: ["base"], + pancakeswap: ["ethereum", "arbitrum", "bsc", "base", "op_bnb"], + aperture: ["manta"], + hercules: ["metis"], + baseswap: ["base"], + swapbased: ["base"], + pharaoh: ["avax"], + swapr: ["xdai"], + thick: ["base"], + cleopatra: ["mantle"], +}; +const CHAINS_API = { + ethereum: '', + polygon: 'polygon/', + polygon_zkevm: 'polygon-zkevm/', + optimism: 'optimism/', + arbitrum: 'arbitrum/', + celo: 'celo/', + bsc: 'bsc/', + moonbeam: 'moonbeam/', + avax: 'avalanche/', + fantom: 'fantom/', + mantle: 'mantle/', + rollux: 'rollux/', + linea: 'linea/', + base: 'base/', + kava: 'kava/', + op_bnb: 'opbnb/', + manta: 'manta/', + metis: 'metis/', + xdai: 'gnosis/', + bob: 'bob/', +}; +const CHAIN_IDS = { + ethereum: 1, + polygon: 137, + polygon_zkevm: 1101, + optimism: 10, + arbitrum: 42161, + celo: 42220, + bsc: 56, + moonbeam: 1284, + avax: 43114, + fantom: 250, + mantle: 5000, + rollux: 570, + linea: 59144, + base: 8453, + kava: 2222, + op_bnb: 204, + manta: 169, + metis: 1088, + xdai: 100, + bob: 60808, +}; +const UNISWAP_FEE = { + "100": "0.01%", + "500": "0.05%", + "1000": "0.1%", + "3000": "0.3%", + "10000": "1%", + "0": "" +} +var pools_processed = []; // unique pools name +// v1 pools (read only) and private hypervisors ( non retail) +const blacklist = { + ethereum: ["0xd930ab15c8078ebae4ac8da1098a81583603f7ce", + "0xdbaa93e030bf2983add67c851892a9e2ee51e66a", + "0x586880065937a0b1b9541723619b75739df8ef13", + "0x33412fef1af035d6dba8b2f9b33b022e4c31dbb4", + "0xf6eeca73646ea6a5c878814e6508e87facc7927c", + "0x336d7e0a0f87e2729c0080f86801e6f4becf146f", + "0xc86b1e7fa86834cac1468937cdd53ba3ccbc1153", + "0x85cbed523459b7f6f81c11e710df969703a8a70c", + "0x7f92463e24b2ea1f7267aceed3ad68f7a956d2d8", + "0x23c85dca3d19b31f14aeea19beac32c2cb2ffc72", + "0x5230371a6d5311b1d7dd30c0f5474c2ef0a24661", + "0xc14e7ec60699a39cfd59bae06168afc2c76f32ac", + "0xbff4a47a0f77637f735e3a0ce10ff2bf9be12e89", + "0x93acb12ae1effb3426220c20c6d408eeaae59d72", + "0x65bc5c6a2630a87c2b494f36148e338dd76c054f", + "0xed354a827d99992d9cdada809449985cb73b8bb1", + "0xb666bfdb553a1aff4042c1e4f39e43852ba9731d", + "0xbb9b86a75ca3115caab045e2af17b0bba483acbc", + "0x0407c810546f1dc007f01a80e65983072d5c6dfa", + "0x4564a37c88e3b13d3a0c08832dcf88278997e6fe", + "0xd8dbdb77305898365d7ba6dd438f2663f7d4e409", + "0x33682bfc1d94480a0e3de0a565180b182b71d485", + "0x53a4512bbe5083695d8e890789fe1cf6f5686d52", + "0x09b8d86c6275e707155cdb5963cf611a432ccb21", + "0xc92ff322c8a18e38b46393dbcc8a7c5691586497", + "0x6e67bb258b6485b688cbb526c868d4428b634cf1", + "0x18d3284d9eff64fc97b64ab2b871738e684aa151", + "0x407e99b20d61f245426031df872966953909e9d3", + "0x97491b65c9c8e8754b5c55ed208ff490b2ee6190", + "0x6c8116abe5c5f2c39553c6f4217840e71462539c", + "0x716bd8a7f8a44b010969a1825ae5658e7a18630d", + "0x9a98bffabc0abf291d6811c034e239e916bbcec0", + "0xe065ff6a26f286ddb0e823920caaecd1fcd57ba1", + "0x5d40e4687e36628267854d0b985a9b6e26493b74", + "0xf0a9f5c64f80fa390a46b298791dab9e2bb29bca", + "0xe14dbb7d054ff1ff5c0cd6adac9f8f26bc7b8945", + "0xa625ea468a4c70f13f9a756ffac3d0d250a5c276", + ], + polygon: [], + polygon_zkevm: [], + optimism: [], + arbitrum: [], + celo: [], + bsc: [], + moonbeam: [], + avax: [], + fantom: [], + mantle: [], + rollux: [], + linea: [], + base: [], + kava: [], + op_bnb: [], + manta: [], + metis: [], + xdai: [], + bob: [], +}; +const masterchef_blacklist = { + ethereum: [], + polygon: ["0x5ca8b7eb3222e7ce6864e59807ddd1a3c3073826", "0x9c64060cac9a20a44dbf9eff47bd4de7d049877d"], + polygon_zkevm: [], + optimism: ["0x097264485014bad028890b6e03ad2dc72bd43bf2", "0x3c21bc5d9fdbb395feba595c5c8ee803fcee84cf"], + arbitrum: [], + celo: [], + bsc: [], + moonbeam: [], + avax: [], + fantom: [], + mantle: [], + rollux: [], + linea: [], + base: [], + kava: [], + op_bnb: [], + manta: [], + metis: [], + xdai: [], + bob: [], +}; +const getUrl_allData = (chain, exchange) => + `https://wire2.gamma.xyz/${exchange}${chain}hypervisors/allData`; + +const getUrl_allRewards2 = (chain, exchange) => + `https://wire2.gamma.xyz/${exchange}${chain}allRewards2` + +const pairsToObj = (pairs) => + pairs.reduce((acc, [el1, el2]) => ({ ...acc, [el1]: el2 }), {}); + +const getApy = async () => { + + var hype_allData = {}; + for (const [exchange, chains] of Object.entries(EXCHANGES_CHAINS)) { + try { + let tmp_dict = pairsToObj( + await Promise.all( + Object.values(chains).map(async (chain) => [ + chain, + await utils.getData(getUrl_allData(CHAINS_API[chain], EXCHANGES_API[exchange])), + ]) + ) + ); + + Object.entries(tmp_dict).forEach(([chain, hypervisors]) => { + // include exchange to hypervisor dta + Object.entries(hypervisors).forEach(([hyp_id, hyp_dta]) => { hyp_dta["dex"] = exchange }); + + + if (chain in hype_allData) { + hype_allData[chain] = Object.assign(hype_allData[chain], hypervisors); + } else { + hype_allData[chain] = hypervisors; + }; + + }); + + + } catch (error) { console.log(error) }; + + // try add rewards + try { + + let tmp_rwrds_dict = await Promise.allSettled( + Object.values(chains).map(async (chain) => [ + chain, + await utils.getData(getUrl_allRewards2(CHAINS_API[chain], EXCHANGES_API[exchange])), + ]) + ).then((results) => { + results.forEach((result) => { + if (result.status == "fulfilled") { + // result.value[0] = chain + // result.value[1] = items + Object.entries(result.value[1]).forEach(([chef_id, chef_dta]) => { + if (masterchef_blacklist[result.value[0]].indexOf(chef_id) == -1) { + Object.entries(chef_dta["pools"]).forEach(([k, v]) => { + if (k in hype_allData[result.value[0]]) { + if (!("apr_rewards2" in hype_allData[result.value[0]][k])) { + hype_allData[result.value[0]][k]["apr_rewards2"] = []; + } + hype_allData[result.value[0]][k]["apr_rewards2"].push(v); + } + }); + } + }); + } + }) + + }); + + } catch (error) { console.log(error) }; + }; + + const tokens = Object.entries(hype_allData).reduce( + (acc, [chain, hypervisors]) => ({ + ...acc, + [chain]: [ + ...new Set( + Object.values(hypervisors) + .map((hypervisor) => [hypervisor.token0, hypervisor.token1]) + .flat() + ), + ], + }), + {} + ); + + let keys = []; + for (const key of Object.keys(tokens)) { + keys.push(tokens[key].map((t) => `${key}:${t}`)); + } + keys = [...new Set(keys.flat())] + + const maxSize = 50; + const pages = Math.ceil(keys.length / maxSize); + let pricesA = []; + let url = ''; + for (const p of [...Array(pages).keys()]) { + url = keys + .slice(p * maxSize, maxSize * (p + 1)) + .join(',') + .toLowerCase() + pricesA = [ + ...pricesA, + (await superagent.get(`https://coins.llama.fi/prices/current/${url}`)) + .body.coins, + ]; + } + let prices = {}; + for (const p of pricesA) { + prices = { ...prices, ...p }; + } + + const pools = Object.keys(hype_allData).map((chain) => { + + const chainAprs = Object.keys(hype_allData[chain]).filter((function (hypervisor_id) { + if (blacklist[chain].indexOf(hypervisor_id) >= 0) { + return false; + } else { + return true; + }; + })).map((hypervisor_id) => { + + // MAIN CALC + const hypervisor = hype_allData[chain][hypervisor_id] + const TVL = + hypervisor.tvl0 * prices[`${chain}:${hypervisor.token0}`]?.price + + hypervisor.tvl1 * prices[`${chain}:${hypervisor.token1}`]?.price; + const apy = hypervisor["returns"]["daily"]["feeApy"]; + const apr = hypervisor["returns"]["daily"]["feeApr"]; + const TVL_alternative = Number(hypervisor.tvlUSD); + + // rewards + let apr_rewards2 = 0; + const rewards2_tokens = new Set(); + try { + + hype_allData[chain][hypervisor_id]["apr_rewards2"].forEach((item) => { + // sum of all + apr_rewards2 += item["apr"] + // add token addresses + Object.entries(item["rewarders"]).forEach(([k, v]) => { + rewards2_tokens.add(v["rewardToken"]) + }); + } + ); + } catch (error) { }; + + // create a unique pool name + var pool_name = hypervisor_id; + if (pools_processed.indexOf(pool_name) >= 0) { + pool_name = `${hypervisor_id}-${chain === 'polygon_zkevm' ? 'Polygon_zkevm' : utils.formatChain(chain)}` + }; + pools_processed.push(pool_name); + + // create a symbol + var symbol_name = hypervisor.name + let fee_name = '' + // uniswap (fee%) quickswap no fee + try { + var symbol_spl = hypervisor.name.split("-"); + fee_name = `${UNISWAP_FEE[symbol_spl[symbol_spl.length - 1]]}`; + if (fee_name == " undefined" || fee_name == "undefined") { + fee_name = ""; + }; + symbol_spl.pop(); + symbol_name = symbol_spl.join("-"); + //symbol_name = `${prices[`${chain}:${hypervisor.token0}`]?.symbol}-${prices[`${chain}:${hypervisor.token1}`]?.symbol}${fee_name}`; + if (symbol_name.includes("undefined")) { + symbol_name = hypervisor.name + } + } catch { + symbol_name = hypervisor.name + }; + + + return { + pool: pool_name, + chain: utils.formatChain(chain), + project: 'gamma', + symbol: `${symbol_name}`, + tvlUsd: TVL || TVL_alternative, + apyBase: apr * 100 || apy * 100, + apyReward: apr_rewards2 * 100, + rewardTokens: [...rewards2_tokens], + underlyingTokens: [hypervisor.token0, hypervisor.token1], + poolMeta: fee_name + }; + }); + return chainAprs; + }); + + // pools on optimism which have wrong reward apy + const x = [ + '0x431f6e577a431d9ee87a535fde2db830e352e33c', + '0xed17209ab7f9224e29cc9894fa14a011f37b6115', + ]; + return pools.flat().map((i) => ({ + ...i, + apyReward: x.includes(i.pool) || i.chain === 'Manta' ? null : i.apyReward, + rewardTokens: x.includes(i.pool) || i.chain === 'Manta' ? null : i.rewardTokens, + })).filter(p => p.chain != 'Binance'); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.gamma.xyz/dashboard', +}; diff --git a/src/adaptors/gammaswap-open-interest/IGammaPool.json b/src/adaptors/gammaswap-open-interest/IGammaPool.json new file mode 100644 index 0000000000..49487cebda --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/IGammaPool.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "viewer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-open-interest/IRewardDistributor.json b/src/adaptors/gammaswap-open-interest/IRewardDistributor.json new file mode 100644 index 0000000000..183fa3bc58 --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/IRewardDistributor.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-open-interest/IRewardTracker.json b/src/adaptors/gammaswap-open-interest/IRewardTracker.json new file mode 100644 index 0000000000..069d79aec5 --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/IRewardTracker.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + } + ], + "name": "totalDepositSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-open-interest/IStakingRouter.json b/src/adaptors/gammaswap-open-interest/IStakingRouter.json new file mode 100644 index 0000000000..7c4f58f13f --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/IStakingRouter.json @@ -0,0 +1,46 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "esToken", + "type": "address" + } + ], + "name": "poolTrackers", + "outputs": [ + { + "internalType": "address", + "name": "rewardTracker", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardDistributor", + "type": "address" + }, + { + "internalType": "address", + "name": "loanRewardTracker", + "type": "address" + }, + { + "internalType": "address", + "name": "loanRewardDistributor", + "type": "address" + }, + { + "internalType": "address", + "name": "vester", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-open-interest/abi.json b/src/adaptors/gammaswap-open-interest/abi.json new file mode 100644 index 0000000000..236efefee8 --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/abi.json @@ -0,0 +1,243 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getLatestPoolData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "poolId", + "type": "address" + }, + { + "internalType": "uint16", + "name": "protocolId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "borrowStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "repayStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "rebalanceStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "shortStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "singleLiquidationStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "batchLiquidationStrategy", + "type": "address" + }, + { + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "internalType": "address", + "name": "paramsStore", + "type": "address" + }, + { + "internalType": "uint256", + "name": "LP_TOKEN_BALANCE", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "LP_TOKEN_BORROWED", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "LP_TOKEN_BORROWED_PLUS_INTEREST", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "BORROWED_INVARIANT", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "LP_INVARIANT", + "type": "uint128" + }, + { + "internalType": "address", + "name": "cfmm", + "type": "address" + }, + { + "internalType": "uint80", + "name": "accFeeIndex", + "type": "uint80" + }, + { + "internalType": "uint8", + "name": "extSwapFee", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "origFee", + "type": "uint16" + }, + { + "internalType": "uint40", + "name": "LAST_BLOCK_NUMBER", + "type": "uint40" + }, + { + "internalType": "uint64", + "name": "lastCFMMFeeIndex", + "type": "uint64" + }, + { + "internalType": "uint128", + "name": "lastCFMMInvariant", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "lastCFMMTotalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "symbols", + "type": "string[]" + }, + { + "internalType": "string[]", + "name": "names", + "type": "string[]" + }, + { + "internalType": "uint8[]", + "name": "decimals", + "type": "uint8[]" + }, + { + "internalType": "uint128[]", + "name": "TOKEN_BALANCE", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "CFMM_RESERVES", + "type": "uint128[]" + }, + { + "internalType": "uint256", + "name": "lastPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastFeeIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "utilizationRate", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "currBlockNumber", + "type": "uint40" + }, + { + "internalType": "uint8", + "name": "ltvThreshold", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "liquidationFee", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "supplyRate", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "emaUtilRate", + "type": "uint40" + }, + { + "internalType": "uint8", + "name": "emaMultiplier", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "minUtilRate1", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "minUtilRate2", + "type": "uint8" + }, + { + "internalType": "uint16", + "name": "feeDivisor", + "type": "uint16" + }, + { + "internalType": "uint72", + "name": "minBorrow", + "type": "uint72" + } + ], + "internalType": "struct IGammaPool.PoolData", + "name": "data", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-open-interest/index.js b/src/adaptors/gammaswap-open-interest/index.js new file mode 100644 index 0000000000..89934f168b --- /dev/null +++ b/src/adaptors/gammaswap-open-interest/index.js @@ -0,0 +1,289 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); +const { BigNumber, utils: etherUtils } = require('ethers'); +const utils = require('../utils'); +const PoolViewerABI = require('./abi.json'); +const IGammaPoolABI = require('./IGammaPool.json'); +const IStakingRouterABI = require('./IStakingRouter.json'); +const IRewardTrackerABI = require('./IRewardTracker.json'); +const IRewardDistributorABI = require('./IRewardDistributor.json'); + +function supplyApy(snapshot, poolInfo) { + const avgDecimals = (Number(poolInfo.decimals[0]) + Number(poolInfo.decimals[1])) / 2; + const totalLiquidityBefore = Number(etherUtils.formatUnits(snapshot.totalLiquidity, avgDecimals)); + const totalLiquidityAfter = Number(etherUtils.formatUnits(BigNumber.from(poolInfo.BORROWED_INVARIANT).add(BigNumber.from(poolInfo.LP_INVARIANT)), avgDecimals)); + const liquidityGrowth = totalLiquidityAfter / totalLiquidityBefore; + const totalSupplyBefore = Number(etherUtils.formatUnits(snapshot.totalSupply, 18)); + const totalSupplyAfter = Number(etherUtils.formatUnits(poolInfo.totalSupply, 18)); + const supplyGrowth = totalSupplyAfter / totalSupplyBefore; + const supplyYield = liquidityGrowth / supplyGrowth - 1.0; + const timeDiff = (new Date()).getTime() / 1000 - Number(snapshot.timestamp); + const secondsOfDay = 24 * 60 * 60; + return supplyYield * (secondsOfDay / timeDiff) * 365 * 100; +} + +function borrowApy(snapshot, poolInfo) { + const accFeeIndex1DayAgoNum = Number(etherUtils.formatUnits(snapshot.accFeeIndex, 18)); + const accFeeIndexNum = Number(etherUtils.formatUnits(poolInfo.accFeeIndex, 18)); + const borrowYield = ((accFeeIndexNum / accFeeIndex1DayAgoNum) - 1.0); + const timeDiff = (new Date()).getTime() / 1000 - Number(snapshot.timestamp); + const secondsOfDay = 24 * 60 * 60; + return borrowYield * (secondsOfDay / timeDiff) * 365 * 100; +} + +function formatSymbols(chainName, symbols, addresses) { + if(chainName == "arbitrum") { + if(addresses[0] == "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8") { + symbols[0] = "USDC.e"; + } + if(addresses[1] == "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8") { + symbols[1] = "USDC.e"; + } + } + return symbols.join("-"); +} + +async function apy() { + const chainInfo = [ + { + chainName: "arbitrum", + endpoint: "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/gammaswap-v1-arbitrum/prod/gn", + refPoolAddr: "0x63c531ffed7e17f8adca4ed490837838f6fa1b66", + }, + { + chainName: "base", + endpoint: "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/gammaswap-v1-base/prod/gn", + refPoolAddr: "0xcd4257699b48d4791e77116d0e6a3bd48ad9567f", + }, + { + chainName: "ethereum", + endpoint: "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/gammaswap-v1-mainnet/prod/gn", + refPoolAddr: "0xc70150188142fbfcbb90db05bffc31bccded3da5", + } + ] + + let pools = []; + for(let i = 0; i < chainInfo.length; i++) { + const _pools = await apyPerChain(chainInfo[i].chainName, chainInfo[i].refPoolAddr, chainInfo[i].endpoint) + pools = pools.concat(_pools); + } + return pools; +} + +function formatChainName(chainName) { + if(chainName == "ethereum") { + return "mainnet"; + } + return chainName; +} + +function getRewardApy(chainName, poolId, stakingPoolData) { + if(chainName == "arbitrum") { + if(stakingPoolData && stakingPoolData[poolId]) { + return stakingPoolData[poolId].apy; + } + } + return 0; +} + +function getRewardTokens(chainName, poolId, stakingPoolData) { + if(chainName == "arbitrum") { + if(stakingPoolData && stakingPoolData[poolId]) { + return ["0xA159463aB4B3aF3865bC9DC0FD28d943f2C048Ce"]; + } + } + return []; +} + +function getStakingInfo(chainName) { + if(chainName == "arbitrum") { + return { + stakingRouter: "0x9b91328f04ed1183548bD6bDad24Da40311E077C", + escrowToken: "0xa159463ab4b3af3865bc9dc0fd28d943f2c048ce", + rewardToken: "0x912ce59144191c1204e64559fe8253a0e49e6548" + } + } + return {}; +} + +async function apyPerChain(chainName, refPoolAddr, endpoint) { + const { output: poolViewer } = await sdk.api.abi.call( { + target: refPoolAddr, + abi: IGammaPoolABI[0], + chain: chainName + }); + + const query = gql` + { + gammaPoolTracers { + lastDailyData { + pool { + id + tvlUSD + activeStaking + token0 { + id + symbol + priceUSD + } + token1 { + id + symbol + priceUSD + } + } + totalLiquidity + totalSupply + accFeeIndex + timestamp + } + } + } + `; + const { gammaPoolTracers: gammaPoolTracersList } = await request(endpoint, query) + const gammaPoolTracers = gammaPoolTracersList.filter((tracer) => tracer.lastDailyData != null ) + + const pools = gammaPoolTracers.map((tracer) => tracer.lastDailyData.pool.id); + + const { output: latestPoolsData } = await sdk.api.abi.multiCall({ + abi: PoolViewerABI[0], + calls: pools.map(pool => ({ + target: poolViewer, + params: pool + })), + chain: chainName, + permitFailure: true, + }); + + let _latestPoolsData = latestPoolsData.filter(function(pool) { + return (Number(pool.output.decimals[0]) + Number(pool.output.decimals[1])) % 2 == 0; + }); + + const _pools = pools.filter(function(pool, i) { + return (Number(latestPoolsData[i].output.decimals[0]) + Number(latestPoolsData[i].output.decimals[1])) % 2 == 0; + }); + + const _gammaPoolTracers = gammaPoolTracers.filter(function(tracer, i) { + return (Number(latestPoolsData[i].output.decimals[0]) + Number(latestPoolsData[i].output.decimals[1])) % 2 == 0; + }); + + const stakingPools = _gammaPoolTracers.filter((tracer) => tracer.lastDailyData.pool.activeStaking ) + const stakingPoolIds = stakingPools.map((tracer) => tracer.lastDailyData.pool.id); + + const stakingInfo = getStakingInfo(chainName); + const stakingRouter = stakingInfo.stakingRouter; + const esToken = stakingInfo.escrowToken; + + const stakingPoolData = {}; // identify by pool + if(false && etherUtils.isAddress(stakingRouter) && etherUtils.isAddress(esToken) && stakingPoolIds.length > 0) { + const latestPoolDataMap = {} + for(let i = 0; i < latestPoolsData.length; i++) { + latestPoolDataMap[latestPoolsData[i].input.params[0]] = latestPoolsData[i].output + } + + const stakingPoolsMap = {}; + for(let i = 0; i < stakingPools.length; i++) { + const poolId = stakingPools[i].lastDailyData.pool.id; + stakingPoolsMap[poolId] = stakingPools[i].lastDailyData.pool; + } + + const queryRewardTokenPriceUSD = gql`{ + token(id:"${stakingInfo.rewardToken}") { + priceUSD + decimals + } + }`; + const { token: rewardToken } = await request(endpoint, queryRewardTokenPriceUSD); + + const { output: trackers } = await sdk.api.abi.multiCall({ + abi: IStakingRouterABI[0], + calls: stakingPoolIds.map(pool => ({ + target: stakingRouter, + params: [pool, esToken] + })), + chain: chainName, + permitFailure: true, + }); + const distributorToPoolMap = {} + for(let i = 0; i < trackers.length; i++) { + distributorToPoolMap[trackers[i].output.rewardDistributor] = trackers[i].input.params[0] + } + + const { output: totalDepositSupply } = await sdk.api.abi.multiCall({ + abi: IRewardTrackerABI[0], + calls: trackers.map(item => ({ + target: item.output.rewardTracker, + params: item.input.params[0] + })), + chain: chainName, + permitFailure: true, + }); + + for(let i = 0; i < totalDepositSupply.length; i++) { + // params0 is the pool + stakingPoolData[totalDepositSupply[i].input.params[0]] = { + rewardTracker: totalDepositSupply[i].target, + totalStaked: BigNumber.from(totalDepositSupply[i].output.toString()), + apy: 0 + } + } + + const { output: tokensPerInterval } = await sdk.api.abi.multiCall({ + abi: IRewardDistributorABI[0], + calls: trackers.map(item => ({ + target: item.output.rewardDistributor + })), + chain: chainName, + permitFailure: true, + }); + const secondsPerYear = 365*24*60*60 + for(let i = 0; i < tokensPerInterval.length; i++) { + const poolId = distributorToPoolMap[tokensPerInterval[i].input.target]; + const annualizedEmissions = etherUtils.formatUnits(BigNumber.from(tokensPerInterval[i].output.toString()).mul(secondsPerYear), rewardToken.decimals); + const annualizedEmissionsUSD = Number(annualizedEmissions) * Number(rewardToken.priceUSD); + + const poolInfo = latestPoolDataMap[poolId]; + const poolSubgraphInfo = stakingPoolsMap[poolId]; + + const token1PriceUSD = Number(poolSubgraphInfo.token1.priceUSD); + const avgDecimals = (Number(poolInfo.decimals[0]) + Number(poolInfo.decimals[1])) / 2; + const priceToken1 = Number(etherUtils.formatUnits(poolInfo.lastPrice, poolInfo.decimals[1])); + const totalStaked = Number(etherUtils.formatUnits(stakingPoolData[poolId].totalStaked, 18)); + const totalInvariant = Number(etherUtils.formatUnits(BigNumber.from(poolInfo.BORROWED_INVARIANT).add(BigNumber.from(poolInfo.LP_INVARIANT)), avgDecimals)); + const totalGSLPSupply = Number(etherUtils.formatUnits(poolInfo.totalSupply, 18)); + const totalStakedUSD = (totalStaked * totalInvariant / totalGSLPSupply) * Math.sqrt(priceToken1) * token1PriceUSD; + stakingPoolData[poolId].apy = annualizedEmissionsUSD * 100 / totalStakedUSD; + } + } + + return _pools.map((pool, i) => { + const pDetails = _gammaPoolTracers[i].lastDailyData.pool; + + return { + pool, + chain: utils.formatChain(chainName), + project: 'gammaswap-open-interest', + symbol: `${pDetails.token0.symbol}-${pDetails.token1.symbol}`, + tvlUsd: Number(_gammaPoolTracers[i].lastDailyData.pool.tvlUSD), + apyBase: supplyApy( + _gammaPoolTracers[i].lastDailyData, + _latestPoolsData[i].output + ), + apyBaseBorrow: borrowApy( + _gammaPoolTracers[i].lastDailyData, + _latestPoolsData[i].output + ), + //rewardTokens: getRewardTokens(chainName, pool, stakingPoolData), + //apyReward: getRewardApy(chainName, pool, stakingPoolData), // APY from pool LM rewards in % + underlyingTokens: _latestPoolsData[i].output.tokens, + url: `https://app.gammaswap.com/earn/${formatChainName( + chainName + )}/${pool}`, + }; + }); +} + +module.exports = { + timetravel: false, + apy +} \ No newline at end of file diff --git a/src/adaptors/gammaswap-yield-tokens/IGammaVault.json b/src/adaptors/gammaswap-yield-tokens/IGammaVault.json new file mode 100644 index 0000000000..5c76d1b5e3 --- /dev/null +++ b/src/adaptors/gammaswap-yield-tokens/IGammaVault.json @@ -0,0 +1,1245 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isDeposit", + "type": "bool" + } + ], + "name": "ReserveLPTokens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_fees0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_fees1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_poolShare", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_protocolShare", + "type": "uint16" + } + ], + "name": "TotalNetFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "name": "TransferFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "nav", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "enum IGammaVault.EventType", + "name": "typ", + "type": "uint8" + } + ], + "name": "UpdateVault", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "assetToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assetDeposit", + "type": "uint256" + } + ], + "name": "calculateLPTokensToReserve", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "calculateNAV", + "outputs": [ + { + "internalType": "uint256", + "name": "nav", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gsPnl", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isGSPnLNeg", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lpTokensToReserve", + "type": "uint256" + } + ], + "name": "canReserveLPTokens", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeModel", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lpTokens", + "type": "uint256" + } + ], + "name": "freeReservedLPTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAssetDust", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollectedFees", + "outputs": [ + { + "internalType": "uint256", + "name": "fees0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fees1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPeriodInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "period", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodExpiration", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVaultData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint16", + "name": "protocolId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "strategyId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "refId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "gsTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reservedLPTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hedgeSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ratio0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ratio1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "dust0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "dust1", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gvFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "manager", + "type": "address" + }, + { + "internalType": "address", + "name": "depositVault", + "type": "address" + }, + { + "internalType": "address", + "name": "withdrawVault", + "type": "address" + }, + { + "internalType": "address", + "name": "lpPool", + "type": "address" + }, + { + "internalType": "address", + "name": "gsPool", + "type": "address" + }, + { + "internalType": "address", + "name": "cfmm", + "type": "address" + }, + { + "internalType": "address", + "name": "nftPosMgr", + "type": "address" + }, + { + "internalType": "address", + "name": "mathLib", + "type": "address" + }, + { + "internalType": "address", + "name": "viewer", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "isAssetToken0", + "type": "bool" + }, + { + "internalType": "uint64", + "name": "decimals0", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "decimals1", + "type": "uint64" + }, + { + "internalType": "uint8", + "name": "numOfDecimals0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "numOfDecimals1", + "type": "uint8" + }, + { + "internalType": "uint24", + "name": "poolFee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSize", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint64", + "name": "poolShare", + "type": "uint64" + }, + { + "internalType": "uint16", + "name": "protocolShare", + "type": "uint16" + }, + { + "internalType": "address", + "name": "protocolShareTo", + "type": "address" + }, + { + "internalType": "uint8", + "name": "maxBorrowReservePct", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "internalType": "struct IGammaVault.VaultData", + "name": "data", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVaultDust", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gsPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gvFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint16", + "name": "refId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "strategyId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lpPool", + "type": "address" + }, + { + "internalType": "address", + "name": "gsPool", + "type": "address" + }, + { + "internalType": "address", + "name": "cfmm", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickSize", + "type": "int24" + }, + { + "internalType": "uint24", + "name": "poolFee", + "type": "uint24" + }, + { + "internalType": "address", + "name": "depositVault", + "type": "address" + }, + { + "internalType": "address", + "name": "withdrawVault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "startPrice", + "type": "uint256" + } + ], + "internalType": "struct IVaultProtocol.InitializeParameters", + "name": "params", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lpPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "manager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mathLib", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nftPosMgr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "path0", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "path1", + "type": "bytes" + } + ], + "name": "processDepositsAndWithdrawals", + "outputs": [ + { + "internalType": "uint8", + "name": "processType", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "processFeeCollection", + "outputs": [ + { + "internalType": "uint256", + "name": "fees0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fees1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "protocolId", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "hedgeSize", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "path0", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "path1", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "ratio0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ratio1", + "type": "uint256" + } + ], + "internalType": "struct IGammaVault.RebalanceParams", + "name": "params", + "type": "tuple" + } + ], + "name": "rebalancePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveLPTokens", + "outputs": [ + { + "internalType": "int256", + "name": "lpTokens", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "poolShare", + "type": "uint64" + } + ], + "name": "setPoolShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "maxBorrowReservePct", + "type": "uint8" + }, + { + "internalType": "uint64", + "name": "dust0", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "dust1", + "type": "uint64" + } + ], + "name": "setVaultParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lpPool", + "type": "address" + }, + { + "internalType": "address", + "name": "gsPool", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "validate", + "outputs": [ + { + "internalType": "address", + "name": "cfmm", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "internalType": "uint24", + "name": "poolFee", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "viewer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gammaswap-yield-tokens/index.js b/src/adaptors/gammaswap-yield-tokens/index.js new file mode 100644 index 0000000000..7fcf2e1288 --- /dev/null +++ b/src/adaptors/gammaswap-yield-tokens/index.js @@ -0,0 +1,494 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { + utils: { formatEther, formatUnits }, +} = require('ethers'); + +const IGammaVaultAbi = require('./IGammaVault.json'); + +// Note: we use GammaSwap internal API per-vault endpoint for live fields needed for APY +const GS_API_URL = "https://api.gammaswap.com/yield-tokens"; + +const CHAINS = { + base: { + chainId: 8453, + subgraphUrl: + "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/gammaswap-v1-base/prod/gn", + vaultSubgraphUrl: + "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/vaults-v1-base/prod/gn", + }, + arbitrum: { + chainId: 42161, + subgraphUrl: + "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/gammaswap-v1-arbitrum/prod/gn", + vaultSubgraphUrl: + "https://api.goldsky.com/api/public/project_clut9lukx80ry01xb5ngf1zmj/subgraphs/vaults-v1-arbitrum/prod/gn", + }, +}; + +const SECONDS_IN_24_HRS = 24 * 60 * 60; + +// Helper function to fetch data from subgraph (uses project utils) +async function fetchFromSubgraph(url, query) { + return utils.getData(url, { query }); +} + +/** + * Extract and parse the calculateNAV result from smart contract call + */ +function parseNAVResult(navResult) { + const [nav, amount0, amount1, gsPnl, isGSPnLNeg] = navResult; + + return { + nav: BigInt(nav.toString()), + amount0: BigInt(amount0.toString()), + amount1: BigInt(amount1.toString()), + gsPnl: BigInt(gsPnl.toString()), + isGSPnLNeg: Boolean(isGSPnLNeg) + }; +} + +/** + * Calculate NAV by making a smart contract call to the vault + */ +async function calculateNAV(vaultAddress, chainKey) { + try { + const chainConfig = CHAINS[chainKey]; + if (!chainConfig) { + throw new Error(`Chain configuration not found for ${chainKey}`); + } + + const navResult = await sdk.api.abi.call({ + target: vaultAddress, + abi: IGammaVaultAbi.find((m) => m.name === 'calculateNAV'), + chain: chainKey, + }); + + if (!navResult.output) { + throw new Error(`No output from calculateNAV call for vault ${vaultAddress}`); + } + + return parseNAVResult(navResult.output); + } catch (error) { + console.error(`Error calculating NAV for vault ${vaultAddress}: ${error}`); + return null; + } +} + +function overlapSec(a0, a1, b0, b1) { + return Math.max(0, Math.min(a1, b1) - Math.max(a0, b0)); +} + +function normalizePeriodStrategies(periods, nowSec) { + const sorted = [...periods].sort((a, b) => Number(a.periodNumber) - Number(b.periodNumber)); + + const out = []; + for (let i = 0; i < sorted.length; i++) { + const cur = sorted[i]; + const next = sorted[i + 1]; + const start = Number(cur.startTime); + const end = Math.max(start, next ? Number(next.startTime) : nowSec); + + out.push({ + periodNumber: Number(cur.periodNumber), + start, + end, + fees0: cur.totalFees0, + fees1: cur.totalFees1, + nav: cur.nav, + }); + } + + return out; +} + +function estimateTrailing24hFees( + periods, + nowSec, + token0Decimals, + token1Decimals, + isReversed +) { + const win0 = nowSec - SECONDS_IN_24_HRS; + const win1 = nowSec; + + let est0 = 0; + let est1 = 0; + let startTime = undefined; + + for (const p of periods) { + const dur = Math.max(1, p.end - p.start); + const ovl = overlapSec(win0, win1, p.start, p.end); + + if (ovl <= 0) continue; + + // Capture the start time of the first period with non-zero overlap + if (startTime === undefined) { + startTime = p.start; + } + + // matches decimals order coming from the subgraph + const orderedToken0Decimals = isReversed ? token1Decimals : token0Decimals; + const orderedToken1Decimals = isReversed ? token0Decimals : token1Decimals; + + const fees0 = Number(formatUnits(BigInt(p.fees0), orderedToken0Decimals)) + const fees1 = Number(formatUnits(BigInt(p.fees1), orderedToken1Decimals)) + + // proportionally attribute fees to the overlapping fraction of the period + est0 += (fees0 * ovl) / dur; + est1 += (fees1 * ovl) / dur; + } + + return { estFees0: est0, estFees1: est1, startTime: startTime }; +} + + +// Calculate 24h averaged APY +function calculateLatestStrategyAPY(params) { + const { + periods, + windowEndTime, + isAssetToken0, + token0Decimals, + token1Decimals, + currentPriceToken0, + currentPriceToken1, + isReversed, + } = params; + console.log("all params:\n", params) + + if (!periods.length) return 0; + + const normalized = normalizePeriodStrategies(periods, windowEndTime); + const { estFees0, estFees1 } = estimateTrailing24hFees(normalized, windowEndTime, token0Decimals, token1Decimals, isReversed); + + const navAtWindowEnd = periods[periods.length - 1].nav; + + return calculate24hAveragedAPY( + estFees0, + estFees1, + SECONDS_IN_24_HRS, + isAssetToken0, + token0Decimals, + token1Decimals, + currentPriceToken0, + currentPriceToken1, + navAtWindowEnd, + isReversed, + ); +} + +/** + * Calculate APY from accumulated fees and window data + */ +function calculate24hAveragedAPY( + totalFees0, + totalFees1, + actualWindowSeconds, + isAssetToken0, + token0Decimals, + token1Decimals, + currentPriceToken0, + currentPriceToken1, + navAtWindowEnd, + isReversed, +) { + + // check for reversal since fees are stored depending on token order from subgraph + const orderedAccumulatedTotalFees0 = isReversed ? totalFees1 : totalFees0; + const orderedAccumulatedTotalFees1 = isReversed ? totalFees0 : totalFees1; + + // converting from portioned fees in each token to all fees converted to each token + const feesInToken0Num = orderedAccumulatedTotalFees0 + orderedAccumulatedTotalFees1 * Number(currentPriceToken0); + const feesInToken1Num = orderedAccumulatedTotalFees1 + orderedAccumulatedTotalFees0 * Number(currentPriceToken1); + + const windowSeconds = Math.max(actualWindowSeconds, 1); + const windowDays = Math.max(windowSeconds / SECONDS_IN_24_HRS, 1e-6); + + const assetTokenDecimals = isAssetToken0 ? token0Decimals : token1Decimals; + const navNum = Number(formatUnits(BigInt(navAtWindowEnd), assetTokenDecimals)); + + if (navNum <= 0) { + console.warn(`Invalid NAV: ${navNum}`); + return 0; + } + + return calculateAnnualizedStrategyAPY( + feesInToken0Num, + feesInToken1Num, + navNum, + isAssetToken0, + currentPriceToken0, + currentPriceToken1, + windowDays, + ); +} + +function calculateAnnualizedStrategyAPY( + feesInToken0Num, + feesInToken1Num, + navNum, + isAssetToken0, + currentPriceToken0, + currentPriceToken1, + windowDays, +) { + let yieldInAssetToken; + let yieldInNonAssetToken; + + if (isAssetToken0) { + yieldInAssetToken = feesInToken0Num / navNum; + + const navInToken1 = navNum * currentPriceToken1; + yieldInNonAssetToken = navInToken1 > 0 ? feesInToken1Num / navInToken1 : 0; + } else { + yieldInAssetToken = feesInToken1Num / navNum; + + const navInToken0 = navNum * currentPriceToken0; + yieldInNonAssetToken = navInToken0 > 0 ? feesInToken0Num / navInToken0 : 0; + } + + const feeYieldWindow = Math.max(yieldInAssetToken, yieldInNonAssetToken); + + // Annualized fee yield + const feeAPR = feeYieldWindow * (365 / windowDays); + + return feeAPR; +} + +// Fetch period strategies from subgraph +async function fetchPeriodStrategies( + chainConfig, + vaultAddress, + latestBlockTimestamp, + limitCount = 100, +) { + const lookbackTime = latestBlockTimestamp - (SECONDS_IN_24_HRS * 2); + + const periodStrategiesQuery = `{ + periodStrategies( + where: { + vault: "${vaultAddress.toLowerCase()}", + startTime_gte: "${lookbackTime}" + } + orderBy: startTime + orderDirection: asc + first: ${limitCount} + ) { + id + periodNumber + nav + startTime + totalFees0 + totalFees1 + lastEventType + totalSupply + } + }`; + + const periodStrategiesData = await fetchFromSubgraph( + chainConfig.vaultSubgraphUrl, + periodStrategiesQuery, + ); + + if ( + !periodStrategiesData.data || + !periodStrategiesData.data.periodStrategies + ) { + return []; + } + + const periodStrategies = periodStrategiesData.data.periodStrategies || []; + const result = []; + + for (const strategy of periodStrategies) { + if (strategy.nav && strategy.startTime) { + result.push({ + id: strategy.id, + periodNumber: strategy.periodNumber, + nav: strategy.nav, + startTime: strategy.startTime, + totalFees0: strategy.totalFees0 || "0", + totalFees1: strategy.totalFees1 || "0", + lastEventType: strategy.lastEventType, + totalSupply: strategy.totalSupply, + }); + } + } + + return result; +} + +// Get strategy APY +async function getStrategyAPY( + chainConfig, + vaultAddress, + feesInToken0, + feesInToken1, + currentNav, + isAssetToken0, + currentPriceToken0, + currentPriceToken1, + token0Decimals, + token1Decimals, + latestBlockTimestamp, + isReversed, +) { + try { + const rows = await fetchPeriodStrategies( + chainConfig, + vaultAddress, + latestBlockTimestamp, + ); + + if (rows.length === 0) { + return 0; + } + + const updatedRows = [...rows]; + if (updatedRows.length > 0) { + const mostRecentPeriod = updatedRows[0]; + + const orderedTotalFees0 = isReversed ? feesInToken1 : feesInToken0; + const orderedTotalFees1 = isReversed ? feesInToken0 : feesInToken1; + + updatedRows[0] = { + ...mostRecentPeriod, + totalFees0: ( + BigInt(mostRecentPeriod.totalFees0) + orderedTotalFees0 + ).toString(), + totalFees1: ( + BigInt(mostRecentPeriod.totalFees1) + orderedTotalFees1 + ).toString(), + nav: currentNav.toString(), + }; + } + + const feeAPR = calculateLatestStrategyAPY({ + periods: updatedRows, + windowEndTime: latestBlockTimestamp, + isAssetToken0, + token0Decimals, + token1Decimals, + currentPriceToken0, + currentPriceToken1, + isReversed, + }); + + return feeAPR; + } catch (error) { + console.error( + `Error calculating strategy APY for vault ${vaultAddress}: ${error}`, + ); + return 0; + } +} + +// Main adaptor function +const apy = async () => { + const pools = []; + + for (const [chainKey, chainConfig] of Object.entries(CHAINS)) { + try { + // Get current timestamp + const latestBlockTimestamp = Math.floor(Date.now() / 1000); + + // Fetch vault list and token info from vault subgraph + const vaultsQuery = `{ + vaults(first: 1000) { + id + } + }`; + + const vaultsData = await fetchFromSubgraph( + chainConfig.vaultSubgraphUrl, + vaultsQuery, + ); + + if (!vaultsData.data || !vaultsData.data.vaults) { + continue; + } + + for (const vaultRow of vaultsData.data.vaults) { + try { + // fetch per-vault data (combination of subgraph and smart contract data) + const yt = await utils.getData( + `${GS_API_URL}/${chainConfig.chainId}/${vaultRow.id}`, + ); + if (!yt) continue; + + // Calculate NAV using smart contract call + const navData = await calculateNAV(vaultRow.id, chainKey); + if (!navData) continue; + + // gammavault onchain data + const totalFees0Raw = yt.currentTotalFees0 || "0"; + const totalFees1Raw = yt.currentTotalFees1 || "0"; + const assetDecimals = Number(yt.assetToken.decimals); + const nav = Number(formatUnits(navData.nav.toString(), assetDecimals)); + const isAssetToken0 = !!yt.isAssetToken0; + const isReversed = !!yt.isReversed; + const price0 = yt.currentPriceToken0 || 1; + const price1 = yt.currentPriceToken1 || 1; + const assetPrice = yt.assetTokenPriceUSD || 1; + const tokenSymbol = yt.symbol; + const token0Meta = yt.token0; + const token1Meta = yt.token1; + + // Calculate APY + const apyValue = await getStrategyAPY( + chainConfig, + vaultRow.id, + BigInt(totalFees0Raw) || 0n, + BigInt(totalFees1Raw) || 0n, + nav, + isAssetToken0, + price0, + price1, + Number(token0Meta?.decimals), + Number(token1Meta?.decimals), + latestBlockTimestamp, + isReversed, + ); + + // Format pool data according to DefiLlama schema + const pool = { + pool: `${vaultRow.id}-${chainKey}`, + chain: utils.formatChain(chainKey), + project: "gammaswap-yield-tokens", + symbol: utils.formatSymbol(tokenSymbol), + tvlUsd: (() => { + try { + // Calculate TVL as NAV * assetTokenPriceUSD + return nav * assetPrice; + } catch (e) { + return 0; + } + })(), + apyBase: apyValue * 100, // convert to % + underlyingTokens: [ + token0Meta?.id || vaultRow.token0?.id, + token1Meta?.id || vaultRow.token1?.id, + ], + poolMeta: "Yield Token", + url: `https://app.gammaswap.com/yield-tokens/${chainKey}/${vaultRow.id}`, + }; + + pools.push(pool); + } catch (error) { + console.error(`Error processing vault ${vaultRow.id}: ${error}`); + } + } + } catch (error) { + console.error(`Error processing chain ${chainKey}: ${error}`); + } + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: "https://app.gammaswap.com/yield-tokens", +}; \ No newline at end of file diff --git a/src/adaptors/garden/index.js b/src/adaptors/garden/index.js new file mode 100644 index 0000000000..5ca3624a42 --- /dev/null +++ b/src/adaptors/garden/index.js @@ -0,0 +1,245 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const { ethers } = require('ethers'); + +const GARDEN_STAKING_CONTRACT = '0xe2239938Ce088148b3Ab398b2b77Eedfcd9d1AfC' +const SEED_TOKEN = '0x86f65121804D2Cdbef79F9f072D4e0c2eEbABC08' +const chain = 'arbitrum' + +// Event topics for staking events +const STAKED_EVENT_TOPIC = '0xa1fdccfe567643a44425efdd141171e8d992854a81e5c819c1432b0de47c9a11'; +const STAKE_REFUNDED_EVENT_TOPIC = '0xba33cc6a4502f7f80bfe643ffa925ba7ab5e0af61c061a9aceabef0349c9dce4'; +const MAX_UINT256 = ethers.constants.MaxUint256; + +// ABI for the events we need +const eventAbi = [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "stakeID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "stakeID", + "type": "bytes32" + } + ], + "name": "StakeRefunded", + "type": "event" + }, +]; + +// TVL Calculator class (simplified for adapter use) +class TVLCalculator { + constructor() { + this.stakes = new Map(); // stakeID -> stake amount + } + + async fetchEvents() { + + try { + // Get current block number + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + const fromBlock = 192080606; // Contract deployment block + + // Fetch Staked events + const stakedLogs = ( + await sdk.api.util.getLogs({ + target: GARDEN_STAKING_CONTRACT, + topic: '', + toBlock, + fromBlock, + keys: [], + topics: [STAKED_EVENT_TOPIC], + chain: chain, + }) + ).output; + + // Fetch StakeRefunded events + const refundedLogs = ( + await sdk.api.util.getLogs({ + target: GARDEN_STAKING_CONTRACT, + topic: '', + toBlock, + fromBlock, + keys: [], + topics: [STAKE_REFUNDED_EVENT_TOPIC], + chain: chain, + }) + ).output; + + return { stakedLogs, refundedLogs, currentBlock: currentBlock.number }; + + } catch (error) { + console.error('Error fetching events:', error); + throw error; + } + } + + async processEvents(stakedLogs, refundedLogs) { + + try { + + const abiInterface = new ethers.utils.Interface(eventAbi); + const refundedStakeIDs = new Set(); // Track refunded stake IDs + + // Process staked events first + for (const log of stakedLogs) { + try { + const formattedLog = { + address: log.address, + topics: log.topics, + data: log.data, + blockNumber: typeof log.blockNumber === 'string' ? parseInt(log.blockNumber, 16) : log.blockNumber, + transactionHash: log.transactionHash, + logIndex: log.logIndex + }; + + const decoded = abiInterface.parseLog(formattedLog); + const stakeID = decoded.args.stakeID; + const stakeAmount = decoded.args.stake; + const owner = decoded.args.owner; + const expiry = decoded.args.expiry; + + this.stakes.set(stakeID, { + amount: stakeAmount.toString(), + owner: owner, + expiry: expiry.toString(), + blockNumber: formattedLog.blockNumber, + transactionHash: log.transactionHash + }); + + } catch (error) { + console.warn('Failed to decode staked event:', error.message); + } + } + + // Process refunded events to remove stakes + for (const log of refundedLogs) { + try { + const formattedLog = { + address: log.address, + topics: log.topics, + data: log.data, + blockNumber: typeof log.blockNumber === 'string' ? parseInt(log.blockNumber, 16) : log.blockNumber, + transactionHash: log.transactionHash, + logIndex: log.logIndex + }; + + const decoded = abiInterface.parseLog(formattedLog); + const stakeID = decoded.args.stakeID; + + refundedStakeIDs.add(stakeID); + this.stakes.delete(stakeID); + + } catch (error) { + console.warn('Failed to decode refunded event:', error.message); + } + } + + } catch (error) { + console.error('Error processing events:', error); + throw error; + } + } + + calculateTVL() { + try { + let totalTVLWei = BigInt(0); + + for (const [stakeID, stakeInfo] of this.stakes.entries()) { + totalTVLWei += BigInt(stakeInfo.amount); + } + + const totalTVLEther = ethers.utils.formatEther(totalTVLWei); + + return { + tvl: totalTVLEther, + }; + + } catch (error) { + console.error('Error calculating TVL:', error); + throw error; + } + } +} + +const getTvl = async () => { + try { + // Get APY data + const apyData = await utils.getData('https://stakingv2.garden.finance/apy'); + + // Calculate TVL using event-based method + const calculator = new TVLCalculator(); + + // Fetch and process events + const { stakedLogs, refundedLogs } = await calculator.fetchEvents(); + await calculator.processEvents(stakedLogs, refundedLogs); + + // Calculate TVL from events + const tvlResult = calculator.calculateTVL(); + const tvl = parseFloat(tvlResult.tvl); + + + // Get SEED price + const priceData = await axios.get( + 'https://coins.llama.fi/prices/current/arbitrum:0x86f65121804D2Cdbef79F9f072D4e0c2eEbABC08' + ); + + const seedPrice = priceData.data.coins[`${chain}:${SEED_TOKEN}`]?.price || 0; + + // Calculate TVL in USD + const tvlUsd = tvl * seedPrice; + + return [{ + pool: '0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf-base', + chain: utils.formatChain(chain), + project: 'garden', + symbol: utils.formatSymbol('SEED'), + tvlUsd: tvlUsd, + apy: apyData.data, + }]; + + } catch (error) { + console.error('Error in getTvl:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: getTvl, + url: 'https://app.garden.finance/stake', +}; \ No newline at end of file diff --git a/src/adaptors/gearbox/index.js b/src/adaptors/gearbox/index.js new file mode 100644 index 0000000000..f6390b7ddb --- /dev/null +++ b/src/adaptors/gearbox/index.js @@ -0,0 +1,1152 @@ +/** + ** + ** + ** + ** This file has been generated from source code in https://github.com/Gearbox-protocol/defillama repo + ** Binary release: https://github.com/Gearbox-protocol/defillama/releases/tag/v1.2.2 + ** + ** + ** + **/ + +var sdk = require('@defillama/sdk'); +var utils = require('../utils'); +const fetch = require('node-fetch'); + +// src/yield-server/index.ts + +// src/yield-server/abis.ts +var abis_default = { + getPoolsV3List: { + inputs: [], + name: 'getPoolsV3List', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'addr', + type: 'address', + }, + { + internalType: 'address', + name: 'underlying', + type: 'address', + }, + { + internalType: 'address', + name: 'dieselToken', + type: 'address', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'uint256', + name: 'baseInterestIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'expectedLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalDebtLimit', + type: 'uint256', + }, + { + components: [ + { + internalType: 'address', + name: 'creditManager', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'availableToBorrow', + type: 'uint256', + }, + ], + internalType: 'struct CreditManagerDebtParams[]', + name: 'creditManagerDebtParams', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'totalAssets', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseInterestRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'dieselRate_RAY', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastBaseInterestUpdate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseInterestIndexLU', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'version', + type: 'uint256', + }, + { + internalType: 'address', + name: 'poolQuotaKeeper', + type: 'address', + }, + { + internalType: 'address', + name: 'gauge', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'uint16', + name: 'rate', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'quotaIncreaseFee', + type: 'uint16', + }, + { + internalType: 'uint96', + name: 'totalQuoted', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'limit', + type: 'uint96', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + ], + internalType: 'struct QuotaInfo[]', + name: 'quotas', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'address', + name: 'zapper', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenOut', + type: 'address', + }, + ], + internalType: 'struct ZapperInfo[]', + name: 'zappers', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'address', + name: 'interestModel', + type: 'address', + }, + { + internalType: 'uint256', + name: 'version', + type: 'uint256', + }, + { + internalType: 'uint16', + name: 'U_1', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'U_2', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'R_base', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'R_slope1', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'R_slope2', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'R_slope3', + type: 'uint16', + }, + { + internalType: 'bool', + name: 'isBorrowingMoreU2Forbidden', + type: 'bool', + }, + ], + internalType: 'struct LinearModel', + name: 'lirm', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isPaused', + type: 'bool', + }, + ], + internalType: 'struct PoolData[]', + name: 'result', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + farmInfo: { + inputs: [], + name: 'farmInfo', + outputs: [ + { + components: [ + { + internalType: 'uint40', + name: 'finished', + type: 'uint40', + }, + { + internalType: 'uint32', + name: 'duration', + type: 'uint32', + }, + { + internalType: 'uint184', + name: 'reward', + type: 'uint184', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + ], + internalType: 'struct FarmAccounting.Info', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + symbol: 'function symbol() external view returns (string)', + totalSupply: 'function totalSupply() external view returns (uint256)', + stakingToken: 'function stakingToken() external view returns (address)', + decimals: 'function decimals() external view returns (uint8)', + fees: 'function fees() external view returns (uint16 feeInterest, uint16 feeLiquidation, uint16 liquidationDiscount, uint16 feeLiquidationExpired, uint16 liquidationDiscountExpired)', + getCreditManagers: + 'function getCreditManagers() external view returns (address[])', + pool: 'function pool() external view returns (address)', + getAddressOrRevert: + 'function getAddressOrRevert(bytes32 key, uint256 version) view returns (address result)', +}; + +// src/yield-server/constants.ts +// Chain-specific configurations +var CHAIN_CONFIGS = { + ethereum: { + ADDRESS_PROVIDER_V3: '0x9ea7b04da02a5373317d745c1571c84aad03321d', + GEAR_TOKEN: '0xBa3335588D9403515223F109EdC4eB7269a9Ab5D'.toLowerCase(), + chainName: 'Ethereum', + // Ethereum-specific exclusions and rewards + EXCLUDED_POOLS: { + '0x1dc0f3359a254f876b37906cfc1000a35ce2d717': 'USDT V3 Broken', + }, + // Ethereum KPK (PoolQuotaKeeper) pools that need manual configuration + POOLS: { + '0xa9d17f6d3285208280a1fd9b94479c62e0aaba64': { + symbol: 'wstETH', + underlying: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', // wstETH + name: 'kpk wstETH', + }, + '0x9396dcbf78fc526bb003665337c5e73b699571ef': { + symbol: 'ETH', + underlying: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH + name: 'kpk ETH', + }, + }, + }, + plasma: { + ADDRESS_PROVIDER_V3: null, // Plasma uses individual pool approach + GEAR_TOKEN: null, // No GEAR rewards on Plasma initially + WXPL_TOKEN: '0x6100E367285b01F48D07953803A2d8dCA5D19873'.toLowerCase(), // WXPL reward token + chainName: 'Plasma', + // Plasma-specific pool configurations + POOLS: { + '0x76309A9a56309104518847BbA321c261B7B4a43f': { + symbol: 'dUSDT0', + underlying: '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb', // USDT0 deposit token + name: 'Invariant USDT0', + }, + '0x53e4e9b8766969c43895839cc9c673bb6bc8ac97': { + symbol: 'USDT0 v3', + underlying: '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb', // USDT0 + name: 'Edge UltraYield', + }, + '0xb74760fd26400030620027dd29d19d74d514700e': { + symbol: 'hyperGearboxUSDT', + underlying: '0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb', // USDT0 + name: 'Hyperithm Gearbox USDT', + }, + }, + }, + etlk: { + ADDRESS_PROVIDER_V3: null, + GEAR_TOKEN: null, + REWARD_TOKEN: '0x0008b6C5b44305693bEB4Cd6E1A91b239D2A041E'.toLowerCase(), + chainName: 'Etherlink', + POOLS: { + '0x653e62A9Ef0e869F91Dc3D627B479592aA02eA75': { + symbol: 'USDC', + underlying: '0x796Ea11Fa2dD751eD01b53C372fFDB4AAa8f00F9', // USDC + name: 'USDC Lending Pool', + }, + }, + }, + lisk: { + ADDRESS_PROVIDER_V3: null, + GEAR_TOKEN: null, + REWARD_TOKEN: '0xac485391EB2d7D88253a7F1eF18C37f4242D1A24'.toLowerCase(), // LISK + chainName: 'Lisk', + POOLS: { + '0xA16952191248E6B4b3A24130Dfc47F96ab1956a7': { + symbol: 'ETH', + underlying: '0x4200000000000000000000000000000000000006', // WETH + name: 'WETH Lending Pool', + }, + }, + }, + hemi: { + ADDRESS_PROVIDER_V3: null, + GEAR_TOKEN: null, + REWARD_TOKEN: '0xad11a8BEb98bbf61dbb1aa0F6d6F2ECD87b35afA'.toLowerCase(), // USDC.E + chainName: 'Hemi', + POOLS: { + '0x614eB485DE3c6C49701b40806AC1B985ad6F0A2f': { + symbol: 'USDC.E', + underlying: '0xad11a8BEb98bbf61dbb1aa0F6d6F2ECD87b35afA', // USDC.E + name: 'USDC.E Lending Pool', + }, + }, + }, + monad: { + ADDRESS_PROVIDER_V3: null, + GEAR_TOKEN: null, + REWARD_TOKEN: '0x34752948b0dc28969485df2066ffe86d5dc36689'.toLowerCase(), // MON + chainName: 'Monad', + POOLS: { + '0x6b343f7b797f1488aa48c49d540690f2b2c89751': { + symbol: 'dUSDC', + underlying: '0x754704Bc059F8C67012fEd69BC8A327a5aafb603', // USDC + name: 'USDC Pool', + }, + '0x34752948b0dc28969485df2066ffe86d5dc36689': { + symbol: 'dMON', + underlying: '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A', // MON + name: 'MON Pool', + }, + '0x164a35f31e4e0f6c45d500962a6978d2cbd5a16b': { + symbol: 'dUSDT0', + underlying: '0xe7cd86e13AC4309349F30B3435a9d337750fC82D', // USDT0 + name: 'USDT0 Pool', + }, + '0xc4173359087ce643235420b7bc610d9b0cf2b82d': { + symbol: 'edgeAUSD', + underlying: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a', // AUSD + name: 'AUSD Pool', + }, + }, + }, +}; + +// Legacy constants for backward compatibility +var ADDRESS_PROVIDER_V3 = CHAIN_CONFIGS.ethereum.ADDRESS_PROVIDER_V3; +var GEAR_TOKEN = CHAIN_CONFIGS.ethereum.GEAR_TOKEN; +var GHO_TOKEN = '0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f'.toLowerCase(); +var POOL_USDT_V3_BROKEN = '0x1dc0f3359a254f876b37906cfc1000a35ce2d717'.toLowerCase(); +var POOL_GHO_V3 = '0x4d56c9cBa373AD39dF69Eb18F076b7348000AE09'.toLowerCase(); + +// src/yield-server/extraRewards.ts +// Chain-specific extra rewards configuration +var EXTRA_REWARDS = { + ethereum: { + [POOL_GHO_V3]: [ + { + token: GHO_TOKEN, + getFarmInfo: (timestamp) => { + const GHO_DECIMALS = Math.pow(10, 18); + const REWARD_PERIOD = 14 * 24 * 60 * 60; + const REWARDS_FIRST_START = 1711448651; + const REWARDS_FIRST_END = REWARDS_FIRST_START + REWARD_PERIOD; + const REWARDS_SECOND_END = REWARDS_FIRST_END + REWARD_PERIOD; + const REWARD_FIRST_PART = 15000 * GHO_DECIMALS; + const REWARD_SECOND_PART = 10000 * GHO_DECIMALS; + const reward = + timestamp >= REWARDS_FIRST_END + ? REWARD_SECOND_PART + : REWARD_FIRST_PART; + return { + balance: 0, + duration: REWARD_PERIOD, + finished: + timestamp >= REWARDS_FIRST_END + ? REWARDS_SECOND_END + : REWARDS_FIRST_END, + reward, + }; + }, + }, + ], + }, + plasma: { + // No extra rewards on Plasma initially + }, +}; + +// Helper function to get chain-specific extra rewards +function getExtraRewards(chain, poolAddr) { + return EXTRA_REWARDS[chain]?.[poolAddr] ?? []; +} + +// Helper function to generate pool URLs +function getPoolUrl(chain, poolAddress) { + const chainIds = { + ethereum: '', + plasma: '9745', + etlk: '42793', + lisk: '1135', + hemi: '43111', + monad: '143', + }; + + const chainId = chainIds[chain]; + return chainId ? + `https://app.gearbox.fi/pools/${chainId}/${poolAddress}` : + `https://app.gearbox.fi/pools/${poolAddress}`; +} + +// Chain-specific Merkl API configurations +const MERKL_CONFIGS = { + ethereum: { + chainId: 1, + rewardToken: '0xBa3335588D9403515223F109EdC4eB7269a9Ab5D', // GEAR + pools: [ + '0xda0002859B2d05F66a753d8241fCDE8623f26F4f', // WETH + '0xe7146F53dBcae9D6Fa3555FE502648deb0B2F823', // DAI + '0xda00000035fef4082F78dEF6A8903bee419FbF8E', // USDC + '0x05A811275fE9b4DE503B3311F51edF6A856D936e', // USDT + '0x4d56c9cBa373AD39dF69Eb18F076b7348000AE09', // GHO + '0x72CCB97cbdC40f8fb7FFA42Ed93AE74923547200', // wstETH (with Merkl rewards) + '0xa9d17f6d3285208280a1fd9b94479c62e0aaba64', // KPK wstETH + '0x9396dcbf78fc526bb003665337c5e73b699571ef', // KPK ETH + ], + }, + plasma: { + chainId: 9745, + rewardToken: '0x6100e367285b01f48d07953803a2d8dca5d19873', // WXPL + pools: [ + '0x76309A9a56309104518847BbA321c261B7B4a43f', // Invariant USDT0 (existing) + '0xB74760FD26400030620027DD29D19d74D514700e', // Hyperithm Gearbox + '0x53E4e9b8766969c43895839CC9c673bb6bC8Ac97', // Edge UltraYield + ], + }, + etlk: { + chainId: 42793, + poolId: '0x653e62A9Ef0e869F91Dc3D627B479592aA02eA75', + rewardToken: '0x0008b6C5b44305693bEB4Cd6E1A91b239D2A041E', + }, + lisk: { + chainId: 1135, + poolId: '0xA16952191248E6B4b3A24130Dfc47F96ab1956a7', + rewardToken: '0xac485391EB2d7D88253a7F1eF18C37f4242D1A24', // LISK + }, + hemi: { + chainId: 43111, + poolId: '0x614eB485DE3c6C49701b40806AC1B985ad6F0A2f', + rewardToken: '0xad11a8BEb98bbf61dbb1aa0F6d6F2ECD87b35afA', // USDC.E + }, + monad: { + chainId: 143, + rewardToken: '0x34752948b0dc28969485df2066ffe86d5dc36689', // MON + pools: [ + '0x6b343f7b797f1488aa48c49d540690f2b2c89751', // USDC Pool + '0x34752948b0dc28969485df2066ffe86d5dc36689', // MON Pool + '0x164a35f31e4e0f6c45d500962a6978d2cbd5a16b', // USDT0 Pool + '0xc4173359087ce643235420b7bc610d9b0cf2b82d', // AUSD Pool + ], + }, +}; + +// Fetch Merkl rewards data for supported chains +async function getMerklRewards(chain) { + const config = MERKL_CONFIGS[chain]; + if (!config) return {}; + + try { + const rewards = {}; + + // Handle multiple pools (new format) or single pool (backward compatibility) + const poolsToFetch = config.pools || [config.poolId]; + + // Fetch rewards for each pool + await Promise.all(poolsToFetch.map(async (poolId) => { + if (!poolId) return; + + try { + const response = await fetch(`https://api.merkl.xyz/v4/opportunities/?chainId=${config.chainId}&identifier=${poolId}`); + const data = await response.json(); + + if (!data || !Array.isArray(data) || data.length === 0) { + console.log(`⚠️ No Merkl rewards data found for ${chain} pool ${poolId}`); + return; + } + + const opportunity = data[0]; + if (opportunity.status !== 'LIVE') { + console.log(`⚠️ Merkl rewards not currently LIVE for ${chain} pool ${poolId}`); + return; + } + + // Extract reward data for this pool + rewards[opportunity.identifier.toLowerCase()] = { + apr: opportunity.apr || 0, + rewardToken: config.rewardToken, + tvl: opportunity.tvl || 0, + dailyRewards: opportunity.dailyRewards || 0, + }; + } catch (poolError) { + console.error(`Error fetching Merkl rewards for ${chain} pool ${poolId}:`, poolError.message); + } + })); + + return rewards; + } catch (error) { + console.error(`Error fetching Merkl rewards for ${chain}:`, error.message); + return {}; + } +} + +// src/yield-server/index.ts +var SECONDS_PER_YEAR = 365 * 24 * 60 * 60; +var WAD = Math.pow(10, 18); +var RAY = Math.pow(10, 27); +var PERCENTAGE_FACTOR = 10000; +async function call(...args) { + return sdk.api2.abi.call(...args); +} +async function multiCall(...args) { + return sdk.api2.abi.multiCall(...args); +} +async function fetchLLamaPrices(chain, addresses) { + const coins = addresses.map((address) => `${chain}:${address}`).join(','); + const resp = await fetch(`https://coins.llama.fi/prices/current/${coins}`); + const data = await resp.json(); + const prices = {}; + for (const [coin, info] of Object.entries(data.coins)) { + const address = coin.split(':')[1]; + prices[address.toLowerCase()] = Number(WAD) * info.price; + } + return prices; +} +async function getPoolsDaoFees(chain) { + const chainConfig = CHAIN_CONFIGS[chain]; + + // For chains without ADDRESS_PROVIDER_V3 (like Plasma), return empty fees + if (!chainConfig?.ADDRESS_PROVIDER_V3) { + console.log(`⚠️ No ADDRESS_PROVIDER_V3 for ${chain}, using default fees`); + return {}; + } + + try { + const contractsRegisterAddr = await call({ + abi: abis_default.getAddressOrRevert, + target: chainConfig.ADDRESS_PROVIDER_V3, + params: [ + // cast format-bytes32-string "CONTRACTS_REGISTER" + '0x434f4e5452414354535f52454749535445520000000000000000000000000000', + 0, + ], + chain, + }); + const cms = await call({ + target: contractsRegisterAddr, + abi: abis_default.getCreditManagers, + chain, + }); + const pools = await multiCall({ + abi: abis_default.pool, + calls: cms.map((target) => ({ target })), + chain, + permitFailure: true, + }); + const daoFees = await multiCall({ + abi: abis_default.fees, + calls: cms.map((target) => ({ target })), + chain, + permitFailure: true, + }); + const result = {}; + for (let i = 0; i < daoFees.length; i++) { + const daoFee = daoFees[i]; + const pool = pools[i]?.toLowerCase(); + if (daoFee && pool) { + result[pool] = Number(daoFee.feeInterest); + } + } + return result; + } catch (error) { + console.error(`Error fetching DAO fees for ${chain}:`, error.message); + return {}; + } +} +// Plasma-specific pool fetching (individual pools, not registry-based) +async function getPlasmaPoolsV3(chain) { + const chainConfig = CHAIN_CONFIGS[chain]; + if (!chainConfig?.POOLS) { + return []; + } + + const poolAddresses = Object.keys(chainConfig.POOLS); + console.log(`🔍 Fetching ${poolAddresses.length} ${chain} pools...`); + + try { + // Get basic pool data including borrowing information + const [symbols, decimalsData, totalSupplies, supplyRates, totalBorrowedAmounts, availableLiquidities, baseInterestRates] = await Promise.all([ + multiCall({ + abi: abis_default.symbol, + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: abis_default.decimals, + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: 'erc20:totalSupply', + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: 'function supplyRate() external view returns (uint256)', + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: 'function totalBorrowed() external view returns (uint256)', + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: 'function availableLiquidity() external view returns (uint256)', + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: 'function baseInterestRate() external view returns (uint256)', + calls: poolAddresses.map((target) => ({ target })), + chain, + }), + ]); + + // Try to get underlying token (may fail, we'll handle gracefully) + let underlyingTokens = []; + try { + underlyingTokens = await multiCall({ + abi: 'function underlying() external view returns (address)', + calls: poolAddresses.map((target) => ({ target })), + chain, + permitFailure: true, + }); + } catch (error) { + console.log('⚠️ underlying() function not available, using pool as underlying'); + underlyingTokens = poolAddresses.map(() => null); + } + + const pools = poolAddresses.map((poolAddr, i) => { + const config = chainConfig.POOLS[poolAddr]; + return { + pool: poolAddr, + addr: poolAddr, + name: config.name, + symbol: symbols[i] || config.symbol, + underlying: underlyingTokens[i] || config.underlying || poolAddr, // Use config.underlying if available + // For Plasma USDT0 pool, use the actual USDT0 deposit token address for pricing + underlyingForPrice: config.underlying || (underlyingTokens[i] || poolAddr), + decimals: Math.pow(10, decimalsData[i]), + totalSupply: Number(totalSupplies[i]), + supplyRate: Number(supplyRates[i]), + // Real borrowing data from contract + availableLiquidity: Number(availableLiquidities[i]), + totalBorrowed: Number(totalBorrowedAmounts[i]), + baseInterestRate: Number(baseInterestRates[i]), + dieselRate: Math.pow(10, 27), // Default 1:1 rate for Plasma + withdrawFee: 0, + }; + }); + + console.log(`✅ Successfully fetched ${pools.length} ${chain} pools`); + return pools; + } catch (error) { + console.error(`Error fetching ${chain} pools:`, error.message); + return []; + } +} + +async function getPoolsV3(chain) { + // Handle non-registry chains using the individual pool approach + if (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') { + return await getPlasmaPoolsV3(chain); + } + + const chainConfig = CHAIN_CONFIGS[chain]; + + // Check if there are manual pools configured for this chain + const manualPools = chainConfig?.POOLS || {}; + const hasManualPools = Object.keys(manualPools).length > 0; + + // If there are manual pools, fetch them using the Plasma approach + let manualPoolsData = []; + if (hasManualPools) { + manualPoolsData = await getPlasmaPoolsV3(chain); + } + + // Original Ethereum implementation with registry + const stakedDieselTokens = [ + '0x9ef444a6d7F4A5adcd68FD5329aA5240C90E14d2', + // sdUSDCV3 + '0xA8cE662E45E825DAF178DA2c8d5Fae97696A788A', + // sdWBTCV3 + '0x0418fEB7d0B25C411EB77cD654305d29FcbFf685', + // sdWETHV3 + '0x16adAb68bDEcE3089D4f1626Bb5AEDD0d02471aD', + // sdUSDTV3 + '0xE2037090f896A858E3168B978668F22026AC52e7', + // sdGHOV3 + '0xC853E4DA38d9Bd1d01675355b8c8f3BBC1451973', + // sdDAIV3 + ]; + const [farmInfos, totalSupplies, poolV3Addrs] = await Promise.all([ + multiCall({ + abi: abis_default.farmInfo, + calls: stakedDieselTokens.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: abis_default.totalSupply, + calls: stakedDieselTokens.map((target) => ({ target })), + chain, + }), + multiCall({ + abi: abis_default.stakingToken, + calls: stakedDieselTokens.map((target) => ({ target })), + chain, + }), + ]); + const farmingPoolsData = {}; + for (let i = 0; i < stakedDieselTokens.length; i++) { + farmingPoolsData[poolV3Addrs[i]] = { + stakedDieselToken: stakedDieselTokens[i], + stakedDieselTokenSupply: Number(totalSupplies[i]), + farmInfo: { + balance: Number(farmInfos[i].balance), + duration: Number(farmInfos[i].duration), + finished: Number(farmInfos[i].finished), + reward: Number(farmInfos[i].reward), + }, + }; + } + const dc300 = await call({ + abi: abis_default.getAddressOrRevert, + target: chainConfig.ADDRESS_PROVIDER_V3, + params: [ + // cast format-bytes32-string "DATA_COMPRESSOR" + '0x444154415f434f4d50524553534f520000000000000000000000000000000000', + 300, + ], + chain, + }); + const pools = await call({ + target: dc300, + abi: abis_default.getPoolsV3List, + chain, + }); + const decimals = await multiCall({ + abi: abis_default.decimals, + calls: pools.map((p) => ({ + target: p.dieselToken, + })), + chain, + }); + const registryPools = pools + .map((pool, i) => ({ + pool: pool.addr, + name: pool.name, + availableLiquidity: Number(pool.availableLiquidity), + totalBorrowed: Number(pool.totalBorrowed), + supplyRate: Number(pool.supplyRate), + baseInterestRate: Number(pool.baseInterestRate), + dieselRate: Number(pool.dieselRate_RAY), + underlying: pool.underlying, + withdrawFee: Number(pool.withdrawFee), + symbol: pool.symbol, + decimals: Math.pow(10, decimals[i]), + ...farmingPoolsData[pool.addr], + })) + .filter(({ pool }) => { + const excludedPools = chainConfig?.EXCLUDED_POOLS || {}; + return !excludedPools[pool.toLowerCase()]; + }); + + // Merge registry pools with manual pools, with manual pools taking precedence + if (hasManualPools) { + const poolMap = new Map(); + // Add registry pools first + for (const pool of registryPools) { + poolMap.set(pool.pool.toLowerCase(), pool); + } + // Add or override with manual pools + for (const pool of manualPoolsData) { + const key = pool.pool.toLowerCase(); + poolMap.set(key, { ...(poolMap.get(key) || {}), ...pool }); + } + return Array.from(poolMap.values()); + } + + return registryPools; +} +async function getTokensData(chain, pools) { + // For non-registry chains, we need to use known token addresses for pricing + let tokens; + if (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') { + tokens = pools.map((p) => p.underlyingForPrice || p.underlying); + } else { + tokens = pools.map((p) => p.underlying); + } + + const chainConfig = CHAIN_CONFIGS[chain]; + + // Add chain-specific reward tokens + if (chainConfig?.GEAR_TOKEN) { + tokens.push(chainConfig.GEAR_TOKEN); + } + if (chainConfig?.WXPL_TOKEN) { + tokens.push(chainConfig.WXPL_TOKEN); + } + if (chainConfig?.REWARD_TOKEN) { + tokens.push(chainConfig.REWARD_TOKEN); + } + + // Add chain-specific extra reward tokens + const chainExtraRewards = EXTRA_REWARDS[chain] || {}; + tokens.push( + ...Object.values(chainExtraRewards).flatMap((poolExtras) => + poolExtras.map(({ token }) => token) + ) + ); + + tokens = Array.from(new Set(tokens.map((t) => t.toLowerCase()).filter(Boolean))); + + // Use the appropriate chain for pricing + const prices = await fetchLLamaPrices(chain, tokens); + const symbols = await multiCall({ + abi: abis_default.symbol, + calls: tokens.map((target) => ({ target })), + chain, + }); + const decimals = await multiCall({ + abi: abis_default.decimals, + calls: tokens.map((target) => ({ target })), + chain, + }); + const result = {}; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + result[token] = { + symbol: symbols[i], + decimals: Math.pow(10, decimals[i]), + price: prices[token], + }; + } + return result; +} +function calcApyV3(info, supply, rewardPrice) { + if (!info) return 0; + const now = Math.floor(Date.now() / 1e3); + + // Convert all values to Numbers for safer calculation + const finished = Number(info.finished || 0); + const amount = Number(supply.amount || 0); + const price = Number(supply.price || 0); + const decimals = Number(supply.decimals || 1); + const reward = Number(info.reward || 0); + const duration = Number(info.duration || 1); + const rewardPriceNum = Number(rewardPrice || 0); + + if (finished <= now) { + return 0; + } + if (amount <= 0) { + return 0; + } + if (price === 0 || rewardPriceNum === 0) { + return 0; + } + if (duration === 0) { + return 0; + } + + const supplyUsd = (price * amount) / decimals; + const rewardUsd = (rewardPriceNum * reward) / WAD; + const secondsPerYear = SECONDS_PER_YEAR; + const percentageFactor = PERCENTAGE_FACTOR; + + return ( + (percentageFactor * rewardUsd * secondsPerYear) / + (supplyUsd * duration) + ) / 100; +} +function calculateTvl(availableLiquidity, totalBorrowed, price, decimals) { + return (((Number(availableLiquidity) + Number(totalBorrowed)) / Number(decimals)) * Number(price)) / WAD; +} +async function getApyV3(pools, tokens, daoFees, chain, merklRewards = {}) { + const chainConfig = CHAIN_CONFIGS[chain]; + + return pools.map((pool) => { + const underlying = pool.underlying.toLowerCase(); + const poolAddr = pool.pool.toLowerCase(); + // For non-registry chains, use the underlyingForPrice token for pricing + const priceToken = (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') && pool.underlyingForPrice ? + pool.underlyingForPrice.toLowerCase() : underlying; + const underlyingPrice = tokens[priceToken]?.price || 0; + const daoFee = Number(daoFees[poolAddr] ?? 0); + + // Calculate TVL and borrowing data using the same logic for all chains + let totalSupplyUsd, totalBorrowUsd, tvlUsd; + + if (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') { + // Use proper Gearbox calculation for non-registry chains with real borrowing data + totalSupplyUsd = calculateTvl( + pool.availableLiquidity, + pool.totalBorrowed, + underlyingPrice, + pool.decimals + ); + totalBorrowUsd = calculateTvl( + 0, + pool.totalBorrowed, + underlyingPrice, + pool.decimals + ); + tvlUsd = totalSupplyUsd - totalBorrowUsd; + } else { + // Original Ethereum calculation + totalSupplyUsd = calculateTvl( + pool.availableLiquidity, + pool.totalBorrowed, + underlyingPrice, + pool.decimals + ); + totalBorrowUsd = calculateTvl( + 0, + pool.totalBorrowed, + underlyingPrice, + pool.decimals + ); + tvlUsd = totalSupplyUsd - totalBorrowUsd; + } + + const dieselPrice = (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') ? + Number(underlyingPrice) / WAD : // For non-registry chains, use simpler calculation + (Number(underlyingPrice) * Number(pool.dieselRate)) / RAY; + const supplyInfo = { + amount: Number(pool.stakedDieselTokenSupply || pool.totalSupply || 0), + decimals: Number(pool.decimals || 1), + price: Number(dieselPrice || 0), + }; + + // Calculate reward APY + let apyRewardTotal = 0; + const rewardTokens = []; + const extraRewardTokens = []; + + // Add GEAR token rewards if available on this chain + if (chainConfig?.GEAR_TOKEN && tokens[chainConfig.GEAR_TOKEN]) { + rewardTokens.push(chainConfig.GEAR_TOKEN); + apyRewardTotal = calcApyV3( + pool.farmInfo, + supplyInfo, + tokens[chainConfig.GEAR_TOKEN].price + ); + } + + // Add extra rewards for this chain and pool + for (const { token, getFarmInfo } of getExtraRewards(chain, poolAddr)) { + extraRewardTokens.push(token); + const farmInfo = getFarmInfo( + Math.floor(new Date().getTime() / 1e3) + ); + const apyReward = calcApyV3(farmInfo, supplyInfo, tokens[token]?.price || 0); + apyRewardTotal += apyReward; + } + + // Add Merkl rewards for supported chains + const merklReward = merklRewards[poolAddr]; + if (merklReward && merklReward.apr > 0) { + // Use the reward token from merklReward itself + extraRewardTokens.push(merklReward.rewardToken); + apyRewardTotal += merklReward.apr; + } + return { + pool: poolAddr, + chain: chainConfig.chainName, + project: 'gearbox', + symbol: tokens[underlying]?.symbol || pool.symbol || 'Unknown', + tvlUsd: Number(tvlUsd) || 0, + apyBase: (Number(pool.supplyRate) / 1e27) * 100, + apyReward: apyRewardTotal, + underlyingTokens: [pool.underlying], + rewardTokens: [...rewardTokens, ...extraRewardTokens], + url: getPoolUrl(chain, pool.pool), + // daoFee here is taken from last cm connected to this pool. in theory, it can be different for different CMs + // in practice, it's 25% for v3 cms and 50% for v2 cms + apyBaseBorrow: (chain === 'plasma' || chain === 'etlk' || chain === 'lisk' || chain === 'hemi' || chain === 'monad') ? + // For non-registry chains, use base interest rate directly (no DAO fees initially) + (Number(pool.baseInterestRate) / 1e27) * 100 : + ((daoFee + PERCENTAGE_FACTOR) * + (Number(pool.baseInterestRate) / 1e27)) / + 100, + apyRewardBorrow: 0, + totalSupplyUsd: Number(totalSupplyUsd) || 0, + totalBorrowUsd: Number(totalBorrowUsd) || 0, + ltv: 0, + }; + }); +} +async function getApy() { + const supportedChains = ['ethereum', 'plasma', 'etlk', 'lisk', 'hemi', 'monad']; + const allPools = []; + + console.log(`🚀 Fetching Gearbox data for chains: ${supportedChains.join(', ')}`); + + for (const chain of supportedChains) { + try { + console.log(`🔍 Processing ${chain}...`); + + const [daoFees, v3Pools, merklRewards] = await Promise.all([ + getPoolsDaoFees(chain), + getPoolsV3(chain), + getMerklRewards(chain) + ]); + + if (v3Pools.length === 0) { + console.log(`⚠️ No pools found for ${chain}`); + continue; + } + + const tokens = await getTokensData(chain, v3Pools); + const chainPools = await getApyV3(v3Pools, tokens, daoFees, chain, merklRewards); + + console.log(`✅ ${chain}: ${chainPools.length} pools processed`); + allPools.push(...chainPools); + } catch (error) { + console.error(`❌ Error processing ${chain}:`, error.message); + // Continue with other chains even if one fails + } + } + + console.log(`🎉 Total pools fetched: ${allPools.length}`); + return allPools.filter((pool) => utils.keepFinite(pool)); +} +var yield_server_default = { + timetravel: false, + apy: getApy, +}; + +module.exports = yield_server_default; diff --git a/src/adaptors/geist-finance/abi.json b/src/adaptors/geist-finance/abi.json new file mode 100644 index 0000000000..ec3e9a3393 --- /dev/null +++ b/src/adaptors/geist-finance/abi.json @@ -0,0 +1,793 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "premium", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidatedCollateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "LiquidationCall", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Paused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RebalanceStableBorrowRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Unpaused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "FLASHLOAN_PREMIUM_TOTAL", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LENDINGPOOL_REVISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_NUMBER_RESERVES", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STABLE_RATE_BORROW_SIZE_PERCENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "interestRateMode", + "type": "uint256" + }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "balanceFromBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceToBefore", + "type": "uint256" + } + ], + "name": "finalizeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiverAddress", + "type": "address" + }, + { "internalType": "address[]", "name": "assets", "type": "address[]" }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "modes", "type": "uint256[]" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "bytes", "name": "params", "type": "bytes" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { "internalType": "uint8", "name": "id", "type": "uint8" } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedIncome", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedVariableDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserAccountData", + "outputs": [ + { + "internalType": "uint256", + "name": "totalCollateralETH", + "type": "uint256" + }, + { "internalType": "uint256", "name": "totalDebtETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "availableBorrowsETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentLiquidationThreshold", + "type": "uint256" + }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { "internalType": "uint256", "name": "healthFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.UserConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "name": "initReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { "internalType": "address", "name": "debtAsset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "debtToCover", "type": "uint256" }, + { "internalType": "bool", "name": "receiveAToken", "type": "bool" } + ], + "name": "liquidationCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "rebalanceStableBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "repay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "configuration", "type": "uint256" } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "val", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { + "internalType": "address", + "name": "rateStrategyAddress", + "type": "address" + } + ], + "name": "setReserveInterestRateStrategyAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "bool", "name": "useAsCollateral", "type": "bool" } + ], + "name": "setUserUseReserveAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" } + ], + "name": "swapBorrowRateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/geist-finance/abiDataProvider.json b/src/adaptors/geist-finance/abiDataProvider.json new file mode 100644 index 0000000000..bbf43f504f --- /dev/null +++ b/src/adaptors/geist-finance/abiDataProvider.json @@ -0,0 +1,233 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "addressesProvider", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADDRESSES_PROVIDER", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllATokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReservesTokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserveFactor", "type": "uint256" }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "isActive", "type": "bool" }, + { "internalType": "bool", "name": "isFrozen", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVariableDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveTokensAddresses", + "outputs": [ + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "currentATokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "scaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint40", + "name": "stableRateLastUpdated", + "type": "uint40" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/geist-finance/index.js b/src/adaptors/geist-finance/index.js index 1af5661156..88599c5e25 100644 --- a/src/adaptors/geist-finance/index.js +++ b/src/adaptors/geist-finance/index.js @@ -1,103 +1,94 @@ -const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); const utils = require('../utils'); +const abi = require('./abi.json'); +const abiDataProvider = require('./abiDataProvider.json'); const pools = require('./pools.json'); const url = 'https://api.geist.finance/api/lendingPoolRewards'; -const sleep = async (ms) => { - return new Promise((resolve) => { - setTimeout(resolve, ms); - }); -}; - -const apy = async (pools, dataTvl) => { - const maxCallsPerSec = 5; - let data = []; - for (const [i, pool] of pools.entries()) { - let x = dataTvl.find((el) => el.tokenAddress === pool.address); - let depositApy = await getDepositApy(x.underlyingAsset); - if ((i + 1) % maxCallsPerSec === 0) { - await sleep(1000); - } - - data.push({ - id: x.tokenAddress, - symbol: pool.symbol, - tvl: x.poolValue, - depositApy, - rewardApy: x.apy * 100, - }); - } - return data; -}; - -const padHex = (hexstring, intSize = 256) => { - hexstring = hexstring.replace('0x', ''); - const length = intSize / 4 - hexstring.length; - for (let i = 0; i < length; i++) { - hexstring = '0' + hexstring; - } - return hexstring; -}; - -const getDepositApy = async (address) => { - const lendingPoolContract = '0x9FAD24f572045c7869117160A571B2e50b10d068'; - const getReserveDataHash = '35ea6a75'; - address = padHex(address); - - const url = - 'https://api.ftmscan.com/api?module=proxy&action=eth_call&to=' + - lendingPoolContract + - '&data=0x' + - getReserveDataHash + - address + - '&tag=latest&apikey=' + - process.env.FANTOMSCAN; - const response = await superagent(url); - const data = response.body; - const hexValue = data.result; - - // extract relevant deposit apy value only - let x = hexValue.replace('0x', ''); - const bytes = 64; - x = parseInt(x.slice(bytes * 3, bytes * 4), 16) / 1e25; +const aaveProtocolDataProvider = '0xf3B0611e2E4D2cd6aB4bb3e01aDe211c3f42A8C3'; - return x; -}; - -const buildPool = (entry, chainString) => { - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'geist-finance', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.tvl, - apy: entry.depositApy + entry.rewardApy, - }; - - return newObj; -}; - -const topLvl = async (chainString, url) => { - // pull data - const dataTvl = await utils.getData(url); - - // calculate apy - let data = await apy(pools, dataTvl.data.poolAPRs); - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; +// geist has an early exit penalty of 50% +const earlyExitPenalty = 0.5; const main = async () => { - const data = await Promise.all([topLvl('fantom', url)]); - return data.flat(); + // total supply for each pool + reward apr for both lend and borrow side + const rewardAPRs = (await utils.getData(url)).data.poolAPRs; + + const reserveDataRes = await sdk.api.abi.multiCall({ + abi: abi.find((a) => a.name === 'getReserveData'), + chain: 'fantom', + calls: pools.map((a) => ({ + target: '0x9FAD24f572045c7869117160A571B2e50b10d068', + params: [a.underlyingAsset], + })), + }); + const reserveData = reserveDataRes.output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: pools.map((a) => ({ + target: a.underlyingAsset, + params: method === 'erc20:balanceOf' ? [a.interestBearing] : null, + })), + chain: 'fantom', + }) + ) + ); + const liquidityData = liquidityRes.output.map((o) => o.output); + const decimalsData = decimalsRes.output.map((o) => o.output); + const symbolsData = symbolsRes.output.map((o) => o.output); + + return await Promise.all( + reserveData.map(async (p, i) => { + const interest = rewardAPRs.find( + (el) => el.tokenAddress === p.aTokenAddress + ); + const debt = rewardAPRs.find( + (el) => el.tokenAddress === p.variableDebtTokenAddress + ); + + const ltv = + ( + await sdk.api.abi.call({ + target: aaveProtocolDataProvider, + params: [interest.underlyingAsset], + abi: abiDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + chain: 'fantom', + }) + ).output.ltv / 1e4; + + return { + pool: p.aTokenAddress, + chain: 'Fantom', + project: 'geist-finance', + symbol: utils.formatSymbol(symbolsData[i]), + // note(!) this is total supply instead of available liquidity, will need to update + tvlUsd: interest.poolValue, + apyBase: p.currentLiquidityRate / 1e25, + apyReward: interest.apy * 100 * earlyExitPenalty, + underlyingTokens: [interest.underlyingAsset], + rewardTokens: ['0xd8321aa83fb0a4ecd6348d4577431310a6e0814d'], // Geist + // borrow fields + apyBaseBorrow: p.currentVariableBorrowRate / 1e25, + apyRewardBorrow: debt.apy * 100 * earlyExitPenalty, + totalSupplyUsd: interest.poolValue, + totalBorrowUsd: + interest.poolValue - + (liquidityData[i] / 10 ** decimalsData[i]) * interest.assetPrice, + ltv, + }; + }) + ); }; module.exports = { timetravel: false, apy: main, + url: 'https://geist.finance/markets', }; diff --git a/src/adaptors/geist-finance/pools.json b/src/adaptors/geist-finance/pools.json index 911f9e369a..3b2f0a2e93 100644 --- a/src/adaptors/geist-finance/pools.json +++ b/src/adaptors/geist-finance/pools.json @@ -1,38 +1,38 @@ [ { - "address": "0x07E6332dD090D287d3489245038daF987955DCFB", - "symbol": "gDAI" + "interestBearing": "0x07E6332dD090D287d3489245038daF987955DCFB", + "underlyingAsset": "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E" }, { - "address": "0x25c130B2624CF12A4Ea30143eF50c5D68cEFA22f", - "symbol": "gETH" + "interestBearing": "0x25c130B2624CF12A4Ea30143eF50c5D68cEFA22f", + "underlyingAsset": "0x74b23882a30290451A17c44f4F05243b6b58C76d" }, { - "address": "0x39B3bd37208CBaDE74D0fcBDBb12D606295b430a", - "symbol": "gFTM" + "interestBearing": "0x39B3bd37208CBaDE74D0fcBDBb12D606295b430a", + "underlyingAsset": "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83" }, { - "address": "0x38aCa5484B8603373Acc6961Ecd57a6a594510A3", - "symbol": "gWBTC" + "interestBearing": "0x38aCa5484B8603373Acc6961Ecd57a6a594510A3", + "underlyingAsset": "0x321162Cd933E2Be498Cd2267a90534A804051b11" }, { - "address": "0x940F41F0ec9ba1A34CF001cc03347ac092F5F6B5", - "symbol": "gfUSDT" + "interestBearing": "0x940F41F0ec9ba1A34CF001cc03347ac092F5F6B5", + "underlyingAsset": "0x049d68029688eAbF473097a2fC38ef61633A3C7A" }, { - "address": "0xe578C856933D8e1082740bf7661e379Aa2A30b26", - "symbol": "gUSDC" + "interestBearing": "0xe578C856933D8e1082740bf7661e379Aa2A30b26", + "underlyingAsset": "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75" }, { - "address": "0x690754A168B022331cAA2467207c61919b3F8A98", - "symbol": "gCRV" + "interestBearing": "0x690754A168B022331cAA2467207c61919b3F8A98", + "underlyingAsset": "0x1E4F97b9f9F913c46F1632781732927B9019C68b" }, { - "address": "0xc664Fc7b8487a3E10824Cda768c1d239F2403bBe", - "symbol": "gMIM" + "interestBearing": "0xc664Fc7b8487a3E10824Cda768c1d239F2403bBe", + "underlyingAsset": "0x82f0B8B456c1A451378467398982d4834b6829c1" }, { - "address": "0xBeCF29265B0cc8D33fA24446599955C7bcF7F73B", - "symbol": "gLINK" + "interestBearing": "0xBeCF29265B0cc8D33fA24446599955C7bcF7F73B", + "underlyingAsset": "0xb3654dc3D10Ea7645f8319668E8F54d2574FBdC8" } ] diff --git a/src/adaptors/genesislrt-(native-restaking)/abi.js b/src/adaptors/genesislrt-(native-restaking)/abi.js new file mode 100644 index 0000000000..6f0da935cd --- /dev/null +++ b/src/adaptors/genesislrt-(native-restaking)/abi.js @@ -0,0 +1,339 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'approver', type: 'address' }], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'spender', type: 'address' }], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { inputs: [], name: 'EnforcedPause', type: 'error' }, + { inputs: [], name: 'ExpectedPause', type: 'error' }, + { inputs: [], name: 'InvalidInitialization', type: 'error' }, + { inputs: [], name: 'MathOverflowedMulDiv', type: 'error' }, + { inputs: [], name: 'NotInitializing', type: 'error' }, + { inputs: [], name: 'OnlyGovernanceAllowed', type: 'error' }, + { inputs: [], name: 'OnlyOperatorAllowed', type: 'error' }, + { inputs: [], name: 'OnlyRestakingPoolAllowed', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'version', + type: 'uint64', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'newName', + type: 'string', + }, + ], + name: 'NameChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'newSymbol', + type: 'string', + }, + ], + name: 'SymbolChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'string', name: 'newName', type: 'string' }], + name: 'changeName', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'string', name: 'newSymbol', type: 'string' }], + name: 'changeSymbol', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'config', + outputs: [ + { internalType: 'contract IProtocolConfig', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IProtocolConfig', + name: 'config', + type: 'address', + }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ratio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { internalType: 'uint256', name: 'totalManagedEth', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/genesislrt-(native-restaking)/abiVault.js b/src/adaptors/genesislrt-(native-restaking)/abiVault.js new file mode 100644 index 0000000000..5b8dfaa454 --- /dev/null +++ b/src/adaptors/genesislrt-(native-restaking)/abiVault.js @@ -0,0 +1,168 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { inputs: [], name: 'InvalidInitialization', type: 'error' }, + { inputs: [], name: 'NotInitializing', type: 'error' }, + { inputs: [], name: 'OnlyGovernanceAllowed', type: 'error' }, + { inputs: [], name: 'OnlyOperatorAllowed', type: 'error' }, + { inputs: [], name: 'OnlyRestakingPoolAllowed', type: 'error' }, + { + inputs: [ + { internalType: 'enum IRatioFeed.RatioError', name: '', type: 'uint8' }, + ], + name: 'RatioNotUpdated', + type: 'error', + }, + { inputs: [], name: 'RatioThresholdNotInRange', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'version', + type: 'uint64', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newValue', + type: 'uint256', + }, + ], + name: 'RatioThresholdChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldRatio', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRatio', + type: 'uint256', + }, + ], + name: 'RatioUpdated', + type: 'event', + }, + { + inputs: [], + name: 'INITIAL_RATIO', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_THRESHOLD', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint8', name: 'day', type: 'uint8' }, + ], + name: 'averagePercentageRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'config', + outputs: [ + { internalType: 'contract IProtocolConfig', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'getRatio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'historicalRatios', + outputs: [{ internalType: 'uint40', name: 'lastUpdate', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IProtocolConfig', + name: 'config', + type: 'address', + }, + { internalType: 'uint256', name: 'ratioThreshold_', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'ratioThreshold', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'newRatio', type: 'uint256' }, + ], + name: 'repairRatio', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newValue', type: 'uint256' }], + name: 'setRatioThreshold', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'newRatio', type: 'uint256' }, + ], + name: 'updateRatio', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/genesislrt-(native-restaking)/index.js b/src/adaptors/genesislrt-(native-restaking)/index.js new file mode 100644 index 0000000000..ce30b21af2 --- /dev/null +++ b/src/adaptors/genesislrt-(native-restaking)/index.js @@ -0,0 +1,63 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abi = require('./abi'); +const abiVault = require('./abiVault'); + +const inETH = '0xf073bAC22DAb7FaF4a3Dd6c6189a70D54110525C'; +const vault = '0x122ee24cb3cc1b6b987800d3b54a68fc16910dbf'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: inETH, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const apr1d = + ( + await sdk.api.abi.call({ + target: vault, + abi: abiVault.find((m) => m.name === 'averagePercentageRate'), + params: [inETH, 1], + }) + ).output / 1e18; + + const apr7d = + ( + await sdk.api.abi.call({ + target: vault, + abi: abiVault.find((m) => m.name === 'averagePercentageRate'), + params: [inETH, 7], + }) + ).output / 1e18; + + const priceKey = `coingecko:genesislrt-restaked-eth`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + console.log(apr7d, price); + process.exit(); + + return [ + { + pool: inETH, + chain: 'ethereum', + project: 'genesislrt-(native-restaking)', + symbol: 'inETH', + tvlUsd: totalSupply * price, + apyBase: apr1d, + apyBase7d: apr7d, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.inceptionlrt.com/app/restaking/restake/?token=ETH', +}; diff --git a/src/adaptors/geth/index.js b/src/adaptors/geth/index.js new file mode 100644 index 0000000000..d859bbb3df --- /dev/null +++ b/src/adaptors/geth/index.js @@ -0,0 +1,34 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const token = '0x3802c218221390025bceabbad5d8c59f40eb74b8'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const apyData = (await axios.get('https://guarda.com/stake-api/eth2')).data; + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'geth', + symbol: 'geth', + tvlUsd: tvl * ethPrice, + apyBase: Number(apyData.eth2.eth_interest.replace('%', '')), + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://guarda.com/staking/ethereum-staking/', +}; diff --git a/src/adaptors/ghost/index.js b/src/adaptors/ghost/index.js new file mode 100644 index 0000000000..b99567f4a0 --- /dev/null +++ b/src/adaptors/ghost/index.js @@ -0,0 +1,73 @@ +const fetch = require('node-fetch'); + +const utils = require('../utils'); + +const uniquePools = new Set(); +const project = 'ghost'; + +const getApy = async () => { + const res = await fetch( + 'https://raw.githubusercontent.com/Team-Kujira/kujira.js/master/src/resources/contracts.json' + ); + const contracts = await res.json(); + const vaultContracts = contracts['kaiyo-1'].ghostVault; + return await Promise.all( + vaultContracts.map(async (contract) => { + const { data } = await utils.getData( + `https://rest.cosmos.directory/kujira/cosmwasm/wasm/v1/contract/${contract.address}/smart/eyJzdGF0dXMiOnt9fQ==` + ); + const { deposited, borrowed, rate } = data; + const borrowApy = parseFloat(rate) * 100; + const utilization = Number(borrowed) / Number(deposited); + const available = Number(deposited) - Number(borrowed); + const lendApy = utilization ? utilization * borrowApy : borrowApy; + + if ('live' in contract.config.oracle) { + const { exchange_rate } = await utils.getData( + `https://rest.cosmos.directory/kujira/oracle/denoms/${contract.config.oracle.live}/exchange_rate` + ); + const totalSupplyUsd = + (Number(deposited) * exchange_rate) / 10 ** contract.config.decimals; + const totalBorrowUsd = + (Number(borrowed) * exchange_rate) / 10 ** contract.config.decimals; + + return { + pool: contract.address, + chain: utils.formatChain('kujira'), + project, + symbol: utils.formatSymbol(contract.config.oracle.live), + tvlUsd: (available * exchange_rate) / 10 ** contract.config.decimals, + apy: lendApy, + apyBaseBorrow: borrowApy, + apyRewardBorrow: 0, + totalSupplyUsd, + totalBorrowUsd, + }; + } else { + const totalSupplyUsd = + Number(deposited) / 10 ** contract.config.decimals; + const totalBorrowUsd = + Number(borrowed) / 10 ** contract.config.decimals; + + return { + pool: contract.address, + chain: utils.formatChain('kujira'), + project, + symbol: utils.formatSymbol('USK'), + tvlUsd: available / 10 ** contract.config.decimals, + apy: lendApy, + apyBaseBorrow: borrowApy, + apyRewardBorrow: 0, + totalSupplyUsd, + totalBorrowUsd, + }; + } + }) + ); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://ghost.kujira.network/lend', +}; diff --git a/src/adaptors/ghostmarket/index.js b/src/adaptors/ghostmarket/index.js new file mode 100644 index 0000000000..e1776ff0a8 --- /dev/null +++ b/src/adaptors/ghostmarket/index.js @@ -0,0 +1,15 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const poolData = await utils.getData( + 'https://api-external.ghostmarket.io/defillama/yield' + ); + console.log(poolData) + return [poolData] +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://ghostmarket.io/incentives/gfund' +}; \ No newline at end of file diff --git a/src/adaptors/glacier-exchange-v2/abiGauge.json b/src/adaptors/glacier-exchange-v2/abiGauge.json new file mode 100644 index 0000000000..0f468d1e41 --- /dev/null +++ b/src/adaptors/glacier-exchange-v2/abiGauge.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimed0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimed1","type":"uint256"}],"name":"ClaimFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchUpdateRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"balanceOf","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFees","outputs":[{"internalType":"uint256","name":"claimed0","type":"uint256"},{"internalType":"uint256","name":"claimed1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"derivedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"derivedBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derivedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"external_bribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorBalanceIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorRewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorSupplyIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stake","type":"address"},{"internalType":"address","name":"_internal_bribe","type":"address"},{"internalType":"address","name":"_external_bribe","type":"address"},{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"bool","name":"_forPair","type":"bool"},{"internalType":"address[]","name":"_allowedRewardTokens","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"internal_bribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isForPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"lastEarn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"left","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerTokenCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"rewardPerToken","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stake","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supplyCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"},{"internalType":"address","name":"oldToken","type":"address"},{"internalType":"address","name":"newToken","type":"address"}],"name":"swapOutRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/adaptors/glacier-exchange-v2/abiPair.json b/src/adaptors/glacier-exchange-v2/abiPair.json new file mode 100644 index 0000000000..667a75c26d --- /dev/null +++ b/src/adaptors/glacier-exchange-v2/abiPair.json @@ -0,0 +1,1140 @@ +[ + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "owner", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "spender", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount", + "type" : "uint256" + } + ], + "name" : "Approval", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "sender", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1", + "type" : "uint256" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "to", + "type" : "address" + } + ], + "name" : "Burn", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "sender", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "recipient", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1", + "type" : "uint256" + } + ], + "name" : "Claim", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "sender", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1", + "type" : "uint256" + } + ], + "name" : "Fees", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : false, + "internalType" : "uint8", + "name" : "version", + "type" : "uint8" + } + ], + "name" : "Initialized", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "sender", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1", + "type" : "uint256" + } + ], + "name" : "Mint", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "sender", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0In", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1In", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount0Out", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount1Out", + "type" : "uint256" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "to", + "type" : "address" + } + ], + "name" : "Swap", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : false, + "internalType" : "uint256", + "name" : "reserve0", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "reserve1", + "type" : "uint256" + } + ], + "name" : "Sync", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "from", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "to", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "amount", + "type" : "uint256" + } + ], + "name" : "Transfer", + "type" : "event" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "allowance", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "spender", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amount", + "type" : "uint256" + } + ], + "name" : "approve", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "balanceOf", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "blockTimestampLast", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "to", + "type" : "address" + } + ], + "name" : "burn", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "amount0", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "amount1", + "type" : "uint256" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "claimFees", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "claimed0", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "claimed1", + "type" : "uint256" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "claimable0", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "claimable1", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "tokenIn", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amountIn", + "type" : "uint256" + } + ], + "name" : "current", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "amountOut", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "currentCumulativePrices", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "reserve0Cumulative", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "reserve1Cumulative", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "blockTimestamp", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "decimals", + "outputs" : [ + { + "internalType" : "uint8", + "name" : "", + "type" : "uint8" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "factory", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "fees", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "amountIn", + "type" : "uint256" + }, + { + "internalType" : "address", + "name" : "tokenIn", + "type" : "address" + } + ], + "name" : "getAmountOut", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "getReserves", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "_reserve0", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "_reserve1", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "_blockTimestampLast", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "index0", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "index1", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "initialize", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "lastObservation", + "outputs" : [ + { + "components" : [ + { + "internalType" : "uint256", + "name" : "timestamp", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "reserve0Cumulative", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "reserve1Cumulative", + "type" : "uint256" + } + ], + "internalType" : "struct Pair.Observation", + "name" : "", + "type" : "tuple" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "metadata", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "dec0", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "dec1", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "r0", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "r1", + "type" : "uint256" + }, + { + "internalType" : "bool", + "name" : "st", + "type" : "bool" + }, + { + "internalType" : "address", + "name" : "t0", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "t1", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "to", + "type" : "address" + } + ], + "name" : "mint", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "liquidity", + "type" : "uint256" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "name", + "outputs" : [ + { + "internalType" : "string", + "name" : "", + "type" : "string" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "nonces", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "observationLength", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "name" : "observations", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "timestamp", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "reserve0Cumulative", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "reserve1Cumulative", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "owner", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "spender", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "value", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "deadline", + "type" : "uint256" + }, + { + "internalType" : "uint8", + "name" : "v", + "type" : "uint8" + }, + { + "internalType" : "bytes32", + "name" : "r", + "type" : "bytes32" + }, + { + "internalType" : "bytes32", + "name" : "s", + "type" : "bytes32" + } + ], + "name" : "permit", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "tokenIn", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amountIn", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "points", + "type" : "uint256" + } + ], + "name" : "prices", + "outputs" : [ + { + "internalType" : "uint256[]", + "name" : "", + "type" : "uint256[]" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "tokenIn", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amountIn", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "granularity", + "type" : "uint256" + } + ], + "name" : "quote", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "amountOut", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "reserve0", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "reserve0CumulativeLast", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "reserve1", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "reserve1CumulativeLast", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "tokenIn", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amountIn", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "points", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "window", + "type" : "uint256" + } + ], + "name" : "sample", + "outputs" : [ + { + "internalType" : "uint256[]", + "name" : "", + "type" : "uint256[]" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "to", + "type" : "address" + } + ], + "name" : "skim", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "stable", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "supplyIndex0", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "supplyIndex1", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "amount0Out", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "amount1Out", + "type" : "uint256" + }, + { + "internalType" : "address", + "name" : "to", + "type" : "address" + }, + { + "internalType" : "bytes", + "name" : "data", + "type" : "bytes" + } + ], + "name" : "swap", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "symbol", + "outputs" : [ + { + "internalType" : "string", + "name" : "", + "type" : "string" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "sync", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "token0", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "token1", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "tokens", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "totalSupply", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "dst", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amount", + "type" : "uint256" + } + ], + "name" : "transfer", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "src", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "dst", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "amount", + "type" : "uint256" + } + ], + "name" : "transferFrom", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + } +] diff --git a/src/adaptors/glacier-exchange-v2/abiPairFactory.json b/src/adaptors/glacier-exchange-v2/abiPairFactory.json new file mode 100644 index 0000000000..f370fe8ba0 --- /dev/null +++ b/src/adaptors/glacier-exchange-v2/abiPairFactory.json @@ -0,0 +1,398 @@ +[ + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : false, + "internalType" : "uint8", + "name" : "version", + "type" : "uint8" + } + ], + "name" : "Initialized", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "token0", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "token1", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "bool", + "name" : "stable", + "type" : "bool" + }, + { + "indexed" : false, + "internalType" : "address", + "name" : "pair", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "name" : "PairCreated", + "type" : "event" + }, + { + "inputs" : [], + "name" : "MAX_FEE", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "acceptFeeManager", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "acceptPauser", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "name" : "allPairs", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "allPairsLength", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "tokenA", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "tokenB", + "type" : "address" + }, + { + "internalType" : "bool", + "name" : "stable", + "type" : "bool" + } + ], + "name" : "createPair", + "outputs" : [ + { + "internalType" : "address", + "name" : "pair", + "type" : "address" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "feeManager", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "bool", + "name" : "_stable", + "type" : "bool" + } + ], + "name" : "getFee", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "getInitializable", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "", + "type" : "address" + }, + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "name" : "getPair", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "initialize", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "name" : "isPair", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "isPaused", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "pairCodeHash", + "outputs" : [ + { + "internalType" : "bytes32", + "name" : "", + "type" : "bytes32" + } + ], + "stateMutability" : "pure", + "type" : "function" + }, + { + "inputs" : [], + "name" : "pauser", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "pendingFeeManager", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "pendingPauser", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "bool", + "name" : "_stable", + "type" : "bool" + }, + { + "internalType" : "uint256", + "name" : "_fee", + "type" : "uint256" + } + ], + "name" : "setFee", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_feeManager", + "type" : "address" + } + ], + "name" : "setFeeManager", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "bool", + "name" : "_state", + "type" : "bool" + } + ], + "name" : "setPause", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_pauser", + "type" : "address" + } + ], + "name" : "setPauser", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [], + "name" : "stableFee", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "volatileFee", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + } +] diff --git a/src/adaptors/glacier-exchange-v2/abiVoter.json b/src/adaptors/glacier-exchange-v2/abiVoter.json new file mode 100644 index 0000000000..745a10996c --- /dev/null +++ b/src/adaptors/glacier-exchange-v2/abiVoter.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Abstained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Attach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Detach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"address","name":"internal_bribe","type":"address"},{"indexed":true,"internalType":"address","name":"external_bribe","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"GaugeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeKilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeRevived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"attachTokenToGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribefactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bribes","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimBribes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_fees","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"createGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"detachTokenFromGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"finish","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distributeFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distro","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"external_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugefactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_minter","type":"address"}],"name":"initialSetup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_gauges","type":"address"},{"internalType":"address","name":"_bribes","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"internal_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAlive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"killGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastVoted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"poke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolForGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolVote","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"reset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"reviveGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_council","type":"address"}],"name":"setEmergencyCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"name":"setGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"updateFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"updateForRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedWeights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"_poolVote","type":"address[]"},{"internalType":"uint256[]","name":"_weights","type":"uint256[]"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/adaptors/glacier-exchange-v2/index.js b/src/adaptors/glacier-exchange-v2/index.js new file mode 100644 index 0000000000..54e2a6f4c2 --- /dev/null +++ b/src/adaptors/glacier-exchange-v2/index.js @@ -0,0 +1,141 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xaC7B7EaC8310170109301034b8FdB75eCa4CC491'; +const voter = '0x4199Cf7D3cd8F92BAFBB97fF66caE507888b01F9'; +const GLCR = '0x3712871408a829C5cd4e86DA1f4CE727eFCD28F6'; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: 'avax', + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'avax', + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [GLCR], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(GLCR) + ), + ]; + const priceKeys = tokens.map((i) => `avax:${i}`).join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + const re0 = r0 || 0; + const re1 = r1 || 0; + + const p0 = prices[`avax:${poolMeta.t0}`]?.price; + const p1 = prices[`avax:${poolMeta.t1}`]?.price; + + const price0 = p0 || 0; + const price1 = p1 || 0; + + const tvlUsd = + price0 === 0 && price1 === 0 + ? 0 + : price0 === 0 + ? re1 * price1 * 2 + : price1 === 0 + ? re0 * price0 * 2 + : re0 * price0 + re1 * price1; + + const s = symbols[i]; + + const rewardPerSec = (rewardRate[i] / 1e18) * prices[`avax:${GLCR}`]?.price; + const apyReward = ((rewardPerSec * 86400 * 365) / tvlUsd) * 100; + + return { + pool: p, + chain: utils.formatChain('avax'), + project: 'glacier-exchange-v2', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [GLCR] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://glacier.exchange/liquidity', +}; diff --git a/src/adaptors/glif/index.js b/src/adaptors/glif/index.js new file mode 100644 index 0000000000..6d5768c21a --- /dev/null +++ b/src/adaptors/glif/index.js @@ -0,0 +1,142 @@ +const axios = require('axios'); +const { ethers } = require('ethers'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const fetchApy = async () => { + const [filPool, icntPool] = await Promise.all([ + getFilecoinPool(), + getICNTPool(), + ]); + + return [filPool, icntPool]; +}; + +const getFilecoinPool = async () => { + const { data: apyData } = await axios.get( + 'https://events.glif.link/pool/apy' + ); + + const { data: metricsData } = await axios.get( + 'https://events.glif.link/metrics' + ); + + // div out the wad of 18 decimals + let tvlFIL = metricsData.totalValueLocked / 10 ** 18; + + // <- Filecoin -> + const filPriceKey = `coingecko:filecoin`; + const filPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${filPriceKey}`) + ).data.coins[filPriceKey]?.price; + + return { + pool: '0xe764Acf02D8B7c21d2B6A8f0a96C78541e0DC3fd-filecoin', + chain: utils.formatChain('filecoin'), + project: 'glif', + symbol: utils.formatSymbol('IFIL'), + tvlUsd: tvlFIL * filPrice, + apy: Number(apyData.apy), + poolMeta: 'GLIF', + }; +}; + +const getICNTPool = async () => { + const icntPool = { + pool: '0xAeD7C2eD7Bb84396AfCB55fF72c8F8E87FFb68f3-base', + chain: utils.formatChain('base'), + project: 'glif', + symbol: utils.formatSymbol('stICNT'), + tvlUsd: 0, + apy: 0, + poolMeta: 'GLIF', + }; + + try { + // Periphery contract address + const peripheryAddress = '0x3a24CFF2F5c9af8e77775418A115214e171112B8'; + + // ABI for the apy() and tvl() methods + const peripheryABI = [ + { + inputs: [], + name: 'apy', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'tvl', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + + // Call both apy() and tvl() methods using DefiLlama SDK with timeout + const [apyRaw, tvlRaw] = await Promise.allSettled([ + sdk.api.abi.call({ + target: peripheryAddress, + abi: peripheryABI.find((abi) => abi.name === 'apy'), + chain: 'base', + }), + sdk.api.abi.call({ + target: peripheryAddress, + abi: peripheryABI.find((abi) => abi.name === 'tvl'), + chain: 'base', + }), + ]); + + // Handle APY result + if (apyRaw.status === 'fulfilled' && apyRaw.value?.output) { + icntPool.apy = + Number(ethers.utils.formatUnits(apyRaw.value.output, 18)) * 100; + } + + // Handle TVL result + let tvlRawNumber = 0; + if (tvlRaw.status === 'fulfilled' && tvlRaw.value?.output) { + tvlRawNumber = Number(ethers.utils.formatUnits(tvlRaw.value.output, 18)); + } + + // Try to get ICNT price with timeout + try { + const icntPriceKey = `coingecko:impossible-cloud-network-token`; + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${icntPriceKey}`, + { + timeout: 10000, // 10 second timeout + } + ); + const icntPrice = priceResponse.data.coins[icntPriceKey]?.price || 0; + icntPool.tvlUsd = tvlRawNumber * icntPrice; + } catch (priceError) { + console.error('Error fetching ICNT price:', priceError.message); + icntPool.tvlUsd = 0; + } + + return icntPool; + } catch (error) { + console.error('Error fetching ICNT pool data:', error.message); + return icntPool; + } +}; + +module.exports = { + timetravel: false, + apy: fetchApy, + url: 'https://www.glif.io', +}; diff --git a/src/adaptors/gloop/Constants.js b/src/adaptors/gloop/Constants.js new file mode 100644 index 0000000000..6e061ecb1d --- /dev/null +++ b/src/adaptors/gloop/Constants.js @@ -0,0 +1,15 @@ +module.exports = { + ADDRESSES: { + USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', + GLOOP: '0x4d48d503ed04d50418C9aBF163b1168FF834E47c', + GMI: '0xAad4187a81689AF72d91966c8119756E425cD7CF', + RECEIVED_TOKEN: '0xFe81b0866a8fBBd7c00f5AaB84E4e531eA7591c2', // USDC receipt token + LENDING_POOL: '0x9BE2e5739B1a6A175d36Ce043f44E66965a433EB', + ORACLE: '0x277e3531d2b697E572E8b4Aa363571836ecA55be', + GM_INCENTIVES: '0x5B28fde611Ed40FFf4d933971fdF975dC6191f9f', + INTEREST_RATE_MODEL: '0x991c54E99a4612d90AA21d675C89a1752Da7c233', + GLOOP_GMI_V3_POOL: '0x84ef1190ba2be3fadded470642520b7f8948aded', + }, + CHAIN: 'arbitrum', + SECONDS_PER_YEAR: 31557600, // 365.25 * 24 * 60 * 60, +}; diff --git a/src/adaptors/gloop/abi/abiGMI.json b/src/adaptors/gloop/abi/abiGMI.json new file mode 100644 index 0000000000..5a38f6676e --- /dev/null +++ b/src/adaptors/gloop/abi/abiGMI.json @@ -0,0 +1,1261 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_protocolFeeRecipient", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "EnforcedPause", + "type": "error" + }, + { + "inputs": [], + "name": "ExpectedPause", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "FeeUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "NewFeeRecipient", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "NewProtocolFeeRatio", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "oracle", + "type": "address" + } + ], + "name": "OracleUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "TokenRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "TreasuryTokenRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + } + ], + "name": "TreasuryVaultRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "UpdateTokenWeight", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "UpdateVaultWeight", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + }, + { + "internalType": "contract ITokenOracle", + "name": "oracle", + "type": "address" + }, + { + "internalType": "contract IBank", + "name": "bank", + "type": "address" + } + ], + "name": "addToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + } + ], + "name": "bankBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isWithdraw", + "type": "bool" + } + ], + "name": "calculateFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "controlledValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmountOut", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeBase", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + } + ], + "name": "getTargetAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeRecipient", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "recoverUnsupported", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + } + ], + "name": "removeTreasuryVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_feeBase", + "type": "uint256" + } + ], + "name": "setFeeBase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minFee", + "type": "uint256" + } + ], + "name": "setMinFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_taxBase", + "type": "uint256" + } + ], + "name": "setTaxBase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "setTokenWeight", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "withdrawal", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tokenValue", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "targetBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taxBase", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "totalControlledValue", + "outputs": [ + { + "internalType": "uint256", + "name": "totalValue", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalTokenWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "treasuryVaults", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_protocolFeeRecipient", + "type": "address" + } + ], + "name": "updateFeeRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "contract ITokenOracle", + "name": "oracle", + "type": "address" + } + ], + "name": "updateOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolFeeRatio", + "type": "uint256" + } + ], + "name": "updateProtocolFeeRatio", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "vaults", + "outputs": [ + { + "internalType": "contract IBank", + "name": "bank", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "contract ITokenOracle", + "name": "oracle", + "type": "address" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "name", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minAmountOut", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/abi/abiGMIncentives.json b/src/adaptors/gloop/abi/abiGMIncentives.json new file mode 100644 index 0000000000..fb050e688d --- /dev/null +++ b/src/adaptors/gloop/abi/abiGMIncentives.json @@ -0,0 +1,656 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_usdcVault", + "type": "address", + "internalType": "address" + }, + { + "name": "_rewardsVault", + "type": "address", + "internalType": "address" + }, + { + "name": "_lendingPool", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewards", + "inputs": [], + "outputs": [ + { + "name": "rewardsList", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "claimedAmounts", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "configureReward", + "inputs": [ + { + "name": "rewardsInput", + "type": "tuple", + "internalType": "struct RewardsDataTypes.RewardsConfigInput", + "components": [ + { + "name": "rewardToken", + "type": "address", + "internalType": "address" + }, + { + "name": "emissionsPerSecond", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "distributionEnd", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getAllUserRewards", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "rewardsList", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "unclaimedAmounts", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "pendingAmounts", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRewardsData", + "inputs": [ + { + "name": "reward", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRewardsList", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address[]", + "internalType": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserAccruedRewards", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "reward", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserRewardIndex", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "reward", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserUSDCBalance", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getVaults", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lendingPool", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract LendingPool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pause", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "paused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "relayVaultAction", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "assetAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "isDeposit", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "removeReward", + "inputs": [ + { + "name": "rewardToRemove", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rewardsVault", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setVaults", + "inputs": [ + { + "name": "_usdcVault", + "type": "address", + "internalType": "address" + }, + { + "name": "_rewardsVault", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "unpause", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "usdcToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ERC20" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "usdcVault", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IGMVault" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Accrued", + "inputs": [ + { + "name": "reward", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "assetIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "userIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "rewardsAccrued", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "name": "account", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RewardConfigUpdated", + "inputs": [ + { + "name": "reward", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "oldEmission", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newEmission", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldDistributionEnd", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newDistributionEnd", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "oldTotalSupply", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "rewardIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RewardRemoved", + "inputs": [ + { + "name": "reward", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RewardsClaimed", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "rewards", + "type": "address[]", + "indexed": true, + "internalType": "address[]" + }, + { + "name": "amount", + "type": "uint256[]", + "indexed": true, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Unpaused", + "inputs": [ + { + "name": "account", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "EmissionsAreActive", + "inputs": [] + }, + { + "type": "error", + "name": "EnforcedPause", + "inputs": [] + }, + { + "type": "error", + "name": "ExpectedPause", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInputs", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidToken", + "inputs": [] + }, + { + "type": "error", + "name": "NoRewardsToClaim", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyVaultCanCall", + "inputs": [] + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/abi/abiInterestRateModel.json b/src/adaptors/gloop/abi/abiInterestRateModel.json new file mode 100644 index 0000000000..d00e119922 --- /dev/null +++ b/src/adaptors/gloop/abi/abiInterestRateModel.json @@ -0,0 +1,139 @@ +[ + { + "inputs": [], + "name": "vertexUtilization", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blocksInOneYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vertexRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + } + ], + "name": "getCurrentBorrowAPY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/abi/abiLendingPool.json b/src/adaptors/gloop/abi/abiLendingPool.json new file mode 100644 index 0000000000..4e48527399 --- /dev/null +++ b/src/adaptors/gloop/abi/abiLendingPool.json @@ -0,0 +1,1622 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_authority", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BonusMustBeBelowTenPercent", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "liquidationsRestoredTime", + "type": "uint256" + } + ], + "name": "LiquidationsDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract AddressStore", + "name": "newAddressStore", + "type": "address" + } + ], + "name": "AddressStoreUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC4626", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "lendFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LendingPool.Configuration", + "name": "newConfiguration", + "type": "tuple" + } + ], + "name": "AssetConfigurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC4626", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "lendFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LendingPool.Configuration", + "name": "configuration", + "type": "tuple" + } + ], + "name": "AssetConfigured", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "AssetDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "AssetEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newGMPointsContract", + "type": "address" + } + ], + "name": "GMPointsContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newWallet", + "type": "address" + } + ], + "name": "GloopStakersWalletUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newGloopStakersYieldRatio", + "type": "uint256" + } + ], + "name": "GloopStakersYieldUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "InterestRateModelUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidated", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizedValue", + "type": "uint256" + } + ], + "name": "Liquidation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationBonus", + "type": "uint256" + } + ], + "name": "LiquidationBonusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidated", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "LiquidationOfBadDebt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newGMToken", + "type": "address" + } + ], + "name": "NewGMToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "newGMTokens", + "type": "address[]" + } + ], + "name": "NewGMTokenArray", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "OracleUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactor", + "type": "uint256" + } + ], + "name": "ReserveFactorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_GM_TOKENS_SUPPORTED", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LIQUIDATION_BONUS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newGMToken", + "type": "address" + } + ], + "name": "addNewGMToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "addressStore", + "outputs": [ + { + "internalType": "contract AddressStore", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "availableLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "baseUnits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "borrowBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "collIncrease", + "type": "bool" + } + ], + "name": "calculateHFAfterCollChange", + "outputs": [ + { + "internalType": "uint256", + "name": "hypotheticalHF", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "calculateHealthFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "configurations", + "outputs": [ + { + "internalType": "uint256", + "name": "lendFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "contract ERC4626", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "lendFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + } + ], + "internalType": "struct LendingPool.Configuration", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "updateVault", + "type": "bool" + } + ], + "name": "configureAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "disableAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "enableAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "enabledCollateral", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getCollateral", + "outputs": [ + { + "internalType": "contract ERC20[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getEffectiveUSDCBalanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getInternalCachedTotalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "getUserCollateralValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gloopStakersWallet", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gloopStakersYield", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gloopStakersYieldFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gmPointsContract", + "outputs": [ + { + "internalType": "contract GMPoints", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "gmTokensAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "interestRateModels", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "isValidGMToken", + "outputs": [ + { + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "borrowAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateUser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationBonus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "maxBorrowableValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AddressStore", + "name": "newAddressStore", + "type": "address" + } + ], + "name": "setAddressStore", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPointsAddress", + "type": "address" + } + ], + "name": "setGMPointsContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "newGMTokensAddress", + "type": "address[]" + } + ], + "name": "setGMTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newWallet", + "type": "address" + } + ], + "name": "setGloopStakersWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newGSYFactor", + "type": "uint256" + } + ], + "name": "setGloopStakersYieldFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + }, + { + "internalType": "bool", + "name": "accrue", + "type": "bool" + } + ], + "name": "setInterestRateModel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "totalUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newLiquidationBonus", + "type": "uint256" + } + ], + "name": "updateLiquidationBonus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactor", + "type": "uint256" + } + ], + "name": "updateReserveFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdcTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userCollateral", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "willBePaused", + "type": "bool" + } + ], + "name": "vaultPauseInterestAccrual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "vaults", + "outputs": [ + { + "internalType": "contract ERC4626", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawStakersYield", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/abi/abiOracle.json b/src/adaptors/gloop/abi/abiOracle.json new file mode 100644 index 0000000000..055eef103e --- /dev/null +++ b/src/adaptors/gloop/abi/abiOracle.json @@ -0,0 +1,196 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_authorityContract", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "GracePeriodNotOver", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAsset", + "type": "error" + }, + { + "inputs": [], + "name": "SequencerIsDown", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + } + ], + "name": "StalePriceFeed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sequencerFeed", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "usdcFeed", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "usdcFeedHeartbeat", + "type": "uint256" + } + ], + "name": "OracleFeedsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sequencerUptimeFeed", + "type": "address" + }, + { + "internalType": "address", + "name": "_usdcPriceFeed", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdcFeedHeartbeat", + "type": "uint256" + } + ], + "name": "updateChainlinkFeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/abi/abiUniswapV3Pool.json b/src/adaptors/gloop/abi/abiUniswapV3Pool.json new file mode 100644 index 0000000000..49cc338ed3 --- /dev/null +++ b/src/adaptors/gloop/abi/abiUniswapV3Pool.json @@ -0,0 +1,988 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gloop/getGMIPrice.js b/src/adaptors/gloop/getGMIPrice.js new file mode 100644 index 0000000000..468c011142 --- /dev/null +++ b/src/adaptors/gloop/getGMIPrice.js @@ -0,0 +1,54 @@ +const abiGMI = require('./abi/abiGMI.json'); + +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const {ADDRESSES, CHAIN} = require('./Constants'); + +/** + * Gets GMI price in USD from GMI token contract + * Formula: GMI price = totalControlledValue / totalSupply + */ +const getGMIPrice = async () => { + try { + // Get total supply of GMI tokens + const totalSupplyResult = await sdk.api.abi.call({ + target: ADDRESSES.GMI, + abi: abiGMI.find((m) => m.name === 'totalSupply'), + chain: CHAIN, + }); + + // Get total controlled value (in USD, with 18 decimals) + const totalControlledValueResult = await sdk.api.abi.call({ + target: ADDRESSES.GMI, + abi: abiGMI.find((m) => m.name === 'totalControlledValue'), + params: [false], // roundUp = false + chain: CHAIN, + }); + + const totalSupply = new BigNumber(totalSupplyResult.output); + const totalControlledValue = new BigNumber( + totalControlledValueResult.output + ); + + if (totalSupply.isZero()) { + console.warn('GMI total supply is zero'); + return 0; + } + + // GMI price = (totalControlledValue * 100000) / totalSupply / 100000 + // This matches the frontend calculation + const gmiPrice = totalControlledValue + .multipliedBy(100000) + .dividedBy(totalSupply) + .dividedBy(100000); + + return gmiPrice.toNumber(); + } catch (error) { + console.error('Error fetching GMI price:', error); + return 0; + } +}; + +module.exports = { + getGMIPrice, +}; diff --git a/src/adaptors/gloop/getGloopPrice.js b/src/adaptors/gloop/getGloopPrice.js new file mode 100644 index 0000000000..cd4e2f7c5f --- /dev/null +++ b/src/adaptors/gloop/getGloopPrice.js @@ -0,0 +1,82 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const abiUniswapV3Pool = require('./abi/abiUniswapV3Pool.json'); + +const {getGMIPrice} = require('./getGMIPrice'); + +const {ADDRESSES, CHAIN} = require('./Constants'); +/** + * Fetches the GLOOP token price using Uniswap V3 pool and GMI contract + * Route: GLOOP -> GMI (from V3 pool) -> USD (from GMI contract) + */ +const getGloopPrice = async () => { + try { + // Not listed on DefiLlama so this approach not used + // const priceKey = `${CHAIN}:${ADDRESSES.GLOOP}`; + // const priceData = await axios.get( + // `https://coins.llama.fi/prices/current/${priceKey}` + // ); + + // if (priceData.data?.coins?.[priceKey]?.price) { + // console.log('Using GLOOP price from DeFiLlama:', priceData.data.coins[priceKey].price); + // return priceData.data.coins[priceKey].price; + // } + + // Step 1: Get GMI price in USD from GMI contract + const gmiPriceInUSD = await getGMIPrice(); + + if (!gmiPriceInUSD || gmiPriceInUSD <= 0) { + console.warn('GMI price not available'); + return 0; + } + + console.log('GMI price in USD:', gmiPriceInUSD); + + // Step 2: Get GLOOP/GMI price from Uniswap V3 pool + const slot0Result = await sdk.api.abi.call({ + target: ADDRESSES.GLOOP_GMI_V3_POOL, + abi: abiUniswapV3Pool.find((m) => m.name === 'slot0'), + chain: CHAIN, + }); + + if (!slot0Result.output || !Array.isArray(slot0Result.output)) { + console.warn('Unable to fetch slot0 from GLOOP/GMI V3 pool'); + return 0; + } + + const sqrtPriceX96 = new BigNumber(slot0Result.output[0].toString()); + + if (sqrtPriceX96.isZero()) { + console.warn('Invalid sqrtPriceX96 (zero) from GLOOP/GMI V3 pool'); + return 0; + } + + // Convert sqrtPriceX96 to price + // price = (sqrtPriceX96 / 2^96)^2 + const twoPow96 = new BigNumber(2).pow(96); + const sqrtPrice = sqrtPriceX96.dividedBy(twoPow96); + const gloopGmiPrice = sqrtPrice.pow(2); + + console.log('GLOOP/GMI price from V3 pool:', gloopGmiPrice.toString()); + + // Step 3: Calculate GLOOP price in USD + // GLOOP/USD = GLOOP/GMI * GMI/USD + const gloopUsdPrice = gloopGmiPrice.multipliedBy(gmiPriceInUSD); + + console.log('Calculated GLOOP/USD price:', gloopUsdPrice.toNumber()); + + return gloopUsdPrice.toNumber(); + } catch (error) { + console.error('Error fetching GLOOP price:', error); + return 0; + } +}; + +module.exports = { + getGloopPrice, +}; + + +getGloopPrice(); \ No newline at end of file diff --git a/src/adaptors/gloop/getRewardAPY.js b/src/adaptors/gloop/getRewardAPY.js new file mode 100644 index 0000000000..61f41ef3db --- /dev/null +++ b/src/adaptors/gloop/getRewardAPY.js @@ -0,0 +1,68 @@ +const sdk = require('@defillama/sdk'); + +const abiGMIncentives = require('./abi/abiGMIncentives.json'); +const {ADDRESSES, CHAIN, SECONDS_PER_YEAR} = require('./Constants'); + +/** + * Calculates the reward APY from GLOOP emissions + */ +const getRewardAPY = async (gloopPrice, totalLendingPoolUSDCValue) => { + try { + if (!gloopPrice || gloopPrice <= 0) { + return 0; + } + + if (!totalLendingPoolUSDCValue || totalLendingPoolUSDCValue <= 0) { + return 0; + } + + // Get GLOOP rewards data + const rewardsDataResult = await sdk.api.abi.call({ + target: ADDRESSES.GM_INCENTIVES, + abi: abiGMIncentives.find((m) => m.name === 'getRewardsData'), + params: [ADDRESSES.GLOOP], + chain: CHAIN, + }); + + const rewardsData = rewardsDataResult.output; + + if (!rewardsData || !Array.isArray(rewardsData) || rewardsData.length < 3) { + return 0; + } + + // Check if reward distribution has ended + // rewardsData[2] is distributionEnd timestamp + const distributionEnd = BigInt(rewardsData[2]); + const currentTimestamp = BigInt(Math.floor(Date.now() / 1000)); + + if (currentTimestamp > distributionEnd) { + // Reward distribution has ended + return 0; + } + + // Get emissions per second (rewardsData[1]) + const emissionsPerSecond = BigInt(rewardsData[1]); + + if (emissionsPerSecond === 0n) { + return 0; + } + + // Convert emissions from 18 decimals to decimal + const emissionsPerSecondDecimal = Number(emissionsPerSecond) / 1e18; + + // Formula: Reward APY = ((GLOOP Emissions Rate * Seconds per year * GLOOP Token Price) / total USDC lent) * 100% + const annualRewardValue = + emissionsPerSecondDecimal * SECONDS_PER_YEAR * gloopPrice; + const aprDecimal = annualRewardValue / totalLendingPoolUSDCValue; + const aprPercentage = aprDecimal * 100; + + return aprPercentage; + } catch (error) { + console.error('Error calculating reward APY:', error); + return 0; + } +}; + +module.exports = { + getRewardAPY, +}; diff --git a/src/adaptors/gloop/getSupplyAPY.js b/src/adaptors/gloop/getSupplyAPY.js new file mode 100644 index 0000000000..0f928e525d --- /dev/null +++ b/src/adaptors/gloop/getSupplyAPY.js @@ -0,0 +1,67 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); + +const abiInterestRateModel = require('./abi/abiInterestRateModel.json'); +const abiLendingPool = require('./abi/abiLendingPool.json'); + +const {ADDRESSES, CHAIN, SECONDS_PER_YEAR} = require('./Constants'); + +/** + * + * Calculates the supply APY for USDC lending + */ +const getSupplyAPY = async (availableLiquidity, totalBorrows) => { + try { + // Get raw borrow rate from interest rate model + const rawBorrowRateResult = await sdk.api.abi.call({ + target: ADDRESSES.INTEREST_RATE_MODEL, + abi: abiInterestRateModel.find((m) => m.name === 'getBorrowRate'), + params: [availableLiquidity, totalBorrows], + chain: CHAIN, + }); + + const rawBorrowRate = BigInt(rawBorrowRateResult.output); + + // Get reserve factor and gloop stakers yield factor + const [reserveFactorResult, gloopStakersYieldFactorResult] = + await Promise.all([ + sdk.api.abi.call({ + target: ADDRESSES.LENDING_POOL, + abi: abiLendingPool.find((m) => m.name === 'reserveFactor'), + chain: CHAIN, + }), + sdk.api.abi.call({ + target: ADDRESSES.LENDING_POOL, + abi: abiLendingPool.find((m) => m.name === 'gloopStakersYieldFactor'), + chain: CHAIN, + }), + ]); + + const reserveFactor = BigInt(reserveFactorResult.output); + const gloopStakersYieldFactor = BigInt( + gloopStakersYieldFactorResult.output + ); + const oneE18 = BigInt('1000000000000000000'); // 1e18 + + // Calculate the multiplier: 1 - (gloopStakersYieldFactor + reserveFactor) / 1e18 + const reductionFactor = gloopStakersYieldFactor + reserveFactor; + const multiplierNumerator = oneE18 - reductionFactor; + + // Calculate raw supply rate: rawBorrowRate * multiplier + const rawSupplyRate = (rawBorrowRate * multiplierNumerator) / oneE18; + + // Convert to APY percentage + // APY = (rawSupplyRate * secondsPerYear / 1e18) * 100 + const supplyApyBigInt = + (rawSupplyRate * BigInt(SECONDS_PER_YEAR) * BigInt(100)) / oneE18; + + return Number(supplyApyBigInt) / 100; // Convert back to decimal percentage + } catch (error) { + console.error('Error calculating supply APY:', error); + return 0; + } +}; + +module.exports = { + getSupplyAPY, +}; diff --git a/src/adaptors/gloop/index.js b/src/adaptors/gloop/index.js new file mode 100644 index 0000000000..8b10817df3 --- /dev/null +++ b/src/adaptors/gloop/index.js @@ -0,0 +1,128 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); + +const abiLendingPool = require('./abi/abiLendingPool.json'); +const abiOracle = require('./abi/abiOracle.json'); +const abiGMIncentives = require('./abi/abiGMIncentives.json'); +const abiInterestRateModel = require('./abi/abiInterestRateModel.json'); +const abiUniswapV3Pool = require('./abi/abiUniswapV3Pool.json'); +const abiGMI = require('./abi/abiGMI.json'); + +const { getGloopPrice } = require('./getGloopPrice'); +const { getSupplyAPY } = require('./getSupplyAPY'); +const { getRewardAPY } = require('./getRewardAPY'); + +// Contract addresses on Arbitrum +const {ADDRESSES, CHAIN} = require('./Constants'); + +/** + * Main function to fetch pool data + */ +const apy = async () => { + try { + // Fetch total underlying USDC in the lending pool + const totalUnderlyingResult = await sdk.api.abi.call({ + target: ADDRESSES.LENDING_POOL, + abi: abiLendingPool.find((m) => m.name === 'totalUnderlying'), + params: [ADDRESSES.USDC], + chain: CHAIN, + }); + + const totalUnderlying = BigInt(totalUnderlyingResult.output); + + // Fetch total borrows + const totalBorrowsResult = await sdk.api.abi.call({ + target: ADDRESSES.LENDING_POOL, + abi: abiLendingPool.find((m) => m.name === 'totalBorrows'), + params: [ADDRESSES.USDC], + chain: CHAIN, + }); + + const totalBorrows = BigInt(totalBorrowsResult.output); + + // Fetch available liquidity + const availableLiquidityResult = await sdk.api.abi.call({ + target: ADDRESSES.LENDING_POOL, + abi: abiLendingPool.find((m) => m.name === 'availableLiquidity'), + params: [ADDRESSES.USDC], + chain: CHAIN, + }); + + const availableLiquidity = BigInt(availableLiquidityResult.output); + + // Get USDC price (should be ~$1, but fetch from oracle to be accurate) + const usdcPriceResult = await sdk.api.abi.call({ + target: ADDRESSES.ORACLE, + abi: abiOracle.find((m) => m.name === 'getUnderlyingPrice'), + params: [ADDRESSES.USDC], + chain: CHAIN, + }); + + // Oracle returns price in 1e18 format, convert to decimal + const usdcPrice = Number(BigInt(usdcPriceResult.output)) / 1e18; + + // Calculate TVL in USD + // For lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + // totalSupplyUsd = totalUnderlying * price + // totalBorrowUsd = totalBorrows * price + const totalUnderlyingDecimal = Number(totalUnderlying) / 1e6; // USDC has 6 decimals + const totalBorrowsDecimal = Number(totalBorrows) / 1e6; + + const totalSupplyUsd = totalUnderlyingDecimal * usdcPrice; + const totalBorrowUsd = totalBorrowsDecimal * usdcPrice; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + // Get GLOOP price + const gloopPrice = await getGloopPrice(); + + // Calculate supply APY + const apyBase = await getSupplyAPY( + availableLiquidity.toString(), + totalBorrows.toString() + ); + + // Calculate reward APY + const apyReward = await getRewardAPY(gloopPrice, totalUnderlyingDecimal); + + // Create pool identifier + const poolIdentifier = `${ADDRESSES.RECEIVED_TOKEN}-${CHAIN}`.toLowerCase(); + + const pool = { + pool: poolIdentifier, + chain: utils.formatChain(CHAIN), + project: 'gloop', + symbol: 'USDC', + tvlUsd: tvlUsd, + apyBase: apyBase * 100, + apyReward: apyReward > 0 ? apyReward * 100 : null, + rewardTokens: apyReward > 0 ? [ADDRESSES.GLOOP] : null, + underlyingTokens: [ADDRESSES.USDC], + poolMeta: 'V1 market', + url: 'https://gloop.finance/', + // Lending protocol specific fields + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + }; + + return [pool]; + } catch (error) { + console.error('Error in Gloop adapter:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.gloop.finance/loop', +}; + +// async function main() { +// console.log(await apy()); +// } + +// main() diff --git a/src/adaptors/glyph-v2/index.js b/src/adaptors/glyph-v2/index.js new file mode 100644 index 0000000000..9fa16498cf --- /dev/null +++ b/src/adaptors/glyph-v2/index.js @@ -0,0 +1,143 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); +const utils = require('../utils'); + +const SUBGRAPH_URL = "https://thegraph.coredao.org/subgraphs/name/glyph/glyph-exchange-v2"; +const liquidityPairFeeRate = 0.003; +const WCORE_TOKEN_ADDRESS = '0x191e94fa59739e188dce837f7f6978d84727ad01'; +const NATIVE_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000'; +const USDT_ADDRESS = '0x81ecac0d6be0550a00ff064a4f9dd2400585fe9c'; + +const PAIR_VOLUME_DAYS_QUERY = gql` + query PairVolumeDays($first: Int!, $skip: Int!, $timestamp_gte: BigInt!) { + pairVolumeDays( + first: $first + skip: $skip + where: { timestamp_gte: $timestamp_gte } + ) { + volumeUsd + pair { id } + } + } +`; + +const PAIRS_QUERY = gql` + query Pairs($first: Int!) { + pairs(first: $first) { + id + reserve0 + reserve1 + token0 { id symbol decimals derivedCORE } + token1 { id symbol decimals derivedCORE } + supply + totalVolumeUsd + token0Price + token1Price + } + } +`; + +const getAllPairVolumeDays = async (timestamp_gte) => { + const volumeDays = []; + let skip = 0; + const first = 1000; + + while (true) { + const result = await request(SUBGRAPH_URL, PAIR_VOLUME_DAYS_QUERY, { + first, + skip, + timestamp_gte + }); + + volumeDays.push(...result.pairVolumeDays); + if (result.pairVolumeDays.length < first) break; + skip += first; + } + + return volumeDays; +}; + +const getWcoreUsdtPrice = async () => { + const response = await axios.get(`https://coins.llama.fi/prices/current/core:${NATIVE_TOKEN_ADDRESS}`); + return response.data.coins[`core:${NATIVE_TOKEN_ADDRESS}`]?.price || 0; +}; + +const calculateTVL = async (pairs) => { + const tokenPrices = {}; + tokenPrices[USDT_ADDRESS] = 1; + tokenPrices[WCORE_TOKEN_ADDRESS] = await getWcoreUsdtPrice(); + + return pairs.map(pair => { + const reserve0 = Number(pair.reserve0); + const reserve1 = Number(pair.reserve1); + + let token0Price = tokenPrices[pair.token0.id]; + let token1Price = tokenPrices[pair.token1.id]; + + if (!token0Price && pair.token0.derivedCORE && tokenPrices[WCORE_TOKEN_ADDRESS]) { + token0Price = Number(pair.token0.derivedCORE) * tokenPrices[WCORE_TOKEN_ADDRESS]; + tokenPrices[pair.token0.id] = token0Price; + } + + if (!token1Price && pair.token1.derivedCORE && tokenPrices[WCORE_TOKEN_ADDRESS]) { + token1Price = Number(pair.token1.derivedCORE) * tokenPrices[WCORE_TOKEN_ADDRESS]; + tokenPrices[pair.token1.id] = token1Price; + } + + const reserve0USD = reserve0 * (token0Price || 0); + const reserve1USD = reserve1 * (token1Price || 0); + + let tvlUsd; + if (token0Price && token1Price) { + tvlUsd = reserve0USD + reserve1USD; + } else if (token0Price) { + tvlUsd = reserve0USD * 2; + } else if (token1Price) { + tvlUsd = reserve1USD * 2; + } else { + tvlUsd = 0; + } + + return { + ...pair, + tvlUsd, + token0Price, + token1Price + }; + }); +}; + +const main = async () => { + const chain = 'core'; + const currentTimestamp = Math.floor(Date.now() / 1000); + const yearAgoTimestamp = currentTimestamp - 365 * 24 * 60 * 60; + + const { pairs } = await request(SUBGRAPH_URL, PAIRS_QUERY, { first: 1000 }); + const pairsWithTVL = await calculateTVL(pairs); + + const allVolumeDays = await getAllPairVolumeDays(yearAgoTimestamp); + const volumeByPair = allVolumeDays.reduce((acc, day) => { + acc[day.pair.id] = (acc[day.pair.id] || 0) + Number(day.volumeUsd); + return acc; + }, {}); + + return pairsWithTVL.map(pair => ({ + pool: `${pair.id}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'glyph-v2', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: pair.tvlUsd, + apyBase: pair.tvlUsd > 0 ? + (volumeByPair[pair.id] || 0) * liquidityPairFeeRate / pair.tvlUsd * 100 : 0, + underlyingTokens: [pair.token0.id, pair.token1.id], + url: `https://app.glyph.exchange/pool/?type=v2&address=${pair.id}`, + })) + .filter(p => p.tvlUsd >= 10000) + .filter(p => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; \ No newline at end of file diff --git a/src/adaptors/glyph/abiLendingPool.js b/src/adaptors/glyph/abiLendingPool.js new file mode 100644 index 0000000000..ddf300738e --- /dev/null +++ b/src/adaptors/glyph/abiLendingPool.js @@ -0,0 +1,692 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/glyph/abiProtocolDataProvider.js b/src/adaptors/glyph/abiProtocolDataProvider.js new file mode 100644 index 0000000000..1c698fcae2 --- /dev/null +++ b/src/adaptors/glyph/abiProtocolDataProvider.js @@ -0,0 +1,148 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/glyph/index.js b/src/adaptors/glyph/index.js new file mode 100644 index 0000000000..9193905c0c --- /dev/null +++ b/src/adaptors/glyph/index.js @@ -0,0 +1,138 @@ +const ethers = require('ethers'); +const { JsonRpcProvider } = require('ethers'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); + +const utils = require('../utils'); + +const chains = { + fraxtal: { + LendingPool: '0xc1c5312BCAA6cb2ada949553AF75802fe48d5228', + ProtocolDataProvider: '0xE767cD4871C5749e59451CAEbc3f1062EaF40958', + url: 'fraxtal', + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const poolSymbol = symbols[i].toLowerCase() + const url = `https://glyph.fi/markets/${poolSymbol}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'glyph', + chain, + tvlUsd, + apyBase, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; \ No newline at end of file diff --git a/src/adaptors/gmd-protocol/abis/ERC20ABI.json b/src/adaptors/gmd-protocol/abis/ERC20ABI.json new file mode 100644 index 0000000000..405d6b3648 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/ERC20ABI.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] diff --git a/src/adaptors/gmd-protocol/abis/GMDStakingABI.json b/src/adaptors/gmd-protocol/abis/GMDStakingABI.json new file mode 100644 index 0000000000..a3ae474030 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/GMDStakingABI.json @@ -0,0 +1,531 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_WETHPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MaxAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETHPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "closeWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devaddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxWETHPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "openWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingWETH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accWETHPerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_WETHPerSecond", + "type": "uint256" + } + ], + "name": "setWETHPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "supplyRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWETHdistributed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/gmd-protocol/abis/IUniswapV3Pool.json b/src/adaptors/gmd-protocol/abis/IUniswapV3Pool.json new file mode 100644 index 0000000000..402dc3d344 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/IUniswapV3Pool.json @@ -0,0 +1,983 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/gmd-protocol/abis/MintABI.json b/src/adaptors/gmd-protocol/abis/MintABI.json new file mode 100644 index 0000000000..3099ac11fe --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/MintABI.json @@ -0,0 +1,338 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "USDC", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claim2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "claimableTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintCap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintOpen", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "recoverTreasuryTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "remainingMintableTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_mintCap", "type": "uint256" } + ], + "name": "setMintCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_mintPrice", "type": "uint256" } + ], + "name": "setMintPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_mintOpen", "type": "bool" }], + "name": "setOpenMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_period", "type": "uint256" } + ], + "name": "setVestingPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userInfo", + "outputs": [ + { "internalType": "uint256", "name": "totalMinted", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastInteractionTime", + "type": "uint256" + }, + { "internalType": "uint256", "name": "VestPeriod", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vestingPeriod", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/gmd-protocol/abis/MultiCallABI.json b/src/adaptors/gmd-protocol/abis/MultiCallABI.json new file mode 100644 index 0000000000..f7d3f962f6 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/MultiCallABI.json @@ -0,0 +1,185 @@ +[ + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "aggregate", + "outputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, + { "internalType": "bytes[]", "name": "returnData", "type": "bytes[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "blockAndAggregate", + "outputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "bool", "name": "success", "type": "bool" }, + { "internalType": "bytes", "name": "returnData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" } + ], + "name": "getBlockHash", + "outputs": [ + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockCoinbase", + "outputs": [ + { "internalType": "address", "name": "coinbase", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockDifficulty", + "outputs": [ + { "internalType": "uint256", "name": "difficulty", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockGasLimit", + "outputs": [ + { "internalType": "uint256", "name": "gaslimit", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentBlockTimestamp", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "addr", "type": "address" } + ], + "name": "getEthBalance", + "outputs": [ + { "internalType": "uint256", "name": "balance", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastBlockHash", + "outputs": [ + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "requireSuccess", "type": "bool" }, + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryAggregate", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "success", "type": "bool" }, + { "internalType": "bytes", "name": "returnData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "requireSuccess", "type": "bool" }, + { + "components": [ + { "internalType": "address", "name": "target", "type": "address" }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "name": "tryBlockAndAggregate", + "outputs": [ + { "internalType": "uint256", "name": "blockNumber", "type": "uint256" }, + { "internalType": "bytes32", "name": "blockHash", "type": "bytes32" }, + { + "components": [ + { "internalType": "bool", "name": "success", "type": "bool" }, + { "internalType": "bytes", "name": "returnData", "type": "bytes" } + ], + "internalType": "struct Multicall2.Result[]", + "name": "returnData", + "type": "tuple[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/gmd-protocol/abis/PriceABI.json b/src/adaptors/gmd-protocol/abis/PriceABI.json new file mode 100644 index 0000000000..c01e921350 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/PriceABI.json @@ -0,0 +1,43 @@ +[ + { + "inputs": [], + "name": "GLP", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GLPm", + "outputs": [ + { "internalType": "contract GLPmanager", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "geAum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGLPprice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/gmd-protocol/abis/ValutABI.json b/src/adaptors/gmd-protocol/abis/ValutABI.json new file mode 100644 index 0000000000..f16ee79c2b --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/ValutABI.json @@ -0,0 +1,445 @@ +[ + { + "inputs": [ + { + "internalType": "contract GDtoken", + "name": "_gdUSDC", + "type": "address" + }, + { + "internalType": "contract GDtoken", + "name": "_gdETH", + "type": "address" + }, + { + "internalType": "contract GDtoken", + "name": "_gdBTC", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "EsGMX", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "GDpriceToStakedtoken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GLPbackingNeeded", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GLPinVault", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDC", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WBTC", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { "internalType": "contract IWETH", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_GLPRouter", + "outputs": [ + { "internalType": "contract GLPRouter", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lptoken", + "type": "address" + }, + { + "internalType": "contract GDtoken", + "name": "_GDlptoken", + "type": "address" + }, + { "internalType": "uint256", "name": "_fees", "type": "uint256" }, + { "internalType": "uint256", "name": "_apr", "type": "uint256" } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "compoundPercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "convertDust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "currentPoolTotal", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cycleRewardsETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cycleRewardsETHandEsGMX", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "displayStakedBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amountin", "type": "uint256" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "enter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "enterETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "fsGLP", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gdUSDC", + "outputs": [ + { "internalType": "contract GDtoken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_share", "type": "uint256" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "leave", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_share", "type": "uint256" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "leaveETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_vaultcap", "type": "uint256" } + ], + "name": "openVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "openWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "pauseReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "contract GDtoken", + "name": "GDlptoken", + "type": "address" + }, + { "internalType": "uint256", "name": "EarnRateSec", "type": "uint256" }, + { "internalType": "uint256", "name": "totalStaked", "type": "uint256" }, + { "internalType": "uint256", "name": "lastUpdate", "type": "uint256" }, + { "internalType": "uint256", "name": "vaultcap", "type": "uint256" }, + { "internalType": "uint256", "name": "glpFees", "type": "uint256" }, + { "internalType": "uint256", "name": "APR", "type": "uint256" }, + { "internalType": "bool", "name": "stakable", "type": "bool" }, + { "internalType": "bool", "name": "withdrawable", "type": "bool" }, + { "internalType": "bool", "name": "rewardStart", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeed", + "outputs": [ + { "internalType": "contract GLPPriceFeed", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "recoverTreasuryTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "GLPamount", "type": "uint256" } + ], + "name": "recoverTreasuryTokensFromGLP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_apr", "type": "uint256" } + ], + "name": "setAPR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_percent", "type": "uint256" } + ], + "name": "setCompoundPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_vaultcap", "type": "uint256" }, + { "internalType": "bool", "name": "_withdrawable", "type": "bool" }, + { "internalType": "bool", "name": "_stakable", "type": "bool" }, + { "internalType": "bool", "name": "_rewardStart", "type": "bool" } + ], + "name": "setPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_slippage", "type": "uint256" } + ], + "name": "setSlippage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slippage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "startReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "min_receive", "type": "uint256" } + ], + "name": "swapGLPout", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "totalUSDvault", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUSDvaults", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "treasuryMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryMintedGLP", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/gmd-protocol/abis/address.js b/src/adaptors/gmd-protocol/abis/address.js new file mode 100644 index 0000000000..0ed2ff4ab3 --- /dev/null +++ b/src/adaptors/gmd-protocol/abis/address.js @@ -0,0 +1,23 @@ +exports.MULTICALL_ADDR = "0x842eC2c7D803033Edf55E478F461FC547Bc54EB2"; +exports.VAULT_ADDR = "0x8080B5cE6dfb49a6B86370d6982B3e2A86FBBb08"; +exports.NEWVAULT_ADDR = "0x8080B5cE6dfb49a6B86370d6982B3e2A86FBBb08"; +exports.BFRVAULT_ADDR = "0x56009e94418ddfe8604331eceff38db0738775f8"; +exports.PRICE_ADDR = "0x06e31Ad70174D7dB1Eb06fCDa75Aa254E311BC3f"; +exports.ETH_ADDR = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"; +exports.BTC_ADDR = "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f"; +exports.USDC_ADDR = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8"; +exports.GDlptoken = [ + "0x4A723DE8aF2be96292dA3F824a96bfA053d4aF66", + "0xc5182E92bf001baE7049c4496caD96662Db1A186", + "0xEffaE8eB4cA7db99e954adc060B736Db78928467", +]; +exports.GD2lptoken = [ + "0x3DB4B7DA67dd5aF61Cb9b3C70501B1BdB24b2C22", + "0x1E95A37Be8A17328fbf4b25b9ce3cE81e271BeB3", + "0x147FF11D9B9Ae284c271B2fAaE7068f4CA9BB619", +]; +exports.MINT_ADDR = "0x4945970EfeEc98D393b4b979b9bE265A3aE28A8B"; +exports.GMD_STAKING_ADDR = "0x8A19F6BC381caf24C7122296AA51047105924074"; +exports.GMD_ADDR = "0x4945970EfeEc98D393b4b979b9bE265A3aE28A8B"; +exports.esGMD_ADDR = "0x49E050dF648E9477c7545fE1779B940f879B787A"; +exports.GMD_STAKING_ADDR2 = "0x5088a423933dbfd94af2d64ad3db3d4ab768107f"; \ No newline at end of file diff --git a/src/adaptors/gmd-protocol/index.js b/src/adaptors/gmd-protocol/index.js new file mode 100644 index 0000000000..7ef3d1d045 --- /dev/null +++ b/src/adaptors/gmd-protocol/index.js @@ -0,0 +1,97 @@ +const axios = require('axios'); +const { multicall } = require('./utils/contracts'); +const PriceABI = require('./abis/PriceABI.json'); +const ValutABI = require('./abis/ValutABI.json'); +const ERC20ABI = require('./abis/ERC20ABI.json'); +const GMDStakingABI = require('./abis/GMDStakingABI.json'); +const IUniswapV3Pool = require('./abis/IUniswapV3Pool.json'); +const getTokenContract = require('./utils/contracts'); +const ethers = require('ethers'); +const { + BTC_ADDR, + ETH_ADDR, + PRICE_ADDR, + USDC_ADDR, + VAULT_ADDR, + GMD_STAKING_ADDR, + GMD_STAKING_ADDR2, + GMD_ADDR, + esGMD_ADDR, +} = require('./abis/address'); + +const SECONDS_PER_YEAR = 365.25 * 24 * 60 * 60; +const BLOCKS_IN_A_YEAR = SECONDS_PER_YEAR / 14; + +const aprToApy = (interest, frequency = BLOCKS_IN_A_YEAR) => + ((1 + interest / 100 / frequency) ** frequency - 1) * 100; + +const getData = async () => { + const fee = 1 - 0.5 / 100; + let calls = [ + { address: VAULT_ADDR, params: [0], name: 'poolInfo' }, + { address: VAULT_ADDR, params: [1], name: 'poolInfo' }, + { address: VAULT_ADDR, params: [2], name: 'poolInfo' }, + ]; + const poolInfomation = await multicall(ValutABI, calls); + calls = [ + { address: PRICE_ADDR, params: [USDC_ADDR], name: 'getPrice' }, + { address: PRICE_ADDR, params: [ETH_ADDR], name: 'getPrice' }, + { address: PRICE_ADDR, params: [BTC_ADDR], name: 'getPrice' }, + ]; + const _prices = await multicall(PriceABI, calls); + + const pools = [ + { + price: _prices ? _prices[0][0] / Math.pow(10, 30) : 0, + apr: aprToApy(poolInfomation[0].APR / 100).toFixed(2), + totalStaked: poolInfomation[0].totalStaked, + }, + { + price: _prices ? _prices[1][0] / Math.pow(10, 30) : 0, + apr: aprToApy(poolInfomation[1].APR / 100).toFixed(2), + totalStaked: poolInfomation[1].totalStaked, + }, + { + price: _prices ? _prices[2][0] / Math.pow(10, 30) : 0, + apr: aprToApy(poolInfomation[2].APR / 100).toFixed(2), + totalStaked: poolInfomation[2].totalStaked, + }, + ]; + + const apy = [ + { + pool: '0x4A723DE8aF2be96292dA3F824a96bfA053d4aF66', + chain: 'Arbitrum', + project: 'gmd-protocol', + symbol: 'USDC', + tvlUsd: (pools[0].totalStaked * pools[0].price) / Math.pow(10, 18), + apyBase: pools[0].apr * fee, + underlyingTokens: [USDC_ADDR], + }, + { + pool: '0xc5182E92bf001baE7049c4496caD96662Db1A186', + chain: 'Arbitrum', + project: 'gmd-protocol', + symbol: 'ETH', + tvlUsd: (pools[1].totalStaked * pools[1].price) / Math.pow(10, 18), + apyBase: pools[1].apr * fee, + underlyingTokens: [ETH_ADDR], + }, + { + pool: '0xEffaE8eB4cA7db99e954adc060B736Db78928467', + chain: 'Arbitrum', + project: 'gmd-protocol', + symbol: 'BTC', + tvlUsd: (pools[2].totalStaked * pools[2].price) / Math.pow(10, 18), + apyBase: pools[2].apr * fee, + underlyingTokens: [BTC_ADDR], + }, + ]; + return apy; +}; + +module.exports = { + timetravel: false, + apy: getData, + url: 'https://gmdprotocol.com/', +}; diff --git a/src/adaptors/gmd-protocol/utils/contracts.js b/src/adaptors/gmd-protocol/utils/contracts.js new file mode 100644 index 0000000000..90572c2a13 --- /dev/null +++ b/src/adaptors/gmd-protocol/utils/contracts.js @@ -0,0 +1,64 @@ +const { ethers } = require("ethers"); +const { + GMD_STAKING_ADDR, + MINT_ADDR, + MULTICALL_ADDR, + PRICE_ADDR, + VAULT_ADDR, +} = require("../abis/address"); +const MultiCallABI = require("../abis/MultiCallABI.json"); +const ERC20ABI = require("../abis/ERC20ABI.json"); +const VaultABI = require("../abis/ValutABI.json"); +const PriceABI = require("../abis/PriceABI.json"); +const MintABI = require("../abis/MintABI.json"); +const GMDStakingABI = require("../abis/GMDStakingABI.json"); + +exports.RPC_ENDPOINT = "https://arb-mainnet.g.alchemy.com/v2/-g2xRou0mvYu9_rsilf44FQREKzsGTo2"; + +exports.getContract = (abi, address, signer) => { + const simpleRpcProvider = new ethers.providers.JsonRpcProvider(exports.RPC_ENDPOINT); + const signerOrProvider = signer ?? simpleRpcProvider; + return new ethers.Contract(address, abi, signerOrProvider); +}; +exports.getTokenContract = (address, signer) => { + return exports.getContract(ERC20ABI, address, signer); +}; +exports.getVaultContract = (signer) => { + return exports.getContract(VaultABI, VAULT_ADDR, signer); +}; + +exports.getPriceContract = (signer) => { + return exports.getContract(PriceABI, PRICE_ADDR, signer); +}; + +exports.getMintContract = (signer) => { + return exports.getContract(MintABI, MINT_ADDR, signer); +}; + +exports.getGMDStakingContract = (signer) => { + return exports.getContract(GMDStakingABI, GMD_STAKING_ADDR, signer); +}; + +exports.getMulticallContract = (signer) => { + return exports.getContract(MultiCallABI, MULTICALL_ADDR, signer); +}; + +exports.multicall = async (abi, calls) => { + try { + const itf = new ethers.utils.Interface(abi); + const multi = exports.getMulticallContract(); + const calldata = calls.map((call) => [ + call.address.toLowerCase(), + itf.encodeFunctionData(call.name, call.params), + ]); + + const { returnData } = await multi.aggregate(calldata); + const res = returnData.map((call, i) => + itf.decodeFunctionResult(calls[i].name, call) + ); + + return res; + } catch (error) { + console.log(error); + } +}; diff --git a/src/adaptors/gmx/abis/abi.json b/src/adaptors/gmx-v1-perps/abis/abi.json similarity index 100% rename from src/adaptors/gmx/abis/abi.json rename to src/adaptors/gmx-v1-perps/abis/abi.json diff --git a/src/adaptors/gmx/index.js b/src/adaptors/gmx-v1-perps/index.js similarity index 79% rename from src/adaptors/gmx/index.js rename to src/adaptors/gmx-v1-perps/index.js index 9704203349..a8c934498f 100644 --- a/src/adaptors/gmx/index.js +++ b/src/adaptors/gmx-v1-perps/index.js @@ -25,6 +25,7 @@ const avalancheInflationGlpTrackerAddress = '0x9e295B5B976a184B14aD8cd72413aD846C299660'; const secondsPerYear = 31536000; +const project = 'gmx-v1-perps'; async function getAdjustedAmount(pTarget, pChain, pAbi, pParams = []) { let decimals = await sdk.api.abi.call({ @@ -67,8 +68,9 @@ async function getPoolGmx( pInflationGmx, pPriceData ) { + const gmxPrice = pPriceData['coingecko:gmx'].price; const tvlGmx = - pPriceData.gmx.usd * + gmxPrice * (await getAdjustedAmount( pChain == 'arbitrum' ? arbitrumGmxAddress : avalacheGmxAddress, pChain, @@ -77,13 +79,14 @@ async function getPoolGmx( ? [arbitrumInflationGmxTrackerAddress] : [avalancheInflationGmxTrackerAddress] )); - const tvsGmx = pStakedGmx * pPriceData.gmx.usd; - const tvsEsGmx = pStakedEsGmx * pPriceData.gmx.usd; + + const tvsGmx = pStakedGmx * gmxPrice; + const tvsEsGmx = pStakedEsGmx * gmxPrice; const yearlyFeeGmx = pChain == 'arbitrum' - ? pFeeGmx * pPriceData.ethereum.usd - : pFeeGmx * pPriceData['avalanche-2'].usd; - const yearlyInflationGmx = pInflationGmx * pPriceData.gmx.usd; + ? pFeeGmx * pPriceData['coingecko:ethereum'].price + : pFeeGmx * pPriceData['coingecko:avalanche-2'].price; + const yearlyInflationGmx = pInflationGmx * gmxPrice; const apyFee = (yearlyFeeGmx / tvsGmx) * 100; const apyInflation = (yearlyInflationGmx / tvsEsGmx) * 100; const chainString = pChain === 'avax' ? 'avalanche' : pChain; @@ -91,10 +94,16 @@ async function getPoolGmx( return { pool: pInflationTrackerAddress, chain: utils.formatChain(chainString), - project: 'gmx', + project, symbol: utils.formatSymbol('GMX'), tvlUsd: tvlGmx, - apy: apyFee + apyInflation, + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + chainString === 'arbitrum' ? [arbitrumGmxAddress] : [avalacheGmxAddress], + underlyingTokens: [ + chainString === 'arbitrum' ? arbitrumGmxAddress : avalacheGmxAddress, + ], }; } @@ -108,9 +117,9 @@ async function getPoolGlp( ) { const yearlyFeeGlp = pChain == 'arbitrum' - ? pFeeGlp * pPriceData.ethereum.usd - : pFeeGlp * pPriceData['avalanche-2'].usd; - const yearlyInflationGlp = pInflationGlp * pPriceData.gmx.usd; + ? pFeeGlp * pPriceData['coingecko:ethereum'].price + : pFeeGlp * pPriceData['coingecko:avalanche-2'].price; + const yearlyInflationGlp = pInflationGlp * pPriceData['coingecko:gmx'].price; const apyFee = (yearlyFeeGlp / pTvl) * 100; const apyInflation = (yearlyInflationGlp / pTvl) * 100; const chainString = pChain === 'avax' ? 'avalanche' : pChain; @@ -118,18 +127,30 @@ async function getPoolGlp( return { pool: pInflationTrackerAddress, chain: utils.formatChain(chainString), - project: 'gmx', - symbol: utils.formatSymbol('GLP'), + project, + symbol: 'WBTC-ETH-USDC-DAI-FRAX-LINK-UNI-USDT', + poolMeta: 'GLP', tvlUsd: parseFloat(pTvl), - apy: apyFee + apyInflation, + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + chainString === 'arbitrum' ? [arbitrumGmxAddress] : [avalacheGmxAddress], + underlyingTokens: [ + chainString === 'arbitrum' + ? '0x4277f8F2c384827B5273592FF7CeBd9f2C1ac258' + : '0x01234181085565ed162a948b6a5e88758CD7c7b8', + ], }; } const getPools = async () => { let pools = []; - const priceData = await utils.getData( - 'https://api.coingecko.com/api/v3/simple/price?ids=gmx%2Cethereum%2Cavalanche-2&vs_currencies=usd' + const priceKeys = ['gmx', 'ethereum', 'avalanche-2'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` ); const arbitrumStakedGmx = await getAdjustedAmount( @@ -244,4 +265,5 @@ const getPools = async () => { module.exports = { timetravel: false, apy: getPools, + url: 'https://app.gmx.io/#/earn', }; diff --git a/src/adaptors/gmx-v2-perps/abi.js b/src/adaptors/gmx-v2-perps/abi.js new file mode 100644 index 0000000000..3a02534487 --- /dev/null +++ b/src/adaptors/gmx-v2-perps/abi.js @@ -0,0 +1,3756 @@ +const ABI = [ + { + inputs: [ + { + internalType: 'address', + name: 'market', + type: 'address', + }, + ], + name: 'DisabledMarket', + type: 'error', + }, + { + inputs: [], + name: 'EmptyMarket', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getAccountOrders', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialCollateralToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'swapPath', + type: 'address[]', + }, + ], + internalType: 'struct Order.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'enum Order.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'enum Order.DecreasePositionSwapType', + name: 'decreasePositionSwapType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialCollateralDeltaAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'triggerPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'acceptablePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minOutputAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Order.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + ], + internalType: 'struct Order.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Order.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'contract IReferralStorage', + name: 'referralStorage', + type: 'address', + }, + { + internalType: 'bytes32[]', + name: 'positionKeys', + type: 'bytes32[]', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices[]', + name: 'prices', + type: 'tuple[]', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getAccountPositionInfoList', + outputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: 'position', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'bytes32', + name: 'referralCode', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'affiliate', + type: 'address', + }, + { + internalType: 'address', + name: 'trader', + type: 'address', + }, + { + internalType: 'uint256', + name: 'totalRebateFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalRebateAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'affiliateRewardAmount', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionReferralFees', + name: 'referral', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'fundingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestFundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestLongTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestShortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFundingFees', + name: 'funding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'borrowingFeeUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmountForFeeReceiver', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionBorrowingFees', + name: 'borrowing', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionUiFees', + name: 'ui', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'collateralTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionFeeFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmountExcludingFunding', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFees', + name: 'fees', + type: 'tuple', + }, + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: 'executionPriceResult', + type: 'tuple', + }, + { + internalType: 'int256', + name: 'basePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'uncappedBasePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'pnlAfterPriceImpactUsd', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.PositionInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getAccountPositions', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + ], + name: 'getAdlState', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'bool', + name: '', + type: 'bool', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getDeposit', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialLongToken', + type: 'address', + }, + { + internalType: 'address', + name: 'initialShortToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'longTokenSwapPath', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'shortTokenSwapPath', + type: 'address[]', + }, + ], + internalType: 'struct Deposit.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'initialLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minMarketTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + ], + internalType: 'struct Deposit.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + ], + internalType: 'struct Deposit.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Deposit.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'longTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getDepositAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionSizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionSizeInTokens', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'sizeDeltaUsd', + type: 'int256', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + name: 'getExecutionPrice', + outputs: [ + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'key', + type: 'address', + }, + ], + name: 'getMarket', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'salt', + type: 'bytes32', + }, + ], + name: 'getMarketBySalt', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + ], + name: 'getMarketInfo', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForLongs', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForShorts', + type: 'uint256', + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSize', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSize', + type: 'tuple', + }, + ], + internalType: 'struct ReaderUtils.BaseFundingValues', + name: 'baseFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'longsPayShorts', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'fundingFactorPerSecond', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'nextSavedFundingFactorPerSecond', + type: 'int256', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSizeDelta', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSizeDelta', + type: 'tuple', + }, + ], + internalType: + 'struct MarketUtils.GetNextFundingAmountPerSizeResult', + name: 'nextFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'virtualPoolAmountForLongToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'virtualPoolAmountForShortToken', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'virtualInventoryForPositions', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.VirtualInventory', + name: 'virtualInventory', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isDisabled', + type: 'bool', + }, + ], + internalType: 'struct ReaderUtils.MarketInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices[]', + name: 'marketPricesList', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getMarketInfoList', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForLongs', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForShorts', + type: 'uint256', + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSize', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSize', + type: 'tuple', + }, + ], + internalType: 'struct ReaderUtils.BaseFundingValues', + name: 'baseFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'longsPayShorts', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'fundingFactorPerSecond', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'nextSavedFundingFactorPerSecond', + type: 'int256', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSizeDelta', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSizeDelta', + type: 'tuple', + }, + ], + internalType: + 'struct MarketUtils.GetNextFundingAmountPerSizeResult', + name: 'nextFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'virtualPoolAmountForLongToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'virtualPoolAmountForShortToken', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'virtualInventoryForPositions', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.VirtualInventory', + name: 'virtualInventory', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isDisabled', + type: 'bool', + }, + ], + internalType: 'struct ReaderUtils.MarketInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + { + internalType: 'bytes32', + name: 'pnlFactorType', + type: 'bytes32', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getMarketTokenPrice', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + components: [ + { + internalType: 'int256', + name: 'poolValue', + type: 'int256', + }, + { + internalType: 'int256', + name: 'longPnl', + type: 'int256', + }, + { + internalType: 'int256', + name: 'shortPnl', + type: 'int256', + }, + { + internalType: 'int256', + name: 'netPnl', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'longTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowingFees', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeePoolFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'impactPoolAmount', + type: 'uint256', + }, + ], + internalType: 'struct MarketPoolValueInfo.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getMarkets', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getNetPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getOpenInterestWithPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getOrder', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialCollateralToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'swapPath', + type: 'address[]', + }, + ], + internalType: 'struct Order.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'enum Order.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'enum Order.DecreasePositionSwapType', + name: 'decreasePositionSwapType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialCollateralDeltaAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'triggerPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'acceptablePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minOutputAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Order.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + ], + internalType: 'struct Order.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Order.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketAddress', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getPnlToPoolFactor', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getPosition', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'contract IReferralStorage', + name: 'referralStorage', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'positionKey', + type: 'bytes32', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'bool', + name: 'usePositionSizeAsSizeDeltaUsd', + type: 'bool', + }, + ], + name: 'getPositionInfo', + outputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: 'position', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'bytes32', + name: 'referralCode', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'affiliate', + type: 'address', + }, + { + internalType: 'address', + name: 'trader', + type: 'address', + }, + { + internalType: 'uint256', + name: 'totalRebateFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalRebateAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'affiliateRewardAmount', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionReferralFees', + name: 'referral', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'fundingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestFundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestLongTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestShortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFundingFees', + name: 'funding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'borrowingFeeUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmountForFeeReceiver', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionBorrowingFees', + name: 'borrowing', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionUiFees', + name: 'ui', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'collateralTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionFeeFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmountExcludingFunding', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFees', + name: 'fees', + type: 'tuple', + }, + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: 'executionPriceResult', + type: 'tuple', + }, + { + internalType: 'int256', + name: 'basePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'uncappedBasePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'pnlAfterPriceImpactUsd', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.PositionInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'bytes32', + name: 'positionKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + ], + name: 'getPositionPnlUsd', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getSwapAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amountAfterFees', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct SwapPricingUtils.SwapFees', + name: 'fees', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenOut', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'tokenInPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'tokenOutPrice', + type: 'tuple', + }, + ], + name: 'getSwapPriceImpact', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getWithdrawal', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address[]', + name: 'longTokenSwapPath', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'shortTokenSwapPath', + type: 'address[]', + }, + ], + internalType: 'struct Withdrawal.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + ], + internalType: 'struct Withdrawal.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + ], + internalType: 'struct Withdrawal.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Withdrawal.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'marketTokenAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getWithdrawalAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { ABI }; diff --git a/src/adaptors/gmx-v2-perps/index.js b/src/adaptors/gmx-v2-perps/index.js new file mode 100644 index 0000000000..5f4e603a67 --- /dev/null +++ b/src/adaptors/gmx-v2-perps/index.js @@ -0,0 +1,336 @@ +const { ABI } = require('./abi'); +const utils = require('../utils'); + +const sdk = require('@defillama/sdk'); +const { gql, default: request } = require('graphql-request'); +const fetch = require('node-fetch'); +const { ethers } = require('ethers'); +const { sub } = require('date-fns'); + +const { default: BigNumber } = require('bignumber.js'); + +const MARKETS_PAGE_SIZE = 100; + +const SUBGRAPH_URL = { + arbitrum: 'https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql', + avax: 'https://gmx.squids.live/gmx-synthetics-avalanche:prod/api/graphql', +}; + +const CONTRACTS = { + arbitrum: { + syntheticsReader: '0xf60becbba223EEA9495Da3f606753867eC10d139', + dataStore: '0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8', + }, + avax: { + syntheticsReader: '0x73BA021ACF4Bb6741E82690DdB821e7936050f8C', + dataStore: '0x2F0b22339414ADeD7D5F06f9D604c7fF5b2fe3f6', + }, +}; + +const TICKERS_URL = { + arbitrum: 'https://arbitrum-api.gmxinfra.io/prices/tickers', + avax: 'https://avalanche-api.gmxinfra.io/prices/tickers', +}; + +const WETH = { + arbitrum: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'.toLowerCase(), + avax: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'.toLowerCase(), +}; + +function hashData(dataTypes, dataValues) { + const bytes = ethers.utils.defaultAbiCoder.encode(dataTypes, dataValues); + const hash = ethers.utils.keccak256(ethers.utils.arrayify(bytes)); + + return hash; +} + +function hashString(string) { + return hashData(['string'], [string]); +} + +const MAX_PNL_FACTOR_FOR_DEPOSITS_KEY = hashString( + 'MAX_PNL_FACTOR_FOR_DEPOSITS' +); + +const marketsQuery = gql` + query M($limit: Int!, $offset: Int!) { + marketInfos(limit: $limit, offset: $offset) { + id + marketTokenAddress + indexTokenAddress + longTokenAddress + shortTokenAddress + } + } +`; + +const marketFeesQuery = (marketAddress) => { + return ` + _${marketAddress}_lte_start_of_period_: collectedFeesInfos( + orderBy: timestampGroup_DESC + where: { + address_containsInsensitive: "${marketAddress.toLowerCase()}" + period_eq: "1h" + timestampGroup_lte: ${Math.floor( + sub(new Date(), { days: 7 }).valueOf() / 1000 + )} + } + limit: 1 + ) { + cumulativeFeeUsdPerPoolValue + } + _${marketAddress}_recent: collectedFeesInfos( + orderBy: timestampGroup_DESC + where: { + address_containsInsensitive: "${marketAddress.toLowerCase()}" + period_eq: "1h" + } + limit: 1 + ) { + cumulativeFeeUsdPerPoolValue + } + `; +}; + +function bigNumberify(n) { + try { + return BigNumber(n); + } catch (e) { + console.error('bigNumberify error', e); + return undefined; + } +} + +function expandDecimals(n, decimals) { + return bigNumberify(n).times(bigNumberify(10).pow(decimals)); +} + +const getMarkets = async (chain) => { + const marketInfos = []; + let offset = 0; + while (true) { + const { marketInfos: batch } = await request( + SUBGRAPH_URL[chain], + marketsQuery, + { limit: MARKETS_PAGE_SIZE, offset } + ); + if (!batch?.length) break; + marketInfos.push(...batch); + if (batch.length < MARKETS_PAGE_SIZE) break; + offset += MARKETS_PAGE_SIZE; + } + + if (!marketInfos.length) return []; + + const queryBody = marketInfos.reduce((acc, market) => { + const marketAddress = ( + market.marketTokenAddress || + market.id || + '' + ).toLowerCase(); + if (!marketAddress) return acc; + return acc + marketFeesQuery(marketAddress); + }, ''); + + const res = queryBody + ? await request( + SUBGRAPH_URL[chain], + gql`query M { + ${queryBody} + }` + ) + : {}; + + const tickers = ( + await fetch(TICKERS_URL[chain]).then((r) => r.json()) + ).reduce( + (acc, price) => ({ + ...acc, + [price?.tokenAddress?.toLowerCase()]: { + min: price.minPrice, + max: price.maxPrice, + data: price, + }, + }), + {} + ); + + const marketResults = {}; + + await Promise.all( + marketInfos.map(async (market) => { + const { + marketTokenAddress, + longTokenAddress, + shortTokenAddress, + indexTokenAddress, + } = market; + + if (!marketTokenAddress || !longTokenAddress || !shortTokenAddress) + return null; + + const marketProps = { + marketToken: marketTokenAddress, + longToken: longTokenAddress, + shortToken: shortTokenAddress, + indexToken: indexTokenAddress, + }; + + const indexTicker = + tickers[indexTokenAddress?.toLowerCase()] || tickers[WETH[chain]]; + const longTicker = tickers[longTokenAddress?.toLowerCase()]; + const shortTicker = tickers[shortTokenAddress?.toLowerCase()]; + + if (!indexTicker || !longTicker || !shortTicker) return null; + + const min = ( + await sdk.api.abi.call({ + target: CONTRACTS[chain].syntheticsReader, // synthetix, + abi: ABI.find((m) => m.name === 'getMarketTokenPrice'), + chain: chain, + params: [ + CONTRACTS[chain].dataStore, //datastore + marketProps, + indexTicker, + longTicker, + shortTicker, + MAX_PNL_FACTOR_FOR_DEPOSITS_KEY, + false, + ], + }) + ).output; + const max = ( + await sdk.api.abi.call({ + target: CONTRACTS[chain].syntheticsReader, // synthetix, + abi: ABI.find((m) => m.name === 'getMarketTokenPrice'), + chain: chain, + params: [ + CONTRACTS[chain].dataStore, //datastore + marketProps, + indexTicker, + longTicker, + shortTicker, + MAX_PNL_FACTOR_FOR_DEPOSITS_KEY, + true, + ], + }) + ).output; + + const supply = await sdk.api.erc20.totalSupply({ + target: marketTokenAddress, + chain: chain, + }); + + const tvl = BigNumber(supply.output || 0) + .div(1e18) + .times(BigNumber(min[0] || 0)) + .div(1e30) + .toNumber(); + if (!Number.isFinite(tvl)) return null; + + marketResults[marketTokenAddress.toLowerCase()] = { + totalSupply: supply.output, + minPrice: min[0], + maxPrice: max[0], + tvl, + }; + return res; + }) + ); + + // bonus apr (ARB) + let rewards; + let priceARB; + const ARB = '0x912ce59144191c1204e64559fe8253a0e49e6548'; + const priceKey = `arbitrum:${ARB}`; + const bonusAPR = await utils.getData( + 'https://arbitrum-api.gmxinfra2.io/incentives/stip?' + ); + if (bonusAPR?.lp?.isActive) { + // weekly rewards + const weeklyRewards = bonusAPR.lp.rewardsPerMarket; + rewards = Object.keys(weeklyRewards).reduce((acc, k) => { + acc[k.toLowerCase()] = weeklyRewards[k]; + return acc; + }, {}); + + priceARB = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + } + + const marketTokensAPRData = marketInfos.map((market) => { + const marketToken = market.marketTokenAddress; + const marketAddress = marketToken?.toLowerCase(); + if (!marketAddress) return; + + const marketData = marketResults[marketAddress]; + if (!marketData) return; + + const lteStartOfPeriodFees = + res[`_${marketAddress}_lte_start_of_period_`] || []; + const recentFees = res[`_${marketAddress}_recent`] || []; + + const poolValue1 = + bigNumberify(lteStartOfPeriodFees[0]?.cumulativeFeeUsdPerPoolValue) || + BigNumber(0); + const poolValue2 = + bigNumberify(recentFees[0]?.cumulativeFeeUsdPerPoolValue) || BigNumber(0); + + if (poolValue1.isNaN() || poolValue2.isNaN()) return; + + if (poolValue2) { + const incomePercentageForPeriod = poolValue2.minus(poolValue1); + + const yearMultiplier = Math.floor(365 / 7); + const apr = incomePercentageForPeriod + .times(yearMultiplier) + .div(expandDecimals(1, 26)); + const apyBase = apr.div(100).toNumber(); + if (!Number.isFinite(apyBase)) return; + + const longSymbol = + tickers[market.longTokenAddress.toLowerCase()]?.data?.tokenSymbol; + const shortSymbol = + tickers[market.shortTokenAddress.toLowerCase()]?.data?.tokenSymbol; + + const tvlUsd = Number(marketData?.tvl); + if (!Number.isFinite(tvlUsd)) return; + + let apyReward; + if (rewards && tvlUsd > 0) { + const rewardPerYear = + (rewards[marketAddress.toLowerCase()] / 1e18) * + 52 * + priceARB.coins[priceKey].price; + + apyReward = (rewardPerYear / tvlUsd) * 100; + } + + return { + pool: marketAddress, + chain: utils.formatChain(chain === 'avax' ? 'avalanche' : chain), + project: 'gmx-v2-perps', + symbol: `${longSymbol}-${shortSymbol}`, + tvlUsd, + apyBase, + apyReward: apyReward ?? null, + underlyingTokens: [market.longTokenAddress, market.shortTokenAddress], + rewardTokens: apyReward > 0 ? [ARB] : [], + }; + } else { + return; + } + }); + return marketTokensAPRData.filter(Boolean).filter((i) => utils.keepFinite(i)); +}; + +const apy = async () => { + return (await Promise.all(['avax', 'arbitrum'].map(getMarkets))).flat(); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.gmx.io/#/earn', +}; diff --git a/src/adaptors/goat-protocol/index.js b/src/adaptors/goat-protocol/index.js new file mode 100644 index 0000000000..2d2cb0788e --- /dev/null +++ b/src/adaptors/goat-protocol/index.js @@ -0,0 +1,54 @@ +const utils = require('../utils'); + +const dappUrl = 'https://app.goat.fi'; +const url = 'https://api.goat.fi'; +const urlMeta = `${url}/vaults`; + +const networkMapping = { + 1: 'ethereum', + 10: 'optimism', + 56: 'bsc', + 100: 'gnosis', + 137: 'polygon', + 146: 'sonic', + 252: 'fraxtal', + 324: 'zksync', + 1101: 'polygon_zkevm', + 5000: 'mantle', + 8453: 'base', + 34443: 'mode', + 42161: 'arbitrum', + 42220: 'celo', + 43114: 'avalanche', + 59144: 'linea', + }; + +const main = async () => { + const meta = await utils.getData(urlMeta); + + const data = []; + for (const chain of Object.keys(meta.data)) { + for (const vaultName in meta.data[Number(chain)]) { + const vault = meta.data[Number(chain)][vaultName]; + + data.push({ + pool: `${vault.address}-${networkMapping[chain]}`.toLowerCase(), + chain: utils.formatChain(networkMapping[chain]), + project: 'goat-protocol', + symbol: utils.formatSymbol(vault.asset.symbol), + tvlUsd: vault.tvl, + apy: vault.apy * 100, + underlyingTokens: [vault.asset.address], + url: `${dappUrl}/vault/${networkMapping[chain]}/${vaultName}` + }); + } + } + + return utils.removeDuplicates(data); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://goat.fi/', +}; diff --git a/src/adaptors/goldfinch/index.ts b/src/adaptors/goldfinch/index.ts new file mode 100644 index 0000000000..3784e8a757 --- /dev/null +++ b/src/adaptors/goldfinch/index.ts @@ -0,0 +1,63 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); + +const GFI_ADDRESS = '0xdab396cCF3d84Cf2D07C4454e10C8A6F5b008D2b'; +const USDC_ADDRESS = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; +const SENIOR_POOL_ADDRESS = '0x8481a6EbAf5c7DABc3F7e09e44A89531fd31F822'; + +const API_URL = sdk.graph.modifyEndpoint('G9N1RFta3jbpPNmeGxSJoMVBZUJeG1jiSxUfYG29UQHj'); + +const apyQuery = gql` + query { + seniorPools { + estimatedApy + estimatedApyFromGfiRaw + assets + } + } +`; + +const GFI = '0xdab396ccf3d84cf2d07c4454e10c8a6f5b008d2b'; +const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +async function apy() { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/ethereum:${GFI},ethereum:${USDC}` + ) + ).data.coins; + + const { seniorPools } = await request(API_URL, apyQuery); + const { estimatedApy, estimatedApyFromGfiRaw, assets } = seniorPools[0]; + const tvlUsd = + new BigNumber(assets).dividedBy(1e6).toNumber() * + prices[`ethereum:${USDC}`].price; + + return [ + { + pool: SENIOR_POOL_ADDRESS, + chain: utils.formatChain('ethereum'), + project: 'goldfinch', + symbol: 'USDC', + tvlUsd, + apyBase: parseFloat(estimatedApy) * 100, + apyReward: + parseFloat(estimatedApyFromGfiRaw) * + prices[`ethereum:${GFI}`].price * + 100, + underlyingTokens: [USDC_ADDRESS], + rewardTokens: [GFI_ADDRESS], + // borrow fields + ltv: 0, // permissioned + }, + ]; +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://beta.app.goldfinch.finance/earn', +}; diff --git a/src/adaptors/goldlink/abis/bank-abi.json b/src/adaptors/goldlink/abis/bank-abi.json new file mode 100644 index 0000000000..1ac5b31be4 --- /dev/null +++ b/src/adaptors/goldlink/abis/bank-abi.json @@ -0,0 +1,13 @@ +{ + "type": "function", + "name": "INSURANCE_PREMIUM", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" +} diff --git a/src/adaptors/goldlink/abis/reserve-abi.json b/src/adaptors/goldlink/abis/reserve-abi.json new file mode 100644 index 0000000000..6f84dc4b5e --- /dev/null +++ b/src/adaptors/goldlink/abis/reserve-abi.json @@ -0,0 +1,56 @@ +{ + "model_": { + "type": "function", + "name": "model_", + "inputs": [], + "outputs": [ + { + "name": "optimalUtilization", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "baseInterestRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rateSlope1", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "rateSlope2", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + "utilizedAssets_": { + "type": "function", + "name": "utilizedAssets_", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + "reserveBalance_": { + "type": "function", + "name": "reserveBalance_", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + } +} diff --git a/src/adaptors/goldlink/index.ts b/src/adaptors/goldlink/index.ts new file mode 100644 index 0000000000..ceae97591a --- /dev/null +++ b/src/adaptors/goldlink/index.ts @@ -0,0 +1,82 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const reserveAbi = require('./abis/reserve-abi.json'); +const bankAbi = require('./abis/bank-abi.json'); + +const arbitrumReserveAddress = '0xd8dD54dF1A7d2EA022B983756d8a481Eea2a382a'; +const arbitrumBankAddress = '0x479889160FEECe9C0fB0FDDF3b45312f54D719CC'; + +const arbAddress = '0x912CE59144191C1204E64559FE8253a0e49E6548'; + +const BONUS = 0.2; + +async function getInterestRate() { + const [model, balance, utilizedAssets, insurancePremium] = await Promise.all([ + sdk.api.abi.call({ + target: arbitrumReserveAddress, + abi: reserveAbi['model_'], + chain: 'arbitrum', + }), + sdk.api.abi.call({ + target: arbitrumReserveAddress, + abi: reserveAbi['reserveBalance_'], + chain: 'arbitrum', + }), + sdk.api.abi.call({ + target: arbitrumReserveAddress, + abi: reserveAbi['utilizedAssets_'], + chain: 'arbitrum', + }), + sdk.api.abi.call({ + target: arbitrumBankAddress, + abi: bankAbi, + chain: 'arbitrum', + }), + ]); + + const utilized = parseInt(utilizedAssets.output); + const insuranceHaircut = parseInt(insurancePremium.output) / 1e18; + console.log(insuranceHaircut); + + const [optimalUtilization, baseInterestRate, rateSlope1, rateSlope2] = [ + parseInt(model.output.optimalUtilization) / 1e18, + parseInt(model.output.baseInterestRate) / 1e18, + parseInt(model.output.rateSlope1) / 1e18, + parseInt(model.output.rateSlope2) / 1e18, + ]; + + const total = parseInt(balance.output) + utilized; + const utilization = utilized / total; + + const utilizationAboveOptimal = + utilization > optimalUtilization ? utilization - optimalUtilization : 0; + const utilizationBelowOptimal = utilization - utilizationAboveOptimal; + + const rateBelowOptimal = utilizationBelowOptimal * rateSlope1; + const rateAboveOptimal = utilizationAboveOptimal * rateSlope2; + + return { + pool: arbitrumReserveAddress, + chain: 'arbitrum', + project: 'goldlink', + symbol: utils.formatSymbol('USDC'), + tvlUsd: total / 1e6, + apyBase: + (baseInterestRate + rateBelowOptimal + rateAboveOptimal) * + 100 * + (1 - insuranceHaircut), + apyReward: BONUS * 100, + rewardTokens: ['0xaf88d065e77c8cC2239327C5EDb3A432268e5831', arbAddress], + underlyingTokens: ['0xaf88d065e77c8cC2239327C5EDb3A432268e5831'], + }; +} + +async function getPools() { + return [await getInterestRate()]; +} + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.goldlink.io', +}; diff --git a/src/adaptors/goledo/abis/lp.json b/src/adaptors/goledo/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/goledo/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/goledo/abis/masterchef.json b/src/adaptors/goledo/abis/masterchef.json new file mode 100644 index 0000000000..154f6a3036 --- /dev/null +++ b/src/adaptors/goledo/abis/masterchef.json @@ -0,0 +1,596 @@ +[ + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + }, + { + "internalType": "address", + "name": "_poolConfigurator", + "type": "address" + }, + { + "internalType": "contract IMultiFeeDistribution", + "name": "_rewardMinter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxMintable", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_allocPoints", + "type": "uint256[]" + } + ], + "name": "batchUpdateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimReceiver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + } + ], + "name": "claimableReward", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "emissionSchedule", + "outputs": [ + { + "internalType": "uint128", + "name": "startTimeOffset", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardsPerSecond", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxMintableTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintedTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolConfigurator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardPerShare", + "type": "uint256" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "onwardIncentives", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "registeredTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardMinter", + "outputs": [ + { + "internalType": "contract IMultiFeeDistribution", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "setClaimReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "_incentives", + "type": "address" + } + ], + "name": "setOnwardIncentives", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + } + ], + "name": "updateNextEmissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userBaseClaimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/goledo/index.js b/src/adaptors/goledo/index.js new file mode 100644 index 0000000000..a292544338 --- /dev/null +++ b/src/adaptors/goledo/index.js @@ -0,0 +1,246 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const GOL_TOKEN = '0xa4B59aA3De2af57959C23E2c9c89a2fCB408Ce6A'; +const MASTERCHEF_ADDRESS = '0x80161779e4d5ecbc33918ca37f7f263ddc480017'; +const CONFLUX_BLOCK_TIME = 1; +const BLOCKS_PER_YEAR = Math.floor((60 / CONFLUX_BLOCK_TIME) * 60 * 24 * 365); + +const getBaseTokensPrice = async () => { + const priceKeys = ['goledo', 'conflux-token'] + .map((t) => `coingecko:${t}`) + .join(','); + + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const golPrice = prices['coingecko:goledo'].price; + const cfxPrice = prices['coingecko:conflux-token'].price; + + return { cfxPrice, golPrice }; +}; + +const getPairInfo = async (pair, tokenAddress) => { + const tokenDecimals0 = await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: tokenAddress[0], + chain: 'conflux', + requery: true, + }); + + const tokenDecimals1 = await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: tokenAddress[1], + chain: 'conflux', + requery: true, + }); + + const tokenDecimals = [tokenDecimals0.output, tokenDecimals1.output]; + + const tokenSymbol0 = await sdk.api.abi.call({ + abi: 'erc20:symbol', + target: tokenAddress[0], + chain: 'conflux', + requery: true, + }); + + const tokenSymbol1 = await sdk.api.abi.call({ + abi: 'erc20:symbol', + target: tokenAddress[1], + chain: 'conflux', + requery: true, + }); + + const tokenSymbol = [tokenSymbol0.output, tokenSymbol1.output]; + + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol[0], + decimals: tokenDecimals[0], + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol[1], + decimals: tokenDecimals[1], + }, + }; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + GOLPerBlock, + GOLPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const GOLPerYear = BLOCKS_PER_YEAR * GOLPerBlock; + return ((poolWeight * GOLPerYear * GOLPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[0]; + const token1Price = tokenPrices[1]; + + const reserve0 = new BigNumber(reserves[0]._reserve0).times(reservesRatio); + const reserve1 = new BigNumber(reserves[0]._reserve1).times(reservesRatio); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const GOLPerSecond = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'rewardsPerSecond'), + }); + const normalizedGOLPerBlock = + (GOLPerSecond.output / 1e18) * CONFLUX_BLOCK_TIME; + + const poolsRes0 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + requery: true, + }); + + const poolsRes = [poolsRes0]; + + const pools = poolsRes; + const lpTokens = ['0x93d4be3c0b11fe52818cd96a5686db1e21d749ce']; + + const masterChefBalancesRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + + const masterChefBalancesRes = [masterChefBalancesRes0.output]; + + const supplyRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + requery: true, + }); + + const supplyRes = [supplyRes0.output]; + + const reservesRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + requery: true, + }); + + const reservesRes = [reservesRes0.output]; + + const underlyingToken00 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + requery: true, + }); + + const underlyingToken0 = [underlyingToken00.output]; + + const underlyingToken10 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0x93d4be3c0b11fe52818cd96a5686db1e21d749ce', + chain: 'conflux', + requery: true, + }); + + const underlyingToken1 = [underlyingToken10.output]; + + const { cfxPrice, golPrice } = await getBaseTokensPrice(); + + const reservesData = reservesRes; + const supplyData = supplyRes; + const masterChefBalData = masterChefBalancesRes; + const tokens0 = underlyingToken0; + const tokens1 = underlyingToken1; + + const tokensPrices = [cfxPrice, golPrice]; + + const pairInfos = await getPairInfo(lpTokens[0], [tokens0[0], tokens1[0]]); + + const poolsApy = []; + + const pairInfo = pairInfos; + + const poolInfo = pools[0].output; + + const reserves = reservesData; + + const supply = supplyData; + + const masterChefBalance = masterChefBalData; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedGOLPerBlock, + tokensPrices[1], + masterChefReservesUsd + ); + + poolsApy.push({ + pool: lpTokens[0], + chain: utils.formatChain('conflux'), + project: 'goledo', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward: apy, + underlyingTokens: [tokens0[0], tokens1[0]], + rewardTokens: [GOL_TOKEN], + }); + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.goledo.cash/', +}; diff --git a/src/adaptors/goose-finance/abis/lp.json b/src/adaptors/goose-finance/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/goose-finance/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/goose-finance/abis/masterchef.json b/src/adaptors/goose-finance/abis/masterchef.json new file mode 100644 index 0000000000..d96860470f --- /dev/null +++ b/src/adaptors/goose-finance/abis/masterchef.json @@ -0,0 +1,544 @@ +[ + { + "inputs": [ + { + "internalType": "contract EggToken", + "name": "_egg", + "type": "address" + }, + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_eggPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + } + ], + "name": "dev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devaddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "egg", + "outputs": [ + { + "internalType": "contract EggToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eggPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingEgg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accEggPerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeAddress", + "type": "address" + } + ], + "name": "setFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eggPerBlock", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/goose-finance/index.js b/src/adaptors/goose-finance/index.js new file mode 100644 index 0000000000..983129f513 --- /dev/null +++ b/src/adaptors/goose-finance/index.js @@ -0,0 +1,217 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const EGG_TOKEN = '0xf952fc3ca7325cc27d15885d37117676d25bfda6'; +const MASTERCHEF_ADDRESS = '0xe70E9185F5ea7Ba3C5d63705784D8563017f2E57'; +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = Math.floor((60 / BSC_BLOCK_TIME) * 60 * 24 * 365); + +const getPairInfo = async (pair, tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + EGGPerBlock, + EGGPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const EGGPerYear = BLOCKS_PER_YEAR * EGGPerBlock; + return ((poolWeight * EGGPerYear * EGGPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const EGGPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'eggPerBlock'), + }); + const normalizedEGGPerBlock = EGGPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter((k) => k.lpToken !== '0xB8157e2506238b06f2d1f3030593f3d620B90a16'); + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + const poolsApy = []; + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedEGGPerBlock, + tokensPrices[EGG_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + poolsApy.push({ + pool: pool.lpToken, + chain: utils.formatChain('binance'), + project: 'goose-finance', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward: apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [EGG_TOKEN], + }); + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://mixswap.finance/', +}; diff --git a/src/adaptors/granary-finance/index.js b/src/adaptors/granary-finance/index.js new file mode 100644 index 0000000000..d7915d215c --- /dev/null +++ b/src/adaptors/granary-finance/index.js @@ -0,0 +1,82 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const subgraphs = { + fantom: sdk.graph.modifyEndpoint( + '2Hjpy81pbiD8V8pTGHfRCFmb5Gsj2CfFRjJjcdGUZK3q' + ), + optimism: sdk.graph.modifyEndpoint( + '7MwUKrqGbDz7voH87MgwLZ9hq1WLJVgK5fHt8NtKeas4' + ), +}; + +const query = gql` + { + reserves { + id + symbol + decimals + liquidityRate + availableLiquidity + price { + priceInEth + } + isActive + underlyingAsset + variableBorrowRate + baseLTVasCollateral + totalDeposits + totalLiquidity + totalCurrentVariableDebt + } + } +`; + +const main = async () => { + const pools = await Promise.all( + Object.keys(subgraphs).map(async (chainString) => { + const data = ( + await request(subgraphs[chainString], query) + ).reserves.filter((p) => p.isActive); + + return data.map((p) => { + tvlUsd = + ((Number(p.availableLiquidity) / `1e${p.decimals}`) * + Number(p.price.priceInEth)) / + 1e8; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'granary-finance', + symbol: utils.formatSymbol(p.symbol), + tvlUsd, + apyBase: Number(p.liquidityRate) / 1e25, + underlyingTokens: [p.underlyingAsset], + apyBaseBorrow: p.variableBorrowRate / 1e25, + apyRewardBorrow: 0, + totalSupplyUsd: + ((Number(p.totalDeposits) / `1e${p.decimals}`) * + Number(p.price.priceInEth)) / + 1e8, + totalBorrowUsd: + ((Number(p.totalCurrentVariableDebt) / `1e${p.decimals}`) * + Number(p.price.priceInEth)) / + 1e8, + ltv: p.baseLTVasCollateral / 10000, + }; + }); + }) + ); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://granary.finance/markets/', +}; diff --git a/src/adaptors/gravita-protocol/index.js b/src/adaptors/gravita-protocol/index.js new file mode 100644 index 0000000000..540634a3ef --- /dev/null +++ b/src/adaptors/gravita-protocol/index.js @@ -0,0 +1,219 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const VESSEL_MANAGER_ADDRESS = '0xdB5DAcB1DFbe16326C3656a88017f0cB4ece0977'; +const ADMIN_CONTRACT_ADDRESS = '0xf7Cc67326F9A1D057c1e4b110eF6c680B13a1f53'; +const GRAI_ADDRESS = '0x15f74458aE0bFdAA1a96CA1aa779D715Cc1Eefe4'; + +const utils = require('../utils'); +// const URL = 'https://api.instadapp.io/defi/mainnet/liquity/trove-types'; + +const ABIS = { + getBorrowingFee: { + inputs: [ + { + internalType: 'address', + name: '_collateral', + type: 'address', + }, + ], + name: 'getBorrowingFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getEntireSystemColl: { + inputs: [ + { + internalType: 'address', + name: '_asset', + type: 'address', + }, + ], + name: 'getEntireSystemColl', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemColl', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getEntireSystemDebt: { + inputs: [ + { + internalType: 'address', + name: '_asset', + type: 'address', + }, + ], + name: 'getEntireSystemDebt', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemDebt', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [ + { + internalType: 'address', + name: '_collateral', + type: 'address', + }, + ], + name: 'getMcr', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getMintCap: { + inputs: [ + { + internalType: 'address', + name: '_collateral', + type: 'address', + }, + ], + name: 'getMintCap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + + getValidCollateral: { + inputs: [], + name: 'getValidCollateral', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getSymbol: { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const fetchAbiData = async (target, abi, params = []) => { + const result = await sdk.api.abi.call({ + target, + abi, + params, + chain: 'ethereum', + }); + return result.output; +}; + +async function fetchPrice(token) { + const key = `ethereum:${token}`.toLowerCase(); + const response = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + return response[key]?.price; +} + +const main = async () => { + // Fetch an array of valid collaterals + const collaterals = await fetchAbiData( + ADMIN_CONTRACT_ADDRESS, + ABIS.getValidCollateral + ); + const graiPrice = await fetchPrice(GRAI_ADDRESS); + // console.log('\nCollaterals:\n', collaterals); + // console.log(`GRAI price -> ${graiPrice}`); + + const pools = await Promise.all( + collaterals.map(async (collateral) => { + const [ + symbol, + assetPrice, + vesselAssetTvl, + mintedGrai, + mintCap, + mcr, + borrowingFee, + ] = await Promise.all([ + fetchAbiData(collateral, ABIS.getSymbol), + fetchPrice(collateral), + fetchAbiData(VESSEL_MANAGER_ADDRESS, ABIS.getEntireSystemColl, [ + collateral, + ]), + fetchAbiData(VESSEL_MANAGER_ADDRESS, ABIS.getEntireSystemDebt, [ + collateral, + ]), + fetchAbiData(ADMIN_CONTRACT_ADDRESS, ABIS.getMintCap, [collateral]), + fetchAbiData(ADMIN_CONTRACT_ADDRESS, ABIS.getMCR, [collateral]), + fetchAbiData(ADMIN_CONTRACT_ADDRESS, ABIS.getBorrowingFee, [ + collateral, + ]), + ]); + + /* + console.log(`ERC20.getSymbol() -> ${symbol}`); + console.log(`${symbol} ERC20.price() -> ${assetPrice}`); + console.log(`${symbol} VesselManager.getEntireSystemColl() -> ${vesselAssetTvl}`); + console.log(`${symbol} VesselManager.getEntireSystemDebt() -> ${mintedGrai}`); + console.log(`${symbol} AdminContract.getMCR() -> ${mcr}`); + console.log(`${symbol} AdminContract.getBorrowingFee() -> ${borrowingFee}`); */ + + const totalSupplyUsd = (vesselAssetTvl * assetPrice) / 1e18; + const totalBorrowUsd = (mintedGrai * graiPrice) / 1e18; + return { + pool: `Gravita-${symbol}-Vault`, + chain: 'ethereum', + project: 'gravita-protocol', + symbol: symbol, + mintedCoin: 'GRAI', + apy: 0, + tvlUsd: totalSupplyUsd, + underlyingTokens: [collateral], + // optional lending protocol specific fields: + apyBaseBorrow: borrowingFee / 1e16, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + debtCeilingUsd: (mintCap * graiPrice) / 1e18, + ltv: 1 / (mcr / 1e18), // btw [0, 1] + }; + }) + ); + + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.gravitaprotocol.com/', +}; diff --git a/src/adaptors/green-planet/abi.js b/src/adaptors/green-planet/abi.js new file mode 100755 index 0000000000..1ed0cf1db6 --- /dev/null +++ b/src/adaptors/green-planet/abi.js @@ -0,0 +1,1109 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_vault', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'prev', type: 'bool' }, + { indexed: false, internalType: 'bool', name: 'curr', type: 'bool' }, + ], + name: 'AuthorizationToClaimToggled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'gammaDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'gammaBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerGamma', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'gammaDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'gammaSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierGamma', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBoost', + type: 'uint256', + }, + ], + name: 'GammaBoostUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'GammaGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'GammaSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'gToken', + type: 'address', + }, + ], + name: 'MarketBoostDeprecated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newReservoirAddress', + type: 'address', + }, + ], + name: 'ReservoirUpdated', + type: 'event', + }, + { + inputs: [ + { + internalType: 'contract UnitrollerInterface', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'gToken', type: 'address' }], + name: '_deprecateBoostMarket', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantGamma', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface[]', + name: 'gTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'gammaSpeeds', type: 'uint256[]' }, + ], + name: '_setGammaSpeeds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface[]', + name: 'gTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract PriceOracleInterface', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_stakeToVault', type: 'bool' }], + name: '_setStakeGammaToVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newInfinityVaultAddress', + type: 'address', + }, + ], + name: '_updateGammaInfinityVaultAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newInfinityVaultAddress', + type: 'address', + }, + { internalType: 'address', name: '_newiGammaAddress', type: 'address' }, + ], + name: '_updateGammaInfinityVaultAddressAndiGammaAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newReservoirAddress', + type: 'address', + }, + ], + name: '_updateReservoirAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [ + { internalType: 'contract GTokenInterface', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allBoostedMarkets', + outputs: [ + { internalType: 'contract GTokenInterface', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [ + { internalType: 'contract GTokenInterface', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'authorizedToClaim', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract GTokenInterface[]', + name: 'suppliedgTokens', + type: 'address[]', + }, + { + internalType: 'contract GTokenInterface[]', + name: 'borrowedgTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrower', type: 'bool' }, + { internalType: 'bool', name: 'supplier', type: 'bool' }, + ], + name: 'claimGamma', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract GTokenInterface[]', + name: 'gTokens', + type: 'address[]', + }, + ], + name: 'claimGamma', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimGamma', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract GTokenInterface[]', + name: 'gTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimGamma', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address[]', name: 'gTokens', type: 'address[]' }], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'gammaAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'gammaBoostPercentage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'gammaBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint224', name: 'boostIndex', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'gammaBorrowerBoostIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'gammaBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'gammaInfinityVaultAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'gammaInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'gammaSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'gammaSupplierBoostIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'gammaSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'gammaSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint224', name: 'boostIndex', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllBoostedMarkets', + outputs: [ + { + internalType: 'contract GTokenInterface[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllMarkets', + outputs: [ + { + internalType: 'contract GTokenInterface[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { + internalType: 'contract GTokenInterface[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'market', type: 'address' }], + name: 'getGammaBoostPercentage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'market', type: 'address' }], + name: 'getGammaSpeed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'gTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getOracle', + outputs: [ + { + internalType: 'contract PriceOracleInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface', + name: 'gToken', + type: 'address', + }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isGammatroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'gTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'gTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracle', + outputs: [ + { + internalType: 'contract PriceOracleInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingGammatrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'reservoirAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'gTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GTokenInterface[]', + name: 'gTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'gammaBoosts', type: 'uint256[]' }, + ], + name: 'setGammaBoost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stakeGammaToVault', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_vault', type: 'address' }], + name: 'updateAuthorizedToClaimAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_newiGammaBalance', type: 'uint256' }, + ], + name: 'updateFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/green-planet/abiToken.js b/src/adaptors/green-planet/abiToken.js new file mode 100644 index 0000000000..7e527d5626 --- /dev/null +++ b/src/adaptors/green-planet/abiToken.js @@ -0,0 +1,1096 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { inputs: [], name: 'AcceptAdminPendingAdminCheck', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'actualAddAmount', type: 'uint256' }, + ], + name: 'AddReservesFactorFreshCheck', + type: 'error', + }, + { inputs: [], name: 'BorrowCashNotAvailable', type: 'error' }, + { inputs: [], name: 'BorrowFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'BorrowGammatrollerRejection', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateAccrueBorrowInterestFailed', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateAccrueCollateralInterestFailed', + type: 'error', + }, + { inputs: [], name: 'LiquidateCloseAmountIsUintMax', type: 'error' }, + { inputs: [], name: 'LiquidateCloseAmountIsZero', type: 'error' }, + { inputs: [], name: 'LiquidateCollateralFreshnessCheck', type: 'error' }, + { inputs: [], name: 'LiquidateFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'LiquidateLiquidatorIsBorrower', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateRepayBorrowFreshFailed', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateSeizeGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'LiquidateSeizeLiquidatorIsBorrower', type: 'error' }, + { inputs: [], name: 'MintFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'MintGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'RedeemFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'RedeemGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'RedeemTransferOutNotPossible', type: 'error' }, + { inputs: [], name: 'ReduceReservesAdminCheck', type: 'error' }, + { inputs: [], name: 'ReduceReservesCashNotAvailable', type: 'error' }, + { inputs: [], name: 'ReduceReservesCashValidation', type: 'error' }, + { inputs: [], name: 'ReduceReservesFreshCheck', type: 'error' }, + { inputs: [], name: 'RepayBorrowFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'RepayBorrowGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'SetDiscountLevelAdminCheck', type: 'error' }, + { inputs: [], name: 'SetGammatrollerOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetInterestRateModelFreshCheck', type: 'error' }, + { inputs: [], name: 'SetInterestRateModelOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetPendingAdminOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorAdminCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorBoundsCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorFreshCheck', type: 'error' }, + { inputs: [], name: 'SetWithdrawFeeFactorBoundsCheck', type: 'error' }, + { inputs: [], name: 'SetWithdrawFeeFactorFreshCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'TransferGammatrollerRejection', + type: 'error', + }, + { inputs: [], name: 'TransferNotAllowed', type: 'error' }, + { inputs: [], name: 'TransferNotEnough', type: 'error' }, + { inputs: [], name: 'TransferTooMuch', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'gTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PlanetDiscount', + name: 'oldDiscountLevel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PlanetDiscount', + name: 'newDiscountLevel', + type: 'address', + }, + ], + name: 'NewDiscountLevel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract GammatrollerInterface', + name: 'oldGammatroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract GammatrollerInterface', + name: 'newGammatroller', + type: 'address', + }, + ], + name: 'NewGammatroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_newiGammaAddress', + type: 'address', + }, + ], + name: 'iGammaAddressUpdated', + type: 'event', + }, + { + inputs: [], + name: 'NO_ERROR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'gammaLikeDelegatee', type: 'address' }, + ], + name: '_delegateGammaLikeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_resignImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newDiscountLevel', type: 'address' }, + ], + name: '_setDiscountLevel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract GammatrollerInterface', + name: 'newGammatroller', + type: 'address', + }, + ], + name: '_setGammatroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newiGammaAddress', type: 'address' }, + ], + name: '_updateiGammaAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'deprecateBoost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'discountLevel', + outputs: [ + { internalType: 'contract PlanetDiscount', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'gammatroller', + outputs: [ + { + internalType: 'contract GammatrollerInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getBoostDeprecatedStatus', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getMarketData', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAndAverageBoost', + outputs: [ + { internalType: 'uint256', name: 'userBoostAPR', type: 'uint256' }, + { internalType: 'uint256', name: 'averageBoostAPR', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserData', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'iGamma', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'interestRateModel', + outputs: [ + { internalType: 'contract InterestRateModel', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isBoostDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isGToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract GTokenInterface', + name: 'gTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'updateDiscountForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'iGammaBalanceOfUser', type: 'uint256' }, + ], + name: 'updateUserAndTotalFactors', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'updateUserDiscount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/green-planet/index.js b/src/adaptors/green-planet/index.js new file mode 100755 index 0000000000..e4e0f34942 --- /dev/null +++ b/src/adaptors/green-planet/index.js @@ -0,0 +1,191 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.js'); +const abiToken = require('./abiToken.js'); +const utils = require('../utils.js'); + +const gammatrollerAddress = '0x1e0c9d09f9995b95ec4175aaa18b49f49f6165a3'; +const GAMMA = '0xb3cb6d2f8f2fde203a022201c81a96c167607f15'; + +const blocksPerDay = 28800; +const daysPerYear = 365; + +const apy = async () => { + const markets = ( + await sdk.api.abi.call({ + target: gammatrollerAddress, + abi: abi.find((m) => m.name === 'getAllMarkets'), + chain: 'bsc', + }) + ).output; + + const metadata = ( + await sdk.api.abi.multiCall({ + abi: abi.find((i) => i.name === 'markets'), + calls: markets.map((m) => ({ + target: gammatrollerAddress, + params: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const gammaSpeeds = ( + await sdk.api.abi.multiCall({ + abi: abi.find((i) => i.name === 'gammaSpeeds'), + calls: markets.map((m) => ({ + target: gammatrollerAddress, + params: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'totalSupply'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const totalBorrows = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'totalBorrows'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const exchangeRateStored = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'exchangeRateStored'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const supplyRatePerBlock = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'supplyRatePerBlock'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const borrowRatePerBlock = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'borrowRatePerBlock'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const underlying = ( + await sdk.api.abi.multiCall({ + abi: abiToken.find((i) => i.name === 'underlying'), + calls: markets.map((m) => ({ + target: m, + })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: underlying.map((m) => ({ + target: m, + })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const priceKeys = [...underlying, GAMMA].map((t) => `bsc:${t}`).join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + const gammaPriceUSD = prices[`bsc:${GAMMA}`].price; + + const pools = markets.map((m, i) => { + const price = prices[`bsc:${underlying[i]}`]?.price; + + const totalSupplyUsd = + (((totalSupply[i] / 1e18) * exchangeRateStored[i]) / 1e18) * price; + + const totalBorrowUsd = (totalBorrows[i] / 1e18) * price; + + const apyBase = + (Math.pow( + (supplyRatePerBlock[i] / 1e18) * blocksPerDay + 1, + daysPerYear + ) - + 1) * + 100; + + const apyBaseBorrow = + (Math.pow( + (borrowRatePerBlock[i] / 1e18) * blocksPerDay + 1, + daysPerYear + ) - + 1) * + 100; + + const gammaPerDay = (gammaSpeeds[i] / 1e18) * blocksPerDay; + + const apyReward = + 100 * + (Math.pow( + 1 + (gammaPriceUSD * gammaPerDay) / totalSupplyUsd, + daysPerYear + ) - + 1); + + const apyRewardBorrow = + 100 * + (Math.pow( + 1 + (gammaPriceUSD * gammaPerDay) / totalBorrowUsd, + daysPerYear + ) - + 1); + + return { + pool: m.toLowerCase(), + chain: 'BSC', + project: 'green-planet', + symbol: symbol[i], + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase, + apyReward, + rewardTokens: + apyReward > 0 ? ['0xb3cb6d2f8f2fde203a022201c81a96c167607f15'] : [], + underlyingTokens: [underlying[i]], + // borrow fields + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv: metadata[i].collateralFactorMantissa / 1e18, + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, + url: 'https://app.planet.finance/lending', +}; diff --git a/src/adaptors/grizzlyfi-hives/abis/lp.json b/src/adaptors/grizzlyfi-hives/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/grizzlyfi-hives/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/grizzlyfi-hives/index.js b/src/adaptors/grizzlyfi-hives/index.js new file mode 100644 index 0000000000..6dbb8f53c2 --- /dev/null +++ b/src/adaptors/grizzlyfi-hives/index.js @@ -0,0 +1,610 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const GHNY = '0xa045e37a0d1dd3a45fefb8803d22457abc0a728a'; +const APY_URL = 'https://api.grizzly.fi/apy/current/bsc'; +const lpABI = require('./abis/lp.json'); + +const abi = { + inputs: [], + name: 'grizzlyStrategyDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const abiGrizzly = { + inputs: [], + name: 'grizzlyStrategyDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; +const abiStandard = { + inputs: [], + name: 'standardStrategyDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; +const abiStable = { + inputs: [], + name: 'stablecoinStrategyDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; +const abiFarm = { + inputs: [], + name: 'totalDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; +const abiYearn = { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; +const abiPcsV3 = { + inputs: [], + name: 'getUnderlyingBalances', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', +}; + +const tokenLpApi = (method) => { + return { + constant: true, + inputs: [], + name: method, + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }; +}; + +const stableTokenLpCoinApi = () => { + return { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'coins', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }; +}; + +const stableTokenLpBalancesApi = () => { + return { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'balances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; +}; + +const pcsHives = [ + // PCS hives + { + hive: '0xDa0Ae0710b080AC64e72Fa3eC44203F27750F801', + token: '0x58F876857a02D6762E0101bb5C46A8c1ED44Dc16', + name: 'Pancakeswap', + }, + { + hive: '0x8D83Ad61Ae6eDE4274876EE9ad9127843ba2AbF7', + token: '0xEc6557348085Aa57C72514D67070dC863C0a5A8c', + name: 'Pancakeswap', + }, + { + hive: '0xE4Dbb05498C42A6E780e4C6F96A4E20a7D7Cb1d6', + token: '0x7EFaEf62fDdCCa950418312c6C91Aef321375A00', + name: 'Pancakeswap', + }, + { + hive: '0x66B1bACAB888017cA96abBf28ad8d10B7A7B5eC3', + token: '0x2354ef4DF11afacb85a5C7f98B624072ECcddbB1', + name: 'Pancakeswap', + }, + { + hive: '0x9F45E2181D365F9057f67153e6D213e2358A5A4B', + token: '0x66FDB2eCCfB58cF098eaa419e5EfDe841368e489', + name: 'Pancakeswap', + }, + { + hive: '0x3cbF1d01A650e9DB566A123E3D5e42B9684C6b6a', + token: '0xEa26B78255Df2bBC31C1eBf60010D78670185bD0', + name: 'Pancakeswap', + }, + { + hive: '0x6fc2FEed99A97105B988657f9917B771CD809f40', + token: '0xF45cd219aEF8618A92BAa7aD848364a158a24F33', + name: 'Pancakeswap', + }, + // Biswap hives + { + hive: '0x0286A72F055A425af9096b187bf7f88e9f7D96A9', + token: '0x8840C6252e2e86e545deFb6da98B2a0E26d8C1BA', + name: 'Biswap', + }, + { + hive: '0xB07a180735657a92d8e2b77D213bCBE5ab819089', + token: '0xa987f0b7098585c735cD943ee07544a84e923d1D', + name: 'Biswap', + }, + { + hive: '0xe178eaDBcb4A64476B8E4673D99192C25ef1B42e', + token: '0x63b30de1A998e9E64FD58A21F68D323B9BcD8F85', + name: 'Biswap', + }, +]; + +const farms = [ + { + hive: '0x3641676bFe07F07DD2f79244BcdBb751f95F67Ca', + token: '0x2b702b4e676b51f98c6b4af1b2cafd6a9fc2a3e0', + name: 'Farm', + }, + { + hive: '0xF530B259fFf408aaB2B02aa60dd6fe48FCDC2FC9', + token: '0x352008bf4319c3b7b8794f1c2115b9aa18259ebb', + name: 'Farm', + }, +]; + +const stableHives = [ + { + hive: '0x7Bf5005F9a427cB4a3274bFCf36125cE979F77cb', + token: '0x36842f8fb99d55477c0da638af5ceb6bbf86aa98', + swap: '0x169f653a54acd441ab34b73da9946e2c451787ef', + name: 'V2-Stable', + }, + { + hive: '0x7E5762A7D68Fabcba39349229014c59Db6dc5eB0', + token: '0xee1bcc9f1692e81a281b3a302a4b67890ba4be76', + swap: '0x3efebc418efb585248a0d2140cfb87afcc2c63dd', + name: 'V2-Stable', + }, + { + hive: '0xCCf6356C96Eadd2702fe6f5Ef99B1C0a3966EDf7', + token: '0x1a77c359d0019cd8f4d36b7cdf5a88043d801072', + swap: '0xc2f5b9a3d9138ab2b74d581fc11346219ebf43fe', + name: 'V2-Stable', + }, +]; + +const yearnHives = [ + // Thena hives + { + hive: '0x5Aa6dd6bA3091ba151B4E5c0C0c4f06335e91482', + token: '0xa97e46dc17e2b678e5f049a2670fae000b57f05e', + name: 'Thena', + } /* + { + hive: "0x38b2f5038F70b8A4a54A2CC8d35d85Cc5f0794e4", + token: "0xc8da40f8a354530f04ce2dde98ebc2960a9ea449", + name: "Thena" + },*/, + { + hive: '0x3dF96fE4E92f38F7C931fA5A00d1f644D1c60dbF', + token: '0x075e794f631ee81df1aadb510ac6ec8803b0fa35', + name: 'Thena', + }, + { + hive: '0x9Ce89aba449135539A61C57665547444a92784aB', + token: '0x3c552e8ac4473222e3d794adecfa432eace85929', + name: 'Thena', + }, + { + hive: '0xc750432473eABE034e84d373CB92f16e6EB0d273', + token: '0x3ec80a1f547ee6fd5d7fc0dc0c1525ff343d087c', + name: 'Thena', + }, + { + hive: '0xf01F9e8A5C6B9Db49e851e8d72B70569042F0e1C', + token: '0x63db6ba9e512186c2faadacef342fb4a40dc577c', + name: 'Thena', + }, + { + hive: '0xF7DE4A13669CB33D54b59f35FE71dFcD67e4635E', + token: '0x34b897289fccb43c048b2cea6405e840a129e021', + name: 'Thena', + }, +]; + +const pcsV3Hives = [ + { + hive: '0x25223015ee4dbaf9525ddd43797cae1dcd83f6b5', + name: 'Pancakeswap-V3', + }, + { + hive: '0x9eab3bf245da9b6d8705b1a906ee228382c38f93', + name: 'Pancakeswap-V3', + }, + { + hive: '0x76ab668d93135bcd64df8e4a7ab9dd05fac4cdbf', + name: 'Pancakeswap-V3', + }, +]; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + return reserve0.times(token0Price).plus(reserve1.times(token1Price)); +}; + +const getPairInfo = async (tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + return { + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +async function apy() { + const getHive = (i) => ({ target: i.hive }); + + const [ + hiveBalancesGrizzly, + hiveBalancesStandard, + hiveBalancesStable, + stableHiveBalancesGrizzly, + stableHiveBalancesStandard, + stableHiveBalancesStable, + farmBalances, + yearnBalances, + ] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: pcsHives.map(getHive), + abi: abiGrizzly, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: pcsHives.map(getHive), + abi: abiStandard, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: pcsHives.map(getHive), + abi: abiStable, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: stableHives.map(getHive), + abi: abiGrizzly, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: stableHives.map(getHive), + abi: abiStandard, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: stableHives.map(getHive), + abi: abiStable, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: farms.map(getHive), + abi: abiFarm, + chain: 'bsc', + }), + sdk.api.abi.multiCall({ + calls: yearnHives.map(getHive), + abi: abiYearn, + chain: 'bsc', + }), + ]); + + const [underlyingToken0Uni, underlyingToken1Uni] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: tokenLpApi(method), + calls: pcsHives + .concat(farms) + .concat(yearnHives) + .map(({ token }) => ({ + target: token, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [underlyingToken0V3, underlyingToken1V3] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: tokenLpApi(method), + calls: pcsV3Hives.map(({ hive }) => ({ + target: hive, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [underlyingToken0Stable, underlyingToken1Stable] = await Promise.all( + [0, 1].map((coin) => + sdk.api.abi.multiCall({ + abi: stableTokenLpCoinApi(), + calls: stableHives.map(({ swap }) => ({ + target: swap, + params: [coin], + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [reservesResUni, supplyResUni] = await Promise.all( + ['getReserves', 'totalSupply'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: pcsHives + .concat(farms) + .concat(yearnHives) + .map(({ token }) => ({ + target: token, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [reservesV3] = await Promise.all([ + sdk.api.abi.multiCall({ + abi: abiPcsV3, + calls: pcsV3Hives.map(({ hive }) => ({ + target: hive, + })), + chain: 'bsc', + requery: true, + }), + ]); + + const [reservesToken0Stable, reservesToken1Stable] = await Promise.all( + [0, 1].map((coin) => + sdk.api.abi.multiCall({ + abi: stableTokenLpBalancesApi(), + calls: stableHives.map(({ swap }) => ({ + target: swap, + params: [coin], + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const totalSupplyStable = await sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + calls: stableHives.map(({ token }) => ({ + target: token, + })), + chain: 'bsc', + requery: true, + }); + + const reserveDataUni = reservesResUni.output.map((res) => res.output); + const reserveDataV3 = reservesV3.output.map((res) => { + return { + _reserve0: res.output[0], + _reserve1: res.output[1], + }; + }); + const reserveDataStable0 = reservesToken0Stable.output.map( + (res) => res.output + ); + const reserveDataStable1 = reservesToken1Stable.output.map( + (res) => res.output + ); + + const reserveDataStable = reserveDataStable0.map((r0, i) => { + const r1 = reserveDataStable1[i]; + return { + _reserve0: r0, + _reserve1: r1, + }; + }); + + const reservesData = reserveDataUni + .concat(reserveDataV3) + .concat(reserveDataStable); + + const supplyDataUni = supplyResUni.output.map((res) => res.output); + const supplyDataV3 = pcsV3Hives.map(() => 1); + const supplyDataStable = totalSupplyStable.output.map((res) => res.output); + + const supplyData = supplyDataUni + .concat(supplyDataV3) + .concat(supplyDataStable); + + const hiveBalances = []; + + hiveBalances.push( + ...hiveBalancesGrizzly.output.map((grizzly, i) => { + const hbg = BigNumber(grizzly.output); + const hbStd = BigNumber(hiveBalancesStandard.output[i].output); + const hbStb = BigNumber(hiveBalancesStable.output[i].output); + + return hbg.plus(hbStd).plus(hbStb).toString(10); + }) + ); + + hiveBalances.push(...farmBalances.output.map((res) => res.output)); + hiveBalances.push(...yearnBalances.output.map((res) => res.output)); + + hiveBalances.push(...pcsV3Hives.map(() => 1)); + + hiveBalances.push( + ...stableHiveBalancesGrizzly.output.map((grizzly, i) => { + const hbg = BigNumber(grizzly.output); + const hbStd = BigNumber(stableHiveBalancesStandard.output[i].output); + const hbStb = BigNumber(stableHiveBalancesStable.output[i].output); + + return hbg.plus(hbStd).plus(hbStb).toString(10); + }) + ); + + const tokens0 = underlyingToken0Uni.output + .map((res) => res.output) + .concat(underlyingToken0V3.output.map((res) => res.output)) + .concat(underlyingToken0Stable.output.map((res) => res.output)); + const tokens1 = underlyingToken1Uni.output + .map((res) => res.output) + .concat(underlyingToken1V3.output.map((res) => res.output)) + .concat(underlyingToken1Stable.output.map((res) => res.output)); + + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + + const pairInfos = await Promise.all( + pcsHives + .concat(farms) + .concat(yearnHives) + .concat(pcsV3Hives) + .concat(stableHives) + .map((val, index) => getPairInfo([tokens0[index], tokens1[index]])) + ); + + const apyComputed = await utils.getData(APY_URL); + + const res = pcsHives + .concat(farms) + .concat(yearnHives) + .concat(pcsV3Hives) + .concat(stableHives) + .map((pool, i) => { + const pairInfo = pairInfos[i]; + const supply = supplyData[i]; + const reserves = reservesData[i]; + const masterChefBalance = hiveBalances[i]; + const fields = apyComputed.find( + (e) => e.point.toLowerCase() === pool.hive.toLowerCase() + ).fields; + + let baseAPY, rewardAPY; + + const grizzlyAPYHive = fields.find((f) => f.field == 'Grizzly-APY'); + if (grizzlyAPYHive != null) { + rewardAPY = grizzlyAPYHive.value; + baseAPY = fields.find((f) => f.field == 'LP-APR').value; + } else { + const farmApr = fields.find((f) => f.field == 'LP-APR'); + if (farmApr != null) { + rewardAPY = fields.find((f) => f.field == 'Base-APR').value; + baseAPY = farmApr.value; + } else { + const yearnHiveAPY = fields.find((f) => f.field == 'APY'); + if (yearnHiveAPY != null) { + baseAPY = yearnHiveAPY.value; + rewardAPY = 0; + } + } + } + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + return { + pool: pool.hive, + poolMeta: pool.name, + chain: utils.formatChain('binance'), + project: 'grizzlyfi-hives', + symbol: pairInfo.pairName, + tvlUsd: Number(masterChefReservesUsd), + apyBase: Number(baseAPY) * 100, + apyReward: Number(rewardAPY) * 100, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [GHNY], + }; + }); + + return res; +} + +module.exports = { + timetravel: false, + apy, + url: 'https://grizzly.fi/', +}; diff --git a/src/adaptors/growihf/index.js b/src/adaptors/growihf/index.js new file mode 100644 index 0000000000..b77c810cd4 --- /dev/null +++ b/src/adaptors/growihf/index.js @@ -0,0 +1,136 @@ +const https = require('https'); + +const VAULT_ADDRESS = '0x1e37a337ed460039d1b15bd3bc489de789768d5e'; +const API_URL = 'https://api.hyperliquid.xyz/info'; +const USDC_ADDRESS_ARBITRUM = '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8'; + +function fetchVaultDetails() { + return new Promise((resolve, reject) => { + const data = JSON.stringify({ + type: 'vaultDetails', + vaultAddress: VAULT_ADDRESS, + }); + + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(data), + }, + }; + + const req = https.request(API_URL, options, (res) => { + let body = ''; + res.on('data', (chunk) => (body += chunk)); + res.on('end', () => { + try { + const parsed = JSON.parse(body); + resolve(parsed); + } catch (err) { + reject('Failed to parse vaultDetails'); + } + }); + }); + + req.on('error', (err) => reject(err)); + req.write(data); + req.end(); + }); +} + +function computeAPYInception(vaultDetails) { + const portfolio = vaultDetails.portfolio.find((p) => p[0] === 'allTime'); + if (!portfolio) throw new Error('Missing allTime portfolio'); + + const accountValueHistory = portfolio[1].accountValueHistory; + const pnlHistory = portfolio[1].pnlHistory; + + if (accountValueHistory.length < 3 || pnlHistory.length < 3) + throw new Error('Not enough data points'); + + const timestamps = accountValueHistory.map(([t]) => t); + const values_tvl = accountValueHistory.map(([, v]) => parseFloat(v)); + const values_pnl = pnlHistory.map(([, v]) => parseFloat(v)); + + const deltaPNL = []; + + for (let i = 1; i < timestamps.length; i++) { + deltaPNL.push(values_pnl[i] - values_pnl[i - 1]); + } + + const twr = []; + for (let i = 0; i < deltaPNL.length; i++) { + twr.push(values_tvl[i] !== 0 ? deltaPNL[i] / values_tvl[i] : 0); + } + + const twr_acc = [1]; + for (let i = 0; i < twr.length; i++) { + twr_acc.push(twr_acc[i] * (1 + twr[i])); + } + + const days = (timestamps[timestamps.length - 1] - timestamps[0]) / 86400000; + const ann_yield = Math.pow(twr_acc[twr_acc.length - 1], 365 / days) - 1; + + const latestTVL = values_tvl[values_tvl.length - 1]; + return { + tvlUsd: latestTVL, + apyBaseInception: ann_yield, + } +} + +function computeAPY7Day(vaultDetails) { + let alltimeData = computeAPYInception(vaultDetails); + + const portfolio = vaultDetails.portfolio.find((p) => p[0] === 'week'); + if (!portfolio) throw new Error('Missing weekly portfolio'); + + const accountValueHistory = portfolio[1].accountValueHistory; + const pnlHistory = portfolio[1].pnlHistory; + + if (accountValueHistory.length < 3 || pnlHistory.length < 3) + throw new Error('Not enough data points'); + + const timestamps = accountValueHistory.map(([t]) => t); + const values_tvl = accountValueHistory.map(([, v]) => parseFloat(v)); + const values_pnl = pnlHistory.map(([, v]) => parseFloat(v)); + + const deltaPNL = []; + + for (let i = 1; i < timestamps.length; i++) { + deltaPNL.push(values_pnl[i] - values_pnl[i - 1]); + } + + const twr = []; + for (let i = 0; i < deltaPNL.length; i++) { + twr.push(values_tvl[i] !== 0 ? deltaPNL[i] / values_tvl[i] : 0); + } + + const twr_acc = [1]; + for (let i = 0; i < twr.length; i++) { + twr_acc.push(twr_acc[i] * (1 + twr[i])); + } + + const days = (timestamps[timestamps.length - 1] - timestamps[0]) / 86400000; + const ann_yield = Math.pow(twr_acc[twr_acc.length - 1], 365 / days) - 1; + + return { + pool: `growihf-vault-hyperliquid`, + chain: 'hyperliquid', + project: 'growihf', + symbol: 'USDC', + tvlUsd: alltimeData['tvlUsd'], + apy: ann_yield * 100, + apyBaseInception: alltimeData['apyBaseInception'] * 100, + underlyingTokens: [USDC_ADDRESS_ARBITRUM], + poolMeta: 'Hyperliquid Vault', + url: 'https://app.hf.growi.fi/', + }; +} + +module.exports = { + timetravel: false, + apy: async () => { + const vaultDetails = await fetchVaultDetails(); + return [computeAPY7Day(vaultDetails)]; + }, +}; diff --git a/src/adaptors/gt3/helpers.js b/src/adaptors/gt3/helpers.js new file mode 100644 index 0000000000..fa6e44b877 --- /dev/null +++ b/src/adaptors/gt3/helpers.js @@ -0,0 +1,237 @@ +// GT3 Finance specific utilities +const utils = require('../utils'); + +// Use superagent as fetch fallback if fetch is not available +let fetch; +try { + fetch = globalThis.fetch; +} catch (e) { + const superagent = require('superagent'); + fetch = async (url, options) => { + const response = await superagent + .post(url) + .set(options.headers) + .send(JSON.parse(options.body)); + return { + ok: response.status < 400, + status: response.status, + json: async () => response.body + }; + }; +} + +// API configuration +const GRAPHQL_ENDPOINT = 'https://backend.gt3.finance/graphql'; +const PROJECT_KEY = 'GT3'; + +const REQUEST_HEADERS = { + 'accept': '*/*', + 'content-type': 'application/json', + 'origin': 'https://dapp.gt3.finance', + 'referer': 'https://dapp.gt3.finance/', + 'x-project-key': PROJECT_KEY, + 'user-agent': 'Mozilla/5.0 (compatible; DeFiLlama/1.0)' +}; + +// Chain ID to chain name mapping for DeFiLlama +const CHAIN_MAPPING = { + 1: 'ethereum', + 56: 'binance', + 137: 'polygon', + 42161: 'arbitrum', + 10: 'optimism', + 8453: 'base', + 43114: 'avalanche', + 250: 'fantom', + 100: 'gnosis', + 324: 'era', + 59144: 'linea', + 534352: 'scroll' +}; + +/** + * Make GraphQL requests using fetch + * @param {Object} query - GraphQL query to execute + * @returns {Promise} - API response + */ +const makeGraphQLRequest = async (query) => { + try { + const response = await fetch(GRAPHQL_ENDPOINT, { + method: 'POST', + headers: REQUEST_HEADERS, + body: JSON.stringify([query]) + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + + if (!data || !Array.isArray(data) || data.length === 0) { + throw new Error('Invalid response format'); + } + + return data[0]; + } catch (error) { + console.error('Error making GraphQL request:', error); + throw new Error(`GraphQL request failed: ${error.message}`); + } +}; + +/** + * Get formatted chain name for DeFiLlama + * @param {number} chainID - Chain ID + * @returns {string} - Formatted chain name + */ +const getChainName = (chainID) => { + const chainKey = CHAIN_MAPPING[chainID]; + if (!chainKey) { + console.warn(`Unknown chainID: ${chainID}, defaulting to ethereum`); + return 'ethereum'; + } + return utils.formatChain(chainKey); +}; + +/** + * Calculate TVL in USD using shareTokenSupply data + * @param {Object} pool - Complete pool with shareTokenSupply + * @returns {number} - TVL in USD + */ +const calculateTVLFromPool = (pool) => { + if (!pool || !pool.shareTokenSupply || !pool.shareTokenSupply.currencyAmounts) { + return 0; + } + + try { + // Find USD value in shareTokenSupply + const usdAmount = pool.shareTokenSupply.currencyAmounts.find(ca => ca.currencyID === 'USD'); + if (usdAmount && usdAmount.number > 0) { + return usdAmount.number; + } + + // Fallback: use main shareTokenSupply number + return pool.shareTokenSupply.number || 0; + } catch (error) { + console.error('Error calculating TVL from pool:', error); + return 0; + } +}; + +/** + * Get all pools with automatic pagination + * @param {Function} createPoolStatsQuery - Function to create pool query + * @returns {Promise} - Complete list of pools + */ +const getAllPools = async (createPoolStatsQuery) => { + let allPools = []; + let offset = 0; + const limit = 100; + let hasMore = true; + + while (hasMore) { + try { + const query = createPoolStatsQuery(offset, limit); + const response = await makeGraphQLRequest(query); + + if (response.data.getPoolStats.__typename === 'SimpleError') { + throw new Error(response.data.getPoolStats.description); + } + + const pools = response.data.getPoolStats.items || []; + const metadata = response.data.getPoolStats.metadata; + + allPools = allPools.concat(pools); + + // Check if there are more pools + hasMore = pools.length === limit && offset + limit < metadata.numElements; + offset += limit; + + } catch (error) { + console.error(`Error fetching pools at offset ${offset}:`, error); + break; + } + } + + return allPools; +}; + +/** + * Get underlying tokens from a pool configuration + * @param {Object} poolConfig - Pool configuration + * @param {Array} addresses - Token ID to address mapping + * @returns {Array} - List of token addresses + */ +const getUnderlyingTokens = (poolConfig, addresses) => { + if (!poolConfig || !poolConfig.tokens || !Array.isArray(poolConfig.tokens)) { + return []; + } + + return poolConfig.tokens + .map(tokenId => { + const addressInfo = addresses.find(addr => addr.tokenID === tokenId); + return addressInfo ? addressInfo.address.toLowerCase() : null; + }) + .filter(address => address !== null); +}; + +/** + * Get reward tokens if they exist + * @param {Object} poolStats - Pool statistics + * @param {Array} gauges - Gauge configuration list + * @param {Array} addresses - Token ID to address mapping + * @returns {Array} - List of reward token addresses + */ +const getRewardTokens = (poolStats, gauges, addresses) => { + if (!gauges || !Array.isArray(gauges)) { + return []; + } + + const poolGauges = gauges.filter(gauge => gauge.poolID === poolStats.shareTokenID); + + return poolGauges + .map(gauge => { + const addressInfo = addresses.find(addr => addr.tokenID === gauge.rewardTokenID); + return addressInfo ? addressInfo.address.toLowerCase() : null; + }) + .filter(address => address !== null); +}; + +/** + * Validate that pool data is valid + * @param {Object} pool - Pool data + * @returns {boolean} - Whether the pool is valid + */ +const isValidPool = (pool) => { + return pool && + pool.address && + (pool.apr > 0 || pool.estimatedApr > 0) && + pool.reserves && + Array.isArray(pool.reserves) && + pool.reserves.length > 0 && + pool.reserves.some(reserve => reserve.currencyAmounts && reserve.currencyAmounts.length > 0); +}; + +/** + * Create specific pool URL + * @param {string} poolId - Pool ID/name (e.g., "GT3-WBTC") + * @returns {string} - Pool URL + */ +const createPoolUrl = (poolId) => { + return `https://dapp.gt3.finance/explore/pools/${poolId}`; +}; + +module.exports = { + GRAPHQL_ENDPOINT, + PROJECT_KEY, + REQUEST_HEADERS, + CHAIN_MAPPING, + makeGraphQLRequest, + getChainName, + calculateTVLFromPool, + getAllPools, + getUnderlyingTokens, + getRewardTokens, + isValidPool, + createPoolUrl +}; \ No newline at end of file diff --git a/src/adaptors/gt3/index.js b/src/adaptors/gt3/index.js new file mode 100644 index 0000000000..aa240da092 --- /dev/null +++ b/src/adaptors/gt3/index.js @@ -0,0 +1,142 @@ +// GT3 Finance adapter for DeFiLlama Yield Server +const utils = require('../utils'); +const { PROJECT_CONFIG_QUERY, createPoolStatsQuery } = require('./queries'); +const { + makeGraphQLRequest, + getChainName, + calculateTVLFromPool, + getAllPools, + getUnderlyingTokens, + getRewardTokens, + isValidPool, + createPoolUrl +} = require('./helpers'); + +/** + * Transform GT3 pool to DeFiLlama format + * @param {Object} pool - GT3 pool data + * @param {Object} config - Project configuration + * @param {string} chainName - Chain name + * @returns {Promise} - Pool in DeFiLlama format or null if invalid + */ +const transformPool = async (pool, config, chainName) => { + try { + // Validate pool + if (!isValidPool(pool)) { + return null; + } + + const { tokens, pools: configPools, addresses, gauges } = config; + + // Find pool configuration + const poolConfig = configPools.find(p => p.id === pool.shareTokenID); + + // Calculate TVL using shareTokenSupply data directly + const tvlUsd = calculateTVLFromPool(pool); + + // Filter pools with very low TVL according to DeFiLlama best practices (>$10k) + if (tvlUsd < 10000) { + return null; + } + + // Get most reliable APR (prioritize APR over estimatedApr) + const aprValue = pool.apr || pool.estimatedApr || 0; + + // Convert APR to APY using DeFiLlama's official utility + const apyBase = utils.aprToApy(aprValue); + + // Get pool symbol - use pool name/id as symbol for better distinction + const symbol = poolConfig && poolConfig.name ? + utils.formatSymbol(poolConfig.name) : + `GT3-${pool.id}`; + + // Get underlying tokens + const underlyingTokens = getUnderlyingTokens(poolConfig, addresses); + + // Get reward tokens + const rewardTokens = getRewardTokens(pool, gauges, addresses); + + // Create pool in DeFiLlama format + const poolData = { + pool: `${pool.address}-${chainName.toLowerCase()}`, + chain: chainName, + project: 'gt3', + symbol: symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: underlyingTokens, + url: createPoolUrl(pool.id) + }; + + // Add poolMeta with descriptive suffix + poolData.poolMeta = `${symbol} Liquidity Pool`; + + if (rewardTokens.length > 0) { + poolData.rewardTokens = rewardTokens; + } + + return poolData; + + } catch (error) { + console.error(`Error transforming pool ${pool.id}:`, error); + return null; + } +}; + +/** + * Main adapter function + * @returns {Promise} - List of pools in DeFiLlama format + */ +const apy = async () => { + try { + // Get project configuration + const configResponse = await makeGraphQLRequest(PROJECT_CONFIG_QUERY); + + if (configResponse.data.getProjectConfiguration.__typename === 'SimpleError') { + throw new Error(`Configuration error: ${configResponse.data.getProjectConfiguration.description}`); + } + + const config = configResponse.data.getProjectConfiguration; + const { chainID } = config; + const chainName = getChainName(chainID); + + // Get all pool statistics with pagination + const allPoolStats = await getAllPools(createPoolStatsQuery); + + // Transform pools to DeFiLlama format in parallel + const poolTransformations = allPoolStats.map(pool => + transformPool(pool, config, chainName) + ); + + const transformedPools = await Promise.all(poolTransformations); + + // Filter valid pools with complete data + const validPools = transformedPools + .filter(pool => pool !== null) + .filter(pool => utils.keepFinite(pool)); + + // Sort by TVL descending + validPools.sort((a, b) => b.tvlUsd - a.tvlUsd); + + return validPools; + + } catch (error) { + console.error('Error in GT3 adapter:', error); + return []; + } +}; + +/** + * Adapter module configuration + */ +module.exports = { + timetravel: false, + apy: apy, + url: 'https://dapp.gt3.finance/', + meta: { + name: 'GT3 Finance', + description: 'Decentralized yield farming protocol', + chains: ['Polygon'], + category: 'yield-farming' + } +}; diff --git a/src/adaptors/gt3/queries.js b/src/adaptors/gt3/queries.js new file mode 100644 index 0000000000..34c7cd2086 --- /dev/null +++ b/src/adaptors/gt3/queries.js @@ -0,0 +1,174 @@ +// GraphQL queries for GT3 Finance API + +/** + * Query to get project configuration including tokens, pools, addresses, and gauges + */ +const PROJECT_CONFIG_QUERY = { + operationName: "GET_PROJECT_CONFIG_QUERY", + variables: {}, + query: `query GET_PROJECT_CONFIG_QUERY { + getProjectConfiguration { + __typename + ... on ProjectConfig { + id + key + chainID + tokens { + id + name + symbol + decimals + type + metadata { + permitted + domainName + domainVersion + swapFeeType + __typename + } + __typename + } + pools { + id + name + symbol + decimals + type + tokens + multiplier + metadata { + permitted + domainName + domainVersion + swapFeeType + __typename + } + __typename + } + addresses { + tokenID + address + feed + __typename + } + externalSources { + uri + purposes + __typename + } + balances + dexRouters { + id + address + type + __typename + } + synthetics { + id + escrowedTokenId + type + vaultAddress + voterAddress + rebaseAddress + epochDuration + minLockDuration + maxLockDuration + minterAddress + __typename + } + gauges { + poolID + address + rewardTokenID + __typename + } + bribes { + poolID + address + __typename + } + __typename + } + ... on SimpleError { + description + __typename + } + } + }` +}; + +/** + * Query to get pool statistics with pagination + * @param {number} offset - Pagination offset + * @param {number} limit - Number of items per page + * @returns {Object} GraphQL query object + */ +const createPoolStatsQuery = (offset = 0, limit = 100) => ({ + operationName: "GET_POOL_STATS_QUERY", + variables: { + input: { + items: [], + paginationMetadata: { + offset, + limit, + orderBy: "id", + orderDirection: "DESC" + } + } + }, + query: `query GET_POOL_STATS_QUERY($input: GetPoolStatsInput!) { + getPoolStats(input: $input) { + __typename + ... on PoolStatsPaginatedListInfo { + items { + id + address + shareTokenID + shareTokenSupply { + number + bigint + tokenID + currencyAmounts { + number + currencyID + __typename + } + __typename + } + reserves { + number + bigint + tokenID + currencyAmounts { + number + currencyID + __typename + } + __typename + } + apr + estimatedApr + __typename + } + metadata { + offset + limit + orderBy + orderDirection + numElements + __typename + } + __typename + } + ... on SimpleError { + description + __typename + } + } + }` +}); + +module.exports = { + PROJECT_CONFIG_QUERY, + createPoolStatsQuery +}; \ No newline at end of file diff --git a/src/adaptors/gyroscope-protocol/index.js b/src/adaptors/gyroscope-protocol/index.js new file mode 100644 index 0000000000..63d687e300 --- /dev/null +++ b/src/adaptors/gyroscope-protocol/index.js @@ -0,0 +1,155 @@ +// const utils = require('../utils'); +// const axios = require('axios'); +// const { BalancerSDK } = require('@balancer-labs/sdk'); +// const BEETHOVEN_API = require('./query'); +// const processBeethovenAPR = require('./utils/processBeethovenAPR'); + +// const API_URL = 'https://app.gyro.finance/pools/'; + +// const SUPPORTED_CHAINS = { +// 1: { +// name: 'ethereum', +// rpcUrl: +// 'https://eth-mainnet.g.alchemy.com/v2/t0aumdpjEYRonvcR7PFZhD8TJGjoTil9', +// coingeckoId: 'ethereum', +// }, +// 10: { +// name: 'optimism', +// rpcUrl: +// 'https://opt-mainnet.g.alchemy.com/v2/VxaW_1W6c4kIGUlm5nX_ZgTZmhAkP6vL', +// coingeckoId: 'optimistic-ethereum', +// }, +// 137: { +// name: 'polygon', +// rpcUrl: 'https://polygon-rpc.com', +// coingeckoId: 'polygon-pos', +// }, +// }; + +// const BAL = { +// 1: '0xba100000625a3754423978a60c9317c58a424e3d', +// 10: '0xFE8B128bA8C78aabC59d4c64cEE7fF28e9379921', +// 137: '0xba100000625a3754423978a60c9317c58a424e3d', +// }; + +// function fetchPools(chainId) { +// const data = utils.getData( +// API_URL + SUPPORTED_CHAINS[chainId].name + '.json' +// ); +// return data; +// } + +// async function fetchPoolTVL(balancerPool, chainId) { +// const tokenPrices = await Promise.all( +// balancerPool.tokens.map(async (token) => { +// const endpoint = +// 'https://europe-west2-gyroscope-ui.cloudfunctions.net/getPrice'; + +// const res = await axios.post(endpoint, { +// networkId: SUPPORTED_CHAINS[chainId].coingeckoId, +// tokenAddress: token.address, +// }); +// return res.data; +// }) +// ); + +// const poolTVL = balancerPool.tokens.reduce((acc, token, index) => { +// const price = tokenPrices[index]; +// const value = Number(price) * Number(token.balance); +// return acc + value; +// }, 0); + +// return poolTVL; +// } + +// async function fetchAPY(balancerSDK, balancerPool, isOptimism) { +// let apr; + +// if (isOptimism) { +// const res = await axios.post( +// 'https://backend-v3.beets-ftm-node.com/', +// { +// query: BEETHOVEN_API, +// variables: { id: balancerPool.id.toLowerCase() }, +// }, +// { +// headers: { +// chainId: '10', +// }, +// } +// ); + +// const beethovenApr = res?.data?.data?.pool?.dynamicData?.apr; + +// apr = processBeethovenAPR(beethovenApr); +// } else { +// apr = await balancerSDK.pools.apr(balancerPool); +// } + +// const protocolFees = (apr.protocolApr ?? 0) / 100; +// const swapFees = (apr.swapFees ?? 0) / 100; +// const apyBase = swapFees + protocolFees; + +// const incentiveRewardsAPR = (apr?.rewardAprs?.total ?? 0) / 100; +// const lstRewards = (apr?.tokenAprs?.total ?? 0) / 100; +// const balRewards = (apr?.stakingApr?.min ?? 0) / 100; +// const stETHApr = apr?.stETHApr ?? 0; +// const apyReward = incentiveRewardsAPR + lstRewards + balRewards + stETHApr; + +// return { +// apyBase, +// apyReward, +// }; +// } + +// const apy = async () => { +// const poolsWithAPY = await Promise.all( +// Object.keys(SUPPORTED_CHAINS).map(async (chainId, i) => { +// chainId = Number(chainId); +// const config = { +// network: chainId, +// rpcUrl: SUPPORTED_CHAINS[chainId].rpcUrl, +// }; + +// const pools = await fetchPools(chainId); + +// const balancerSDK = new BalancerSDK(config); + +// const formattedPools = await Promise.all( +// pools.map(async (pool) => { +// const balancerPool = await balancerSDK.pools.find(pool.id); + +// const poolTVL = await fetchPoolTVL(balancerPool, chainId); + +// const { apyBase, apyReward } = await fetchAPY( +// balancerSDK, +// balancerPool, +// chainId === 10 +// ); + +// return { +// pool: `${pool.address}-${SUPPORTED_CHAINS[chainId].name}`, +// chain: utils.formatChain(SUPPORTED_CHAINS[chainId].name), +// project: 'gyroscope-protocol', +// symbol: pool.tokens.map(({ symbol }) => symbol).join('-'), +// tvlUsd: poolTVL, +// apyBase, +// apyReward, +// rewardTokens: +// apyReward > 0 ? pool.rewardTokens ?? [BAL[chainId]] : [], +// }; +// }) +// ); + +// return formattedPools; +// }) +// ); + +// return poolsWithAPY.flat(); +// }; + +// module.exports = { +// timetravel: false, +// apy: apy, +// url: 'https://app.gyro.finance', +// }; diff --git a/src/adaptors/gyroscope-protocol/query.js b/src/adaptors/gyroscope-protocol/query.js new file mode 100644 index 0000000000..566c05eb49 --- /dev/null +++ b/src/adaptors/gyroscope-protocol/query.js @@ -0,0 +1,64 @@ +const BEETHOVEN_API = ` +query GetPool($id: String!) { + pool: poolGetPool( + id: $id + ) { + id + dynamicData { + apr { + swapApr + nativeRewardApr { + __typename + ... on GqlPoolAprRange { + min + max + } + ... on GqlPoolAprTotal { + total + } + } + thirdPartyApr { + __typename + ... on GqlPoolAprRange { + min + max + } + ... on GqlPoolAprTotal { + total + } + } + items { + id + title + __typename + apr { + ... on GqlPoolAprRange { + min + max + } + ... on GqlPoolAprTotal { + total + } + } + subItems { + id + title + __typename + apr { + ... on GqlPoolAprRange { + min + max + } + ... on GqlPoolAprTotal { + total + } + } + } + } + } + } + } + } + `; + +module.exports = BEETHOVEN_API; diff --git a/src/adaptors/gyroscope-protocol/utils/processBeethovenAPR.js b/src/adaptors/gyroscope-protocol/utils/processBeethovenAPR.js new file mode 100644 index 0000000000..acb486d934 --- /dev/null +++ b/src/adaptors/gyroscope-protocol/utils/processBeethovenAPR.js @@ -0,0 +1,27 @@ +function processBeethovenAPR(apr) { + if (!apr) return apr; + + const swapFees = + Number(apr.items.find(({ title }) => title === 'Swap fees APR').apr.total) * + 10000; + const nativeRewardApr = Number(apr.nativeRewardApr.min) * 10000; + const thirdPartyApr = Number(apr.thirdPartyApr.min) * 10000; + + const min = swapFees + nativeRewardApr + thirdPartyApr; + + const stETHApr = apr.items.find(({ title }) => title === 'stETH APR')?.apr + ?.total; + + return { + min, + swapFees, + stakingApr: { + min: nativeRewardApr, + max: Number(apr.nativeRewardApr.max) * 10000, + }, + rewardAprs: { total: thirdPartyApr }, + stETHApr: stETHApr && stETHApr * 100, + }; +} + +module.exports = processBeethovenAPR; diff --git a/src/adaptors/harbor-market/abiLendingPool.js b/src/adaptors/harbor-market/abiLendingPool.js new file mode 100644 index 0000000000..ddf300738e --- /dev/null +++ b/src/adaptors/harbor-market/abiLendingPool.js @@ -0,0 +1,692 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/harbor-market/abiProtocolDataProvider.js b/src/adaptors/harbor-market/abiProtocolDataProvider.js new file mode 100644 index 0000000000..1c698fcae2 --- /dev/null +++ b/src/adaptors/harbor-market/abiProtocolDataProvider.js @@ -0,0 +1,148 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/harbor-market/abiSimplifiedProtocolDataReader.js b/src/adaptors/harbor-market/abiSimplifiedProtocolDataReader.js new file mode 100644 index 0000000000..e01b36c463 --- /dev/null +++ b/src/adaptors/harbor-market/abiSimplifiedProtocolDataReader.js @@ -0,0 +1,375 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "protocolDataProviderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "thenaOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lendingOracleAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ILENDING_ORACLE", + "outputs": [ + { + "internalType": "contract ILendingOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ITHENA_ORACLE", + "outputs": [ + { + "internalType": "contract IThenaOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAYMENT_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_DATA_PROVIDER", + "outputs": [ + { + "internalType": "contract ProtocolDataProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARDER", + "outputs": [ + { + "internalType": "contract IRewarder0612", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetFullYieldBreakdown", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetRewardsAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getDepositAndBorrowAPRs", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPaymentTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolBalancesUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolYearlyRewardsUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRawOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRealOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReceiptTokenAddresses", + "outputs": [ + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardsDataEPS", + "outputs": [ + { + "internalType": "uint256", + "name": "aTokenRewardEPS", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vTokenRewardEPS", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/harbor-market/index.js b/src/adaptors/harbor-market/index.js new file mode 100644 index 0000000000..c005115a58 --- /dev/null +++ b/src/adaptors/harbor-market/index.js @@ -0,0 +1,181 @@ +const ethers = require('ethers'); +const { JsonRpcProvider } = require('ethers'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiSimplifiedProtocolDataReader = require('./abiSimplifiedProtocolDataReader'); + +const utils = require('../utils'); + +const chains = { + bsc: { + LendingPool: '0xf5Ab6C920af8f1bd4b16fDa9e7EF3173ffb616f7', + ProtocolDataProvider: '0xFa0AC9b741F0868B2a8C4a6001811a5153019818', + url: 'bsc', + SimplifiedProtocolDataReader: '0x2756F9db44dB040437bF58E850A454a38E390b9C', + rewardTokens: ['0x45c19a3068642b98f5aef1dede023443cd1fbfad'] + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + const rewardTokens = addresses.rewardTokens; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output.filter((address) => address.toLowerCase() !== '0x4206931337dc273a630d328dA6441786BfaD668f'.toLowerCase());; + + // try catches incase of safemath error + let rewardsData; + try { + rewardsData = await sdk.api.abi.multiCall({ + calls: reservesList.map((reserve) => ({ + target: addresses.SimplifiedProtocolDataReader, + params: [reserve], + })), + abi: abiSimplifiedProtocolDataReader.find((m) => m.name === 'getAssetRewardsAPR'), + chain: sdkChain, + failOnRevert: false, // Add this option to prevent failing on reverts + }); + } catch (error) { + console.error(`Error fetching rewards data for chain ${chain}:`, error); + // Implement fallback mechanism or use default values + rewardsData = { + output: reservesList.map(() => ({ success: false, output: null })) + }; + } + + // Process the results, handling potential failures + const processedRewardsData = rewardsData.output.map((result, index) => { + if (result.success && Array.isArray(result.output) && result.output.length === 2) { + return { + apyReward: Number(result.output[0]) / 1e8, + apyRewardBorrow: Number(result.output[1]) / 1e8 + }; + } else { + console.warn(`Failed to get rewards data for reserve ${reservesList[index]} on chain ${chain}`); + return { apyReward: 0, apyRewardBorrow: 0 }; + } + }); + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + + const { apyReward, apyRewardBorrow } = processedRewardsData[i]; + + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const poolSymbol = symbols[i].toLowerCase() + const url = `https://harbor.market/markets/${poolSymbol}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'harbor-market', + chain, + tvlUsd, + apyBase, + // apyReward, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + // apyRewardBorrow, + // rewardTokens, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/harmonix-finance/index.js b/src/adaptors/harmonix-finance/index.js new file mode 100644 index 0000000000..8f3cf72248 --- /dev/null +++ b/src/adaptors/harmonix-finance/index.js @@ -0,0 +1,137 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils') + +// ABI for totalValueLocked function +const totalValueLockedABI = { + "inputs": [], + "name": "totalValueLocked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +}; + +// Mapping of chain names to chain IDs +const chains = { + ethereum: 'ethereum', + arbitrum_one: 'arbitrum', + hyperevm: 'hyperevm', + base: 'base', +}; + +const getTvl = async (contractAddress, chain) => { + try { + const tvl = await sdk.api.abi.call({ + target: contractAddress, + abi: totalValueLockedABI, + chain + }); + return tvl.output; + } catch (error) { + throw new Error(`Failed to fetch TVL from contract ${contractAddress} on chain ${chain} : ${error.message}`); + } +}; + +const assets = { + arbitrum: { + eth: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + wbtc: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + rseth: '0x4186BFC76E2E237523CBC30FD220FE055156b41F', + link: '0xf97f4df75117a78c1A5a0DBb814Af92458539FB4', + uni: '0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0' + }, + ethereum: { + eth: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + rseth: '0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7', + }, + hyperevm: { + hype: '0x0000000000000000000000000000000000000000', + } +}; + +const getApy = async () => { + const response = await axios.get('https://api.harmonix.fi/api/v1/vaults/', { + headers: { + 'accept': 'application/json' + } + }); + + const pools = await Promise.all(response.data.map(async vault => { + return Promise.all(vault.vaults.map(async v => { + const chainId = chains[v.network_chain]; + let tvlUsd = 0 + + if (chainId === 'hyperevm') { + const provider = new ethers.providers.JsonRpcProvider("https://rpc.hyperliquid.xyz/evm"); + + const contractAddress = "0xe9d69CdD6Fe41e7B621B4A688C5D1a68cB5c8ADc"; + const abi = [ + "function getPriceUnsafe(bytes32) view returns (tuple(int64, uint64, int32, uint256))" + ]; + + const priceFeed = "0x4279e31cc369bbcc2faf022b382b080e32a8e689ff20fbc530d2a603eb6cd98b"; + + + const contract = new ethers.Contract(contractAddress, abi, provider); + const [price, conf, expo, timestamp] = await contract.getPriceUnsafe(priceFeed); + const normalizedPrice = Number(price) * 10 ** expo; + + + tvlUsd = normalizedPrice * v.tvl; + + } + else { + const tvl = await getTvl(v.contract_address, chainId); + tvlUsd = tvl; // Default to the fetched TVL + // Convert TVL to USDC if vault_currency is not USDC + if (v.vault_currency !== 'USDC') { + const tokenKey = `${chainId}:${assets[chainId][v.vault_currency.toLowerCase()]}` + const priceData = await axios.get(`https://coins.llama.fi/prices/current/${tokenKey}`); + const tokenPrice = priceData.data.coins[`${tokenKey}`]?.price; + if (tokenPrice) { + if (v.vault_currency === 'ETH') { + tvlUsd = (tvl / 1e18) * tokenPrice; + } else if (v.vault_currency === 'WBTC') { + tvlUsd = (tvl / 1e8) * tokenPrice; + } else { + tvlUsd = (tvl / 1e6) * tokenPrice; + } + } else { + throw new Error(`Price for ${v.vault_currency} not found.`); + } + } + else { + tvlUsd /= 1e6 + } + } + + return { + pool: v.contract_address, // unique identifier for the pool + chain: chainId || null, // map chain name to chain ID + project: 'harmonix-finance', // project slug + symbol: utils.formatSymbol(v.vault_currency), // format the symbol + tvlUsd, // total value locked in USD + apyBase: v.apy, // APY from the vault + apyReward: 0, // hardcoded for now + rewardTokens: [], // hardcoded for now + url: `https://app.harmonix.fi/vaults/${v.slug}`, // URL to the vault + underlyingTokens: assets[chainId][v.underlying_asset.toLowerCase()] ? [assets[chainId][v.underlying_asset.toLowerCase()]] : [], // underlying asset + }; + })); + })); + + return pools.flat(); // flatten the array of pools +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.harmonix.fi/vaults/', // Link to page with pools +}; diff --git a/src/adaptors/harvest-finance/index.js b/src/adaptors/harvest-finance/index.js index 752dc3e3ae..bf8d4009ae 100644 --- a/src/adaptors/harvest-finance/index.js +++ b/src/adaptors/harvest-finance/index.js @@ -1,53 +1,156 @@ -const axios = require("axios"); +const superagent = require('superagent'); + const utils = require('../utils'); -const farmsUrl = 'https://api-ui.harvest.finance/vaults?key=41e90ced-d559-4433-b390-af424fdc76d6'; -const poolsUrl = 'https://api-ui.harvest.finance/pools?key=41e90ced-d559-4433-b390-af424fdc76d6'; +const { readFromS3 } = require('../../utils/s3'); +// no longer needed, see note below +const farmsUrl = + 'https://api.harvest.finance/vaults?key=41e90ced-d559-4433-b390-af424fdc76d6'; +const poolsUrl = + 'https://api.harvest.finance/pools?key=41e90ced-d559-4433-b390-af424fdc76d6'; +const statsUrl = + 'https://api.harvest.finance/token-stats?key=41e90ced-d559-4433-b390-af424fdc76d6'; const chains = { - "bsc": "binance", - "eth": "ethereum", - "matic": "polygon" + eth: 'ethereum', + matic: 'polygon', + arbitrum: 'arbitrum', + base: 'base', + zksync: 'era', }; +const url_config = { + eth: 'ethereum', + matic: 'polygon', + arbitrum: 'arbitrum', + base: 'base', + zksync: 'zksync', +} -function aggregateApys(farm, poolsResponse) { - const farmApy = farm.estimatedApy; - const selectedPools = poolsResponse.filter(p => p.contractAddress == farm.rewardPool); - if (selectedPools.length == 0) return farmApy; - const pool = selectedPools[0]; - const poolApy = Number(pool.tradingApy) + pool.rewardAPY - .reduce((a,b) => Number(a) + Number(b), 0); - return Number(farmApy) + Number(poolApy); -}; +function aggregateBaseApys(farm, poolsResponse) { + const farmApy = farm.estimatedApy; + const selectedPools = poolsResponse.filter( + (p) => p.contractAddress == farm.rewardPool + ); + if (selectedPools.length == 0) return Number(farmApy); + const pool = selectedPools[0]; + const poolApy = Number(pool.tradingApy); -async function apy() { - const farmsResponse = (await axios.get(farmsUrl)).data; - const poolsResponse = (await axios.get(poolsUrl)).data; + return Number(farmApy) + Number(poolApy); +} - let allVaults = []; +function aggregateRewardApys(farm, poolsResponse) { + const selectedPools = poolsResponse.filter( + (p) => p.contractAddress == farm.rewardPool + ); + if (selectedPools.length == 0) return null; + const pool = selectedPools[0]; + const rewardApy = pool.rewardAPY.reduce((a, b) => Number(a) + Number(b), 0); - for (let chain of Object.keys(chains)) { - const activeFarms = Object.values(farmsResponse[chain]) - .filter(v => !v.hasOwnProperty('inactive') || v.inactive != true); + return Number(rewardApy) > 0 ? Number(rewardApy) : null; +} - const farms = activeFarms.map(v => ({ - pool: v.vaultAddress, - chain: utils.formatChain(chains[chain]), - project: 'harvest-finance', - symbol: utils.formatSymbol(v.displayName), - tvlUsd: Number(v.totalValueLocked), - apy: aggregateApys(v, poolsResponse[chain]) - })); +async function apy() { + let allVaults = []; + let specialVaults = []; + + // note (!) calling their api via aws lambda stopped working due to cloudflare bot protection. + // instead, we use a python lambda which bypasses cloudflare + // and stores the output to s3 (i tried node js packages, none of them worked; the repo to the + // lambda + const farmsResponse = (await superagent.get(farmsUrl)).body; + const poolsResponse = (await superagent.get(poolsUrl)).body; + const statsResponse = (await superagent.get(statsUrl)).body; + // const data = await readFromS3('llama-apy-prod-data', 'harvest_api_data.json'); + // const farmsResponse = data['vaults']; + // const poolsResponse = data['pools']; + // const statsResponse = data['token-stats']; - allVaults = [...allVaults, ...farms]; + let specialVaultIds = ['farm-grain', 'farm-weth']; + specialVaults = specialVaultIds.map((vaultId) => { + const selectedPools = poolsResponse['eth'].filter((p) => p.id == vaultId); + if (selectedPools.length == 0) return null; + const pool = selectedPools[0]; + const rewardApy = pool.rewardAPY.reduce((a, b) => Number(a) + Number(b), 0); + + return { + pool: pool.contractAddress, + chain: 'Ethereum', + project: 'harvest-finance', + symbol: utils.formatSymbol(vaultId).replace(/[{()}]/g, ''), + tvlUsd: + vaultId === 'farm-weth' + ? Number(pool.lpTokenData.liquidity) + : Number(pool.totalValueLocked), + apyBase: pool.tradingApy, + apyReward: Number(rewardApy) > 0 ? Number(rewardApy) : null, + rewardTokens: Number(rewardApy) > 0 ? pool.rewardTokens : null, }; + }); + // for binance inactive !== true + for (let chain of Object.keys(chains)) { + const activeFarms = Object.values(farmsResponse[chain]).filter( + (v) => !v?.inactive + ); + const farms = activeFarms.map((v) => { + const selectedPools = poolsResponse[chain].filter( + (p) => p.contractAddress == v.rewardPool + ); + let rewardTokens; + if (selectedPools.length == 0) { + rewardTokens = null; + } else { + const pool = selectedPools[0]; + rewardTokens = + pool.rewardTokens && + aggregateRewardApys(v, poolsResponse[chain]) != null + ? pool.rewardTokens.flat() + : null; + } - return allVaults; -}; + let apyBase, tvlUsd; + if (v.vaultAddress === '0x1571eD0bed4D987fe2b498DdBaE7DFA19519F651') { + //It's special vault for iFarm + apyBase = Number(statsResponse.historicalAverageProfitSharingAPY); + const iFarmPools = poolsResponse['eth'].filter( + (p) => p.id == 'profit-sharing-farm' + ); + tvlUsd = Number(iFarmPools[0].totalValueLocked); + } else { + apyBase = aggregateBaseApys(v, poolsResponse[chain]); + tvlUsd = Number(v.totalValueLocked); + } + return { + pool: v.vaultAddress, + chain: utils.formatChain(chains[chain]), + project: 'harvest-finance', + symbol: v.tokenNames.join('-'), + tvlUsd, + apyBase, + apyReward: aggregateRewardApys(v, poolsResponse[chain]), + rewardTokens, + poolMeta: v.platform ? `${v.platform[0]}` : null, + url: `https://app.harvest.finance/${url_config[chain]}/${v.vaultAddress}`, + }; + }); -const main = async () => { - return await apy(); -}; + allVaults = [...allVaults, ...farms]; + } + + allVaults = [...allVaults, ...specialVaults].filter((i) => Boolean(i)); + + return ( + allVaults + .filter((p) => utils.keepFinite(p)) + // getting a conflict on that particular pool, removing for now until i know why + .filter( + (p) => + ![ + '0xE4E6055A7eB29F2Fa507ba7f8c4FAcc0C5ef9a2A', + '0xd7b17297B9884Aa73BF5E6e39e3cEC107ffe6b17', + ].includes(p.pool) + ) + ); +} module.exports = { - timetravel: false, - apy: main, -}; \ No newline at end of file + timetravel: false, + apy, +}; diff --git a/src/adaptors/hashking/index.js b/src/adaptors/hashking/index.js new file mode 100644 index 0000000000..3f5cd54b38 --- /dev/null +++ b/src/adaptors/hashking/index.js @@ -0,0 +1,84 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); + +const filHubPool = '0xfeB16A48dbBB0E637F68215b19B4DF5b12449676'; +const sdkChain = 'filecoin'; +const url = 'https://www.nodedao.com/'; +const liquidStakingABI = require('./liquidStaking'); + +const getApyAbi = { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'getApy', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const getApy = async () => { + // <- Filecoin -> + const filPriceKey = `coingecko:filecoin`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${filPriceKey}`) + ).data.coins[filPriceKey]?.price; + + const tokenAddress = '0x84B038DB0fCde4fae528108603C7376695dc217F'; // Replace with your token address + const getFilAPY = await sdk.api2.abi.call({ + target: filHubPool, + abi: getApyAbi, + params: [tokenAddress], + chain: sdkChain, + }); + + console.log('getFilAPY: ', parseFloat(getFilAPY / 100)); + + const owner = '0xe012f3957226894b1a2a44b3ef5070417a069dc2'; + const validators = await sdk.api2.abi.call({ + target: owner, + abi: liquidStakingABI.find((m) => m.name === 'beneficiarys'), + chain: sdkChain, + }); + const bals = await sdk.api2.abi.multiCall({ + abi: { + inputs: [], + name: 'totalStakingFil', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + calls: validators, + chain: sdkChain, + }); + // parsing them to BigInt + bigInts = bals.map(BigInt); + + // summing them up using reduce + let sumBigInt = bigInts.reduce( + (accumulator, current) => accumulator + current, + BigInt(0) + ); + const divisor = BigInt(10 ** 18); + const filBigInt = Number(sumBigInt / divisor); + const filTvl = filBigInt * price; + const filecoinAPY = { + pool: `${filHubPool}-${sdkChain}`.toLowerCase(), // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase() + chain: `${sdkChain}`, // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) + project: 'hashking', // protocol (using the slug again) + symbol: 'FIL', // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP + tvlUsd: filTvl, // number representing current USD TVL in pool + apyBase: parseFloat(getFilAPY / 100), // APY from pool fees/supplying in % + url, + }; + + return [filecoinAPY]; +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/hashking/liquidStaking.js b/src/adaptors/hashking/liquidStaking.js new file mode 100644 index 0000000000..b7e7869516 --- /dev/null +++ b/src/adaptors/hashking/liquidStaking.js @@ -0,0 +1,691 @@ +module.exports = [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "ben", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "node", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "to", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "FilMining", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "FilRepayment", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "FilReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "name": "FilStake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "name": "FilUnStake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "addBeneficiary", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "beneficiarys", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "curProfitBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "delBeneficiary", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "depositFil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "equityPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "equityPointLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "freeNFil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + } + ], + "name": "getFilOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + } + ], + "name": "getNFilOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "hasBeneficiary", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INFIL", + "name": "nFIL", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "len", + "type": "uint256" + } + ], + "name": "lastEquityPoint", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct EquityPoint[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nFilContract", + "outputs": [ + { + "internalType": "contract INFIL", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "repayment", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "gov", + "type": "address" + } + ], + "name": "setGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setTotalPoolFilLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "setTotalUnStakeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakeFil", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "totalPoolFil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalPoolFilLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalPoolProfit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStakeFil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnStakeFil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnStakeLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unStakeFil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/src/adaptors/hashstack/abis/erc20abi.js b/src/adaptors/hashstack/abis/erc20abi.js new file mode 100644 index 0000000000..9467b0e081 --- /dev/null +++ b/src/adaptors/hashstack/abis/erc20abi.js @@ -0,0 +1,27 @@ +const erc20 = [ +{ + inputs: [ + { + name: "account", + type: "felt" + } + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "Uint256" + } + ], + stateMutability: "view", + type: "function" +} + ] + + const erc20abi = {}; + erc20.forEach((i) => (erc20abi[i.name] = i)); + + module.exports = { + erc20abi, + }; + \ No newline at end of file diff --git a/src/adaptors/hashstack/abis/metricsAbi.js b/src/adaptors/hashstack/abis/metricsAbi.js new file mode 100644 index 0000000000..8d98f42413 --- /dev/null +++ b/src/adaptors/hashstack/abis/metricsAbi.js @@ -0,0 +1,46 @@ +const metrics = [ + { + inputs: [ + { + name: 'token_add', + type: 'felt', + }, + ], + name: 'get_protocol_stats', + outputs: [ + { name: "borrow_rate", type: "Uint256" }, + { name: "_dummy0", type: "Uint256" }, + { name: "supply_rate", type: "Uint256" }, + { name: "_dummy1", type: "Uint256" }, + { name: "staking_rate", type: "Uint256" }, + { name: "_dummy2", type: "Uint256" }, + { name: "total_supply", type: "Uint256" }, + { name: "_dummy3", type: "Uint256" }, + { name: "lent_assets", type: "Uint256" }, + { name: "_dummy4", type: "Uint256" }, + { name: "total_borrow", type: "Uint256" }, + { name: "_dummy5", type: "Uint256" }, + { name: "utilisation_per_market", type: "Uint256" }, + { name: "_dummy6", type: "Uint256" }, + { name: "exchange_rate_rToken_to_asset", type: "Uint256" }, + { name: "_dummy7", type: "Uint256" }, + { name: "exchange_rate_dToken_to_asset", type: "Uint256" }, + { name: "_dummy8", type: "Uint256" }, + { name: "exchange_rate_asset_to_rToken", type: "Uint256" }, + { name: "_dummy9", type: "Uint256" }, + { name: "exchange_rate_asset_to_dToken", type: "Uint256" }, + { name: "_dummy10", type: "Uint256" }, + { name: "token_address", type: "felt" }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +const metricsAbi = {}; +metrics.forEach((i) => (metricsAbi[i.name] = i)); + +module.exports = { + metricsAbi, + metrics +}; diff --git a/src/adaptors/hashstack/index.js b/src/adaptors/hashstack/index.js new file mode 100644 index 0000000000..c17feba275 --- /dev/null +++ b/src/adaptors/hashstack/index.js @@ -0,0 +1,305 @@ +const axios = require('axios'); +const { uint256 } = require('starknet'); +const { call } = require('../../helper/starknet'); +const { metricsAbi } = require('./abis/metricsAbi'); +const { default: BigNumber } = require('bignumber.js'); +const { erc20abi } = require('./abis/erc20abi'); +const oracle = + '0x07b05e8dc9c770b72befcf09599132093cf9e57becb2d1b3e89514e1f9bdf0ab'; + +const starknetFoundationIncentivesEndpoint = + 'https://kx58j6x5me.execute-api.us-east-1.amazonaws.com/starknet/fetchFile?file=prod-api/lending/lending_strk_grant.json'; + +const TOKENS = [ + { + name: 'BTC', + symbol: 'BTC', + decimals: 8, + minDeposit: '50000', + maxDeposit: '100000000000', + minLoan: '380000', + maxLoan: '6600000', + rToken: '0x1320a9910e78afc18be65e4080b51ecc0ee5c0a8b6cc7ef4e685e02b50e57ef', + dToken: '0x2614c784267d2026042ab98588f90efbffaade8982567e93530db4ed41201cf', + address: + '0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac', + CEXSymbol: 'BTCUSDT', + pontis_key: '18669995996566340', + mockPrice: 20000, + ethereumAddress: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + NETWORK_TOKEN_ADDRESS: + '0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac', + base_apr: '400', + apr_at_optimal_ur: '2000', + optimal_ur: '4500', + apr_max: '20000', + }, + { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + minDeposit: '6250000000000000', + maxDeposit: '100000000000000000000000', + minLoan: '66000000000000000', + maxLoan: '1040000000000000000', + rToken: '0x436d8d078de345c11493bd91512eae60cd2713e05bcaa0bb9f0cba90358c6e', + dToken: '0x1ef7f9f8bf01678dc6d27e2c26fb7e8eac3812a24752e6a1d6a49d153bec9f3', + address: + '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + CEXSymbol: 'ETHUSDT', + pontis_key: '19514442401534788', + mockPrice: 2000, + ethereumAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + NETWORK_TOKEN_ADDRESS: + '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + base_apr: '200', + apr_at_optimal_ur: '1200', + optimal_ur: '6000', + apr_max: '10000', + }, + { + name: 'USDT', + symbol: 'USDT', + decimals: 6, + minDeposit: '10000000', + maxDeposit: '100000000000000', + minLoan: '100000000', + maxLoan: '1550000000', + rToken: '0x5fa6cc6185eab4b0264a4134e2d4e74be11205351c7c91196cb27d5d97f8d21', + dToken: '0x12b8185e237dd0340340faeb3351dbe53f8a42f5a9bf974ddf90ced56e301c7', + address: + '0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8', + CEXSymbol: null, + pontis_key: '6148333044652921668', + mockPrice: 1, + ethereumAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7', + NETWORK_TOKEN_ADDRESS: + '0x68f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8', + base_apr: '200', + apr_at_optimal_ur: '1000', + optimal_ur: '7500', + apr_max: '10000', + }, + { + name: 'USDC', + symbol: 'USDC', + decimals: 6, + minDeposit: '10000000', + maxDeposit: '100000000000000', + minLoan: '100000000', + maxLoan: '1270000000', + rToken: '0x3bcecd40212e9b91d92bbe25bb3643ad93f0d230d93237c675f46fac5187e8c', + dToken: '0x21d8d8519f5464ec63c6b9a80a5229c5ddeed57ecded4c8a9dfc34e31b49990', + address: + '0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8', + CEXSymbol: 'USDCUSDT', + pontis_key: '6148332971638477636', + mockPrice: 1, + ethereumAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + NETWORK_TOKEN_ADDRESS: + '0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8', + base_apr: '200', + apr_at_optimal_ur: '1000', + optimal_ur: '7500', + apr_max: '10000', + }, + // { + // name: 'DAI', + // symbol: 'DAI', + // decimals: 18, + // minDeposit: '10000000000000000000', + // maxDeposit: '100000000000000000000000000', + // minLoan: '100000000000000000000', + // maxLoan: '1275000000000000000000', + // rToken: '0x19c981ec23aa9cbac1cc1eb7f92cf09ea2816db9cbd932e251c86a2e8fb725f', + // dToken: '0x7eeed99c095f83716e465e2c52a3ec8f47b323041ddc4f97778ac0393b7f358', + // address: + // '0x0da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3', + // CEXSymbol: 'USDTDAI', + // pontis_key: '19212080998863684', + // mockPrice: 1, + // ethereumAddress: '0x6b175474e89094c44da98b954eedeac495271d0f', + // NETWORK_TOKEN_ADDRESS: + // '0xda114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3', + // base_apr: '300', + // apr_at_optimal_ur: '1500', + // optimal_ur: '5000', + // apr_max: '15000', + // }, + { + name: 'STRK', + symbol: 'STRK', + decimals: 18, + minDeposit: '10000000000000000000', + maxDeposit: '500000000000000000000000', + minLoan: '40000000000000000000', + maxLoan: '400000000000000000000', + rToken: '0x7514ee6fa12f300ce293c60d60ecce0704314defdb137301dae78a7e5abbdd7', + dToken: '0x1bdbaaa456c7d6bbba9ff740af3cfcd40bec0e85cd5cefc3fbb05a552fd14df', + address: + '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', + CEXSymbol: 'STRKUSDT', + pontis_key: '6004514686061859652', + mockPrice: 2, + ethereumAddress: '0xCa14007Eff0dB1f8135f4C25B34De49AB0d42766', + NETWORK_TOKEN_ADDRESS: + '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', + base_apr: '200', + apr_at_optimal_ur: '1500', + optimal_ur: '5000', + apr_max: '11000', + }, +]; + +const getTokenPrice = async (token) => { + const networkTokenPair = `starknet:${token}`; + return ( + await axios.get(`https://coins.llama.fi/prices/current/${networkTokenPair}`) + ).data.coins[networkTokenPair].price; +}; + +const market= '0x548f38cb45720a101a1ec2edfaf608b47d2b39d137d0d3134087315f1b5f4a5' + +async function getSpendBalances() { + const marketStats=[]; + + try { + const promises = []; + for (let i = 0; i < TOKENS?.length; ++i) { + const token = TOKENS[i]; + + const res=call({ + abi:erc20abi?.balanceOf, + target:token?.address, + params:[token?.dToken], + allAbi:[], + }) + + promises.push(res); + } + + return new Promise((resolve, _) => { + Promise.allSettled([...promises]).then((val) => { + const results = val.map((stat, idx) => { + if ( + stat?.status == "fulfilled" && + stat?.value + ) { + return { + token: TOKENS[idx]?.name, + balance: + BigNumber(stat?.value).div(BigNumber(`1e${TOKENS[idx]?.decimals}`)).toNumber(), + }; + } else return marketStats; + }); + resolve(results); + }); + }); + } catch (e) { + return marketStats; + } +} + +async function netStrkBorrow(){ + let netstrk=0; + let strkData=await getStarknetFoundationIncentives(); + if (strkData != null) { + let netallocation = 0 + for (let token in strkData) { + if (strkData.hasOwnProperty(token)) { + const array = strkData[token] + const lastObject = array[array.length - 1] + netallocation += 0.3 * (lastObject?.allocation ?lastObject?.allocation:0) + } + } + netstrk=netallocation + } else { + netstrk=0 + } + return netstrk; +} + +async function getStarknetFoundationIncentives() { + const { data } = await axios.get(starknetFoundationIncentivesEndpoint); + return data['Hashstack']; +} + +async function netSpendbalance(){ + let netbalance = 0; + const spendBalances=await getSpendBalances(); + for(var i=0;i{ + }) + return netbalance +} + +async function apy() { + const incentives = await getStarknetFoundationIncentives(); + const strkPrice=await getTokenPrice('0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d') + const netSpendBalance=await netSpendbalance(); + const netsrtkborrow=await netStrkBorrow(); + const promises = + TOKENS.map(async (token, i) => { + const priceInUsd = await getTokenPrice(token?.address); + const res = await call({ + abi: metricsAbi?.get_protocol_stats, + target: + market, + params: [token?.address], + allAbi: [], + }); + const borrow_rate=BigNumber(res?.borrow_rate.toString()).div(100).toNumber(); + const supply_rate=BigNumber(res?.supply_rate.toString()).div(100).toNumber() + const totalDebt=BigNumber(res?.total_borrow.toString()).div(BigNumber(`1e${token.decimals}`)) + const totalSupply=BigNumber(res?.total_supply.toString()).div(BigNumber(`1e${token.decimals}`)) + const totalSupplyUsd=totalSupply.times(priceInUsd); + const totalBorrowUsd=totalDebt.times(priceInUsd); + const tokenIncentive = incentives[token.name]; + return{ + pool:`${token?.dToken.toLowerCase()}`, + chain:'Starknet', + project:'hashstack', + symbol:token?.name, + tvlUsd:totalSupplyUsd.toNumber(), + apyBase:supply_rate, + apyReward: + tokenIncentive && tokenIncentive.length > 0 + ? 365 * + 100 * + tokenIncentive[tokenIncentive.length - 1]['allocation']*0.7*strkPrice/ tokenIncentive[tokenIncentive.length - 1]['supply_usd'] + : 0, + rewardTokens:tokenIncentive ? ['0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d']:[], + apyBaseBorrow:borrow_rate, + apyRewardBorrow:tokenIncentive && tokenIncentive.length > 0 + ?netsrtkborrow*365*100*strkPrice/netSpendBalance:0, + underlyingTokens:[token?.address], + totalSupplyUsd:totalSupplyUsd.toNumber(), + totalBorrowUsd:totalBorrowUsd.toNumber(), + url:`https://app.hashstack.finance/v1/market` + } + }) + return Promise.all(promises) +} +apy() +module.exports = { + apy, + url: 'https://app.hashstack.finance', +}; diff --git a/src/adaptors/hatom-lending/index.js b/src/adaptors/hatom-lending/index.js new file mode 100644 index 0000000000..1dd7e9de37 --- /dev/null +++ b/src/adaptors/hatom-lending/index.js @@ -0,0 +1,63 @@ +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); +const { calcRewardsAPY } = require('./utils/math.js'); +const { getMoneyMarkets, getTokenPrices, getExchangeRates, getRewardsBatches, getBoostedRewards, getBoostedColateralMap } = require('./utils/data.js'); + +const MARKETS = [ + { symbol: 'EGLD', address: 'erd1qqqqqqqqqqqqqpgq35qkf34a8svu4r2zmfzuztmeltqclapv78ss5jleq3' }, + { symbol: 'SEGLD', address: 'erd1qqqqqqqqqqqqqpgqxmn4jlazsjp6gnec95423egatwcdfcjm78ss5q550k' }, + { symbol: 'WBTC', address: 'erd1qqqqqqqqqqqqqpgqg47t8v5nwzvdxgf6g5jkxleuplu8y4f678ssfcg5gy' }, + { symbol: 'WETH', address: 'erd1qqqqqqqqqqqqqpgq8h8upp38fe9p4ny9ecvsett0usu2ep7978ssypgmrs' }, + { symbol: 'USDC', address: 'erd1qqqqqqqqqqqqqpgqkrgsvct7hfx7ru30mfzk3uy6pxzxn6jj78ss84aldu' }, + { symbol: 'USDT', address: 'erd1qqqqqqqqqqqqqpgqvxn0cl35r74tlw2a8d794v795jrzfxyf78sstg8pjr' }, + { symbol: 'UTK', address: 'erd1qqqqqqqqqqqqqpgqta0tv8d5pjzmwzshrtw62n4nww9kxtl278ssspxpxu' }, + { symbol: 'HTM', address: 'erd1qqqqqqqqqqqqqpgqxerzmkr80xc0qwa8vvm5ug9h8e2y7jgsqk2svevje0' }, + { symbol: 'WTAO', address: 'erd1qqqqqqqqqqqqqpgqz9pvuz22qvqxfqpk6r3rluj0u2can55c78ssgcqs00' }, + { symbol: 'SWTAO', address: 'erd1qqqqqqqqqqqqqpgq7sspywe6e2ehy7dn5dz00ved3aa450mv78ssllmln6'}, +] + +const apy = async () => { + const [mm, prices, rewards] = await Promise.all([ + getMoneyMarkets(), + getTokenPrices(), + getRewardsBatches(), + ]); + const exchangeRates = getExchangeRates(mm) + + return MARKETS.map(({ symbol }) => { + const currentMM = mm[symbol] + const currentPrice = prices[symbol] + const currentExchangeRate = exchangeRates[symbol] + const currentRewards = rewards[symbol] + + const rewardsAPY = calcRewardsAPY({ + speed: currentRewards.speed, + hTokenExchangeRate: currentExchangeRate, + totalCollateral: currentMM.totalColateral.toString(), + marketPrice: currentPrice, + rewardsToken: currentRewards.rewardsToken, + rewardsTokenPrice: prices[currentRewards.rewardsToken.symbol], + marketDecimals: currentMM.decimals + }) + + const tvlUsd = new BigNumber(currentMM.cash).multipliedBy(currentPrice).dividedBy(`1e${currentMM.decimals}`).toNumber() + const apyBase = mm[symbol].supplyAPY + const apyReward = new BigNumber(rewardsAPY).toNumber() + return { + pool: symbol, + chain: 'MultiversX', + project: 'hatom-lending', + symbol: symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + apyReward: apyReward, + rewardTokens: [currentRewards.rewardsToken.symbol], + } + }) +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.hatom.com/lend', +}; \ No newline at end of file diff --git a/src/adaptors/hatom-lending/utils/data.js b/src/adaptors/hatom-lending/utils/data.js new file mode 100644 index 0000000000..79e6f80e45 --- /dev/null +++ b/src/adaptors/hatom-lending/utils/data.js @@ -0,0 +1,179 @@ +const BigNumber = require('bignumber.js'); +const { default: axios } = require('axios'); +const { request } = require('graphql-request'); + +const { queryPrices, queryMoneyMarkets, queryRewards } = require('./queries'); +const { calcLiquidStakingExchangeRate, calcSimulateExchangeRate } = require('./math'); + +const API_URL = 'https://mainnet-api.hatom.com/graphql'; +const WAD = '1000000000000000000'; + +async function getMoneyMarkets() { + const response = await request(API_URL, queryMoneyMarkets, {}); + + return response.queryMoneyMarket.reduce((prev, market) => { + if (!market.stateHistory.length) { + return prev; + } + + const symbol = market.underlying.symbol; + const latestState = market.stateHistory[0]; + const value = { + address: market.address, + decimals: market.underlying.decimals, + cash: latestState.cash, + borrows: latestState.borrows, + reserves: latestState.reserves, + rate: latestState.supplyRatePerSecond, + timestamp: latestState.timestamp, + totalSupply: latestState.totalSupply, + borrowRatePerSecond: latestState.borrowRatePerSecond, + supplyAPY: latestState.supplyAPY, + supplyRatePerSecond: latestState.supplyRatePerSecond, + totalColateral: market.totalCollateral, + }; + + return { + ...prev, + [symbol]: value, + }; + }, {}); +} + +async function getTokenPrices() { + const { queryToken, queryLiquidStaking } = + await request(API_URL, queryPrices, {}); + + const liquidStakingExchangeRate = calcLiquidStakingExchangeRate( + queryLiquidStaking?.[0]?.state?.cashReserve, + queryLiquidStaking?.[0]?.state?.totalShares, + ); + + const queryTokenPopulated = queryToken + .filter( + ({ dailyPriceHistory, symbol }) => + dailyPriceHistory.length > 0 || symbol === 'EGLD', + ) + .map((tokenItem) => { + const filteredToken = tokenItem.dailyPriceHistory; + + const priceEgld = filteredToken?.[0]?.quote?.priceInEgld || '0'; + + let dailyPriceInEgld = '0'; + + if (tokenItem.symbol == 'EGLD') { + dailyPriceInEgld = '1'; + } else if (tokenItem.symbol == 'SEGLD') { + dailyPriceInEgld = new BigNumber(1).multipliedBy(liquidStakingExchangeRate).dividedBy(WAD); + } else { + dailyPriceInEgld = priceEgld; + } + + const dailyPriceInUSD = filteredToken?.[0]?.price?.price || '0'; + + return { + ...tokenItem, + dailyPriceInEgld, + dailyPriceInUSD, + }; + }); + + const itemEgldInUSD = queryTokenPopulated.find( + ({ symbol }) => symbol === 'EGLD', + ); + const itemEgldInUSDC = queryTokenPopulated.find( + ({ symbol }) => symbol === 'USDC', + ); + + const agregatorEGLDInUSD = new BigNumber( + itemEgldInUSD?.dailyPriceInUSD || '0', + ) + .dividedBy(`1e${18}`) + .toString(); + + const priceHistoryEGLDInUSDC = + new BigNumber(1) + .dividedBy(itemEgldInUSDC?.dailyPriceInEgld || 0) + .toString() || '0'; + + const usdcPriceInEgld = new BigNumber(agregatorEGLDInUSD).isZero() + ? priceHistoryEGLDInUSDC + : agregatorEGLDInUSD; + + const egldInUsdc = usdcPriceInEgld !== '0' ? usdcPriceInEgld : '0'; + + return queryTokenPopulated.reduce( + (prev, { dailyPriceInEgld, dailyPriceInUSD, symbol }) => { + const priceUSD = + !new BigNumber(egldInUsdc).isEqualTo('0') || + !new BigNumber(dailyPriceInEgld).isEqualTo('0') + ? new BigNumber(egldInUsdc) + .multipliedBy(dailyPriceInEgld) + .toString() + : '0'; + + const value = !new BigNumber(dailyPriceInUSD).isZero() + ? new BigNumber(dailyPriceInUSD).dividedBy(`1e${18}`).toString() + : priceUSD; + + return { + ...prev, + [symbol]: value, + }; + }, + {}, + ) +} + +function getExchangeRates(moneyMarkets) { + const symbols = Object.keys(moneyMarkets); + return symbols.reduce( + (prev, symbol) => { + const value = calcSimulateExchangeRate({ + cash: moneyMarkets[symbol].cash || '0', + borrows: + moneyMarkets[symbol].borrows || '0', + reserves: + moneyMarkets[symbol].reserves || '0', + totalSupply: + moneyMarkets[symbol].totalSupply || '0', + rate: + moneyMarkets[symbol].supplyRatePerSecond || '0', + timestamp: + moneyMarkets[symbol].timestamp || new Date().toISOString(), + }) + return { + ...prev, + [symbol]: value + } + }, + {}, + ); +} + +async function getRewardsBatches() { + const response = await request(API_URL, queryRewards, {}); + return response.queryRewardsBatchState.reduce((prev, batch) => { + const symbol = batch.moneyMarket.underlying.symbol; + const value = { + id: batch.id, + speed: batch.speed, + type: batch.type, + endTime: batch.endTime, + fullyDistributed: batch.fullyDistributed, + totalAmount: batch.totalAmount, + rewardsToken: batch.rewardsToken, + } + return { + ...prev, + [symbol]: value, + }; + }, {}) +} + +module.exports = { + getMoneyMarkets, + getTokenPrices, + getExchangeRates, + getRewardsBatches, +} diff --git a/src/adaptors/hatom-lending/utils/math.js b/src/adaptors/hatom-lending/utils/math.js new file mode 100644 index 0000000000..3e825db68d --- /dev/null +++ b/src/adaptors/hatom-lending/utils/math.js @@ -0,0 +1,92 @@ +const BigNumber = require('bignumber.js'); + +const calcRewardsAPY = ({ + speed, + hTokenExchangeRate, + totalCollateral, + marketPrice, + rewardsToken, + rewardsTokenPrice, + marketDecimals, +}) => { + const SECONDS_PER_DAY = new BigNumber(86400); + const DAYS_PER_YEAR = new BigNumber(365); + const secondsInAYear = new BigNumber(SECONDS_PER_DAY).multipliedBy( + DAYS_PER_YEAR, + ); + + const sp = new BigNumber(speed).dividedBy(`1e${18 + rewardsToken?.decimals}`); + + const calc1 = sp + .multipliedBy(rewardsTokenPrice) + .multipliedBy(secondsInAYear); + + const calc2 = new BigNumber(totalCollateral) + .multipliedBy(hTokenExchangeRate) + .dividedBy(`1e18`) + .dividedBy(`1e${marketDecimals}`) + .multipliedBy(marketPrice); + + if (calc2.isEqualTo(0)) { + return '0'; + } + + const result = calc1.dividedBy(calc2).multipliedBy(100); + + return result.isNaN() ? '0' : result.toString(); +}; + +const calcSimulateExchangeRate = ({ + cash, + borrows, + reserves, + totalSupply, + rate, + timestamp, +}) => { + return new BigNumber( + calcExchangeRate({ cash, borrows, reserves, totalSupply }), + ) + .multipliedBy(calcRateSimulate(rate, timestamp)) + .toString(); +}; + +const calcRateSimulate = (rate, timestamp) => { + const currentDate = new Date(); + const currentDateInSeconds = currentDate.getTime() / 1000; + const timestampInSeconds = new Date(timestamp).getTime() / 1000; + + return new BigNumber(rate) + .multipliedBy(currentDateInSeconds - timestampInSeconds) + .dividedBy(`1e18`) + .plus(1) + .toString(); +}; + +const calcExchangeRate = ({ cash, borrows, reserves, totalSupply }) => { + const value = new BigNumber(cash) + .plus(borrows) + .minus(reserves) + .times(1e18) + .div(totalSupply) + .toFixed(0); + + return new BigNumber(value).isNaN() ? '0' : value; +}; + +const calcLiquidStakingExchangeRate = (cashReserve, totalShares) => { + if (totalShares === '0') { + return INITIAL_EXCHANGE_RATE; + } + + return new BigNumber(cashReserve) + .multipliedBy('1e18') + .dividedBy(totalShares) + .toFixed(0, BigNumber.ROUND_DOWN); +}; + +module.exports = { + calcRewardsAPY, + calcLiquidStakingExchangeRate, + calcSimulateExchangeRate, +}; \ No newline at end of file diff --git a/src/adaptors/hatom-lending/utils/queries.js b/src/adaptors/hatom-lending/utils/queries.js new file mode 100644 index 0000000000..2bbf6c391d --- /dev/null +++ b/src/adaptors/hatom-lending/utils/queries.js @@ -0,0 +1,78 @@ +const queryPrices = ` + query QueryTokenPrices { + queryLiquidStaking { + state { + cashReserve + totalShares + } + } + queryToken { + id + symbol + dailyPriceHistory(first: 1, order: { desc: day }) { + quote { + priceInEgld + timestamp + } + price { + price + timestamp + } + } + } + } +`; + +const queryMoneyMarkets = ` +query QueryMoneyMarket { + queryMoneyMarket { + address + totalCollateral + underlying { + symbol + name + decimals + id + } + stateHistory(first:1, order:{ + desc: timestamp + }) { + cash + borrows + reserves + timestamp + supplyAPY + supplyRatePerSecond + borrowAPY + borrowRatePerSecond + totalSupply + } + } + }` + +const queryRewards = ` +query QueryRewards { + queryRewardsBatchState { + id + speed + type + endTime + fullyDistributed + totalAmount + moneyMarket{ + address + underlying{ + symbol + } + } + rewardsToken{ + symbol + decimals + } + } +}` +module.exports = { + queryPrices, + queryMoneyMarkets, + queryRewards +}; \ No newline at end of file diff --git a/src/adaptors/hedge/index.js b/src/adaptors/hedge/index.js new file mode 100644 index 0000000000..6639790bdf --- /dev/null +++ b/src/adaptors/hedge/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils'); + +const apr = async () => { + const apyData = await utils.getData( + 'http://hedge.so/api/yield?mode=defillama' + ); + + const pools = []; + for (const pool of apyData) { + const name = pool.symbol.split(' '); + pools.push({ + pool: pool.pool, + chain: utils.formatChain('solana'), + project: 'hedge', + symbol: name[0], + poolMeta: name + .slice(1) + .join(' ') + .replace(/[\])}[{(]/g, ''), + tvlUsd: Number(pool.tvl), + apyBase: Number(pool.apyBase), + apyReward: Number(pool.apyReward), + rewardTokens: pool.rewardTokens, + underlyingTokens: pool.underlyingTokens, + }); + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: apr, + url: 'https://www.hedge.so/pools', +}; diff --git a/src/adaptors/hedgefarm/index.js b/src/adaptors/hedgefarm/index.js new file mode 100644 index 0000000000..fa2004f8ae --- /dev/null +++ b/src/adaptors/hedgefarm/index.js @@ -0,0 +1,105 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const ALPHA1_V1_CONTRACT = '0xdE4133f0CFA1a61Ba94EC64b6fEde4acC1fE929E'; +const ALPHA1_V2_CONTRACT = '0x60908A71FbC9027838277f9f98e458BeF2A201da'; +const ALPHA2_CONTRACT = '0x3C390b91Fc2f248E75Cd271e2dAbF7DcC955B1A3'; + +const abiAlpha1 = { + inputs: [], + name: 'totalBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const abiAlpha2 = { + inputs: [], + name: 'getLastUpdatedModulesBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +async function tvlAlpha1() { + const balanceV1 = ( + await sdk.api.abi.call({ + abi: abiAlpha1, + chain: 'avax', + target: ALPHA1_V1_CONTRACT, + params: [], + }) + ).output; + + const balanceV2 = ( + await sdk.api.abi.call({ + abi: abiAlpha1, + chain: 'avax', + target: ALPHA1_V2_CONTRACT, + params: [], + }) + ).output; + + return parseFloat(balanceV1) + parseFloat(balanceV2); +} + +async function tvlAlpha2() { + const totalBalance = ( + await sdk.api.abi.call({ + abi: abiAlpha2, + chain: 'avax', + target: ALPHA2_CONTRACT, + params: [], + }) + ).output; + + return totalBalance; +} + +const poolsFunction = async () => { + const alpha1ApyData = await utils.getData( + 'https://api.hedgefarm.finance/alpha1/v2/performance' + ); + + const alpha2ApyData = await utils.getData( + 'https://api.hedgefarm.finance/alpha2/performance' + ); + + const btcbKey = 'avax:0x152b9d0fdc40c096757f570a51e494bd4b943e50'; + const btcbTokenPrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${btcbKey}`) + ).body.coins[btcbKey].price; + + const balanceAlpha1 = await tvlAlpha1(); + const balanceAlpha2 = await tvlAlpha2(); + + const alpha1 = { + pool: '0xdE4133f0CFA1a61Ba94EC64b6fEde4acC1fE929E', + chain: utils.formatChain('avalanche'), + project: 'hedgefarm', + symbol: utils.formatSymbol('USDC'), + tvlUsd: balanceAlpha1 / 1e6, + apy: alpha1ApyData.averageApy * 100, + poolMeta: '28 Days Lock-up', + underlyingTokens: ['0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'], + }; + + const alpha2 = { + pool: '0x3C390b91Fc2f248E75Cd271e2dAbF7DcC955B1A3', + chain: utils.formatChain('avalanche'), + project: 'hedgefarm', + symbol: utils.formatSymbol('BTC.b'), + tvlUsd: (balanceAlpha2 / 1e8) * btcbTokenPrice, + apy: alpha2ApyData.last24hApy * 100, + underlyingTokens: ['0x50b7545627a5162F82A992c33b87aDc75187B218'], + }; + + return [alpha1, alpha2]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://hedgefarm.finance', +}; diff --git a/src/adaptors/helius-staked-sol/index.js b/src/adaptors/helius-staked-sol/index.js new file mode 100644 index 0000000000..e3c2f1f482 --- /dev/null +++ b/src/adaptors/helius-staked-sol/index.js @@ -0,0 +1,36 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const HSOL_ADDRESS = 'he1iusmfkpAdwvxLNGV8Y1iSbj4rUy6yMhEA3fotn9A'; +const priceKey = `solana:${HSOL_ADDRESS}`; + +const apy = async () => { + const totalSupply = await getTotalSupply(HSOL_ADDRESS); + + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const currentPrice = priceResponse.data.coins[priceKey].price; + + const apyResponse = await axios.get( + `https://extra-api.sanctum.so/v1/apy/latest?lst=${HSOL_ADDRESS}` + ); + const apy = apyResponse.data.apys[HSOL_ADDRESS]; + + return [ + { + pool: HSOL_ADDRESS, + chain: 'Solana', + project: 'helius-staked-sol', + symbol: 'HSOL', + tvlUsd: totalSupply * currentPrice, + apyBase: apy * 100, + underlyingTokens: [HSOL_ADDRESS], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.helius.dev/blog/solana-staking-simplified-guide-to-sol-staking#what-is-liquid-staking', +}; diff --git a/src/adaptors/hercules-v2/factory.js b/src/adaptors/hercules-v2/factory.js new file mode 100644 index 0000000000..3ba1439aae --- /dev/null +++ b/src/adaptors/hercules-v2/factory.js @@ -0,0 +1,348 @@ +module.exports = [ + { + inputs: [{ internalType: 'address', name: 'feeTo_', type: 'address' }], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'FeePercentOwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevFeeTo', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newFeeTo', + type: 'address', + }, + ], + name: 'FeeToTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'prevOwnerFeeShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'ownerFeeShare', + type: 'uint256', + }, + ], + name: 'OwnerFeeShareUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token0', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token1', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'pair', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'length', + type: 'uint256', + }, + ], + name: 'PairCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'referrer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'prevReferrerFeeShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'referrerFeeShare', + type: 'uint256', + }, + ], + name: 'ReferrerFeeShareUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'prevOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'SetStableOwnershipTransferred', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'OWNER_FEE_SHARE_MAX', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'REFERER_FEE_SHARE_MAX', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allPairs', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'allPairsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tokenA', type: 'address' }, + { internalType: 'address', name: 'tokenB', type: 'address' }, + ], + name: 'createPair', + outputs: [{ internalType: 'address', name: 'pair', type: 'address' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feeInfo', + outputs: [ + { internalType: 'uint256', name: '_ownerFeeShare', type: 'uint256' }, + { internalType: 'address', name: '_feeTo', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feePercentOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'feeTo', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'getPair', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'ownerFeeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'referrersFeeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_feePercentOwner', type: 'address' }, + ], + name: 'setFeePercentOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: '_feeTo', type: 'address' }], + name: 'setFeeTo', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'setOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'newOwnerFeeShare', type: 'uint256' }, + ], + name: 'setOwnerFeeShare', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'referrer', type: 'address' }, + { internalType: 'uint256', name: 'referrerFeeShare', type: 'uint256' }, + ], + name: 'setReferrerFeeShare', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_setStableOwner', type: 'address' }, + ], + name: 'setSetStableOwner', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'setStableOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/hercules-v2/index.js b/src/adaptors/hercules-v2/index.js new file mode 100644 index 0000000000..9a994d178d --- /dev/null +++ b/src/adaptors/hercules-v2/index.js @@ -0,0 +1,240 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const masterchefAbi = require('./masterchef'); +const stakingPositionAbi = require('./stakingPosition'); +const factoryAbi = require('./factory'); +const lp = require('./lp'); +const lpAbi = require('./lp'); +const axios = require('axios'); + +const masterchef = '0x438718E30B6395c4a0B5622490CC3DC9B1B8ba3d'; +const factory = '0xF38E7c7f8eA779e8A193B61f9155E6650CbAE095'; +const TORCH = '0xbB1676046C36BCd2F6fD08d8f60672c7087d9aDF'; + +const utils = require('../utils'); + +const url = + 'https://metisapi.0xgraph.xyz/subgraphs/name/amm-subgraph-andromeda/'; + +const query = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + reserve0 + reserve1 + token0 { + id + symbol + } + token1 { + id + symbol + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + // --- fee tier + const allPairsLength = ( + await sdk.api.abi.call({ + target: factory, + abi: factoryAbi.find((m) => m.name === 'allPairsLength'), + chain: chainString, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: factory, + params: [i], + })), + abi: factoryAbi.find((m) => m.name === 'allPairs'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const token0FeePercent = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: lpAbi.find((m) => m.name === 'token0FeePercent'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const token1FeePercent = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: lpAbi.find((m) => m.name === 'token1FeePercent'), + chain: chainString, + }) + ).output.map((o) => o.output); + + // --- rewards + const poolsLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolsLength'), + chain: chainString, + }) + ).output; + + const pools = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'getPoolAddressByIndex'), + chain: chainString, + }) + ).output.map((o) => o.output); + + let poolInfo = ( + await sdk.api.abi.multiCall({ + calls: pools.map((i) => ({ + target: i, + })), + abi: stakingPositionAbi.find((m) => m.name === 'getPoolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const lpTokens = poolInfo.map((p) => p.lpToken); + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((i) => ({ + target: i, + })), + abi: lp.find((m) => m.name === 'totalSupply'), + chain: chainString, + }) + ).output.map((o) => o.output); + + poolInfo = poolInfo.map((p, i) => ({ ...p, totalSupply: totalSupply[i] })); + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPoint'), + chain: chainString, + }) + ).output; + + const torchPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'emissionRate'), + chain: chainString, + }) + ).output / 1e18; + + const priceKey = `metis:${TORCH}`; + const torchPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const torchPerYearUsd = torchPerSec * 86400 * 365 * torchPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + data = await utils.tvl(data, chainString); + + // add fee tier + data = data.map((p) => { + const idx = allPairs.findIndex( + (i) => i.toLowerCase() === p.id.toLowerCase() + ); + const feeAvg = + ((Number(token0FeePercent[idx]) + Number(token1FeePercent[idx])) / 2) * + 10; + return { ...p, feeTier: feeAvg }; + }); + + // calculate apy + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + // build pool objects + data = data.map((p) => { + const pi = poolInfo.find( + (pi) => pi.lpToken.toLowerCase() === p.id?.toLowerCase() + ); + + const farmReserveRatio = pi?.lpSupplyWithMultiplier / pi?.totalSupply; + + const apyReward = + (((pi?.allocPoint / totalAllocPoint) * torchPerYearUsd) / + (p.totalValueLockedUSD * farmReserveRatio)) * + 100; + + // rewards are 20% in liquid torch and 80% in non-transferable xtorch (which can be used to boost though) + // gonna report 20% torch only + + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'hercules-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward: apyReward * 0.2, + underlyingTokens: [p.token0.id, p.token1.id], + rewardTokens: apyReward > 0 ? [TORCH] : [], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([topLvl('metis', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://app.hercules.exchange/liquidity', +}; diff --git a/src/adaptors/hercules-v2/lp.js b/src/adaptors/hercules-v2/lp.js new file mode 100644 index 0000000000..65d0d5cb14 --- /dev/null +++ b/src/adaptors/hercules-v2/lp.js @@ -0,0 +1,626 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { indexed: false, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'DrainWrongToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'token0FeePercent', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'token1FeePercent', + type: 'uint16', + }, + ], + name: 'FeePercentUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'SetPairTypeImmutable', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'prevStableSwap', + type: 'bool', + }, + { + indexed: false, + internalType: 'bool', + name: 'stableSwap', + type: 'bool', + }, + ], + name: 'SetStableSwap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Skim', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'FEE_DENOMINATOR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MAX_FEE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'drainWrongToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + ], + name: 'getAmountOut', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint16', name: '_token0FeePercent', type: 'uint16' }, + { internalType: 'uint16', name: '_token1FeePercent', type: 'uint16' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pairTypeImmutable', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'precisionMultiplier0', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'precisionMultiplier1', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint16', name: 'newToken0FeePercent', type: 'uint16' }, + { internalType: 'uint16', name: 'newToken1FeePercent', type: 'uint16' }, + ], + name: 'setFeePercent', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'setPairTypeImmutable', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bool', name: 'stable', type: 'bool' }, + { internalType: 'uint112', name: 'expectedReserve0', type: 'uint112' }, + { internalType: 'uint112', name: 'expectedReserve1', type: 'uint112' }, + ], + name: 'setStableSwap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'stableSwap', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + { internalType: 'address', name: 'referrer', type: 'address' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0FeePercent', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1FeePercent', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/hercules-v2/masterchef.js b/src/adaptors/hercules-v2/masterchef.js new file mode 100644 index 0000000000..3ba12d541a --- /dev/null +++ b/src/adaptors/hercules-v2/masterchef.js @@ -0,0 +1,318 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IGrailTokenV2', + name: 'grailToken_', + type: 'address', + }, + { internalType: 'uint256', name: 'startTime_', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ClaimRewards', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + ], + name: 'PoolAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + ], + name: 'PoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reserve', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + ], + name: 'PoolUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'emergencyUnlock', + type: 'bool', + }, + ], + name: 'SetEmergencyUnlock', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousYieldBooster', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newYieldBooster', + type: 'address', + }, + ], + name: 'SetYieldBooster', + type: 'event', + }, + { + inputs: [], + name: 'activePoolsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract INFTPool', name: 'nftPool', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'bool', name: 'withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'claimRewards', + outputs: [ + { internalType: 'uint256', name: 'rewardsAmount', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyUnlock', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emissionRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getActivePoolAddressByIndex', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getPoolAddressByIndex', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'poolAddress_', type: 'address' }, + ], + name: 'getPoolInfo', + outputs: [ + { internalType: 'address', name: 'poolAddress', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'reserve', type: 'uint256' }, + { internalType: 'uint256', name: 'poolEmissionRate', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'grailToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'poolAddress', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'bool', name: 'withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'emergencyUnlock_', type: 'bool' }], + name: 'setEmergencyUnlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IYieldBooster', + name: 'yieldBooster_', + type: 'address', + }, + ], + name: 'setYieldBooster', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'nftPool', type: 'address' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'yieldBooster', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/hercules-v2/stakingPosition.js b/src/adaptors/hercules-v2/stakingPosition.js new file mode 100644 index 0000000000..afdc34f103 --- /dev/null +++ b/src/adaptors/hercules-v2/stakingPosition.js @@ -0,0 +1,909 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'AddToPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'approved', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockDuration', + type: 'uint256', + }, + ], + name: 'CreatePosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { indexed: false, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'pending', + type: 'uint256', + }, + ], + name: 'HarvestPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lockDuration', + type: 'uint256', + }, + ], + name: 'LockPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenIds', + type: 'uint256[]', + }, + ], + name: 'MergePositions', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accRewardsPerShare', + type: 'uint256', + }, + ], + name: 'PoolUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'boostPoints', + type: 'uint256', + }, + ], + name: 'SetBoost', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'maxGlobalMultiplier', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'maxBoostMultiplier', + type: 'uint256', + }, + ], + name: 'SetBoostMultiplierSettings', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'emergencyUnlock', + type: 'bool', + }, + ], + name: 'SetEmergencyUnlock', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'maxLockDuration', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'maxLockMultiplier', + type: 'uint256', + }, + ], + name: 'SetLockMultiplierSettings', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'operator', + type: 'address', + }, + ], + name: 'SetOperator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'operator', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'isAdded', type: 'bool' }, + ], + name: 'SetUnlockOperator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'xGrailRewardsShare', + type: 'uint256', + }, + ], + name: 'SetXGrailRewardsShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'splitAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTokenId', + type: 'uint256', + }, + ], + name: 'SplitPosition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawFromPosition', + type: 'event', + }, + { + inputs: [], + name: 'MAX_BOOST_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_GLOBAL_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_LOCK_MULTIPLIER_LIMIT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amountToAdd', type: 'uint256' }, + ], + name: 'addToPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseURI', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'boost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'createPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyUnlock', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'exists', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'boostPoints', type: 'uint256' }, + ], + name: 'getMultiplierByBoostPoints', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'getMultiplierByLockDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getMultiplierSettings', + outputs: [ + { internalType: 'uint256', name: 'maxGlobalMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxBoostMultiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPoolInfo', + outputs: [ + { internalType: 'address', name: 'lpToken', type: 'address' }, + { internalType: 'address', name: 'grailToken', type: 'address' }, + { internalType: 'address', name: 'xGrailToken', type: 'address' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardsPerShare', type: 'uint256' }, + { internalType: 'uint256', name: 'lpSupply', type: 'uint256' }, + { + internalType: 'uint256', + name: 'lpSupplyWithMultiplier', + type: 'uint256', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getStakingPosition', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'uint256', + name: 'amountWithMultiplier', + type: 'uint256', + }, + { internalType: 'uint256', name: 'startLockTime', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'lockMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'boostPoints', type: 'uint256' }, + { internalType: 'uint256', name: 'totalMultiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'harvestPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvestPositionTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'tokenIds', type: 'uint256[]' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvestPositionsTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'hasDeposits', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ICamelotMaster', + name: 'master_', + type: 'address', + }, + { internalType: 'contract IERC20', name: 'grailToken', type: 'address' }, + { + internalType: 'contract IXGrailToken', + name: 'xGrailToken', + type: 'address', + }, + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'initialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_operator', type: 'address' }], + name: 'isUnlockOperator', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isUnlocked', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastTokenId', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'lockPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'master', + outputs: [ + { internalType: 'contract ICamelotMaster', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'tokenIds', type: 'uint256[]' }, + { internalType: 'uint256', name: 'lockDuration', type: 'uint256' }, + ], + name: 'mergePositions', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'operator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'pendingRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'renewLockPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'bytes', name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'operator', type: 'address' }, + { internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'maxGlobalMultiplier', type: 'uint256' }, + { internalType: 'uint256', name: 'maxBoostMultiplier', type: 'uint256' }, + ], + name: 'setBoostMultiplierSettings', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'emergencyUnlock_', type: 'bool' }], + name: 'setEmergencyUnlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'maxLockDuration', type: 'uint256' }, + { internalType: 'uint256', name: 'maxLockMultiplier', type: 'uint256' }, + ], + name: 'setLockMultiplierSettings', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator_', type: 'address' }], + name: 'setOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_operator', type: 'address' }, + { internalType: 'bool', name: 'add', type: 'bool' }, + ], + name: 'setUnlockOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'xGrailRewardsShare_', type: 'uint256' }, + ], + name: 'setXGrailRewardsShare', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'splitAmount', type: 'uint256' }, + ], + name: 'splitPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'tokenByIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'tokenOfOwnerByIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'unboost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'unlockOperator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unlockOperatorsLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + { internalType: 'uint256', name: 'amountToWithdraw', type: 'uint256' }, + ], + name: 'withdrawFromPosition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'xGrailRewardsShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'yieldBooster', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/hercules-v3/index.js b/src/adaptors/hercules-v3/index.js new file mode 100644 index 0000000000..a237bfe6d6 --- /dev/null +++ b/src/adaptors/hercules-v3/index.js @@ -0,0 +1,136 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const url = + 'https://metisapi.0xgraph.xyz/subgraphs/name/cryptoalgebra/analytics'; + +const query = gql` + { + pools(first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + token0 { + symbol + id + decimals + } + token1 { + id + symbol + decimals + } + reserve0: totalValueLockedToken0 + reserve1: totalValueLockedToken1 + feeOtZ + feeZtO + + } + } +`; + +const queryPrior = gql` + { + pools(first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pools; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pools; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pools; + + const balanceCalls = []; + for (const pool of data) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + data = data.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + data = await utils.tvl(data, chainString); + + data = data.map((p) => ({ + ...p, + feeTier: (Number(p.feeOtZ) + Number(p.feeZtO)) / 2, + })); + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v3')); + + data = data.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'hercules-v3', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens: [p.token0.id, p.token1.id], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + url: `https://app.hercules.exchange/pools/${p.id}`, + }; + }); + + return data; +}; + +const main = async (timestamp = null) => { + console.log(timestamp); + const data = await Promise.all([topLvl('metis', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: main, +}; diff --git a/src/adaptors/hermes-protocol/index.ts b/src/adaptors/hermes-protocol/index.ts new file mode 100644 index 0000000000..5b0fa407e3 --- /dev/null +++ b/src/adaptors/hermes-protocol/index.ts @@ -0,0 +1,28 @@ +const utils = require('../utils'); + +const API_URL: string = 'http://api.maiadao.io:9090/apr'; + +const getApy = async () => { + const res = await utils.getData(API_URL); + + const pools = res.map((pool) => { + return { + pool: pool.poolAddress, + chain: utils.formatChain('metis'), + project: 'hermes-protocol', + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd: pool.tvlUsd, + apyReward: pool.apr, + underlyingTokens: [pool.token0.address, pool.token1.address], + rewardTokens: pool.rewardAddresses, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://hermes.maiadao.io/#/stake', +}; diff --git a/src/adaptors/hermes-v2/index.ts b/src/adaptors/hermes-v2/index.ts new file mode 100644 index 0000000000..8ac0287e79 --- /dev/null +++ b/src/adaptors/hermes-v2/index.ts @@ -0,0 +1,881 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils'); + +// ============================================================================ +// CONFIGURATION +// ============================================================================ + +const CHAIN = 'arbitrum'; +const PROJECT = 'hermes-v2'; + +// Contract Addresses on Arbitrum +const ADDRESSES = { + // HERMES + HERMES: '0x45940000009600102A1c002F0097C4A500fa00AB', + + // bHERMES + bHERMES: '0x3A0000000000E1007cEb00351F65a1806eCd937C', + + // bHERMES-Gauges + GAUGE_WEIGHT: '0xe6D0aeA7cEf79B08B906e0C455C25042b57b23Ed', + + // BaseV2Minter + BASE_V2_MINTER: '0x000000B473F20DEA03618d00315900eC5900dc59', + + // UniswapV3Staker + UNISWAP_V3_STAKER: '0x54De3b7b5D1993Db4B2a93C897b5272FBd60e99E', + + // FlywheelGaugeRewards + FLYWHEEL_GAUGE_REWARDS: '0x000000b53E67c90000e1C22e1530c70020657Ff7', + + // Uniswap V3 NonfungiblePositionManager + NFT_POSITION_MANAGER: '0xC36442b4a4522E871399CD717aBDD847Ab11FE88', +}; + +// Epoch timing +const WEEK_SECONDS = 7 * 24 * 60 * 60; +const YEAR_IN_SECONDS = 31_536_000; + +// ============================================================================ +// EPOCH CONTEXT +// ============================================================================ + +interface EpochContext { + currentBlock: number; + timestamp: number | null; + epochStartTime: number; // from getIncentiveStartTime() + epochEndTime: number; // from getIncentiveStartTime() + WEEK_SECONDS + epochStartBlock: number; +} + +// ============================================================================ +// HELPER FUNCTIONS +// ============================================================================ + +/** + * Get incentive epoch start time for a given timestamp/block + */ +const getIncentiveStartTime = async (timestamp = null) => { + const referenceTime = timestamp || Math.floor(Date.now() / 1000); + + return Math.trunc((referenceTime - 43200) / 604800) * 604800 + 43200; +}; + +/** + * Build epoch context - compute shared epoch data once + */ +const getEpochContext = async ( + timestamp: number | null, + currentBlock: number +): Promise => { + const epochStartTime = await getIncentiveStartTime(timestamp); + const [epochStartBlock] = await utils.getBlocksByTime( + [epochStartTime], + CHAIN + ); + + const epochEndTime = epochStartTime + WEEK_SECONDS; + + return { + currentBlock, + timestamp, + epochStartTime, + epochEndTime, + epochStartBlock, + }; +}; + +/** + * Compute incentiveId from pool address and epoch start + */ +const computeIncentiveId = (poolAddress, epochStart) => { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ['address', 'uint96'], + [poolAddress, epochStart] + ) + ); +}; + +/** + * Convert tick to sqrt price + * Based on Uniswap V3 Math: price = 1.0001^tick, sqrtPrice = sqrt(price) + */ +const tickToSqrtPrice = (tick) => { + return Math.sqrt(Math.pow(1.0001, tick)); +}; + +/** + * Calculate token amounts from liquidity and tick range + */ +const getAmountsFromLiquidity = ( + liquidity, + tickLower, + tickUpper, + currentTick, + decimals0, + decimals1 +) => { + const currentPrice = tickToSqrtPrice(currentTick); + const lowerPrice = tickToSqrtPrice(tickLower); + const upperPrice = tickToSqrtPrice(tickUpper); + + let amount0, amount1; + + if (currentPrice < lowerPrice) { + // Current price below range - all token0 + amount1 = 0; + amount0 = liquidity * (1 / lowerPrice - 1 / upperPrice); + } else if (lowerPrice <= currentPrice && currentPrice <= upperPrice) { + // Current price in range - mixed + amount1 = liquidity * (currentPrice - lowerPrice); + amount0 = liquidity * (1 / currentPrice - 1 / upperPrice); + } else { + // Current price above range - all token1 + amount1 = liquidity * (upperPrice - lowerPrice); + amount0 = 0; + } + + // Apply decimals + return [amount0 / 10 ** decimals0, amount1 / 10 ** decimals1]; +}; + +/** + * Get all gauge addresses from AddGauge events + */ +const getAllGauges = async (currentBlock) => { + const addGaugeTopic = ethers.utils.id('AddGauge(address)'); + + const logs = await sdk.api.util.getLogs({ + target: ADDRESSES.GAUGE_WEIGHT, + topic: '', + toBlock: currentBlock, + fromBlock: 1, + keys: [], + chain: CHAIN, + topics: [addGaugeTopic], + }); + + if (!logs.output || logs.output.length === 0) { + return []; + } + + // Extract gauge addresses from event topics + return logs.output.map((log) => '0x' + log.topics[1].slice(-40)); +}; + +/** + * Get the pool address linked to a gauge + */ +const getGaugeInfo = async (gaugeAddress, block = null) => { + try { + const strategyResult = await sdk.api.abi.call({ + target: gaugeAddress, + abi: 'function strategy() external view returns (address)', + chain: CHAIN, + block, + }); + + return { + strategy: strategyResult.output, + }; + } catch (e) { + return null; + } +}; + +/** + * Get UniswapV3 pool info + */ +const getPoolInfo = async (poolAddress, block = null) => { + try { + const [token0Result, token1Result, feeResult, liquidityResult] = + await Promise.all([ + sdk.api.abi.call({ + target: poolAddress, + abi: 'function token0() external view returns (address)', + chain: CHAIN, + block, + }), + sdk.api.abi.call({ + target: poolAddress, + abi: 'function token1() external view returns (address)', + chain: CHAIN, + block, + }), + sdk.api.abi.call({ + target: poolAddress, + abi: 'function fee() external view returns (uint24)', + chain: CHAIN, + block, + }), + sdk.api.abi.call({ + target: poolAddress, + abi: 'function liquidity() external view returns (uint128)', + chain: CHAIN, + block, + }), + ]); + + return { + token0: token0Result.output, + token1: token1Result.output, + fee: feeResult.output, + liquidity: liquidityResult.output, + }; + } catch (e) { + return null; + } +}; + +/** + * Get ERC20 token metadata + */ +const getTokenMetadata = async (tokenAddress, block = null) => { + try { + const [symbolResult, decimalsResult] = await Promise.all([ + sdk.api.abi.call({ + target: tokenAddress, + abi: 'function symbol() external view returns (string)', + chain: CHAIN, + block, + }), + sdk.api.abi.call({ + target: tokenAddress, + abi: 'function decimals() external view returns (uint8)', + chain: CHAIN, + block, + }), + ]); + + return { + symbol: symbolResult.output, + decimals: parseInt(decimalsResult.output), + }; + } catch (e) { + return { symbol: 'UNKNOWN', decimals: 18 }; + } +}; + +/** + * Get staked token IDs for a pool by querying TokenStaked events + */ +const getStakedTokenIds = async ( + incentiveId: string, + epochContext: EpochContext +) => { + try { + // Query TokenStaked events for this specific incentive + const tokenStakedTopic = ethers.utils.id( + 'TokenStaked(uint256,bytes32,bool)' + ); + const stakedLogs = await sdk.api.util.getLogs({ + target: ADDRESSES.UNISWAP_V3_STAKER, + topic: '', + toBlock: epochContext.currentBlock, + fromBlock: + epochContext.epochStartBlock > 0 ? epochContext.epochStartBlock : 1, + keys: [], + chain: CHAIN, + topics: [tokenStakedTopic, null, incentiveId], + }); + + if (!stakedLogs.output || stakedLogs.output.length === 0) { + return []; + } + + // Extract and deduplicate staked tokenIds + const tokenIds = stakedLogs.output.map((log) => BigInt(log.topics[1])); + return [...new Set(tokenIds.map((id) => id.toString()))].map((id: string) => + BigInt(id) + ); + } catch (e) { + return []; + } +}; + +/** + * Get staked liquidity for a position from the staker contract + */ +const getStakedLiquidity = async (tokenId, incentiveId, block = null) => { + try { + const result = await sdk.api.abi.call({ + target: ADDRESSES.UNISWAP_V3_STAKER, + abi: 'function stakes(uint256 tokenId, bytes32 incentiveId) external view returns (uint160 secondsPerLiquidityInsideInitialX128, uint128 liquidity)', + params: [tokenId.toString(), incentiveId], + chain: CHAIN, + block, + }); + + return BigInt(result.output.liquidity || 0); + } catch (e) { + return 0n; + } +}; + +/** + * Get position info from NFT Position Manager + */ +const getPositionInfo = async (tokenId, block = null) => { + try { + const result = await sdk.api.abi.call({ + target: ADDRESSES.NFT_POSITION_MANAGER, + abi: 'function positions(uint256 tokenId) external view returns (uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1)', + params: [tokenId.toString()], + chain: CHAIN, + block, + }); + + return { + token0: result.output.token0, + token1: result.output.token1, + tickLower: parseInt(result.output.tickLower), + tickUpper: parseInt(result.output.tickUpper), + liquidity: BigInt(result.output.liquidity), + }; + } catch (e) { + return null; + } +}; + +/** + * Get pool slot0 data + */ +const getPoolSlot0 = async (poolAddress, block = null) => { + try { + const result = await sdk.api.abi.call({ + target: poolAddress, + abi: 'function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)', + chain: CHAIN, + block, + }); + + return { + sqrtPriceX96: BigInt(result.output.sqrtPriceX96), + tick: parseInt(result.output.tick), + }; + } catch (e) { + return null; + } +}; + +/** + * Calculate staked TVL from staked positions + */ +const calculateStakedTvl = async ( + token0: string, + token1: string, + decimals0: number, + decimals1: number, + prices: Record, + slot0: { sqrtPriceX96: bigint; tick: number }, + incentiveId: string, + epochContext: EpochContext +) => { + try { + // Get staked token IDs for this pool + const tokenIds = await getStakedTokenIds(incentiveId, epochContext); + + if (tokenIds.length === 0) { + return 0; + } + + const price0 = prices[token0.toLowerCase()] || 0; + const price1 = prices[token1.toLowerCase()] || 0; + + if (price0 === 0 && price1 === 0) return 0; + + let totalTvl = 0; + + // Calculate TVL from each staked position + for (const tokenId of tokenIds) { + // Get staked liquidity from staker contract + const stakedLiquidity = await getStakedLiquidity( + tokenId, + incentiveId, + epochContext.currentBlock + ); + + if (stakedLiquidity === 0n) continue; + + // Get position tick range from NFT manager + const position = await getPositionInfo( + tokenId, + epochContext.currentBlock + ); + if (!position) continue; + + // Calculate token amounts from liquidity + const [amount0, amount1] = getAmountsFromLiquidity( + Number(stakedLiquidity), + position.tickLower, + position.tickUpper, + slot0.tick, + decimals0, + decimals1 + ); + + // Add to TVL + if (price0 > 0 && price1 > 0) { + totalTvl += amount0 * price0 + amount1 * price1; + } else if (price0 > 0) { + totalTvl += amount0 * price0; + } else if (price1 > 0) { + totalTvl += amount1 * price1; + } + } + + return totalTvl; + } catch (e) { + console.error('Error calculating staked TVL:', e.message); + return 0; + } +}; + +/** + * Get gauge weight allocation percentage + * @dev this will be used for bHERMES gauge vote yield calculation, currently only used for display purposes + */ +const getGaugeAllocation = async (gaugeAddress, block = null) => { + try { + const [totalWeightResult, gaugeWeightResult] = await Promise.all([ + sdk.api.abi.call({ + target: ADDRESSES.GAUGE_WEIGHT, + abi: 'function totalWeight() external view returns (uint256)', + chain: CHAIN, + block, + }), + sdk.api.abi.call({ + target: ADDRESSES.GAUGE_WEIGHT, + abi: 'function getGaugeWeight(address) external view returns (uint256)', + params: [gaugeAddress], + chain: CHAIN, + block, + }), + ]); + + const totalWeight = BigInt(totalWeightResult.output); + const gaugeWeight = BigInt(gaugeWeightResult.output); + + if (totalWeight === 0n) return 0; + + // Return allocation as percentage + return Number((gaugeWeight * 10000n) / totalWeight) / 100; + } catch (e) { + return 0; + } +}; + +/** + * Get incentive data from QueueRewards events on FlywheelGaugeRewards emitted at epoch start + */ +const getIncentiveFromEvents = async ( + incentiveId: string, + epochContext: EpochContext +) => { + try { + const result = await sdk.api.abi.call({ + target: ADDRESSES.UNISWAP_V3_STAKER, + abi: 'function incentives(bytes32 incentiveId) external view returns (uint256 totalRewardUnclaimed, uint160 totalSecondsClaimedX128, uint96 numberOfStakes)', + params: [incentiveId], + chain: CHAIN, + block: epochContext.epochStartBlock, + }); + + const totalRewardUnclaimed = BigInt( + result.output.totalRewardUnclaimed || 0 + ); + + // Use epoch timing from context + const endTime = epochContext.epochStartTime + WEEK_SECONDS; + + const reward = parseFloat( + ethers.utils.formatUnits(totalRewardUnclaimed.toString(), 18) + ); + + return { startTime: epochContext.epochStartTime, endTime, reward }; + } catch (e) { + console.error('Error getting incentive from events:', e.message); + return null; + } +}; + +/** + * Fee tier to tick spacing mapping (copied from SDK) + */ +const feeTierToTickSpacing = (feeTier) => { + if (feeTier == 100) return 1; + if (feeTier == 500) return 10; + if (feeTier == 3000) return 60; + if (feeTier == 10000) return 200; + return 60; +}; + +/** + * Calculate position efficiency based on fee tier and minimum width + * Efficiency ranges from ~1 (full range) to ~40,000 (single tick) + * @dev extracted from https://github.com/Maia-DAO/sdks/blob/main/sdks/hermes-v2-sdk/src/utils/tvl.ts + */ +const positionEfficiency = (feeTier, minWidth) => { + const tickSpacing = feeTierToTickSpacing(feeTier); + const MAX_RANGE = 2 ** 20; + + // Get the larger of tick spacing or minWidth (rounded to tick spacing) + const width = Math.max( + tickSpacing, + Math.ceil(minWidth / tickSpacing) * tickSpacing + ); + + // If width exceeds max range, treat as full range (efficiency = 1) + if (width >= MAX_RANGE) { + return 1; + } + + // Calculate price ratio: Pa/Pb = 1.0001^(-width) + const priceRatio = Math.pow(1.0001, -width); + + // efficiency = 1 / (1 - (Pa/Pb)^0.25) + const efficiency = 1 / (1 - Math.pow(priceRatio, 0.25)); + + return efficiency; +}; + +/** + * Convert liquidity USD based on efficiency difference + * @dev extracted from https://github.com/Maia-DAO/sdks/blob/main/sdks/hermes-v2-sdk/src/utils/tvl.ts + */ +const convertBasedOnEfficiency = (amount, feeTier, minWidth) => { + const wideTicks = 6 * minWidth; + + const efficiencyAt0 = positionEfficiency(feeTier, 0); + const efficiencyAtWide = positionEfficiency(feeTier, wideTicks); + + return (amount * efficiencyAt0) / efficiencyAtWide; +}; + +/** + * Get minimumWidth from gauge contract + */ +const getGaugeMinimumWidth = async (gaugeAddress, feeTier, block = null) => { + try { + const result = await sdk.api.abi.call({ + target: gaugeAddress, + abi: 'function minimumWidth() external view returns (uint24)', + chain: CHAIN, + block, + }); + + const minWdith = parseInt(result.output); + const minSpacing = feeTierToTickSpacing(feeTier); + + // Ensure minimumWidth is at least tick spacing + if (minWdith < minSpacing) { + return minSpacing; + } + + return minWdith; + } catch (e) { + // Default to 0 if not available + return 0; + } +}; + +/** + * Calculate the USD value of liquidity at the current tick + * @dev extracted from getAmountsCurrentTickUSD at https://github.com/Maia-DAO/sdks/blob/main/sdks/hermes-v2-sdk/src/utils/tvl.ts + */ +const getAmountsCurrentTickUSD = ( + sqrtPriceX96, + tick, + liquidity, + feeTier, + decimals0, + decimals1, + price0, + price1 +) => { + if (!liquidity || liquidity === '0' || liquidity === 0n) return 0; + + const tickSpacing = feeTierToTickSpacing(feeTier); + + // Get tick bounds for current tick + const tickLower = Math.floor(tick / tickSpacing) * tickSpacing; + const tickUpper = tickLower + tickSpacing; + + // Convert sqrtPriceX96 to regular sqrtPrice + const Q96 = BigInt(2) ** BigInt(96); + const sqrtPrice = Number(sqrtPriceX96) / Number(Q96); + + // Calculate sqrtPrice at tick boundaries using Uniswap V3 formula + const sqrtPriceLower = Math.sqrt(Math.pow(1.0001, tickLower)); + const sqrtPriceUpper = Math.sqrt(Math.pow(1.0001, tickUpper)); + + // Calculate amounts using proper Uniswap V3 + const L = Number(liquidity); + const amount0 = L * (1 / sqrtPrice - 1 / sqrtPriceUpper); + const amount1 = L * (sqrtPrice - sqrtPriceLower); + + // Apply decimals and convert to USD + const usdValue = + (amount0 / 10 ** decimals0) * price0 + (amount1 / 10 ** decimals1) * price1; + + return usdValue; +}; + +/** + * Calculate active liquidity USD for maximum APR calculation + * @dev extracted from calculateLiquidityData formula for max APR at https://github.com/Maia-DAO/sdks/blob/main/sdks/hermes-v2-sdk/src/utils/calculateLiquidityData.ts + */ +const calculateActiveLiquidityUSD = async ( + gaugeAddress: string, + poolInfo: { token0: string; token1: string; fee: string; liquidity: string }, + slot0: { sqrtPriceX96: bigint; tick: number }, + decimals0: number, + decimals1: number, + feeTier: number, + prices: Record, + block: number | null = null +) => { + try { + const price0 = prices[poolInfo.token0.toLowerCase()] || 0; + const price1 = prices[poolInfo.token1.toLowerCase()] || 0; + + if (price0 === 0 && price1 === 0) return 0; + + // Get current tick liquidity value in USD + const currentTickLiquidityUSD = getAmountsCurrentTickUSD( + slot0.sqrtPriceX96, + slot0.tick, + poolInfo.liquidity, + feeTier, + decimals0, + decimals1, + price0, + price1 + ); + + // If liquidity is 0, return minimum value + if (currentTickLiquidityUSD <= 0) { + return 1; + } + + // Get minimumWidth from gauge contract + const minWidth = await getGaugeMinimumWidth(gaugeAddress, feeTier, block); + + // Apply efficiency conversion based on minimumWidth + const activeLiquidityUSD = convertBasedOnEfficiency( + currentTickLiquidityUSD, + feeTier, + minWidth + ); + + return activeLiquidityUSD; + } catch (e) { + console.error('Error calculating active liquidity:', e.message); + return 0; + } +}; + +/** + * Calculate APR from incentive reward + */ +const calculateAprReward = ( + reward, + hermesPrice, + activeLiquidityUSD, + startTime, + endTime, + timestamp = null +) => { + if (activeLiquidityUSD <= 0 || reward <= 0 || hermesPrice <= 0) { + return 0; + } + + // Use provided timestamp or current time + const now = timestamp || Math.floor(Date.now() / 1000); + + // Check if incentive has ended + if (now > endTime) { + return 0; + } + + const period = endTime - startTime; + if (period <= 0) return 0; + + // apr = (rewardsUSD / liquidityUSD) * (YEAR / period) * 100 + const multiplier = (YEAR_IN_SECONDS / period) * 100; + const rewardsUSD = reward * hermesPrice; + const apr = (rewardsUSD / activeLiquidityUSD) * multiplier; + + return apr; +}; + +// ============================================================================ +// MAIN ADAPTER FUNCTION +// ============================================================================ + +const getPools = async (timestamp = null) => { + try { + // Get block for the given timestamp (or latest if null) + let currentBlock; + if (timestamp) { + [currentBlock] = await utils.getBlocksByTime([timestamp], CHAIN); + } else { + const latestBlock = await sdk.api.util.getLatestBlock(CHAIN); + currentBlock = latestBlock.number; + } + + // Compute epoch context + const epochContext = await getEpochContext(timestamp, currentBlock); + + // Get all gauges from AddGauge events + const gauges = await getAllGauges(currentBlock); + + if (gauges.length === 0) { + console.log('No gauges found'); + return []; + } + + // Collect all unique tokens for price fetching + const tokenSet = new Set(); + tokenSet.add(ADDRESSES.HERMES); // Need HERMES price for APY calculation + const gaugeData = []; + + // Get gauge and pool info, collect tokens + for (const gaugeAddress of gauges) { + const gaugeInfo = await getGaugeInfo(gaugeAddress, currentBlock); + if (!gaugeInfo) continue; + + const poolInfo = await getPoolInfo(gaugeInfo.strategy, currentBlock); + if (!poolInfo) continue; + + tokenSet.add(poolInfo.token0); + tokenSet.add(poolInfo.token1); + + gaugeData.push({ + gaugeAddress, + gaugeInfo, + poolInfo, + poolAddress: gaugeInfo.strategy, + }); + } + + // Fetch all prices + const tokens = Array.from(tokenSet); + const prices = (await utils.getPrices(tokens, CHAIN, timestamp)) + .pricesByAddress; + + // Extract HERMES price + const hermesPrice = prices[ADDRESSES.HERMES.toLowerCase()] || 0; + + const pools = []; + for (const { gaugeAddress, poolInfo, poolAddress } of gaugeData) { + try { + // Get token metadata + const [token0Meta, token1Meta] = await Promise.all([ + getTokenMetadata(poolInfo.token0, currentBlock), + getTokenMetadata(poolInfo.token1, currentBlock), + ]); + + // Get gauge allocation + const allocation = await getGaugeAllocation(gaugeAddress, currentBlock); + + // Compute shared data for this pool + const slot0 = await getPoolSlot0(poolAddress, currentBlock); + const feeTier = parseInt(poolInfo.fee); + const incentiveId = computeIncentiveId( + poolAddress, + epochContext.epochStartTime + ); + + // Get incentive data from QueueRewards events + const incentiveData = await getIncentiveFromEvents( + incentiveId, + epochContext + ); + + // Calculate staked TVL + let tvlUsd = 0; + if (slot0 && incentiveData) { + tvlUsd = await calculateStakedTvl( + poolInfo.token0, + poolInfo.token1, + token0Meta.decimals, + token1Meta.decimals, + prices, + slot0, + incentiveId, + epochContext + ); + } + + // Calculate active liquidity USD for APR + let activeLiquidityUSD = 0; + if (slot0) { + activeLiquidityUSD = await calculateActiveLiquidityUSD( + gaugeAddress, + poolInfo, + slot0, + token0Meta.decimals, + token1Meta.decimals, + feeTier, + prices, + currentBlock + ); + } + + // Calculate APR + let apyReward = null; + if (incentiveData && activeLiquidityUSD > 0) { + apyReward = calculateAprReward( + incentiveData.reward, + hermesPrice, + activeLiquidityUSD, + epochContext.epochStartTime, + epochContext.epochEndTime, + timestamp + ); + } + + // Create pool symbol + const poolSymbol = `${token0Meta.symbol}-${token1Meta.symbol}`; + const feePercent = feeTier / 10000; + + pools.push({ + pool: `${gaugeAddress}-${CHAIN}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT, + symbol: poolSymbol, + tvlUsd, + apyBase: 0, + apyReward: apyReward && apyReward > 0 ? apyReward : null, + rewardTokens: [ADDRESSES.HERMES], + underlyingTokens: [poolInfo.token0, poolInfo.token1], + poolMeta: `${feePercent}% fee, ${allocation.toFixed( + 2 + )}% gauge weight`, + url: `https://app.maiadao.io/earn/${gaugeAddress}`, + }); + } catch (e) { + console.error(`Error processing gauge ${gaugeAddress}:`, e.message); + continue; + } + } + + return pools; + } catch (e) { + console.error('Error in getPools:', e); + return []; + } +}; + +// ============================================================================ +// EXPORTS +// ============================================================================ + +module.exports = { + timetravel: true, + apy: getPools, + url: 'https://app.maiadao.io', +}; diff --git a/src/adaptors/hipo/index.js b/src/adaptors/hipo/index.js new file mode 100644 index 0000000000..f4c9451d28 --- /dev/null +++ b/src/adaptors/hipo/index.js @@ -0,0 +1,76 @@ +const utils = require('../utils'); + +const address = 'EQCLyZHP4Xe8fpchQz76O-_RmUhaVc_9BAoGyJrwJrcbz2eZ'; + +module.exports = { + timetravel: false, + url: 'https://app.hipo.finance', + apy: async () => { + const protocolData = await utils.getData( + 'https://api.llama.fi/protocol/hipo' + ); + const tvlUsd = protocolData.currentChainTvls['TON']; + + const getTreasuryState = await utils.getData( + 'https://toncenter.com/api/v3/runGetMethod', + { + address, + method: 'get_treasury_state', + stack: [], + } + ); + if (getTreasuryState.exit_code !== 0) { + throw new Error( + 'Expected a zero exit code, but got ' + getTreasuryState.exit_code + ); + } + + await sleep(1000); + + const getTimes = await utils.getData( + 'https://toncenter.com/api/v3/runGetMethod', + { + address, + method: 'get_times', + stack: [], + } + ); + if (getTimes.exit_code !== 0) { + throw new Error( + 'Expected a zero exit code, but got ' + getTimes.exit_code + ); + } + + const lastStaked = Number(getTreasuryState.stack[11].value); + const lastRecovered = Number(getTreasuryState.stack[12].value); + + const currentRoundSince = Number(getTimes.stack[0].value); + const nextRoundSince = Number(getTimes.stack[3].value); + + const duration = 2 * (nextRoundSince - currentRoundSince); + const year = 365 * 24 * 60 * 60; + const compoundingFrequency = year / duration; + const apyBase = + (Math.pow( + lastRecovered / lastStaked || 1, + compoundingFrequency + ) - + 1) * + 100; + + return [ + { + pool: (address + '-ton').toLowerCase(), + chain: utils.formatChain('ton'), + project: 'hipo', + symbol: utils.formatSymbol('hTON'), + tvlUsd, + apyBase, + }, + ]; + }, +}; + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/src/adaptors/hmx/abi.js b/src/adaptors/hmx/abi.js new file mode 100644 index 0000000000..91a2b4854e --- /dev/null +++ b/src/adaptors/hmx/abi.js @@ -0,0 +1,53 @@ +module.exports = { + balanceOf: { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getAumE30: { + inputs: [ + { + internalType: 'bool', + name: '_isMaxPrice', + type: 'bool', + }, + ], + name: 'getAUME30', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; diff --git a/src/adaptors/hmx/addresses.json b/src/adaptors/hmx/addresses.json new file mode 100644 index 0000000000..7888a9528c --- /dev/null +++ b/src/adaptors/hmx/addresses.json @@ -0,0 +1,20 @@ +{ + "ARB": "0x912CE59144191C1204E64559FE8253a0e49E6548", + "DAI": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", + "HLP": "0x4307fbDCD9Ec7AEA5a1c2958deCaa6f316952bAb", + "HLP_BLAST": "0xF4F7123fFe42c4C90A4bCDD2317D397E0B7d7cc0", + "HMX": "0x83d6c8C06ac276465e4C92E7aC8C23740F435140", + "ESHMX": "0x8a011EF14a92AA37cE82A4c95004a70730b6AC38", + "ESHMX_BLAST": "0x22b71DE758E49a6Ef5B3cAEF9558063D28731D00", + "WBTC": "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f", + "WETH": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", + "WETH_BLAST": "0x4300000000000000000000000000000000000004", + "USDC": "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", + "USDT": "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", + "USDB_BLAST": "0x4300000000000000000000000000000000000003", + "CALCULATOR": "0x0FdE910552977041Dc8c7ef652b5a07B40B9e006", + "CALCULATOR_BLAST": "0x4307fbDCD9Ec7AEA5a1c2958deCaa6f316952bAb", + "HLP_STAKING": "0xbE8f8AF5953869222eA8D39F1Be9d03766010B1C", + "HLP_STAKING_BLAST": "0x6D59A9acC2e0fa6CA568b24C07B3D6A39d408C18", + "HMX_STAKING": "0x92E586B8D4Bf59f4001604209A292621c716539a" +} diff --git a/src/adaptors/hmx/index.js b/src/adaptors/hmx/index.js new file mode 100755 index 0000000000..b482cc9ca1 --- /dev/null +++ b/src/adaptors/hmx/index.js @@ -0,0 +1,258 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); + +const abi = require('./abi'); +const addresses = require('./addresses.json'); +const utils = require('../utils'); + +const WeiPerEther = BigNumber(1000000000000000000); + +const arbUrl = 'https://arbitrum-gapi.hmx.org/v1/apr-pools'; +const blastUrl = 'https://blast-gapi.hmx.org/v1/apr-pools'; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const apy = async () => { + const [ + arbResponse, + blastResponse, + { pricesBySymbol }, + { output: hlpStakingAumE30Arb }, + { output: hlpTotalSupplyArb }, + { output: hlpBalanceInPoolArb }, + { output: hlpStakingAumE30Blast }, + { output: hlpTotalSupplyBlast }, + { output: hlpBalanceInPoolBlast }, + { output: hmxBalanceInPool }, + ] = await Promise.all([ + utils.getData(arbUrl), + utils.getData(blastUrl), + getPrices([`arbitrum:${addresses.HMX}`]), + sdk.api.abi.call({ + abi: abi.getAumE30, + chain: 'arbitrum', + target: addresses.CALCULATOR, + params: [false], + }), + sdk.api.abi.call({ + abi: abi.totalSupply, + chain: 'arbitrum', + target: addresses.HLP, + params: [], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'arbitrum', + target: addresses.HLP, + params: [addresses.HLP_STAKING], + }), + sdk.api.abi.call({ + abi: abi.getAumE30, + chain: 'blast', + target: addresses.CALCULATOR_BLAST, + params: [false], + }), + sdk.api.abi.call({ + abi: abi.totalSupply, + chain: 'blast', + target: addresses.HLP_BLAST, + params: [], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'blast', + target: addresses.HLP_BLAST, + params: [addresses.HLP_STAKING_BLAST], + }), + sdk.api.abi.call({ + abi: abi.balanceOf, + chain: 'arbitrum', + target: addresses.HMX, + params: [addresses.HMX_STAKING], + }), + ]); + + // ---------------- Arbitrum ---------------- + const { aprPools: arbAprPools } = arbResponse.data; + + const arbHlpApr = arbAprPools.find((p) => p.key === 'hlp_staking'); + const arbHlpAprBase = () => { + if (!arbHlpApr || !arbHlpApr.Info) return BigNumber(0); + + const _arbHlpAprBase = arbHlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken == 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_arbHlpAprBase).dividedBy(WeiPerEther); + }; + + const arbHlpAprReward = () => { + if (!arbHlpApr || !arbHlpApr.Info) return BigNumber(0); + + const _arbHlpAprReward = arbHlpApr.Info.reduce((acc, apr) => { + if (apr.rewardToken != 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_arbHlpAprReward).dividedBy(WeiPerEther); + }; + + const arbHmxApr = arbAprPools.find((p) => p.key === 'hmx_staking'); + const arbHmxAprBase = () => { + if (!arbHmxApr || !arbHmxApr.Info) return BigNumber(0); + + const _arbHmxAprBase = arbHmxApr.Info.reduce((acc, apr) => { + if (apr.rewardToken == 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_arbHmxAprBase).dividedBy(WeiPerEther); + }; + + const arbHmxAprReward = () => { + if (!arbHmxApr || !arbHmxApr.Info) return BigNumber(0); + + const _arbHmxAprReward = arbHmxApr.Info.reduce((acc, apr) => { + if (apr.rewardToken != 'usdc') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_arbHmxAprReward).dividedBy(WeiPerEther); + }; + + // // ---------------- Blast ---------------- + const { aprPools: blastAprPools } = blastResponse.data; + + const blastHlpApr = blastAprPools.find((p) => p.key === 'hlp_staking'); + const blastHlpAprBase = () => { + if (!blastHlpApr || !blastHlpApr.Info) return BigNumber(0); + + const _blastHlpAprBase = blastHlpApr.Info.reduce((acc, apr) => { + if (apr.rewardName == 'HLP Staking Protocol Revenue') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_blastHlpAprBase).dividedBy(WeiPerEther); + }; + + const blastHlpAprReward = () => { + if (!blastHlpApr || !blastHlpApr.Info) return BigNumber(0); + + const _blastHlpAprReward = blastHlpApr.Info.reduce((acc, apr) => { + if (apr.rewardName != 'HLP Staking Protocol Revenue') { + acc += apr.apr; + } + return acc; + }, 0); + + return BigNumber(_blastHlpAprReward).dividedBy(WeiPerEther); + }; + + // ---------------- HLP ---------------- + const hlpPriceInE30Arb = BigNumber(hlpStakingAumE30Arb).dividedBy( + BigNumber(hlpTotalSupplyArb) + ); + + const tvlUsdHlpArb = BigNumber(hlpBalanceInPoolArb) + .multipliedBy(hlpPriceInE30Arb) + .dividedBy(1e30); + + const hlpPriceInE30Blast = BigNumber(hlpStakingAumE30Blast).dividedBy( + BigNumber(hlpTotalSupplyBlast) + ); + + const tvlUsdHlpBlast = BigNumber(hlpBalanceInPoolBlast) + .multipliedBy(hlpPriceInE30Blast) + .dividedBy(1e30); + + const hlpStakingPoolArb = { + pool: `${addresses.HLP_STAKING}-arbitrum`, + chain: 'Arbitrum', + project: 'hmx', + symbol: 'ETH-BTC-USDC', + tvlUsd: tvlUsdHlpArb.toNumber(), + apyBase: arbHlpAprBase().toNumber(), + apyReward: arbHlpAprReward().toNumber(), + rewardTokens: [addresses.USDC, addresses.ESHMX], + underlyingTokens: [addresses.WETH, addresses.WBTC, addresses.USDC], + poolMeta: 'HLP Staking', + url: 'https://hmx.org/arbitrum/earn', + }; + + const hlpStakingPoolBlast = { + pool: `${addresses.HLP_STAKING_BLAST}-blast`, + chain: 'Blast', + project: 'hmx', + symbol: 'ETH-USDB', + tvlUsd: tvlUsdHlpBlast.toNumber(), + apyBase: blastHlpAprBase().toNumber(), + apyReward: blastHlpAprReward().toNumber(), + rewardTokens: [addresses.USDB_BLAST, addresses.ESHMX_BLAST], + underlyingTokens: [addresses.WETH_BLAST, addresses.USDB_BLAST], + poolMeta: 'HLP Staking blast', + url: 'https://hmx.org/blast/earn', + }; + + // // ---------------- HMX ---------------- + const tvlUsdHmx = BigNumber(hmxBalanceInPool) + .multipliedBy(pricesBySymbol.hmx) + .dividedBy(WeiPerEther); + const hmxStakingPool = { + pool: `${addresses.HMX_STAKING}-arbitrum`, + chain: 'Arbitrum', + project: 'hmx', + symbol: 'HMX-esHMX', + tvlUsd: tvlUsdHmx.toNumber(), + apyBase: arbHmxAprBase().toNumber(), + apyReward: arbHmxAprReward().toNumber(), + rewardTokens: [addresses.USDC, addresses.ESHMX], + underlyingTokens: [addresses.ESHMX, addresses.HMX], + poolMeta: 'HMX Staking - esHMX reward is 1 year linear vested', + url: 'https://hmx.org/arbitrum/earn', + }; + + return [hlpStakingPoolArb, hlpStakingPoolBlast, hmxStakingPool]; +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/holdstation-defutures/index.js b/src/adaptors/holdstation-defutures/index.js new file mode 100644 index 0000000000..e23dbe1472 --- /dev/null +++ b/src/adaptors/holdstation-defutures/index.js @@ -0,0 +1,85 @@ +const utils = require('../utils'); +const ethers = require('ethers'); +const axios = require('axios'); + +const erc20Abi = [ + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; + +const vaultBSC = '0x7470C48FBf23067F6F8Ef63f7D9B4A2aA5D0afEf'; +const usd1 = '0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d'; + +const vaultWC = '0x9BD647B2C8Fed689ADd2e7AA8b428d3eD12f75cb'; +const wld = '0x2cFc85d8E48F8EAB294be644d9E25C3030863003'; + +const BSCProvider = new ethers.providers.JsonRpcProvider( + 'https://binance.llamarpc.com' +); + +const WLDProvider = new ethers.providers.JsonRpcProvider( + 'https://worldchain-mainnet.g.alchemy.com/public' +); + +const wldPool = async () => { + const currentTime = Math.trunc(Date.now() / 1000); + + const apy7dUrl = `https://worldfuture.holdstation.com/api/apy/history/vault/time/${currentTime}`; + const apy7d = await utils.getData(apy7dUrl); + + const apy24hUrl = `https://worldfuture.holdstation.com/api/apy/mUSDC`; + const apyBase = await utils.getData(apy24hUrl); + + const wldContract = new ethers.Contract(wld, erc20Abi, WLDProvider); + const wldBalance = await wldContract.balanceOf(vaultWC); + + return { + pool: `${vaultWC}-worldchain`, + chain: 'World Chain', + project: 'holdstation-defutures', + symbol: utils.formatSymbol('WLD'), + tvlUsd: wldBalance / 1e18, + apyBase7d: apy7d.rate, + apyBase: apyBase.rate, + + underlyingTokens: [wld], + }; +}; + +const usd1Pool = async () => { + const currentTime = Math.trunc(Date.now() / 1000); + + const apy7dUrl = `https://bnbfutures.holdstation.com/api/apy/history/vault/time/${currentTime}`; + const apy7d = await utils.getData(apy7dUrl); + + const apy24hUrl = `https://bnbfutures.holdstation.com/api/apy/mUSDC`; + const apyBase = await utils.getData(apy24hUrl); + + const usd1Contract = new ethers.Contract(usd1, erc20Abi, BSCProvider); + const usd1Balance = await usd1Contract.balanceOf(vaultBSC); + + return { + pool: `${vaultBSC}-binance`, + chain: 'Binance', + project: 'holdstation-defutures', + symbol: utils.formatSymbol('USD1'), + tvlUsd: usd1Balance / 1e18, + apyBase7d: apy7d.rate, + apyBase: apyBase.rate, + + underlyingTokens: [usd1], + }; +}; + +module.exports = { + timetravel: true, + apy: async () => { + return [await usd1Pool(), await wldPool()]; + }, + url: 'https://holdstation.exchange/vault', +}; diff --git a/src/adaptors/homora-v2/abi.json b/src/adaptors/homora-v2/abi.json new file mode 100644 index 0000000000..5439552a1a --- /dev/null +++ b/src/adaptors/homora-v2/abi.json @@ -0,0 +1,234 @@ +{ + "chef": { + "inputs": [], + "name": "chef", + "outputs": [ + { + "internalType": "contract IMasterChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolInfo": { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "accRewardPerShare", + "type": "uint128" + }, + { "internalType": "uint64", "name": "lastRewardTime", "type": "uint64" }, + { "internalType": "uint64", "name": "allocPoint", "type": "uint64" } + ], + "stateMutability": "view", + "type": "function" + }, + "lpToken": { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lpToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + "poolInfo2": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accSushiPerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "token0": { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "token1": { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "userInfo": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getUnderlyingToken": { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "getUnderlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "gauges": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "gauges", + "outputs": [ + { + "internalType": "contract ILiquidityGauge", + "name": "impl", + "type": "address" + }, + { + "internalType": "uint256", + "name": "accCrvPerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "underlying": { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolLength": { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "balanceOfRewards": { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "staking": { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/homora-v2/index.js b/src/adaptors/homora-v2/index.js new file mode 100644 index 0000000000..b4069c4d46 --- /dev/null +++ b/src/adaptors/homora-v2/index.js @@ -0,0 +1,540 @@ +// const axios = require('axios'); +// const sdk = require('@defillama/sdk'); +// const abi = require('./abi.json'); +// const { +// unwrapUniswapLPs, +// genericUnwrapCrv, +// } = require('../../helper/unwrapLPs'); +// const { default: computeTVL } = require('@defillama/sdk/build/computeTVL'); +// const chains = { +// 1: 'Ethereum', +// 250: 'Fantom', +// 43114: 'Avax', +// }; +// const crv3 = '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490'; +// const LP_SYMBOLS = [ +// 'SLP', +// 'spLP', +// 'JLP', +// 'OLP', +// 'SCLP', +// 'DLP', +// 'MLP', +// 'MSLP', +// 'ULP', +// 'TLP', +// 'HMDX', +// 'YLP', +// 'SCNRLP', +// 'PGL', +// 'GREEN-V2', +// 'PNDA-V2', +// ]; + +// async function chefSymbols(poolInfos, lpTokens, chainId) { +// const [ +// { output: token0sa }, +// { output: token1sa }, +// { output: token0sb }, +// { output: token1sb }, +// ] = await Promise.all([ +// sdk.api.abi.multiCall({ +// abi: abi.token0, +// calls: poolInfos.map((p) => ({ +// target: p.success ? p.output.lpToken : undefined, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: abi.token1, +// calls: poolInfos.map((p) => ({ +// target: p.success ? p.output.lpToken : undefined, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: abi.token0, +// calls: lpTokens.map((p) => ({ +// target: p.success ? p.output : undefined, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: abi.token1, +// calls: lpTokens.map((p) => ({ +// target: p.success ? p.output : undefined, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// const token0s = token0sa.map((t, i) => +// t.success ? t.output : token0sb[i].output +// ); +// const token1s = token1sa.map((t, i) => +// t.success ? t.output : token1sb[i].output +// ); + +// const [{ output: token0Symbols }, { output: token1Symbols }] = +// await Promise.all([ +// sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: token0s.map((t) => ({ +// target: t, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: token1s.map((t) => ({ +// target: t, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// return token0Symbols.map((t, i) => `${t.output}-${token1Symbols[i].output}`); +// } +// async function lpSymbols(address, chainId) { +// const [{ output: token0 }, { output: token1 }] = await Promise.all([ +// sdk.api.abi.call({ +// abi: abi.token0, +// target: address, +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.call({ +// abi: abi.token1, +// target: address, +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// const [{ output: token0Symbol }, { output: token1Symbol }] = +// await Promise.all([ +// sdk.api.abi.call({ +// abi: 'erc20:symbol', +// target: token0, +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.call({ +// abi: 'erc20:symbol', +// target: token1, +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// return `${token0Symbol}-${token1Symbol}`; +// } +// async function chefTvls(poolInfos, poolInfos2, lpTokens, apys, chainId) { +// const transform = (addr) => `${chain}:${addr}` + +// const balance = ( +// await sdk.api.abi.multiCall({ +// abi: abi.userInfo, +// calls: Object.keys(apys).map((p, i) => ({ +// target: poolInfos[i].input.target, +// params: [ +// p.substring(p.lastIndexOf('-') + 1), +// p.substring(p.indexOf('-') + 1, p.lastIndexOf('-')), +// ], +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const tvls = []; + +// for (let i = 0; i < balance.length; i++) { +// const balances = {}; +// await unwrapUniswapLPs( +// balances, +// [ +// { +// balance: balance[i].output.amount, +// token: poolInfos2[i].success +// ? poolInfos2[i].output.lpToken +// : lpTokens[i].output, +// }, +// ], +// undefined, +// chains[chainId].toLowerCase(), +// transform +// ); +// tvls.push( +// (await computeTVL(balances, 'now', false, [], getCoingeckoLock, 5)).usdTvl +// ); +// } + +// return tvls; +// } +// async function chefs(apys, chainId) { +// const chefs = ( +// await sdk.api.abi.multiCall({ +// abi: abi.chef, +// calls: Object.keys(apys).map((p) => ({ +// target: p.substring(p.indexOf('-') + 1, p.lastIndexOf('-')), +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// let poolInfos = await sdk.api.abi.multiCall({ +// abi: abi.poolInfo, +// calls: Object.keys(apys).map((p, i) => ({ +// target: chefs[i].output, +// params: [p.substring(p.lastIndexOf('-') + 1)], +// })), +// chain: chains[chainId].toLowerCase(), +// }); + +// let poolInfos2 = await sdk.api.abi.multiCall({ +// abi: abi.poolInfo2, +// calls: Object.keys(apys).map((p, i) => ({ +// target: chefs[i].output, +// params: [p.substring(p.lastIndexOf('-') + 1)], +// })), +// chain: chains[chainId].toLowerCase(), +// }); + +// let lpTokens = ( +// await sdk.api.abi.multiCall({ +// abi: abi.lpToken, +// calls: Object.keys(apys).map((p, i) => ({ +// target: poolInfos.output[i].input.target, +// params: [p.substring(p.lastIndexOf('-') + 1)], +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const [symbols, tvls] = await Promise.all([ +// chefSymbols(poolInfos2.output, lpTokens, chainId), +// chefTvls(poolInfos.output, poolInfos2.output, lpTokens, apys, chainId), +// ]); + +// return Object.entries(apys).map(([k, v], i) => ({ +// pool: `${k}`, +// chain: chainId == 43114 ? 'Avalanche' : chains[chainId], +// project: 'homora-v2', +// symbol: symbols[i], +// tvlUsd: tvls[i], +// apy: Number(v.totalAPY), +// })); +// } +// async function erc20Symbols(tokens, chainId) { +// const [{ output: token0s }, { output: token1s }] = await Promise.all([ +// sdk.api.abi.multiCall({ +// abi: abi.token0, +// calls: tokens.map((p) => ({ +// target: p.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: abi.token1, +// calls: tokens.map((p) => ({ +// target: p.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// const [{ output: token0Symbols }, { output: token1Symbols }] = +// await Promise.all([ +// sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: token0s.map((t) => ({ +// target: t.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: token1s.map((t) => ({ +// target: t.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// ]); + +// return token0Symbols.map((t, i) => `${t.output}-${token1Symbols[i].output}`); +// } +// async function erc20Tvls(apys, tokens, chainId) { +// const transform = (addr) => `${chain}:${addr}`; + +// const balance = ( +// await sdk.api.abi.multiCall({ +// abi: 'erc20:balanceOf', +// calls: Object.keys(apys).map((p, i) => ({ +// target: tokens[i].output, +// params: [p.substring(p.indexOf('-') + 1, p.lastIndexOf('-'))], +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const tvls = []; + +// for (let i = 0; i < balance.length; i++) { +// const balances = {}; +// await unwrapUniswapLPs( +// balances, +// [ +// { +// balance: balance[i].output, +// token: tokens[i].output, +// }, +// ], +// undefined, +// chains[chainId].toLowerCase(), +// transform +// ); +// tvls.push( +// (await computeTVL(balances, 'now', false, [], getCoingeckoLock, 5)).usdTvl +// ); +// } + +// return tvls; +// } +// async function erc20s(apys, chainId) { +// const tokens = ( +// await sdk.api.abi.multiCall({ +// abi: abi.getUnderlyingToken, +// calls: Object.keys(apys).map((p) => ({ +// target: p.substring(p.indexOf('-') + 1, p.lastIndexOf('-')), +// params: p.substring(p.lastIndexOf('-') + 1), +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const [symbols, tvls] = await Promise.all([ +// erc20Symbols(tokens, chainId), +// erc20Tvls(apys, tokens, chainId), +// ]); + +// return Object.entries(apys).map(([k, v], i) => ({ +// pool: `${k}`, +// chain: chainId == 43114 ? 'Avalanche' : chains[chainId], +// project: 'homora-v2', +// symbol: symbols[i], +// tvlUsd: tvls[i], +// apy: Number(v.totalAPY), +// })); +// } +// async function gauge(apys, chainId) { +// const tokens = ( +// await sdk.api.abi.multiCall({ +// abi: abi.getUnderlyingToken, +// calls: Object.keys(apys).map((p) => ({ +// target: p.substring(p.indexOf('-') + 1, p.lastIndexOf('-') - 2), +// params: p.substring(p.lastIndexOf('-') + 1), +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const [{ output: symbols }, tvls] = await Promise.all([ +// sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: tokens.map((t) => ({ +// target: t.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }), +// gaugeTvls(apys, tokens, chainId), +// ]); + +// return Object.entries(apys).map(([k, v], i) => ({ +// pool: `${k}`, +// chain: chainId == 43114 ? 'Avalanche' : chains[chainId], +// project: 'homora-v2', +// symbol: symbols[i].output, +// tvlUsd: tvls[i], +// apy: Number(v.totalAPY), +// })); +// } +// async function gaugeTvls(apys, tokens, chainId) { +// const gauges = ( +// await sdk.api.abi.multiCall({ +// abi: abi.gauges, +// calls: Object.keys(apys).map((p, i) => ({ +// target: p.substring(p.indexOf('-') + 1, p.lastIndexOf('-') - 2), +// params: [ +// p.substring(p.lastIndexOf('-') - 1, p.lastIndexOf('-')), +// p.substring(p.lastIndexOf('-') + 1), +// ], +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const balance = ( +// await sdk.api.abi.multiCall({ +// abi: 'erc20:balanceOf', +// calls: Object.keys(apys).map((p, i) => ({ +// target: gauges[i].output.impl, +// params: [p.substring(p.indexOf('-') + 1, p.lastIndexOf('-') - 2)], +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const tvls = []; + +// for (let i = 0; i < balance.length; i++) { +// const balances = {}; +// if (tokens[i].output.toLowerCase() == crv3) { +// sdk.util.sumSingleBalance(balances, crv3, balance[i].output); +// } else { +// await genericUnwrapCrv( +// balances, +// tokens[i].output, +// balance[i].output, +// undefined, +// chains[chainId].toLowerCase() +// ); +// } +// tvls.push( +// (await computeTVL(balances, 'now', false, [], getCoingeckoLock, 5)).usdTvl +// ); +// } + +// return tvls; +// } +// async function staking(apys, chainId) { +// const stakingTokens = ( +// await sdk.api.abi.multiCall({ +// abi: abi.underlying, +// calls: Object.keys(apys).map((p) => ({ +// target: p.substring(p.indexOf('-') + 1), +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const symbols = ( +// await sdk.api.abi.multiCall({ +// abi: 'erc20:symbol', +// calls: stakingTokens.map((t) => ({ +// target: t.output, +// })), +// chain: chains[chainId].toLowerCase(), +// }) +// ).output; + +// const stakingContracts = ( +// await sdk.api.abi.multiCall({ +// calls: Object.keys(apys).map((p) => ({ +// target: p.substring(p.indexOf('-') + 1), +// })), +// chain: chains[chainId].toLowerCase(), +// abi: abi.staking, +// }) +// ).output; + +// const balance = ( +// await sdk.api.abi.multiCall({ +// calls: stakingContracts.map((c) => ({ +// target: c.output, +// params: [c.input.target], +// })), +// chain: chains[chainId].toLowerCase(), +// abi: abi.balanceOfRewards, +// }) +// ).output; + +// const transform = (addr) => `${chain}:${addr}`; +// let pools = []; +// for (let i = 0; i < Object.keys(apys).length; i++) { +// let symbol; +// const balances = {}; + +// if ( +// LP_SYMBOLS.includes(symbols[i].output) || +// /(UNI-V2)/.test(symbols[i].output) || +// symbols[i].output.split(/\W+/).includes('LP') +// ) { +// symbol = await lpSymbols(stakingTokens[i].output, chainId); +// await unwrapUniswapLPs( +// balances, +// [ +// { +// token: stakingTokens[i].output, +// balance: balance[i].output, +// }, +// ], +// undefined, +// chains[chainId].toLowerCase(), +// transform +// ); +// } else { +// symbol = symbols[i]; +// sdk.util.sumSingleBalance(balances, transform, balance[i].output); +// } + +// pools.push({ +// pool: Object.keys(apys)[i], +// chain: chainId == 43114 ? 'Avalanche' : chains[chainId], +// project: 'homora-v2', +// symbol, +// tvlUsd: ( +// await computeTVL(balances, 'now', false, [], getCoingeckoLock, 5) +// ).usdTvl, +// apy: Number(Object.values(apys)[i].totalAPY), +// }); +// } +// return pools; +// } +// function sortByKey(apys, key) { +// return Object.fromEntries( +// Object.entries(apys).filter(([k]) => k.includes(key)) +// ); +// } +// async function apy(chainId) { +// let apys = ( +// await axios.get(`https://api.homora.alphaventuredao.io/v2/${chainId}/apys`) +// ).data; + +// // NOTE(slasher): new pool on fantom (beethoven pool) was added which requires different abi, +// // for now just excluding this so that the adaptor doesn't break for the pools we are already tracking +// // until fix is deployed for new pool +// if (chainId === 250) { +// apys = Object.fromEntries( +// Object.entries(apys).filter( +// (p) => p[0] !== 'wchef-0xed0dcec4d50b6374971ad7c7180f80775eaff1ef-17' +// ) +// ); +// } + +// return [ +// ...(await chefs(sortByKey(apys, 'wchef'), chainId)), +// ...(await erc20s(sortByKey(apys, 'werc20'), chainId)), +// ...(await gauge(sortByKey(apys, 'wgauge'), chainId)), +// ...(await staking(sortByKey(apys, 'wstaking'), chainId)), +// ]; +// } +// const main = async () => { +// const pools = []; +// for (const chain of Object.keys(chains)) { +// console.log(chains[chain]); +// try { +// const poolsChain = await apy(chain); +// pools.push(poolsChain); +// } catch (err) { +// console.log(err); +// } +// } + +// return pools.flat(); +// }; +// function getCoingeckoLock() { +// return new Promise((resolve) => { +// locks.push(resolve); +// }); +// } +// module.exports = { +// timetravel: false, +// apy: main, +// url: 'https://homora-v2.alphaventuredao.io/farm-pools', +// }; diff --git a/src/adaptors/hop-protocol/index.js b/src/adaptors/hop-protocol/index.js new file mode 100644 index 0000000000..5ee55d5e01 --- /dev/null +++ b/src/adaptors/hop-protocol/index.js @@ -0,0 +1,114 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const api = 'https://assets.hop.exchange'; + +const getApy = async () => { + const data = (await axios.get(`${api}/v1.1-pool-stats.json`)).data.data; + + const coreConfig = (await axios.get(`${api}/mainnet/v1-core-config.json`)) + .data.bridges; + + const tokens = Object.keys(data.pools); + + const pools = []; + for (const token of tokens) { + const tokenPools = data.pools[token]; + const chains = Object.keys(tokenPools).filter((c) => !['nova'].includes(c)); + + for (chain of chains) { + const config = coreConfig[token][chain]; + const poolAddress = config?.l2SaddleSwap; + const tokenAddress = config?.l2CanonicalToken; + const hopTokenAddress = config?.l2HopBridgeToken; + if (!tokenAddress || !poolAddress) continue; + + const adaptedChain = + chain === 'gnosis' + ? 'xdai' + : chain === 'polygonzk' + ? 'polygon_zkevm' + : chain; + + const tokenBalance = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + chain: adaptedChain, + target: tokenAddress, + params: [poolAddress], + }) + ).output; + + const hopTokenBalance = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + chain: adaptedChain, + target: hopTokenAddress, + params: [poolAddress], + }) + ).output; + + const decimals = ( + await sdk.api.abi.call({ + abi: 'erc20:decimals', + chain: adaptedChain, + target: tokenAddress, + }) + ).output; + + const key = `${adaptedChain}:${tokenAddress}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${key}`) + ).data.coins[key]?.price; + + const totalBalance = new BigNumber(tokenBalance) + .plus(new BigNumber(hopTokenBalance)) + .div(new BigNumber(10 ** decimals)); + const tvlUsd = totalBalance.multipliedBy(price).toNumber(); + + let optimalStakingRewardData; + let stakingRewardAddresses = []; + const stakingRewards = data.stakingRewards?.[token]?.[chain]; + if (stakingRewards) { + const stakingRewardsContracts = Object.keys(stakingRewards); + for (const stakingRewardsContract of stakingRewardsContracts) { + const stakingRewardsContractData = + stakingRewards[stakingRewardsContract]; + const isOptimal = stakingRewardsContractData.isOptimalStakingContract; + if (isOptimal) { + optimalStakingRewardData = stakingRewardsContractData; + } + stakingRewardAddresses.push( + stakingRewardsContractData.rewardTokenAddress + ); + } + } + const apyReward = optimalStakingRewardData + ? optimalStakingRewardData.apy * 100 + : 0; + + pools.push({ + pool: `${chain}-${token}`, + chain: utils.formatChain(adaptedChain), + project: 'hop-protocol', + symbol: token, + apyBase: tokenPools[chain].apy * 100, + apyReward, + rewardTokens: apyReward > 0 ? stakingRewardAddresses : [], + underlyingTokens: [tokenAddress, hopTokenAddress], + tvlUsd, + url: `https://app.hop.exchange/#/pool?token=${token}`, + }); + } + } + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/hord/index.js b/src/adaptors/hord/index.js new file mode 100644 index 0000000000..38a3278246 --- /dev/null +++ b/src/adaptors/hord/index.js @@ -0,0 +1,38 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const token = '0x5bBe36152d3CD3eB7183A82470b39b29EedF068B'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const apyData = ( + await axios.get('https://api.hord.app/validators/stats/latest') + ).data.stats; + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'hord', + symbol: 'heth', + tvlUsd: (tvl / apyData.heth_to_eth) * ethPrice, + apyBase: apyData.eth_staking_apy, + apyReward: apyData.hord_staking_apy, + rewardTokens: ['0x43a96962254855f16b925556f9e97be436a43448'], + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.hord.fi/', +}; diff --git a/src/adaptors/horizondex/index.js b/src/adaptors/horizondex/index.js new file mode 100644 index 0000000000..0933854318 --- /dev/null +++ b/src/adaptors/horizondex/index.js @@ -0,0 +1,100 @@ +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +// todo: llama block api returning 502 for linea chain +CHAINS_API = { + linea: + 'https://graph-v2.horizondex.io/subgraphs/name/cryptoalgebra/analytics', + // base: 'https://subgraph-base.horizondex.io/subgraphs/name/horizondex/horizondex-base-v2', +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + volumeUSD + fee + token0 { + symbol + id + } + token1 { + symbol + id + } + totalValueLockedToken0 + totalValueLockedToken1 + } + } +`; + +const queryPrior = gql` + { + pools (first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, url, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + CHAINS_API[chainString], + ]); + + let data = (await request(url, query.replace('', block))) + .pools; + + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pools; + + data = data.map((p) => ({ + ...p, + reserve0: p.totalValueLockedToken0, + reserve1: p.totalValueLockedToken1, + feeTier: p.fee * 10, + })); + data = await utils.tvl(data, chainString); + + data = data.map((p) => utils.apy(p, dataPrior, [])); + + return data.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'horizondex', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + underlyingTokens: [p.token0.id, p.token1.id], + poolMeta: `${p.feeTier / 1e4}%`, + volumeUsd1d: p.volumeUSD1d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const data = await Promise.all( + Object.entries(CHAINS_API).map(([chain, url]) => + topLvl(chain, url, timestamp) + ) + ); + + return data.flat().filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + apy: main, + timetravel: false, + url: 'https://app.horizondex.io/pools', +}; diff --git a/src/adaptors/hubble-exchange/index.js b/src/adaptors/hubble-exchange/index.js new file mode 100644 index 0000000000..a021425d9f --- /dev/null +++ b/src/adaptors/hubble-exchange/index.js @@ -0,0 +1,87 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const VAMM_ABI_JSON = require('./vamm.abi.json'); +const { BigNumber } = require('ethers'); + +const API_BASE = 'https://mainnet-efb9f.web.app/apy'; +const HIF = '0x870850A72490379f60A4924Ca64BcA89a6D53a9d'; +const HUSD = '0x5c6FC0AaF35A55E7a43Fff45575380bCEdb5Cbc2'; +const AVAX_VAMM = '0x269Cd1827fCa5c4d3c7748C45708806c026052FE'; +const CHAIN = 'avax'; +const WAVAX = '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7'; + +const main = async () => { + const { + data: { hour: makerApy }, + } = await axios.get(`${API_BASE}/maker/AVAX-PERP`); + + const priceKey = `avax:${WAVAX}`; + const { data: prices } = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const avaxPrice = prices.coins[priceKey].price; + const TEN = BigNumber.from(10); + + const [vammHusdBalance, vammAvaxBalance] = await Promise.all([ + sdk.api.abi + .call({ + target: AVAX_VAMM, + abi: VAMM_ABI_JSON.find((x) => x.name === 'balances'), + params: [0], + chain: CHAIN, + }) + .then((x) => BigNumber.from(x.output).div(TEN.pow(6)).toNumber()), + sdk.api.abi + .call({ + target: AVAX_VAMM, + abi: VAMM_ABI_JSON.find((x) => x.name === 'balances'), + params: [1], + chain: CHAIN, + }) + .then((x) => + BigNumber.from(x.output) + .div(TEN.pow(18)) + .mul(Math.floor(avaxPrice * 100)) + .div(100) + .toNumber() + ), + ]); + + const avaxMakerPool = { + pool: `maker-AVAX`, + apy: +makerApy, + symbol: `AVAX-hUSD-USDC`, + tvlUsd: vammAvaxBalance + vammHusdBalance, + }; + + const { + data: { hour: hifApy }, + } = await axios.get(`${API_BASE}/insurance`); + const husdBalance = await sdk.api.erc20.balanceOf({ + target: HUSD, + owner: HIF, + chain: 'avax', + decimals: 6, + }); + + const hifPool = { + pool: 'HIF', + apy: +hifApy, + symbol: 'USDC', + tvlUsd: +husdBalance.output, + }; + + const allPools = [avaxMakerPool, hifPool]; + + return allPools.map((pool) => ({ + ...pool, + chain: 'Avalanche', + project: 'hubble-exchange', + })); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.hubble.exchange', +}; diff --git a/src/adaptors/hubble-exchange/vamm.abi.json b/src/adaptors/hubble-exchange/vamm.abi.json new file mode 100644 index 0000000000..673878b3ed --- /dev/null +++ b/src/adaptors/hubble-exchange/vamm.abi.json @@ -0,0 +1,1363 @@ +[ + { + "name": "TokenExchange", + "inputs": [ + { + "name": "sold_id", + "type": "uint256", + "indexed": false + }, + { + "name": "tokens_sold", + "type": "uint256", + "indexed": false + }, + { + "name": "bought_id", + "type": "uint256", + "indexed": false + }, + { + "name": "tokens_bought", + "type": "uint256", + "indexed": false + }, + { + "name": "trade_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "vamm", + "type": "bytes", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "AddLiquidity", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "token_amounts", + "type": "uint256[2]", + "indexed": false + }, + { + "name": "fee", + "type": "uint256", + "indexed": false + }, + { + "name": "token_supply", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RemoveLiquidity", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "token_amounts", + "type": "uint256[2]", + "indexed": false + }, + { + "name": "token_supply", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RemoveLiquidityOne", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "token_amount", + "type": "uint256", + "indexed": false + }, + { + "name": "coin_index", + "type": "uint256", + "indexed": false + }, + { + "name": "coin_amount", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "CommitNewAdmin", + "inputs": [ + { + "name": "deadline", + "type": "uint256", + "indexed": true + }, + { + "name": "admin", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "name": "admin", + "type": "address", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "CommitNewParameters", + "inputs": [ + { + "name": "deadline", + "type": "uint256", + "indexed": true + }, + { + "name": "admin_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "mid_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "out_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "fee_gamma", + "type": "uint256", + "indexed": false + }, + { + "name": "allowed_extra_profit", + "type": "uint256", + "indexed": false + }, + { + "name": "adjustment_step", + "type": "uint256", + "indexed": false + }, + { + "name": "ma_half_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewParameters", + "inputs": [ + { + "name": "admin_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "mid_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "out_fee", + "type": "uint256", + "indexed": false + }, + { + "name": "fee_gamma", + "type": "uint256", + "indexed": false + }, + { + "name": "allowed_extra_profit", + "type": "uint256", + "indexed": false + }, + { + "name": "adjustment_step", + "type": "uint256", + "indexed": false + }, + { + "name": "ma_half_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RampAgamma", + "inputs": [ + { + "name": "initial_A", + "type": "uint256", + "indexed": false + }, + { + "name": "future_A", + "type": "uint256", + "indexed": false + }, + { + "name": "initial_gamma", + "type": "uint256", + "indexed": false + }, + { + "name": "future_gamma", + "type": "uint256", + "indexed": false + }, + { + "name": "initial_time", + "type": "uint256", + "indexed": false + }, + { + "name": "future_time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StopRampA", + "inputs": [ + { + "name": "current_A", + "type": "uint256", + "indexed": false + }, + { + "name": "current_gamma", + "type": "uint256", + "indexed": false + }, + { + "name": "time", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "ClaimAdminFee", + "inputs": [ + { + "name": "admin", + "type": "address", + "indexed": true + }, + { + "name": "tokens", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "view", + "type": "function", + "name": "vars", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "gas": 41181 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "math", + "type": "address" + }, + { + "name": "views", + "type": "address" + }, + { + "name": "A", + "type": "uint256" + }, + { + "name": "gamma", + "type": "uint256" + }, + { + "name": "mid_fee", + "type": "uint256" + }, + { + "name": "out_fee", + "type": "uint256" + }, + { + "name": "allowed_extra_profit", + "type": "uint256" + }, + { + "name": "fee_gamma", + "type": "uint256" + }, + { + "name": "adjustment_step", + "type": "uint256" + }, + { + "name": "admin_fee", + "type": "uint256" + }, + { + "name": "ma_half_time", + "type": "uint256" + } + ], + "outputs": [], + "gas": 583243 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setinitialPrice", + "inputs": [ + { + "name": "initial_price", + "type": "uint256" + } + ], + "outputs": [], + "gas": 142651 + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "view", + "type": "function", + "name": "A", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 537 + }, + { + "stateMutability": "view", + "type": "function", + "name": "gamma", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11871 + }, + { + "stateMutability": "view", + "type": "function", + "name": "fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11084 + }, + { + "stateMutability": "view", + "type": "function", + "name": "fee_calc", + "inputs": [ + { + "name": "xp", + "type": "uint256[2]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3337 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_virtual_price", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 13061 + }, + { + "stateMutability": "view", + "type": "function", + "name": "calc_mark_price", + "inputs": [ + { + "name": "_balances", + "type": "uint256[2]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 27576 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "exchange", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dx", + "type": "uint256" + }, + { + "name": "min_dy", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "gas": 818646 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "exchangeExactOut", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dy", + "type": "uint256" + }, + { + "name": "max_dx", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "gas": 818694 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_dy", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dx", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11855 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_dx", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dy", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11885 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_dy_fee", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dx", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11921 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_dx_fee", + "inputs": [ + { + "name": "i", + "type": "uint256" + }, + { + "name": "j", + "type": "uint256" + }, + { + "name": "dy", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 11951 + }, + { + "stateMutability": "view", + "type": "function", + "name": "calc_token_fee", + "inputs": [ + { + "name": "amounts", + "type": "uint256[2]" + }, + { + "name": "xp", + "type": "uint256[2]" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 10308 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_liquidity", + "inputs": [ + { + "name": "amounts", + "type": "uint256[2]" + }, + { + "name": "min_mint_amount", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 834486 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "remove_liquidity", + "inputs": [ + { + "name": "amount", + "type": "uint256" + }, + { + "name": "min_amounts", + "type": "uint256[2]" + }, + { + "name": "vUSD", + "type": "uint256" + }, + { + "name": "vAsset", + "type": "uint256" + }, + { + "name": "makerDToken", + "type": "uint256" + }, + { + "name": "takerPosSize", + "type": "int256" + }, + { + "name": "takerOpenNotional", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "uint256[2]" + } + ], + "gas": 304119 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_maker_position", + "inputs": [ + { + "name": "amount", + "type": "uint256" + }, + { + "name": "vUSD", + "type": "uint256" + }, + { + "name": "vAsset", + "type": "uint256" + }, + { + "name": "makerDToken", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "int256" + } + ], + "gas": 34057 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_notional", + "inputs": [ + { + "name": "makerDToken", + "type": "uint256" + }, + { + "name": "vUSD", + "type": "uint256" + }, + { + "name": "vAsset", + "type": "uint256" + }, + { + "name": "takerPosSize", + "type": "int256" + }, + { + "name": "takerOpenNotional", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "uint256" + } + ], + "gas": 44228 + }, + { + "stateMutability": "view", + "type": "function", + "name": "calc_token_amount", + "inputs": [ + { + "name": "amounts", + "type": "uint256[2]" + }, + { + "name": "deposit", + "type": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 5658 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setAMM", + "inputs": [ + { + "name": "_address", + "type": "address" + } + ], + "outputs": [], + "gas": 38294 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setNewParameters", + "inputs": [ + { + "name": "mid_fee", + "type": "uint256" + } + ], + "outputs": [], + "gas": 38224 + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3168 + }, + { + "stateMutability": "view", + "type": "function", + "name": "price_scale", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3198 + }, + { + "stateMutability": "view", + "type": "function", + "name": "price_oracle", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3228 + }, + { + "stateMutability": "view", + "type": "function", + "name": "mark_price", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3258 + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_prices", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3288 + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_prices_timestamp", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3318 + }, + { + "stateMutability": "view", + "type": "function", + "name": "initial_A_gamma", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3348 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_A_gamma", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3378 + }, + { + "stateMutability": "view", + "type": "function", + "name": "initial_A_gamma_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3408 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_A_gamma_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3438 + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowed_extra_profit", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3468 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_allowed_extra_profit", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3498 + }, + { + "stateMutability": "view", + "type": "function", + "name": "fee_gamma", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3528 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_fee_gamma", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3558 + }, + { + "stateMutability": "view", + "type": "function", + "name": "adjustment_step", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3588 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_adjustment_step", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3618 + }, + { + "stateMutability": "view", + "type": "function", + "name": "ma_half_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3648 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_ma_half_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3678 + }, + { + "stateMutability": "view", + "type": "function", + "name": "mid_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3708 + }, + { + "stateMutability": "view", + "type": "function", + "name": "out_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3738 + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3768 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_mid_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3798 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_out_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3828 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_admin_fee", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3858 + }, + { + "stateMutability": "view", + "type": "function", + "name": "balances", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3933 + }, + { + "stateMutability": "view", + "type": "function", + "name": "D", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 3918 + }, + { + "stateMutability": "view", + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "gas": 3948 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "gas": 3978 + }, + { + "stateMutability": "view", + "type": "function", + "name": "xcp_profit", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4008 + }, + { + "stateMutability": "view", + "type": "function", + "name": "xcp_profit_a", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4038 + }, + { + "stateMutability": "view", + "type": "function", + "name": "virtual_price", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4068 + }, + { + "stateMutability": "view", + "type": "function", + "name": "not_adjusted", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "gas": 4098 + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "gas": 4128 + }, + { + "stateMutability": "view", + "type": "function", + "name": "kill_deadline", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4158 + }, + { + "stateMutability": "view", + "type": "function", + "name": "transfer_ownership_deadline", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4188 + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin_actions_deadline", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "gas": 4218 + } +] diff --git a/src/adaptors/hydradex-v2/index.js b/src/adaptors/hydradex-v2/index.js new file mode 100755 index 0000000000..8a0a063c95 --- /dev/null +++ b/src/adaptors/hydradex-v2/index.js @@ -0,0 +1,164 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const url = 'https://info.hydradex.org/graphql'; + +const pairsQuery = gql` + { + pairs(first: 1000, orderBy: "trackedReserveHYDRA", orderDirection: "desc") { + id + } + } +`; +const query = gql` + { + pairs(first: 1000, orderBy: "trackedReserveHYDRA", orderDirection: "desc", block: {number: }, where: {id_in: }) { + id + reserve0 + reserve1 + volumeUSD + reserveUSD + token0 { + symbol + tokenAddress + } + token1 { + symbol + tokenAddress + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000, orderBy: "trackedReserveHYDRA", orderDirection: "desc", block: {number: }, where: {id_in: }) { + id + volumeUSD + reserveUSD + } + } +`; + +const queryBlocks = gql` + { + blocks( + orderBy: "height" + first: 1 + orderDirection: "desc" + where: { timestamp_lte: } + ) { + number + } + } +`; + +const getV2Blocks = async (tsTimeTravel, offset = 86400) => { + const timestamp = + tsTimeTravel !== null + ? Number(tsTimeTravel) + : Math.floor(Date.now() / 1000); + + const timestampPrior = timestamp - offset; + + const blocks = []; + for (const ts of [timestamp, timestampPrior]) { + const data = (await request(url, queryBlocks.replace('', ts))) + .blocks; + blocks.push(data[0].number); + } + + return blocks; +}; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const [block, blockPrior] = await getV2Blocks(timestamp); + + const [_, blockPrior7d] = await getV2Blocks(timestamp, 604800); + // Hotfix for v2 graph bug + const pairIds = JSON.stringify( + (await request(url, pairsQuery))?.pairs?.map((pair) => pair?.id) + ); + + // pull data + let queryC = query; + let dataNow = await request( + url, + queryC.replace('', block).replace('', pairIds) + ); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC + .replace('', blockPrior) + .replace('', pairIds) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request( + url, + queryPriorC + .replace('', blockPrior7d) + .replace('', pairIds) + ) + ).pairs; + + // calculate tvl + dataNow = dataNow.map((x) => { + x.totalValueLockedUSD = Number(x.reserveUSD); + delete x.reserveUSD; + return x; + }); + + // calculate apy + dataNow = dataNow + .filter((x) => x.token0.symbol) + .map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.tokenAddress, p.token1.tokenAddress]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'hydra' ? 'mainnet' : chainString; + const url = `https://hydradex.org/#/add/v2/${token0}/${token1}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'hydradex-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +}; + +const main = async (timestamp = null) => { + let data = await topLvl('hydra', url, query, queryPrior, 'v2', timestamp); + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/hydradex-v3/index.js b/src/adaptors/hydradex-v3/index.js new file mode 100644 index 0000000000..19c6a0c704 --- /dev/null +++ b/src/adaptors/hydradex-v3/index.js @@ -0,0 +1,322 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('../uniswap-v3/estimateFee.ts'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); + +const WHYDRA = '0x6d9115a21863ce31b44cd231e4c4ccc87566222f'; +const ignoreIncentives = [ + '0x3fd993e02095478ec7272d949f5c63dfece7eed8c884ff46035f301b37707754', + '0xa8235e34eba238ccf1cf952f853e1a095637be92c1f4fe4fee07240d2b8e545f', + '0xc87f5d3ed6c61582bc4b866202c0953730121615e3560d2c18539e6ba2babccd', + '0xff8b5ea09291191f6eca3ea3d827daa094cebc75734935656aa6cd932b3bc448', +]; + +const baseUrl = 'https://graph.hydradex.org/subgraphs/name/v3-subgraph'; +const blocksUrl = + 'https://graph.hydradex.org/subgraphs/name/blocklytics/ethereum-blocks'; +const incentivesUrl = 'https://graph.hydradex.org/subgraphs/name/v3-staker'; +const chains = { + hydra: baseUrl, +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + totalValueLockedUSD + totalValueLockedETH + volumeUSD + feeTier + token0Price + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const queryBlocks = gql` + { + blocks( + orderBy: "number" + first: 1 + orderDirection: "desc" + where: { timestamp_lte: } + ) { + number + } + } +`; + +const queryIncentives = gql` + { + incentives( + where: { + startTime_lte: + endTime_gt: + pool_in: + } + ) { + pool + id + startTime + endTime + reward + } + } +`; + +const getV3Blocks = async (tsTimeTravel, offset = 86400) => { + const timestamp = + tsTimeTravel !== null + ? Number(tsTimeTravel) + : Math.floor(Date.now() / 1000); + + const timestampPrior = timestamp - offset; + + const blocks = []; + for (const ts of [timestamp, timestampPrior]) { + const data = ( + await request(blocksUrl, queryBlocks.replace('', ts)) + ).blocks; + blocks.push(data[0].number); + } + + return blocks; +}; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await getV3Blocks(timestamp); + + const [_, blockPrior7d] = await getV3Blocks(timestamp, 604800); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // map reserves + dataNow = dataNow.map((p) => ({ + ...p, + reserve0: Number(p.totalValueLockedToken0), + reserve1: Number(p.totalValueLockedToken1), + totalValueLockedUSD: Number(p.totalValueLockedUSD), + })); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = false; + if (enableV3Apy) { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.token0Price, + })); + + // split up subgraph tick calls into n-batches + // (tick response can be in the thousands per pool) + const skip = 20; + let start = 0; + let stop = skip; + const pages = Math.floor(dataNow.length / skip); + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + let X = []; + for (let i = 0; i <= pages; i++) { + console.log(i); + let promises = dataNow.slice(start, stop).map((p) => { + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + return EstimatedFees( + p.id, + priceAssumption, + [ + p.token1_in_token0 * (1 - delta), + p.token1_in_token0 * (1 + delta), + ], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + url, + p.volumeUSD7d + ); + }); + X.push(await Promise.all(promises)); + start += skip; + stop += skip; + } + const d = {}; + X.flat().forEach((p) => { + d[p.poolAddress] = p.estimatedFee; + }); + + dataNow = dataNow.map((p) => ({ + ...p, + apy7d: ((d[p.id] * 52) / investmentAmount) * 100, + })); + } + + const ts = + timestamp !== null ? Number(timestamp) : Math.floor(Date.now() / 1000); + const incentives = ( + await request( + incentivesUrl, + queryIncentives + .replace('', ts) + .replace('', ts) + .replace( + '', + JSON.stringify(dataNow.map((p) => p.id)) + ) + ) + ).incentives; + + const incentivesReward = incentives.reduce((acc, cur) => { + if (ignoreIncentives.includes(cur.id)) return acc; + + const duration = (cur.endTime - cur.startTime) / 60 / 60 / 24; + const annualReward = (cur.reward / 1e8) * (365.25 / duration); + + if (!acc[cur.pool]) { + acc[cur.pool] = 0; + } + + acc[cur.pool] += annualReward; + return acc; + }, {}); + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'hydra' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://hydradex.org/#/add/${token0}/${token1}/${feeTier}`; + + const apyReward = + ((incentivesReward[p.id] || 0) / p.totalValueLockedETH) * 100; + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'hydradex-v3', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward: apyReward || undefined, + rewardTokens: apyReward ? [WHYDRA] : undefined, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/hydration-dex/index.js b/src/adaptors/hydration-dex/index.js new file mode 100644 index 0000000000..a3d10d3118 --- /dev/null +++ b/src/adaptors/hydration-dex/index.js @@ -0,0 +1,401 @@ +const { gql, request } = require('graphql-request'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const HYDRATION_GRAPHQL_URL = "https://galacticcouncil.squids.live/hydration-pools:whale-prod/api/graphql"; + +// Asset mapping for TVL calculation +const cgMapping = { + DAI: 'dai', + INTR: 'interlay', + GLMR: 'moonbeam', + vDOT: 'voucher-dot', + ZTG: 'zeitgeist', + CFG: 'centrifuge', + BNC: 'bifrost-native-coin', + WETH: 'ethereum', + DOT: 'polkadot', + APE: 'apecoin', + USDC: 'usd-coin', + USDT: 'tether', + ASTR: 'astar', + WBTC: 'wrapped-bitcoin', + iBTC: 'interbtc', + HDX: 'hydradx', + tBTC: 'tbtc', + AAVE: 'aave', + PHA: 'pha', + vASTR: 'bifrost-voucher-astr', + KSM: 'kusama', + KILT: 'kilt-protocol', + SKY: 'sky', + LINK: 'chainlink', + SOL: 'solana', + CRU: 'crust-network', + EWT: 'energy-web-token', + UNQ: 'unique-network', + MYTH: 'mythos', + WUD: 'gawun-wud', + +}; + +const poolsFunction = async () => { + try { + // Fetch yield metrics for all assets + const yieldMetrics = await fetchYieldMetrics(); + + // Fetch asset symbols mapping + const assetSymbols = await fetchAssetSymbols(); + + // Fetch TVL data + const tvlData = await getTvlData(); + + // Create symbol lookup map + const symbolMap = {}; + assetSymbols.forEach(asset => { + symbolMap[asset.assetRegistryId] = asset.symbol; + }); + + const pools = []; + + // Process each asset's yield metrics + for (const metric of yieldMetrics) { + // Handle isolated pools separately (they use pool account IDs instead of asset IDs) + if (metric.poolType === 'isolatedpool' && metric.id.length > 20) { + // For isolated pools, get the actual TVL from our TVL data using the pool account ID + const poolAccountId = metric.id; + const poolTvl = tvlData[poolAccountId] || 0; + + // Skip if no TVL data available for this pool + if (poolTvl === 0) { + continue; + } + + // Parse APY values + const apyBase = parseFloat(metric.feeApyPerc) || 0; + const apyReward = parseFloat(metric.incentivesApyPerc) || 0; + + // Skip pools with no yield + if (apyBase === 0 && apyReward === 0) { + continue; + } + + // Get the pool composition from stored data + const poolComposition = tvlData[`${poolAccountId}_composition`]; + let poolName = poolAccountId.substring(0, 10) + '...'; + let underlyingSymbols = [poolAccountId]; + + if (poolComposition) { + poolName = poolComposition.join('-'); + underlyingSymbols = poolComposition; + } + + // Map incentive tokens to symbols + const rewardTokens = apyReward > 0 ? mapIncentiveTokens(metric.incentivesTokens, symbolMap) : null; + + const pool = { + pool: `${poolName}-hydration-dex`, + chain: 'Polkadot', + project: 'hydration-dex', + symbol: poolName, + tvlUsd: poolTvl, + apyBase: apyBase > 0 ? apyBase : null, + apyReward: apyReward > 0 ? apyReward : null, + rewardTokens: rewardTokens, + underlyingTokens: underlyingSymbols, + url: 'https://app.hydration.net/liquidity/all-pools', + poolMeta: formatPoolType(metric.poolType) + }; + + pools.push(pool); + continue; + } + + // Get symbol from the mapping + let symbol = symbolMap[metric.id]; + + // Skip if no symbol found + if (!symbol) { + continue; + } + + // Clean up symbol formatting + symbol = cleanSymbol(symbol); + + // Parse APY values + const apyBase = parseFloat(metric.feeApyPerc) || 0; + const apyReward = parseFloat(metric.incentivesApyPerc) || 0; + + // Skip pools with no yield + if (apyBase === 0 && apyReward === 0) { + continue; + } + + // Get TVL for this asset + let tvlUsd = tvlData[symbol] || 0; + + // Skip pools with no TVL + if (tvlUsd === 0) { + continue; + } + + // Map incentive tokens to symbols + const rewardTokens = apyReward > 0 ? mapIncentiveTokens(metric.incentivesTokens, symbolMap) : null; + + const pool = { + pool: `${symbol}-hydration-dex`, + chain: 'Polkadot', + project: 'hydration-dex', + symbol: utils.formatSymbol(symbol), + tvlUsd: tvlUsd, + apyBase: apyBase > 0 ? apyBase : null, + apyReward: apyReward > 0 ? apyReward : null, + rewardTokens: rewardTokens, + underlyingTokens: [symbol], + url: 'https://app.hydration.net/liquidity/all-pools', + poolMeta: formatPoolType(metric.poolType) + }; + + pools.push(pool); + } + + return pools; + + } catch (error) { + console.error('Error fetching HydraDX pools:', error); + return []; + } +}; + +// Fetch yield metrics for all assets +async function fetchYieldMetrics() { + const query = gql` + query MyQuery { + allAssetsYieldMetrics { + nodes { + id + poolType + feeApyPerc + incentivesApyPerc + incentivesTokens + } + totalCount + } + } + `; + + const response = await request(HYDRATION_GRAPHQL_URL, query); + return response.allAssetsYieldMetrics.nodes || []; +} + +// Fetch asset symbols mapping +async function fetchAssetSymbols() { + const query = gql` + query MyQuery { + assets { + nodes { + assetRegistryId + symbol + } + } + } + `; + + const response = await request(HYDRATION_GRAPHQL_URL, query); + return response.assets.nodes || []; +} + +// Fetch omnipool TVL data using the new omnipoolAssetsLatestTvl query +async function fetchOmnipoolTvl() { + const query = gql` + query MyQuery { + omnipoolAssetsLatestTvl { + nodes { + assetId + assetRegistryId + tvlInRefAssetNorm + paraBlockHeight + } + } + } + `; + + const response = await request(HYDRATION_GRAPHQL_URL, query); + return response.omnipoolAssetsLatestTvl.nodes || []; +} + +// Fetch all available XYK pools to get their pool IDs +async function fetchAllXykPools() { + const query = gql` + query MyQuery { + xykpoolsLatestTvl { + nodes { + poolId + tvlInRefAssetNorm + paraBlockHeight + } + } + } + `; + + const response = await request(HYDRATION_GRAPHQL_URL, query); + return response.xykpoolsLatestTvl.nodes || []; +} + +// Fetch XYK pool TVL data using the new xykpoolsLatestTvl query +async function fetchXykPoolTvl(poolIds) { + if (!poolIds || poolIds.length === 0) { + return []; + } + + const poolIdsFilter = poolIds.map(id => `"${id}"`).join(', '); + const query = gql` + query MyQuery { + xykpoolsLatestTvl(filter: {poolIds: [${poolIdsFilter}]}) { + nodes { + poolId + tvlInRefAssetNorm + paraBlockHeight + } + } + } + `; + + const response = await request(HYDRATION_GRAPHQL_URL, query); + return response.xykpoolsLatestTvl.nodes || []; +} + +// Get asset TVL using the new TVL queries +async function getTvlData() { + try { + // Fetch asset symbols mapping + const assetSymbols = await fetchAssetSymbols(); + + // Create asset ID to symbol mapping + const assetIdToSymbol = {}; + assetSymbols.forEach(asset => { + assetIdToSymbol[asset.assetRegistryId] = asset.symbol; + }); + + const assetTvls = {}; + + // Fetch omnipool TVL data + const omnipoolTvlData = await fetchOmnipoolTvl(); + + // Process omnipool TVL data + for (const tvlEntry of omnipoolTvlData) { + const assetId = tvlEntry.assetRegistryId; + const symbol = assetIdToSymbol[assetId]; + + if (symbol) { + const cleanedSymbol = cleanSymbol(symbol); + // Skip if we don't have a CoinGecko mapping for this asset + if (cgMapping[cleanedSymbol]) { + const tvlUsd = parseFloat(tvlEntry.tvlInRefAssetNorm); + assetTvls[cleanedSymbol] = tvlUsd; + } + } + } + + // Handle isolated pools (XYK pools) with correct pool ID mapping + const allXykPools = await fetchAllXykPools(); + + // Known mappings of pool IDs to compositions based on actual pool IDs + const xykPoolMappings = { + '0xbf80080b4d0077544ef058a29e878ae6f6bdb8cf2f462ab390490f668eb50b73': { + poolAccountId: "15L6BQ1sMd9pESapK13dHaXBPPtBYnDnKTVhb2gBeGrrJNBx", + composition: ['MYTH', 'DOT'] + }, + '0xd4044eed8c3a16740b3edf9e85cd6384c66eecf21179843cd863c20bfa6b082f': { + poolAccountId: "15nzS2D2wJdh52tqZdUJVMeDQqQe7wJfo5NZKL7pUxhwYgwq", + composition: ['DOT', 'EWT'] + } + }; + + // Process XYK pool TVL data using known mappings + for (const xykPool of allXykPools) { + const poolTvl = parseFloat(xykPool.tvlInRefAssetNorm); + const poolMapping = xykPoolMappings[xykPool.poolId]; + + if (poolMapping && poolTvl > 0) { + assetTvls[poolMapping.poolAccountId] = poolTvl; + assetTvls[`${poolMapping.poolAccountId}_composition`] = poolMapping.composition; + } + } + + return assetTvls; + } catch (error) { + console.error('Error fetching TVL data:', error); + return {}; + } +} + +// Helper function to map incentive token IDs to symbols +function mapIncentiveTokens(incentivesTokens, symbolMap) { + if (!incentivesTokens || !Array.isArray(incentivesTokens) || incentivesTokens.length === 0) { + return null; + } + + const mappedTokens = incentivesTokens + .map(tokenId => { + // Handle HDX (asset ID 0) specially + if (tokenId === "0" || tokenId === 0) { + return 'HDX'; + } + + // Map other token IDs to symbols + const symbol = symbolMap[tokenId]; + return symbol ? cleanSymbol(symbol) : null; + }) + .filter(symbol => symbol !== null); // Remove any unmapped tokens + + return mappedTokens.length > 0 ? mappedTokens : null; +} + +// Helper function to clean up symbol formatting +function cleanSymbol(symbol) { + // Handle null or undefined symbols + if (!symbol) { + return null; + } + + // Remove common prefixes that might come from the API + symbol = symbol.replace(/^2-POOL-/i, ''); + symbol = symbol.replace(/^3-POOL-/i, ''); + symbol = symbol.replace(/^4-POOL-/i, ''); + symbol = symbol.replace(/^POOL-/i, ''); + + // Handle specific symbol mappings for better display + const symbolMappings = { + 'TBTC': 'tBTC', + 'VASTR': 'vASTR', + 'VDOT': 'vDOT' + }; + + const upperSymbol = symbol.toUpperCase(); + if (symbolMappings[upperSymbol]) { + return symbolMappings[upperSymbol]; + } + + return symbol; +} + +// Helper function to format pool type for display +function formatPoolType(poolType) { + switch(poolType) { + case 'omnipool': + return 'Omnipool'; + case 'isolatedpool': + return 'Isolated Pool'; + case 'stableswap': + return 'Stable Swap'; + default: + return 'Pool'; + } +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.hydration.net/liquidity/all-pools', +}; diff --git a/src/adaptors/hydt-protocol/earnABI.js b/src/adaptors/hydt-protocol/earnABI.js new file mode 100644 index 0000000000..b85d2b2405 --- /dev/null +++ b/src/adaptors/hydt-protocol/earnABI.js @@ -0,0 +1,957 @@ +module.exports = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "index", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "payout", + type: "uint256" + } + ], + name: "Payout", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "bytes32", + name: "previousAdminRole", + type: "bytes32" + }, + { + indexed: true, + internalType: "bytes32", + name: "newAdminRole", + type: "bytes32" + } + ], + name: "RoleAdminChanged", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + } + ], + name: "RoleGranted", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + } + ], + name: "RoleRevoked", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "index", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint8", + name: "stakeType", + type: "uint8" + }, + { + indexed: false, + internalType: "uint256", + name: "startTime", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "endTime", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "activeDeposits", + type: "uint256" + } + ], + name: "Stake", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "index", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "activeDeposits", + type: "uint256" + } + ], + name: "Unstake", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "stakeType", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newAllocPoint", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "oldAllocPoint", + type: "uint256" + } + ], + name: "UpdateAllocationWithUpdate", + type: "event" + }, + { + inputs: [], + name: "DEFAULT_ADMIN_ROLE", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "GOVERNOR_ROLE", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "HYDT", + outputs: [ + { + internalType: "contract IHYDT", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "HYGT", + outputs: [ + { + internalType: "contract IHYGT", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "HYGTPerSecond", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "TREASURY", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "stakeType", + type: "uint256" + }, + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "allPoolInfo", + outputs: [ + { + components: [ + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + }, + { + internalType: "uint256", + name: "allocPoint", + type: "uint256" + }, + { + internalType: "uint256", + name: "stakeSupply", + type: "uint256" + }, + { + internalType: "uint256", + name: "accHYGTPerShare", + type: "uint256" + }, + { + internalType: "uint256", + name: "lastRewardTime", + type: "uint256" + } + ], + internalType: "struct Earn.PoolInfo", + name: "", + type: "tuple" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "claimPayout", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "dailyPayouts", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "depositFee", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "getDailyPayoutBatch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + }, + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "getPayout", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "getPayoutBatch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + }, + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + } + ], + name: "getPayoutType", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + }, + { + internalType: "uint256", + name: "index", + type: "uint256" + } + ], + name: "getPending", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "getPendingBatch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + }, + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + } + ], + name: "getPendingType", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + } + ], + name: "getRoleAdmin", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "getStakingLengths", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "getStakings", + outputs: [ + { + internalType: "uint256", + name: "index", + type: "uint256" + }, + { + internalType: "bool", + name: "status", + type: "bool" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + }, + { + internalType: "uint256", + name: "startTime", + type: "uint256" + }, + { + internalType: "uint256", + name: "endTime", + type: "uint256" + }, + { + internalType: "uint256", + name: "lastClaimTime", + type: "uint256" + }, + { + internalType: "uint256", + name: "rewardDebt", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "grantRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "hasRole", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "hydt_", + type: "address" + }, + { + internalType: "address", + name: "hygt_", + type: "address" + }, + { + internalType: "address", + name: "shydt_", + type: "address" + }, + { + internalType: "address", + name: "treasury_", + type: "address" + }, + { + internalType: "uint256", + name: "initialMintStartTime_", + type: "uint256" + } + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "lockPeriods", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "massUpdatePools", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "poolInfo", + outputs: [ + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + }, + { + internalType: "uint256", + name: "allocPoint", + type: "uint256" + }, + { + internalType: "uint256", + name: "stakeSupply", + type: "uint256" + }, + { + internalType: "uint256", + name: "accHYGTPerShare", + type: "uint256" + }, + { + internalType: "uint256", + name: "lastRewardTime", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "poolLength", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "renounceRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "revokeRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "sHYDT", + outputs: [ + { + internalType: "contract IHYDT", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + } + ], + name: "stake", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "startTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceId", + type: "bytes4" + } + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "totalAllocPoint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + }, + { + internalType: "uint256", + name: "newAllocPoint", + type: "uint256" + } + ], + name: "updateAllocationWithUpdate", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint8", + name: "stakeType", + type: "uint8" + } + ], + name: "updatePool", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "yearlyYields", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + } +]; \ No newline at end of file diff --git a/src/adaptors/hydt-protocol/farmABI.js b/src/adaptors/hydt-protocol/farmABI.js new file mode 100644 index 0000000000..e78a65aa5b --- /dev/null +++ b/src/adaptors/hydt-protocol/farmABI.js @@ -0,0 +1,682 @@ +module.exports = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "address", + name: "lpToken", + type: "address" + }, + { + indexed: false, + internalType: "string", + name: "symbol", + type: "string" + }, + { + indexed: false, + internalType: "uint256", + name: "allocPoint", + type: "uint256" + } + ], + name: "AddPool", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Deposit", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "EmergencyWithdraw", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "bytes32", + name: "previousAdminRole", + type: "bytes32" + }, + { + indexed: true, + internalType: "bytes32", + name: "newAdminRole", + type: "bytes32" + } + ], + name: "RoleAdminChanged", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + } + ], + name: "RoleGranted", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + } + ], + name: "RoleRevoked", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newAllocPoint", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "oldAllocPoint", + type: "uint256" + } + ], + name: "UpdateAllocation", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Withdraw", + type: "event" + }, + { + inputs: [], + name: "DEFAULT_ADMIN_ROLE", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "GOVERNOR_ROLE", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "HYGT", + outputs: [ + { + internalType: "contract IHYGT", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "HYGTPerBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "contract IERC20", + name: "lpToken", + type: "address" + }, + { + internalType: "uint256", + name: "allocPoint", + type: "uint256" + }, + { + internalType: "string", + name: "symbol", + type: "string" + }, + { + internalType: "bool", + name: "withUpdate", + type: "bool" + } + ], + name: "addPool", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "deposit", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + } + ], + name: "emergencyWithdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "getPending", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "getPendingBatch", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + } + ], + name: "getRoleAdmin", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "grantRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "hasRole", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "hygt_", + type: "address" + }, + { + internalType: "address[3]", + name: "lpTokens_", + type: "address[3]" + }, + { + internalType: "uint256", + name: "initialMintStartTime_", + type: "uint256" + } + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "massUpdatePools", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "poolInfo", + outputs: [ + { + internalType: "contract IERC20", + name: "lpToken", + type: "address" + }, + { + internalType: "uint256", + name: "allocPoint", + type: "uint256" + }, + { + internalType: "uint256", + name: "lastRewardBlock", + type: "uint256" + }, + { + internalType: "uint256", + name: "accHYGTPerShare", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "poolLength", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "renounceRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32" + }, + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "revokeRole", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "startBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceId", + type: "bytes4" + } + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "totalAllocPoint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "newAllocPoint", + type: "uint256" + }, + { + internalType: "bool", + name: "withUpdate", + type: "bool" + } + ], + name: "updateAllocation", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + } + ], + name: "updatePool", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "userInfo", + outputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + internalType: "uint256", + name: "rewardDebt", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "pid", + type: "uint256" + } + ], + name: "withdrawRewards", + outputs: [], + stateMutability: "nonpayable", + type: "function" + } +]; \ No newline at end of file diff --git a/src/adaptors/hydt-protocol/index.js b/src/adaptors/hydt-protocol/index.js new file mode 100644 index 0000000000..b182b4bc56 --- /dev/null +++ b/src/adaptors/hydt-protocol/index.js @@ -0,0 +1,403 @@ +const sdk = require('@defillama/sdk'); +const farmABI = require('./farmABI'); +const earnABI = require('./earnABI'); +const pairABI = require('./pairABI'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); + +const chain = 'bsc'; + +const project = 'hydt-protocol'; + +const earn = '0x8e48d5b2Ac80d9861d07127F06BbF02F73520Ced'; +const farm = '0x4590BaD61aE62ACFF33032e3Bf64b52b7264A779'; +const hydt = '0x9810512Be701801954449408966c630595D0cD51'; +const hygt = '0x100995a7e5fFd8Ee60cc18A10C75CEe8C572c59b'; + +const hygtPair = [{ lpToken: '0xE0e9bBc7aE8EBE4D74065F6EBD710665DA285a0B' }]; + +const getEarnPoolInfo = async (block, poolInfo) => { + const apys = [16, 20, 30]; + const poolDetails = []; + + for (let i = 0; i < poolInfo.length; i++) { + poolDetails.push({ + id: poolInfo[i].stakeType, + allocPoint: poolInfo[i].allocPoint, + totalDeposit: poolInfo[i].stakeSupply, + apy: apys[i], + }); + } + + return poolDetails; +}; + +const getFarmPoolInfo = async (block, poolInfo) => { + const poolDetails = []; + + for (let i = 0; i < poolInfo.length; i++) { + const token0Id = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: pairABI.find((m) => m.name === 'token0'), + chain, + }) + ).output; + const token0Symbol = ( + await sdk.api.abi.call({ + target: token0Id, + abi: pairABI.find((m) => m.name === 'symbol'), + chain, + }) + ).output; + const token0Decimals = ( + await sdk.api.abi.call({ + target: token0Id, + abi: pairABI.find((m) => m.name === 'decimals'), + chain, + }) + ).output; + const token1Id = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: pairABI.find((m) => m.name === 'token1'), + chain, + }) + ).output; + const token1Symbol = ( + await sdk.api.abi.call({ + target: token1Id, + abi: pairABI.find((m) => m.name === 'symbol'), + chain, + }) + ).output; + const token1Decimals = ( + await sdk.api.abi.call({ + target: token1Id, + abi: pairABI.find((m) => m.name === 'decimals'), + chain, + }) + ).output; + + try { + // lpToken variables + const reserves = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: pairABI.find((m) => m.name === 'getReserves'), + block, + chain, + }) + ).output; + const totalSupply = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: pairABI.find((m) => m.name === 'totalSupply'), + block, + chain, + }) + ).output; + const totalDeposit = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: pairABI.find((m) => m.name === 'balanceOf'), + params: farm, + block, + chain, + }) + ).output; + + // pool details + poolDetails.push({ + id: poolInfo[i].lpToken, + allocPoint: poolInfo[i].allocPoint, + reserve0: reserves._reserve0 / (1 * 10 ** token0Decimals), + reserve1: reserves._reserve1 / (1 * 10 ** token1Decimals), + totalSupply: totalSupply, + totalDeposit: totalDeposit, + token0: { + symbol: token0Symbol, + id: token0Id, + }, + token1: { + symbol: token1Symbol, + id: token1Id, + }, + }); + } catch (e) { + // default pool details + poolDetails.push({ + id: poolInfo[i].lpToken, + allocPoint: poolInfo[i].allocPoint, + reserve0: 0, + reserve1: 0, + totalSupply: 0, + token0: { + symbol: token0Symbol, + id: token0Id, + }, + token1: { + symbol: token1Symbol, + id: token1Id, + }, + }); + } + } + + return poolDetails; +}; + +const getData = async (target, block, hydtPrice) => { + let targetABI; + let abiParameter; + + if (target === earn) { + targetABI = earnABI; + abiParameter = 'HYGTPerSecond'; + } else { + targetABI = farmABI; + abiParameter = 'HYGTPerBlock'; + } + + const poolLength = ( + await sdk.api.abi.call({ + target, + abi: targetABI.find((m) => m.name === 'poolLength'), + chain, + }) + ).output; + + let poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target, + params: i, + })), + abi: targetABI.find((m) => m.name === 'poolInfo'), + chain, + }) + ).output.map((o) => o.output); + + poolInfo = poolInfo.filter((i) => i.allocPoint > 0); + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target, + abi: targetABI.find((m) => m.name === 'totalAllocPoint'), + chain, + }) + ).output; + + const hygtPer = + ( + await sdk.api.abi.call({ + target, + abi: targetABI.find((m) => m.name === abiParameter), + chain, + }) + ).output / 1e18; + + // getting hygt price + const hygtPairInfo = await getFarmPoolInfo(block, hygtPair, chain); + const hygtPrice = + (parseFloat(hydtPrice) * hygtPairInfo[0].reserve1) / + parseFloat(hygtPairInfo[0].reserve0); + + return [poolInfo, totalAllocPoint, hygtPer, hygtPrice]; +}; + +const getEarnAPY = async (block, blockPrior, blockPrior7d, hydtPrice) => { + const [poolInfo, totalAllocPoint, hygtPer, hygtPrice] = await getData( + earn, + block, + hydtPrice + ); + + const secondsPerYear = 86400 * 365; + const hygtPerYearUSD = hygtPer * secondsPerYear * hygtPrice; + + // pull data + let data = await getEarnPoolInfo(block, poolInfo, chain); + + // pull data 24h offest + let dataPrior = await getEarnPoolInfo(blockPrior, poolInfo, chain); + + // pull data 7d offest + let dataPrior7d = await getEarnPoolInfo(blockPrior7d, poolInfo, chain); + + // calculate apy + data = data.map((i) => utils.apy(i, dataPrior, dataPrior7d, 'v2')); + + const formattedChain = utils.formatChain(chain); + const pool = `${hydt}-${formattedChain}`.toLowerCase(); + const symbol = 'HYDT'; + const rewardTokens = [hydt, hygt]; + const underlyingTokens = [hydt]; + const url = 'https://app.hydtprotocol.com/HYDT/earn'; + + let apyTotal = 0; + let tvlTotal = 0; + let volumeUsd1dTotal = 0; + let volumeUsd7dTotal = 0; + + data.forEach((p) => { + const totalDeposit = new BigNumber(p.totalDeposit) + .dividedBy(new BigNumber(10).pow(18)) + .toFixed(18); + const tvlUSD = totalDeposit * hydtPrice; + + const apyBase = + (((p.allocPoint / totalAllocPoint) * hygtPerYearUSD) / tvlUSD) * 100 + + p.apy; + + apyTotal += apyBase; + tvlTotal += tvlUSD; + volumeUsd1dTotal += p?.volumeUsd1d || 0; + volumeUsd7dTotal += p?.volumeUsd7d || 0; + }); + + apyTotal /= data.length; + + return [ + { + pool, + chain: formattedChain, + project, + symbol, + url, + tvlUsd: tvlTotal, + apyBase: 0, + apyBase7d: 0, + apyReward: apyTotal || 0, + rewardTokens, + underlyingTokens, + volumeUsd1d: volumeUsd1dTotal, + volumeUsd7d: volumeUsd7dTotal, + }, + ]; +}; + +const getFarmAPY = async (block, blockPrior, blockPrior7d, hydtPrice) => { + const [poolInfo, totalAllocPoint, hygtPer, hygtPrice] = await getData( + farm, + block, + hydtPrice + ); + + const blocksPerYear = (86400 * 365) / 3; + const hygtPerYearUSD = hygtPer * blocksPerYear * hygtPrice; + + // pull data + let data = await getFarmPoolInfo(block, poolInfo, chain); + + // pull data 24h offest + let dataPrior = await getFarmPoolInfo(blockPrior, poolInfo, chain); + + // pull data 7d offest + let dataPrior7d = await getFarmPoolInfo(blockPrior7d, poolInfo, chain); + + // calculate tvl + data = await utils.tvl(data, chain); + + data = data.map((i) => { + const price0 = + i.token0.id == hydt + ? hydtPrice + : i.token0.id == hygt + ? hygtPrice + : i.price0; + const price1 = + i.token1.id == hydt + ? hydtPrice + : i.token1.id == hygt + ? hygtPrice + : i.price1; + const totalValueLockedUSD = price0 * i.reserve0 + price1 * i.reserve1; + return { + ...i, + price0, + price1, + totalValueLockedUSD, + }; + }); + + // calculate apy + data = data.map((i) => utils.apy(i, dataPrior, dataPrior7d, 'v2')); + + data = data.map((p) => { + const formattedChain = utils.formatChain(chain); + const pool = `${p.id}-${formattedChain}`.toLowerCase(); + const symbol = + p.token0.symbol === 'HYDT' + ? utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`) + : p.token1.symbol === 'HYDT' + ? utils.formatSymbol(`${p.token1.symbol}-${p.token0.symbol}`) + : utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const rewardTokens = [hygt]; + const underlyingTokens = [p.id]; + const url = 'https://app.hydtprotocol.com/HYDT/farm'; + + const totalDeposit = new BigNumber(p.totalDeposit) + .dividedBy(new BigNumber(10).pow(18)) + .toFixed(18); + const totalSupply = new BigNumber(p.totalSupply) + .dividedBy(new BigNumber(10).pow(18)) + .toFixed(18); + const ratio = totalDeposit / totalSupply || 1; + const tvlUsd = p.totalValueLockedUSD * ratio; + + const rewardAPY = + (((p.allocPoint / totalAllocPoint) * hygtPerYearUSD) / tvlUsd) * 100; + + return { + pool, + chain: formattedChain, + project, + symbol, + url, + tvlUsd, + apyBase: 0, + apyBase7d: 0, + apyReward: rewardAPY || 0, + rewardTokens, + underlyingTokens, + volumeUsd1d: p?.volumeUSD1d || 0, + volumeUsd7d: p?.volumeUSD7d || 0, + }; + }); + + return data; +}; + +const getAPY = async () => { + // getting all block variables + const timestamp = Date.now() / 1000; + const [block, blockPrior] = await utils.getBlocks(chain, timestamp, []); + const [_, blockPrior7d] = await utils.getBlocks(chain, timestamp, [], 604800); + + // getting hydt price + const hydtPrice = ( + await axios.get(`https://api.dexscreener.com/latest/dex/tokens/${hydt}`) + ).data.pairs[0]?.priceUsd; + + let data = await getEarnAPY(block, blockPrior, blockPrior7d, hydtPrice); + let farmData = await getFarmAPY(block, blockPrior, blockPrior7d, hydtPrice); + + farmData.forEach((i) => data.push(i)); + + return data; +}; + +const main = async () => { + let data = await getAPY(); + + // process.exit(1) + return data.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/hydt-protocol/pairABI.js b/src/adaptors/hydt-protocol/pairABI.js new file mode 100644 index 0000000000..a868a25e29 --- /dev/null +++ b/src/adaptors/hydt-protocol/pairABI.js @@ -0,0 +1,440 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +]; \ No newline at end of file diff --git a/src/adaptors/hyperdrive/abi.js b/src/adaptors/hyperdrive/abi.js new file mode 100644 index 0000000000..d18d7c3655 --- /dev/null +++ b/src/adaptors/hyperdrive/abi.js @@ -0,0 +1,128 @@ +module.exports = { + GET_POOL_CONFIG_ABI: { + "inputs": [], + "name": "getPoolConfig", + "outputs": [{ + "components": [ + { "name": "baseToken", "type": "address" }, + { "name": "vaultSharesToken", "type": "address" }, + { "name": "linkerFactory", "type": "address" }, + { "name": "linkerCodeHash", "type": "bytes32" }, + { "name": "initialVaultSharePrice", "type": "uint256" }, + { "name": "minimumShareReserves", "type": "uint256" }, + { "name": "minimumTransactionAmount", "type": "uint256" }, + { "name": "circuitBreakerDelta", "type": "uint256" }, + { "name": "positionDuration", "type": "uint256" }, + { "name": "checkpointDuration", "type": "uint256" }, + { "name": "timeStretch", "type": "uint256" }, + { "name": "governance", "type": "address" }, + { "name": "feeCollector", "type": "address" }, + { "name": "sweepCollector", "type": "address" }, + { "name": "checkpointRewarder", "type": "address" }, + { + "components": [ + { "name": "curve", "type": "uint256" }, + { "name": "flat", "type": "uint256" }, + { "name": "governanceLP", "type": "uint256" }, + { "name": "governanceZombie", "type": "uint256" } + ], + "name": "fees", + "type": "tuple" + } + ], + "name": "", + "type": "tuple" + }], + "stateMutability": "view", + "type": "function" + }, + GET_POOL_INFO_ABI: { + "inputs": [], + "name": "getPoolInfo", + "outputs": [{ + "components": [ + { "name": "shareReserves", "type": "uint256" }, + { "name": "shareAdjustment", "type": "int256" }, + { "name": "zombieBaseProceeds", "type": "uint256" }, + { "name": "zombieShareReserves", "type": "uint256" }, + { "name": "bondReserves", "type": "uint256" }, + { "name": "lpTotalSupply", "type": "uint256" }, + { "name": "vaultSharePrice", "type": "uint256" }, + { "name": "longsOutstanding", "type": "uint256" }, + { "name": "longAverageMaturityTime", "type": "uint256" }, + { "name": "shortsOutstanding", "type": "uint256" }, + { "name": "shortAverageMaturityTime", "type": "uint256" }, + { "name": "withdrawalSharesReadyToWithdraw", "type": "uint256" }, + { "name": "withdrawalSharesProceeds", "type": "uint256" }, + { "name": "lpSharePrice", "type": "uint256" }, + { "name": "longExposure", "type": "uint256" } + ], + "name": "", + "type": "tuple" + }], + "stateMutability": "view", + "type": "function" + }, + POSITION_ABI: { + "inputs": [ + { "name": "id", "type": "bytes32" }, + { "name": "user", "type": "address" } + ], + "name": "position", + "outputs": [{ + "components": [ + { "name": "supplyShares", "type": "uint256" }, + { "name": "borrowShares", "type": "uint128" }, + { "name": "collateral", "type": "uint128" } + ], + "name": "", + "type": "tuple" + }], + "stateMutability": "view", + "type": "function" + }, + MARKET_ABI: { + "inputs": [ + { + "internalType": "Id", + "name": "", + "type": "bytes32" + } + ], + "name": "market", + "outputs": [ + { + "internalType": "uint128", + "name": "totalSupplyAssets", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "totalSupplyShares", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "totalBorrowAssets", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "totalBorrowShares", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastUpdate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "fee", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + } +}; \ No newline at end of file diff --git a/src/adaptors/hyperdrive/index.js b/src/adaptors/hyperdrive/index.js new file mode 100644 index 0000000000..2f952717cb --- /dev/null +++ b/src/adaptors/hyperdrive/index.js @@ -0,0 +1,316 @@ +const ethers = require("ethers") +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const providers = require('@defillama/sdk/build/providers.json'); +const { GET_POOL_CONFIG_ABI, GET_POOL_INFO_ABI, POSITION_ABI, MARKET_ABI } = require('./abi'); + +const config = { + ethereum: { registry: '0xbe082293b646cb619a638d29e8eff7cf2f46aa3a', }, + xdai: { registry: '0x666fa9ef9bca174a042c4c306b23ba8ee0c59666', }, + base: { registry: '0x6668310631Ad5a5ac92dC9549353a5BaaE16C666', }, + linea: { registry: '0x6668310631Ad5a5ac92dC9549353a5BaaE16C666', }, +} + +function queryBaseTokenBalance(config, poolContract) { + if (config.baseToken === '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') { + // ETH case + return sdk.api.eth.getBalance({ + target: poolContract.address, + chain: config.chain + }).then(result => result.output); + } else if (config.kind.toLowerCase().includes('lp')) { + // LP token case + return sdk.api.abi.call({ + target: poolContract.address, + chain: config.chain, + abi: 'function gauge() view returns (address)', + }).then(gaugeResult => { + const gauge_contract_address = gaugeResult.output; + return sdk.api.erc20.balanceOf({ + target: gauge_contract_address, + owner: poolContract.address, + chain: config.chain + }).then(balanceResult => balanceResult.output); + }); + } else if (config.baseToken !== ethers.constants.AddressZero) { + // Standard ERC20 case + return sdk.api.erc20.balanceOf({ + target: config.baseToken, + owner: poolContract.address, + chain: config.chain + }).then(result => result.output); + } + return '0'; +} + +function encodeMorphoMarketIds(baseToken, collateral, oracle, irm, lltv) { + const packedIds = ethers.utils.defaultAbiCoder.encode( + ['address', 'address', 'address', 'address', 'uint256'], + [baseToken, collateral, oracle, irm, lltv] + ); + return ethers.utils.keccak256(packedIds); +} + +async function calculateMorphoVaultSharesBalance(poolContract, config) { + const vaultContractAddress = ( + await sdk.api.abi.call({ + target: poolContract.address, + abi: 'function vault() view returns (address)', + chain: config.chain + }) + ).output; + + const [collateralToken, oracle, irm, lltv] = await Promise.all([ + sdk.api.abi.call({ + target: poolContract.address, + abi: 'function collateralToken() view returns (address)', + chain: config.chain + }), + sdk.api.abi.call({ + target: poolContract.address, + abi: 'function oracle() view returns (address)', + chain: config.chain + }), + sdk.api.abi.call({ + target: poolContract.address, + abi: 'function irm() view returns (address)', + chain: config.chain + }), + sdk.api.abi.call({ + target: poolContract.address, + abi: 'function lltv() view returns (uint256)', + chain: config.chain + }) + ]); + + const morphoMarketId = encodeMorphoMarketIds(config.baseToken, collateralToken.output, oracle.output, irm.output, lltv.output); + + const position = ( + await sdk.api.abi.call({ + target: vaultContractAddress, + abi: POSITION_ABI, + params: [morphoMarketId, poolContract.address], + chain: config.chain + }) + ).output; + + const market = ( + await sdk.api.abi.call({ + target: vaultContractAddress, + abi: MARKET_ABI, + params: [morphoMarketId], + chain: config.chain + }) + ).output; + + // https://github.com/morpho-org/morpho-blue/blob/a4210e9198bf5e3aa3cde891e035f33dcb31e0de/src/libraries/SharesMathLib.sol#L33 + const vaultSharePrice = (market.totalSupplyAssets + 1) / (market.totalSupplyShares + 1e6) * 1e12; + + return position.supplyShares / 1e6 * vaultSharePrice; +} + +async function calculateVanillaVaultSharesBalance(poolContract, config) { + return (await sdk.api.erc20.balanceOf({ + target: config.vaultSharesToken, + owner: poolContract.address, + chain: config.chain + })).output; +} + +async function queryVaultSharesBalance(poolContract, config, baseTokenBalance) { + if (config.kind === "MorphoBlueHyperdrive") return calculateMorphoVaultSharesBalance(poolContract, config); + if (config.vaultSharesToken !== ethers.constants.AddressZero) return calculateVanillaVaultSharesBalance(poolContract, config); + return baseTokenBalance; // Otherwise, use base token balance as vault shares balance +} + +async function queryPoolHoldings(poolContract, config) { + let baseTokenBalance = await queryBaseTokenBalance(config, poolContract); + return queryVaultSharesBalance(poolContract, config, baseTokenBalance); +} + +async function calculateAPYfromPool(pool) { + // https://github.com/delvtech/hyperdrive/blob/8347e32d566258da44c44984c8b70f06517f6e46/contracts/src/libraries/HyperdriveMath.sol#L78-L173 + const effective_share_reserves = pool.info.shareReserves - pool.info.shareAdjustment; + const ratio = (pool.config.initialVaultSharePrice / 1e18 * effective_share_reserves) / pool.info.bondReserves; + const spot_price = Math.pow(ratio, pool.config.timeStretch / 1e18); + const time_stretch = pool.config.positionDuration / (365 * 24 * 60 * 60); + const APR = (1 - spot_price) / (spot_price * time_stretch); + + // convert APR to APY + // time_stretch is in fractions of a year so we can use it to convert from apr to apy + // compounding happens every time_stretch years, so we use discrete compounding formula + const APY = Math.pow(1 + APR * time_stretch, 1 / time_stretch) - 1; + + return APY; +} + +async function getApy(chain) { + const registry = config[chain].registry; + + try { + // First get the number of instances + const numInstances = ( + await sdk.api.abi.call({ + target: registry, + chain, + abi: 'function getNumberOfInstances() view returns (uint256)', + }) + ).output; + + // Then fetch each instance + const instanceCalls = Array.from({ length: Number(numInstances) }, (_, i) => ({ + target: registry, + params: [i], + })); + + let instances = ( + await sdk.api.abi.multiCall({ + abi: 'function getInstanceAtIndex(uint256) view returns (address)', + calls: instanceCalls, + chain, + }) + ).output.map(o => o.output); + + const poolNames = ( + await sdk.api.abi.multiCall({ + abi: 'function name() view returns (string)', + calls: instances.map(i => ({ target: i })), + chain + }) + ).output.map(o => o.output); + + const poolConfig = ( + await sdk.api.abi.multiCall({ + abi: GET_POOL_CONFIG_ABI, + calls: instances.map(i => ({ target: i })), + chain + }) + ).output.map(o => o.output); + + const poolKinds = ( + await sdk.api.abi.multiCall({ + abi: 'function kind() pure returns (string)', + calls: instances.map(i => ({ target: i })), + chain + }) + ).output.map(o => o.output); + + // First try to check if gauge function exists using a try-catch + const hasGauge = await Promise.all( + instances.map(async (instance) => { + try { + const result = await sdk.api.abi.call({ + target: instance, + chain, + abi: 'function gauge() view returns (address)', + }); + return result.output !== ethers.constants.AddressZero; + } catch (e) { + return false; + } + }) + ); + + // Add chain and kind to each config + poolConfig.forEach((config, index) => { + config.chain = chain; + config.kind = poolKinds[index]; + config.hasGauge = hasGauge[index]; + }); + + // Get token addresses and fetch prices + await Promise.all(poolConfig.map(async config => { + let priceWithBase = false; + let tokenAddress = config.vaultSharesToken === ethers.constants.AddressZero + ? config.baseToken + : config.vaultSharesToken; + try { + let priceKey = `${chain}:${tokenAddress}`; + config.token_contract_address = tokenAddress; + let priceResponse = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`); + let price = priceResponse.data.coins[priceKey]; + // some share tokens (like sGYD) have no price + // so instead we price the base token (like GYD) and multiply by the latest vaultSharePrice in Hyperdrive + if (price === undefined && config.baseToken !== ethers.constants.AddressZero) { + tokenAddress = config.baseToken; + priceKey = `${chain}:${tokenAddress}`; + priceResponse = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`); + price = priceResponse.data.coins[priceKey]; + config.token_contract_address = config.baseToken; + priceWithBase = true; + } + config.token = price; + config.token.priceWithBase = priceWithBase; + config.token.address = tokenAddress; + } catch (error) { + console.error(`Error fetching price for ${priceKey}:`, error); + // Return default token price info + config.token = { price: 0, decimals: 0, symbol: '?', priceWithBase: priceWithBase, address: tokenAddress }; + } + })); + + const poolInfos = ( + await sdk.api.abi.multiCall({ + abi: GET_POOL_INFO_ABI, + calls: instances.map(i => ({ target: i })), + chain + }) + ).output.map(o => o.output); + + const pools = poolNames.map((name, i) => ({ name, config: poolConfig[i], info: poolInfos[i], address: instances[i] })) + + const poolsData = await Promise.allSettled( + pools.map(async (pool) => { + try { + const APY = await calculateAPYfromPool(pool); + + const vaultSharesBalance = await queryPoolHoldings(pool, pool.config); + + let tvlUsd = (vaultSharesBalance / 10 ** pool.config.token.decimals) * pool.config.token.price; + // apply vaultSharePrice from config if priceWithBase is true + if (pool.config.token.priceWithBase) tvlUsd = tvlUsd * pool.info.vaultSharePrice / 1e18; + + const result = { + pool: pool.address, + chain, + project: 'hyperdrive', + symbol: pool.config.token.symbol, + tvlUsd: Number(tvlUsd) || 0, + apyBase: APY * 100, + underlyingTokens: [pool.config.token_contract_address], + url: `https://app.hyperdrive.box/market/${providers[chain].chainId}/${pool.address}`, + poolMeta: `Matures in ${pool.config.positionDuration / (24 * 60 * 60).toFixed(0)} days from position open` + }; + return result; + } catch (error) { + console.error('Error processing pool:', pool.name, error); + return null; + } + }) + ); + + return poolsData + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value); + } catch (error) { + console.error('Error getting APY for chain:', chain, error); + return []; + } +} + +async function apy() { + const pools = await Promise.allSettled( + Object.keys(config).map(async (chain) => getApy(chain)) + ); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter(Boolean); +} + +module.exports = { + apy, +}; diff --git a/src/adaptors/hyperion/index.js b/src/adaptors/hyperion/index.js new file mode 100644 index 0000000000..c317fab1bb --- /dev/null +++ b/src/adaptors/hyperion/index.js @@ -0,0 +1,55 @@ +const utils = require('../utils'); + +const POOL_LIST_URL = 'https://assets.hyperion.xyz/files/pool-list.json'; + +function aprToApy(apr) { + if (apr === undefined || apr === null) { + return 0; + } + return (Math.pow(1 + Number(apr) / 100 / 365, 365) - 1) * 100; +} + +async function apy() { + const liquidityPools = (await utils.getData(POOL_LIST_URL))?.data; + if (!liquidityPools) { + return []; + } + + const result = []; + for (const pool of liquidityPools) { + if (pool.pool.isPublic === false) { + continue; + } + + const poolId = pool.pool.poolId; + const feeAPR = pool.feeAPR; + const farmAPR = pool.farmAPR; + const tvl = pool.tvlUSD; + const tokenA = pool.pool.token1; + const tokenB = pool.pool.token2; + const symbolA = pool.pool.token1Info.symbol; + const symbolB = pool.pool.token2Info.symbol; + + result.push({ + pool: `${poolId}-aptos`, + chain: utils.formatChain('aptos'), + project: 'hyperion', + symbol: `${symbolA}-${symbolB}`, + tvlUsd: Number(tvl), + apyBase: aprToApy(feeAPR), + apyReward: aprToApy(farmAPR), + rewardTokens: pool.pool.farm.map((item) => item.rewardFa), + underlyingTokens: [tokenA, tokenB], + url: `https://hyperion.xyz/pool/${poolId}`, + poolMeta: `${Number(pool.pool.feeRate) / 10000}%`, + }); + } + + return result; +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://hyperion.xyz/pools', +}; diff --git a/src/adaptors/hyperlend-pooled/index.js b/src/adaptors/hyperlend-pooled/index.js new file mode 100644 index 0000000000..e0c9a9a5e2 --- /dev/null +++ b/src/adaptors/hyperlend-pooled/index.js @@ -0,0 +1,142 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); + +const protocolDataProvider = ['0x5481bf8d3946E6A3168640c1D7523eB59F055a29']; + +const getApy = async (market) => { + const chain = 'hyperliquid'; + + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider[0], + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider[0], + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider[0], + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider[0], + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + + const url = `https://app.hyperlend.finance/markets/${pool.tokenAddress}`; + + return { + pool: `${aTokens[i].tokenAddress}-${market}`.toLowerCase(), + chain, + project: 'hyperlend-pooled', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd: null, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + url, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + mintedCoin: null, + poolMeta: null, + }; + }) + .filter((i) => Boolean(i)); +}; + +const apy = async () => { + const pools = await Promise.allSettled( + Object.keys(protocolDataProvider).map(async (market) => getApy(market)) + ); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/hyperlend-pooled/poolAbi.js b/src/adaptors/hyperlend-pooled/poolAbi.js new file mode 100644 index 0000000000..bba1c9dc38 --- /dev/null +++ b/src/adaptors/hyperlend-pooled/poolAbi.js @@ -0,0 +1,242 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/hyperwave/Accountant.json b/src/adaptors/hyperwave/Accountant.json new file mode 100644 index 0000000000..b0ec287e63 --- /dev/null +++ b/src/adaptors/hyperwave/Accountant.json @@ -0,0 +1,667 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + }, + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + }, + { + "internalType": "uint96", + "name": "startingExchangeRate", + "type": "uint96" + }, + { + "internalType": "address", + "name": "_base", + "type": "address" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__LowerBoundTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__ManagementFeeTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__OnlyCallableByBoringVault", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__Paused", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__UpdateDelayTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__UpperBoundTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__ZeroFeesOwed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "oldDelay", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newDelay", + "type": "uint32" + } + ], + "name": "DelayInSecondsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint96", + "name": "oldRate", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "newRate", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "currentTime", + "type": "uint64" + } + ], + "name": "ExchangeRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FeesClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldBound", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newBound", + "type": "uint16" + } + ], + "name": "LowerBoundUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldFee", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newFee", + "type": "uint16" + } + ], + "name": "ManagementFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPayout", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPayout", + "type": "address" + } + ], + "name": "PayoutAddressUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isPegged", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateProvider", + "type": "address" + } + ], + "name": "RateProviderUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldBound", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newBound", + "type": "uint16" + } + ], + "name": "UpperBoundUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "accountantState", + "outputs": [ + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + }, + { + "internalType": "uint128", + "name": "feesOwedInBase", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "totalSharesLastUpdate", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "exchangeRate", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "lastUpdateTimestamp", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "isPaused", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "feeAsset", + "type": "address" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRate", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "quote", + "type": "address" + } + ], + "name": "getRateInQuote", + "outputs": [ + { + "internalType": "uint256", + "name": "rateInQuote", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "quote", + "type": "address" + } + ], + "name": "getRateInQuoteSafe", + "outputs": [ + { + "internalType": "uint256", + "name": "rateInQuote", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRateSafe", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "rateProviderData", + "outputs": [ + { + "internalType": "bool", + "name": "isPeggedToBase", + "type": "bool" + }, + { + "internalType": "contract IRateProvider", + "name": "rateProvider", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "isPeggedToBase", + "type": "bool" + }, + { + "internalType": "address", + "name": "rateProvider", + "type": "address" + } + ], + "name": "setRateProviderData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + } + ], + "name": "updateDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "newExchangeRate", + "type": "uint96" + } + ], + "name": "updateExchangeRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + } + ], + "name": "updateLower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "name": "updateManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + } + ], + "name": "updatePayoutAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + } + ], + "name": "updateUpper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract BoringVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/hyperwave/Vault.json b/src/adaptors/hyperwave/Vault.json new file mode 100644 index 0000000000..18b0f9b217 --- /dev/null +++ b/src/adaptors/hyperwave/Vault.json @@ -0,0 +1,806 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Enter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Exit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "enter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "hook", + "outputs": [ + { + "internalType": "contract BeforeTransferHook", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_hook", + "type": "address" + } + ], + "name": "setBeforeTransferHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/hyperwave/index.ts b/src/adaptors/hyperwave/index.ts new file mode 100644 index 0000000000..724def44bc --- /dev/null +++ b/src/adaptors/hyperwave/index.ts @@ -0,0 +1,282 @@ +/** + * @fileoverview Hyperwave Finance vault adapter for calculating TVL and APR metrics + * This module interfaces with Hyperwave vault contracts (hwHLP and hwHYPE) and their + * accountants to fetch financial metrics across Ethereum and Hyperliquid chains. + * + * @author maybeYonas + * @version 1.1.1 + */ + +const utils = require("../utils"); +const ethers = require("ethers"); +const axios = require("axios"); +const sdk = require("@defillama/sdk"); +const Vault = require("./Vault.json"); +const Accountant = require("./Accountant.json"); + +const hwHLP = "0x9FD7466f987Fd4C45a5BBDe22ED8aba5BC8D72d1"; +const hwHYPE = "0x4DE03cA1F02591B717495cfA19913aD56a2f5858"; +const hwUSD = "0xa2f8Da4a55898B6c947Fa392eF8d6BFd87A4Ff77" + +const hwHLP_ACCOUNTANT = "0x78E3Ac5Bf48dcAF1835e7F9861542c0D43D0B03E"; +const hwHYPE_ACCOUNTANT = "0xCf9be8BF79ad26fdD7aA73f3dd5bA73eCDee2a32"; +const hwUSD_ACCOUNTANT = "0xa77F32BaDEeA2d2B7De78680C3A6d8B88C46055D"; + +const hwHLP_UNDERLYING_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC +const hwHLP_UNDERLYING_USDT0 = "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"; +const hwHYPE_UNDERLYING_WHYPE = "0x5555555555555555555555555555555555555555"; +const hwUSD_UNDERLYING_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC +const hwUSD_UNDERLYING_USDT0 = "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"; +const hwUSD_UNDERLYING_USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on base + +interface AssetConfig { + symbol: string; + boringVault: string; + accountant: string; + underlying: string; + decimals: number; + chain: string; +} + +const config: AssetConfig[] = [ + { + symbol: "hwHLP", + boringVault: hwHLP, + accountant: hwHLP_ACCOUNTANT, + underlying: hwHLP_UNDERLYING_USDC, + decimals: 6, + chain: "ethereum", + }, + { + symbol: "hwHLP", + boringVault: hwHLP, + accountant: hwHLP_ACCOUNTANT, + underlying: hwHLP_UNDERLYING_USDT0, + decimals: 6, + chain: "hyperliquid", + }, + { + symbol: "hwHYPE", + boringVault: hwHYPE, + accountant: hwHYPE_ACCOUNTANT, + underlying: hwHYPE_UNDERLYING_WHYPE, + decimals: 18, + chain: "hyperliquid", + }, + { + symbol: "hwUSD", + boringVault: hwUSD, + accountant: hwUSD_ACCOUNTANT, + underlying: hwUSD_UNDERLYING_USDT0, + decimals: 6, + chain: "hyperliquid", + }, + { + symbol: "hwUSD", + boringVault: hwUSD, + accountant: hwUSD_ACCOUNTANT, + underlying: hwUSD_UNDERLYING_USDC, + decimals: 6, + chain: "ethereum", + }, + { + symbol: "hwUSD", + boringVault: hwUSD, + accountant: hwUSD_ACCOUNTANT, + underlying: hwUSD_UNDERLYING_USDC_BASE, + decimals: 6, + chain: "base", + }, +]; + +/** + * Calculate TVL (Total Value Locked) for a vault + * + * Fetches the total supply of vault tokens, current exchange rate from the accountant, + * and underlying asset price to compute the total USD value locked in the vault. + * Supports both hwHLP and hwHYPE vaults across different chains. + * + * @async + * @function calculateTVL + * @param {AssetConfig} config - Configuration object containing vault details + * @returns {Promise} Object containing TVL metrics + * @returns {number} returns.tvlUsd - Total Value Locked in USD + * @returns {string} returns.currentRate - Current exchange rate from accountant contract + * + * @throws {Error} Throws error if contract calls fail or price data is unavailable + * + * @example + * const tvlData = await calculateTVL(configObject); + * console.log(`TVL: $${tvlData.tvlUsd.toFixed(2)}`); + */ +const calculateTVL = async (config: AssetConfig) => { + const { chain, underlying, accountant, boringVault, decimals } = config; + const totalSupplyCall = sdk.api.abi.call({ + target: boringVault, + abi: Vault.find((m) => m.name === "totalSupply"), + chain: chain, + }); + + const priceKey = `${chain}:${underlying}`; + const underlyingPriceCall = axios.get( + `https://coins.llama.fi/prices/current/${priceKey}?searchWidth=24h`, + ); + + const currentRateCall = sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === "getRate"), + chain: chain, + }); + + const [totalSupplyResponse, underlyingPriceResponse, currentRateResponse] = + await Promise.all([totalSupplyCall, underlyingPriceCall, currentRateCall]); + + const scalingFactor = 10 ** decimals; + const totalSupply = totalSupplyResponse.output / scalingFactor; + const underlyingPrice = underlyingPriceResponse.data.coins[priceKey].price; + const currentRate = currentRateResponse.output; + + const tvlUsd = totalSupply * (currentRate / scalingFactor) * underlyingPrice; + + return { + tvlUsd, + currentRate, + }; +}; + +/** + * Calculate APR (Annual Percentage Rate) for 1 day and 7 days + * + * Computes yield rates by comparing the current exchange rate with historical rates + * from 1 day and 7 days ago. Uses block height data to fetch historical contract state. + * Supports both hwHLP and hwHYPE vaults with appropriate decimal scaling. + * + * @async + * @function calculateAPR + * @param {AssetConfig} config - Configuration object containing vault and chain details + * @param {string|number} currentRate - Current exchange rate from the accountant contract + * @returns {Promise} Object containing APR calculations + * @returns {number} returns.apr1d - 1-day APR as a percentage + * @returns {number} returns.apr7d - 7-day APR as a percentage + * + * @throws {Error} Throws error if historical block data or contract calls fail + * + * @example + * const aprData = await calculateAPR(configObject, currentRate); + * console.log(`1d APR: ${aprData.apr1d.toFixed(2)}%`); + * console.log(`7d APR: ${aprData.apr7d.toFixed(2)}%`); + */ +const calculateAPR = async (config: AssetConfig, currentRate: number) => { + const { chain, accountant, decimals } = config; + const scalingFactor = 10 ** decimals; + + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + + const block1dayAgoCall = axios.get( + `https://coins.llama.fi/block/${chain}/${timestamp1dayAgo}`, + ); + const block7dayAgoCall = axios.get( + `https://coins.llama.fi/block/${chain}/${timestamp7dayAgo}`, + ); + + const [block1dayAgoResponse, block7dayAgoResponse] = await Promise.all([ + block1dayAgoCall, + block7dayAgoCall, + ]); + + const block1dayAgo = block1dayAgoResponse.data.height; + const block7dayAgo = block7dayAgoResponse.data.height; + + const [rate1dayAgo, rate7dayAgo] = await Promise.all([ + sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === "getRate"), + block: block1dayAgo, + chain: chain, + // provider + }), + sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === "getRate"), + block: block7dayAgo, + chain: chain, + }), + ]); + + // console.log("Rates:", { + // chain, + // currentRate, + // rate1dayAgo: rate1dayAgo.output, + // rate7dayAgo: rate7dayAgo.output, + // block1dayAgo, + // block7dayAgo + // }); + + const apr1d = + ((currentRate - rate1dayAgo.output) / scalingFactor) * 365 * 100; + const apr7d = + ((currentRate - rate7dayAgo.output) / scalingFactor / 7) * 365 * 100; + + return { + apr1d, + apr7d, + }; +}; + +/** + * Main function that orchestrates TVL and APR calculations + * + * Processes all configured vaults (hwHLP and hwHYPE) to calculate TVL and APR metrics + * across Ethereum and Hyperliquid chains. Returns standardized pool data for each + * vault configuration that can be consumed by DeFi dashboards. + * + * @async + * @function apy + * @returns {Promise>} Array of pool objects with metrics for each vault configuration + * @returns {string} returns[].pool - Unique pool identifier (chain_contractAddress) + * @returns {string} returns[].project - Project name ('hyperwave') + * @returns {string} returns[].chain - Formatted chain name + * @returns {string} returns[].symbol - Token symbol ('hwHLP' or 'hwHYPE') + * @returns {number} returns[].tvlUsd - Total Value Locked in USD + * @returns {number} returns[].apyBase - 1-day APR as base yield percentage + * @returns {number} returns[].apyBase7d - 7-day APR as base yield percentage + * @returns {Array} returns[].underlyingTokens - Array of underlying token addresses + * + * @throws {Error} Throws error if TVL or APR calculations fail for any configured vault + * + * @example + * const poolData = await apy(); + * poolData.forEach(pool => { + * console.log(`${pool.symbol} ${pool.chain}: TVL $${pool.tvlUsd.toFixed(2)}, APR ${pool.apyBase.toFixed(2)}%`); + * }); + */ +const apy = async () => { + const out = await Promise.all( + config.map(async (chainConfig) => { + const { tvlUsd, currentRate } = await calculateTVL(chainConfig); + // using ethereum for APR as most HyperEVM RPCs don't have archival state + // const { apr1d, apr7d } = await calculateAPR(currentRate, scalingFactor); + const { apr1d, apr7d } = await calculateAPR(chainConfig, currentRate); + return { + pool: `${chainConfig.chain}_${chainConfig.boringVault}`, + project: "hyperwave", + chain: utils.formatChain(chainConfig.chain), + symbol: chainConfig.symbol, + tvlUsd: tvlUsd, + apyBase: apr1d, + apyBase7d: apr7d, + underlyingTokens: [chainConfig.underlying], + }; + }), + ); + + return out; +}; + +module.exports = { + apy, + timetravel: false, + url: "https://app.hyperwavefi.xyz/assets/hwhlp", +}; diff --git a/src/adaptors/hypha/index.js b/src/adaptors/hypha/index.js new file mode 100644 index 0000000000..0550114b3d --- /dev/null +++ b/src/adaptors/hypha/index.js @@ -0,0 +1,90 @@ +const utils = require('../utils'); +const axios = require('axios'); +const { ethers } = require('ethers'); + +const provider = new ethers.providers.JsonRpcProvider( + 'https://api.avax.network/ext/bc/C/rpc' +); +const GGAVAX_CONTRACT = '0xA25EaF2906FA1a3a13EdAc9B9657108Af7B703e3'; + +const totalAssetsAbi = [ + { + inputs: [], + name: 'totalAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +async function fetchTotalAssets() { + try { + const contract = new ethers.Contract( + GGAVAX_CONTRACT, + totalAssetsAbi, + provider + ); + const totalAssets = await contract.totalAssets(); + return ethers.utils.formatUnits(totalAssets, 18); + } catch (error) { + console.error('Error in fetching total assets:', error); + } +} + +const avaxPrice = async () => { + try { + const response = await axios.get( + 'https://api.coingecko.com/api/v3/simple/price?ids=avalanche-2&vs_currencies=usd' + ); + return response.data['avalanche-2'].usd; + } catch (error) { + console.error('Error fetching price data', error); + return null; + } +}; + +const fetchData = async () => { + const apiUrl = 'https://api.gogopool.com/metrics'; + const avaxUSD = await avaxPrice(); + const avaxLstSide = await fetchTotalAssets(); + + const data = await utils.getData(apiUrl); + + const tvlUsd = parseFloat(avaxLstSide) * avaxUSD; + + return { + apyBase: Number(data.ggavax_apy), + tvlUsd: tvlUsd, + }; +}; + +const topLvl = async () => { + const { apyBase, tvlUsd } = await fetchData(); + return { + pool: '0xA25EaF2906FA1a3a13EdAc9B9657108Af7B703e3', + chain: 'Avalanche', + project: 'hypha', + symbol: 'ggAVAX', + tvlUsd: tvlUsd, + apyBase: apyBase, + apyReward: 0, + rewardTokens: [], + underlyingTokens: ['0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'], + }; +}; + +const main = async () => { + return [await topLvl()]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.gogopool.com', +}; diff --git a/src/adaptors/iaero-protocol/index.js b/src/adaptors/iaero-protocol/index.js new file mode 100644 index 0000000000..46e89059bc --- /dev/null +++ b/src/adaptors/iaero-protocol/index.js @@ -0,0 +1,62 @@ +const axios = require('axios'); + +const DATA_URL = 'https://raw.githubusercontent.com/iaeroProtocol/ChainProcessingBot/main/data/estimated_rewards_usd.json'; + +const AERO_TOKEN = '0x940181a94A35A4569E4529A3CDfB74e38FD98631'; +const VAULT_ADDRESS = '0x180DAB53968e599Dd43CF431E27CB01AA5C37909'; + +const main = async () => { + // Use axios directly to avoid any caching in utils.getData + const response = await axios.get(DATA_URL, { + headers: { + 'Cache-Control': 'no-cache', + 'Accept': 'application/json' + } + }); + + const data = response.data; + + // Validate response + if (!data || typeof data !== 'object') { + throw new Error(`Invalid data response: ${JSON.stringify(data)}`); + } + + // Parse TVL - string in 1e18 precision + const tvlUsdRaw = data.tvlUSD_1e18; + if (!tvlUsdRaw) { + throw new Error(`Missing tvlUSD_1e18. Fields: ${Object.keys(data).join(', ')}`); + } + const tvlUsd = Number(tvlUsdRaw) / 1e18; + + // Parse APY - string like "42.5" + const apyRaw = data.apyPct; + if (apyRaw === undefined || apyRaw === null) { + throw new Error(`Missing apyPct. Fields: ${Object.keys(data).join(', ')}`); + } + const apy = Number(apyRaw); + + // Validate + if (!Number.isFinite(tvlUsd) || tvlUsd < 0) { + throw new Error(`Invalid tvlUsd: ${tvlUsd}`); + } + if (!Number.isFinite(apy) || apy < 0) { + throw new Error(`Invalid apy: ${apy}`); + } + + return [{ + pool: VAULT_ADDRESS, + chain: 'Base', + project: 'iaero-protocol', + symbol: 'iAERO', + tvlUsd, + apyBase: apy, + underlyingTokens: [AERO_TOKEN], + url: 'https://iaero.finance' + }]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://iaero.finance', +}; \ No newline at end of file diff --git a/src/adaptors/icpex/index.js b/src/adaptors/icpex/index.js new file mode 100644 index 0000000000..d47def3b70 --- /dev/null +++ b/src/adaptors/icpex/index.js @@ -0,0 +1,14 @@ +const utils = require('../utils'); + +const API_URL = 'https://2jbbf-vqaaa-aaaam-ab5fa-cai.raw.icp0.io/pool-list'; + +const getApy = async () => { + const pools = await utils.getData(API_URL); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://icpex.org', +}; diff --git a/src/adaptors/icpswap/index.js b/src/adaptors/icpswap/index.js new file mode 100644 index 0000000000..d868df0b3b --- /dev/null +++ b/src/adaptors/icpswap/index.js @@ -0,0 +1,47 @@ +const utils = require('../utils'); + +const API_URL = 'https://uvevg-iyaaa-aaaak-ac27q-cai.raw.ic0.app/tickers'; + +const TOKEN_LIST_URL = + 'https://uvevg-iyaaa-aaaak-ac27q-cai.raw.ic0.app/token-list'; + +const getApy = async () => { + const tickers = await utils.getData(API_URL); + const allTokens = await utils.getData(TOKEN_LIST_URL); + + const pools = tickers + .filter((ticker) => { + return ( + allTokens.includes(ticker.base_id) && + allTokens.includes(ticker.target_id) + ); + }) + .map((ticker) => ({ + pool: ticker.ticker_id, + chain: utils.formatChain('ICP'), + // Should be the same as adaptor slug + project: 'icpswap', + symbol: ticker.ticker_name, + tvlUsd: Number(ticker.liquidity_in_usd), + apyBase: + // if liquidity_in_usd is zero, the apy result is not finite + Number(ticker.liquidity_in_usd) === 0 + ? 0 + : ((Number(ticker.volume_usd_24H) * 3) / + 1000 / + Number(ticker.liquidity_in_usd)) * + 100 * + 360 * + 0.8, + underlyingTokens: [ticker.target_id, ticker.base_id], + poolMeta: 'V3 market', + })); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.icpswap.com', +}; diff --git a/src/adaptors/idle-finance/index.js b/src/adaptors/idle-finance/index.js deleted file mode 100644 index 0e5c28316f..0000000000 --- a/src/adaptors/idle-finance/index.js +++ /dev/null @@ -1,55 +0,0 @@ -const utils = require('../utils'); -const mainnetPoolsUrl = - 'https://api.idle.finance/pools?api-key=bPrtC2bfnAvapyXLgdvzVzW8u8igKv6E'; -const polygonPoolsUrl = - 'https://api-polygon.idle.finance/pools?api-key=bPrtC2bfnAvapyXLgdvzVzW8u8igKv6E'; -const chains = { - eth: 'ethereum', - matic: 'polygon', -}; - -async function apy() { - const mainnetPoolsResponse = await utils.getData(mainnetPoolsUrl); - const polygonPoolsResponse = await utils.getData(polygonPoolsUrl); - - const poolsResponse = { - matic: polygonPoolsResponse, - eth: mainnetPoolsResponse, - }; - - let allVaults = []; - - for (let chain of Object.keys(chains)) { - const chainPools = Object.values(poolsResponse[chain]); - - const pools = chainPools.map((v) => { - var poolNameParts = v.poolName.split(' '); - let poolName = ( - utils.formatSymbol(poolNameParts[0].toUpperCase()) + - ' ' + - poolNameParts.slice(1, poolNameParts.length).join(' ') - ).trim(); - return { - pool: v.address, - apy: Number(v.apr), - symbol: poolName.replace('-LP', ' LP'), - tvlUsd: Number(v.tvl), - project: 'idle-finance', - chain: utils.formatChain(chains[chain]), - }; - }); - - allVaults = [...allVaults, ...pools]; - } - - return allVaults; -} - -const main = async () => { - return await apy(); -}; - -module.exports = { - apy: main, - timetravel: false, -}; diff --git a/src/adaptors/idle/index.js b/src/adaptors/idle/index.js new file mode 100644 index 0000000000..1b7f6aa8fa --- /dev/null +++ b/src/adaptors/idle/index.js @@ -0,0 +1,61 @@ +const utils = require('../utils'); +const superagent = require('superagent'); + +const chains = { + ethereum: 'https://api.idle.finance/pools', + polygon: 'https://api-polygon.idle.finance/pools', + optimism: 'https://api-optimism.idle.finance/pools', + polygon_zkevm: 'https://api-zkevm.idle.finance/pools', +}; + +const AUTH_TOKEN_ENCODED = + 'ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SmpiR2xsYm5SSlpDSTZJa0Z3Y0RZaUxDSnBZWFFpT2pFMk56QXlNemMxTWpkOS5rbnNtekVOSm40Yk5Ea0ZCM3h2eWZyaDBwVlFLTHY0NW9JanJQNHdRTU5N'; + +async function getDataWithAuth(url, token) { + const data = await superagent + .get(url) + .set('Authorization', `Bearer ${token}`); + return data?.body; +} + +const getApy = async () => { + const AUTH_TOKEN_DECODED = atob(AUTH_TOKEN_ENCODED); + const data = await Promise.allSettled( + Object.entries(chains).map(async (chain) => { + const data = await getDataWithAuth(chain[1], AUTH_TOKEN_DECODED); + return data.map((v) => { + let protocolName = v.protocolName; + if (v.borrowerName) { + protocolName += ` ${v.borrowerName}`; + } + const apyReward = v.apyReward || Number(0); + const rewardTokens = v.rewardTokens || []; + return { + pool: v.address, + apyBase: Number(v.apr), + apyReward, + rewardTokens, + symbol: v.tokenName, + poolMeta: v.poolName.includes('Best') + ? v.poolName.split(' ').slice(1).join(' ') + : `${protocolName} ${v.strategy}`, + tvlUsd: Number(v.tvl), + project: 'idle', + chain: utils.formatChain(chain[0]), + underlyingTokens: [v.underlyingAddress], + }; + }); + }) + ); + + return data + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat(); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.idle.finance/', +}; diff --git a/src/adaptors/illuminate/abis/ERC5095.json b/src/adaptors/illuminate/abis/ERC5095.json new file mode 100644 index 0000000000..7f3db147c4 --- /dev/null +++ b/src/adaptors/illuminate/abis/ERC5095.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"uint256","name":"_maturity","type":"uint256"},{"internalType":"address","name":"_redeemer","type":"address"},{"internalType":"address","name":"_lender","type":"address"},{"internalType":"address","name":"_marketplace","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"Exception","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"approveMarketPlace","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"},{"internalType":"address","name":"s","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"f","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authBurn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"convertToUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketplace","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p","type":"address"}],"name":"setPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/illuminate/abis/Pool.json b/src/adaptors/illuminate/abis/Pool.json new file mode 100644 index 0000000000..3d4ccda62b --- /dev/null +++ b/src/adaptors/illuminate/abis/Pool.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"sharesToken_","type":"address"},{"internalType":"address","name":"fyToken_","type":"address"},{"internalType":"int128","name":"ts_","type":"int128"},{"internalType":"uint16","name":"g1Fee_","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AfterMaturity","type":"error"},{"inputs":[],"name":"FYTokenCachedBadState","type":"error"},{"inputs":[],"name":"Initialized","type":"error"},{"inputs":[{"internalType":"uint16","name":"proposedFee","type":"uint16"}],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"MaturityOverflow","type":"error"},{"inputs":[],"name":"MuCannotBeZero","type":"error"},{"inputs":[{"internalType":"uint128","name":"newFYTokenBalance","type":"uint128"},{"internalType":"uint128","name":"newSharesBalanceTimesMu","type":"uint128"}],"name":"NegativeInterestRatesNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"baseAvailable","type":"uint256"},{"internalType":"uint256","name":"baseNeeded","type":"uint256"}],"name":"NotEnoughBaseIn","type":"error"},{"inputs":[{"internalType":"uint256","name":"fYTokensAvailable","type":"uint256"},{"internalType":"uint256","name":"fYTokensNeeded","type":"uint256"}],"name":"NotEnoughFYTokenIn","type":"error"},{"inputs":[],"name":"NotInitialized","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[{"internalType":"uint256","name":"newRatio","type":"uint256"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"SlippageDuringBurn","type":"error"},{"inputs":[{"internalType":"uint256","name":"newRatio","type":"uint256"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"SlippageDuringMint","type":"error"},{"inputs":[{"internalType":"uint128","name":"fyTokenOut","type":"uint128"},{"internalType":"uint128","name":"min","type":"uint128"}],"name":"SlippageDuringSellBase","type":"error"},{"inputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"},{"internalType":"uint128","name":"min","type":"uint128"}],"name":"SlippageDuringSellFYToken","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"g1Fee","type":"uint16"}],"name":"FeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"maturity","type":"uint32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"fyTokenTo","type":"address"},{"indexed":false,"internalType":"int256","name":"base","type":"int256"},{"indexed":false,"internalType":"int256","name":"fyTokens","type":"int256"},{"indexed":false,"internalType":"int256","name":"poolTokens","type":"int256"}],"name":"Liquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"PausePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint112","name":"baseCached","type":"uint112"},{"indexed":false,"internalType":"uint112","name":"fyTokenCached","type":"uint112"},{"indexed":false,"internalType":"uint256","name":"cumulativeBalancesRatio","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"maturity","type":"uint32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"int256","name":"base","type":"int256"},{"indexed":false,"internalType":"int256","name":"fyTokens","type":"int256"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"gg","type":"event"},{"anonymous":false,"inputs":[],"name":"gm","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"base","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseToken","outputs":[{"internalType":"contract IERC20Like","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"baseTo","type":"address"},{"internalType":"address","name":"fyTokenTo","type":"address"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"burn","outputs":[{"internalType":"uint256","name":"lpTokensBurned","type":"uint256"},{"internalType":"uint256","name":"baseOut","type":"uint256"},{"internalType":"uint256","name":"fyTokenOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"burnForBase","outputs":[{"internalType":"uint256","name":"lpTokensBurned","type":"uint256"},{"internalType":"uint256","name":"baseOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint128","name":"baseOut","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"name":"buyBase","outputs":[{"internalType":"uint128","name":"fyTokenIn","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"}],"name":"buyBasePreview","outputs":[{"internalType":"uint128","name":"fyTokenIn","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint128","name":"fyTokenOut","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"name":"buyFYToken","outputs":[{"internalType":"uint128","name":"baseIn","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"fyTokenOut","type":"uint128"}],"name":"buyFYTokenPreview","outputs":[{"internalType":"uint128","name":"baseIn","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cumulativeRatioLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCumulativeRatio","outputs":[{"internalType":"uint256","name":"currentCumulativeRatio_","type":"uint256"},{"internalType":"uint256","name":"blockTimestampCurrent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fyToken","outputs":[{"internalType":"contract IMaturingToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"g1","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"g1Fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"g2","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseBalance","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getC","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCache","outputs":[{"internalType":"uint104","name":"","type":"uint104"},{"internalType":"uint104","name":"","type":"uint104"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSharePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFYTokenBalance","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharesBalance","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"init","outputs":[{"internalType":"uint256","name":"baseIn","type":"uint256"},{"internalType":"uint256","name":"fyTokenIn","type":"uint256"},{"internalType":"uint256","name":"lpTokensMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"invariant","outputs":[{"internalType":"uint128","name":"result","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBaseIn","outputs":[{"internalType":"uint128","name":"baseIn","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBaseOut","outputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFYTokenIn","outputs":[{"internalType":"uint128","name":"fyTokenIn","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFYTokenOut","outputs":[{"internalType":"uint128","name":"fyTokenOut","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"remainder","type":"address"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"baseIn","type":"uint256"},{"internalType":"uint256","name":"fyTokenIn","type":"uint256"},{"internalType":"uint256","name":"lpTokensMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"remainder","type":"address"},{"internalType":"uint256","name":"fyTokenToBuy","type":"uint256"},{"internalType":"uint256","name":"minRatio","type":"uint256"},{"internalType":"uint256","name":"maxRatio","type":"uint256"}],"name":"mintWithBase","outputs":[{"internalType":"uint256","name":"baseIn","type":"uint256"},{"internalType":"uint256","name":"fyTokenIn","type":"uint256"},{"internalType":"uint256","name":"lpTokensMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mu","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"b","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"retrieveBase","outputs":[{"internalType":"uint128","name":"retrieved","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"retrieveFYToken","outputs":[{"internalType":"uint128","name":"retrieved","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"retrieveShares","outputs":[{"internalType":"uint128","name":"retrieved","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scaleFactor","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint128","name":"min","type":"uint128"}],"name":"sellBase","outputs":[{"internalType":"uint128","name":"fyTokenOut","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"baseIn","type":"uint128"}],"name":"sellBasePreview","outputs":[{"internalType":"uint128","name":"fyTokenOut","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint128","name":"min","type":"uint128"}],"name":"sellFYToken","outputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"fyTokenIn","type":"uint128"}],"name":"sellFYTokenPreview","outputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"fyTokenIn","type":"uint128"},{"internalType":"uint128","name":"shares","type":"uint128"},{"internalType":"uint128","name":"fyTokens","type":"uint128"}],"name":"sellFYTokenPreview","outputs":[{"internalType":"uint128","name":"baseOut","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"g1Fee_","type":"uint16"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharesToken","outputs":[{"internalType":"contract IERC20Like","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ts","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"unwrap","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"unwrapPreview","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"wrap","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"wrapPreview","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/illuminate/index.js b/src/adaptors/illuminate/index.js new file mode 100644 index 0000000000..39cc06d494 --- /dev/null +++ b/src/adaptors/illuminate/index.js @@ -0,0 +1,175 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const marketPlace = '0xcd1D02fDa51CD24123e857CE94e4356D5C073b3f'; +const poolAbi = require('./abis/Pool.json'); +const erc5095 = require('./abis/ERC5095.json'); +const { secondsInYear } = require('date-fns'); + +// get symbol of a principal token +async function getSymbol(pt) { + return ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'symbol'), + chain: 'ethereum', + }) + ).output; +} + +// get the tvl of a pt +async function getTvlPt(pt, pool) { + const decimals = ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'decimals'), + chain: 'ethereum', + }) + ).output; + const one = 10 ** decimals; + const totalSupply = ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'totalSupply'), + chain: 'ethereum', + }) + ).output; + const fyTokenValue = ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'sellFYTokenPreview'), + chain: 'ethereum', + params: [one], + }) + ).output; + + return (totalSupply * fyTokenValue) / one / one; +} + +// get the tvl in the pool +async function getTvlPool(pt, pool) { + const decimals = ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'decimals'), + chain: 'ethereum', + }) + ).output; + const one = 10 ** decimals; + // Start by getting the value of fyTokens in the pool + const fyTokenValue = ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'sellFYTokenPreview'), + chain: 'ethereum', + params: [one], + }) + ).output; + const virtualFyTokenBalance = ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'getFYTokenBalance'), + chain: 'ethereum', + }) + ).output; + const poolTotalSupply = ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'totalSupply'), + chain: 'ethereum', + }) + ).output; + const fyTokenTvl = + ((virtualFyTokenBalance - poolTotalSupply) * fyTokenValue) / one / one; + // Get the amount of underlying held by the pool (value of shares token) + const baseTokenTvl = + ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'getBaseBalance'), + chain: 'ethereum', + }) + ).output / one; + return baseTokenTvl + fyTokenTvl; +} + +// get the base (fixed) apy of a pool +async function getBaseApy(pt, pool) { + const decimals = ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'decimals'), + chain: 'ethereum', + }) + ).output; + + const one = 10 ** decimals; + + const fyTokenValue = ( + await sdk.api.abi.call({ + target: pool, + abi: poolAbi.find((i) => i.name === 'sellFYTokenPreview'), + chain: 'ethereum', + params: [one], + }) + ).output; + const rate = one / fyTokenValue - 1; + + // calculate fixed rate over the course of a year + const maturity = ( + await sdk.api.abi.call({ + target: pt, + abi: erc5095.find((i) => i.name === 'maturity'), + chain: 'ethereum', + }) + ).output; + const timestamp = Math.floor(Date.now() / 1000); + const secondsToMaturity = maturity - timestamp; + const apy = (rate * secondsInYear) / secondsToMaturity; + + return apy * 100; +} + +const main = async () => { + let data = ( + await axios.get('https://illumigate-main.swivel.exchange/v1/pools') + )['data']; + data = await Promise.all( + data.map(async (p) => { + return [ + { + pool: p.address, + chain: 'ethereum', + project: 'illuminate', + symbol: await getSymbol(p.address), + tvlUsd: await getTvlPool(p.pt, p.address), + apyBase: p.apy * 100, + apyReward: 0, + rewardTokens: [], + underlyingTokens: [p.underlying], + poolMeta: '', + }, + { + pool: p.pt, + chain: 'ethereum', + project: 'illuminate', + symbol: await getSymbol(p.pt), + tvlUsd: await getTvlPt(p.pt, p.address), + apyBase: await getBaseApy(p.pt, p.address), + apyReward: 0, + rewardTokens: [], + underlyingTokens: [p.underlying], + poolMeta: '', + }, + ]; + }) + ); + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://illumigate-main.swivel.exchange/v1/pools', +}; diff --git a/src/adaptors/impermax-v2/abi.js b/src/adaptors/impermax-v2/abi.js new file mode 100644 index 0000000000..e03a5d6a1a --- /dev/null +++ b/src/adaptors/impermax-v2/abi.js @@ -0,0 +1,220 @@ +module.exports = { + allLendingPools: { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'allLendingPools', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + allLendingPoolsLength: { + constant: true, + inputs: [], + name: 'allLendingPoolsLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + getLendingPool: { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'getLendingPool', + outputs: [ + { + internalType: 'bool', + name: 'initialized', + type: 'bool', + }, + { + internalType: 'uint24', + name: 'lendingPoolId', + type: 'uint24', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable0', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable1', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + totalBorrows: { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint112', name: '', type: 'uint112' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + symbol: { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + getReserves: { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: 'reserve0', type: 'uint112' }, + { internalType: 'uint112', name: 'reserve1', type: 'uint112' }, + { internalType: 'uint32', name: 'blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token0: { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token1: { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + decimals: { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + reserveFactor: { + constant: true, + inputs: [], + name: 'reserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + borrowRate: { + constant: true, + inputs: [], + name: 'borrowRate', + outputs: [{ internalType: 'uint48', name: '', type: 'uint48' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + factory: { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + safetyMarginSqrt: { + constant: true, + inputs: [], + name: 'safetyMarginSqrt', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + liquidationPenalty: { + constant: true, + inputs: [], + name: 'liquidationPenalty', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + liquidationIncentive: { + constant: true, + inputs: [], + name: 'liquidationIncentive', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, +}; diff --git a/src/adaptors/impermax-v2/blacklist.js b/src/adaptors/impermax-v2/blacklist.js new file mode 100644 index 0000000000..18c5df0ab1 --- /dev/null +++ b/src/adaptors/impermax-v2/blacklist.js @@ -0,0 +1,75 @@ +const blacklistedLendingPools = { + ethereum: [ + /* No token prices */ + '0x3e5b7929c71b4d6fe88c3577382786d6169005d7', + '0x4849bb3f7fcad49437f3107a578e063677424302', + '0x81ec6e89fd4e45c90ce77c9abbea3629f649c4e9', + '0x8dcba0b75c1038c4babbdc0ff3bd9a8f6979dd13', + '0xa00d47b4b304792eb07b09233467b690db847c91', + '0xe46456153cf0e767528f4a4cd3b613d5c4101e48', + '0xefa2e1e46b83d572d01521c4c64845b0227b6314', + '0xf28e099827cb05c9c35397859b4b626218c5a1cc', + ], + polygon: [ + /* very old pools ignore */ + '0x1e987756305c6506a8687e6ceb85872c48ceaa3b', + '0x2bb779ce585a19a202ccc6e583968431b3f15ea8', + '0x5c796c3cee0ca11e21f707bc3dfea8edda6b197d', + '0x63489c42530234b8f5d1124d2e671129be32b3b5', + '0xb343cc2378dcff9a6f81b4eee3d8ecdc88560f6a', + '0xb957d5a232eebd7c4c4b0a1af9f2043430304e65', + '0xc1b384610a90513ea599bb15fefa3d5bffb2a790', + '0xec07dd093007aae16508f76c07d26217b7db9f1b', + '0x2cbc4487f0b489d554b72b2e7f9679c3cd1efbc2', + '0x06d3ae1cfe7d3d27b8b9f541e2d76e5f33778923', + '0x242dd049be49e795cd60f0da812deef7cf4104dc', + '0x7166f0509bd1deedf90e42046025d929078089b4', + '0x6817f1adf8fc29f5cf23ba814cee18120f5e88b7', + ], + fantom: [ + '0x65151e7a82c4415a73756608e2c66b39a57dca12'.toLowerCase(), + '0x16875107bb3ce4b0c120c95b3b8d3f94d799c0ef'.toLowerCase(), + ], + scroll: [ + /* deployed with the univ2 not staked so ignore these */ + '0x838D141BdBECeAA2EB1C576b6a4309f26f795CF2'.toLowerCase(), // tkn/chi + '0xFFCe6dB18f18D711EF7Bf45b501A6b652b44bC43'.toLowerCase(), // zen/chi + '0xD448ac2A2d9C85010459E5f5Bf81931E5Bc40EC3'.toLowerCase(), // chi/weth + '0x7f0997bC0ee78553DDAb736d945b7Ba10Fe38B2E'.toLowerCase(), // wbtc/weth + '0x94d81405985A4c34EaC4945d2b98c74258EdD07F'.toLowerCase(), // tkn/chi - stakedlp + '0xE8f4895DF06a0c69A9BA87509EfdBBFBAFe86c2d'.toLowerCase(), // weth/tkn - stakedlp + '0x7c80Be56a6f23A3E598822648baaFD7524fe1239'.toLowerCase(), // chi/wUKRE stakedlp + '0xDD14d0c651C63e1EeA5bd8b250cf99757425D68F'.toLowerCase(), // chi/usdc stakedlp + '0xc90073e1cabcf5069e00c5a6cb10023c9e1d5c4f'.toLowerCase(), // wbtc/eth stakedlp + ], + arbitrum: [ + /* Exclude IMX/WETH pool on sushi */ + '0xb7e5e74b52b9ada1042594cfd8abbdee506cc6c5', + /* No token prices */ + '0x15ed28e9396fa906b2a2bca0c729d7cced7c646e', + '0xcc5c1540683aff992201d8922df44898e1cc9806', + '0x01a464e2bf76bd4a3a50073026ff2335584d67d8', + '0x1c1ccd7199afb175b425e9a1a910a3326f73faa3', + '0x3d5fcbed1c9b6c9b0f6dea1ded55b161a6efef31', + '0x4b28550846405a7825247f54070b568c2ece3eeb', + '0xcf49f93ff15b0ab9d336f1d5c8697f12d95012c4', + ], + sonic: [ + '0xd9de9f15994182518a688933d09787a9a9fb5bc9' // s/shadow stakedlp + ] +}; + +const blacklistedLendingVaults = { + scroll: ['0x83f22f87f504f8b9f10eb73ab05c58a0973b6681'], + polygon: [], + real: [], + arbitrum: ['0x7f2ffc27618afded2813e457953514c54778fa1c'], + ethereum: [], + optimism: [], + fantom: [], +}; + +module.exports = { + blacklistedLendingPools, + blacklistedLendingVaults, +}; diff --git a/src/adaptors/impermax-v2/geckoterminal.js b/src/adaptors/impermax-v2/geckoterminal.js new file mode 100644 index 0000000000..f09ffe60bb --- /dev/null +++ b/src/adaptors/impermax-v2/geckoterminal.js @@ -0,0 +1,17 @@ +const GECKOTERMINAL_IDS = { + avalanche: 'avax', + ethereum: 'eth', + polygon: 'polygon_pos', + arbitrum: 'arbitrum', + fantom: 'ftm', + base: 'base', + scroll: 'scroll', + optimism: 'optimism', + real: 're-al', + blast: 'blast', + sonic: 'sonic' +} + +module.exports = { + GECKOTERMINAL_IDS +} diff --git a/src/adaptors/impermax-v2/index.js b/src/adaptors/impermax-v2/index.js new file mode 100644 index 0000000000..ed37872c84 --- /dev/null +++ b/src/adaptors/impermax-v2/index.js @@ -0,0 +1,425 @@ +// Llama +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); +const { request } = require('graphql-request'); +const { default: BigNumber } = require('bignumber.js'); + +// Impermax +const { + blacklistedLendingPools, + blacklistedLendingVaults, +} = require('./blacklist.js'); +const { graphQuery } = require('./query.js'); +const { GECKOTERMINAL_IDS } = require('./geckoterminal.js'); + +/** + * LENDING POOLS CONFIGS + */ + +const config = { + ethereum: [ + 'https://api.studio.thegraph.com/query/46041/impermax-mainnet-v1/v0.0.1', + ], + polygon: [ + 'https://api.studio.thegraph.com/query/46041/impermax-x-uniswap-v2-polygon-v2/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-polygon-solv2/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-polygon-sol-stable/v0.0.1', + ], + arbitrum: [ + 'https://api.studio.thegraph.com/query/46041/impermax-arbitrum-v1/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-arbitrum-v2/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-arbitrum-solv2/v0.0.2', + ], + optimism: [ + 'https://api.studio.thegraph.com/query/46041/impermax-optimism-solv2/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-optimism-solv2-stable/v0.0.1', + ], + fantom: [ + 'https://api.studio.thegraph.com/query/46041/impermax-fantom-solv2/v0.0.2', + ], + base: [ + 'https://api.studio.thegraph.com/query/46041/impermax-base-solv2/v0.0.2', + 'https://api.studio.thegraph.com/query/46041/impermax-base-solv2-stable/v0.0.1', + 'https://api.studio.thegraph.com/query/46041/impermax-base-v2/v0.0.3', + ], + scroll: [ + 'https://api.studio.thegraph.com/query/46041/impermax-scroll-solv2/v0.0.2', + 'https://api.studio.thegraph.com/query/46041/impermax-scroll-solv2-stable/0.0.9', + ], + real: [ + 'https://api.goldsky.com/api/public/project_cm2d5q4l4w31601vz4swb3vmi/subgraphs/impermax-finance/impermax-real-v2-stable/gn', + 'https://api.goldsky.com/api/public/project_cm2rhb30ot9wu01to8c9h9e37/subgraphs/impermax-real-solv2/3.0/gn', + ], + blast: [ + 'https://api.studio.thegraph.com/query/46041/impermax-blast-solv2/v0.0.3', + 'https://api.studio.thegraph.com/query/46041/impermax-blast-v2/v0.0.2', + 'https://api.studio.thegraph.com/query/46041/impermax-blast-solv2-stable/v0.0.2', + ], + sonic: [ + 'https://api.studio.thegraph.com/query/46041/impermax-sonic-solv2/v0.0.2', + 'https://api.studio.thegraph.com/query/46041/impermax-sonic-solv2-stable/v0.0.1', + ], + avalanche: [ + 'https://api.studio.thegraph.com/query/46041/impermax-avalanche-solv2/v0.0.3', + ], +}; + +// DEXes or all our StakedLP Token factories for the dex +const projectPoolFactories = { + ethereum: { + UniswapV2: ['0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f'], + }, + polygon: { + Quickswap: ['0x5757371414417b8c6caad45baef941abc7d3ab32'], + Sushiswap: ['0xc35dadb65012ec5796536bd9864ed8773abc74c4'], + Apeswap: ['0xcf083be4164828f00cae704ec15a36d711491284'], + Tetuswap: ['0x684d8c187be836171a1af8d533e4724893031828'], + Pearl: [ + '0xb07c75e3db03eb69f047b92274019912014ba78e', + '0x1a645bfb46b00bb2dce6a1a517d7de2999155fe4', + '0xfb8bd40c0a13d141b26ee190ca87991ec54932e9', + ], + Satin: ['0xcaf3fb1b03f1d71a110167327f5106be82bee209'], + }, + arbitrum: { + Sushiswap: ['0xc35dadb65012ec5796536bd9864ed8773abc74c4'], + DXSwap: ['0x359f20ad0f42d75a5077e65f30274cabe6f4f01a'], + Arbidex: ['0x1c6e968f2e6c9dec61db874e28589fd5ce3e1f2c'], + Swapfish: ['0x71539d09d3890195dda87a6198b98b75211b72f3'], + Zyberswap: ['0xac2ee06a14c52570ef3b9812ed240bce359772e7'], + Chronos: ['0x111eeeb6bfab9e8d0e87e45db15031d89846e5d7'], + Ramses: ['0x78a2251f1aaeaa8fc1eafcc379663cca3f894708'], + Solunea: ['0x6ef065573cd3fff4c375d4d36e6ca93cd6e3d499'], + SolidLizard: ['0x734d84631f00dc0d3fcd18b04b6cf42bfd407074'], + Auragi: ['0x268bb0220ab61abd9bd42c5db49470bb3e6b0b2f'], + }, + optimism: { + Velodrome: ['0xf1046053aa5682b4f9a81b5481394da16be5ff5a'], + }, + fantom: { + Equalizer: ['0xc6366efd0af1d09171fe0ebf32c7943bb310832a'], + }, + base: { + Aerodrome: ['0x420dd381b31aef6683db6b902084cb0ffece40da'], + Scale: ['0xed8db60acc29e14bc867a497d94ca6e3ceb5ec04'], + UniswapV2: [ + '0x3e84d913803b02a4a7f027165e8ca42c14c0fde7', + '0x8909dc15e40173ff4699343b6eb8132c65e18ec6', + ], + }, + scroll: { + Tokan: [ + '0x92af10c685d2cf4cd845388c5f45ac5dc97c5024', + '0x074568f090e93194289c2c2bf285ee7f60b485a9', + '0x6c041ff2d25310a2751c57555265f2364caca195', + ], + }, + avalanche: { + TraderJoe: ['0x9ad6c38be94206ca50bb0d90783181662f0cfa10'], + Pangolin: ['0xefa94de7a4656d787667c749f7e1223d71e9fd88'], + Thorus: ['0xa98ea6356a316b44bf710d5f9b6b4ea0081409ef'], + Blackhole: [ + '0x48168439ca4ef9e95975e3e2488bfcbd8fb1a80c', + '0x1899d3b1e62a1e52cab440ef065d6a6cdfcf1125', + ], + }, + real: { + PearlV2: [ + '0x28e22d8c807b6e6c0eca4373fc3b9920453ceeee', + '0x317371f126680734d7db2ace2d751ffc0bd4b771', + '0x2b965fdf04f9e9beef1659464ef3a0094a68d923', + ], + }, + blast: { + Fenix: ['0xa19c51d91891d3df7c13ed22a2f89d328a82950f'], + }, + sonic: { + Equalizer: [ + '0xddd9845ba0d8f38d3045f804f67a1a8b9a528fcc', + '0x543cc9542314e0bec710eccd03586006df355d83', + ], + SwapX: [ + '0x05c1be79d3ac21cc4b727eed58c9b2ff757f5663', + '0xb84bba16a3a332ac2e66aa4508db1efd300cde2b', + ], + Shadow: [ + '0x2da25e7446a70d7be65fd4c053948becaa6374c8', + '0x1d3258b9c35198454c1f44e89003de5851748cc5', + ], + }, +}; + +/** + * Gets all impermax borrowables in `chain` + */ +const getChainBorrowables = async (chain) => { + const urls = config[chain]; + let allBorrowables = []; + + for (const url of urls) { + const queryResult = await request(url, graphQuery); + allBorrowables = allBorrowables.concat(queryResult.borrowables); + } + + const blacklist = blacklistedLendingPools[chain] || []; + return allBorrowables.filter( + (i) => + !blacklist + .map((i) => i.toLowerCase()) + .includes(i.lendingPool.id.toLowerCase()) + ); +}; + +/** + * Gets a third party DEX given a factory address + */ +const getProject = (chain, factoryAddress) => { + const chainProjects = projectPoolFactories[chain] || {}; + for (const [project, factories] of Object.entries(chainProjects)) { + if (factories.includes(factoryAddress.toLowerCase())) return project; + } + + return null; +}; + +/** + * TOKEN PRICES + */ + +// Try llama, then geckoterminal, if all fail exclude +async function getChainUnderlyingPrices(chain, tokenAddresses) { + // Remove duplicate underlyings + const uniqueTokens = [...new Set(tokenAddresses)]; + + const { tokenPrices, missingTokens } = await getPriceFromDefiLlama( + chain, + uniqueTokens + ); + if (tokenPrices && missingTokens.length == 0) return tokenPrices; + + const coingeckoPrices = await getPriceFromGeckoTerminal(chain, missingTokens); + if (coingeckoPrices) { + for (const [key, price] of Object.entries(coingeckoPrices)) { + if (price) tokenPrices[key] = price; + } + } + + return tokenPrices; +} + +const getPriceFromDefiLlama = async (chain, tokenAddresses) => { + const MAX_LLAMA_COINS = 100; + const tokenPrices = {}; + const missingTokens = []; + + try { + for (let i = 0; i < tokenAddresses.length; i += MAX_LLAMA_COINS) { + const maxTokens = tokenAddresses.slice(i, i + MAX_LLAMA_COINS); + const chainTokens = maxTokens.map((address) => `${chain}:${address}`); + + const { coins } = await fetch( + `https://coins.llama.fi/prices/current/${chainTokens.join(',')}` + ).then((i) => i.json()); + + maxTokens.forEach((token) => { + const key = `${chain}:${token}`; + const tokenPrice = coins[key]?.price; + + // Push to missing and try get these from gecko + if (!tokenPrice) { + missingTokens.push(token); + return; + } + + tokenPrices[key] = parseFloat(tokenPrice); + }); + } + + return { tokenPrices, missingTokens }; + } catch (error) { + console.warn(`DefiLlama prices fail on ${chain}:`, error.message); + return { undefined, missingTokens: tokenAddresses }; + } +}; + +async function getPriceFromGeckoTerminal(chain, tokenAddresses) { + console.log(`Getting ${tokenAddresses.length} tokens from gecko on ${chain}`); + const MAX_GECKO_COINS = 25; + const geckoChainId = GECKOTERMINAL_IDS[chain]; + const tokenPrices = {}; + + try { + for (let i = 0; i < tokenAddresses.length; i += MAX_GECKO_COINS) { + const maxTokens = tokenAddresses.slice(i, i + MAX_GECKO_COINS); + const tokens = maxTokens.join(','); + + const { data } = await fetch( + `https://api.geckoterminal.com/api/v2/simple/networks/${geckoChainId}/token_price/${tokens}` + ).then((i) => i.json()); + + maxTokens.forEach((token) => { + const key = `${chain}:${token}`; + const tokenPrice = data.attributes.token_prices[token]; + + if (!tokenPrice) { + console.warn(`No price found on Gecko for token: ${token}`); + return; + } + + tokenPrices[key] = parseFloat(tokenPrice); + }); + } + return tokenPrices; + } catch (error) { + console.error(`Gecko prices fail on ${chain}:`, error.message); + return undefined; + } +} + +/** + * BORROWABLE YIELDS + */ + +const SECONDS_PER_YEAR = BigNumber(60 * 60 * 24 * 365); + +// Since we're a lending protocol the TVL is the excess supply (ie. `totalBalance`) +const getTvlUsd = (totalBalance, tokenPriceUsd) => + BigNumber(totalBalance).times(BigNumber(tokenPriceUsd)); + +const getBorrowApr = (borrowRate) => + BigNumber(borrowRate).times(SECONDS_PER_YEAR).times(BigNumber(100)); + +const getSupplyApr = ( + totalBorrows, + totalBalance, + borrowRate, + reserveFactor +) => { + if (BigNumber(totalBorrows).eq(BigNumber(0))) return BigNumber(0); + + const utilization = BigNumber(totalBorrows).div( + BigNumber(totalBorrows).plus(BigNumber(totalBalance)) + ); + + return BigNumber(borrowRate) + .times(utilization) + .times(BigNumber(1).minus(BigNumber(reserveFactor))); +}; + +const getTotalBorrowsUsd = (totalBorrows, tokenPriceUsd) => + BigNumber(totalBorrows).times(BigNumber(tokenPriceUsd)); + +const getLtv = (safetyMargin, liqIncentive, liqFee) => + BigNumber(1).div( + BigNumber(safetyMargin).sqrt().times(BigNumber(liqIncentive).plus(liqFee)) + ); + +const getTotalSupplyUsd = (totalBalance, totalBorrows, tokenPriceUsd) => + BigNumber(totalBorrows) + .plus(BigNumber(totalBalance)) + .times(BigNumber(tokenPriceUsd)); + +/** + * -> Loop through each chain from config + * -> Get all borrowables + lending vaults on this chain + * -> Get all borrowable underlyings prices on this chain + * -> Loop through each borrowable on this chain + * -> Match project from this borrowable's `uniswapV2Factory` and add to pools array + * -> Loop through each lending vault on this chain + * -> Get vault risk profile and add to pools and add to pools aray + */ +const main = async () => { + const pools = []; + const chains = Object.keys(config); + + for (const chain of chains) { + try { + const borrowables = await getChainBorrowables(chain); + + const prices = await getChainUnderlyingPrices( + chain, + borrowables.map((i) => i.underlying.id) + ); + + /** + * Add borrowables + */ + for (const borrowable of borrowables) { + const { + id, + underlying, + totalBorrows, + totalBalance, + reserveFactor, + borrowRate, + lendingPool, + } = borrowable; + + const project = getProject(chain, lendingPool.pair.uniswapV2Factory); + if (!project) { + console.warn(`Missing project, skipping pool ${lendingPool.id} `); + continue; + } + + const price = prices[`${chain}:${underlying.id}`]; + if (!price) { + console.warn(`Missing price, skipping pool ${lendingPool.id} `); + continue; + } + + // Geckoterminal is reporting the wrong price + if ( + underlying.id.toLowerCase() === + '0x0f929C29dcE303F96b1d4104505F2e60eE795caC'.toLowerCase() + ) { + continue; + } + + const { safetyMargin, liquidationFee, liquidationIncentive } = + lendingPool.collateral; + + const ltv = getLtv(safetyMargin, liquidationIncentive, liquidationFee); + const tvlUsd = getTvlUsd(totalBalance, price); + const totalBorrowsUsd = getTotalBorrowsUsd(totalBorrows, price); + const totalSupplyUsd = getTotalSupplyUsd( + totalBalance, + totalBorrows, + price + ); + const borrowApr = getBorrowApr(borrowRate); + const supplyApr = getSupplyApr( + totalBorrows, + totalBalance, + borrowApr, + reserveFactor + ); + + const { token0, token1 } = lendingPool.pair; + + pools.push({ + pool: `${lendingPool.id}-${underlying.symbol}-${chain}`.toLowerCase(), + poolMeta: `${project} ${token0.symbol}/${token1.symbol}`, + chain, + project: 'impermax-v2', + symbol: underlying.symbol, + tvlUsd: tvlUsd.toNumber(), + totalBorrowUsd: totalBorrowsUsd.toNumber(), + totalSupplyUsd: totalSupplyUsd.toNumber(), + apyBase: supplyApr.toNumber(), + apyBaseBorrow: borrowApr.toNumber(), + underlyingTokens: [token0.id, token1.id], + ltv: Number(ltv.toFixed(3)), + url: 'https://impermax.finance', + }); + } + } catch (err) { + console.log(`error for chain ${chain}:`, err); + } + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/impermax-v2/query.js b/src/adaptors/impermax-v2/query.js new file mode 100644 index 0000000000..ed421d7099 --- /dev/null +++ b/src/adaptors/impermax-v2/query.js @@ -0,0 +1,42 @@ +const graphQuery = `{ + borrowables { + id + totalBalance + totalBorrows + reserveFactor + borrowRate + underlying { + id + name + symbol + decimals + } + lendingPool { + id + collateral { + liquidationFee + liquidationIncentive + safetyMargin + } + pair { + uniswapV2Factory + token0 { + id + name + symbol + decimals + } + token1 { + id + name + symbol + decimals + } + } + } + } +}`; + +module.exports = { + graphQuery, +}; diff --git a/src/adaptors/impermax-v3/abi.js b/src/adaptors/impermax-v3/abi.js new file mode 100644 index 0000000000..e03a5d6a1a --- /dev/null +++ b/src/adaptors/impermax-v3/abi.js @@ -0,0 +1,220 @@ +module.exports = { + allLendingPools: { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'allLendingPools', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + allLendingPoolsLength: { + constant: true, + inputs: [], + name: 'allLendingPoolsLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + getLendingPool: { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'getLendingPool', + outputs: [ + { + internalType: 'bool', + name: 'initialized', + type: 'bool', + }, + { + internalType: 'uint24', + name: 'lendingPoolId', + type: 'uint24', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable0', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable1', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + totalBorrows: { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint112', name: '', type: 'uint112' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + symbol: { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + getReserves: { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: 'reserve0', type: 'uint112' }, + { internalType: 'uint112', name: 'reserve1', type: 'uint112' }, + { internalType: 'uint32', name: 'blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token0: { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token1: { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + decimals: { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + reserveFactor: { + constant: true, + inputs: [], + name: 'reserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + borrowRate: { + constant: true, + inputs: [], + name: 'borrowRate', + outputs: [{ internalType: 'uint48', name: '', type: 'uint48' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + factory: { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + safetyMarginSqrt: { + constant: true, + inputs: [], + name: 'safetyMarginSqrt', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + liquidationPenalty: { + constant: true, + inputs: [], + name: 'liquidationPenalty', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, + liquidationIncentive: { + constant: true, + inputs: [], + name: 'liquidationIncentive', + outputs: [{ internalType:'uint256', name: '', 'type': 'uint256'}], + payable: false, + stateMutability:'view', + type: 'function' + }, +}; diff --git a/src/adaptors/impermax-v3/blacklist.js b/src/adaptors/impermax-v3/blacklist.js new file mode 100644 index 0000000000..0f8800c593 --- /dev/null +++ b/src/adaptors/impermax-v3/blacklist.js @@ -0,0 +1,72 @@ +const blacklistedLendingPools = { + ethereum: [ + /* No token prices */ + '0x3e5b7929c71b4d6fe88c3577382786d6169005d7', + '0x4849bb3f7fcad49437f3107a578e063677424302', + '0x81ec6e89fd4e45c90ce77c9abbea3629f649c4e9', + '0x8dcba0b75c1038c4babbdc0ff3bd9a8f6979dd13', + '0xa00d47b4b304792eb07b09233467b690db847c91', + '0xe46456153cf0e767528f4a4cd3b613d5c4101e48', + '0xefa2e1e46b83d572d01521c4c64845b0227b6314', + '0xf28e099827cb05c9c35397859b4b626218c5a1cc', + ], + polygon: [ + /* very old pools ignore */ + '0x1e987756305c6506a8687e6ceb85872c48ceaa3b', + '0x2bb779ce585a19a202ccc6e583968431b3f15ea8', + '0x5c796c3cee0ca11e21f707bc3dfea8edda6b197d', + '0x63489c42530234b8f5d1124d2e671129be32b3b5', + '0xb343cc2378dcff9a6f81b4eee3d8ecdc88560f6a', + '0xb957d5a232eebd7c4c4b0a1af9f2043430304e65', + '0xc1b384610a90513ea599bb15fefa3d5bffb2a790', + '0xec07dd093007aae16508f76c07d26217b7db9f1b', + '0x2cbc4487f0b489d554b72b2e7f9679c3cd1efbc2', + '0x06d3ae1cfe7d3d27b8b9f541e2d76e5f33778923', + '0x242dd049be49e795cd60f0da812deef7cf4104dc', + '0x7166f0509bd1deedf90e42046025d929078089b4', + '0x6817f1adf8fc29f5cf23ba814cee18120f5e88b7', + ], + fantom: [ + '0x65151e7a82c4415a73756608e2c66b39a57dca12'.toLowerCase(), + '0x16875107bb3ce4b0c120c95b3b8d3f94d799c0ef'.toLowerCase(), + ], + scroll: [ + /* deployed with the univ2 not staked so ignore these */ + '0x838D141BdBECeAA2EB1C576b6a4309f26f795CF2'.toLowerCase(), // tkn/chi + '0xFFCe6dB18f18D711EF7Bf45b501A6b652b44bC43'.toLowerCase(), // zen/chi + '0xD448ac2A2d9C85010459E5f5Bf81931E5Bc40EC3'.toLowerCase(), // chi/weth + '0x7f0997bC0ee78553DDAb736d945b7Ba10Fe38B2E'.toLowerCase(), // wbtc/weth + '0x94d81405985A4c34EaC4945d2b98c74258EdD07F'.toLowerCase(), // tkn/chi - stakedlp + '0xE8f4895DF06a0c69A9BA87509EfdBBFBAFe86c2d'.toLowerCase(), // weth/tkn - stakedlp + '0x7c80Be56a6f23A3E598822648baaFD7524fe1239'.toLowerCase(), // chi/wUKRE stakedlp + '0xDD14d0c651C63e1EeA5bd8b250cf99757425D68F'.toLowerCase(), // chi/usdc stakedlp + ], + arbitrum: [ + /* Exclude IMX/WETH pool on sushi */ + '0xb7e5e74b52b9ada1042594cfd8abbdee506cc6c5', + /* No token prices */ + '0x15ed28e9396fa906b2a2bca0c729d7cced7c646e', + '0xcc5c1540683aff992201d8922df44898e1cc9806', + '0x01a464e2bf76bd4a3a50073026ff2335584d67d8', + '0x1c1ccd7199afb175b425e9a1a910a3326f73faa3', + '0x3d5fcbed1c9b6c9b0f6dea1ded55b161a6efef31', + '0x4b28550846405a7825247f54070b568c2ece3eeb', + '0xcf49f93ff15b0ab9d336f1d5c8697f12d95012c4', + ], +}; + +const blacklistedLendingVaults = { + scroll: ['0x83f22f87f504f8b9f10eb73ab05c58a0973b6681'], + polygon: [], + real: [], + arbitrum: ['0x7f2ffc27618afded2813e457953514c54778fa1c'], + ethereum: [], + optimism: [], + fantom: [], + avalanche: [] +}; + +module.exports = { + blacklistedLendingPools, + blacklistedLendingVaults, +}; diff --git a/src/adaptors/impermax-v3/geckoterminal.js b/src/adaptors/impermax-v3/geckoterminal.js new file mode 100644 index 0000000000..92ac2af766 --- /dev/null +++ b/src/adaptors/impermax-v3/geckoterminal.js @@ -0,0 +1,17 @@ +const GECKOTERMINAL_IDS = { + avax: 'avax', + ethereum: 'eth', + polygon: 'polygon_pos', + arbitrum: 'arbitrum', + fantom: 'ftm', + base: 'base', + scroll: 'scroll', + optimism: 'optimism', + real: 're-al', + blast: 'blast', + sonic: 'sonic' +} + +module.exports = { + GECKOTERMINAL_IDS +} diff --git a/src/adaptors/impermax-v3/index.js b/src/adaptors/impermax-v3/index.js new file mode 100644 index 0000000000..2a30d0b616 --- /dev/null +++ b/src/adaptors/impermax-v3/index.js @@ -0,0 +1,485 @@ +// Llama +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); +const { request } = require('graphql-request'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + +// Impermax +const { + blacklistedLendingPools, + blacklistedLendingVaults, +} = require('./blacklist.js'); +const { graphQuery, vaultGraphQuery, vaultGraphQueryV2 } = require('./query.js'); +const { GECKOTERMINAL_IDS } = require('./geckoterminal.js'); + +/** + * LENDING POOLS CONFIGS + */ + +const config = { + arbitrum: ['https://arbitrum-factory-v3-production.up.railway.app/'], + base: ['https://base-factory-v3-production.up.railway.app/'], + unichain: ['https://unichain-factoryv3-production.up.railway.app/'], + avax: [], + scroll: [], + polygon: [], + sonic: [], + blast: [] +}; + +const lendingVaultsConfig = { + polygon: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-polygon/v0.0.3', + ], + arbitrum: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-arbitrum/v0.0.4', + ], + base: [ + 'https://base-lendingvaults-production.up.railway.app', + ], + scroll: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-scroll/v0.0.3', + ], + real: [], + fantom: [], + optimism: [], + ethereum: [], + blast: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-blast/v0.0.2', + ], + sonic: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-sonic/v0.0.3', + ], + unichain: [ + 'https://api.studio.thegraph.com/query/46041/lending-vault-unichain/v0.0.1', + ], + avax: [ + 'https://avalanche-lendingvaults-production.up.railway.app' + ] +}; + +// NFTLP factory address +const projectPoolFactories = { + arbitrum: { + UniswapV3: ['0x4936b5aafe83611aa2fa926a683973ddb48ce7f1'], + }, + base: { + UniswapV3: ['0xc2da400cf63e9a01680c8fe14ab360098a35dcd8'], + Aerodrome: ['0xf159c02bff0617a58d8e5b811aa63ca3aea0bb04'] + }, + unichain: { + UniswapV3: ['0x62b45128b3c2783d5b1f86e6db92c9aa43eed6af'], + }, +}; + +// Only list balanced/aggressive vaults as default is conservative +const lendingVaultProfiles = { + arbitrum: [], + polygon: [], + scroll: [], + base: [ + // These vaults were affected by the exploit, are replaced below + //{ + // address: '0x7838a0329CFF90434424952411D5fFE687360F49'.toLowerCase(), + // risk: 'Conservative', + //}, // USDCV2 + //{ + // address: '0xaD9cfEBB7666f2698cA9d836eD8CBeb0545a4263'.toLowerCase(), + // risk: 'Aggressive', + //}, // ETHV2 + //{ + // address: '0xa1D0f86d74BB7C832308c640b504b8525168Ed62'.toLowerCase(), + // risk: 'Conservative', + //}, // cbBTCV2 (high) + { + address: '0x0988cc53b8Ddd625C20e382f1af2f9c385E4f9A3'.toLowerCase(), + risk: 'Conservative', + }, // ETHV2 + { + address: '0x5e68e1bde6699bae9cab165b35989e5acc6b7e67'.toLowerCase(), + risk: 'Conservative' + }, // CBBTC + { + address: '0xf7408ba0aaf8ca80d4442731415bbe2156da8958'.toLowerCase(), + risk: 'Conservative' + }, // Usdc + { + address: '0xad9cfebb7666f2698ca9d836ed8cbeb0545a4263'.toLowerCase(), + risk: 'Aggressive' + } // eth + ], + blast: [ + { + address: '0xFBFBd1c9E05c114684Bc447Da5182Fe09315E038'.toLowerCase(), + risk: 'Balanced', + }, // ETH + ], + sonic: [ + { + address: '0x49967493310250254Aee27F0AbD2C97b45cb1509'.toLowerCase(), + risk: 'Balanced', + }, // ws + { + address: '0xDD8761dec5dF366a6AF7fE4E15b8f3888c0a905c'.toLowerCase(), + risk: 'Balanced', + }, // usdc.e + { + address: '0x835dA504bEfedC85404ad6A11df278049bc56d12'.toLowerCase(), + risk: 'Balanced', + }, // weth + ], + unichain: [ + { + address: '0xcae4a89a26aadbe63a20d575259386d3f3dd4e5c'.toLowerCase(), + risk: "Conservative", + }, // ETH + { + address: '0xdb6a07a55177724e27a47f39fb1f73dba2d7e07a'.toLowerCase(), + risk: "Conservative", + }, // USDC + { + address: '0x80e019CB1e5b3cb42c66b45974290cfD28FBfe18'.toLowerCase(), + risk: "Conservative", + }, // WbBTC + { + address: '0x16507321843166033894da01547bf48483a9abc8'.toLowerCase(), + risk: "Conservative" + } + ], + avax: [ + { + address: "0x6859e20754ffbf93a81428f3da55c9f0eb723b2a".toLowerCase(), + risk: "Balanced", + }, // AVAX + { + address: "0xf35c95bd8869f4ae4b68a97e25462c3db08e9468".toLowerCase(), + risk: "Balanced", + }, // USDC + { + address: "0x738f2d9a7c52f91c4f2fdf515fb8aad951c22cd9".toLowerCase(), + risk: "Balanced", + }, // WETH.e + ] +}; + +/** + * Gets all impermax borrowables in `chain` + */ +const getChainBorrowables = async (chain) => { + const urls = config[chain]; + let allBorrowables = []; + + for (const url of urls) { + const queryResult = await request(url, graphQuery); + allBorrowables = allBorrowables.concat(queryResult.borrowables.items); + } + + const blacklist = blacklistedLendingPools[chain] || []; + return allBorrowables.filter((i) => !blacklist.includes(i.lendingPool.id)); +}; + +/** + * Gets all deployed lending vaults in `chain` + */ +const getChainVaults = async (chain) => { + const urls = lendingVaultsConfig[chain]; + let allLendingVaults = []; + + for (const url of urls) { + const isV2 = url.includes("railway"); + const queryResult = await request(url, isV2 ? vaultGraphQueryV2 : vaultGraphQuery); + allLendingVaults = allLendingVaults.concat(isV2 ? queryResult.lendingVaults.items : queryResult.lendingVaults); + } + + const blacklist = blacklistedLendingVaults[chain] || []; + return allLendingVaults.filter((i) => !blacklist.includes(i.id)); +}; + +/** + * Gets a third party DEX given a factory address + */ +const getProject = (chain, factoryAddress) => { + const chainProjects = projectPoolFactories[chain] || {}; + for (const [project, factories] of Object.entries(chainProjects)) { + if (factories.includes(factoryAddress.toLowerCase())) return project; + } + + return null; +}; + +/** + * TOKEN PRICES + */ + +// Try llama, then geckoterminal, if all fail exclude +async function getChainUnderlyingPrices(chain, tokenAddresses) { + // Remove duplicate underlyings + const uniqueTokens = [...new Set(tokenAddresses)]; + + const { tokenPrices, missingTokens } = await getPriceFromDefiLlama( + chain, + uniqueTokens + ); + if (tokenPrices && missingTokens.length == 0) return tokenPrices; + + const coingeckoPrices = await getPriceFromGeckoTerminal(chain, missingTokens); + if (coingeckoPrices) { + for (const [key, price] of Object.entries(coingeckoPrices)) { + if (price) tokenPrices[key] = price; + } + } + + return tokenPrices; +} + +const getPriceFromDefiLlama = async (chain, tokenAddresses) => { + const MAX_LLAMA_COINS = 100; + const tokenPrices = {}; + const missingTokens = []; + + try { + for (let i = 0; i < tokenAddresses.length; i += MAX_LLAMA_COINS) { + const maxTokens = tokenAddresses.slice(i, i + MAX_LLAMA_COINS); + const chainTokens = maxTokens.map((address) => `${chain}:${address}`); + + const { coins } = await fetch( + `https://coins.llama.fi/prices/current/${chainTokens.join(',')}` + ).then((i) => i.json()); + + maxTokens.forEach((token) => { + const key = `${chain}:${token}`; + const tokenPrice = coins[key]?.price; + + // Push to missing and try get these from gecko + if (!tokenPrice) { + missingTokens.push(token); + return; + } + + tokenPrices[key] = parseFloat(tokenPrice); + }); + } + + return { tokenPrices, missingTokens }; + } catch (error) { + console.warn(`DefiLlama prices fail on ${chain}:`, error.message); + return { undefined, missingTokens: tokenAddresses }; + } +}; + +async function getPriceFromGeckoTerminal(chain, tokenAddresses) { + console.log(`Getting ${tokenAddresses.length} tokens from gecko on ${chain}`); + const MAX_GECKO_COINS = 25; + const geckoChainId = GECKOTERMINAL_IDS[chain]; + const tokenPrices = {}; + + try { + for (let i = 0; i < tokenAddresses.length; i += MAX_GECKO_COINS) { + const maxTokens = tokenAddresses.slice(i, i + MAX_GECKO_COINS); + const tokens = maxTokens.join(','); + + const { data } = await fetch( + `https://api.geckoterminal.com/api/v2/simple/networks/${geckoChainId}/token_price/${tokens}` + ).then((i) => i.json()); + + maxTokens.forEach((token) => { + const key = `${chain}:${token}`; + const tokenPrice = data.attributes.token_prices[token]; + + if (!tokenPrice) { + console.warn(`No price found on Gecko for token: ${token}`); + return; + } + + tokenPrices[key] = parseFloat(tokenPrice); + }); + } + return tokenPrices; + } catch (error) { + console.error(`Gecko prices fail on ${chain}:`, error.message); + return undefined; + } +} + +/** + * BORROWABLE YIELDS + */ + +const SECONDS_PER_YEAR = BigNumber(60 * 60 * 24 * 365); + +// Since we're a lending protocol the TVL is the excess supply (ie. `totalBalance`) +const getTvlUsd = (totalBalance, tokenPriceUsd) => + BigNumber(totalBalance).times(BigNumber(tokenPriceUsd)); + +const getBorrowApr = (borrowRate) => + BigNumber(borrowRate).times(SECONDS_PER_YEAR).times(BigNumber(100)); + +const getSupplyApr = ( + totalBorrows, + totalBalance, + borrowRate, + reserveFactor +) => { + if (BigNumber(totalBorrows).eq(BigNumber(0))) return BigNumber(0); + + const utilization = BigNumber(totalBorrows).div( + BigNumber(totalBorrows).plus(BigNumber(totalBalance)) + ); + + return BigNumber(borrowRate) + .times(utilization) + .times(BigNumber(1).minus(BigNumber(reserveFactor))); +}; + +const getTotalBorrowsUsd = (totalBorrows, tokenPriceUsd) => + BigNumber(totalBorrows).times(BigNumber(tokenPriceUsd)); + +const getLtv = (safetyMargin, liqIncentive, liqFee) => + BigNumber(1).div( + BigNumber(safetyMargin).sqrt().times(BigNumber(liqIncentive).plus(liqFee)) + ); + +const getTotalSupplyUsd = (totalBalance, totalBorrows, tokenPriceUsd) => + BigNumber(totalBorrows) + .plus(BigNumber(totalBalance)) + .times(BigNumber(tokenPriceUsd)); + +// For urls +const formatImpermaxURLChain = (chain) => { + if (chain === 'avax') return 'avalanche' + return chain +} + +/** + * -> Loop through each chain from config + * -> Get all borrowables + lending vaults on this chain + * -> Get all borrowable underlyings prices on this chain + * -> Loop through each borrowable on this chain + * -> Match project from this borrowable's `uniswapV2Factory` and add to pools array + * -> Loop through each lending vault on this chain + * -> Get vault risk profile and add to pools and add to pools aray + */ +const main = async () => { + const pools = []; + const chains = Object.keys(config); + + for (const chain of chains) { + const [borrowables, lendingVaults] = await Promise.all([ + getChainBorrowables(chain), + getChainVaults(chain), + ]); + + const chainPools = [...borrowables, ...lendingVaults]; + const prices = await getChainUnderlyingPrices( + chain, + chainPools.map((i) => i.underlying.id) + ); + + /** + * Add borrowables + */ + for (const borrowable of borrowables) { + const { + id, + underlying, + totalBorrows, + totalBalance, + reserveFactor, + borrowRate, + lendingPool, + } = borrowable; + + const project = getProject(chain, lendingPool.nftlp.factory); + if (!project) { + console.warn(`Missing project, skipping pool ${lendingPool.id} `); + continue; + } + + const price = prices[`${chain}:${underlying.id}`]; + if (!price) { + console.warn(`Missing price, skipping pool ${lendingPool.id} `); + continue; + } + + const { safetyMargin, liquidationFee, liquidationIncentive } = + lendingPool.collateral; + + const ltv = getLtv(safetyMargin, liquidationIncentive, liquidationFee); + const tvlUsd = getTvlUsd(totalBalance, price); + const totalBorrowsUsd = getTotalBorrowsUsd(totalBorrows, price); + const totalSupplyUsd = getTotalSupplyUsd( + totalBalance, + totalBorrows, + price + ); + const borrowApr = getBorrowApr(borrowRate); + const supplyApr = getSupplyApr( + totalBorrows, + totalBalance, + borrowApr, + reserveFactor + ); + + const { token0, token1 } = lendingPool.nftlp; + + pools.push({ + pool: `${lendingPool.id}-${underlying.symbol}-${chain}`.toLowerCase(), + poolMeta: `${project} ${token0.symbol}/${token1.symbol}`, + chain: utils.formatChain(formatImpermaxURLChain(chain)), + project: 'impermax-v3', + symbol: underlying.symbol, + tvlUsd: tvlUsd.toNumber(), + totalBorrowUsd: totalBorrowsUsd.toNumber(), + totalSupplyUsd: totalSupplyUsd.toNumber(), + apyBase: supplyApr.toNumber(), + apyBaseBorrow: borrowApr.toNumber(), + underlyingTokens: [token0.id, token1.id], + ltv: Number(ltv.toFixed(3)), + url: `https://app.impermax.finance/markets/${formatImpermaxURLChain(chain)}/8/${lendingPool.id}`, // V3 pools always use factory "8" + }); + } + + /** + * Add lending vaults + */ + for (const vault of lendingVaults) { + const { id, supplyRate, underlying, totalSupply, exchangeRate } = vault; + + const price = prices[`${chain}:${underlying.id}`]; + if (!price) { + console.warn(`Missing price, skipping vault ${vault.id} on ${chain}`); + continue; + } + + const apyBase = Number(supplyRate) * 24 * 60 * 60 * 365 * 100; + const tvlUsd = price * Number(totalSupply) * Number(exchangeRate); + + const chainVaults = lendingVaultProfiles[chain] || []; + const vaultRisk = chainVaults.find((v) => v?.address.toLowerCase() === id.toLowerCase())?.risk; + if (!vaultRisk) { + console.warn(`Deprecated vault or missing profile, skipping vault ${vault.id} on ${chain}`) + continue; + } + + pools.push({ + pool: `${id}-${underlying.symbol}-${chain}`.toLowerCase(), + poolMeta: `${vaultRisk}`, + chain: utils.formatChain(formatImpermaxURLChain(chain)), + project: 'impermax-v3', + symbol: underlying.symbol, + tvlUsd, + apyBase, + underlyingTokens: [underlying.id], + url: `https://app.impermax.finance/vaults/${formatImpermaxURLChain(chain)}/${id}`, + }); + } + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/impermax-v3/query.js b/src/adaptors/impermax-v3/query.js new file mode 100644 index 0000000000..a90337afaa --- /dev/null +++ b/src/adaptors/impermax-v3/query.js @@ -0,0 +1,82 @@ +const graphQuery = `{ + borrowables(limit: 1000) { + items { + id + totalBalance + totalBorrows + reserveFactor + borrowRate + underlying { + id + name + symbol + decimals + } + lendingPool { + id + collateral { + liquidationFee + liquidationIncentive + safetyMargin + } + nftlp { + factory + token0 { + id + name + symbol + decimals + } + token1 { + id + name + symbol + decimals + } + } + } + } + } +}`; + +const vaultGraphQuery = `{ + lendingVaults { + id + supplyRate + underlying { + id + symbol + } + reserveFactor + lastUpdate + totalBalance + totalSupply + exchangeRate + availableLiquidity + } +}` + +const vaultGraphQueryV2 = `{ + lendingVaults { + items { + id + supplyRate + underlying { + id + symbol + } + reserveFactor + lastUpdate + totalBalance + totalSupply + exchangeRate + availableLiquidity + } + } +}` + +module.exports = { + graphQuery, + vaultGraphQuery, + vaultGraphQueryV2, +}; diff --git a/src/adaptors/index-coop/index.js b/src/adaptors/index-coop/index.js new file mode 100644 index 0000000000..8574177db1 --- /dev/null +++ b/src/adaptors/index-coop/index.js @@ -0,0 +1,97 @@ +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const { ethers } = require('ethers'); +const superagent = require('superagent'); + +const utils = require('../utils'); + +const chainId = { + Ethereum: 1, + Base: 8453, +}; + +const dsEthIndex = { + address: '0x341c05c0E9b33C0E38d64de76516b2Ce970bB3BE', + chain: 'Ethereum', + symbol: 'dsETH', +}; + +const icEthIndex = { + address: '0x7C07F7aBe10CE8e33DC6C5aD68FE033085256A84', + chain: 'Ethereum', + symbol: 'icETH', +}; + +const hyEthData = { + address: '0xc4506022Fb8090774E8A628d5084EED61D9B99Ee', + chain: 'Ethereum', + symbol: 'hyETH', +}; + +const wstETH15xData = { + address: '0xc8DF827157AdAf693FCb0c6f305610C28De739FD', + chain: 'Base', + symbol: 'wstETH15x', +}; + +const SetTokenABI = ['function totalSupply() external view returns (uint256)']; + +const buildPool = async (index) => { + try { + const apy = await getApy(index.address, chainId[index.chain]); + const tvlUsd = await getTvlUsd(index); + const chain = utils.formatChain(index.chain); + return { + pool: `${index.address}-${chain}`.toLowerCase(), + chain, + project: 'index-coop', + symbol: index.symbol, + tvlUsd, + apy, + }; + } catch (err) { + console.log(err); + } +}; + +const getApy = async (address, chain) => { + const res = await superagent.get( + `https://api.indexcoop.com/v2/data/${address}?chainId=${chain}&metrics=apy` + ); + const json = JSON.parse(res.text); + const { APY, Rate, StreamingFee } = json.metrics[0]; + return APY + Rate + StreamingFee; +}; + +const getPrice = async (index) => { + const chain = utils.formatChain(index.chain); + const key = `${chain}:${index.address}`.toLowerCase(); + const ethPriceUSD = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + return ethPriceUSD; +}; + +const getTvlUsd = async (index) => { + const priceUsd = await getPrice(index); + const supply = await sdk.api2.erc20.totalSupply({ + target: index.address, + chain: index.chain.toLowerCase(), + }); + const supplyNumber = new BigNumber(supply.output.toString()); + const tvlUsd = supplyNumber.div(1e18).toNumber() * priceUsd; + return tvlUsd; +}; + +const main = async () => { + const hyETH = await buildPool(hyEthData); + const icETH = await buildPool(icEthIndex); + const wstETH15x = await buildPool(wstETH15xData); + return [hyETH, icETH, wstETH15x]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.indexcoop.com', +}; diff --git a/src/adaptors/indigo/http-helper.js b/src/adaptors/indigo/http-helper.js new file mode 100644 index 0000000000..3022dc700a --- /dev/null +++ b/src/adaptors/indigo/http-helper.js @@ -0,0 +1,22 @@ +const axios = require("axios") + +async function get(endpoint, options) { + try { + return (await axios.get(endpoint, options)).data + } catch (e) { + throw new Error(`Failed to get ${endpoint}`) + } +} + +async function post(endpoint, body, options) { + try { + return (await axios.post(endpoint, body, options)).data + } catch (e) { + throw new Error(`Failed to post ${endpoint}`) + } +} + +module.exports = { + get, + post +} \ No newline at end of file diff --git a/src/adaptors/indigo/index.js b/src/adaptors/indigo/index.js new file mode 100644 index 0000000000..946ade49e9 --- /dev/null +++ b/src/adaptors/indigo/index.js @@ -0,0 +1,84 @@ +const { get, post } = require('./http-helper') + +// Get Pool Data for each Stability Pool +async function apy() { + const stabilityPools = await fetchStabilityPools(); + const adaPriceUsd = await fetchAdaPriceToUsd(); + + return Promise.all(stabilityPools.map(async (pool) => { + const adaRewardsKey = `sp_${pool.asset}_ada`; + const indyRewardsKey = `sp_${pool.asset}_indy`; + + const [adaApy, indyApy] = await Promise.all([ + fetchApr(adaRewardsKey), + fetchApr(indyRewardsKey) + ]); + + const assetAnalytics = await fetchAssetAnalytics(pool.asset); + const tvlUsd = await calculateTvlUsd(assetAnalytics, adaPriceUsd); + + return { + pool: pool.asset, + chain: "Cardano", + project: "indigo", + symbol: pool.asset, + apyReward: (adaApy || 0) + (indyApy || 0), + rewardTokens: ['ADA', 'INDY'], + underlyingTokens: [pool.asset], + tvlUsd: Number(tvlUsd), + }; + })); +} + +// fetch stability pools +async function fetchStabilityPools() { + return await get(`https://analytics.indigoprotocol.io/api/stability-pools`); +} + +// Fetch APR for each Stability Pool +async function fetchApr(key) { + return await post(`https://analytics.indigoprotocol.io/api/apr/?key=${key}`) + .then(res => { + return parseFloat(res.value) || 0; + }) + .catch((error) => { + console.error(`Error fetching APR for ${key}:`, error); + return 0; + }); +} + +// Fetch iAsset analytics for a specific asset +async function fetchAssetAnalytics(assetName) { + try { + const response = await get(`https://analytics.indigoprotocol.io/api/assets/${assetName}/analytics`); + return response[assetName]; + } catch (error) { + console.error(`Error fetching analytics for ${assetName}:`, error); + return null; + } +} + +// Fetch the ADA price in USD +async function fetchAdaPriceToUsd() { + try { + const response = await get('https://analytics.indigoprotocol.io/api/price?from=ADA&to=USD'); + return response.price; + } catch (error) { + console.error('Error fetching ADA price:', error); + return 0; + } +} + +// Calculate TVL in USD +async function calculateTvlUsd(assetAnalytics, adaPriceUsd) { + if (!assetAnalytics) return 0; + + return assetAnalytics.totalValueLocked * adaPriceUsd; +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.indigoprotocol.io/stability-pools', +}; + diff --git a/src/adaptors/infinifi/index.js b/src/adaptors/infinifi/index.js new file mode 100644 index 0000000000..d57a6e9922 --- /dev/null +++ b/src/adaptors/infinifi/index.js @@ -0,0 +1,135 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); + +const siUSDAddress = '0xDBDC1Ef57537E34680B898E1FEBD3D68c7389bCB'; + +const lockingControllerCallData = { + address: '0x1d95cC100D6Cd9C7BbDbD7Cb328d99b3D6037fF7', + exchangeRateAbi: 'function exchangeRate(uint32 epoch) external view returns (uint256)', + bucketsAbi: 'function buckets(uint32 epoch) external view returns (address,uint256,uint256)', // shareToken address, totalReceiptTokens uint256, multiplier uint256 +} + +const poolsFunction = async () => { + try { + const pools = []; + + pools.push(await computeStakedTokenAPY()); + + pools.push(...await computeLockedTokensAPY()); + + return pools; + + } catch (error) { + console.error('Error fetching infiniFi data:', error); + return []; + } +}; + + +/** + * Compute the APY for the staked iUSD token, this is a simple erc4626, using the utils function + * @returns {Promise<{pool: string;chain: any;project: string;symbol: any;tvlUsd: number;apyBase: number;poolMeta: string;url: string;}>} + */ +async function computeStakedTokenAPY() { + const erc4626Infos = await utils.getERC4626Info(siUSDAddress, 'ethereum'); + + return { + pool: `${siUSDAddress}-ethereum`.toLowerCase(), + chain: utils.formatChain('ethereum'), + project: 'infinifi', + symbol: utils.formatSymbol('siUSD'), + tvlUsd: parseFloat(ethers.utils.formatUnits(erc4626Infos.tvl, 18)), + apyBase: erc4626Infos.apyBase, + poolMeta: 'Staked iUSD', + url: 'https://infinifi.xyz/', + }; + +} + + +/** + * Compute the APY for the locked tokens, this is a bit more complex, we need to get the exchange rate for the bucket and the total supply of the bucket + * This is done using multicalls to the locking controller contract and querying for blockNow and blockYesterday + * @returns {Promise<{pool: string;chain: any;project: string;symbol: any;tvlUsd: number;apyBase: number;poolMeta: string;url: string;}[]>} + */ +async function computeLockedTokensAPY() { + const pools = []; + const dateNow = Math.round(Date.now() / 1000); + const dateOneDayAgo = dateNow - 24 * 60 * 60; + const [blockOneDayAgo, blockNow] = await utils.getBlocksByTime([dateOneDayAgo, dateNow], 'ethereum'); + const buckets = [1, 2, 4, 6, 8, 13]; + + const multicallOptionsNow = { + abi: lockingControllerCallData.exchangeRateAbi, + calls: buckets.map((bucket) => ({ + target: lockingControllerCallData.address, + params: [bucket.toString()], + })), + block: blockNow, + chain: 'ethereum', + }; + + + const multicallOptionsTotalSupplyNow = { + abi: lockingControllerCallData.bucketsAbi, + calls: buckets.map((bucket) => ({ + target: lockingControllerCallData.address, + params: [bucket.toString()], + })), + block: blockNow, + chain: 'ethereum', + }; + + const multicallOptionsOneDayAgo = { + abi: lockingControllerCallData.exchangeRateAbi, + calls: buckets.map((bucket) => ({ + target: lockingControllerCallData.address, + params: [bucket.toString()], + })), + block: blockOneDayAgo, + chain: 'ethereum', + }; + + const multicallNow = await sdk.api.abi.multiCall(multicallOptionsNow); + const multicallBucketsNow = await sdk.api.abi.multiCall(multicallOptionsTotalSupplyNow); + const multicallOneDayAgo = await sdk.api.abi.multiCall(multicallOptionsOneDayAgo); + + // console.log(multicallNow.output); + // console.log(multicallOneDayAgo.output); + for (let i = 0; i < buckets.length; i++) { + const bucket = buckets[i]; + const exchangeRateNow = multicallNow.output[i]; + const bucketData = multicallBucketsNow.output[i]; + console.log(bucketData); + const tokenAddress = bucketData.output[0]; + const totalSupplyNow = bucketData.output[1]; + const totalSupplyNowNormalized = parseFloat(ethers.utils.formatUnits(totalSupplyNow, 18)); + const exchangeRateOneDayAgo = multicallOneDayAgo.output[i]; + // console.log(exchangeRateNow, exchangeRateOneDayAgo); + const exchangeRateNowNormalized = parseFloat(ethers.utils.formatUnits(exchangeRateNow.output, 18)); + const exchangeRateOneDayAgoNormalized = parseFloat(ethers.utils.formatUnits(exchangeRateOneDayAgo.output, 18)); + const apy = (exchangeRateNowNormalized / exchangeRateOneDayAgoNormalized) ** 365 * 100 - 100; + // console.log(`bucket ${bucket} apy: ${apy}`); + pools.push({ + pool: `${tokenAddress}-ethereum`.toLowerCase(), + chain: utils.formatChain('ethereum'), + project: 'infinifi', + symbol: utils.formatSymbol(`liUSD-${bucket}w`), + tvlUsd: totalSupplyNowNormalized, + apyBase: apy, + poolMeta: `Locked iUSD - ${bucket} week${bucket > 1 ? 's' : ''}`, + url: 'https://infinifi.xyz/', + }); + } + + return pools; +} + + + +module.exports = { + timetravel: true, + apy: poolsFunction, + url: 'https://infinifi.xyz/', +}; \ No newline at end of file diff --git a/src/adaptors/infrared-finance/index.js b/src/adaptors/infrared-finance/index.js new file mode 100644 index 0000000000..27b78e0d7c --- /dev/null +++ b/src/adaptors/infrared-finance/index.js @@ -0,0 +1,74 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const ibera = '0x9b6761bf2397bb5a6624a856cc84a3a14dcd3fe5'; +const bera = '0x0000000000000000000000000000000000000000'; +const project = 'infrared-finance'; +const symbol = 'ibera'; + +const apy = async () => { + const priceKey = `berachain:${bera}`; + const beraPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + const timestampNow = Math.floor(Date.now() / 1000); + const timestampYesterday = timestampNow - 86400; + + const blockNow = ( + await axios.get( + `https://coins.llama.fi/block/berachain/${timestampNow}` + ) + ).data.height; + const blockYesterday = ( + await axios.get(`https://coins.llama.fi/block/berachain/${timestampYesterday}`) + ).data.height; + + const exchangeRateAbi = { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + const exchangeRateYesterday = await sdk.api.abi.call({ + target: ibera, + chain: 'berachain', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockYesterday, + }); + + const exchangeRateToday = await sdk.api.abi.call({ + target: ibera, + chain: 'berachain', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockNow, + }); + const totalPooledBera = await sdk.api.abi.call({ + target: ibera, + chain: 'berachain', + abi: 'uint256:totalAssets', + }); + + const apr = + ((exchangeRateToday.output / 1e18 - + exchangeRateYesterday.output / 1e18) / + (exchangeRateYesterday.output / 1e18)) * + 365 * + 100; + + return [ + { + pool: `${ibera}`, + chain: 'berachain', + project, + symbol, + underlyingTokens: [bera], + apyBase: apr, + tvlUsd: totalPooledBera.output/1e18 * beraPrice, + }, + ]; +}; + +module.exports = { apy, url: 'https://infrared.finance/ibera' }; diff --git a/src/adaptors/insuredao/abis/abi.json b/src/adaptors/insuredao/abis/abi.json new file mode 100644 index 0000000000..abd9a50d33 --- /dev/null +++ b/src/adaptors/insuredao/abis/abi.json @@ -0,0 +1,104 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "rate": { + "inputs": [], + "name": "rate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "gauge_relative_weight": { + "inputs": [ + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_time", + "type": "uint256" + } + ], + "name": "gauge_relative_weight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "balanceOf": { + "constant": true, + "inputs": [{ "name": "_owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "name": "balance", "type": "uint256" }], + "type": "function" + }, + "exchangeRateOfLP": { + "inputs": [], + "name": "rate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalLiquidity": { + "inputs": [], + "name": "totalLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/insuredao/index.js b/src/adaptors/insuredao/index.js new file mode 100644 index 0000000000..7707c69dd5 --- /dev/null +++ b/src/adaptors/insuredao/index.js @@ -0,0 +1,480 @@ +// const sdk = require('@defillama/sdk'); +// const superagent = require('superagent'); +// const { default: BigNumber } = require('bignumber.js'); +// const utils = require('../utils'); +// const abi = require('./abis/abi.json'); +// const { request, gql } = require('graphql-request'); +// const dayjs = require('dayjs'); +// const { default: computeTVL } = require('@defillama/sdk/build/computeTVL'); +// const { +// sumTokens, +// sumTokensAndLPs, +// unwrapCrv, +// genericUnwrapCvx, +// } = require('../../helper/unwrapLPs'); + +// const insureTokenContract = '0xd83AE04c9eD29d6D3E6Bf720C71bc7BeB424393E'; +// const usdcTokenContract = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +// const gaugeController = '0x297ea2afcE594149Cd31a9b11AdBAe82fa1Ddd04'; + +// const uni = '0x1b459aec393d604ae6468ae3f7d7422efa2af1ca'; +// const uniStaking = '0xf57882cf186db61691873d33e3511a40c3c7e4da'; +// const gageAddressUniLP = '0xf57882cf186db61691873d33e3511a40c3c7e4da'; + +// const vlINSURE = '0xA12ab76a82D118e33682AcB242180B4cc0d19E29'; +// const gageAddressVlINSURE = '0xbCBCf05F2f77E2c223334368162D88f5d6032699'; + +// const secondsPerYear = 31536000; +// const startPrice = 1000000; +// // From Feb-22-2022 02:22:22 UTC Release date +// const yeildStartETH = 1645496542; +// // From Jul-08-2022 08:07:42 +// const yeildStartASTAR = 1657264062; +// // From Aug-05-2022 08:03:34 UTC +// const yeildStartOP = 1659683014; +// // From Nov-14-2022 18:30:00 UTC +// const yeildStartARB = 1668450600; + +// const data = [ +// { +// chain: 'ethereum', +// underlyingTokensContract: '0xDAea5b1B6b12Ac4c4f51aB12649e96ab3aB98C3A', +// rewardTokensContract: '0x1daa36ce317b704b2a26c02af90a02aa572dc49a', +// symbol: 'USDC', +// poolMeta: 'Genesis Index', +// }, +// { +// chain: 'ethereum', +// underlyingTokensContract: '0xd5f1Ab3c61eF3a6a6f1AA6141256Aa008D2fb5A1', +// rewardTokensContract: '0x43Eb5Dc8A1426dCD6029010aDEe7B62b73AC2918', +// symbol: 'USDC', +// poolMeta: 'Curve Wars Index', +// }, +// { +// chain: 'ethereum', +// underlyingTokensContract: '0x7E08daB409Ad1bCeBc5bE5674CB2C0f3540A4d3d', +// rewardTokensContract: '0x1a047380b29fd8f6bfc8363f653114b15129c708', +// symbol: 'USDC', +// poolMeta: 'Quanstamp Index', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x9789dc4B4bb39566592B3761be42A9eB23EA5d34', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Starlay Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x4C1800E02532ed0fC60183454B9bffdf96B134F0', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Arthswap', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x37D65A2f66d022b3F1739dEDcA1DfA076526D53E', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Algem', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xD7Bd4cCBA0e500e1506b4B5783339b62e4d44F7f', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'AstridDAO', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x4C83C55cDAecd197CB2Ef04AFb2964e4403819a0', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Muuu Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xF89A343Eeb7F5c82b5B1C8469899F8b8018c2956', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'SiO2 Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xE3F491c575e02902342ef8488Bb3D6C392869FdA', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Zenlink', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xd2b848a364Df5410CE2161F9FD033Da42BaF7b78', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Avault Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xB6D53534CABF9cD65F51A9E1FC0d0bE1d9Bfd303', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Kagla Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0xb4Bcb8a8E8C4760Dd26A95C9cdA302afCa9063a8', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'AstarFarm', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x36CE8dB174e14A673fd31cD46CF8Dc1CE430AFFf', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Sirius Finance', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x96f88002c1b1342DA65D3D19c214cA398D3ECd7f', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Astar Core-A Index', +// }, +// { +// chain: 'astar', +// underlyingTokensContract: '0x9d5AD4016BB6b70fd2b2228471664a8cB5b97125', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Astar Core-B Index', +// }, +// { +// chain: 'optimism', +// underlyingTokensContract: '0x9AC5895302662abF7C88f1A9289f629c21634aDf', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Optimism Core-A Index', +// }, +// { +// chain: 'optimism', +// underlyingTokensContract: '0x6D702e9eF07d0E5Ae32f5C4Bb53EdCf7BC61974F', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Optimism Core-B Index', +// }, +// { +// chain: 'optimism', +// underlyingTokensContract: '0xF3037Fa2185776601196bC10E88448a9518b848F', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Optimism Core-C Index', +// }, +// { +// chain: 'optimism', +// underlyingTokensContract: '0x5c9618F2DcC50B349d61F5F00B0371E94f203e29', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Optimism Core-D Index', +// }, +// { +// chain: 'arbitrum', +// underlyingTokensContract: '0xCA570cb02dCaB8C89f47e52E0d083ad481728283', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Arbitrum Core-A Index', +// }, +// { +// chain: 'arbitrum', +// underlyingTokensContract: '0x49f97e64b5eae37558976eb7a5bb1d7fba7b4cdb', +// rewardTokensContract: null, +// symbol: 'USDC', +// poolMeta: 'Arbitrum Core-B Index', +// }, +// ]; + +// //get InflationRate of INSURE token + +// async function getRate(Chain) { +// let tvltemp = await sdk.api.abi.call({ +// target: insureTokenContract, +// abi: abi['rate'], +// chain: Chain, +// params: [], +// }); + +// return tvltemp.output * 10 ** -18; +// } + +// //get gauge_relative_weight + +// async function gauge_relative_weight(gaugeAddess) { +// let gauge_relative_weight_value = await sdk.api.abi.call({ +// target: gaugeController, +// abi: abi['gauge_relative_weight'], +// chain: 'ethereum', +// params: [gaugeAddess, 0], +// }); + +// return gauge_relative_weight_value.output * 10 ** -18; +// } + +// // get Uniswap v2 LP Staking TVL + +// async function pool2(timestamp, block) { +// const balances = {}; +// await sumTokensAndLPs(balances, [[uni, uniStaking, true]], block); +// return balances; +// } + +// function getCoingeckoLock() { +// return new Promise((resolve) => { +// locks.push(resolve); +// }); +// } + +// // get pools liquidity + +// async function get_pools_liquidity(_underlyingTokensContract, _chainString) { +// let pools_liquidity = await sdk.api.abi.call({ +// target: _underlyingTokensContract, +// abi: abi['totalLiquidity'], +// chain: _chainString, +// }); +// return pools_liquidity.output * 10 ** -6; +// } + +// //get Get the exchange rate of LP tokens against underlying asset(scaled by MAGIC_SCALE_1E6) + +// async function get_pricePerToken(_underlyingTokensContract, _chainString) { +// let pricePerToken = await sdk.api.abi.call({ +// target: _underlyingTokensContract, +// abi: abi['exchangeRateOfLP'], +// chain: _chainString, +// }); + +// return pricePerToken.output; +// } + +// //calculate to Uni v2 Staking APY + +// async function getPoolUniLp( +// pChain, +// pTvl, +// pPoolContract, +// pGauge_relative_weight, +// pInflationRate, +// pPriceData +// ) { +// const yearlyInflationRate = +// pInflationRate * secondsPerYear * pGauge_relative_weight; + +// const yearlyInflationInsure = +// yearlyInflationRate * pPriceData['coingecko:insuredao']?.price; + +// const apyInflation = parseFloat( +// BigNumber(yearlyInflationInsure).div(pTvl).times(100) +// ); + +// const chainString = 'ethereum'; + +// return { +// pool: pPoolContract, +// chain: utils.formatChain(chainString), +// project: 'insuredao', +// symbol: utils.formatSymbol('INSURE-ETH'), +// tvlUsd: parseFloat(pTvl), +// apyReward: apyInflation, +// rewardTokens: [insureTokenContract], +// underlyingTokens: [uni], +// }; +// } + +// //calculate to vlINSURE Staking APY + +// async function getVlInsurePoolLp( +// pChain, +// pTvl, +// pPoolContract, +// pGauge_relative_weight, +// pInflationRate, +// pPriceData +// ) { +// const yearlyInflationRate = +// pInflationRate * secondsPerYear * pGauge_relative_weight; + +// const yearlyInflationInsure = +// yearlyInflationRate * pPriceData['coingecko:insuredao']?.price; + +// const apyInflation = (yearlyInflationInsure / pTvl) * 100; + +// const chainString = 'Ethereum'; + +// return { +// pool: pPoolContract, +// chain: utils.formatChain(chainString), +// project: 'insuredao', +// symbol: utils.formatSymbol('vlINSURE'), +// tvlUsd: parseFloat(pTvl), +// apyReward: apyInflation, +// rewardTokens: [insureTokenContract], +// underlyingTokens: [insureTokenContract], +// }; +// } + +// //calculate to USDC underwriting APY + +// async function getUnderwritingAPY( +// _poolContract, +// _underlyingTokensContract, +// _symbol, +// _poolMeta, +// _chainString, +// _tvl, +// _pricePerToken, +// _startPrice, +// _yieldStart +// ) { +// const pricePerToken = new BigNumber(_pricePerToken); +// const startPrice = new BigNumber(_startPrice); +// const increasePrice = pricePerToken.minus(startPrice); +// const span = new BigNumber(dayjs().unix()) +// .minus(new BigNumber(_yieldStart)) +// .div(24 * 60 * 60); + +// const apr = parseFloat( +// increasePrice.div(startPrice).div(span).times(365).times(100) +// ); + +// return { +// pool: _poolContract, +// chain: utils.formatChain(_chainString), +// project: 'insuredao', +// symbol: utils.formatSymbol(_symbol), +// poolMeta: _poolMeta, +// tvlUsd: parseFloat(_tvl), +// apyBase: apr, +// // apyReward: apr, +// rewardTokens: [usdcTokenContract], +// underlyingTokens: [_underlyingTokensContract], +// }; +// } + +// const getPools = async () => { +// let pools = []; + +// const balances = {}; + +// const priceKeys = ['insuredao', 'ethereum'] +// .map((t) => `coingecko:${t}`) +// .join(','); + +// const [gauge_relative_weight_data, priceData, inflationRate] = +// await Promise.all([ +// gauge_relative_weight(gageAddressUniLP), +// utils.getData(`https://coins.llama.fi/prices/current/${priceKeys}`), +// getRate('ethereum'), +// ]); + +// const LPbalances = await pool2(); + +// const uniContractTVL = await computeTVL( +// LPbalances, +// 'now', +// false, +// [], +// getCoingeckoLock, +// 5 +// ); + +// pools.push( +// await getPoolUniLp( +// 'ethereum', +// uniContractTVL.usdTvl, +// gageAddressUniLP, +// gauge_relative_weight_data, +// inflationRate, +// priceData.coins +// ) +// ); + +// const vlinsureTVL = +// ( +// await sdk.api.abi.call({ +// target: insureTokenContract, +// params: vlINSURE, +// abi: abi['balanceOf'], +// chain: 'ethereum', +// }) +// ).output * +// 10 ** -18 * +// priceData.coins['coingecko:insuredao']?.price; + +// const gauge_relative_weight_data_vlinsure = await gauge_relative_weight( +// gageAddressVlINSURE +// ); + +// pools.push( +// await getVlInsurePoolLp( +// 'ethereum', +// vlinsureTVL, +// vlINSURE, +// gauge_relative_weight_data_vlinsure, +// inflationRate, +// priceData.coins +// ) +// ); + +// //USDC underwriting Pool APY + +// for (var i = 0; i < data.length; i++) { +// underlyingTokensContract = data[i].underlyingTokensContract; +// symbol = data[i].symbol; +// poolMeta = data[i].poolMeta; +// chainString = data[i].chain; + +// if (data[i].stakingTokensContract == null) { +// poolContract = data[i].underlyingTokensContract; +// } else { +// poolContract = data[i].stakingTokensContract; +// } + +// if (chainString == 'ethereum') { +// yeildStart = yeildStartETH; +// } else if (chainString == 'optimism') { +// yeildStart = yeildStartOP; +// } else if (chainString == 'astar') { +// yeildStart = yeildStartASTAR; +// } else if (chainString == 'arbitrum') { +// yeildStart = yeildStartARB; +// } else { +// null; +// } + +// [tvl, pricePerToken] = await Promise.all([ +// get_pools_liquidity(underlyingTokensContract, chainString), +// get_pricePerToken(underlyingTokensContract, chainString), +// ]); + +// pools.push( +// await getUnderwritingAPY( +// poolContract, +// underlyingTokensContract, +// symbol, +// poolMeta, +// chainString, +// tvl, +// pricePerToken, +// startPrice, +// yeildStart +// ) +// ); +// } + +// return pools.filter((p) => utils.keepFinite(p)); +// }; + +// module.exports = { +// timetravel: false, +// apy: getPools, +// url: 'https://www.insuredao.fi/', +// }; diff --git a/src/adaptors/integral/index.js b/src/adaptors/integral/index.js index 5d2bf31057..4e009806a5 100644 --- a/src/adaptors/integral/index.js +++ b/src/adaptors/integral/index.js @@ -1,15 +1,13 @@ const { default: BigNumber } = require('bignumber.js'); const utils = require('../utils'); -const baseUrlSize = - 'https://size-api.integral.link/api/v5/pools?apiKey=00Gfs4iNa%2FXJDBkF%2B%2FX83SRqx3MXXAngJMkpx3lM%2FTU='; -const baseUrlFive = - 'https://five-api.integral.link/api/v1/pools?apiKey=00Gfs4iNa%2FXJDBkF%2B%2FX83SRqx3MXXAngJMkpx3lM%2FTU='; -const mainnetUrlSize = `${baseUrlSize}&network=Mainnet`; -const mainnetUrlFive = `${baseUrlFive}&network=Mainnet`; +const mainnetUrlSize = `https://size-api.integral.link/api/v6/pools?apiKey=00Gfs4iNa%2FXJDBkF%2B%2FX83SRqx3MXXAngJMkpx3lM%2FTU=&network=Mainnet`; +const mainnetUrlFive = `https://five-api.integral.link/api/v1/pools?apiKey=00Gfs4iNa%2FXJDBkF%2B%2FX83SRqx3MXXAngJMkpx3lM%2FTU=&network=Mainnet`; +const arbitrumUrlSize = `https://arbitrum-size-api.integral.link/api/v6/pools?apiKey=00Gfs4iNa%2FXJDBkF%2B%2FX83SRqx3MXXAngJMkpx3lM%2FTU=&network=Arbitrum`; const chains = { eth: 'ethereum', + arb: 'arbitrum', }; const buildPool = (entry, chainString, version) => { @@ -17,20 +15,11 @@ const buildPool = (entry, chainString, version) => { pool: entry.address, chain: utils.formatChain(chainString), project: 'integral', - market: version, - symbol: `${entry.name.toUpperCase()} (${version})`, + poolMeta: version, + symbol: entry.name.toUpperCase(), tvlUsd: parseFloat(BigNumber(entry.totalTokenValue).div(10 ** 18)), - apy: entry.apy - ? parseFloat( - BigNumber(entry.apy) - .div(10 ** 18) - .times(100) - ) - : parseFloat( - BigNumber(entry.apr) - .div(10 ** 18) - .times(100) - ), + apyBase: entry.swapApr ? parseFloat(BigNumber(entry.swapApr).div(10 ** 18).times(100)) : 0, + apyReward: entry.lpRewardApr ? parseFloat(BigNumber(entry.lpRewardApr).div(10 ** 18).times(100)) : 0, }; return newObj; @@ -49,6 +38,7 @@ const main = async () => { const data = await Promise.all([ topLvl(chains.eth, mainnetUrlSize, 'SIZE'), topLvl(chains.eth, mainnetUrlFive, 'FIVE'), + topLvl(chains.arb, arbitrumUrlSize, 'SIZE'), ]); return data.flat(); @@ -57,4 +47,5 @@ const main = async () => { module.exports = { timetravel: false, apy: main, + url: 'https://size.integral.link/pools', }; diff --git a/src/adaptors/interest-curve/index.ts b/src/adaptors/interest-curve/index.ts new file mode 100644 index 0000000000..f78d2358d6 --- /dev/null +++ b/src/adaptors/interest-curve/index.ts @@ -0,0 +1,68 @@ +const utils = require('../utils'); + +const API_URL_BASE = + 'https://api.interestlabs.io/v1/movement/mainnet/curve/metrics'; + +const INTEREST_DAPP_URL = 'https://www.interest.xyz'; + +async function getPools() { + const pageSize = 100; + let currentPage = 1; + const allPools = []; + + while (true) { + const response = await utils.getData( + `${API_URL_BASE}?page=${currentPage}&limit=${pageSize}` + ); + + if (!response || +response.total === 0) { + break; + } + + allPools.push(...response.data); + + // If we've fetched all pools, break + if (allPools.length >= +response.total) { + break; + } + + currentPage++; + } + + return allPools; +} + +async function main() { + // We're not using on-chain RPC requests here due to the rate limiting and instability of both official and third party RPCs and using our own load-balanced API. + const pools = await getPools(); + + const defiLlamaPools = pools + .map((pool) => { + return { + pool: pool.poolId + '-move', + chain: utils.formatChain('move'), + project: 'interest-curve', + symbol: pool.symbols + .map((symbol) => utils.formatSymbol(symbol)) + .join('-'), + tvlUsd: parseFloat(pool.metrics.tvl), + apyBase: +pool.metrics.apr, + apyReward: +pool.metrics.farmApr, + rewardTokens: Array.from(new Set(pool.rewards)), + underlyingTokens: pool.coins, + url: `${INTEREST_DAPP_URL}/pools/details?address=${pool.poolId}`, + poolMeta: pool.isStable ? 'stable' : 'volatile', + volumeUsd1d: +pool.metrics.volume1D, + volumeUsd7d: +pool.metrics.volume7D, + }; + }) + .filter((pool) => pool.apyReward > 0); // Pools when farm APR is 0 + + return defiLlamaPools; +} + +module.exports = { + timetravel: false, + apy: main, + url: `${INTEREST_DAPP_URL}/pools`, +}; diff --git a/src/adaptors/interport-finance/abis/abi.json b/src/adaptors/interport-finance/abis/abi.json new file mode 100644 index 0000000000..ce1e8c7a77 --- /dev/null +++ b/src/adaptors/interport-finance/abis/abi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address[]","name":"_assetSpenders","type":"address[]"},{"internalType":"bool","name":"_depositAllowed","type":"bool"},{"internalType":"bool","name":"_variableRepaymentEnabled","type":"bool"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_managers","type":"address[]"},{"internalType":"bool","name":"_addOwnerToManagers","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BurnAccessError","type":"error"},{"inputs":[],"name":"BurnAllowanceError","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerGuardError","type":"error"},{"inputs":[],"name":"ListSizeLimitError","type":"error"},{"inputs":[],"name":"MintAccessError","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NonContractAddressError","type":"error"},{"inputs":[],"name":"OnlyAssetSpenderError","type":"error"},{"inputs":[],"name":"OnlyManagerError","type":"error"},{"inputs":[],"name":"ReservedTokenError","type":"error"},{"inputs":[],"name":"SafeTransferError","type":"error"},{"inputs":[],"name":"SafeTransferFromError","type":"error"},{"inputs":[],"name":"SafeTransferNativeError","type":"error"},{"inputs":[],"name":"TokenBurnError","type":"error"},{"inputs":[],"name":"TokenDecimalsError","type":"error"},{"inputs":[],"name":"TotalSupplyLimitError","type":"error"},{"inputs":[],"name":"VariableRepaymentNotEnabledError","type":"error"},{"inputs":[],"name":"VariableTokenAlreadySetError","type":"error"},{"inputs":[],"name":"VariableTokenNotSetError","type":"error"},{"inputs":[],"name":"ZeroAddressError","type":"error"},{"inputs":[],"name":"ZeroAmountError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RedeemVariableToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RenounceManagerRole","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAssetSpender","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum CallerGuard.CallerGuardMode","name":"callerGuardMode","type":"uint8"}],"name":"SetCallerGuardMode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":true,"internalType":"bool","name":"isListed","type":"bool"}],"name":"SetListedCallerGuardContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetMultichainRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetTotalSupplyLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"variableRepaymentEnabled","type":"bool"}],"name":"SetVariableRepaymentEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"variableToken","type":"address"}],"name":"SetVariableToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SYSTEM_VERSION_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetSpenderCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"callerGuardMode","outputs":[{"internalType":"enum CallerGuard.CallerGuardMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkVariableTokenState","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"cleanup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fullAssetSpenderList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullListedCallerGuardContractList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullManagerList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullMultichainRouterList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isAssetSpender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isListedCallerGuardContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isMultichainRouter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"isReservedToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listedCallerGuardContractCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"listedCallerGuardContractIndexMap","outputs":[{"internalType":"bool","name":"isSet","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"listedCallerGuardContractList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managerCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"multichainRouterCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeemVariableToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceManagerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bool","name":"_forVariableBalance","type":"bool"}],"name":"requestAsset","outputs":[{"internalType":"address","name":"assetAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"setAssetSpender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum CallerGuard.CallerGuardMode","name":"_callerGuardMode","type":"uint8"}],"name":"setCallerGuardMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"internalType":"struct AccountToFlag[]","name":"_items","type":"tuple[]"}],"name":"setListedCallerGuardContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_value","type":"bool"}],"name":"setMultichainRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setTotalSupplyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_variableRepaymentEnabled","type":"bool"}],"name":"setVariableRepaymentEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_variableToken","type":"address"}],"name":"setVariableToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"tokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"variableRepaymentEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"variableToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/interport-finance/abis/erc20.abi.json b/src/adaptors/interport-finance/abis/erc20.abi.json new file mode 100644 index 0000000000..d094cbc5ea --- /dev/null +++ b/src/adaptors/interport-finance/abis/erc20.abi.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } + ] \ No newline at end of file diff --git a/src/adaptors/interport-finance/abis/stable.abi.json b/src/adaptors/interport-finance/abis/stable.abi.json new file mode 100644 index 0000000000..f46b2fa31b --- /dev/null +++ b/src/adaptors/interport-finance/abis/stable.abi.json @@ -0,0 +1,1115 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardTokenPerSecond", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_startTime", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "_vestingDuration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ListSizeLimitError", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyManagerError", + "type": "error" + }, + { + "inputs": [], + "name": "ReservedTokenError", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferError", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferNativeError", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ExitEarly", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Locked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "RenounceManagerRole", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "value", + "type": "bool" + } + ], + "name": "SetManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Vested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawVesting", + "type": "event" + }, + { + "inputs": [], + "name": "LPRevenueShare", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_allocPoint", + "type": "uint16" + }, + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_addSeconds", + "type": "uint32" + } + ], + "name": "changeEndTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "checkVestingBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "vestedTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vestingTotal", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unlockTime", + "type": "uint256" + } + ], + "internalType": "struct StablecoinFarm.VestedBalance[]", + "name": "vestData", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenAmount", + "type": "uint256" + } + ], + "name": "cleanup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "endTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "exitEarly", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exitEarlyLPShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exitEarlyTreasuryShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exitEarlyUserShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fullManagerList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "isManager", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + } + ], + "name": "isReservedToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isStakingTokenSet", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "lockPending", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "lockVesting", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "managerCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingRewardToken", + "outputs": [ + { + "internalType": "uint256", + "name": "pending", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakingTokenTotalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accumulatedRewardTokenPerShare", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "lastRewardTime", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "allocationPoint", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceManagerRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokenPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_allocPoint", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newRevenueShare", + "type": "address" + } + ], + "name": "setLPRevenueShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "setManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_userPercent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_treasuryPercent", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lpPercent", + "type": "uint256" + } + ], + "name": "setPercentsShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardTokenPerSecond", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "setRewardTokenPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newTreasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + } + ], + "name": "tokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocationPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "remainingRewardTokenAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userVested", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unlockTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "vest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vestingDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "withdrawVestedRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/interport-finance/index.js b/src/adaptors/interport-finance/index.js new file mode 100644 index 0000000000..619db87d0c --- /dev/null +++ b/src/adaptors/interport-finance/index.js @@ -0,0 +1,161 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abis/abi.json'); +const erc20Abi = require('./abis/erc20.abi.json'); +const stableAbi = require('./abis/stable.abi.json'); +const { getProvider } = require('@defillama/sdk'); + +const BASE_URL = 'https://api.interport.fi'; +const STABLECOIN_URL = 'https://app.interport.fi/stablecoin-pools'; + +const CHAINS = { + 1: 'Ethereum', + 250: 'Fantom', + 81457: 'Blast', + 59144: 'Linea', + 169: 'Manta', + // 2525: 'inEVM', +}; + +const ITP_ADDRESS = '0x2b1D36f5B61AdDAf7DA7ebbd11B35FD8cfb0DE31'; +const STABLE_ADDRESS = '0x29d44c17f4f83b3c77ae2eac4bc1468a496e3196'; +const PROJECT_NAME = 'interport-finance'; + +const STABLECOIN_FARM_TYPE_LIST = { + 250: { + '0xb6AB8EeFAE1a2c22Ca6338E143cb7dE544800c6e': 0, + }, + 1: { + '0xEc8DDCb498b44C35EFaD7e5e43E0Caf6D16A66E8': 0, + '0x5b45B414c6CD2a3341bE70Ba22BE786b0124003F': 1, + }, + 81457: { + '0x5b45B414c6CD2a3341bE70Ba22BE786b0124003F': 0, + }, + 59144: { + '0xEc8DDCb498b44C35EFaD7e5e43E0Caf6D16A66E8': 0, + '0x5b45B414c6CD2a3341bE70Ba22BE786b0124003F': 1, + }, + 169: { + '0xEc8DDCb498b44C35EFaD7e5e43E0Caf6D16A66E8': 0, + '0x5b45B414c6CD2a3341bE70Ba22BE786b0124003F': 1, + }, + // 2525: { + // '0xEc8DDCb498b44C35EFaD7e5e43E0Caf6D16A66E8': 0, + // '0x5b45B414c6CD2a3341bE70Ba22BE786b0124003F': 1, + // }, +}; + +const formatNumber = (n, decimals) => { + return n / 10 ** decimals; +}; + +const getAPY = async () => { + const promises = Object.keys(STABLECOIN_FARM_TYPE_LIST).map((chainId) => { + return Object.keys(STABLECOIN_FARM_TYPE_LIST[chainId]).map((address) => { + return getData({ + chainId: Number(chainId), + address, + }); + }); + }); + + return await Promise.all(promises.flat()); +}; + +const getData = async ({ chainId, address }) => { + const calls = []; + const chain = CHAINS[chainId].toLowerCase(); + + const symbol = await sdk.api.abi.call({ + target: address, + abi: erc20Abi.find(({ name }) => name === 'symbol'), + chain, + }); + + const decimals = await sdk.api.abi.call({ + target: address, + abi: erc20Abi.find(({ name }) => name === 'decimals'), + chain, + }); + + calls.push( + sdk.api.abi.call({ + target: address, + abi: abi.find(({ name }) => name === 'balanceOf'), + params: [STABLE_ADDRESS], + chain, + }) + ); + + calls.push( + sdk.api.abi.call({ + target: STABLE_ADDRESS, + abi: stableAbi.find(({ name }) => name === 'rewardTokenPerSecond'), + chain, + }) + ); + + calls.push( + sdk.api.abi.call({ + target: STABLE_ADDRESS, + abi: stableAbi.find(({ name }) => name === 'totalAllocationPoint'), + chain, + }) + ); + + calls.push( + sdk.api.abi.call({ + target: STABLE_ADDRESS, + abi: stableAbi.find(({ name }) => name === 'poolInfo'), + params: [STABLECOIN_FARM_TYPE_LIST[chainId][address]], + chain, + }) + ); + + const [ + tvlResponse, + itpPerSecondResponse, + totalAllocationPointResponse, + poolInfoResponse, + ] = await Promise.all(calls); + + const tvl = formatNumber(tvlResponse.output, decimals.output); + + const { data } = await axios.get( + `${BASE_URL}/utils/get-interport-token-info` + ); + const itpPrice = data.price; + const itpPerSecond = itpPerSecondResponse.output / 1e18; + const itpPerYear = itpPerSecond * 60 * 60 * 24 * 365; + + const totalAllocationPoint = Number(totalAllocationPointResponse.output); + const { + stakingToken, + stakingTokenTotalAmount, + accumulatedRewardTokenPerShare, + lastRewardTime, + allocationPoint, + } = poolInfoResponse.output; + + const totalInUSD = formatNumber(stakingTokenTotalAmount, decimals.output); + const totalUSDPerPeriod = + ((itpPerYear * itpPrice) / totalAllocationPoint) * Number(allocationPoint); + + const apr = (totalUSDPerPeriod * 100) / totalInUSD; + + return { + chain: CHAINS[chainId], + project: PROJECT_NAME, + pool: `${chainId}-${address}`, + symbol: symbol.output.replace('i', ''), + apyBase: Number(apr), + tvlUsd: Number(tvl), + }; +}; + +module.exports = { + apy: getAPY, + url: STABLECOIN_URL, +}; diff --git a/src/adaptors/inverse-finance-firm/ERC4626.json b/src/adaptors/inverse-finance-firm/ERC4626.json new file mode 100644 index 0000000000..90dcd58ec3 --- /dev/null +++ b/src/adaptors/inverse-finance-firm/ERC4626.json @@ -0,0 +1,461 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_spender", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [{ "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "_owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "name": "balance", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "_to", "type": "address" }, + { "name": "_value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "_owner", "type": "address" }, + { "name": "_spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "owner", "type": "address" }, + { "indexed": true, "name": "spender", "type": "address" }, + { "indexed": false, "name": "value", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "from", "type": "address" }, + { "indexed": true, "name": "to", "type": "address" }, + { "indexed": false, "name": "value", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "name": "asset", + "type": "function", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "name": "assetTokenAddress", + "type": "address" + } + ] + }, + { + "name": "totalAssets", + "type": "function", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "name": "totalManagedAssets", + "type": "uint256" + } + ] + }, + { + "name": "convertToShares", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "convertToAssets", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "maxDeposit", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxAssets", + "type": "uint256" + } + ] + }, + { + "name": "previewDeposit", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "deposit", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "assets", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "maxMint", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxShares", + "type": "uint256" + } + ] + }, + { + "name": "previewMint", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "mint", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "shares", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "maxWithdraw", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxAssets", + "type": "uint256" + } + ] + }, + { + "name": "previewWithdraw", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "assets", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "withdraw", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "assets", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + }, + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "shares", + "type": "uint256" + } + ] + }, + { + "name": "maxRedeem", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "maxShares", + "type": "uint256" + } + ] + }, + { + "name": "previewRedeem", + "type": "function", + "stateMutability": "view", + "inputs": [ + { + "name": "shares", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "redeem", + "type": "function", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "shares", + "type": "uint256" + }, + { + "name": "receiver", + "type": "address" + }, + { + "name": "owner", + "type": "address" + } + ], + "outputs": [ + { + "name": "assets", + "type": "uint256" + } + ] + }, + { + "name": "Deposit", + "type": "event", + "inputs": [ + { + "name": "_caller", + "indexed": true, + "type": "address" + }, + { + "name": "owner", + "indexed": true, + "type": "address" + }, + { + "name": "assets", + "indexed": false, + "type": "uint256" + }, + { + "name": "shares", + "indexed": false, + "type": "uint256" + } + ] + }, + { + "name": "Withdraw", + "type": "event", + "inputs": [ + { + "name": "_caller", + "indexed": true, + "type": "address" + }, + { + "name": "receiver", + "indexed": true, + "type": "address" + }, + { + "name": "owner", + "indexed": true, + "type": "address" + }, + { + "name": "assets", + "indexed": false, + "type": "uint256" + }, + { + "name": "shares", + "indexed": false, + "type": "uint256" + } + ] + } + ] + \ No newline at end of file diff --git a/src/adaptors/inverse-finance-firm/abi.ts b/src/adaptors/inverse-finance-firm/abi.ts new file mode 100644 index 0000000000..fc3658a21c --- /dev/null +++ b/src/adaptors/inverse-finance-firm/abi.ts @@ -0,0 +1,81 @@ +module.exports = { + "balance": { + "inputs": [ + ], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalDebt": { + "inputs": [ + ], + "name": "totalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "collateralFactorBps": { + "inputs": [ + ], + "name": "collateralFactorBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "borrowPaused": { + "inputs": [ + ], + "name": "borrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + "collateral": { + "inputs": [ + ], + "name": "collateral", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "market": [ + "function totalDebt() public view returns (uint)", + "event CreateEscrow(address indexed user, address escrow)", + ], + "dbr": [ + "event AddMarket(address indexed market)" + ], + "weeklyRevenue": {"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"weeklyRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}, + "getMarketPrice": {"inputs":[{"internalType":"address","name":"market","type":"address"}],"name":"getMarketPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}, +} \ No newline at end of file diff --git a/src/adaptors/inverse-finance-firm/index.js b/src/adaptors/inverse-finance-firm/index.js new file mode 100644 index 0000000000..0024eca466 --- /dev/null +++ b/src/adaptors/inverse-finance-firm/index.js @@ -0,0 +1,353 @@ +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); +const abi = require('./abi'); +const path = require('path'); +const ERC4626abi = require('./ERC4626.json'); + +require('dotenv').config({ + path: path.resolve(__dirname, '../../../config.env'), +}); + +const firmStart = 16159015; +const DBR = '0xAD038Eb671c44b853887A7E32528FaB35dC5D710'; +const DOLA = '0x865377367054516e17014CcdED1e7d814EDC9ce4'; +const INV = '0x41D5D79431A913C4aE7d69a668ecdfE5fF9DFB68'; +const SINV_ADDRESS = '0x08d23468A467d2bb86FaE0e32F247A26C7E2e994'; +const SDOLA_ADDRESS = '0xb45ad160634c528Cc3D2926d9807104FA3157305'; +const TOKENS_VIEWER = '0x826bBeB1DBd9aA36CD44538CC45Dcf9E93BDA574'; +const FIRM_VIEWER = '0x545C963eB523199969cf0298395EeAdcE514b691'; +const ONE_DAY_MS = 86400000; +const WEEKS_PER_YEAR = 365 / 7; + +const provider = new ethers.providers.JsonRpcProvider( + process.env.ALCHEMY_CONNECTION_ETHEREUM +); + +const getWeekIndexUtc = (ts) => { + const d = ts ? new Date(ts) : new Date(); + const weekFloat = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0) / (ONE_DAY_MS * 7); + return Math.floor(weekFloat); +} + +const aprToApy = (apr, compoundingsPerYear) => + !compoundingsPerYear ? apr : (Math.pow(1 + (apr / 100) / compoundingsPerYear, compoundingsPerYear) - 1) * 100; + +const l1TokenPrices = async (l1TokenAddrs) => { + const l1TokenQuery = l1TokenAddrs.map((addr) => `ethereum:${addr}`).join(); + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${l1TokenQuery}` + ); + + return Object.fromEntries( + l1TokenAddrs.map((addr) => { + const coinData = data.coins[`ethereum:${addr}`]; + if (coinData) { + const { decimals, price, symbol } = coinData; + return [addr, { price, decimals, symbol }]; + } else { + return [addr, { price: null, decimals: null, symbol: null }]; + } + }) + ); +}; + +const getFirmMarkets = async (dbrContract) => { + const logs = await dbrContract.queryFilter(dbrContract.filters.AddMarket()); + return logs.map((l) => l.args.market); +}; + +const getFirmEscrowsWithMarket = async (markets, provider) => { + const escrowCreations = await Promise.all( + markets.map((m) => { + const market = new ethers.Contract(m, abi.market, provider); + return market.queryFilter(market.filters.CreateEscrow(), firmStart); + }) + ); + + const escrowsWithMarkets = escrowCreations + .map((marketEscrows, marketIndex) => { + const market = markets[marketIndex]; + return marketEscrows.map((escrowCreationEvent) => { + return { escrow: escrowCreationEvent.args[1], market }; + }); + }) + .flat(); + + return escrowsWithMarkets; +}; + + +const main = async () => { + const balances = {}; + + const dbrContract = new ethers.Contract(DBR, abi.dbr, provider); + const markets = await getFirmMarkets(dbrContract); + + const escrowsWithMarkets = await getFirmEscrowsWithMarket(markets, provider); + + const allBalances = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: escrowsWithMarkets.map((em) => ({ + target: em.escrow, + params: [], + })), + abi: abi.balance, + }) + ).output; + + const allUnderlying = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: m, + params: [], + })), + abi: abi.collateral, + }) + ).output; + + const underlyings = allUnderlying.map((u) => u.output); + const addressesToPrice = underlyings.concat([DBR, DOLA, INV]); + const prices = await l1TokenPrices(addressesToPrice); + + const allDebt = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: m, + params: [], + })), + abi: abi.totalDebt, + }) + ).output; + + const allSymbols = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: underlyings.map((m) => ({ + target: m, + params: [], + })), + abi: 'string:symbol', + }) + ).output; + + const allDecimals = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: underlyings.map((m) => ({ + target: m, + params: [], + })), + abi: 'uint:decimals', + }) + ).output; + + const allPrices = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: FIRM_VIEWER, + params: [m], + })), + abi: abi.getMarketPrice, + permitFailure: true, + }) + ).output; + + const allCfs = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: m, + params: [], + })), + abi: abi.collateralFactorBps, + }) + ).output; + + const allBorrowPaused = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: m, + params: [], + })), + abi: abi.borrowPaused, + }) + ).output; + + const allLiquidity = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + calls: markets.map((m) => ({ + target: DOLA, + params: [m], + })), + abi: 'erc20:balanceOf', + }) + ).output; + + allBalances.map((b, i) => { + const market = escrowsWithMarkets[i].market; + if (!balances[market]) { + balances[market] = BigNumber(0); + } + balances[market] = balances[market].plus(b.output); + }); + + // the current fixed borrow rate is always directly related to DBR's current price + // (1 DBR allows to borrow 1 DOLA for one year) + const currentFixedRate = prices[DBR].price * 100; + + const pools = markets.map((m, marketIndex) => { + const underlying = allUnderlying.find((u) => u.input.target === m).output; + const decimals = Number(allDecimals[marketIndex].output); + const symbol = allSymbols[marketIndex].output; + // use oracle price as fallback for exotic collaterals such as pendle collaterals + const price = prices[underlying].price || (Number(allPrices[marketIndex].output)/1e18); + const totalSupplyUsd = + (Number(balances[m]) / 10 ** decimals) * price; + const totalBorrowUsd = Number(allDebt[marketIndex].output) / 1e18; + const debtCeilingUsd = + (Number(allLiquidity[marketIndex].output) / 1e18) * prices[DOLA].price; + return { + pool: `firm-${m}`, + chain: 'Ethereum', + project: 'inverse-finance-firm', + mintedCoin: 'DOLA', + symbol, + tvlUsd: totalSupplyUsd, + apyBase: 0, + underlyingTokens: [underlying], + poolMeta: 'Fixed Borrow Rate', + url: 'https://inverse.finance/firm', + apyBaseBorrow: currentFixedRate, + debtCeilingUsd: debtCeilingUsd + totalBorrowUsd, + totalSupplyUsd, + totalBorrowUsd, + borrowable: !allBorrowPaused[marketIndex].output, + ltv: Number(allCfs[marketIndex].output) / 1e4, + }; + }); + + const weekIndex = getWeekIndexUtc(); + // sDOLA + const sdolaData = ( + await Promise.all([ + sdk.api.abi.multiCall( + { + chain: 'ethereum', + calls: [ + { + target: SDOLA_ADDRESS, + params: [], + }, + ], + abi: 'uint:totalAssets', + } + ), + sdk.api.abi.multiCall( + { + chain: 'ethereum', + calls: [ + { + target: SDOLA_ADDRESS, + params: [weekIndex - 1], + }, + ], + abi: abi.weeklyRevenue, + } + ), + ]) + ); + + const sDolaTotalAssets = Number(sdolaData[0].output[0].output) / 1e18; + const sDolaPastWeekRevenue = Number(sdolaData[1].output[0].output) / 1e18; + const sDOLAapr = sDolaTotalAssets > 0 ? (sDolaPastWeekRevenue * WEEKS_PER_YEAR) / sDolaTotalAssets * 100 : 0; + + // add sDOLA + pools.push({ + pool: `sDOLA`, + chain: 'Ethereum', + project: 'inverse-finance-firm', + mintedCoin: 'sDOLA', + symbol: 'sDOLA', + tvlUsd: sDolaTotalAssets * prices[DOLA].price, + apyBase: aprToApy(sDOLAapr, WEEKS_PER_YEAR), + underlyingTokens: [DOLA], + poolMeta: 'Yield-Bearing stable', + url: 'https://inverse.finance/sDOLA', + }); + + // sINV + const sinvData = ( + await Promise.all([ + sdk.api.abi.multiCall( + { + chain: 'ethereum', + calls: [ + { + target: SINV_ADDRESS, + params: [], + }, + ], + abi: 'uint:totalAssets', + } + ), + sdk.api.abi.multiCall( + { + chain: 'ethereum', + calls: [ + { + target: SINV_ADDRESS, + params: [], + }, + ], + abi: 'uint:lastPeriodRevenue', + } + ), + sdk.api.abi.multiCall( + { + chain: 'ethereum', + calls: [ + { + target: TOKENS_VIEWER, + params: [], + }, + ], + abi: 'uint:getDbrApr', + } + ), + ]) + ); + + const sInvTotalAssets = Number(sinvData[0].output[0].output) / 1e18; + const sinvPastWeekRevenue = Number(sinvData[1].output[0].output) / 1e18; + const sINVapr = sDolaTotalAssets > 0 ? (sinvPastWeekRevenue * WEEKS_PER_YEAR) / sInvTotalAssets * 100 : 0; + const dbrApr = Number(sinvData[2].output[0].output) / 1e18; + + // add sINV + pools.push({ + pool: `sINV`, + chain: 'Ethereum', + project: 'inverse-finance-firm', + mintedCoin: 'sINV', + symbol: 'sINV', + tvlUsd: sInvTotalAssets * prices[INV].price, + apyBase: aprToApy(sINVapr, WEEKS_PER_YEAR), + underlyingTokens: [INV], + url: 'https://inverse.finance/sINV', + }); + + return utils.removeDuplicates(pools.filter((p) => utils.keepFinite(p))); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/iolend/abiChefIncentivesController.js b/src/adaptors/iolend/abiChefIncentivesController.js new file mode 100644 index 0000000000..c89a8ce1a7 --- /dev/null +++ b/src/adaptors/iolend/abiChefIncentivesController.js @@ -0,0 +1,1243 @@ +module.exports = [ + { + inputs: [], + name: 'AddressZero', + type: 'error', + }, + { + inputs: [], + name: 'AlreadyStarted', + type: 'error', + }, + { + inputs: [], + name: 'ArrayLengthMismatch', + type: 'error', + }, + { + inputs: [], + name: 'AuthorizationAlreadySet', + type: 'error', + }, + { + inputs: [], + name: 'BountyOnly', + type: 'error', + }, + { + inputs: [], + name: 'CadenceTooLong', + type: 'error', + }, + { + inputs: [], + name: 'DuplicateSchedule', + type: 'error', + }, + { + inputs: [], + name: 'ExceedsMaxInt', + type: 'error', + }, + { + inputs: [], + name: 'InsufficientPermission', + type: 'error', + }, + { + inputs: [], + name: 'InvalidRToken', + type: 'error', + }, + { + inputs: [], + name: 'InvalidStart', + type: 'error', + }, + { + inputs: [], + name: 'NotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'NotAscending', + type: 'error', + }, + { + inputs: [], + name: 'NotEligible', + type: 'error', + }, + { + inputs: [], + name: 'NotMFD', + type: 'error', + }, + { + inputs: [], + name: 'NotRTokenOrMfd', + type: 'error', + }, + { + inputs: [], + name: 'NothingToVest', + type: 'error', + }, + { + inputs: [], + name: 'OutOfRewards', + type: 'error', + }, + { + inputs: [], + name: 'PoolExists', + type: 'error', + }, + { + inputs: [], + name: 'UnknownPool', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: '_authorized', + type: 'bool', + }, + ], + name: 'AuthorizedContractUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + ], + name: 'BalanceUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address[]', + name: '_tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: '_allocPoints', + type: 'uint256[]', + }, + ], + name: 'BatchAllocPointsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_bountyManager', + type: 'address', + }, + ], + name: 'BountyManagerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + ], + name: 'ChefReserveLow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'Disqualified', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bool', + name: '_newVal', + type: 'bool', + }, + ], + name: 'EligibilityEnabledUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256[]', + name: 'startTimeOffsets', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'rewardsPerSeconds', + type: 'uint256[]', + }, + ], + name: 'EmissionScheduleAppended', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: '_lapse', + type: 'uint256', + }, + ], + name: 'EndingTimeUpdateCadence', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_token', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IOnwardIncentivesController', + name: '_incentives', + type: 'address', + }, + ], + name: 'OnwardIncentivesUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Recovered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'RewardDeposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'rewardsPerSecond', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'persist', + type: 'bool', + }, + ], + name: 'RewardsPerSecondUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [], + name: 'accountedRewards', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'uint256', + name: '_allocPoint', + type: 'uint256', + }, + ], + name: 'addPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'afterLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'allPendingRewards', + outputs: [ + { + internalType: 'uint256', + name: 'pending', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'authorizedContracts', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_tokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '_allocPoints', + type: 'uint256[]', + }, + ], + name: 'batchUpdateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'beforeLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bountyManager', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'address[]', + name: '_tokens', + type: 'address[]', + }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'claimAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'bool', + name: '_execute', + type: 'bool', + }, + ], + name: 'claimBounty', + outputs: [ + { + internalType: 'bool', + name: 'issueBaseBounty', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositedRewards', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibilityEnabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'eligibilityExempt', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibleDataProvider', + outputs: [ + { + internalType: 'contract IEligibilityDataProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'emissionSchedule', + outputs: [ + { + internalType: 'uint128', + name: 'startTimeOffset', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rewardsPerSecond', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emissionScheduleIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'endRewardTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'endingTime', + outputs: [ + { + internalType: 'uint256', + name: 'estimatedTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdatedTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updateCadence', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_totalSupply', + type: 'uint256', + }, + ], + name: 'handleActionAfter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'handleActionBefore', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_poolConfigurator', + type: 'address', + }, + { + internalType: 'contract IEligibilityDataProvider', + name: '_eligibleDataProvider', + type: 'address', + }, + { + internalType: 'contract IMiddleFeeDistribution', + name: '_rewardMinter', + type: 'address', + }, + { + internalType: 'uint256', + name: '_rewardsPerSecond', + type: 'uint256', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAllPoolUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastRPS', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'address[]', + name: '_tokens', + type: 'address[]', + }, + ], + name: 'pendingRewards', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'persistRewardsPerSecond', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolConfigurator', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'poolInfo', + outputs: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + { + internalType: 'contract IOnwardIncentivesController', + name: 'onwardIncentives', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'tokenAmount', + type: 'uint256', + }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'registerRewardDeposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'registeredTokens', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardMinter', + outputs: [ + { + internalType: 'contract IMiddleFeeDistribution', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsPerSecond', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_bountyManager', + type: 'address', + }, + ], + name: 'setBountyManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_address', + type: 'address', + }, + { + internalType: 'bool', + name: '_authorize', + type: 'bool', + }, + ], + name: 'setContractAuthorization', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: '_newVal', + type: 'bool', + }, + ], + name: 'setEligibilityEnabled', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_contract', + type: 'address', + }, + { + internalType: 'bool', + name: '_value', + type: 'bool', + }, + ], + name: 'setEligibilityExempt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: '_startTimeOffsets', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_rewardsPerSecond', + type: 'uint256[]', + }, + ], + name: 'setEmissionSchedule', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_lapse', + type: 'uint256', + }, + ], + name: 'setEndingTimeUpdateCadence', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'contract IOnwardIncentivesController', + name: '_incentives', + type: 'address', + }, + ], + name: 'setOnwardIncentives', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_rewardsPerSecond', + type: 'uint256', + }, + { + internalType: 'bool', + name: '_persist', + type: 'bool', + }, + ], + name: 'setRewardsPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'start', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'userBaseClaimable', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'userInfo', + outputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'enterTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastClaimTime', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/iolend/abiLendingPool.js b/src/adaptors/iolend/abiLendingPool.js new file mode 100644 index 0000000000..6e52ba71bf --- /dev/null +++ b/src/adaptors/iolend/abiLendingPool.js @@ -0,0 +1,1163 @@ +module.exports = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { + anonymous: false, + inputs: [], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'interestRateMode', + type: 'uint256', + }, + { + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + { + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'delegatee', + type: 'address', + }, + ], + name: 'delegateWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balanceFromBefore', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balanceToBefore', + type: 'uint256', + }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiverAddress', + type: 'address', + }, + { + internalType: 'address[]', + name: 'assets', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'amounts', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'modes', + type: 'uint256[]', + }, + { + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + internalType: 'bytes', + name: 'params', + type: 'bytes', + }, + { + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getConfiguration', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'data', + type: 'uint256', + }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'data', + type: 'uint256', + }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'liquidityIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { + internalType: 'uint8', + name: 'id', + type: 'uint8', + }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveNormalizedIncome', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveNormalizedVariableDebt', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserAccountData', + outputs: [ + { + internalType: 'uint256', + name: 'totalCollateralETH', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalDebtETH', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'availableBorrowsETH', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ltv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'healthFactor', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'data', + type: 'uint256', + }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'stableDebtAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + { + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + ], + name: 'repay', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'configuration', + type: 'uint256', + }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'val', + type: 'bool', + }, + ], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'rateStrategyAddress', + type: 'address', + }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'bool', + name: 'useAsCollateral', + type: 'bool', + }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'delegatee', + type: 'address', + }, + ], + name: 'undelegateWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'withdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + ], + name: 'withdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'withdrawDelegatesOf', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/iolend/abiPriceProvider.js b/src/adaptors/iolend/abiPriceProvider.js new file mode 100644 index 0000000000..a6c87efcf9 --- /dev/null +++ b/src/adaptors/iolend/abiPriceProvider.js @@ -0,0 +1,232 @@ +module.exports = [ + { + inputs: [], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'getLpTokenPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getLpTokenPriceUsd', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTokenPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTokenPriceUsd', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IOracle', + name: '_lpOracle', + type: 'address', + }, + { + internalType: 'contract IOracle', + name: '_rtOracle', + type: 'address', + }, + { + internalType: 'contract IChainlinkAdapter', + name: '_wethOracle', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lpOracle', + outputs: [ + { + internalType: 'contract IOracle', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rtOracle', + outputs: [ + { + internalType: 'contract IOracle', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IOracle', + name: '_lpOracle', + type: 'address', + }, + ], + name: 'setLpOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IOracle', + name: '_rtOracle', + type: 'address', + }, + ], + name: 'setRtOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IChainlinkAdapter', + name: '_wethOracle', + type: 'address', + }, + ], + name: 'setWethOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'update', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'wethOracle', + outputs: [ + { + internalType: 'contract IChainlinkAdapter', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/iolend/abiProtocolDataProvider.js b/src/adaptors/iolend/abiProtocolDataProvider.js new file mode 100644 index 0000000000..e98d033060 --- /dev/null +++ b/src/adaptors/iolend/abiProtocolDataProvider.js @@ -0,0 +1,297 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveConfigurationData', + outputs: [ + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ltv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowingEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'stableBorrowRateEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getReserveTokensAddresses', + outputs: [ + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'principalStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'scaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'stableRateLastUpdated', + type: 'uint40', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/iolend/index.js b/src/adaptors/iolend/index.js new file mode 100644 index 0000000000..af7855a51c --- /dev/null +++ b/src/adaptors/iolend/index.js @@ -0,0 +1,214 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiChefIncentivesController = require('./abiChefIncentivesController'); +const abiPriceProvider = require('./abiPriceProvider'); +const { format } = require('date-fns'); +const { formatUnits } = require('ethers/lib/utils'); + +const chains = { + iotaevm: { + RewardToken: '0xF5755e48B6F2F06F8ea904bdA26177CB3ca06Ff0', + LendingPool: '0xb51d18e6D14beD6C3af796201A6f2DcEbBE7BfEE', + ProtocolDataProvider: '0x779a294CF4D200936881c4c8d0771b8a1935fB5B', + AddressesProvider: '0x3893e30500d13990b36C9b2A05FE210A204a2F9a', + ChefIncentivesController: '0xE7a2ad04066D1c634BCA379fad32832D3B1475f1', + PriceProvider: '0x427E373B0882E534ddcC71C30dd8cc83aF83b568', + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain, + }) + ).output; + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const rewardsPerSecond = ( + await sdk.api.abi.call({ + target: addresses.ChefIncentivesController, + abi: abiChefIncentivesController.find( + (m) => m.name === 'rewardsPerSecond' + ), + chain, + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abiChefIncentivesController.find( + (n) => n.name === 'totalAllocPoint' + ), + target: addresses.ChefIncentivesController, + chain, + }) + ).output; + + const poolInfoInterest = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentivesController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: addresses.ChefIncentivesController, + params: reserveData[i].aTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const poolInfoDebt = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentivesController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: addresses.ChefIncentivesController, + params: reserveData[i].variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const rewardTokenPriceUsd = ( + await sdk.api.abi.call({ + target: addresses.PriceProvider, + abi: abiPriceProvider.find((n) => n.name === 'getTokenPriceUsd'), + chain, + }) + ).output; + + const rewardTokenPriceDecimals = ( + await sdk.api.abi.call({ + target: addresses.PriceProvider, + abi: abiPriceProvider.find((n) => n.name === 'decimals'), + chain, + }) + ).output; + + const rewardTokenPrice = formatUnits( + rewardTokenPriceUsd, + rewardTokenPriceDecimals + ); + + const pricesArray = reservesList.map((t) => `${chain}:${t}`); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const rewardPerYear = + (rewardsPerSecond / 1e18) * 86400 * 365 * rewardTokenPrice; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${chain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const apyReward = + (((poolInfoInterest[i].allocPoint / totalAllocPoint) * + rewardPerYear) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((poolInfoDebt[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalBorrowUsd) * + 100; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + https: return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + chain, + project: 'iolend', + symbol: symbols[i], + tvlUsd, + apyBase, + apyReward: apyReward, + rewardTokens: [chains[chain].RewardToken], + underlyingTokens: [t], + poolMeta: frozen ? 'frozen' : null, + url: `https://www.iolend.fi/reserve-overview/${t}-${t}${chains[chain].AddressesProvider}`.toLowerCase(), + // optional lending protocol specific fields: + apyBaseBorrow, + apyRewardBorrow: apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + borrowable, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/ion-protocol/index.js b/src/adaptors/ion-protocol/index.js new file mode 100644 index 0000000000..bcbe7b0ae7 --- /dev/null +++ b/src/adaptors/ion-protocol/index.js @@ -0,0 +1,99 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const ionAbi = { + usd: 'int256:latestAnswer', + debt: 'function debt(address pool) external view returns (uint256)', + lenderExchangeRate: 'uint256:stEthPerToken', + totalSupply: 'uint256:totalSupply', + marketBorrowRate: + 'function getCurrentBorrowRate(uint8 ilkIndex) external view returns (uint256 borrowRate, uint256 reserveFactor)', +}; + +const apy = async () => { + const markets = await utils.getData( + 'https://ion-backend.vercel.app/v1/bigbrother/markets' + ); + + const usdExchangeRate = + ( + await sdk.api.abi.call({ + target: '0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8', // chainlink stEth/USD + abi: ionAbi.usd, + chain: 'ethereum', + }) + ).output / 1e8; + + const debt = ( + await sdk.api.abi.multiCall({ + calls: markets.map((i) => ({ + target: i.ionLens, + params: i.ionPool, + })), + abi: ionAbi.debt, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: markets.map((i) => ({ + target: i.ionPool, + })), + abi: ionAbi.totalSupply, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const lenderAssetExchangeRate = ( + await sdk.api.abi.multiCall({ + calls: markets.map((i) => ({ + target: i.lenderAssetAddress, + })), + abi: ionAbi.lenderExchangeRate, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const borrowRate = ( + await sdk.api.abi.multiCall({ + calls: markets.map((i) => ({ + target: i.ionPool, + params: 0, + })), + abi: ionAbi.marketBorrowRate, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const pools = markets.map((market, i) => { + const totalSupplyUsd = + (totalSupply[i] / 1e18) * + (lenderAssetExchangeRate[i] / 1e18) * + usdExchangeRate; + const totalBorrowUsd = + (debt[i] / 1e45) * (lenderAssetExchangeRate[i] / 1e18) * usdExchangeRate; + const ltv = debt[i] / 1e45 / (totalSupply[i] / 1e18); + const borrowRateYearly = (borrowRate[i].borrowRate / 1e27) ** 31536000; + const marketApy = (borrowRateYearly - 1) * ltv * 100; + + return { + pool: market.ionPool, + chain: 'ethereum', + project: 'ion-protocol', + symbol: market.collateralAssetName + '-' + market.lenderAssetName, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: marketApy, + underlyingTokens: [market.lenderAssetAddress], + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + ltv: ltv, + }; + }); + return pools; +}; + +module.exports = { + apy, + url: 'https://www.app.ionprotocol.io/', +}; diff --git a/src/adaptors/ionic-protocol/abiCore.json b/src/adaptors/ionic-protocol/abiCore.json new file mode 100644 index 0000000000..4e29d345a2 --- /dev/null +++ b/src/adaptors/ionic-protocol/abiCore.json @@ -0,0 +1,1488 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "rewardsDistributor", + "type": "address" + } + ], + "name": "AddedRewardsDistributor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract BasePriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract BasePriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "enforce", + "type": "bool" + } + ], + "name": "WhitelistEnforcementChanged", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "distributor", + "type": "address" + } + ], + "name": "_addRewardsDistributor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_afterNonReentrant", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_becomeImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_beforeNonReentrant", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "delegateType", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "constructorData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "becomeImplData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_deployMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_getExtensionFunctions", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract BasePriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "enforce", + "type": "bool" + } + ], + "name": "_setWhitelistEnforcement", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "suppliers", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "statuses", + "type": "bool[]" + } + ], + "name": "_setWhitelistStatuses", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract ICErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adminHasRights", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allBorrowers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract ICErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCapForCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "accountBorrowsNew", + "type": "uint256" + } + ], + "name": "borrowWithinLimits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowingAgainstCollateralBlacklist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "cTokensByUnderlying", + "outputs": [ + { + "internalType": "contract ICErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "enforceWhitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract ICErc20[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract ICErc20", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "bool", + "name": "isBorrow", + "type": "bool" + } + ], + "name": "getMaxRedeemOrBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionicAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionicAdminHasRights", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICErc20", + "name": "cToken", + "type": "address" + } + ], + "name": "isDeprecated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "nonAccruingRewardsDistributors", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract BasePriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardsDistributors", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "suppliers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "whitelistArray", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/ionic-protocol/abiFlyWheel.json b/src/adaptors/ionic-protocol/abiFlyWheel.json new file mode 100644 index 0000000000..49dac31c63 --- /dev/null +++ b/src/adaptors/ionic-protocol/abiFlyWheel.json @@ -0,0 +1,554 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsIndex", + "type": "uint256" + } + ], + "name": "AccrueRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newStrategy", + "type": "address" + } + ], + "name": "AddStrategy", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newBooster", + "type": "address" + } + ], + "name": "FlywheelBoosterUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newFlywheelRewards", + "type": "address" + } + ], + "name": "FlywheelRewardsUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "NewOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPendingOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "NewPendingOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPerformanceFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPerformanceFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "oldFeeRecipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newFeeRecipient", + "type": "address" + } + ], + "name": "UpdatedFeeSettings", + "type": "event" + }, + { + "inputs": [], + "name": "_acceptOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "_setPendingOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "accrue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "address", "name": "secondUser", "type": "address" } + ], + "name": "accrue", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + } + ], + "name": "addMarketForRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + } + ], + "name": "addStrategyForRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allStrategies", + "outputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "compAccrued", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeRecipient", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "flywheelBooster", + "outputs": [ + { + "internalType": "contract IFlywheelBooster", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "flywheelPreBorrowerAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "address", "name": "supplier", "type": "address" } + ], + "name": "flywheelPreSupplierAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" } + ], + "name": "flywheelPreTransferAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "flywheelRewards", + "outputs": [ + { + "internalType": "contract IFlywheelRewards", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllStrategies", + "outputs": [ + { "internalType": "contract ERC20[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "contract IFlywheelRewards", + "name": "_flywheelRewards", + "type": "address" + }, + { + "internalType": "contract IFlywheelBooster", + "name": "_flywheelBooster", + "type": "address" + }, + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isFlywheel", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isRewardsDistributor", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + } + ], + "name": "marketState", + "outputs": [ + { "internalType": "uint224", "name": "", "type": "uint224" }, + { "internalType": "uint32", "name": "", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "performanceFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "rewardsAccrued", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFlywheelBooster", + "name": "newBooster", + "type": "address" + } + ], + "name": "setBooster", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFlywheelRewards", + "name": "newFlywheelRewards", + "type": "address" + } + ], + "name": "setFlywheelRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + } + ], + "name": "strategyState", + "outputs": [ + { "internalType": "uint224", "name": "index", "type": "uint224" }, + { + "internalType": "uint32", + "name": "lastUpdatedTimestamp", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_performanceFee", + "type": "uint256" + }, + { "internalType": "address", "name": "_feeRecipient", "type": "address" } + ], + "name": "updateFeeSettings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "strategy", + "type": "address" + }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "userIndex", + "outputs": [{ "internalType": "uint224", "name": "", "type": "uint224" }], + "stateMutability": "nonpayable", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/ionic-protocol/abiLToken.json b/src/adaptors/ionic-protocol/abiLToken.json new file mode 100644 index 0000000000..71b3950641 --- /dev/null +++ b/src/adaptors/ionic-protocol/abiLToken.json @@ -0,0 +1,958 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAdminFeeMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAdminFeeMantissa", + "type": "uint256" + } + ], + "name": "NewAdminFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldIonicFeeMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newIonicFeeMantissa", + "type": "uint256" + } + ], + "name": "NewIonicFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "_becomeImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_getExtensionFunctions", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "_withdrawAdminFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "_withdrawIonicFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adminFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract IonicComptroller", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "contractType", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "delegateType", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "feeSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionicAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionicFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "selfTransferIn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "selfTransferOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAdminFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalIonicFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/ionic-protocol/abiRateModelSlope.json b/src/adaptors/ionic-protocol/abiRateModelSlope.json new file mode 100644 index 0000000000..667f784293 --- /dev/null +++ b/src/adaptors/ionic-protocol/abiRateModelSlope.json @@ -0,0 +1,234 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_blocksPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "jumpMultiplierPerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kink_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "baseRatePerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "jumpMultiplierPerBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "kink", + "type": "uint256" + } + ], + "name": "NewInterestParams", + "type": "event" + }, + { + "inputs": [], + "name": "baseRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blocksPerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "getBorrowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa", + "type": "uint256" + } + ], + "name": "getSupplyRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInterestRateModel", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "jumpMultiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "kink", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "multiplierPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "cash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserves", + "type": "uint256" + } + ], + "name": "utilizationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } +] diff --git a/src/adaptors/ionic-protocol/abiRewardContract.json b/src/adaptors/ionic-protocol/abiRewardContract.json new file mode 100644 index 0000000000..7bd4c33a38 --- /dev/null +++ b/src/adaptors/ionic-protocol/abiRewardContract.json @@ -0,0 +1,475 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_fpd", + "internalType": "contract PoolDirectory", + "type": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + } + ], + "name": "claimAllRewardTokens", + "outputs": [ + { + "name": "", + "internalType": "address[]", + "type": "address[]" + }, + { + "name": "", + "internalType": "uint256[]", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "market", + "internalType": "contract ERC20", + "type": "address" + }, + { + "name": "flywheels", + "internalType": "contract IonicFlywheelCore[]", + "type": "address[]" + }, + { + "name": "accrue", + "internalType": "bool[]", + "type": "bool[]" + } + ], + "name": "claimRewardsForMarket", + "outputs": [ + { + "name": "", + "internalType": "contract IonicFlywheelCore[]", + "type": "address[]" + }, + { + "name": "rewardTokens", + "internalType": "address[]", + "type": "address[]" + }, + { + "name": "rewards", + "internalType": "uint256[]", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "markets", + "internalType": "contract ERC20[]", + "type": "address[]" + }, + { + "name": "flywheels", + "internalType": "contract IonicFlywheelCore[]", + "type": "address[]" + }, + { + "name": "accrue", + "internalType": "bool[]", + "type": "bool[]" + } + ], + "name": "claimRewardsForMarkets", + "outputs": [ + { + "name": "", + "internalType": "contract IonicFlywheelCore[]", + "type": "address[]" + }, + { + "name": "rewardTokens", + "internalType": "address[]", + "type": "address[]" + }, + { + "name": "rewards", + "internalType": "uint256[]", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "comptroller", + "internalType": "contract IonicComptroller", + "type": "address" + } + ], + "name": "claimRewardsForPool", + "outputs": [ + { + "name": "", + "internalType": "contract IonicFlywheelCore[]", + "type": "address[]" + }, + { + "name": "", + "internalType": "address[]", + "type": "address[]" + }, + { + "name": "", + "internalType": "uint256[]", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "rewardToken", + "internalType": "address", + "type": "address" + } + ], + "name": "claimRewardsOfRewardToken", + "outputs": [ + { + "name": "rewardsClaimed", + "internalType": "uint256", + "type": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [], + "name": "fpd", + "outputs": [ + { + "name": "", + "internalType": "contract PoolDirectory", + "type": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "blocksPerYear", + "internalType": "int256", + "type": "int256" + }, + { + "name": "offchainRewardsAprMarkets", + "internalType": "address[]", + "type": "address[]" + }, + { + "name": "offchainRewardsAprs", + "internalType": "int256[]", + "type": "int256[]" + } + ], + "name": "getAdjustedUserNetApr", + "outputs": [ + { + "name": "", + "internalType": "int256", + "type": "int256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [], + "name": "getAllRewardTokens", + "outputs": [ + { + "name": "uniqueRewardTokens", + "internalType": "address[]", + "type": "address[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "inputs": [ + { + "name": "markets", + "internalType": "contract ICErc20[]", + "type": "address[]" + } + ], + "name": "getMarketRewardsInfo", + "outputs": [ + { + "name": "", + "internalType": "struct IonicFlywheelLensRouter.MarketRewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "underlyingPrice", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "market", + "internalType": "contract ICErc20", + "type": "address" + }, + { + "name": "rewardsInfo", + "internalType": "struct IonicFlywheelLensRouter.RewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "rewardSpeedPerSecondPerToken", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "rewardTokenPrice", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "formattedAPR", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "flywheel", + "internalType": "address", + "type": "address" + }, + { + "name": "rewardToken", + "internalType": "address", + "type": "address" + } + ] + } + ] + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "inputs": [ + { + "name": "comptroller", + "internalType": "contract IonicComptroller", + "type": "address" + } + ], + "name": "getPoolMarketRewardsInfo", + "outputs": [ + { + "name": "", + "internalType": "struct IonicFlywheelLensRouter.MarketRewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "underlyingPrice", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "market", + "internalType": "contract ICErc20", + "type": "address" + }, + { + "name": "rewardsInfo", + "internalType": "struct IonicFlywheelLensRouter.RewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "rewardSpeedPerSecondPerToken", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "rewardTokenPrice", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "formattedAPR", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "flywheel", + "internalType": "address", + "type": "address" + }, + { + "name": "rewardToken", + "internalType": "address", + "type": "address" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + }, + { + "name": "markets", + "internalType": "contract ICErc20[]", + "type": "address[]" + } + ], + "name": "getUserRewardsInfo", + "outputs": [ + { + "name": "", + "internalType": "struct IonicFlywheelLensRouter.UserRewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "rewardToken", + "internalType": "address", + "type": "address" + }, + { + "name": "claimedRewards", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "unclaimedRewards", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "formattedAPR", + "internalType": "uint256", + "type": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "inputs": [ + { + "name": "markets", + "internalType": "contract ICErc20[]", + "type": "address[]" + } + ], + "name": "getUserTotalRewardsInfo", + "outputs": [ + { + "name": "", + "internalType": "struct IonicFlywheelLensRouter.UserTotalRewardsInfo[]", + "type": "tuple[]", + "components": [ + { + "name": "rewardToken", + "internalType": "address", + "type": "address" + }, + { + "name": "claimedRewards", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "unclaimedRewards", + "internalType": "uint256", + "type": "uint256" + }, + { + "name": "formattedAPR", + "internalType": "uint256", + "type": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "inputs": [ + { + "name": "user", + "internalType": "address", + "type": "address" + } + ], + "name": "hasClaimableRewards", + "outputs": [ + { + "name": "", + "internalType": "bool", + "type": "bool" + } + ], + "stateMutability": "view" + } +] diff --git a/src/adaptors/ionic-protocol/helpers.js b/src/adaptors/ionic-protocol/helpers.js new file mode 100644 index 0000000000..6f4e85cdc3 --- /dev/null +++ b/src/adaptors/ionic-protocol/helpers.js @@ -0,0 +1,6 @@ +const formatUnits = (value, decimals = 18) => { + return Number(value) / Math.pow(10, decimals); + }; + + module.exports = { formatUnits }; + \ No newline at end of file diff --git a/src/adaptors/ionic-protocol/index.js b/src/adaptors/ionic-protocol/index.js new file mode 100644 index 0000000000..b433790de9 --- /dev/null +++ b/src/adaptors/ionic-protocol/index.js @@ -0,0 +1,489 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const abiCore = require('./abiCore.json'); +const abiLToken = require('./abiLToken.json'); +const abiRateModelSlope = require('./abiRateModelSlope.json'); +const abiRewardContract = require('./abiRewardContract.json'); // Import the updated reward contract ABI +const abiFlyWheel = require('./abiFlyWheel.json'); +const utils = require('../utils'); +const { ethers } = require('ethers'); +const { rewardTokens } = require('../sommelier/config'); +// Helper function to format units without ethers.js +const formatUnits = (value, decimals) => { + return Number(value) / Math.pow(10, decimals); +}; +const project = 'ionic-protocol' +// Define markets per chain +const markets = { + mode: [ + { ionWETH: '0x71ef7EDa2Be775E5A7aa8afD02C45F059833e9d2' }, + { ionUSDC: '0x2BE717340023C9e14C1Bb12cb3ecBcfd3c3fB038' }, + { ionUSDT: '0x94812F2eEa03A49869f95e1b5868C6f3206ee3D3' }, + { ionWBTC: '0xd70254C3baD29504789714A7c69d60Ec1127375C' }, + { ionweETH: '0x9a9072302B775FfBd3Db79a7766E75Cf82bcaC0A' }, + { ionezETH: '0x59e710215d45F584f44c0FEe83DA6d43D762D857' }, + { ionSTONE: '0x959FA710CCBb22c7Ce1e59Da82A247e686629310' }, + // { ionmsDAI: '0x0aCC14dcFf35b731A3f9Bd70DCBa3c97C44EdBA0' }, + // { iondMBTC: '0x5158ae44C1351682B3DC046541Edf84BF28c8ca4' }, + // { ionsUSDe: '0x4417A9B33bA8dD6fC9dfd8274B401AFd42299AA3' }, + { ionwrsETH: '0x49950319aBE7CE5c3A6C90698381b45989C99b46' }, + // { ionUSDe: '0xBb2B9780BDB4Ccc168947050dFfC3181503c4D18' }, + { 'ionweETH.mode': '0xA0D844742B4abbbc43d8931a6Edb00C56325aA18' }, + { 'M-BTC': '0x19F245782b1258cf3e11Eda25784A378cC18c108' }, + // {xxxxxxxxxxxxxxxx-below are native mode markets-xxxxxxxxxxxxxxxxxx}, + // { ionMODE: '0x4341620757Bee7EB4553912FaFC963e59C949147' }, + // { ionWETH: '0xDb8eE6D1114021A94A045956BBeeCF35d13a30F2' }, + // { ionUSDC: '0xc53edEafb6D502DAEC5A7015D67936CEa0cD0F52' }, + // { ionUSDT: '0x3120B4907851cc9D780eef9aF88ae4d5360175Fd' }, + ], + // mode_native: [ + // { ionWETH: '0xDb8eE6D1114021A94A045956BBeeCF35d13a30F2' }, + // { ionUSDC: '0xc53edEafb6D502DAEC5A7015D67936CEa0cD0F52' }, + // { ionUSDT: '0x94812F2eEa03A49869f95e1b5868C6f3206ee3D3' }, + // { ionWBTC: '0xd70254C3baD29504789714A7c69d60Ec1127375C' }, + // { ionweETH: '0x9a9072302B775FfBd3Db79a7766E75Cf82bcaC0A' }, + // { ionezETH: '0x59e710215d45F584f44c0FEe83DA6d43D762D857' }, + // { ionSTONE: '0x959FA710CCBb22c7Ce1e59Da82A247e686629310' }, + // ], + base: [ + { ionWETH: '0x49420311B518f3d0c94e897592014de53831cfA3' }, + { ionUSDC: '0xa900A17a49Bc4D442bA7F72c39FA2108865671f0' }, + { ioncbBTC: '0x1De166df671AE6DB4C4C98903df88E8007593748' }, + { ionUSDz: '0xa4442b665d4c6DBC6ea43137B336e3089f05626C' }, + { ionwUSD: '0xF1bbECD6aCF648540eb79588Df692c6b2F0fbc09' }, + { ioneUSD: '0x9c2A4f9c5471fd36bE3BBd8437A33935107215A1' }, + { ionbsdETH: '0x3D9669DE9E3E98DB41A1CbF6dC23446109945E3C' }, + { ioncbETH: '0x9c201024A62466F9157b2dAaDda9326207ADDd29' }, + { ionwsuperOETHb: '0xC462eb5587062e2f2391990b8609D2428d8Cf598' }, + { ionOGN: '0xE00B2B2ca7ac347bc7Ca82fE5CfF0f76222FF375' }, + // { ionwUSDM: '0xe30965Acd0Ee1CE2e0Cd0AcBFB3596bD6fC78A51' }, + { ionuSOL: '0xbd06905590b6E1b6Ac979Fc477A0AebB58d52371' }, + { ionEURC: '0x0E5A87047F871050c0D713321Deb0F008a41C495' }, + { ionhyUSD: '0x751911bDa88eFcF412326ABE649B7A3b28c4dEDe' }, + { ionezETH: '0x079f84161642D81aaFb67966123C9949F9284bf5' }, + { ionAERO: '0x014e08F05ac11BB532BE62774A4C548368f59779' }, + { ionRSR: '0xfc6b82668E10AFF62f208C492fc95ef1fa9C0426' }, + { ionwstETH: '0x9D62e30c6cB7964C99314DCf5F847e36Fcb29ca9' }, + { 'ionweETH.mode': '0x84341B650598002d427570298564d6701733c805' }, + { 'ionUSD%2B': '0x74109171033F662D5b898A7a2FcAB2f1EF80c201' }, + // Add other markets for Base as needed + ], + optimism: [ + { ionWETH: '0x53b1D15b24d93330b2fD359C798dE7183255e7f2' }, + { ionUSDC: '0x50549be7e21C3dc0Db03c3AbAb83e1a78d07e6e0' }, + { ionUSDT: '0xb2918350826C1FB3c8b25A553B5d49611698206f' }, + { ionwUSDM: '0xc63B18Fc9025ACC7830B9df05e5A0B208940a3EE' }, + { ionOP: '0xAec01BB498bec2Fe8f3416314D5E0Db7EC76576b' }, + { ionwstETH: '0x2527e8cC363Ef3fd470c6320B22956021cacd149' }, + { ionSNX: '0xe4c5Aeb87762789F854B3Bae7515CF00d77a1f5e' }, + { ionWBTC: '0x863dccAaD60A1105f4B948C67895B4F0411C4497' }, + { ionLUSD: '0x9F4089Ea33773A090ac514934517990dF04ae5a7' }, + // Add other markets for Optimism as needed + ], + // bob: [ + // { ionWETH: '0x10f07DF86f5c3cB16f0cA62Bd8239A4954EeD2Df' }, + // { ionUSDC: '0x3E14B5D5187efE86eA99422F7696db5408a5E372' }, + // // Add other markets for Bob as needed + // ], + // Add other chains if needed +}; +// Define CORE and Reward contract addresses per chain +const CHAINS = { + mode: { + CORE: '0xFB3323E24743Caf4ADD0fDCCFB268565c0685556', + REWARD_CONTRACT: '0x01aB485A0fae0667be36AB876c95ADc1A2a5e449', // Replace with actual reward contract address + }, + // mode_native: { + // CORE: '0x8Fb3D4a94D0aA5D6EDaAC3Ed82B59a27f56d923a', + // REWARD_CONTRACT: '0x01aB485A0fae0667be36AB876c95ADc1A2a5e449', // Replace with actual reward contract address + // }, + base: { + CORE: '0x05c9C6417F246600f8f5f49fcA9Ee991bfF73D13', + REWARD_CONTRACT: '0xB1402333b12fc066C3D7F55d37944D5e281a3e8B', // Replace with actual reward contract address + }, + optimism: { + CORE: '0xaFB4A254D125B0395610fdc8f1D022936c7b166B', + REWARD_CONTRACT: '0xa6BA5F1164dc66F9C5bDCE33A6d2fC70bE8Da108', // Replace with actual reward contract address + }, + // bob: { + // CORE: '0x9cFEe81970AA10CC593B83fB96eAA9880a6DF715', + // REWARD_CONTRACT: '0xYourRewardContractAddressHere', // Replace with actual reward contract address + // }, + // Add other chains if needed +}; +// APY Calculation Function +const apy = async (chain) => { + const { CORE, REWARD_CONTRACT } = CHAINS[chain]; + const chainMarkets = markets[chain]; + if (!chainMarkets) { + console.warn(`No markets defined for chain: ${chain}`); + return []; + } + const allMarkets = chainMarkets.map((i) => Object.values(i)).flat(); + try { + // Fetch collateral factors + + + const collateralFactorMantissa = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiCore.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: CORE, + params: [m], + })), + }) + ).output.map((o) => o.output.collateralFactorMantissa); + // Fetch decimals first to use for formatting + //////console.log("Current Chain:", chain); + const decimalsRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: allMarkets.map((m) => ({ + target: m, + })), + permitFailure: true, + }) + ).output.map((o) => (o.output !== undefined ? Number(o.output) : 18)); + // Fetch totalSupply and format it + const totalSupplyRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalSupply'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + const totalSupply = totalSupplyRaw.map((val, i) => formatUnits(val, decimalsRaw[i])); + // Fetch totalBorrow and format it + const totalBorrowRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalBorrows'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + const totalBorrow = totalBorrowRaw.map((val, i) => formatUnits(val, decimalsRaw[i])); + // Fetch totalReserve and format it + const totalReserveRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalReserves'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + const totalReserve = totalReserveRaw.map((val, i) => formatUnits(val, decimalsRaw[i])); + // Fetch interestRateModel + const rateModel = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'interestRateModel'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + // Fetch reserveFactorMantissa + const reserveFactorRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'reserveFactorMantissa'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + const reserveFactor = reserveFactorRaw.map((val) => formatUnits(val, 18)); + // Fetch cash and format it + const cashRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'getCash'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + const cash = cashRaw.map((val, i) => formatUnits(val, decimalsRaw[i])); + // Fetch borrowRate and format it + const borrowRateRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiRateModelSlope.find((n) => n.name === 'getBorrowRate'), + calls: rateModel.map((m, i) => ({ + target: m, + params: [cashRaw[i], totalBorrowRaw[i], totalReserveRaw[i]], + })), + }) + ).output.map((o) => o.output); + const borrowRate = borrowRateRaw.map((val) => formatUnits(val, 18)); + // Fetch supplyRate and format it + const supplyRateRaw = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiRateModelSlope.find((n) => n.name === 'getSupplyRate'), + calls: rateModel.map((m, i) => ({ + target: m, + params: [cashRaw[i], totalBorrowRaw[i], totalReserveRaw[i], reserveFactorRaw[i]], + })), + }) + ).output.map((o) => o.output); + const supplyRate = supplyRateRaw.map((val) => formatUnits(val, 18)); + // Fetch underlying tokens + + const underlying = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'underlying'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + // Fetch symbols + const symbol = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:symbol', + calls: underlying.map((m) => ({ + target: m, + })), + permitFailure: true, + }) + ).output.map((o) => o.output || 'UNKNOWN'); + // Assemble pool data + const tokenDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'decimals'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + // Fetch prices + + const priceKeys = underlying.map((t) => `${chain}:${t}`).join(','); + let prices = {}; + try { + const pricesResponse = await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`); + prices = pricesResponse.data.coins; + } catch (error) { + console.error(`Error fetching prices for chain ${chain}:`, error); + } + // Fetch reward rates from the Reward Contract using the updated ABI + // Fetch reward rates from the Reward Contract using the updated ABI + let rewardApyPerMarket = []; // Array to hold APY per market + const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; + + if (REWARD_CONTRACT && REWARD_CONTRACT !== '') { + try { + // Ensure the function exists in the ABI + const getMarketRewardsInfoFunction = abiRewardContract.find(n => n.name === 'getMarketRewardsInfo'); + if (!getMarketRewardsInfoFunction) { + throw new Error("Function 'getMarketRewardsInfo' not found in abiRewardContract.json"); + } + + // Fetch Market Rewards Info by passing all market addresses + // Step 1: Fetch raw market rewards info + const marketRewardsInfoRaw = await sdk.api.abi.call({ + chain, + abi: getMarketRewardsInfoFunction, + target: REWARD_CONTRACT, + params: [allMarkets], // Pass all markets as parameters + }); + + // Step 2: Function to get the flywheel booster address for each reward's flywheel + async function getFlywheelBoosterAddress(sdk, chain, flywheelAddress) { + const flywheelBoosterFunction = abiFlyWheel.find(n => n.name === 'flywheelBooster'); + if (!flywheelBoosterFunction) { + throw new Error("Function 'flywheelBooster' not found in abiFlyWheel.json"); + } + + // Fetch the flywheelBooster address + const flywheelBoosterAddressRaw = await sdk.api.abi.call({ + chain, + abi: flywheelBoosterFunction, + target: flywheelAddress, + }); + return flywheelBoosterAddressRaw.output; // Ensure you access the `output` field for the result + } + + // Step 3: Filter and map the output based on flywheel's booster address + async function getFilteredMarketRewardsInfo(sdk, chain, marketRewardsInfoRaw) { + const filteredRewards = []; + + for (let info of marketRewardsInfoRaw.output) { + const filteredRewardsInfo = []; + + // Iterate over each reward in rewardsInfo and check booster address + for (let reward of info.rewardsInfo) { + //console.log("reward flywheel",reward.flywheel) + const boosterAddress = await getFlywheelBoosterAddress(sdk, chain, reward.flywheel); // Use flywheel here + if (boosterAddress === '0x0000000000000000000000000000000000000000') { + filteredRewardsInfo.push(reward); + } + } + + // Add market info only if there are valid rewards + if (filteredRewardsInfo.length > 0) { + filteredRewards.push({ + market: info.market, + underlyingPrice: info.underlyingPrice, + rewardsInfo: filteredRewardsInfo.map(reward => ({ + rewardSpeedPerSecondPerToken: reward.rewardSpeedPerSecondPerToken, + rewardToken: reward.rewardToken || 0, + rewardTokenPrice: reward.rewardTokenPrice, + formattedAPR: reward.formattedAPR || null, + })), + rewardTokens: filteredRewardsInfo.map(reward => reward.rewardToken) || 0, + }); + } + } + return filteredRewards; + } + + // Step 4: Execute the function to get the filtered rewards + const marketRewardsInfo = await getFilteredMarketRewardsInfo(sdk, chain, marketRewardsInfoRaw); + + const BLOCKS_PER_MINUTE = 27; // Given: 27 blocks per minute + const BLOCKS_PER_YEAR = BLOCKS_PER_MINUTE * 60 * 24 * 365; // Blocks in a year + + await Promise.all(marketRewardsInfo.map(async (marketReward, index) => { + const rewards = marketReward.rewardsInfo || []; + const decimals = decimalsRaw[index]; + + // Filter out rewards with invalid formattedAPR + const validRewards = rewards.filter(reward => reward.formattedAPR); + + if (validRewards.length === 0) { + console.warn(`No valid rewards found for market at index ${index}:`, marketReward); + rewardApyPerMarket.push(0); // Push zero if no valid rewards are found + return; // Exit early for this market + } + + const totalRewardApy = await Promise.all( + validRewards.map(async (reward) => { + const formattedAPR = reward.formattedAPR; + const parsedRate = parseFloat(ethers.utils.formatUnits(formattedAPR, decimals)); + const scaleFactor = 10 ** (18 - decimals); + let normalizedRate; + + // Normalize rates based on decimals + if (decimals < 18) { + normalizedRate = parsedRate / scaleFactor; + } else { + normalizedRate = parsedRate; // No scaling needed if decimals are 18 or more + } + + //console.log("Normalized Rate for reward:", normalizedRate); + return normalizedRate; // Return the normalized rate + }) + ); + + // Calculate total APY for the current market + const totalAPY = totalRewardApy.reduce((acc, curr) => acc + curr, 0); + const apyPercentage = (totalAPY > 0) ? totalAPY * 100 : 0; // Calculate percentage + + const apyPercFormatted = apyPercentage.toFixed(2) + // Push the calculated total APY into the array + rewardApyPerMarket.push(apyPercFormatted); // Ensure this is the same array you're checking later + })); + //console.log('Final rewardApyPerMarket:', rewardApyPerMarket); + + } catch (error) { + console.error("Error fetching Market Rewards Info:", error); + } + } + // Inside your pools mapping + + const blocksPerMin = 27; + + const pools = allMarkets.map((p, i) => { + const price = prices[`${chain}:${underlying[i]}`]?.price || 0; + if (!price) { + console.warn(`Price not found for ${chain}:${underlying[i]}`); + return null; + } + //////console.log("token",underlying[i]) + const decimal = tokenDecimals[i] || 18; // Fallback to 18 if token not found + const totalBorrowInUsd = totalBorrow[i]; // Convert totalBorrow to token value + const cashInUsd = cash[i]; // Convert cash to token value + + // Ensure price is in USD (double-check this value) + const totalBorrowUsd = totalBorrowInUsd * price; // Convert to USD + const tvlUsd = cashInUsd * price; // Convert to USD + + // Calculate total supply USD + const totalSupplyUsd = totalBorrowUsd + tvlUsd; + function ratePerBlockToAPY(ratePerBlock, blocksPerMin) { + // Check if ratePerBlock is null, undefined, or NaN + if (ratePerBlock == null || isNaN(ratePerBlock)) { + return 0; + } + + const blocksPerDay = blocksPerMin * 60 * 24; // Calculate blocks per day + const rateAsNumber = Number(ratePerBlock); + + return (Math.pow(rateAsNumber * blocksPerDay + 1, 365) - 1) * 100; // Calculate APY + } + let apyBase = 0; + if (supplyRate[i] !== 0 && supplyRate[i] !== null && supplyRate[i] !== undefined) { + apyBase = ratePerBlockToAPY(supplyRate[i], blocksPerMin) || 0; + } + // Reward APR calculation (adjusted with totalSupplyUsd for normalization) + //////console.log('rewards APY', rewardApyPerMarket[i]) + // // const rewardApy = rewardApyPerMarket[i] / (10 ** 12); // Convert from wei to ether if applicable + // const apyReward = (totalSupplyUsd > 0 && rewardApyPerMarket[i] !== undefined) + // ? (rewardApy / totalSupplyUsd) * 100 // Normalize reward APY + // : 0; + //console.log("Final rewardApyPerMarket:", rewardApyPerMarket); + const apyReward = (rewardApyPerMarket[i]) + ? Number((rewardApyPerMarket[i])) + : 0; + const apyTotal = apyReward + apyBase; + // const apyTotal = (totalSupplyUsd > 0) ? (apyBase + totalSupplyRewardsAPR) : 0; + return { + pool: p, + chain, + project: 'ionic-protocol', + symbol: symbol[i], + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + apyReward: apyReward !== null && apyReward !== undefined ? apyReward : 0, // Ensure apyBase has a valid value, + apyBase: apyBase !== null && apyBase !== undefined ? apyBase : 0, // Ensure apyBase has a valid value + rewardTokens: rewardTokens, + }; + }); + return pools; + } catch (error) { + console.error(`Error processing APY for chain ${chain}:`, error); + return []; + } +}; +// Main Function +const main = async () => { + try { + const poolArrays = await Promise.all( + Object.keys(CHAINS).map((chain) => apy(chain)) + ); + const pools = poolArrays.flat().filter((i) => i !== null && utils.keepFinite(i)); + return pools; + } catch (error) { + console.error('Error in main APY function:', error); + return []; + } +}; +// Export the module +module.exports = { + apy: main, + url: 'https://app.ionic.money/', +}; + diff --git a/src/adaptors/ipor-derivatives/abiV2.js b/src/adaptors/ipor-derivatives/abiV2.js new file mode 100644 index 0000000000..27f1b3e4c0 --- /dev/null +++ b/src/adaptors/ipor-derivatives/abiV2.js @@ -0,0 +1,96 @@ +module.exports = { + liquidityMiningV2Abi: [ + { + inputs: [ + { + internalType: "address[]", + name: "lpTokens", + type: "address[]" + } + ], + name: "getGlobalIndicators", + outputs: [ + { + components: [ + { + internalType: "address", + name: "lpToken", + type: "address" + }, + { + components: [ + { + internalType: "uint256", + name: "aggregatedPowerUp", + type: "uint256" + }, + { + internalType: "uint128", + name: "compositeMultiplierInTheBlock", + type: "uint128" + }, + { + internalType: "uint128", + name: "compositeMultiplierCumulativePrevBlock", + type: "uint128" + }, + { + internalType: "uint32", + name: "blockNumber", + type: "uint32" + }, + { + internalType: "uint32", + name: "rewardsPerBlock", + type: "uint32" + }, + { + internalType: "uint88", + name: "accruedRewards", + type: "uint88" + } + ], + internalType: "struct ILiquidityMiningLens.GlobalRewardsIndicators", + name: "indicators", + type: "tuple" + } + ], + internalType: "struct ILiquidityMiningLens.GlobalIndicatorsResult[]", + name: "", + type: "tuple[]" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "lpToken", + type: "address" + } + ], + name: "getPoolPowerUpModifiers", + outputs: [ + { + "name": "pwTokenModifier", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "logBase", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "vectorOfCurve", + "type": "uint256", + "internalType": "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + ] +} diff --git a/src/adaptors/ipor-derivatives/index.js b/src/adaptors/ipor-derivatives/index.js new file mode 100644 index 0000000000..c3481b9ff6 --- /dev/null +++ b/src/adaptors/ipor-derivatives/index.js @@ -0,0 +1,155 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const {liquidityMiningV2Abi} = require('./abiV2'); + +const COIN_PRICES_URL = 'https://coins.llama.fi/prices/current'; + +const CHAIN_CONFIG = { + ethereum: { + statsUrl: 'https://api.ipor.io/monitor/liquiditypool-statistics-1', + lmAddress: '0xCC3Fc4C9Ba7f8b8aA433Bc586D390A70560FF366', + urlTemplate: (asset) => `https://app.ipor.io/zap/ethereum/${asset.toLowerCase()}`, + blocksPerYear: (365 * 24 * 3600) / 12 + }, + arbitrum: { + statsUrl: 'https://api.ipor.io/monitor/liquiditypool-statistics-42161', + lmAddress: '0xdE645aB0560E5A413820234d9DDED5f4a55Ff6dd', + urlTemplate: (asset) => asset === 'USDM' ? + `https://app.ipor.io/deposit/arbitrum/${asset.toLowerCase()}` : `https://app.ipor.io/zap/arbitrum/${asset.toLowerCase()}`, + blocksPerYear: (365 * 24 * 3600) / 12 // On Arbitrum block.number is an approximated Ethereum block number + }, + base: { + statsUrl: 'https://api.ipor.io/monitor/liquiditypool-statistics-8453', + lmAddress: '0xE9331948766593EE9CeBBB426faE317b44DaF0f2', + urlTemplate: (asset) => `https://app.ipor.io/deposit/base/${asset.toLowerCase()}`, + blocksPerYear: (365 * 24 * 3600) / 2 + } +}; + +const getChainData = async (chain) => { + const config = CHAIN_CONFIG[chain]; + const assets = (await superagent.get(config.statsUrl)).body.assets; + + const lpTokenAddresses = assets.map( + (assetData) => assetData.ipTokenAssetAddress + ); + + const globalStats = new Map( + ( + await sdk.api.abi.multiCall({ + chain, + abi: liquidityMiningV2Abi.find( + ({name}) => name === 'getGlobalIndicators' + ), + calls: [{ + target: config.lmAddress, + params: [lpTokenAddresses], + },], + }) + ).output.flatMap((response) => + response.output.map((stats) => [ + stats.lpToken.toLowerCase(), + stats.indicators, + ]) + ) + ); + + const poolPowerUpModifiers = new Map( + ( + await sdk.api.abi.multiCall({ + chain, + abi: liquidityMiningV2Abi.find( + ({name}) => name === 'getPoolPowerUpModifiers' + ), + calls: lpTokenAddresses.map(address => ({ + target: config.lmAddress, + params: [address] + })), + }) + ).output.map((response) => [ + response.input.params[0].toLowerCase(), + response.output, + ]) + ); + + return {assets, globalStats, poolPowerUpModifiers}; +}; + +const buildPool = (asset, chainData, chainConfig, chainName, coinPrices) => { + const {globalStats, poolPowerUpModifiers} = chainData; + + const poolStartDate = new Date(asset.poolStartDate); + const now = new Date(); + const poolAgeInDays = (now - poolStartDate) / (1000 * 60 * 60 * 24); + + let lpApr; + if (poolAgeInDays < 7) { + lpApr = asset.periods.find(({period}) => period === 'DAY').ipTokenReturnValue; + } else if (poolAgeInDays < 30) { + lpApr = asset.periods.find(({period}) => period === 'WEEK').ipTokenReturnValue; + } else { + lpApr = asset.periods.find(({period}) => period === 'MONTH').ipTokenReturnValue; + } + + const coinPrice = coinPrices[`${chainName}:${asset.assetAddress.toLowerCase()}`]?.price; + const lpBalanceHistory = asset.periods.find(({period}) => period === 'HOUR').totalLiquidity; + const lpBalance = lpBalanceHistory[lpBalanceHistory.length - 1].totalLiquidity; + const lpTokenPriceHistory = asset.periods.find(({period}) => period === 'HOUR').ipTokenExchangeRates; + const lpTokenPrice = lpTokenPriceHistory[lpTokenPriceHistory.length - 1].exchangeRate; + + const liquidityMiningGlobalStats = globalStats.get(asset.ipTokenAssetAddress.toLowerCase()); + const vectorOfCurve = poolPowerUpModifiers.get( + asset.ipTokenAssetAddress.toLowerCase() + ).vectorOfCurve / 1e18; + + const apyReward = (((liquidityMiningGlobalStats.rewardsPerBlock / 1e8 / + (liquidityMiningGlobalStats.aggregatedPowerUp / 1e18)) * + (0.2 + vectorOfCurve) * //base powerup + chainConfig.blocksPerYear) / + lpTokenPrice / + coinPrice / + 2) * //50% early withdraw fee + 100; //percentage + + return { + pool: `${asset.ipTokenAssetAddress}-${chainName}`, + chain: chainName.charAt(0).toUpperCase() + chainName.slice(1), + project: 'ipor-derivatives', + symbol: asset.asset, + tvlUsd: lpBalance * coinPrice, + apyBase: Number(lpApr), + apyReward: Number(apyReward), + underlyingTokens: [asset.assetAddress], + rewardTokens: [], + url: chainConfig.urlTemplate(asset.asset), + }; +}; + +const apy = async () => { + const chainsData = await Promise.all( + Object.entries(CHAIN_CONFIG).map(async ([chain, config]) => ({ + chain, + config, + data: await getChainData(chain) + })) + ); + + const coinKeys = chainsData.flatMap(({chain, data}) => + data.assets.map(asset => `${chain}:${asset.assetAddress}`) + ); + + const coinPrices = ( + await superagent.get(`${COIN_PRICES_URL}/${coinKeys.join(',').toLowerCase()}`) + ).body.coins; + + return chainsData.flatMap(({chain, config, data}) => + data.assets.map(asset => + buildPool(asset, data, config, chain, coinPrices) + ) + ); +}; + +module.exports = { + timetravel: false, + apy: apy +}; \ No newline at end of file diff --git a/src/adaptors/ipor-fusion/index.js b/src/adaptors/ipor-fusion/index.js new file mode 100644 index 0000000000..33acefff5d --- /dev/null +++ b/src/adaptors/ipor-fusion/index.js @@ -0,0 +1,103 @@ +const superagent = require('superagent'); + +const IPOR_GITHUB_ADDRESSES_URL = "https://raw.githubusercontent.com/IPOR-Labs/ipor-abi/refs/heads/main/mainnet/addresses.json"; +const FUSION_API_URL = 'https://api.ipor.io/fusion/vaults'; +const CHAIN_CONFIG = { + ethereum: { + chainId: 1 + }, + arbitrum: { + chainId: 42161 + }, + base: { + chainId: 8453 + }, + unichain: { + chainId: 130 + }, + tac: { + chainId: 239 + }, + ink: { + chainId: 57073 + }, + plasma: { + chainId: 9745 + }, + avax: { + chainId: 43114 + } +}; + +async function getChainData(chain) { + const allVaultsRes = await superagent.get(FUSION_API_URL); + const chainVaults = allVaultsRes.body.vaults.filter( + vault => vault.chainId === CHAIN_CONFIG[chain].chainId + ); + + return chainVaults; +} + +async function getPublicVaults() { + const response = await superagent.get(IPOR_GITHUB_ADDRESSES_URL); + const publicVaults = JSON.parse(response.text); + const chainVaults = new Map(); + + Object.entries(publicVaults).forEach(([chainName, { vaults }]) => { + const lowerCaseVaults = (vaults || []).map(vault => vault.PlasmaVault.toLowerCase()); + chainVaults.set(chainName, lowerCaseVaults); + }); + + return chainVaults; +} + +async function buildPool(vault) { + const tvlUsd = Number(vault.tvl); + const apyBase = Number(vault.apy); + const chainConfig = Object.entries(CHAIN_CONFIG).find( + ([_, config]) => config.chainId === vault.chainId + ); + const chain = chainConfig[0]; + const chainData = chainConfig[1]; + const url = `https://app.ipor.io/fusion/${chain}/${vault.address.toLowerCase()}`; + + return { + pool: vault.address, + chain, + project: 'ipor-fusion', + symbol: `${vault.asset}`, + tvlUsd, + apyBase, + apyReward: 0, + rewardTokens: [], + underlyingTokens: [vault.assetAddress], + poolMeta: `${vault.name}`, + url + }; +} + +const apy = async() => { + const publicVaults = await getPublicVaults(); + const chainsData = await Promise.all( + Object.entries(CHAIN_CONFIG).map(async([chain, config]) => ({ + chain, + config, + data: await getChainData(chain) + })) + ); + + const pools = await Promise.all( + chainsData.flatMap(({ chain, data }) => + data + .filter(vault => publicVaults.get(chain)?.includes(vault.address.toLowerCase())) + .map(vault => buildPool(vault)) + ) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy +}; diff --git a/src/adaptors/iq/abi.js b/src/adaptors/iq/abi.js new file mode 100644 index 0000000000..06301a2056 --- /dev/null +++ b/src/adaptors/iq/abi.js @@ -0,0 +1,69 @@ +module.exports = [ + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256', + }, + ], + payable: false, + type: 'function', + }, + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address', + }, + { + name: '_spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + + diff --git a/src/adaptors/iq/index.js b/src/adaptors/iq/index.js new file mode 100644 index 0000000000..3b80b121bb --- /dev/null +++ b/src/adaptors/iq/index.js @@ -0,0 +1,85 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const IqAbi = require('./abi'); + +const token = '0x1bf5457ecaa14ff63cc89efd560e251e814e16ba'; + +const getApy = async () => { + const dataTvl = await utils.getData('https://api.llama.fi/protocol/iq'); + + const totalHiiq = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const REWARDS_FOR_THE_FIRST_YEAR = 1095000000; + + const getTotalIQMintedPerYear = (year = 0) => { + const newModelStartDate = new Date('November 1, 2022'); + const currentDate = new Date(); + currentDate.setFullYear(currentDate.getFullYear() + year); + const diffInMiliseconds = + currentDate.getTime() - newModelStartDate.getTime(); + const yearsOfDifference = Math.abs( + new Date(diffInMiliseconds).getUTCFullYear() - 1970 + ); + if (yearsOfDifference === 0) return REWARDS_FOR_THE_FIRST_YEAR; + return REWARDS_FOR_THE_FIRST_YEAR / 2 ** yearsOfDifference; + }; + + const calculateUserPoolRewardOverTheYear = ( + years, + userTotalHiiq, + totalHIIQ + ) => { + let totalPoolReward = 0; + for (let i = 0; i < years; i += 1) { + const totalIQMintedEachYear = getTotalIQMintedPerYear(i); + const userPoolRationForTheYear = + (userTotalHiiq / (totalHIIQ + userTotalHiiq)) * totalIQMintedEachYear; + totalPoolReward += userPoolRationForTheYear; + } + return totalPoolReward; + }; + + const calculateStakeReward = ( + totalHiiq, + amountLocked, + years, + poolRewardCalculationYear + ) => { + const yearsLocked = years; + const rewardsBasedOnLockPeriod = + amountLocked + amountLocked * 3 * (yearsLocked / 4); + const totalPoolRewardForTheLockYear = calculateUserPoolRewardOverTheYear( + poolRewardCalculationYear, + rewardsBasedOnLockPeriod, + totalHiiq + ); + return totalPoolRewardForTheLockYear; + }; + + const calculateAPR = () => { + const amountLocked = 1000000; + const stakeReward = calculateStakeReward(totalHiiq, amountLocked, 4, 1); + const aprDividedByLockPeriod = (stakeReward / amountLocked) * 100; + return aprDividedByLockPeriod; + }; + + return [ + { + pool: token, + chain: utils.formatChain('ethereum'), + project: 'iq', + symbol: 'hiiq', + tvlUsd: Number(dataTvl.currentChainTvls['staking']), + apy: calculateAPR(), + underlyingTokens: [dataTvl.address], + poolMeta: `Lock for 4 years to earn more IQ`, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://iq.braindao.org/dashboard/stake', +}; diff --git a/src/adaptors/iron-bank/index.js b/src/adaptors/iron-bank/index.js new file mode 100644 index 0000000000..2c31a26da6 --- /dev/null +++ b/src/adaptors/iron-bank/index.js @@ -0,0 +1,54 @@ +const utils = require('../utils'); + +const getUrl = (chain) => + `https://api.ib.xyz/api/v1/itoken?comptroller=${chain}`; + +const CHAINS = { + eth: 'ethereum', + fantom: 'fantom', + avalanche: 'avalanche', + optimism: 'optimism', +}; + +const getApy = async () => { + const vaultsData = await Promise.all( + Object.keys(CHAINS).map(async (chain) => ({ + chain: CHAINS[chain], + data: await utils.getData(getUrl(chain)), + })) + ); + + const pools = vaultsData.map((chainData) => { + const chainPools = chainData.data.map((pool) => { + const tvlUsd = + Number(pool.cash.value) * Number(pool.underlying_price.value); + const totalBorrowUsd = + Number(pool.total_borrows.value) * Number(pool.underlying_price.value); + const totalSupplyUsd = totalBorrowUsd + tvlUsd; + + return { + pool: `${pool.token_address}-${chainData.chain}`, + chain: utils.formatChain(chainData.chain), + project: 'iron-bank', + symbol: pool.underlying_symbol, + tvlUsd, + apyBase: Number(pool.supply_apy.value) * 100, + underlyingTokens: [pool.underlying_address], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.borrow_apy.value) * 100, + ltv: Number(pool.collateral_factor.value), + }; + }); + return chainPools; + }); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.ib.xyz/', +}; diff --git a/src/adaptors/ironclad-finance/abiLendingPool.js b/src/adaptors/ironclad-finance/abiLendingPool.js new file mode 100644 index 0000000000..ddf300738e --- /dev/null +++ b/src/adaptors/ironclad-finance/abiLendingPool.js @@ -0,0 +1,692 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/ironclad-finance/abiProtocolDataProvider.js b/src/adaptors/ironclad-finance/abiProtocolDataProvider.js new file mode 100644 index 0000000000..1c698fcae2 --- /dev/null +++ b/src/adaptors/ironclad-finance/abiProtocolDataProvider.js @@ -0,0 +1,148 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/ironclad-finance/abiSimplifiedProtocolDataReader.js b/src/adaptors/ironclad-finance/abiSimplifiedProtocolDataReader.js new file mode 100644 index 0000000000..e01b36c463 --- /dev/null +++ b/src/adaptors/ironclad-finance/abiSimplifiedProtocolDataReader.js @@ -0,0 +1,375 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "protocolDataProviderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "thenaOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lendingOracleAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ILENDING_ORACLE", + "outputs": [ + { + "internalType": "contract ILendingOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ITHENA_ORACLE", + "outputs": [ + { + "internalType": "contract IThenaOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAYMENT_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_DATA_PROVIDER", + "outputs": [ + { + "internalType": "contract ProtocolDataProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARDER", + "outputs": [ + { + "internalType": "contract IRewarder0612", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetFullYieldBreakdown", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetRewardsAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getDepositAndBorrowAPRs", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPaymentTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolBalancesUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolYearlyRewardsUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRawOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRealOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReceiptTokenAddresses", + "outputs": [ + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardsDataEPS", + "outputs": [ + { + "internalType": "uint256", + "name": "aTokenRewardEPS", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vTokenRewardEPS", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/ironclad-finance/index.js b/src/adaptors/ironclad-finance/index.js new file mode 100644 index 0000000000..64d63a0102 --- /dev/null +++ b/src/adaptors/ironclad-finance/index.js @@ -0,0 +1,193 @@ +const ethers = require('ethers'); +const { JsonRpcProvider } = require('ethers'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiSimplifiedProtocolDataReader = require('./abiSimplifiedProtocolDataReader'); + +const utils = require('../utils'); + +const chains = { + mode: { + LendingPool: '0xB702cE183b4E1Faa574834715E5D4a6378D0eEd3', + ProtocolDataProvider: '0x29563f73De731Ae555093deb795ba4D1E584e42E', + url: 'mode', + SimplifiedProtocolDataReader: '0x78d5439da3201F44ce9A642DB95D798e9249952F', + rewardTokens: ['0x3b6ea0fa8a487c90007ce120a83920fd52b06f6d'] + }, + base: { + LendingPool: '0xB702cE183b4E1Faa574834715E5D4a6378D0eEd3', + ProtocolDataProvider: '0xed984A0E9c12Ee27602314191Fc4487A702bB83f', + url: 'base', + SimplifiedProtocolDataReader: '0x78d5439da3201F44ce9A642DB95D798e9249952F', + rewardTokens: ['0x3b6ea0fa8a487c90007ce120a83920fd52b06f6d'] + } + +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + const rewardTokens = addresses.rewardTokens; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + // try catches incase of safemath error + let rewardsData; + try { + rewardsData = await sdk.api.abi.multiCall({ + calls: reservesList.map((reserve) => ({ + target: addresses.SimplifiedProtocolDataReader, + params: [reserve], + })), + abi: abiSimplifiedProtocolDataReader.find((m) => m.name === 'getAssetRewardsAPR'), + chain: sdkChain, + failOnRevert: false, // Add this option to prevent failing on reverts + }); + } catch (error) { + console.error(`Error fetching rewards data for chain ${chain}:`, error); + // Implement fallback mechanism or use default values + rewardsData = { + output: reservesList.map(() => ({ success: false, output: null })) + }; + } + + // Process the results, handling potential failures + const processedRewardsData = rewardsData.output.map((result, index) => { + if (result.success && Array.isArray(result.output) && result.output.length === 2) { + return { + apyReward: Number(result.output[0]) / 1e8, + apyRewardBorrow: Number(result.output[1]) / 1e8 + }; + } else { + console.warn(`Failed to get rewards data for reserve ${reservesList[index]} on chain ${chain}`); + return { apyReward: 0, apyRewardBorrow: 0 }; + } + }); + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + + const { apyReward, apyRewardBorrow } = processedRewardsData[i]; + + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + console.log(`Raw reward data for ${symbols[i]}:`, rewardsData.output[i]?.output); + console.log(`Parsed apyReward for ${symbols[i]}:`, apyReward); + console.log(`Parsed apyRewardBorrow for ${symbols[i]}:`, apyRewardBorrow); + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const poolSymbol = symbols[i].toLowerCase() + const url = `https://app.ironclad.finance/markets/${poolSymbol}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'ironclad-finance', + chain, + tvlUsd, + apyBase, + // apyReward, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + // apyRewardBorrow, + // rewardTokens, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/isle-finance/index.js b/src/adaptors/isle-finance/index.js new file mode 100644 index 0000000000..7634a250de --- /dev/null +++ b/src/adaptors/isle-finance/index.js @@ -0,0 +1,81 @@ +const { request } = require('graphql-request'); + +const GRAPH_URL = { + Hedera: "https://api.goldsky.com/api/public/project_cmdfkhd2uxajf01vq022c7ion/subgraphs/isle-hedera-main/main/gn" +}; +const POOL_URL_BASE= "https://app.isle.finance/pools/"; +const PROJECT_SLUG = "isle-finance"; +const gqlQueries = { + poolsData: ` + query PoolsData { + pools: markets(where: { isActive: true }) { + address: id + lockedAmount: inputTokenBalance + borrowedAmount: variableBorrowedTokenBalance + rates { + rate + side + } + inputToken { + address: id + decimals + name + symbol + } + } + } + ` +} + +function roundTo2Decimals(num) { + return Math.round(num * 100) / 100; +} + +function formatByDecimals(value, decimals = 0) { + if (value == null || isNaN(value)) return 0; + const num = Number(value) / 10 ** decimals; + return roundTo2Decimals(num); +} + +function formatApy(value) { + if (value == null || isNaN(value)) return 0; + const num = Number(value); + return roundTo2Decimals(num); +} + +const apy = async () => { + const allPools = []; + + for (const [chain, url] of Object.entries(GRAPH_URL)) { + try { + const { pools } = await request(url, gqlQueries.poolsData); + if (!pools?.length) continue; + + const chainPools = pools.map((p) => { + const tokenAddr = p?.inputToken?.address || ""; + const tokenDecimals = p?.inputToken?.decimals ?? 0; + return { + pool: `${p?.address || ""}-${chain}`.toLowerCase(), + chain, + project: PROJECT_SLUG, + symbol: p?.inputToken?.symbol || "", + tvlUsd: formatByDecimals(p?.lockedAmount, tokenDecimals), + totalBorrowUsd: formatByDecimals(p?.borrowedAmount, tokenDecimals), + apyBase: formatApy(p?.rates?.find((r) => (r?.side || "") === "LENDER")?.rate), + apyBaseBorrow: formatApy(p?.rates?.find((r) => (r?.side || "") === "BORROWER")?.rate), + underlyingTokens: tokenAddr ? [tokenAddr] : [], + url: `${POOL_URL_BASE}${p?.address ?? ""}/overview`, + }; + }); + + allPools.push(...chainPools); + } catch (err) { + console.error(`${chain} error:`, err?.message ?? err); + } + } + return allPools; +}; + +module.exports = { + apy, +}; \ No newline at end of file diff --git a/src/adaptors/iziswap/index.js b/src/adaptors/iziswap/index.js new file mode 100644 index 0000000000..a79a885149 --- /dev/null +++ b/src/adaptors/iziswap/index.js @@ -0,0 +1,48 @@ +const utils = require('../utils'); + +const url = 'https://izumi.finance/api/v1/farm/dashboard/?status=LIVE'; + +const chain = { + 1: 'ethereum', + 56: 'bsc', + 137: 'polygon', + 42161: 'arbitrum', + 1313161554: 'aurora', + 25: 'cronos', + 324: 'zksync_era', + 5000: 'mantle', + 169: 'manta', + 534352: 'scroll', +}; + +const getApy = async () => { + const urlData = await utils.getData(url); + const data = urlData.data.data; + + const pools = data.map((poolInfo) => { + const rewardTokens = poolInfo.rewards.map((info) => { + return info.address; + }); + + return { + pool: poolInfo.pool_address.toLowerCase(), + chain: chain[poolInfo.chain_id] + ? utils.formatChain(chain[poolInfo.chain_id]) + : null, + project: 'iziswap', + symbol: `${poolInfo.tokenX_symbol}-${poolInfo.tokenY_symbol}`, + tvlUsd: poolInfo.tvl, + apyReward: poolInfo.apr.length > 1 ? poolInfo.apr[1] : poolInfo.apr[0], + rewardTokens: rewardTokens, + underlyingTokens: [poolInfo.tokenX_address, poolInfo.tokenY_address], + }; + }); + + return pools.filter((i) => i.chain); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://izumi.finance/farm', +}; diff --git a/src/adaptors/javsphere/index.js b/src/adaptors/javsphere/index.js new file mode 100644 index 0000000000..ffeaacc0e0 --- /dev/null +++ b/src/adaptors/javsphere/index.js @@ -0,0 +1,123 @@ +const sdk = require('@defillama/sdk'); +const { getData } = require('../utils'); + +const ADDRESSES = { + base: { + LeverageXJAVVault: '0x96aF2003ab259a56104d639eb6ed9EACe54B1142', + LeverageXJAVLISPool: '0xdfc8c41816Cd6CCa9739f946e73b4eeB17195836', + LeverageXLLPPool: '0xFd916d70eB2d0E0E1C17A6a68a7FBEdE3106b852', + USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + cbBTC: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', + wETH: '0x4200000000000000000000000000000000000006', + JAV: '0xEdC68c4c54228D273ed50Fc450E253F685a2c6b9', + JAVLIS: '0x440D06b2aC83Ff743d9e149Be582A4b2b2c6adEc' + + }, +}; + +// NOTE: OUR SUBGRAPH IS NOT CAUGHT UP TO DATE, SO WE ARE USING THE API FOR NOW +// ----------------------------------------------------------------------------- +// We will reenable time travel once our subgraph is caught up +const main = async (timestamp = null) => { + // timestamp = timestamp ? parseInt(timestamp) : Math.floor(Date.now() / 1000); + + // NOTE: OUR SUBGRAPH IS NOT CAUGHT UP TO DATE, SO WE ARE USING THE API FOR NOW + // ----------------------------------------------------------------------------- + // Get total fees distributed for junior and senior tranches + // const feesDistributedIds = await fetchFeeDistributedIds(timestamp); + // const { totalJunior, totalSenior } = await fetchTransfersForFeeDistributedIds( + // feesDistributedIds + // ); + + // const [block] = await getBlocksByTime([timestamp], 'base'); + + const meta = await getData( + 'https://1f5i4e87mf.execute-api.eu-central-1.amazonaws.com/prod/cols-stats' + ); + + // Get TVL for junior and senior tranches + let [javlisTvl, javTvl, + wethTvl, cbBTCTvl, usdcTvl] = await Promise.all([ + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.JAVLIS, + params: [ADDRESSES.base.LeverageXJAVLISPool], + chain: 'base', + // block: block, + }), + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.JAV, + params: [ADDRESSES.base.LeverageXJAVVault], + chain: 'base', + // block: block, + }), + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.wETH, + params: [ADDRESSES.base.LeverageXLLPPool], + chain: 'base', + // block: block, + }), + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.cbBTC, + params: [ADDRESSES.base.LeverageXLLPPool], + chain: 'base', + // block: block, + }), + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: ADDRESSES.base.USDC, + params: [ADDRESSES.base.LeverageXLLPPool], + chain: 'base', + // block: block, + }), + ]); + + javlisTvl = javlisTvl.output / 1e18 * meta.collaterals[4].price; + javTvl = javTvl.output / 1e18 * meta.collaterals[3].price; + + const wethTvlUsd = wethTvl.output / 1e18 * meta.collaterals[0].price; + const cbBtcTvlUsd = cbBTCTvl.output / 1e8 * meta.collaterals[1].price; + const usdcTvlUsd = usdcTvl.output / 1e6; + const llpTvl = wethTvlUsd + cbBtcTvlUsd + usdcTvlUsd; + + return [ + { + pool: `LEVERAGEX-${ADDRESSES.base.LeverageXJAVLISPool}-base`.toLowerCase(), + chain: 'base', + project: 'javsphere', + symbol: 'JAVLIS', + poolMeta: 'xJAVLIS Vault', + tvlUsd: javlisTvl, + apyBase: meta.yieldJavlisVault.apy, + url: 'https://app.leveragex.trade/x-vault/xJAVLIS', + }, + { + pool: `LEVERAGEX-${ADDRESSES.base.LeverageXJAVVault}-base`.toLowerCase(), + chain: 'base', + project: 'javsphere', + symbol: 'JAV', + poolMeta: 'xJAV Vault', + tvlUsd: javTvl, + apyBase: meta.yieldJavVault.apy, + url: 'https://app.leveragex.trade/x-vault/xJAV', + }, + { + pool: `LEVERAGEX-${ADDRESSES.base.LeverageXLLPPool}-base`.toLowerCase(), + chain: 'base', + project: 'javsphere', + symbol: 'USDC-wETH-cbBTC', + poolMeta: 'LLP Pool', + tvlUsd: llpTvl, + apyBase: meta.yield.apy, + url: 'https://app.leveragex.trade/llppool', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/jelly/index.js b/src/adaptors/jelly/index.js index f4bf8f8857..10db37a84b 100644 --- a/src/adaptors/jelly/index.js +++ b/src/adaptors/jelly/index.js @@ -1,13 +1,13 @@ const sdk = require('@defillama/sdk'); -const { getPoolInfos } = require('./abi.json') +const { getPoolInfos } = require('./abi.json'); const { default: BigNumber } = require('bignumber.js'); const utils = require('../utils'); -const helper = "0xEd950eB5acAD4CD63784618437bAF28fA2eE36Ab" -const jellyUsdcLP = "0x64C2F792038f1FB55da1A9a22749971eAC94463E" -const sweetPool = '0xF897C014a57298DA3453f474312079cC6cB140c0' -const royalPool = '0xcC43331067234a0014d298b5226A1c22cb0ac66a' -const pools = [sweetPool, royalPool] +const helper = '0xEd950eB5acAD4CD63784618437bAF28fA2eE36Ab'; +const jellyUsdcLP = '0x64C2F792038f1FB55da1A9a22749971eAC94463E'; +const sweetPool = '0xF897C014a57298DA3453f474312079cC6cB140c0'; +const royalPool = '0xcC43331067234a0014d298b5226A1c22cb0ac66a'; +const pools = [sweetPool, royalPool]; const rewardTokenDecimals = 1e18; const usdcDecimals = 1e6; const lpTokenDecimals = 1e18; @@ -15,50 +15,51 @@ const BLOCKS_PER_DAY = 4 * 60 * 24; const BLOCKS_PER_YEAR = BLOCKS_PER_DAY * 365; const getPools = async () => { - const poolInfos = Object.values( - ( - await sdk.api.abi.call({ - target: helper, - abi: getPoolInfos, - params: [pools], - }) - ).output - ); + const poolInfos = Object.values( + ( + await sdk.api.abi.call({ + target: helper, + abi: getPoolInfos, + params: [pools], + }) + ).output + ); - return Promise.all( - [...Array(Number(poolInfos.length)).keys()].map(async (i) => { - const poolInfo = poolInfos[i]; - const rewards = Object.values(poolInfo.rewards); - const rewardPrices = []; - const rewardBlocks = []; - rewards.forEach((rewardInfo) => { - const rewardTokenPrice = rewardInfo.rewardTokenPrice / usdcDecimals; - const rewardsPerBlock = - rewardInfo.rewardsPerBlock / rewardTokenDecimals; - rewardPrices.push(rewardTokenPrice); - rewardBlocks.push(rewardsPerBlock); - }); + return Promise.all( + [...Array(Number(poolInfos.length)).keys()].map(async (i) => { + const poolInfo = poolInfos[i]; + const rewards = Object.values(poolInfo.rewards); + const rewardPrices = []; + const rewardBlocks = []; + rewards.forEach((rewardInfo) => { + const rewardTokenPrice = rewardInfo.rewardTokenPrice / usdcDecimals; + const rewardsPerBlock = + rewardInfo.rewardsPerBlock / rewardTokenDecimals; + rewardPrices.push(rewardTokenPrice); + rewardBlocks.push(rewardsPerBlock); + }); - const lpStaked = poolInfo.stakedTokenTotal / lpTokenDecimals; - const lpTokenPrice = poolInfo.stakingTokenPrice / lpTokenDecimals; - const tvl = lpStaked * lpTokenPrice; - const token0 = poolInfo.token0; - const token1 = poolInfo.token1; - const poolId = poolInfo.poolId; + const lpStaked = poolInfo.stakedTokenTotal / lpTokenDecimals; + const lpTokenPrice = poolInfo.stakingTokenPrice / lpTokenDecimals; + const tvl = lpStaked * lpTokenPrice; + const token0 = poolInfo.token0; + const token1 = poolInfo.token1; + const poolId = poolInfo.poolId; - const documents = Object.values(poolInfo.documents) - const poolName = documents.find(doc => doc.name === 'poolName')?.data + const documents = Object.values(poolInfo.documents); + const poolName = documents.find((doc) => doc.name === 'poolName')?.data; - const apy = await calcApr(rewardPrices, rewardBlocks, tvl); - return { - tvl, - apy, - symbol: `${token0.symbol}-${token1.symbol}(${poolName})`, - poolId - } - }) - ); -} + const apy = await calcApr(rewardPrices, rewardBlocks, tvl); + return { + tvl, + apy, + symbol: `${token0.symbol}-${token1.symbol}`, + poolName, + poolId, + }; + }) + ); +}; const calcApr = async (rewardTokenPrices, tokensPerBlock, tvl) => { let totalRewardsPerYear = new BigNumber(0); @@ -80,9 +81,10 @@ const calcApr = async (rewardTokenPrices, tokensPerBlock, tvl) => { const buildPool = (entry) => { const newObj = { pool: entry.poolId, - chain: 'ethereum', + chain: 'Ethereum', project: 'jelly', symbol: utils.formatSymbol(entry.symbol), + poolMeta: entry.poolName, tvlUsd: parseInt(entry.tvl, 10), apy: parseFloat(entry.apy), }; @@ -90,13 +92,13 @@ const buildPool = (entry) => { }; async function main() { - const pools = await getPools() - const data = pools.map((pool) => buildPool(pool)); - return data; + const pools = await getPools(); + const data = pools.map((pool) => buildPool(pool)); + return data; } module.exports = { - timetravel: false, - apy: main, + timetravel: false, + apy: main, + url: 'https://app.jelly.io/farms/0xcC43331067234a0014d298b5226A1c22cb0ac66a', }; - \ No newline at end of file diff --git a/src/adaptors/jito-liquid-staking/index.js b/src/adaptors/jito-liquid-staking/index.js new file mode 100644 index 0000000000..d0418c167c --- /dev/null +++ b/src/adaptors/jito-liquid-staking/index.js @@ -0,0 +1,33 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const JITOSOL_ADDRESS = 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn'; +const priceKey = `solana:${JITOSOL_ADDRESS}`; + +const apy = async () => { + const totalSupply = await getTotalSupply(JITOSOL_ADDRESS); + + const priceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const currentPrice = priceResponse.data.coins[priceKey].price; + + const jitoResponse = await axios.get( + 'https://www.jito.network/api/getJitoPoolStatsRecentOnly/' + ).then((res) => res.data); + const apy = jitoResponse.latestApy; + + return [ + { + pool: JITOSOL_ADDRESS, + chain: 'Solana', + project: 'jito-liquid-staking', + symbol: 'JITOSOL', + tvlUsd: totalSupply * currentPrice, + apyBase: Number(apy), + underlyingTokens: [JITOSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://www.jito.network/staking/' }; diff --git a/src/adaptors/joe-dex/abi_masterchef.js b/src/adaptors/joe-dex/abi_masterchef.js new file mode 100644 index 0000000000..16c9f7fab0 --- /dev/null +++ b/src/adaptors/joe-dex/abi_masterchef.js @@ -0,0 +1,433 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'veJoeShareBp', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'Add', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Init', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'veJoeShareBp', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'overwrite', type: 'bool' }, + ], + name: 'Set', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accJoePerShare', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accJoePerFactorPerShare', + type: 'uint256', + }, + ], + name: 'UpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'JOE', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_CHEF_V2', + outputs: [ + { internalType: 'contract IMasterChefJoe', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_PID', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'VEJOE', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint96', name: '_allocPoint', type: 'uint96' }, + { internalType: 'uint32', name: '_veJoeShareBp', type: 'uint32' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'claimableJoe', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'harvestFromMasterChef', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_dummyToken', type: 'address' }, + ], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMasterChefJoe', + name: '_MASTER_CHEF_V2', + type: 'address', + }, + { internalType: 'contract IERC20', name: '_joe', type: 'address' }, + { internalType: 'contract IERC20', name: '_veJoe', type: 'address' }, + { internalType: 'uint256', name: '_MASTER_PID', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'joePerSec', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'uint256', name: 'pendingJoe', type: 'uint256' }, + { internalType: 'address', name: 'bonusTokenAddress', type: 'address' }, + { internalType: 'string', name: 'bonusTokenSymbol', type: 'string' }, + { internalType: 'uint256', name: 'pendingBonusToken', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + { internalType: 'uint96', name: 'allocPoint', type: 'uint96' }, + { internalType: 'uint256', name: 'accJoePerShare', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accJoePerFactorPerShare', + type: 'uint256', + }, + { internalType: 'uint64', name: 'lastRewardTimestamp', type: 'uint64' }, + { internalType: 'contract IRewarder', name: 'rewarder', type: 'address' }, + { internalType: 'uint32', name: 'veJoeShareBp', type: 'uint32' }, + { internalType: 'uint256', name: 'totalFactor', type: 'uint256' }, + { internalType: 'uint256', name: 'totalLpSupply', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint96', name: '_allocPoint', type: 'uint96' }, + { internalType: 'uint32', name: '_veJoeShareBp', type: 'uint32' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: '_overwrite', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_newVeJoeBalance', type: 'uint256' }, + ], + name: 'updateFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'factor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/joe-dex/index.js b/src/adaptors/joe-dex/index.js new file mode 100644 index 0000000000..07714f148a --- /dev/null +++ b/src/adaptors/joe-dex/index.js @@ -0,0 +1,177 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const abi_masterchef = require('./abi_masterchef'); + +const url = sdk.graph.modifyEndpoint( + '9ZjERoA7jGANYNz1YNuFMBt11fK44krveEhzssJTWokM' +); +const masterchef = '0x4483f0b6e2F5486D06958C20f8C39A7aBe87bf8F'; + +const JOE_TOKEN = '0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd'; + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveAVAX, orderDirection: desc block: {number: }) { + id + volumeUSD + reserve0 + reserve1 + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveAVAX orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const buildPool = (entry, chainString) => { + const apyFee = Number(entry.apy1d); + const apyJoe = isNaN(entry.apyJoe) ? null : entry.apyJoe; + const symbol = utils.formatSymbol( + `${entry.token0.symbol}-${entry.token1.symbol}` + ); + const newObj = { + pool: entry.id, + chain: utils.formatChain(chainString), + project: 'joe-dex', + symbol, + tvlUsd: entry.totalValueLockedUSD, + apyBase: apyFee, + apyReward: apyJoe, + rewardTokens: apyJoe > 0 ? [JOE_TOKEN] : [], + underlyingTokens: [entry.token0.id, entry.token1.id], + apyBase7d: entry.apy7d, + volumeUsd1d: entry.volumeUSD1d, + volumeUsd7d: entry.volumeUSD7d, + }; + + return newObj; +}; + +const topLvl = async (chainString, timestamp, url) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let dataNow = await request(url, query.replace('', block)); + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = await request( + url, + queryPrior.replace('', blockPrior) + ); + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow.pairs, 'avax'); + + // calculate apy + let data = dataNow.map((el) => + utils.apy(el, dataPrior.pairs, dataPrior7d, 'v2') + ); + + // prepare LM rewards + const joePerSec = ( + await sdk.api.abi.call({ + target: masterchef, + chain: 'avax', + abi: abi_masterchef.find((n) => n.name === 'joePerSec'), + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + chain: 'avax', + abi: abi_masterchef.find((n) => n.name === 'totalAllocPoint'), + }) + ).output; + + const poolsLength = ( + await sdk.api.abi.call({ + target: masterchef, + chain: 'avax', + abi: abi_masterchef.find((n) => n.name === 'poolLength'), + }) + ).output; + + let poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLength)).keys()].map((idx) => ({ + params: idx, + target: masterchef, + })), + abi: abi_masterchef.find((n) => n.name === 'poolInfo'), + chain: 'avax', + }) + ).output.map(({ output }) => output); + + // get joe price + const key = 'avax:0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd'; + const joeUsd = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + + const dataLM = {}; + for (const p of poolInfo) { + const relPoolShare = Number(p.allocPoint) / Number(totalAllocPoint); + // LPs receive 50% of rewards, so we divide by 2 + const rewardPerSecond = (relPoolShare * Number(joePerSec)) / 1e18 / 2; + const rewardPerDay = rewardPerSecond * 86400; + + dataLM[p.lpToken.toLowerCase()] = { + joePerYearUsd: rewardPerDay * 365 * joeUsd, + }; + } + + data = data.map((p) => ({ + ...p, + apyJoe: + (dataLM[p.id.toLowerCase()]?.joePerYearUsd / + Number(p.totalValueLockedUSD)) * + 100, + })); + // build pool objects + data = data.map((el) => buildPool(el, chainString)); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([topLvl('avalanche', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://traderjoexyz.com/pool', +}; diff --git a/src/adaptors/joe-lend/abi.js b/src/adaptors/joe-lend/abi.js new file mode 100644 index 0000000000..8b260a5b74 --- /dev/null +++ b/src/adaptors/joe-lend/abi.js @@ -0,0 +1,2492 @@ +module.exports = { + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'protocol', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'creditLimit', + type: 'uint256', + }, + ], + name: 'CreditLimitChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + ], + name: 'MarketDelisted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'enum JoetrollerV1Storage.Version', + name: 'oldVersion', + type: 'uint8', + }, + { + indexed: false, + internalType: 'enum JoetrollerV1Storage.Version', + name: 'newVersion', + type: 'uint8', + }, + ], + name: 'NewJTokenVersion', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract JToken', + name: 'jToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSupplyCap', + type: 'uint256', + }, + ], + name: 'NewSupplyCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldSupplyCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newSupplyCapGuardian', + type: 'address', + }, + ], + name: 'NewSupplyCapGuardian', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + ], + name: '_delistMarket', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'protocol', type: 'address' }, + { internalType: 'uint256', name: 'creditLimit', type: 'uint256' }, + ], + name: '_setCreditLimit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setFlashloanPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract JToken[]', + name: 'jTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract JToken[]', + name: 'jTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newSupplyCaps', type: 'uint256[]' }, + ], + name: '_setMarketSupplyCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newRewardDistributor', + type: 'address', + }, + ], + name: '_setRewardDistributor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newSupplyCapGuardian', + type: 'address', + }, + ], + name: '_setSupplyCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + { + internalType: 'enum JoetrollerV1Storage.Version', + name: 'version', + type: 'uint8', + }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract JToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract JToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract JToken', name: 'jToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + { + internalType: 'contract JToken[]', + name: 'jTokens', + type: 'address[]', + }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { + internalType: 'address payable[]', + name: 'holders', + type: 'address[]', + }, + { + internalType: 'contract JToken[]', + name: 'jTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimReward', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'creditLimits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'jTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + ], + name: 'flashloanAllowed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'flashloanGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract JToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract JToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'jTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isCreditAccount', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isJoetroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'jTokenAddress', type: 'address' }, + ], + name: 'isMarketListed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'jTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'jTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'jTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'jTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'enum JoetrollerV1Storage.Version', + name: 'version', + type: 'uint8', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rewardDistributor', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'jTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'jTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'supplyCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'jToken', type: 'address' }, + { + internalType: 'enum JoetrollerV1Storage.Version', + name: 'newVersion', + type: 'uint8', + }, + ], + name: 'updateJTokenVersion', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + ercDelegator: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reservesFee', + type: 'uint256', + }, + ], + name: 'Flashloan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'jTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract JoetrollerInterface', + name: 'oldJoetroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract JoetrollerInterface', + name: 'newJoetroller', + type: 'address', + }, + ], + name: 'NewJoetroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_addReservesNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract JoetrollerInterface', + name: 'newJoetroller', + type: 'address', + }, + ], + name: '_setJoetroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: 'change', type: 'uint256' }, + { internalType: 'bool', name: 'repay', type: 'bool' }, + ], + name: 'estimateBorrowRatePerSecondAfterChange', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint256', name: 'change', type: 'uint256' }, + { internalType: 'bool', name: 'repay', type: 'bool' }, + ], + name: 'estimateSupplyRatePerSecondAfterChange', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'flashFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'flashFeeBips', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ERC3156FlashBorrowerInterface', + name: 'receiver', + type: 'address', + }, + { internalType: 'address', name: 'initiator', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'flashLoan', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract JoetrollerInterface', + name: 'joetroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract JoetrollerInterface', + name: 'joetroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isJToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'joetroller', + outputs: [ + { + internalType: 'contract JoetrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract JTokenInterface', + name: 'jTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'contract JTokenInterface', + name: 'jTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrowNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxFlashLoan', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'mintNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlyingNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'borrower', type: 'address' }], + name: 'repayBorrowBehalfNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'repayBorrowNative', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/joe-lend/index.js b/src/adaptors/joe-lend/index.js new file mode 100644 index 0000000000..55e8c6fadd --- /dev/null +++ b/src/adaptors/joe-lend/index.js @@ -0,0 +1,187 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0xdc13687554205E5b89Ac783db14bb5bba4A1eDaC'; +const CHAIN = 'avax'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerSecond'; +const BORROW_RATE = 'borrowRatePerSecond'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400; +const PROJECT_NAME = 'joe-lend'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WAVAX', + address: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'JOE', + address: '0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + }) + ).output.map(({ output }) => output); +}; + +const lendingApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + return { + pool: market, + chain: utils.formatChain('avalanche'), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + underlyingTokens: [token], + url: `https://v1.lfj.gg/lend/supply/${market}`, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: lendingApy, +}; diff --git a/src/adaptors/joe-v2.1/index.js b/src/adaptors/joe-v2.1/index.js new file mode 100644 index 0000000000..6b4c8a2892 --- /dev/null +++ b/src/adaptors/joe-v2.1/index.js @@ -0,0 +1,38 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const apy = async () => { + const pools = await Promise.all( + ['avalanche', 'arbitrum', 'ethereum'].map(async (chain) => { + const apiUrl = `https://api.lfj.dev/v1/pools/${chain}?filterBy=1d&orderBy=volume&pageNum=1&pageSize=100&status=main`; + + const pools = ( + await axios.get(apiUrl, { + headers: { + 'x-traderjoe-api-key': process.env.TRADERJOE, + }, + }) + ).data; + + return pools.map((p) => { + return { + pool: `${p.pairAddress}-${chain}`, + chain: utils.formatChain(chain), + project: 'joe-v2.1', + symbol: p.name, + underlyingTokens: [p.tokenX.address, p.tokenY.address], + tvlUsd: p.liquidityUsd, + apyBase: ((p.feesUsd * 365) / p.liquidityUsd) * 100, + volumeUsd1d: p.volumeUsd, + }; + }); + }) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, + url: 'https://lfj.gg/avalanche/pool', +}; diff --git a/src/adaptors/joe-v2/index.js b/src/adaptors/joe-v2/index.js new file mode 100644 index 0000000000..2fca3e0252 --- /dev/null +++ b/src/adaptors/joe-v2/index.js @@ -0,0 +1,108 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const chains = { + avalanche: sdk.graph.modifyEndpoint( + '6KD9JYCg2qa3TxNK3tLdhj5zuZTABoLLNcnUZXKG9vuH' + ), + arbitrum: sdk.graph.modifyEndpoint( + '9RoEdAwZiP651miLbKLYQczjckg7HxmyoKXWYXBDYsJc' + ), +}; + +const query = gql` + { + lbpairs (first: 1000 block: {number: }) { + id + volumeUSD + reserve0: reserveX + reserve1: reserveY + token0: tokenX { + id + symbol + } + token1: tokenY { + id + symbol + } + feeTier: baseFeePct + } + } +`; + +const queryPrior = gql` + { + lbpairs (first: 1000 block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let dataNow = (await request(url, query.replace('', block))) + .lbpairs; + + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).lbpairs; + + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).lbpairs; + + dataNow = await utils.tvl( + dataNow, + chainString === 'avalanche' ? 'avax' : chainString + ); + dataNow = dataNow.map((p) => ({ ...p, feeTier: p.feeTier * 10000 })); + + let data = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, 'joe-v2') + ); + + return data.map((p) => { + const apyFee = Number(p.apy1d); + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'joe-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: apyFee, + underlyingTokens: [p.token0.id, p.token1.id], + apyBase7d: p.apy7d, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +}; + +const main = async (timestamp = null) => { + const pools = await Promise.all( + Object.keys(chains).map((chain) => topLvl(chain, timestamp, chains[chain])) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://traderjoexyz.com/pool', +}; diff --git a/src/adaptors/jolt/abiAToken.js b/src/adaptors/jolt/abiAToken.js new file mode 100644 index 0000000000..0943f07ba5 --- /dev/null +++ b/src/adaptors/jolt/abiAToken.js @@ -0,0 +1,418 @@ +[ + { + inputs: [], + name: 'EIP712_REVISION', + outputs: [ + { + internalType: 'bytes', + name: '', + type: 'bytes', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: '_nonces', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'RESERVE_TREASURY_ADDRESS', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'UNDERLYING_ASSET_ADDRESS', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'POOL', + outputs: [ + { + internalType: 'contract ILendingPool', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getIncentivesController', + outputs: [ + { + internalType: 'contract IAaveIncentivesController', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract ILendingPool', name: 'pool', type: 'address' }, + { internalType: 'address', name: 'treasury', type: 'address' }, + { internalType: 'address', name: 'underlyingAsset', type: 'address' }, + { + internalType: 'contract IAaveIncentivesController', + name: 'incentivesController', + type: 'address', + }, + { internalType: 'uint8', name: 'aTokenDecimals', type: 'uint8' }, + { internalType: 'string', name: 'aTokenName', type: 'string' }, + { internalType: 'string', name: 'aTokenSymbol', type: 'string' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { + internalType: 'address', + name: 'receiverOfUnderlying', + type: 'address', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'mintToTreasury', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'mintToTeam', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferOnLiquidation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'scaledBalanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getScaledUserBalanceAndSupply', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'scaledTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'target', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferUnderlyingTo', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdrawReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'handleRepayment', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'underlyingAsset', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'treasury', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'incentivesController', + type: 'address', + }, + { + indexed: false, + internalType: 'uint8', + name: 'aTokenDecimals', + type: 'uint8', + }, + { + indexed: false, + internalType: 'string', + name: 'aTokenName', + type: 'string', + }, + { + indexed: false, + internalType: 'string', + name: 'aTokenSymbol', + type: 'string', + }, + { indexed: false, internalType: 'bytes', name: 'params', type: 'bytes' }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'receiverOfUnderlying', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: false, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'BalanceTransfer', + type: 'event', + }, +]; diff --git a/src/adaptors/jolt/abiChefIncentivesController.js b/src/adaptors/jolt/abiChefIncentivesController.js new file mode 100644 index 0000000000..0c4e132659 --- /dev/null +++ b/src/adaptors/jolt/abiChefIncentivesController.js @@ -0,0 +1,582 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + ], + name: 'BalanceUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + ], + name: 'ChefReserveEmpty', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + ], + name: 'ChefReserveLow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'Disqualified', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256[]', + name: 'startTimeOffsets', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'rewardsPerSeconds', + type: 'uint256[]', + }, + ], + name: 'EmissionScheduleAppended', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'uint8', name: 'version', type: 'uint8' }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'rewardsPerSecond', + type: 'uint256', + }, + { indexed: false, internalType: 'bool', name: 'persist', type: 'bool' }, + ], + name: 'RewardsPerSecondUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [], + name: 'accountedRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'addPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'afterLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'allPendingRewards', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + { internalType: 'uint256[]', name: '_allocPoints', type: 'uint256[]' }, + ], + name: 'batchUpdateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'beforeLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bountyManager', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'claimAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'bool', name: '_execute', type: 'bool' }, + ], + name: 'claimBounty', + outputs: [{ internalType: 'bool', name: 'issueBaseBounty', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositedRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibilityEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'eligibilityExempt', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibleDataProvider', + outputs: [ + { + internalType: 'contract IEligibilityDataProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'emissionSchedule', + outputs: [ + { internalType: 'uint128', name: 'startTimeOffset', type: 'uint128' }, + { internalType: 'uint128', name: 'rewardsPerSecond', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emissionScheduleIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'endRewardTime', + outputs: [{ internalType: 'uint256', name: 'timestamp', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_balance', type: 'uint256' }, + { internalType: 'uint256', name: '_totalSupply', type: 'uint256' }, + ], + name: 'handleActionAfter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'handleActionBefore', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_poolConfigurator', type: 'address' }, + { + internalType: 'contract IEligibilityDataProvider', + name: '_eligibleDataProvider', + type: 'address', + }, + { + internalType: 'contract IMiddleFeeDistribution', + name: '_rewardMinter', + type: 'address', + }, + { internalType: 'uint256', name: '_rewardsPerSecond', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAllPoolUpdate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastRPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + ], + name: 'pendingRewards', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'persistRewardsPerSecond', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolConfigurator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardPerShare', type: 'uint256' }, + { + internalType: 'contract IOnwardIncentivesController', + name: 'onwardIncentives', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'registerRewardDeposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'registeredTokens', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardMinter', + outputs: [ + { + internalType: 'contract IMiddleFeeDistribution', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_bountyManager', type: 'address' }, + ], + name: 'setBountyManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_newVal', type: 'bool' }], + name: 'setEligibilityEnabled', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_contract', type: 'address' }], + name: 'setEligibilityExempt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: '_startTimeOffsets', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_rewardsPerSecond', + type: 'uint256[]', + }, + ], + name: 'setEmissionSchedule', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { + internalType: 'contract IOnwardIncentivesController', + name: '_incentives', + type: 'address', + }, + ], + name: 'setOnwardIncentives', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_rewardsPerSecond', type: 'uint256' }, + { internalType: 'bool', name: '_persist', type: 'bool' }, + ], + name: 'setRewardsPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'start', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userBaseClaimable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'enterTime', type: 'uint256' }, + { internalType: 'uint256', name: 'lastClaimTime', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/jolt/abiLendingPool.js b/src/adaptors/jolt/abiLendingPool.js new file mode 100644 index 0000000000..a7b1a83709 --- /dev/null +++ b/src/adaptors/jolt/abiLendingPool.js @@ -0,0 +1,739 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'depositWithAutoDLP', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'leverager', + outputs: [ + { internalType: 'contract ILeverager', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILeverager', + name: '_leverager', + type: 'address', + }, + ], + name: 'setLeverager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_newOwner', type: 'address' }], + name: 'setNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/jolt/abiProtocolDataProvider.js b/src/adaptors/jolt/abiProtocolDataProvider.js new file mode 100644 index 0000000000..e7a171f8c1 --- /dev/null +++ b/src/adaptors/jolt/abiProtocolDataProvider.js @@ -0,0 +1,147 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/jolt/abiUniswap.js b/src/adaptors/jolt/abiUniswap.js new file mode 100644 index 0000000000..799f3eb437 --- /dev/null +++ b/src/adaptors/jolt/abiUniswap.js @@ -0,0 +1,25 @@ +module.exports = [ + { + inputs: [], + name: 'slot0', + outputs: [ + { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' }, + { internalType: 'int24', name: 'tick', type: 'int24' }, + { internalType: 'uint16', name: 'observationIndex', type: 'uint16' }, + { + internalType: 'uint16', + name: 'observationCardinality', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'observationCardinalityNext', + type: 'uint16', + }, + { internalType: 'uint8', name: 'feeProtocol', type: 'uint8' }, + { internalType: 'bool', name: 'unlocked', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/jolt/index.js b/src/adaptors/jolt/index.js new file mode 100644 index 0000000000..6c876bd520 --- /dev/null +++ b/src/adaptors/jolt/index.js @@ -0,0 +1,239 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiAToken = require('./abiAToken'); +const abiUniswap = require('./abiUniswap'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const { default: BigNumber } = require('bignumber.js'); +const abiChefIncentivesController = require('./abiChefIncentivesController'); + +const utils = require('../utils'); + +const earlyExitPenalty = 1 - 0.5; +const JOLT = '0xd549aa17c5010a33ca5e3d2051b8904b5a279b0a'; + +const chains = { + optimism: { + LendingPool: '0x2ABC4DE4ceB60BF15Fa57122CbB07fA5a50D3C50', + ProtocolDataProvider: '0xe9c0EFeA9236467fa9aaC41E2c728aD47aaD74d3', + ChefIncentivesController: '0x0774275e354561c2edcaac816f2ce7971aca1d9a', + uniswapLp: '0xd2BF5c6d948C83B7C6Bc357239E8C42E056ed295', + url: '0x3d8a1ea95ea4afa2469bfb80d94a4f9068670e82', + eth: 'optimism:0x4200000000000000000000000000000000000006', + }, +}; + +const getApy = async () => { + console.log('getAPY'); + const pools = await Promise.allSettled( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const rewardsPerSecond = ( + await sdk.api.abi.call({ + target: addresses.ChefIncentivesController, + abi: abiChefIncentivesController.find( + (m) => m.name === 'rewardsPerSecond' + ), + chain, + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abiChefIncentivesController.find( + (n) => n.name === 'totalAllocPoint' + ), + target: addresses.ChefIncentivesController, + chain, + }) + ).output; + + const poolInfoInterest = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentivesController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: addresses.ChefIncentivesController, + params: reserveData[i].aTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const poolInfoDebt = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentivesController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: addresses.ChefIncentivesController, + params: reserveData[i].variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList + .map((t) => `${chain}:${t}`) + .concat(`${chain}:${JOLT}`); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const joltPrice = await getUniswapV3Price( + addresses.uniswapLp, + chain, + prices[addresses.eth]?.price + ); + + const rewardPerYear = (rewardsPerSecond / 1e18) * 86400 * 365 * joltPrice; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${chain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const apyReward = + (((poolInfoInterest[i].allocPoint / totalAllocPoint) * + rewardPerYear) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((poolInfoDebt[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalBorrowUsd) * + 100; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + // url for pools + const url = `https://jolt.finance`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'jolt', + chain, + tvlUsd, + apyBase, + apyReward: apyReward, + underlyingTokens: [t], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: apyRewardBorrow, + rewardTokens: [JOLT], + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + url: `${url}`, + }; + }); + }) + ); + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => p !== null && utils.keepFinite(p)); +}; + +async function getUniswapV3Price(uniswapLp, chain, ethPrice) { + const { output: slot0 } = await sdk.api.abi.call({ + target: uniswapLp, + abi: abiUniswap.find((m) => m.name === 'slot0'), + chain, + }); + + const sqrtPriceX96 = new BigNumber(slot0[0]); // Q64.96 fixed-point + + const precisionFactor = new BigNumber('1e18'); + const numerator = sqrtPriceX96.pow(2).times(precisionFactor); // (sqrtPriceX96)^2 * 1e18 + const denominator = new BigNumber(2).pow(192); // 2^192 + + const priceRatio = numerator.div(denominator); + + let price = new BigNumber('1e36').div(priceRatio); + + price = price.div(precisionFactor); + + price = price.times(ethPrice); + + return price.toFixed(2); +} + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/jones-dao/aura-locker-abi.json b/src/adaptors/jones-dao/aura-locker-abi.json new file mode 100644 index 0000000000..c192dedb47 --- /dev/null +++ b/src/adaptors/jones-dao/aura-locker-abi.json @@ -0,0 +1,48 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "lockedBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "total", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unlockable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "locked", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint112", + "name": "amount", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "unlockTime", + "type": "uint32" + } + ], + "internalType": "struct AuraLocker.LockedBalance[]", + "name": "lockData", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/jones-dao/index.js b/src/adaptors/jones-dao/index.js new file mode 100644 index 0000000000..7fbdb1dd14 --- /dev/null +++ b/src/adaptors/jones-dao/index.js @@ -0,0 +1,146 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const lockerABI = require('./aura-locker-abi.json'); + +const aura = '0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF'; +const auraLocker = '0x3Fa73f1E5d8A792C80F426fc8F84FBF7Ce9bBCAC'; +const auraStrategy = '0x7629fc134e5a7feBEf6340438D96881C8D121f2c'; +const glp = '0x1aDDD80E6039594eE970E5872D247bf0414C8903'; +const glpTracker = '0x13C6Bed5Aa16823Aba5bBA691CAeC63788b19D9d'; +const glpStrategy = '0x64ECc55a4F5D61ead9B966bcB59D777593afBd6f'; +const bridgedUsdc = '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'; +const usdc = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831'; +const arbToken = '0x912CE59144191C1204E64559FE8253a0e49E6548'; +const jusdcUnderlyingVault = '0xB0BDE111812EAC913b392D80D51966eC977bE3A2'; + +const SECONDS_PER_YEAR = 31556952; +// 0.97% see https://docs.jonesdao.io/jones-dao/features/incentives +const JUSDC_RETENTION = 0.97 / 100; +const JGLP_RETENTION = 3 / 100; + +async function pools() { + const [ + prices, + auraLeftoverStrategy, + auraLocked, + jauraApyRes, + jusdcApy, + jglpApy, + jusdcCollateralBalance, + jglpCollateralBalance, + smartLpStrategiesRes, + ] = await Promise.all([ + utils.getPrices([ + `ethereum:${aura}`, + `arbitrum:${glp}`, + `arbitrum:${usdc}`, + ]), + sdk.api.erc20 + .balanceOf({ + target: aura, + owner: auraStrategy, + }) + .then((result) => result.output), + sdk.api.abi + .call({ + abi: lockerABI.at(0), + target: auraLocker, + params: auraStrategy, + }) + .then((result) => result.output[0]), + utils.getData('https://api.jonesdao.io/api/v1/jones/apy-wjaura'), + utils + .getData('https://api.jonesdao.io/api/v1/jones/apy-jusdc') + .then((res) => res.jusdcApy), + utils + .getData('https://api.jonesdao.io/api/v1/jones/apy-jglp') + .then((res) => res.jglpApy), + sdk.api.abi.call({ + abi: 'uint256:totalAssets', + target: jusdcUnderlyingVault, + chain: 'arbitrum', + }), + sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: glp, + params: [glpStrategy], + chain: 'arbitrum', + }), + utils + .getData('https://app.jonesdao.io/api/smart-lp/pools') + .then((res) => res.strategies), + ]); + + const { + aura: auraPrice, + fsglp: glpPrice, + usdc: usdcPrice, + } = prices.pricesBySymbol; + + const jglpTvl = (Number(jglpCollateralBalance.output) / 1e18) * glpPrice; + const jusdcTvl = (Number(jusdcCollateralBalance.output) / 1e6) * usdcPrice; + + const jAuraTvl = + (Number(auraLocked) / 1e18 + Number(auraLeftoverStrategy) / 1e18) * + auraPrice; + + const jAuraPool = { + pool: `${auraStrategy}-arbitrum`.toLowerCase(), + chain: 'Ethereum', + project: 'jones-dao', + symbol: 'jAURA', + underlyingTokens: [aura], + tvlUsd: jAuraTvl, + apyBase: jauraApyRes.jauraApy * (1 - JGLP_RETENTION), + apyBaseInception: jauraApyRes.jauraApyInception, + }; + + const jUsdcPool = { + pool: `${jusdcUnderlyingVault}-arbitrum-jones-dao`.toLowerCase(), // TODO update + chain: 'Arbitrum', + project: 'jones-dao', + symbol: 'jUSDC', + underlyingTokens: [usdc], + tvlUsd: jusdcTvl, + apyBase: jusdcApy.week * (1 - JUSDC_RETENTION), + apyBaseInception: jusdcApy.full, + poolMeta: '1day lock', + }; + + const jGlpPool = { + pool: `${glpTracker}-arbitrum`.toLowerCase(), + chain: 'Arbitrum', + project: 'jones-dao', + symbol: 'jGLP', + underlyingTokens: [glp], + tvlUsd: jglpTvl, + apyBase: jglpApy.week * (1 - JGLP_RETENTION), + apyBaseInception: jglpApy.full, + }; + + const smartLpStrategies = smartLpStrategiesRes.map((strat) => ({ + pool: `${strat.vaultAddress}-arbitrum`.toLowerCase(), + chain: 'Arbitrum', + project: 'jones-dao', + symbol: strat.poolName, + underlyingTokens: [strat.token0.address, strat.token1.address], + tvlUsd: strat.tvl, + apyBase: strat.apy, + apyReward: + (strat.stipApr ?? 0) + (strat.merklApr ?? 0) + (strat.camelotApr ?? 0), + rewardTokens: [arbToken], + poolMeta: `${strat.strategyName.toUpperCase()} strategy on ${strat.dex.toUpperCase()}`, + })); + + return [jUsdcPool, jGlpPool, jAuraPool, ...smartLpStrategies]; +} + +module.exports = { + timetravel: false, + url: 'https://app.jonesdao.io/vaults', + apy: pools, +}; + +// cd src/adaptors +// npm run test --adapter=jones-dao diff --git a/src/adaptors/jpegd/abi.ts b/src/adaptors/jpegd/abi.ts new file mode 100644 index 0000000000..ec9e59c79f --- /dev/null +++ b/src/adaptors/jpegd/abi.ts @@ -0,0 +1,273 @@ +const APE_STAKING_ABI = { + getPoolsUI: { + inputs: [], + name: 'getPoolsUI', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'poolId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedAmount', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint48', + name: 'startTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'endTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint96', + name: 'rewardsPerHour', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'capPerPosition', + type: 'uint96', + }, + ], + internalType: 'struct ApeCoinStaking.TimeRange', + name: 'currentTimeRange', + type: 'tuple', + }, + ], + internalType: 'struct ApeCoinStaking.PoolUI', + name: '', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'poolId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedAmount', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint48', + name: 'startTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'endTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint96', + name: 'rewardsPerHour', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'capPerPosition', + type: 'uint96', + }, + ], + internalType: 'struct ApeCoinStaking.TimeRange', + name: 'currentTimeRange', + type: 'tuple', + }, + ], + internalType: 'struct ApeCoinStaking.PoolUI', + name: '', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'poolId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedAmount', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint48', + name: 'startTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'endTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint96', + name: 'rewardsPerHour', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'capPerPosition', + type: 'uint96', + }, + ], + internalType: 'struct ApeCoinStaking.TimeRange', + name: 'currentTimeRange', + type: 'tuple', + }, + ], + internalType: 'struct ApeCoinStaking.PoolUI', + name: '', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'poolId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedAmount', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint48', + name: 'startTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'endTimestampHour', + type: 'uint48', + }, + { + internalType: 'uint96', + name: 'rewardsPerHour', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'capPerPosition', + type: 'uint96', + }, + ], + internalType: 'struct ApeCoinStaking.TimeRange', + name: 'currentTimeRange', + type: 'tuple', + }, + ], + internalType: 'struct ApeCoinStaking.PoolUI', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const APE_MATCHING_ABI = { + nextNonce: { + inputs: [], + name: 'nextNonce', + outputs: [ + { + internalType: 'uint24', + name: '', + type: 'uint24', + }, + ], + stateMutability: 'view', + type: 'function', + }, + + offers: { + inputs: [ + { + internalType: 'uint24', + name: '', + type: 'uint24', + }, + ], + name: 'offers', + outputs: [ + { + internalType: 'enum ApeMatchingMarketplace.OfferType', + name: 'offerType', + type: 'uint8', + }, + { + components: [ + { + internalType: 'enum ApeStakingLib.Collections', + name: 'collection', + type: 'uint8', + }, + { + internalType: 'uint16', + name: 'tokenId', + type: 'uint16', + }, + ], + internalType: 'struct ApeMatchingMarketplace.MainNFT', + name: 'mainNft', + type: 'tuple', + }, + { + internalType: 'uint16', + name: 'bakcTokenId', + type: 'uint16', + }, + { + internalType: 'uint80', + name: 'apeAmount', + type: 'uint80', + }, + { + internalType: 'uint16', + name: 'apeRewardShareBps', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'bakcRewardShareBps', + type: 'uint16', + }, + { + internalType: 'bool', + name: 'isPaired', + type: 'bool', + }, + { + internalType: 'uint80', + name: 'lastSingleStakingRewardPerShare', + type: 'uint80', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; +module.exports = { + APE_STAKING_ABI, + APE_MATCHING_ABI, +}; diff --git a/src/adaptors/jpegd/apy.ts b/src/adaptors/jpegd/apy.ts new file mode 100644 index 0000000000..3c52863a7c --- /dev/null +++ b/src/adaptors/jpegd/apy.ts @@ -0,0 +1,101 @@ +const sdk = require('@defillama/sdk'); +const BN = require('bignumber.js'); + +const abi = require('./abi'); +require('dotenv').config({ path: './config.env' }); + +const APE_STAKING = '0x5954aB967Bc958940b7EB73ee84797Dc8a2AFbb9'; +const APE_MATCHING = '0xD4b06218C545C047ac3ACc7cE49d124C172DB409'; + +async function getApeStakingAprs() { + const [apePool, baycPool, maycPool, bakcPool] = ( + await sdk.api.abi.call({ + target: APE_STAKING, + abi: abi.APE_STAKING_ABI.getPoolsUI, + chain: 'ethereum', + }) + ).output; + + const _apr = (pool: any) => + new BN(pool.currentTimeRange.rewardsPerHour.toString()) + .div(1e18) + .times(24) + .times(365) + .div(new BN(pool.stakedAmount.toString()).div(1e18)) + .times(100) + .toFixed(); + + const aprs = { + APE: _apr(apePool), + BAYC: _apr(baycPool), + MAYC: _apr(maycPool), + BAKC: _apr(bakcPool), + }; + + return aprs; +} + +async function getApecoinApy() { + const [lastNonce, stakingAprs] = await Promise.all([ + sdk.api.abi.call({ + target: APE_MATCHING, + abi: abi.APE_MATCHING_ABI.nextNonce, + chain: 'ethereum', + }), + getApeStakingAprs(), + ]); + + const offers = ( + await sdk.api.abi.multiCall({ + abi: abi.APE_MATCHING_ABI.offers, + calls: new Array(Number(lastNonce.output)) + .fill(null) + .map((_, i) => ({ target: APE_MATCHING, params: [i] })), + chain: 'ethereum', + }) + ).output; + + const { aprSum, count } = offers.reduce( + (acc, offer, nonce) => { + const { apeRewardShareBps, mainNft, offerType, apeAmount } = offer.output; + const isBakcOffer = nonce % 2 === 1; + const collection = isBakcOffer + ? 'BAKC' + : mainNft.collection === 0 + ? 'BAYC' + : 'MAYC'; + const apeRewardShare = new BN(apeRewardShareBps.toString()) + .div(100) + .toNumber(); + const mainPoolApr = + collection === 'BAYC' ? stakingAprs.BAYC : stakingAprs.MAYC; + const apeApr = new BN(isBakcOffer ? stakingAprs.BAKC : mainPoolApr) + .times(apeRewardShare) + .div(100) + .toFixed(); + const isValidOffer = + [1, 2].includes(Number(offerType)) && + new BN(apeAmount.toString()).gt(0); + + if (isValidOffer) { + acc.count += 1; + acc.aprSum = new BN(acc.aprSum).plus(apeApr).toFixed(); + } + return acc; + }, + { aprSum: '0', count: 0 } + ); + const avgApr = new BN(aprSum).div(count).toFixed(2); + const apy = toApy(avgApr); + return apy; +} + +function toApy(apr: string) { + const formattedApr = Number(apr) / 100; + const apy = Math.pow(1 + formattedApr / 365, 365) - 1; + return apy * 100; +} + +module.exports = { + getApecoinApy, +}; diff --git a/src/adaptors/jpegd/index.ts b/src/adaptors/jpegd/index.ts new file mode 100644 index 0000000000..c243105196 --- /dev/null +++ b/src/adaptors/jpegd/index.ts @@ -0,0 +1,29 @@ +const utils = require('../utils'); +const { getApecoinApy } = require('./apy'); + +const poolsFunction = async () => { + const [apeApy, tvlData] = await Promise.all([ + getApecoinApy(), + utils.getData('https://endpoints.jpegd.io/api/tvl'), + ]); + + const APE = '0x4d224452801aced8b2f0aebe155379bb5d594381'; + const apePool = { + pool: '0xD4b06218C545C047ac3ACc7cE49d124C172DB409', + chain: utils.formatChain('ethereum'), + project: 'jpegd', + symbol: utils.formatSymbol('APE'), + rewardTokens: [APE], + underlyingTokens: [APE], + tvlUsd: Number(tvlData.tokenBalancesUsd.ape), + apy: apeApy, + }; + + return [apePool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://jpegd.io/ape-staking', +}; diff --git a/src/adaptors/jupiter-staked-sol/index.js b/src/adaptors/jupiter-staked-sol/index.js new file mode 100644 index 0000000000..a7fef0f052 --- /dev/null +++ b/src/adaptors/jupiter-staked-sol/index.js @@ -0,0 +1,31 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const JUPSOL_ADDRESS = 'jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v'; +const priceKey = `solana:${JUPSOL_ADDRESS}`; + +const apy = async () => { + const [apyResponse, priceResponse, totalSupply] = await Promise.all([ + axios.get('https://worker.jup.ag/lst-apys'), + axios.get(`https://coins.llama.fi/prices/current/${priceKey}`), + getTotalSupply(JUPSOL_ADDRESS), + ]); + + const apyValue = apyResponse.data.apys[JUPSOL_ADDRESS]; + const currentPrice = priceResponse.data.coins[priceKey].price; + const tvlUsd = totalSupply * currentPrice; + + return [ + { + pool: JUPSOL_ADDRESS, + chain: 'Solana', + project: 'jupiter-staked-sol', + symbol: 'JUPSOL', + tvlUsd: tvlUsd, + apyBase: apyValue * 100, + underlyingTokens: [JUPSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://station.jup.ag/guides/jupsol/jupsol' }; diff --git a/src/adaptors/justlend/index.js b/src/adaptors/justlend/index.js new file mode 100644 index 0000000000..5c8f1b560e --- /dev/null +++ b/src/adaptors/justlend/index.js @@ -0,0 +1,64 @@ +const utils = require('../utils'); + +const API_URL = 'https://labc.ablesdxd.link/justlend/yieldInfos'; + +const getMarketDetails = async (tokedAddress) => { + const details = await utils.getData( + `https://labc.ablesdxd.link/justlend/markets/jtokenDetails?jtokenAddr=${tokedAddress}` + ); + + return details; +}; + +const getRewardApy = async (marketsData) => { + const tokens = marketsData.map( + ({ data: { jtokenAddress } }) => jtokenAddress + ); + const tvls = marketsData.map(({ data: { depositedUSD } }) => depositedUSD); + const rewards = await utils.getData( + `https://labc.ablesdxd.link/sunProject/tronbull?pool=${tokens.join( + ',' + )}&tvl=${tvls.join(',')}` + ); + + return rewards; +}; + +const getApy = async () => { + const tokensData = await utils.getData(API_URL); + const tokensAddress = tokensData.data.assetList.map( + ({ jtokenAddress }) => jtokenAddress + ); + + const marketsData = await Promise.all(tokensAddress.map(getMarketDetails)); + const { data: rewards } = await getRewardApy(marketsData); + + const pools = marketsData.map(({ data: market }) => { + console.log(market); + return { + pool: market.jtokenAddress, + chain: utils.formatChain('tron'), + project: 'justlend', + symbol: market.collateralSymbol, + tvlUsd: Number(market.depositedUSD) - Number(market.borrowedUSD), + apyBase: + ((Number(market.earnUSDPerDay) * 365) / Number(market.depositedUSD)) * + 100, + apyReward: rewards[market.jtokenAddress]['USDDNEW'] * 100, + rewardTokens: ['TPYmHEhy5n8TCEfYGqW2rPxsghSfzghPDn'], + underlyingTokens: [market.collateralAddress], + apyBaseBorrow: market.borrowedAPY * 100, + totalSupplyUsd: Number(market.depositedUSD), + totalBorrowUsd: Number(market.borrowedUSD), + ltv: market.collateralFactor, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://justlend.just.network/#/market', +}; diff --git a/src/adaptors/k9-finance-dao/index.js b/src/adaptors/k9-finance-dao/index.js new file mode 100644 index 0000000000..b17ba5360c --- /dev/null +++ b/src/adaptors/k9-finance-dao/index.js @@ -0,0 +1,31 @@ +const utils = require('../utils'); + +const SHIBARIUM_CHAIN_NAME = 'shibarium'; + +const API_URL = 'https://adapters.k9finance.com/pools'; + +const getPoolsData = async () => { + const poolsResponse = await utils.getData(API_URL); + + const poolsData = poolsResponse.map((pool) => { + return { + chain: utils.formatChain(SHIBARIUM_CHAIN_NAME), + pool: pool.pool, + symbol: `${utils.formatSymbol(pool.symbol)}`, + underlyingTokens: [pool.underlying_token], + rewardTokens: [pool.reward_token], + tvlUsd: pool.tvlUsd, + apy: pool.apy, + project: 'k9-finance-dao', + poolMeta: 'V2 pool with zap/unzap option (zap fees applied)', + url: `https://app.k9finance.com/farming/${pool.pool}`, + }; + }); + + return poolsData; +}; + +module.exports = { + timetravel: false, + apy: getPoolsData, +}; diff --git a/src/adaptors/kagla-finance/index.js b/src/adaptors/kagla-finance/index.js new file mode 100644 index 0000000000..0e1e7d3622 --- /dev/null +++ b/src/adaptors/kagla-finance/index.js @@ -0,0 +1,94 @@ +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const KGL_API_BASE_URL = 'https://api.kagla.finance/api/kagla/'; + +const getPools = async () => { + const { pools } = await utils.getData(KGL_API_BASE_URL + 'pools'); + + return pools; +}; + +const getMarkets = async () => { + const { + market: { pools: market }, + } = await utils.getData(KGL_API_BASE_URL + 'market/overview'); + return market; +}; + +const getPoolsData = async () => { + const pools = await getPools(); + const market = await getMarkets(); + + return pools.map((pool) => { + const poolMarket = market.find((item) => item.address == pool.address); + return { + ...pool, + gauges: poolMarket?.gauges || [], + }; + }); +}; + +const getAssetPrice = async () => { + const assets = { + ASTR: 'astar:0xecc867de9f5090f55908aaa1352950b9eed390cd', + LAY: 'astar:0xc4335b1b76fa6d52877b3046eca68f6e708a27dd', + KGL: 'astar:0x257f1a047948f73158dadd03eb84b34498bcdc60', + }; + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${Object.entries(assets)}` + ); + + return { + 0: 1, + 5: prices[assets.ASTR]?.price, + 6: prices[assets.KGL]?.price, + 7: prices[assets.LAY]?.price, + }; +}; + +const convertAPR2APY = (apr) => { + return (apy = Math.pow(apr / 12 + 1, 12) - 1); +}; + +const getApy = async () => { + const chain = 'astar'; + const poolsData = await getPoolsData(); + const prices = await getAssetPrice(); + + return poolsData + .map((pool) => { + const { + assetType, + underlyingCoins, + lpToken: { totalSupply, virtualPrice, address: lpAddress }, + gauges: [gauge], + } = pool; + const decimals = 18; + let tvlUsd = + (totalSupply * virtualPrice * prices[assetType]) / + (10 ** decimals) ** 2; + + const apy = convertAPR2APY(gauge?.minAPR) * 100; + return { + pool: pool.address, + chain: chain, + project: 'kagla-finance', + symbol: pool.name, + tvlUsd: tvlUsd, + apyReward: apy, + underlyingTokens: underlyingCoins.map((coin) => coin.address), + rewardTokens: [lpAddress], + url: `https://kagla.finance/app/pools/${pool.address}`, + }; + }) + .sort((pool) => pool.tvlUsd > 0) + .filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/kai-finance/index.js b/src/adaptors/kai-finance/index.js new file mode 100644 index 0000000000..244a1dbaf9 --- /dev/null +++ b/src/adaptors/kai-finance/index.js @@ -0,0 +1,128 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); + +const RPC_URL = 'https://fullnode.mainnet.sui.io' + +const VAULTS = [ + { + id: '0x7a2f75a3e50fd5f72dfc2f8c9910da5eaa3a1486e4eb1e54a825c09d82214526', + coinType: '0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN', // wUSDC + }, + { + id: '0x0fce8baed43faadf6831cd27e5b3a32a11d2a05b3cd1ed36c7c09c5f7bcb4ef4', + coinType: '0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN', // wUSDT + }, + { + id: '0x16272b75d880ab944c308d47e91d46b2027f55136ee61b3db99098a926b3973c', + coinType: '0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI', // SUI + }, + { + id: '0x3e8a6d1e29d2c86aed50d6055863b878a7dd382de22ea168177c80c1d7150061', + coinType: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC', // USDC + }, + { + id: '0xbfcab5f22e253be0768e2cc5e75e170c5266edf7b68c813af0d676e84285681c', + coinType: '0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT', // USDT + }, + { + id: '0x02ec915b35fb958ca9a7d94e57d7254513ff711832ba8aebfc0ac3395152260b', + coinType: '0x960b531667636f39e85867775f52f6b1f220a058c4de786905bdf761e06a56bb::usdy::USDY' // USDY + }, + { + id: '0x6e58792dccbaa1d1d708d9a847a7c5b3f90c7878d1b76fd79afa48d31063bca6', + coinType: '0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP' // DEEP + }, + { + id: '0x4ee20ca2594e137a1388d5de03c0b1f3dd7caddefb4c55b1c7bca15d0fe18c86', + coinType: '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL' // WAL + }, + { + id: '0x5674aae155d38e09edaf3163f2e3f85fe77790f484485f0b480ca55915d7c446', + coinType: '0xaafb102dd0902f5055cadecd687fb5b71ca82ef0e0285d90afde828ec58ca96b::btc::BTC' // wBTC + }, + { + id: '0x362ce1fc1425ec0bdf958f2023b07cda52c924fa42e4ff88a9a48c595fd8437d', + coinType: '0x3e8e9423d80e1774a7ca128fccd8bf5f1f7753be658c5e645929037f7c819040::lbtc::LBTC' // LBTC + }, + { + id: '0x653beede5a005272526f0c835c272ef37491dc5bff3f8e466175e02675510137', + coinType: '0x876a4b7bce8aeaef60464c11f4026903e9afacab79b9b142686158aa86560b50::xbtc::XBTC' // xBTC + } +] + +async function getCoinInfos(coinTypes) { + const usdcType = '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC' + const response = await fetch(`https://coins.llama.fi/prices/current/${coinTypes.map(c=>`sui:${c}`).join(',')}`) + + const json = await response.json(); + return coinTypes.map(coinType => json.coins[`sui:${coinType}`]); +} + +async function getApyData() { + const vaultIds = VAULTS.map(vault => vault.id); + const coinTypes = VAULTS.map(vault => vault.coinType); + + const [vaultsResponse, coinInfos] = await Promise.all([axios.post(RPC_URL, { + jsonrpc: "2.0", + id: 1, + method: "sui_multiGetObjects", + params: [ + vaultIds, + { + showContent: true, + } + ] + }), + getCoinInfos(coinTypes) + ]); + + const apyData = []; + for (let i = 0; i < vaultsResponse.data.result.length; i++) { + const vaultInfo = VAULTS[i]; + const vaultResponse = vaultsResponse.data.result[i]; + const coinInfo = coinInfos[i] + + const vaultData = vaultResponse.data.content.fields; + const tlp = vaultData.time_locked_profit.fields; + + let tvl = BigNumber(vaultData.free_balance) + for (const strategy of vaultData.strategies.fields.contents) { + tvl = tvl.plus(BigNumber(strategy.fields.value.fields.borrowed)) + } + const tvlUsd = tvl.div(10 ** coinInfo.decimals).times(coinInfo.price).toNumber(); + + const now = Date.now() / 1000; + let unlockPerSecond = new BigNumber(tlp.unlock_per_second) + if (now > Number(tlp.final_unlock_ts_sec)) { + unlockPerSecond = new BigNumber(0) + } + + let apr + const unlockPerYear = unlockPerSecond.times(365 * 24 * 60 * 60); + if (tvl.gt(0)) { + apr = unlockPerYear.div(tvl).toNumber() + } else { + apr = 0 + } + const apy = utils.aprToApy(apr * 100) + + apyData.push({ + pool: vaultInfo.id, + chain: utils.formatChain('sui'), + project: 'kai-finance', + symbol: coinInfo.symbol, + apy, + tvlUsd, + }) + } + + return apyData; +}; + +module.exports = { + timetravel: false, + apy: getApyData, + url: 'https://kai.finance', +}; \ No newline at end of file diff --git a/src/adaptors/kamino-lend/index.js b/src/adaptors/kamino-lend/index.js new file mode 100644 index 0000000000..6efb2d1da7 --- /dev/null +++ b/src/adaptors/kamino-lend/index.js @@ -0,0 +1,36 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getApy = async () => { + const markets = ['7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF']; + const reserveApys = []; + for (const market of markets) { + const reserves = (await axios.get(`https://api.kamino.finance/kamino-market/${market}/reserves/metrics?env=mainnet-beta`)).data; + + reserveApys.push( + ...reserves.map((r) => { + return { + pool: r.reserve, + chain: 'Solana', + project: 'kamino-lend', + symbol: utils.formatSymbol(r.liquidityToken), + underlyingTokens: [r.liquidityTokenMint], + tvlUsd: Number(r.totalSupplyUsd - r.totalBorrowUsd), + url: `https://app.kamino.finance/lending/reserve/${r.reserve}`, + apyBase: Number(r.supplyApy) * 100, + totalSupplyUsd: Number(r.totalSupplyUsd), + totalBorrowUsd: Number(r.totalBorrowUsd), + apyBaseBorrow: Number(r.borrowApy) * 100, + ltv: Number(r.maxLtv), + }; + }) + ); + } + + return reserveApys; +}; + +module.exports = { + apy: getApy, + url: 'https://app.kamino.finance/', +}; diff --git a/src/adaptors/kamino-liquidity/index.js b/src/adaptors/kamino-liquidity/index.js new file mode 100644 index 0000000000..c0aaf25741 --- /dev/null +++ b/src/adaptors/kamino-liquidity/index.js @@ -0,0 +1,50 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getApy = async () => { + const strategies = ( + await axios.get( + 'https://api.kamino.finance/strategies/metrics?env=mainnet-beta&status=LIVE' + ) + ).data; + + const volume = ( + await axios.get( + 'https://api.kamino.finance/v2/strategies/volume?env=mainnet-beta' + ) + ).data; + + const apy = strategies.map((p) => { + const strategyVolume = volume.find((x) => x.strategy === p.strategy); + return { + pool: p.strategy, + chain: 'Solana', + project: 'kamino-liquidity', + symbol: utils.formatSymbol(`${p.tokenA}-${p.tokenB}`), + underlyingTokens: [p.tokenAMint, p.tokenBMint], + rewardTokens: p.krewardMints, + tvlUsd: Number(p.totalValueLocked), + url: `https://app.kamino.finance/liquidity/${p.strategy}`, + apyBase: Number(p.kaminoApy.vault.apy24h) * 100, + apyBase7d: Number(p.kaminoApy.vault.apy7d) * 100, + apyReward: + p.kaminoApy.kamino.reduce( + (partialSum, x) => partialSum + Number(x.apy), + 0 + ) * 100, + volumeUsd1d: Number( + strategyVolume?.kaminoVolume.find((x) => x.period === '24h')?.amount + ), + volumeUsd7d: Number( + strategyVolume?.kaminoVolume.find((x) => x.period === '7d')?.amount + ), + }; + }); + + return apy; +}; + +module.exports = { + apy: getApy, + url: 'https://app.kamino.finance/', +}; diff --git a/src/adaptors/kaspacom-dex/index.js b/src/adaptors/kaspacom-dex/index.js new file mode 100644 index 0000000000..e25cea4eae --- /dev/null +++ b/src/adaptors/kaspacom-dex/index.js @@ -0,0 +1,198 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const { chunk } = require('lodash'); + +const utils = require('../utils'); + +const SUBGRAPH_URL = + 'https://graph-kasplex.kaspa.com/subgraphs/name/kasplex-kas-v2-core'; +const CHAIN = 'kasplex'; +const FEE_RATE = 0.01; +const PAGE_SIZE = 1000; +const DAY_IN_SECONDS = 86400; + +const PAIRS_QUERY = gql` + query getPairs($first: Int!, $skip: Int!) { + pairs( + first: $first + skip: $skip + orderBy: reserveKAS + orderDirection: desc + ) { + id + token0 { + id + symbol + } + token1 { + id + symbol + } + reserveKAS + trackedReserveKAS + reserve0 + reserve1 + volumeKAS + } + } +`; + +const PAIR_DAY_DATA_QUERY = gql` + query getPairDayData($pairAddresses: [Bytes!]!, $startTime: Int!) { + pairDayDatas( + first: 1000 + orderBy: date + orderDirection: desc + where: { pairAddress_in: $pairAddresses, date_gt: $startTime } + ) { + date + pairAddress + dailyVolumeKAS + } + } +`; + +const fetchKasPrice = async () => { + try { + const priceKey = 'coingecko:kaspa'; + const kaspa = ( + await utils.getData(`https://coins.llama.fi/prices/current/${priceKey}`) + ).coins[priceKey].price; + if (Number.isFinite(kaspa) && kaspa > 0) return kaspa; + } catch (error) { + console.log('Kas price from CoinGecko failed, falling back to API', error); + try { + const { data } = await axios.get('https://api.kaspa.org/info/price'); + const price = Number(data.price); + if (Number.isFinite(price) && price > 0) return price; + } catch (fallbackError) { + console.log('Kas price from API also failed', fallbackError); + } + } + + return 0; +}; + +const fetchPairs = async () => { + const pairs = []; + let skip = 0; + + while (true) { + const { pairs: page } = await request(SUBGRAPH_URL, PAIRS_QUERY, { + first: PAGE_SIZE, + skip, + }); + pairs.push(...page); + if (page.length < PAGE_SIZE) break; + skip += PAGE_SIZE; + } + + return pairs; +}; + +const fetchPairDayData = async (pairIds) => { + if (pairIds.length === 0) return { daily: {}, weekly: {} }; + + const startWeek = Math.floor(Date.now() / 1000) - 7 * DAY_IN_SECONDS; + const volumes = {}; + const latestDaily = {}; + + for (const batch of chunk(pairIds, 75)) { + const { pairDayDatas } = await request(SUBGRAPH_URL, PAIR_DAY_DATA_QUERY, { + pairAddresses: batch, + startTime: startWeek, + }); + + pairDayDatas.forEach((entry) => { + const pairAddress = entry.pairAddress?.toLowerCase(); + const volumeKas = Number(entry.dailyVolumeKAS); + if (!pairAddress || !Number.isFinite(volumeKas)) return; + + if (!volumes[pairAddress]) { + volumes[pairAddress] = 0; + } + volumes[pairAddress] += volumeKas; + + if ( + !latestDaily[pairAddress] || + entry.date > latestDaily[pairAddress].date + ) { + latestDaily[pairAddress] = { + date: entry.date, + volumeKas, + }; + } + }); + } + + return { + daily: Object.fromEntries( + Object.entries(latestDaily).map(([pair, { volumeKas }]) => [ + pair, + volumeKas, + ]) + ), + weekly: volumes, + }; +}; + +const buildPools = (pairs, volumeData, kasPrice) => { + const { daily, weekly } = volumeData; + + return pairs + .map((pair) => { + const pairId = pair.id.toLowerCase(); + const kasReserve = + Number(pair.trackedReserveKAS ?? pair.reserveKAS ?? 0) || 0; + if (!(Number.isFinite(kasReserve) && kasReserve > 10000)) return null; + const tvlUsd = kasReserve * kasPrice; + + const volumeKas1d = daily[pairId] ?? 0; + const volumeKas7d = weekly[pairId] ?? 0; + + const volumeUsd1d = volumeKas1d * kasPrice; + const volumeUsd7d = volumeKas7d * kasPrice; + + const apyBase = + tvlUsd > 0 ? ((volumeUsd1d * FEE_RATE * 365) / tvlUsd) * 100 : 0; + const apyBase7d = + tvlUsd > 0 ? ((volumeUsd7d * FEE_RATE * 52) / tvlUsd) * 100 : 0; + + const symbol = utils.formatSymbol( + `${pair.token0.symbol}-${pair.token1.symbol}` + ); + + return { + pool: `${pair.id}-${CHAIN}`, + chain: CHAIN, + project: 'kaspacom-dex', + symbol, + tvlUsd, + apyBase, + apyBase7d, + volumeUsd1d, + volumeUsd7d, + underlyingTokens: [pair.token0.id, pair.token1.id], + url: 'https://defi.kaspa.com', + }; + }) + .filter((pool) => pool && utils.keepFinite(pool)); +}; + +const apy = async () => { + const [pairs, kasPrice] = await Promise.all([fetchPairs(), fetchKasPrice()]); + if (!pairs.length || !Number.isFinite(kasPrice) || kasPrice <= 0) { + return []; + } + + const pairIds = pairs.map((pair) => pair.id.toLowerCase()); + const volumeData = await fetchPairDayData(pairIds); + + return buildPools(pairs, volumeData, kasPrice); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://defi.kaspa.com', +}; diff --git a/src/adaptors/kava-mint/index.js b/src/adaptors/kava-mint/index.js new file mode 100644 index 0000000000..8460ed1c89 --- /dev/null +++ b/src/adaptors/kava-mint/index.js @@ -0,0 +1,132 @@ +const axios = require('axios'); +const superagent = require('superagent'); +const utils = require('../utils'); +const USDX_ID = 'usdx'; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + return pricesObj; +}; + +const main = async () => { + const parametersUrl = 'https://api2.kava.io/kava/cdp/v1beta1/params'; + const dispoistedUrl = 'https://api2.kava.io/kava/cdp/v1beta1/totalCollateral'; + const principalUrl = 'https://api2.kava.io/kava/cdp/v1beta1/totalPrincipal'; + + const [parametersCall, dispoistedCall, principalCall] = ( + await Promise.all([ + axios.get(parametersUrl), + axios.get(dispoistedUrl), + axios.get(principalUrl), + ]) + ).map((e) => e.data); + + const parameters = parametersCall.params.collateral_params.map((e) => { + return { + ...convertSymbol(e.denom), + stability_fee: e.stability_fee, + type: e.type, + liquidation_ratio: e.liquidation_ratio, + debt_limit: e.debt_limit.amount, + }; + }); + + const dispoisted = dispoistedCall.total_collateral.map((e) => { + const info = convertSymbol(e.amount.denom); + return { + ...info, + amount: Number(e.amount.amount / 10 ** (info?.decimals || 0)), + type: e.collateral_type, + }; + }); + + const borrowed = principalCall.total_principal.map((e) => { + const info = convertSymbol(e.collateral_type.split('-')[0]); + return { + ...info, + amount: Number(e.amount.amount / 10 ** 6), + type: e.collateral_type, + }; + }); + + const coins = dispoisted.map((e) => `coingecko:${e.id}`); + const prices = await getPrices([...coins, `coingecko:${USDX_ID}`]); + + return parameters + .filter((e) => e.id) + .map((pool) => { + const parameter = parameters.find((e) => e.type === pool.type); + const collateral = dispoisted.find((e) => e.type === pool.type); + const _borrowed = borrowed.find((e) => e.type === pool.type); + const totalSupplyUsd = collateral.amount * prices[pool.id.toLowerCase()]; + const totalBorrowUsd = _borrowed.amount * prices[USDX_ID.toLowerCase()]; + const ltv = 1 / Number(parameter.liquidation_ratio); + const debtCeilingUsd = + Number(parameter.debt_limit / 10 ** 6) * prices[USDX_ID.toLowerCase()]; + return { + pool: `${pool.id}-${pool.symbol}-${pool.type}`, + chain: utils.formatChain('kava'), + project: 'kava-mint', + symbol: pool.symbol, + tvlUsd: totalSupplyUsd, + apy: 0, + poolMeta: pool.type, + apyBaseBorrow: + pool.type === 'busd-b' + ? 50 + : (Number(parameter.stability_fee) ** 31536000 - 1) * 100, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + ltv: ltv, + debtCeilingUsd: debtCeilingUsd, + mintedCoin: 'USDX', + }; + }); +}; + +function convertSymbol(symbol) { + switch (symbol) { + case 'bnb': + return { id: 'binancecoin', decimals: 8, symbol: 'WBNB' }; + case 'btcb': + return { id: 'bitcoin', decimals: 8, symbol: 'WBTC' }; + case 'busd': + return { id: 'binance-usd', decimals: 8, symbol: 'BUSD' }; + case 'hard': + return { id: 'kava-lend', decimals: 6, symbol: 'HARD' }; + case 'hbtc': + return { id: 'bitcoin', decimals: 8, symbol: 'WBTC' }; + case 'swp': + return { id: 'kava-swap', decimals: 6, symbol: 'SWP' }; + case 'ukava': + return { id: 'kava', decimals: 6, symbol: 'KAVA' }; + case 'xrpb': + return { id: 'ripple', decimals: 8, symbol: 'XRP' }; + case 'ibc/B448C0CA358B958301D328CCDC5D5AD642FC30A6D3AE106FF721DB315F3DDE5C': + return { id: 'terra-usd', decimals: 6, symbol: 'UST' }; + case 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2': + return { id: 'kava-swap', decimals: 6, symbol: 'SWP' }; + default: + console.log(symbol); + } +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.kava.io/', +}; diff --git a/src/adaptors/kelp/index.js b/src/adaptors/kelp/index.js new file mode 100644 index 0000000000..b4133728c2 --- /dev/null +++ b/src/adaptors/kelp/index.js @@ -0,0 +1,68 @@ +const sdk = require('@defillama/sdk'); + +const axios = require('axios'); + +async function getTokenPrice(chain, token) { + const data = await axios.get( + `https://coins.llama.fi/prices/current/${chain}:${token}` + ); + return data.data.coins[`${chain}:${token}`]?.price; +} + +const rsETH = '0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7'; +const DEPOSIT_POOL = '0x036676389e48133B63a802f8635AD39E752D375D'; +const apy = async () => { + const apy = (await axios.get('https://universe.kelpdao.xyz/rseth/apy')).data + .value; + const config = ( + await sdk.api.abi.call({ abi: 'address:lrtConfig', target: DEPOSIT_POOL }) + ).output; + const tokens = ( + await sdk.api.abi.call({ + abi: 'address[]:getSupportedAssetList', + target: config, + }) + ).output; + + let tvlUsd = 0; + for (let token of tokens) { + const balance = ( + await sdk.api.abi.call({ + abi: 'function getTotalAssetDeposits(address) external view returns (uint)', + params: [token], + target: DEPOSIT_POOL, + }) + ).output; + + let decimals = 18; + if (token !== '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') { + decimals = ( + await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: token, + }) + ).output; + } + + const tokenPrice = await getTokenPrice('ethereum', token); + tvlUsd += (balance * tokenPrice) / 10 ** decimals; + } + + return [ + { + pool: `${rsETH}-ethereum`.toLowerCase(), + chain: 'Ethereum', + project: 'kelp', + symbol: 'rsETH', + underlyingTokens: tokens, + tvlUsd, + apy, + url: 'https://kelpdao.xyz/restake/', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/keom-protocol/Abis.ts b/src/adaptors/keom-protocol/Abis.ts new file mode 100644 index 0000000000..dd18bac90a --- /dev/null +++ b/src/adaptors/keom-protocol/Abis.ts @@ -0,0 +1,43 @@ +const keomABI = [ + 'function supplyRatePerTimestamp() view returns (uint256)', + 'function borrowRatePerTimestamp() view returns (uint256)', + 'function exchangeRateStored() view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function name() external view returns (string memory)', + 'function totalSupply() view returns (uint256)', + 'function totalBorrows() external view returns(uint)', + 'function symbol() external view returns (string)', + 'function underlying() external view returns (address)', +]; + +const erc20ABI = [ + 'function decimals() external pure returns (uint8)', + 'function balanceOf(address owner) external view returns (uint256 balance)', +]; + +const unitrollerABI = [ + 'function getAllMarkets() external view returns(address[] memory)', + 'function markets(address) external view returns(bool isListed,bool autoCollaterize,uint256 collateralFactorMantissa)', +]; + +const oracleABI = [ + 'function getUnderlyingPrice(address oToken) view returns (uint)', + 'function borrowBalanceStored(address account) view returns (uint256)', +]; + +const rewardsManagerABI = [ + "function getMarketRewardSpeeds(address rewardToken, address market) view returns (uint256 supplySpeed, uint256 borrowSpeed)", + "function getRewardTokensForMarket(address market) view returns (address[] memory)", + "function getRewardedMarkets(IKToken[] calldata markets, address rewardToken) view returns (bool[])", + "function getAllRewardsTokens() external view returns (address[])" +] + + + +module.exports = { + keomABI, + erc20ABI, + unitrollerABI, + oracleABI, + rewardsManagerABI +}; diff --git a/src/adaptors/keom-protocol/Provider.ts b/src/adaptors/keom-protocol/Provider.ts new file mode 100644 index 0000000000..6903fc1e93 --- /dev/null +++ b/src/adaptors/keom-protocol/Provider.ts @@ -0,0 +1,11 @@ +const ethers = require('ethers'); + +// initialize the provider -- can be hot-swapped with any other RPC Provider with instant flow-down through all functions +const PROVIDERS = { + polygon: new ethers.providers.JsonRpcProvider('https://polygon-rpc.com'), + polygon_zkevm: new ethers.providers.JsonRpcProvider('https://zkevm-rpc.com'), + manta: new ethers.providers.JsonRpcProvider('https://1rpc.io/manta'), + astrzk: new ethers.providers.JsonRpcProvider('https://rpc.astar-zkevm.gelato.digital'), +} + +module.exports = { PROVIDERS }; diff --git a/src/adaptors/keom-protocol/index.js b/src/adaptors/keom-protocol/index.js new file mode 100644 index 0000000000..b824252b40 --- /dev/null +++ b/src/adaptors/keom-protocol/index.js @@ -0,0 +1,454 @@ +const { ethers } = require('ethers'); +const { + keomABI, + unitrollerABI, + erc20ABI, + oracleABI, + preminingABI, + rewardsManagerABI, +} = require('./Abis'); +const { PROVIDERS } = require('./Provider'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const decimals = ethers.utils.parseEther('1'); +const BN = ethers.BigNumber.from; +const retry = require('async-retry'); + +function createFallbackProvider(rpcs, chainId = 1101) { + const providers = rpcs.map( + (rpc) => new ethers.providers.JsonRpcProvider(rpc, chainId) + ); + return new ethers.providers.FallbackProvider(providers, 1); +} + +const chains = { + polygon: { + comptroller: '0x5B7136CFFd40Eee5B882678a5D02AA25A48d669F', + oracle: '0x17feC0DD2c6BC438Fd65a1d2c53319BEA130BEFb', + wnative: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', + rewardManager: '', + }, + polygon_zkevm: { + comptroller: '0x6EA32f626e3A5c41547235ebBdf861526e11f482', + oracle: '0x483aDB7c100F1E19369a7a33c80709cfdd124c4e', + wnative: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9', + rewardManager: '', + }, + manta: { + comptroller: '0x91e9e99AC7C39d5c057F83ef44136dFB1e7adD7d', + oracle: '0xfD01946C35C98D71A355B8FF18d9E1697b2dd2Ea', + wnative: '0x0Dc808adcE2099A9F62AA87D9670745AbA741746', + rewardManager: '0xfcA6fa66a83Cf0D5DB05d882e5A04dfbe9Eea214', + }, + isolated_manta_wusdm: { + comptroller: '0x014991ec771aD943A487784cED965Af214FD253C', + oracle: '0xfD01946C35C98D71A355B8FF18d9E1697b2dd2Ea', + wnative: '0x0Dc808adcE2099A9F62AA87D9670745AbA741746', + rewardManager: '0xC51b8519D183ff75a23873EAACfA20E7D1191EC9', + }, + isolated_manta_stone: { + comptroller: '0xBAc1e5A0B14490Dd0b32fE769eb5637183D8655d', + oracle: '0xfD01946C35C98D71A355B8FF18d9E1697b2dd2Ea', + wnative: '0x0Dc808adcE2099A9F62AA87D9670745AbA741746', + rewardManager: '0xf6681028D895921ddb5eD625282C7121D92E36F7', + }, + astrzk: { + comptroller: '0xcD906c5f632daFCBD23d574f85294B32E7986fD9', + oracle: '0x5798beC729579c65A496fc18577d627E6aB5e2F2', + wnative: '0x79D7c05352a900bE30992D525f946eA939f6FA3E', + rewardManager: '', + }, +}; + +async function main() { + const chainPromises = Object.entries(chains).map( + async ([name, chainData]) => { + return retry( + async (bail) => { + let provider = PROVIDERS[name]; + let chain = name; + + if ( + name === 'isolated_manta_wusdm' || + name === 'isolated_manta_stone' + ) { + chain = 'manta'; + provider = PROVIDERS[chain]; + } + const comptroller = new ethers.Contract( + chainData.comptroller, + unitrollerABI, + provider + ); + let markets; + try { + markets = ( + await sdk.api.abi.call({ + target: chainData.comptroller, + abi: unitrollerABI.find((abi) => abi.includes('getAllMarkets')), + chain, + }) + ).output; + } catch (error) { + console.error(`Error fetching markets for ${chain}:`, error); + throw error; + } + + const marketPromises = markets.map(async (market) => { + return retry( + async (bail) => { + if (market === '0x95B847BD54d151231f1c82Bf2EECbe5c211bD9bC') + return null; + + const [APYS, tvl, ltv] = await Promise.all([ + getAPY(market, chain), + getErc20Balances(market, chainData.oracle, provider, chain), + ( + await sdk.api.abi.call({ + target: chainData.comptroller, + abi: unitrollerABI.find((abi) => abi.includes('markets')), + params: [market], + chain, + }) + ).output, + ]); + + const [rewardTokens, supplyAPY, borrowAPY] = await getRewardAPY( + chain, + chainData.rewardManager, + market, + tvl.totalSupplyUsd, + tvl.totalBorrowsUsd, + provider + ); + + return { + pool: `${market}-${chain}`, + project: 'keom-protocol', + symbol: + APYS.symbol.slice(1) === 'Native' + ? 'ETH' + : APYS.symbol.slice(1), + chain: chain, + apyBase: APYS.supplyAPY, + apyReward: supplyAPY, + tvlUsd: tvl.tvlUsd, + apyBaseBorrow: APYS.borrowAPY, + apyRewardBorrow: borrowAPY, + rewardTokens: + supplyAPY > 0 || borrowAPY > 0 ? rewardTokens : [], + totalSupplyUsd: tvl.totalSupplyUsd, + totalBorrowUsd: tvl.totalBorrowsUsd, + ltv: parseInt(ltv.collateralFactorMantissa) / 1e18, + }; + }, + { + retries: 3, + onRetry: (err) => { + console.log( + `Retrying market ${market} due to error: ${err.message}` + ); + }, + } + ); + }); + + return (await Promise.all(marketPromises)).filter(Boolean); + }, + { + retries: 3, + onRetry: (err) => { + console.log(`Retrying chain ${name} due to error: ${err.message}`); + }, + } + ); + } + ); + + const results = await Promise.all(chainPromises); + return results.flat(); +} + +async function getRewardAPY( + chain, + rewardManager, + strategy, + tvlSupplyUsd, + tvlBorrowUsd, + provider +) { + if (rewardManager === '') { + return [ethers.constants.AddressZero, 0, 0]; + } + const arr = ( + await sdk.api.abi.call({ + target: rewardManager, + abi: rewardsManagerABI?.find((abi) => + abi.includes('getRewardTokensForMarket') + ), + params: [strategy], + chain, + }) + ).output; + const rewards = arr.filter((addr) => addr !== ethers.constants.AddressZero); + if (rewards.length === 0) { + return [ethers.constants.AddressZero, 0, 0]; + } + + const rewardPromises = rewards.map(async (reward) => { + const [prices, rewardSpeeds] = await Promise.all([ + axios.get(`https://coins.llama.fi/prices/current/${chain}:${reward}`), + sdk.api.abi.call({ + target: rewardManager, + abi: rewardsManagerABI?.find((abi) => + abi.includes('getRewardTokensForMarket') + ), + params: [reward, strategy], + chain, + }), + ]); + + const tokenPriceInUSD = prices.data.coins[`${chain}:${reward}`]?.price || 0; + const [supplySpeed, borrowSpeed] = rewardSpeeds.output; + + const totalSupplyRewardsInUsdForAYear = + supplySpeed * 60 * 60 * 24 * 365 * tokenPriceInUSD; + const totalBorrowRewardsInUsdForAYear = + borrowSpeed * 60 * 60 * 24 * 365 * tokenPriceInUSD; + + const supplyAPY = + ((totalSupplyRewardsInUsdForAYear / tvlSupplyUsd) * 100) / 10 ** 18; + const borrowAPY = + ((totalBorrowRewardsInUsdForAYear / tvlBorrowUsd) * 100) / 10 ** 18; + + return { supplyAPY, borrowAPY }; + }); + + const rewardResults = await Promise.all(rewardPromises); + + const apySupplyMultipliers = []; + const apyBorrowMultipliers = []; + + rewardResults.forEach(({ supplyAPY, borrowAPY }) => { + if (supplyAPY > 0) { + let multiplier = 1 + Number(supplyAPY.toFixed(2)) / 100; + apySupplyMultipliers.push(multiplier); + } + if (borrowAPY > 0) { + let multiplier = 1 + Number(borrowAPY.toFixed(2)) / 100; + apyBorrowMultipliers.push(multiplier); + } + }); + + const supplyAPY = + apySupplyMultipliers.length > 0 + ? (apySupplyMultipliers.reduce((a, b) => a * b) - 1) * 100 + : 0; + + const borrowAPY = + apyBorrowMultipliers.length > 0 + ? (apyBorrowMultipliers.reduce((a, b) => a * b) - 1) * 100 + : 0; + + return [rewards, supplyAPY, borrowAPY]; +} + +async function getAPY(strategy, chain) { + const contract = new ethers.Contract(strategy, keomABI); + + const symbol = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('symbol')), + chain, + }) + ).output; + // retrieve the supply rate per timestamp for the main0vixContract + const supplyRatePerTimestamp = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('supplyRatePerTimestamp')), + chain, + }) + ).output; + + const supplyAPY = calculateAPY(supplyRatePerTimestamp); + + const borrowRatePerTimestamp = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('borrowRatePerTimestamp')), + chain, + }) + ).output; + const borrowAPY = calculateAPY(borrowRatePerTimestamp); + + return { symbol, supplyAPY, borrowAPY }; +} + +function calculateAPY(rate) { + const year = 365 * 24 * 60 * 60; + let a = 1 + rate / 1e18; + a = parseFloat(String(a)); + const b = Math.pow(a, year); + return (b - 1) * 100; +} + +async function getErc20Balances(strategy, oracleAddress, provider, chain) { + // get decimals for the oToken + const oDecimals = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('decimals')), + chain, + }) + ).output; + + // get the total supply + const oTokenTotalSupply = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('totalSupply')), + chain, + }) + ).output; + + // get total borrows + const oTokenTotalBorrows = BN( + ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('totalBorrows')), + chain, + }) + ).output + ); + + // get the exchange rate stored + const oExchangeRateStored = BN( + ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('exchangeRateStored')), + chain, + }) + ).output + ); + + let underlyingDecimals = 18; + let native = false; + let _address = ''; + try { + _address = ( + await sdk.api.abi.call({ + target: strategy, + abi: keomABI?.find((abi) => abi.includes('underlying')), + chain, + }) + ).output; + const _token = new ethers.Contract(_address, erc20ABI, provider); + underlyingDecimals = ( + await sdk.api.abi.call({ + target: _address, + abi: erc20ABI?.find((abi) => abi.includes('decimals')), + chain, + }) + ).output; + } catch (error) { + native = true; + } + + // retrieve the oracle contract + const oracle = new ethers.Contract(oracleAddress, oracleABI, provider); + + // get the underlying price of the asset from the oracle + let oracleUnderlyingPrice = BN('0'); + let apiPrice = 0; + try { + const price = ( + await sdk.api.abi.call({ + target: oracleAddress, + abi: oracleABI?.find((abi) => abi.includes('getUnderlyingPrice')), + params: [strategy], + chain, + }) + ).output; + oracleUnderlyingPrice = BN(price); + } catch (error) { + if (native) { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${chain}:${chains[chain].wnative} ` + ) + ).data.coins; + apiPrice = prices[`${chain}:${chains[chain].wnative}`]?.price; + } else { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${chain}:${_address} ` + ) + ).data.coins; + apiPrice = prices[`${chain}:${_address}`]?.price; + } + } + + // do the conversions + return convertTvlUSD( + oTokenTotalSupply, + oTokenTotalBorrows, + oExchangeRateStored, + oDecimals, + underlyingDecimals, + oracleUnderlyingPrice, + apiPrice + ); +} + +function convertUSDC(balance, exchangeRateStored, decimals) { + return ( + (parseFloat(balance) * parseFloat(exchangeRateStored)) / + Math.pow(1, Math.pow(10, decimals)) / + Math.pow(1, Math.pow(10, 18)) + ); +} + +function convertTvlUSD( + totalSupply, + totalBorrows, + exchangeRateStored, + oDecimals, + underlyingDecimals, + oracleUnderlyingPrice, + apiPrice +) { + let totalSupplyUsd = 0; + let totalBorrowsUsd = 0; + if (!oracleUnderlyingPrice.isZero()) { + let supplyUSD = exchangeRateStored + .mul(oracleUnderlyingPrice) + .div(decimals) + .mul(totalSupply) + .div(decimals); + let borrowUSD = totalBorrows.mul(oracleUnderlyingPrice).div(decimals); + totalSupplyUsd = Number(ethers.utils.formatEther(supplyUSD)); + totalBorrowsUsd = Number(ethers.utils.formatEther(borrowUSD)); + } else { + apiPrice = apiPrice === undefined ? 0 : apiPrice; + let supplyUSD = ethers.utils.formatUnits( + exchangeRateStored.mul(totalSupply).div(decimals), + underlyingDecimals + ); + let borrowUSD = ethers.utils.formatUnits(totalBorrows, underlyingDecimals); + totalSupplyUsd = Number(supplyUSD) * apiPrice; + totalBorrowsUsd = Number(borrowUSD) * apiPrice; + } + const tvlUsd = totalSupplyUsd - totalBorrowsUsd; + + return { totalSupplyUsd, totalBorrowsUsd, tvlUsd }; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.keom.io/', +}; diff --git a/src/adaptors/killswitch/index.js b/src/adaptors/killswitch/index.js new file mode 100644 index 0000000000..cd773855a3 --- /dev/null +++ b/src/adaptors/killswitch/index.js @@ -0,0 +1,166 @@ +const sdk = require('@defillama/sdk'); +const API_APY_URL = (chainId) => + `https://api.killswitch.finance/ksw2/apy?chain=${chainId}`; +const API_TVL_URL = 'https://api.killswitch.finance/ksw/tvl'; +const utils = require('../utils'); +const POOL_ONE_TOKEN = { + bsc: [ + 'apeswap.0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95', + 'belt.0x51bd63f240fb13870550423d208452ca87c44444', + 'belt.0x9cb73f20164e399958261c289eb5f9846f4d1404', + 'belt.0xa8bb71facdd46445644c277f9499dd22f6f0a30c', + 'belt.0xaa20e8cb61299df2357561c2ac2e1172bc68bc25', + 'definix.0x070a9867ea49ce7afc4505817204860e823489fe', + 'definix.0x0f02b1f5af54e04fb6dd6550f009ac2429c4e30d', + 'evry.0xc2d4a3709e076a7a3487816362994a78ddaeabb6', + 'foodcourtv2.0x084bb94e93891d74579b54ab63ed24c4ef9cd5ef', + 'killswitch.0x270178366a592ba598c2e9d2971da65f7baa7c86', + 'luckylion.0xc3d912863152e1afc935ad0d42d469e7c6b05b77', + 'pancake.0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82', + 'samoyed.0xbdb44df0a914c290dfd84c1eaf5899d285717fdc', + ], + aurora: [], + kcc: [], +}; + +const maprewardTokens = { + bsc: { + Banana: 'bsc:0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95', + BELT: 'bsc:0xe0e514c71282b6f4e823703a39374cf58dc3ea4f', + BSW: 'bsc:0x965f527d9159dce6288a2219db51fc6eef120dd1', + Finix: 'bsc:0x0f02b1f5af54e04fb6dd6550f009ac2429c4e30d', + VELO: 'bsc:0xf486ad071f3bEE968384D2E39e2D8aF0fCf6fd46', + Coupon: 'bsc:0x084bb94e93891D74579B54Ab63ED24C4ef9cd5Ef', + LATTEV2: 'bsc:0xa269a9942086f5f87930499dc8317ccc9df2b6cb', + LUCKY: 'bsc:0xc3D912863152E1Afc935AD0D42d469e7C6B05B77', + Cake: 'bsc:0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + SMOY: 'bsc:0xBdb44DF0A914c290DFD84c1eaf5899d285717fdc', + }, + kcc: { + MJT: 'kcc:0x2ca48b4eea5a731c2b54e7c3944dbdb87c0cfb6f', + }, + aurora: { + BRL: 'aurora:0x12c87331f086c3C926248f964f8702C0842Fd77F', + TRI: 'aurora:0xfa94348467f64d5a457f75f8bc40495d33c65abb', + NEAR: 'aurora:0xc42c30ac6cc15fac9bd938618bcaa1a1fae8501d', + WANNA: 'aurora:0x7faa64faf54750a2e3ee621166635feaf406ab22', + }, +}; + +const mapChainId = { + kcc: 321, + aurora: 1313161554, + bsc: 56, +}; + +const mapChain = { + bsc: 'binance', + aurora: 'aurora', + kcc: 'kcc', +}; + +const tokenAbi = (name) => { + return { + inputs: [], + name: name, + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }; +}; + +const getTokenSymbol = async (pair, tokenAddress, chain) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain, + requery: true, + }) + ) + ); + return { + lpToken: pair, + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + }, + }; +}; + +async function getApyByChain(chain, dataTvl) { + const dataApy = await utils.getData(API_APY_URL(mapChainId[chain])); + const lpTokens = Object.keys(dataTvl.data[chain]) + .filter((e) => dataTvl.data[chain][e] !== '0') + .filter((e) => !POOL_ONE_TOKEN[chain].includes(e)); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: tokenAbi(method), + calls: lpTokens.map((address) => ({ + target: address.split('.')[1], + })), + chain: chain, + requery: true, + }) + ) + ); + + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const pools = await Promise.all( + lpTokens.map((pool, i) => + getTokenSymbol(lpTokens[i], [tokens0[i], tokens1[i]], chain).then( + (pair) => { + const apyBase = dataApy[pool]?.details + ? dataApy[pool].details.find((e) => e.title === 'Trading Fee') + : 0; + const apyReward = dataApy[pool]?.details + ? dataApy[pool].details.find((e) => e.title !== 'Trading Fee') + : 0; + const _pool = { + pool: pair.lpToken + `-${chain}`, + chain: utils.formatChain(mapChain[chain]), + project: 'killswitch', + symbol: pair.pairName, + tvlUsd: Number(dataTvl.data[chain][pool] || 0), + apyBase: Number(apyBase?.value || 0) * 100, + apyReward: Number(apyReward?.value || 0) * 100, + rewardTokens: [maprewardTokens[chain][apyReward?.title]], + }; + return _pool; + } + ) + ) + ); + return pools.filter((e) => e.apyReward !== 0); +} + +async function apy() { + const dataTvl = await utils.getData(API_TVL_URL); + const bscApr = await getApyByChain('bsc', dataTvl); + const auroraApr = await getApyByChain('aurora', dataTvl); + const kccApr = await getApyByChain('kcc', dataTvl); + return [...bscApr, ...auroraApr, ...kccApr]; +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.killswitch.finance/', +}; diff --git a/src/adaptors/kiloex/index.js b/src/adaptors/kiloex/index.js new file mode 100644 index 0000000000..c1c7321d7a --- /dev/null +++ b/src/adaptors/kiloex/index.js @@ -0,0 +1,113 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); + +const chains = { + op_bnb: { + kUSDT: '0x1Bc6F42D6D1680115A52F82DFA29265085E91d93', + apyEndpoint: 'https://opapi.kiloex.io/common/queryKiloNewVaultApyHistory', + htokens:'https://opapi.kiloex.io/vault/hTokens' + }, + manta: { + kUSDT: '0xa10f74374b8bE9E9C8Fb62c1Dc17B8D4247E332A', + apyEndpoint: 'https://mantaapi.kiloex.io/common/queryKiloNewVaultApyHistory', + STONE: '0xEc901DA9c68E90798BbBb74c11406A32A70652C3', + htokens:'https://mantaapi.kiloex.io/vault/hTokens' + }, + bsc: { + kUSDT: '0xef7aF0804AAB3885da59a8236fabfA19DDc6Cf48', + apyEndpoint: 'https://api.kiloex.io/common/queryKiloNewVaultApyHistory', + htokens:'https://api.kiloex.io/vault/hTokens' + }, + taiko: { + kUSDT: '0x2646E743A8F47b8d2427dBcc10f89e911f2dBBaa', + apyEndpoint: 'https://taikoapi.kiloex.io/common/queryKiloNewVaultApyHistory', + htokens:'https://taikoapi.kiloex.io/vault/hTokens' + }, + bsquared: { + kUSDT: '0xB20Faa4BA0DdEbDe49299557f4F1ebB5532745e3', + apyEndpoint: 'https://b2api.kiloex.io/common/queryKiloNewVaultApyHistory', + htokens:'https://b2api.kiloex.io/vault/hTokens' + }, + base: { + kUSDT: '0xdf5ACC616cD3ea9556EC340a11B54859a393ebBB', + apyEndpoint: 'https://baseapi.kiloex.io/common/queryKiloNewVaultApyHistory', + htokens:'https://baseapi.kiloex.io/vault/hTokens' + } +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const y = chains[chain]; + let results = []; + + const hTokensData = (await axios.get(y.htokens)).data.data; + const apr = hTokensData.apy + for (const key in hTokensData.tokens) { + try { + const token = hTokensData.tokens[key]; + const balance = + ( + await sdk.api.abi.call({ + target: token.originToken, + abi: 'erc20:balanceOf', + params: [y.kUSDT], + chain, + }) + ).output / token.tokenPrecision; + + results.push({ + chain, + project: 'kiloex', + pool: token.originToken, + symbol: token.tokenName, + tvlUsd: balance * token.price, + apyBase: parseFloat((apr * 100 * token.ltv /10000).toFixed(2)), + underlyingTokens: [token.originToken], + }); + } catch(e) { + //skip error + } + + } + // if (chain === 'manta') { + // const stoneBalance = + // ( + // await sdk.api.abi.call({ + // target: y.STONE, + // abi: 'erc20:balanceOf', + // params: ['0x471C5e8Cc0fEC9aeeb7ABA6697105fD6aaaDFf99'], + // chain, + // }) + // ).output / 1e18; + // + // const priceKey = `manta:${y.STONE}`; + // const price = ( + // await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + // ).data.coins[priceKey].price; + // + // const stoneApy = (await axios.get('https://mantaapi.kiloex.io/sidevault/info')).data.data.apy; + // + // results.push({ + // chain, + // project: 'kiloex', + // pool: y.STONE, + // symbol: 'STONE', + // tvlUsd: stoneBalance * price, + // apyBase: Number(stoneApy) * 100, + // underlyingTokens: [y.STONE], + // }); + // } + return results; + }) + ); + + return utils.removeDuplicates(pools.flat()) +}; + +module.exports = { + apy: getApy, + url: 'https://app.kiloex.io/trade/vault', +}; diff --git a/src/adaptors/kinetic/abi.js b/src/adaptors/kinetic/abi.js new file mode 100644 index 0000000000..eb22a9cf4b --- /dev/null +++ b/src/adaptors/kinetic/abi.js @@ -0,0 +1,1155 @@ +module.exports = { + comptrollerAbi: [{ + "constant": true, + "inputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyRewardSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowRewardSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }], + cToken: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'qiTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isQiToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract QiTokenInterface', + name: 'qiTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + flrETH: [ + { + "inputs": [], + "name": "LSTPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }] +}; diff --git a/src/adaptors/kinetic/index.js b/src/adaptors/kinetic/index.js new file mode 100644 index 0000000000..a6686a1627 --- /dev/null +++ b/src/adaptors/kinetic/index.js @@ -0,0 +1,337 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const { Web3, eth } = require('web3'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { comptrollerAbi, cToken, flrETH } = require('./abi'); +const { symbol } = require('@defillama/sdk/build/erc20'); + +const COMPTROLLER_ADDRESS = '0x8041680Fb73E1Fe5F851e76233DCDfA0f2D2D7c8'; +const ISO_COMPTROLLER_ADDRESS = '0xDcce91d46Ecb209645A26B5885500127819BeAdd'; +const FXRP_ISO_COMPTROLLER_ADDRESS = '0x15F69897E6aEBE0463401345543C26d1Fd994abB'; +const FLR_ETH = '0x26a1fab310bd080542dc864647d05985360b16a5'; +const WETH = '0x1502fa4be69d526124d453619276faccab275d3d'; +const C_ETH_MARKET = '0xd7291D5001693d15b6e4d56d73B5d2cD7eCfE5c6'; +const FLARE_CHAIN = 'flare'; + +const JOULE = { + decimals: 18, + symbol: 'JOULE', + address: "0xe6505f92583103af7ed9974dec451a7af4e3a3be" +}; + +const FLR = { + decimals: 18, + symbol: 'FLR', + address: '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', // same price of WFLR +}; + +const KII = { + decimals: 18, + symbol: 'KII', + address: '0xe6505f92583103af7ed9974dec451a7af4e3a3be', // same price of JOULE +}; + +const RFLR = { + decimals: 18, + symbol: 'RFLR', + address: '0x1d80c49bbbcd1c0911346656b529df9e5c2f783d', // same price of WFLR +}; + +const REWARD_TYPES = { + JOULE: 0, + FLR: 1, + KII: 2, + RFLR: 3 +}; + +const SECONDS_PER_DAY = 86400; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const secondsPerDay = 86400; // seconds per day + const daysPerYear = 365; + + return ( + (Math.pow((ratePerTimestamps / 1e18) * secondsPerDay + 1, daysPerYear) - + 1) * + 100 + ); +}; + +const getRewards = async (rewardType, markets, comptroller, isBorrow = false) => { + return ( + await sdk.api.abi.multiCall({ + chain: FLARE_CHAIN, + calls: markets.map((market) => ({ + target: comptroller, + params: [rewardType, market], + })), + abi: comptrollerAbi.find( + ({ name }) => name === `${isBorrow ? 'borrow' : 'supply'}RewardSpeeds` + ), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: FLARE_CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const getApy = async (comptroller) => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: comptroller, + chain: FLARE_CHAIN, + abi: comptrollerAbi.find(({ name }) => name === 'getAllMarkets'), + permitFailure: true, + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const marketsInfo = ( + await sdk.api.abi.multiCall({ + chain: FLARE_CHAIN, + calls: allMarkets.map((market) => ({ + target: comptroller, + params: market, + })), + abi: comptrollerAbi.find(({ name }) => name === 'markets'), + permitFailure: true, + }) + ).output.map(({ output }) => output); + + const jouleRewards = await getRewards(REWARD_TYPES.JOULE, allMarkets, comptroller); + const flrRewards = await getRewards(REWARD_TYPES.FLR, allMarkets, comptroller); + const kiiRewards = await getRewards(REWARD_TYPES.KII, allMarkets, comptroller); + const rFLRRewards = await getRewards(REWARD_TYPES.RFLR, allMarkets, comptroller); + + const jouleBorrowRewards = await getRewards(REWARD_TYPES.JOULE, allMarkets, comptroller, true); + const flrBorrowRewards = await getRewards(REWARD_TYPES.FLR, allMarkets, comptroller, true); + const kiiBorrowRewards = await getRewards(REWARD_TYPES.KII, allMarkets, comptroller, true); + const rflrBorrowRewards = await getRewards(REWARD_TYPES.RFLR, allMarkets, comptroller, true); + + const supplyRatePerTimestamp = await multiCallMarkets( + allMarkets, + 'supplyRatePerTimestamp', + cToken + ); + + const borrowRatePerTimestamp = await multiCallMarkets( + allMarkets, + 'borrowRatePerTimestamp', + cToken + ); + + const marketsCash = await multiCallMarkets(allMarkets, 'getCash', cToken); + const totalBorrows = await multiCallMarkets( + allMarkets, + 'totalBorrows', + cToken + ); + const totalReserves = await multiCallMarkets( + allMarkets, + 'totalReserves', + cToken + ); + + const tempMarkets = allMarkets.filter(m => m.toLocaleLowerCase() != C_ETH_MARKET.toLocaleLowerCase()) + + let underlyingTokens = await multiCallMarkets( + tempMarkets, + 'underlying', + cToken + ); + + let underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + cToken + ); + + let underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + cToken + ); + + if(underlyingTokens.length != allMarkets.length){ + underlyingTokens = underlyingTokens.concat([FLR.address]); + underlyingSymbols = underlyingSymbols.concat('FLR'); + underlyingDecimals = underlyingDecimals.concat(18); + } + + const prices = await getPrices( + underlyingTokens.concat([FLR.address, JOULE.address]).map((token) => 'flare:' + token) + ); + + if(!prices[FLR_ETH]){ + const wethPrice = prices[WETH]; + if(wethPrice){ + const flrETHToETH = ( + await sdk.api.abi.call({ + target: FLR_ETH, + chain: FLARE_CHAIN, + abi: flrETH.find(({ name }) => name === 'LSTPerToken'), + permitFailure: true, + }) + ).output; + + if(flrETHToETH){ + prices[FLR_ETH] = wethPrice * (flrETHToETH / 10 ** 18); + } + } + } + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i]; + const decimals = Number(underlyingDecimals[i]); + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + prices[token.toLowerCase()]; + + const totalBorrowUsd = + (Number(totalBorrows[i]) / 10 ** decimals) * prices[token.toLowerCase()]; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRatePerTimestamp[i]); + const apyBaseBorrow = calculateApy(borrowRatePerTimestamp[i]); + + const jouleApy = + ((1 + ( + ( + (jouleRewards[i] / 10 ** JOULE.decimals) * + SECONDS_PER_DAY * + prices[JOULE.address] + ) / + totalSupplyUsd))**365 - 1) * 100; + const flrApy = + ((1 + ( + ( + (flrRewards[i] / 10 ** FLR.decimals) * + SECONDS_PER_DAY * + prices[FLR.address] + ) / + totalSupplyUsd))**365 - 1) * 100; + const kiiApy = + ((1 + ( + ( + (kiiRewards[i] / 10 ** KII.decimals) * + SECONDS_PER_DAY * + prices[KII.address] + ) / + totalSupplyUsd))**365 - 1) * 100; + const rflrApy = + ((1 + ( + ( + (rFLRRewards[i] / 10 ** RFLR.decimals) * + SECONDS_PER_DAY * + prices[RFLR.address] + ) / + totalSupplyUsd))**365 - 1) * 100; + + const jouleBorrowApy = + ((1 + ( + ( + (jouleBorrowRewards[i] / 10 ** JOULE.decimals) * + SECONDS_PER_DAY * + prices[JOULE.address] + ) / + totalBorrowUsd))**365 - 1) * 100; + const flrBorrowApy = + ((1 + ( + ( + (flrBorrowRewards[i] / 10 ** FLR.decimals) * + SECONDS_PER_DAY * + prices[FLR.address] + ) / + totalBorrowUsd))**365 - 1) * 100; + const kiiBorrowApy = + ((1 + ( + ( + (kiiBorrowRewards[i] / 10 ** KII.decimals) * + SECONDS_PER_DAY * + prices[KII.address] + ) / + totalBorrowUsd))**365 - 1) * 100; + const rflrBorrowApy = + ((1 + ( + ( + (rflrBorrowRewards[i] / 10 ** RFLR.decimals) * + SECONDS_PER_DAY * + prices[RFLR.address] + ) / + totalBorrowUsd))**365 - 1) * 100; + + const apyRewardBorrow = jouleBorrowApy + flrBorrowApy + kiiBorrowApy + rflrBorrowApy; + + return { + pool: market, + chain: utils.formatChain('flare'), + project: 'kinetic', + symbol: underlyingSymbols[i], + tvlUsd, + apyBase, + apyReward: jouleApy + flrApy + kiiApy + rflrApy, + underlyingTokens: [token], + rewardTokens: [ + jouleApy ? JOULE.address : null, + flrApy ? FLR.address : null, + kiiApy ? KII.address : null, + rflrApy ? RFLR.address : null, + ].filter(Boolean), + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: Number.isFinite(apyRewardBorrow) ? apyRewardBorrow : 0, + ltv: marketsInfo[i].collateralFactorMantissa / 10 ** 18, + }; + }); + + return pools; +}; + +const getAPys = async() => { + let pools = await getApy(COMPTROLLER_ADDRESS); + pools = pools.concat(await getApy(ISO_COMPTROLLER_ADDRESS)) + return pools.concat(await getApy(FXRP_ISO_COMPTROLLER_ADDRESS)) +} + +module.exports = { + timetravel: false, + apy: getAPys, + url: 'https://app.kinetic.market/dashboard', +}; diff --git a/src/adaptors/kinetix-amm-v3/index.js b/src/adaptors/kinetix-amm-v3/index.js new file mode 100644 index 0000000000..31871ee82d --- /dev/null +++ b/src/adaptors/kinetix-amm-v3/index.js @@ -0,0 +1,64 @@ +const { gql, request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const KAI = '0x52369B1539EA8F4e1eadEEF18D85462Dcf9a3658'; + +const STEER_POOLS_URL = + 'https://mv-platform.vercel.app/liquidity/vaults?dex=Kinetix&chain=2222&provider=steer'; + +const chain = 'kava'; + +const getApy = async () => { + const { data: steerPoolsWithTokens } = await axios.get(STEER_POOLS_URL); + + const poolsValues = steerPoolsWithTokens.map((p, i) => { + const { address: poolAddress, apr, feeTier, decimals, token0, token1 } = p; + + const { feeApr, farmApr } = apr; + + const { + address: token0Address, + symbol: token0Symbol, + decimals: token0Decimals, + balance: token0Balance, + price: token0Price, + } = token0; + + const { + address: token1Address, + symbol: token1Symbol, + decimals: token1Decimals, + balance: token1Balance, + price: token1Price, + } = token1; + + const tvlUsd = + Number(token0Balance) * token0Price + Number(token1Balance) * token1Price; + + const apyBase = utils.aprToApy(feeApr); + const apyReward = utils.aprToApy(farmApr); + + return { + pool: poolAddress, + chain: utils.formatChain('kava'), + project: 'kinetix-amm-v3', + symbol: `${token0Symbol}-${token1Symbol}`, + tvlUsd, + apyBase, + apyReward, + rewardTokens: apyReward ? [KAI] : [], + underlyingTokens: [token0Address, token1Address], + }; + }); + + return poolsValues.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://kinetix.finance/pool/v3', +}; diff --git a/src/adaptors/kinetix-derivatives/abis/abi.json b/src/adaptors/kinetix-derivatives/abis/abi.json new file mode 100644 index 0000000000..0076eb2c32 --- /dev/null +++ b/src/adaptors/kinetix-derivatives/abis/abi.json @@ -0,0 +1,69 @@ +{ + "tokensPerInterval": { + "inputs": [ + { "internalType": "address", "name": "_rewardToken", "type": "address" } + ], + "name": "tokensPerInterval", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdk": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdk", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAums": { + "inputs": [], + "name": "getAums", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ] + }, + "allWhitelistedTokensLength": { + "inputs": [], + "name": "allWhitelistedTokensLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "allWhitelistedTokens": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allWhitelistedTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/kinetix-derivatives/index.js b/src/adaptors/kinetix-derivatives/index.js new file mode 100644 index 0000000000..21dcb8b3b4 --- /dev/null +++ b/src/adaptors/kinetix-derivatives/index.js @@ -0,0 +1,141 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); +const BigNumber = require('bignumber.js'); + +const klpManagerAddress = '0x53E6D11B66aBF344028b69f2468120c6afA47F53'; +const feeKlpTrackerAddress = '0xbD1a3CBD6E391A01eD98289cC82D1b0b5D14b1f1'; +const PERP_V1_VAULT = '0xa721f9f61CECf902B2BCBDDbd83E71c191dEcd8b'; // Kava PerpV1 Vault + +const KAI = '0x52369B1539EA8F4e1eadEEF18D85462Dcf9a3658'; +const KLP = '0x5d370C8Fb021cfaa663D35a7c26fb59699ff42DA'; + +const secondsPerYear = 31536000; + +async function getKlpTvl() { + let tvl = await sdk.api.abi.call({ + target: klpManagerAddress, + abi: abi['getAumInUsdk'], + chain: 'kava', + params: [false], + }); + + return tvl.output * 10 ** -18; +} + +async function calculateKlpPrice() { + try { + // Fetch AUMs and KLP Supply + let aums = await sdk.api.abi.call({ + target: klpManagerAddress, + abi: abi['getAums'], + chain: 'kava', + params: [], + }); + + let klpSupply = await sdk.api.abi.call({ + target: KLP, + abi: 'erc20:totalSupply', + chain: 'kava', + params: [], + }); + + // Convert AUMs to a readable format (divide by 1e30) + const aumValues = aums.output.map((value) => + new BigNumber(value).dividedBy(1e30) + ); + const klpSupplyAdjusted = new BigNumber(klpSupply.output).dividedBy(1e18); + + // Calculate the median of AUMs + if (aumValues.length !== 2) { + throw new Error('Expected exactly 2 values from getAums'); + } + const medianAum = aumValues[0].plus(aumValues[1]).dividedBy(2); + + // Calculate the price + const price = medianAum.dividedBy(klpSupplyAdjusted); + + return price.toString(); + } catch (error) { + console.error('Error calculating KLP price:', error); + } +} + +async function getFeeKLPTrackerValues() { + let decimals = await sdk.api.abi.call({ + target: feeKlpTrackerAddress, + abi: 'erc20:decimals', + chain: 'kava', + }); + + let supply = await sdk.api.abi.call({ + target: feeKlpTrackerAddress, + abi: 'erc20:totalSupply', + chain: 'kava', + params: [], + }); + + let tokensPerInterval = await sdk.api.abi.call({ + target: feeKlpTrackerAddress, + abi: abi['tokensPerInterval'], + chain: 'kava', + params: [KAI], + }); + + const feeKlp = new BigNumber(tokensPerInterval.output) + .multipliedBy(secondsPerYear) + .dividedBy(1e18) + .toString(); + + const feeKlpSupply = new BigNumber(supply.output).dividedBy(1e18).toString(); + + return { feeKlp, feeKlpSupply }; +} + +async function getPoolKlp(pTvl, pFeeKlp, pFeeKlpSupply, pKlpPrice, pPriceData) { + const rewardTvl = Number(pFeeKlpSupply) * Number(pKlpPrice); + + const yearlyFeeKlp = + Number(pFeeKlp) * pPriceData['coingecko:kinetixfi'].price; + const apyFee = (yearlyFeeKlp / rewardTvl) * 100; + + return { + pool: feeKlpTrackerAddress, + chain: utils.formatChain('kava'), + project: 'kinetix-derivatives', + symbol: 'KAVA-axlETH-WETH-axlWBTC-WBTC-ATOM-USDt', + poolMeta: 'KLP', + tvlUsd: parseFloat(pTvl), + apyBase: apyFee, + apyReward: 0, + rewardTokens: [KAI], + underlyingTokens: [KLP], + }; +} + +const getPools = async () => { + let pools = []; + + const priceKeys = ['kinetixfi'].map((t) => `coingecko:${t}`).join(','); + + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const klpTvl = await getKlpTvl(); + const klpPrice = await calculateKlpPrice(); + + const { feeKlp, feeKlpSupply } = await getFeeKLPTrackerValues(); + + pools.push( + await getPoolKlp(klpTvl, feeKlp, feeKlpSupply, klpPrice, priceData) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://kinetix.finance/pool/perpv1', +}; diff --git a/src/adaptors/kintsu/index.js b/src/adaptors/kintsu/index.js new file mode 100644 index 0000000000..e30c3ab53d --- /dev/null +++ b/src/adaptors/kintsu/index.js @@ -0,0 +1,131 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const SECONDS_PER_DAY = 86400; +const DAYS_PER_YEAR = 365; + +const vaults = { + monad: '0xA3227C5969757783154C60bF0bC1944180ed81B9', +} +const underlyingTokenPriceId = { + monad: 'coingecko:monad', +}; + +const chainApy = async (chain) => { + // Get current timestamp + const now = Math.floor(Date.now() / 1000); + const timestamp1DayAgo = now - SECONDS_PER_DAY; + + // Fetch block numbers for current and 1 day ago + const [blockNow, block1DayAgo] = await Promise.all([ + axios + .get(`https://coins.llama.fi/block/${chain}/${now}`) + .then((r) => r.data.height), + axios + .get(`https://coins.llama.fi/block/${chain}/${timestamp1DayAgo}`) + .then((r) => r.data.height), + ]); + + if (!blockNow || !block1DayAgo) { + throw new Error('RPC issue: Failed to fetch block numbers'); + } + + // Fetch current totalPooled, totalSupply, and symbol + const [totalPooledNow, totalSupplyNow, symbol] = await Promise.all([ + sdk.api.abi.call({ + target: vaults[chain], + abi: 'function totalPooled() view returns (uint96)', + chain: chain, + block: blockNow, + }), + sdk.api.abi.call({ + target: vaults[chain], + abi: 'erc20:totalSupply', + chain: chain, + block: blockNow, + }), + sdk.api.abi.call({ + target: vaults[chain], + abi: 'erc20:symbol', + chain: chain, + block: blockNow, + }), + ]); + + // Fetch totalPooled and totalSupply from 1 day ago + const [totalPooled1DayAgo, totalSupply1DayAgo] = await Promise.all([ + sdk.api.abi.call({ + target: vaults[chain], + abi: 'function totalPooled() view returns (uint96)', + chain: chain, + block: block1DayAgo, + }), + sdk.api.abi.call({ + target: vaults[chain], + abi: 'erc20:totalSupply', + chain: chain, + block: block1DayAgo, + }), + ]); + + // Calculate share values (multiply by 1e18 to handle decimals) + const shareValueNow = + (BigInt(totalPooledNow.output) * BigInt(1e18)) / + BigInt(totalSupplyNow.output); + const shareValue1DayAgo = + (BigInt(totalPooled1DayAgo.output) * BigInt(1e18)) / + BigInt(totalSupply1DayAgo.output); + + if (shareValue1DayAgo === 0n) { + throw new Error('RPC issue: Previous share value is zero'); + } + + // Calculate proportion: shareValueNow / shareValue1DayAgo + // Multiply by 1e18 to maintain precision + const proportion = + Number((shareValueNow * BigInt(1e18)) / shareValue1DayAgo) / 1e18; + + if (proportion <= 0) { + throw new Error('RPC issue: Invalid proportion calculated'); + } + + // Calculate APY using the formula: + // APY = ((1 + ((proportion - 1) / 365)) ** 365 - 1) * 100 + // This is equivalent to: APY = (proportion ** 365 - 1) * 100 + const apyBase = (Math.pow(proportion, DAYS_PER_YEAR) - 1) * 100; + + // Convert to number (assuming 18 decimals for underlying token) + const tvlUnderlyingToken = Number(totalPooledNow.output) / 1e18; + + // Get native token price to convert to USD + const underlyingTokenPriceResponse = await axios.get( + `https://coins.llama.fi/prices/current/${underlyingTokenPriceId[chain]}` + ); + const underlyingTokenPrice = + underlyingTokenPriceResponse.data.coins[underlyingTokenPriceId[chain]].price; + const tvlUsd = tvlUnderlyingToken * underlyingTokenPrice; + + return [ + { + pool: vaults[chain].toLowerCase(), + chain: chain, + project: 'kintsu', + symbol: symbol.output, + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], + }, + ]; +}; + +const apy = async () => { + const chains = Object.keys(vaults); + const apys = await Promise.all(chains.map(async (chain) => await chainApy(chain))); + return apys.flat(); +}; + +module.exports = { + apy, + url: 'https://kintsu.xyz/staking', +}; + diff --git a/src/adaptors/kinza-finance/index.js b/src/adaptors/kinza-finance/index.js new file mode 100644 index 0000000000..2ef17c25e6 --- /dev/null +++ b/src/adaptors/kinza-finance/index.js @@ -0,0 +1,124 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const chain = 'bsc'; +// PoolDataProvider +const target = '0x09Ddc4AE826601b0F9671b9edffDf75e7E6f5D61'; + +const apy = async () => { + const reserveTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupplyEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalancesEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimalsEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'decimals'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const pricesEthereum = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens + .map((pool, i) => { + const p = poolsReserveData[i]; + const price = pricesEthereum[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupplyEthereum[i]; + const totalSupplyUsd = + (supply / 10 ** underlyingDecimalsEthereum[i]) * price; + + const currentSupply = underlyingBalancesEthereum[i]; + const tvlUsd = + (currentSupply / 10 ** underlyingDecimalsEthereum[i]) * price; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + chain, + project: 'kinza-finance', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd: totalSupplyUsd - tvlUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + }; + }) + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.kinza.finance/', +}; diff --git a/src/adaptors/klap/abiChefIncentiveController.json b/src/adaptors/klap/abiChefIncentiveController.json new file mode 100644 index 0000000000..6adaa3ac37 --- /dev/null +++ b/src/adaptors/klap/abiChefIncentiveController.json @@ -0,0 +1,865 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "BalanceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dialutingRepartition", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonDialutingRepartition", + "type": "uint256" + } + ], + "name": "UpdateEmissionRepartition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startingAllocPoint", + "type": "uint256" + } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allocPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_allocPoints", + "type": "uint256[]" + } + ], + "name": "batchUpdateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "beginVoting", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimReceiver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimableKlap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + } + ], + "name": "claimableReward", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dialutingRepartition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "emissionSchedule", + "outputs": [ + { + "internalType": "uint128", + "name": "startTimeOffset", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardsPerSecond", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_totalSupply", + "type": "uint256" + } + ], + "name": "handleAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + }, + { + "internalType": "address", + "name": "_poolConfigurator", + "type": "address" + }, + { + "internalType": "contract IMultiFeeDistribution", + "name": "_rewardMinter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxMintable", + "type": "uint256" + }, + { + "internalType": "address", + "name": "ve_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_dialutingRepartition", + "type": "uint256" + }, + { + "internalType": "contract IRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxMintableTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintedTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonDialutingRepartition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolConfigurator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accKlapPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accKlapPerFactorShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sumOfFactors", + "type": "uint256" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "onwardIncentives", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolVote", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "registeredTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "remove_vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardMinter", + "outputs": [ + { + "internalType": "contract IMultiFeeDistribution", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewarder", + "outputs": [ + { + "internalType": "contract IRewarder", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "setClaimReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + } + ], + "name": "setEmissionSchedule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "_incentives", + "type": "address" + } + ], + "name": "setOnwardIncentives", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "setRewarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_dialutingRepartition", + "type": "uint256" + } + ], + "name": "updateEmissionRepartition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "updateFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usedWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "factor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_pools", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_weights", + "type": "uint256[]" + } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "votingCommenced", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/klap/abiLendingPool.json b/src/adaptors/klap/abiLendingPool.json new file mode 100644 index 0000000000..287cd636b1 --- /dev/null +++ b/src/adaptors/klap/abiLendingPool.json @@ -0,0 +1,1014 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "premium", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidatedCollateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "LiquidationCall", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RebalanceStableBorrowRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestRateMode", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceFromAfter", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceToBefore", + "type": "uint256" + } + ], + "name": "finalizeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiverAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "modes", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "internalType": "bytes", + "name": "params", + "type": "bytes" + }, + { + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "id", + "type": "uint8" + } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveNormalizedIncome", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveNormalizedVariableDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserAccountData", + "outputs": [ + { + "internalType": "uint256", + "name": "totalCollateralETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDebtETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableBorrowsETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentLiquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ltv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserConfiguration", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.UserConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "name": "initReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "liquidationCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "rebalanceStableBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + } + ], + "name": "repay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "internalType": "uint256", + "name": "configuration", + "type": "uint256" + } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "val", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "internalType": "address", + "name": "rateStrategyAddress", + "type": "address" + } + ], + "name": "setReserveInterestRateStrategyAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "useAsCollateral", + "type": "bool" + } + ], + "name": "setUserUseReserveAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "swapBorrowRateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/klap/abiProtocolDataProvider.json b/src/adaptors/klap/abiProtocolDataProvider.json new file mode 100644 index 0000000000..6da4e3f1a6 --- /dev/null +++ b/src/adaptors/klap/abiProtocolDataProvider.json @@ -0,0 +1,297 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "addressesProvider", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADDRESSES_PROVIDER", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllATokens", + "outputs": [ + { + "components": [ + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReservesTokens", + "outputs": [ + { + "components": [ + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ltv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactor", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowingEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isFrozen", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveTokensAddresses", + "outputs": [ + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "currentATokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "scaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "stableRateLastUpdated", + "type": "uint40" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/klap/index.js b/src/adaptors/klap/index.js new file mode 100644 index 0000000000..3cbb92950b --- /dev/null +++ b/src/adaptors/klap/index.js @@ -0,0 +1,214 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const abiLendingPool = require('./abiLendingPool.json'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider.json'); +const abiChefIncentiveController = require('./abiChefIncentiveController.json'); +const utils = require('../utils'); + +const lendingPool = '0x1b9c074111ec65E1342Ea844f7273D5449D2194B'; +const protocolDataProvider = '0x1C08Af0455A4D90667172D87D23E60669f90eA4E'; +const chefIncentiveController = '0x422ABB57E4Bb7D46032852b884b7bB4Cc4A39CC7'; +const lendingPoolAddressesProvider = + '0x78b6ADDE60A9181C1889913D31906bbF5C3795dD'; +const rewardToken = '0xd109065ee17e2dc20b3472a4d4fb5907bd687d09'; + +const synapseAssets = [ + '0x6270B58BE569a7c0b8f47594F191631Ae5b2C86C', // USDC, + '0xd6dAb4CfF47dF175349e6e7eE2BF7c40Bb8C05A3', // USDT, + '0xDCbacF3f7a069922E677912998c8d57423C37dfA', // WBTC + '0xCD6f29dC9Ca217d0973d3D21bF58eDd3CA871a86', // WETH + '0x078dB7827a5531359f6CB63f62CFA20183c4F10c', // DAI +]; + +const apy = async () => { + const chain = 'klaytn'; + // underlying pools + const reservesList = ( + await sdk.api.abi.call({ + target: lendingPool, + chain, + abi: abiLendingPool.find((n) => n.name === 'getReservesList'), + }) + ).output; + + // supply and borrow base rate, interest and debt addresses + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ target: lendingPool, params: t })), + chain, + abi: abiLendingPool.find((n) => n.name === 'getReserveData'), + }) + ).output.map((o) => o.output); + + // available + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' ? reserveData[i].aTokenAddress : null, + })), + chain, + }) + ) + ); + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + // borrowed + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ target: p.variableDebtTokenAddress })), + chain, + }) + ).output.map((o) => o.output); + + // ltv + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: protocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + // --- rewards + const rewardsPerSecond = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find( + (n) => n.name === 'rewardsPerSecond' + ), + target: chefIncentiveController, + chain, + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find( + (n) => n.name === 'totalAllocPoints' + ), + target: chefIncentiveController, + chain, + }) + ).output; + + // allocPoints (poolInfo is available but doesn't have allocation point value) (alloc point) + // need to run this twice, + // once for interest bearing and another time for debt bearing tokens + const allocPointsInterest = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'allocPoints'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].aTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const allocPointsDebt = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'allocPoints'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + // prices + let pricesArray = [rewardToken, ...reservesList].map((t) => `${chain}:${t}`); + // note: we don't have prices for many of those tokens -> defaulting to the + // base token (eg wrapped sol on klaytn -> sol price) using gecko ids + const geckoIds = [ + 'solana', + 'wrapped-avax', + 'binance-usd', + 'wbnb', + 'tether', + ].map((t) => `coingecko:${t}`); + pricesArray = pricesArray.concat(geckoIds); + + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).body.coins; + + const secondsPerYear = 60 * 60 * 24 * 365; + const rewardPerYear = + (rewardsPerSecond / 1e18) * + secondsPerYear * + prices[`${chain}:${rewardToken}`].price; + + return reservesList.map((t, i) => { + const price = + prices[`${chain}:${t}`]?.price ?? + Object.values(prices).find((pr) => pr.symbol === symbols[i])?.price; + + // tvl data + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + // apy base + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + // apy reward + const apyReward = + ((((allocPointsInterest[i] / totalAllocPoint) * rewardPerYear) / + totalSupplyUsd) * + 100) / + 2; + + const apyRewardBorrow = + ((((allocPointsDebt[i] / totalAllocPoint) * rewardPerYear) / + totalBorrowUsd) * + 100) / + 2; + + // ltv + const ltv = reserveConfigurationData[i].ltv / 1e4; + + // url for pools + const poolUrl = reservesList[i]; + const url = + `https://app.klap.finance/reserve-overview/${poolUrl}-${poolUrl}${lendingPoolAddressesProvider}`.toLowerCase(); + + return { + pool: reserveData[i].aTokenAddress, + symbol: utils.formatSymbol(symbols[i]), + project: 'klap', + chain: utils.formatChain(chain), + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [t], + rewardTokens: [rewardToken], + poolMeta: synapseAssets.includes(t) ? 'Synapse' : null, + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/koalaswap/index.js b/src/adaptors/koalaswap/index.js new file mode 100644 index 0000000000..3f431f78db --- /dev/null +++ b/src/adaptors/koalaswap/index.js @@ -0,0 +1,74 @@ +const { request, gql } = require('graphql-request') +const utils = require('../utils') + +const chain = 'unit0' +const config = { + uiBase: 'https://koalaswap.app', + subgraph: 'https://graph-unit-zero.umerge.org/subgraphs/name/koalaswap-v3-unit-zero/', +} + +const POOLS_QUERY = gql` + query GetPools($first: Int!, $skip: Int!) { + pools(first: $first, skip: $skip, orderBy: totalValueLockedUSD, orderDirection: desc) { + id + token0 { id symbol } + token1 { id symbol } + totalValueLockedUSD + volumeUSD + feesUSD + feeTier + } + } +` + +async function getAllPoolsFromGraph() { + const pageSize = 100 + let skip = 0 + let results = [] + + while (true) { + const data = await request(config.subgraph, POOLS_QUERY, { first: pageSize, skip }) + if (!data.pools || data.pools.length === 0) break + results = results.concat(data.pools) + skip += pageSize + } + return results +} + +async function getPools() { + const pools = await getAllPoolsFromGraph() + + const dataPools = pools.map((p) => { + const tvlUsd = Number(p.totalValueLockedUSD || 0) + const volumeUsd1d = Number(p.volumeUSD || 0) + const feesUsd1d = Number(p.feesUSD || 0) + + const apr = tvlUsd > 0 ? (feesUsd1d / tvlUsd) * 365 : 0 + const apyBase = apr * 100 + + return { + pool: p.id, + chain, + project: 'koalaswap', + symbol: `${p.token0.symbol}-${p.token1.symbol}`, + poolMeta: `${Number(p.feeTier) / 1e4}%`, + tvlUsd, + apyBase, + underlyingTokens: [p.token0.id, p.token1.id], + url: `${config.uiBase}/pools/${p.id}`, + volumeUsd1d, + } + }) + + return dataPools.filter((p) => utils.keepFinite(p)) +} + +async function main() { + const data = await getPools() + return data +} + +module.exports = { + timetravel: false, + apy: main, +} diff --git a/src/adaptors/koi-finance-amm/abi.js b/src/adaptors/koi-finance-amm/abi.js new file mode 100644 index 0000000000..b579585cde --- /dev/null +++ b/src/adaptors/koi-finance-amm/abi.js @@ -0,0 +1,1630 @@ +module.exports = { + factoryABI: [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_protocolFeeDynamic", + "type": "uint256" + } + ], + "name": "ProtocolFeeDynamicChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_protocolFeeFixed", + "type": "uint256" + } + ], + "name": "ProtocolFeeFixedChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_feeTo", + "type": "address" + } + ], + "name": "ProtocolFeeToChange", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeType", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeDynamic", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeFixed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeTo", + "type": "address" + } + ], + "name": "setFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolFeeDynamic", + "type": "uint256" + } + ], + "name": "setProtocolFeeDynamic", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolFeeFixed", + "type": "uint256" + } + ], + "name": "setProtocolFeeFixed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + lpTokenABI: [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "pairFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liqFee", + "type": "uint256" + } + ], + "name": "ChangeFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pAmount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pAmount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "changeFeeType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "votes", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegator", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getCurrentVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPriorVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct MuteSwitchPairDynamic.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "sig", + "type": "bytes" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] + , + }; + \ No newline at end of file diff --git a/src/adaptors/koi-finance-amm/index.js b/src/adaptors/koi-finance-amm/index.js new file mode 100644 index 0000000000..0ef42094c3 --- /dev/null +++ b/src/adaptors/koi-finance-amm/index.js @@ -0,0 +1,186 @@ +//const {Web3} = require('web3'); +//const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const { factoryABI, lpTokenABI } = require('./abi'); +const utils = require('../utils'); +const axios = require('axios'); + +//const web3 = new Web3(RPC_URL); +const RPC_URL = 'https://mainnet.zksync.io/'; +const GRAPH = + 'https://api.goldsky.com/api/public/project_clmtie4nnezuh2nw6hhjg6mo7/subgraphs/mute_switch/v0.0.7/gn'; +const BLOCK_GRAPH = + 'https://api.studio.thegraph.com/query/12332/blocks---zksync-era/version/latest'; +const AMPS = 'https://raw.githubusercontent.com/muteio/farms/main/index.json'; + +const FACTORY = '0x40be1cBa6C5B47cDF9da7f963B6F761F4C60627D'; + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + pairFee + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + stable + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + pairFee + stable + } + } +`; + +const apy = (pool, dataPrior1d, dataPrior7d) => { + pool = { ...pool }; + + pool['feeTier'] = pool.pairFee; + + // calc prior volume on 24h offset + pool['volumeUSDPrior1d'] = dataPrior1d.find( + (el) => el.id === pool.id + )?.volumeUSD; + + pool['volumeUSDPrior7d'] = dataPrior7d.find( + (el) => el.id === pool.id + )?.volumeUSD; + + // calc 24h volume + pool['volumeUSD1d'] = Number(pool.volumeUSD) - Number(pool.volumeUSDPrior1d); + pool['volumeUSD7d'] = Number(pool.volumeUSD) - Number(pool.volumeUSDPrior7d); + + // calc fees + pool['feeUSD1d'] = (pool.volumeUSD1d * Number(pool.feeTier)) / 10000; + pool['feeUSD7d'] = (pool.volumeUSD7d * Number(pool.feeTier)) / 10000; + + // annualise + pool['feeUSDyear1d'] = pool.feeUSD1d * 365; + pool['feeUSDyear7d'] = pool.feeUSD7d * 52; + + // calc apy + pool['apy1d'] = (pool.feeUSDyear1d / pool.totalValueLockedUSD) * 100; + pool['apy7d'] = (pool.feeUSDyear7d / pool.totalValueLockedUSD) * 100; + + return pool; +}; + +const topLvl = async ( + chainString, + url, + block_url, + query, + queryPrior, + timestamp +) => { + const farms = (await axios.get(AMPS)).data; + var farmRewards = {}; + + for (let i in farms) { + farmRewards[farms[i].pair.toLowerCase()] = { + apy: farms[i].apy, + payout: farms[i].payoutToken, + }; + } + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + block_url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [block_url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => apy(el, dataPrior, dataPrior7d)); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const url = `https://dapp.koi.finance/pool/${token0}/${token1}/${p.stable}`; + + const apyReward = farmRewards[p.id.toLowerCase()] + ? farmRewards[p.id.toLowerCase()].apy / 100 + : 0; + const rewardTokens = farmRewards[p.id.toLowerCase()] + ? [...underlyingTokens, farmRewards[p.id.toLowerCase()].payout] + : underlyingTokens; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'koi-finance-amm', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + apyReward, + rewardTokens, + }; + }); +}; + +const main = async (timestamp = null) => { + let data = await topLvl( + 'era', + GRAPH, + BLOCK_GRAPH, + query, + queryPrior, + timestamp + ); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://koi.finance/farms', +}; diff --git a/src/adaptors/kokoa-finance/index.js b/src/adaptors/kokoa-finance/index.js new file mode 100644 index 0000000000..b1be5cd57d --- /dev/null +++ b/src/adaptors/kokoa-finance/index.js @@ -0,0 +1,85 @@ +const utils = require('../utils'); +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); + +const LP_Mapping = { + '0x029e2A1B2bb91B66bd25027E1C211E5628dbcb93': 'oETH-oUSDT', + '0x2E9269B718cc816De6A9E3C27E5bdb0F6A01b0ac': 'oUSDT-oUSDC', + '0xc320066b25B731A11767834839Fe57f9b2186f84': 'oUSDT-KDAI', + '0xE75a6A3a800A2C5123e67e3bde911Ba761FE0705': 'KSP-oUSDT', + '0x4B50d0e4F29bF5B39a6234B11753fDB3b28E76Fc': 'oXRP-KDAI', +}; + +const poolsFunction = async () => { + const dksdData = await utils.getData( + 'https://prod.kokoa-api.com/earn/status' + ); //dKSD is a tokenized version of deposited KSD that is dynamically balanced at the APY rate + + const earnPool = { + pool: `0x5e6215dfb33b1fb71e48000a47ed2ebb86d5bf3d`, //dKSD pool address + chain: utils.formatChain('klaytn'), + project: 'kokoa-finance', + symbol: utils.formatSymbol('KSD'), //Users deposit KSD and claims the realized APY upon withdrawal + tvlUsd: Number(dksdData.dKsdTotalSupply), + apy: Number(dksdData.apy), + }; + + return [earnPool]; // Kokoa Finance Earn pool(the only pool) accrues APY yields via collateral management yields +}; +const KSD_COIN_ID = 'kokoa-stable-dollar'; +const KOKOA = '0xb15183d0d4d5e86ba702ce9bb7b633376e7db29f'; +const cdpDataFunction = async () => { + const URL = 'https://prod.kokoa-api.com/vaults/borrow'; + const data = (await utils.getData(URL)).vaults; + const prices = (await utils.getPrices([`coingecko:${KSD_COIN_ID}`])) + .pricesByAddress; + const address = data.map((pool) => pool.address); + const symbols = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: address.map((address) => { + return { target: address }; + }), + chain: 'klaytn', + requery: false, + permitFailure: true, + }) + ).output.map((e) => e.output); + return data + .map((pool, index) => { + const totalSupplyUsd = + Number(pool.totalCollateralAmount) * Number(pool.collateralPrice); + const totalBorrowUsd = + Number(pool.totalBorrowedAmount) * prices[KSD_COIN_ID.toLowerCase()]; + return { + pool: pool.address, + project: 'kokoa-finance', + symbol: + symbols[index] === 'KSLP' ? LP_Mapping[pool.address] : symbols[index], + chain: utils.formatChain('klaytn'), + apy: 0, + tvlUsd: totalSupplyUsd, + apyRewardBorrow: Number(pool.rewardApr), + apyBaseBorrow: Number(pool.stabilityFeeApr), + totalSupplyUsd: totalSupplyUsd, + rewardTokens: [KOKOA], + totalBorrowUsd: totalBorrowUsd, + ltv: Number(pool.liqLtvPercent) / 100, + mintedCoin: 'KSD', + poolMeta: symbols[index] === 'KSLP' ? 'KlaySwap LP' : null, + }; + }) + .filter((e) => e.symbol); +}; + +const main = async () => { + const poolData = await poolsFunction(); + const cdpData = await cdpDataFunction(); + return [...poolData, ...cdpData]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.kokoa.finance/earn', +}; diff --git a/src/adaptors/kokonut-swap/index.ts b/src/adaptors/kokonut-swap/index.ts new file mode 100644 index 0000000000..8139772108 --- /dev/null +++ b/src/adaptors/kokonut-swap/index.ts @@ -0,0 +1,44 @@ +const utils = require('../utils'); + +const API_URL = 'https://prod.kokonut-api.com/pools'; + +interface Pool { + address: string; + symbol: string; + tvl: string; + coins: Array; + baseApr: string; + stakingApr: string; +} + +interface Pools { + pools: Array; +} + +const apy = async () => { + const { pools: data }: Pools = await utils.getData(API_URL); + + const pools = data.map((pool) => { + return { + pool: pool.address, + chain: utils.formatChain('klaytn'), + project: 'kokonut-swap', + symbol: pool.symbol, + tvlUsd: Number(pool.tvl), + apyBase: Number(pool.baseApr) || 0, + apyReward: Number(pool.stakingApr) || 0, + underlyingTokens: pool.coins, + rewardTokens: [ + '0xcd670d77f3dcab82d43dff9bd2c4b87339fb3560', // KOKOS + ], + url: `https://kokonutswap.finance/pools/${pool.address}`, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/kolibri/index.js b/src/adaptors/kolibri/index.js new file mode 100644 index 0000000000..40022a71fa --- /dev/null +++ b/src/adaptors/kolibri/index.js @@ -0,0 +1,17 @@ +const { getFarms } = require('../quipuswap-stableswap/helpers'); + +const projectName = 'kolibri'; + +const poolsFunction = async () => + getFarms( + projectName, + ({ item: pool }) => + pool.stakeStatus === 'ACTIVE' && + parseFloat(pool.tvlInUsd) > 10e3 && + pool.rewardToken.metadata.name.toLowerCase().includes(projectName) + ); + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/kordfi/helper.js b/src/adaptors/kordfi/helper.js new file mode 100644 index 0000000000..28f44648c2 --- /dev/null +++ b/src/adaptors/kordfi/helper.js @@ -0,0 +1,130 @@ +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); + +const BAKING_REWARD_PERCENT = 5.5; +const PERCENT_EXP = 10 ** 2; +const TZBTC_EXP = 10 ** 8; +const XTZ_EXP = 10 ** 6; + +const tzbtcContractAddress = 'KT1WL6sHt8syFT2ts7NCmb5gPcS2tyfRxSyi'; +const xtzContractAddress = 'KT19qWdPBRtkWrsQnDvVfsqJgJB19keBhhMX'; +const chain = utils.formatChain('Tezos'); + +const calcTotalSupply = (deposit, depositIndex, rate, EXP, tenth) => { + const totalSupply = new BigNumber(deposit) + .times(depositIndex) + .div(EXP) + .toFixed(tenth); + const totalSupplyUSD = new BigNumber(totalSupply).times(rate).toFixed(2); + return { totalSupply, totalSupplyUSD }; +}; + +const calcTotalBorrow = (grossCredit, grossCreditIndex, rate, EXP, tenth) => { + const totalBorrow = new BigNumber(grossCredit) + .times(grossCreditIndex) + .div(EXP) + .toFixed(tenth); + const totalBorrowUSD = new BigNumber(totalBorrow).times(rate).toFixed(2); + return { totalBorrow, totalBorrowUSD }; +}; + +const calcUtilization = (totalBorrow, totalSupply) => { + const utilization = + totalBorrow === 0 + ? 0 + : new BigNumber(totalBorrow) + .div(totalSupply) + .times(PERCENT_EXP) + .toFixed(4); + if (utilization > 100) { + return 100; + } + return utilization; +}; + +const calcXtzBakingRewards = (utilization) => + new BigNumber(BAKING_REWARD_PERCENT) + .times(1 - utilization / PERCENT_EXP) + .toFixed(4); + +const calcXtzRate = (bakingRewards, savingsRate) => + new BigNumber(bakingRewards).plus(savingsRate).toFixed(2); + +function getTzbtcLendPool(data) { + const { totalSupplyUSD } = calcTotalSupply( + data['contractInfo'][0]['tzbtcDeposit'], + data['contractInfo'][0]['tzbtcDepositIndex'], + data['externalInfo'][0]['tzbtcRate'], + TZBTC_EXP, + 8 + ); + + const { totalBorrowUSD } = calcTotalBorrow( + data['contractInfo'][0]['tzbtcGrossCredit'], + data['contractInfo'][0]['tzbtcGrossCreditIndex'], + data['externalInfo'][0]['tzbtcRate'], + TZBTC_EXP, + 8 + ); + + const tvlUsd = new BigNumber(totalSupplyUSD).minus(totalBorrowUSD).toFixed(2); + const apyBase = new BigNumber( + data['contractInfo'][0]['tzbtcDepositRate'] + ).toFixed(2); + + return { + pool: `${tzbtcContractAddress}-${chain}`.toLowerCase(), + chain: chain, + project: 'kordfi', + symbol: utils.formatSymbol('TZBTC'), + tvlUsd: parseFloat(tvlUsd), + url: 'https://kord.fi/lend', + apyBase: parseFloat(apyBase), + totalSupplyUsd: parseFloat(totalSupplyUSD), + totalBorrowUsd: parseFloat(totalBorrowUSD), + underlyingTokens: ['KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn'], + }; +} + +function getXtzLendPool(data) { + const { totalSupply, totalSupplyUSD } = calcTotalSupply( + data['contractInfo'][0]['xtzDeposit'], + data['contractInfo'][0]['xtzDepositIndex'], + data['externalInfo'][0]['xtzRate'], + XTZ_EXP, + 6 + ); + + const { totalBorrow, totalBorrowUSD } = calcTotalBorrow( + data['contractInfo'][0]['xtzGrossCredit'], + data['contractInfo'][0]['xtzGrossCreditIndex'], + data['externalInfo'][0]['xtzRate'], + XTZ_EXP, + 6 + ); + + const tvlUsd = new BigNumber(totalSupplyUSD).minus(totalBorrowUSD).toFixed(2); + const utilization = calcUtilization(totalBorrow, totalSupply); + const bakingRewards = calcXtzBakingRewards(utilization); + const rate = calcXtzRate( + bakingRewards, + data['contractInfo'][0]['xtzDepositRate'] + ); + + return { + pool: `${xtzContractAddress}-${chain}`.toLowerCase(), + chain: chain, + project: 'kordfi', + symbol: utils.formatSymbol('XTZ'), + tvlUsd: parseFloat(tvlUsd), + url: 'https://kord.fi/lend', + apyBase: parseFloat(rate), + totalSupplyUsd: parseFloat(totalSupplyUSD), + totalBorrowUsd: parseFloat(totalBorrowUSD), + }; +} + +module.exports = { + getTzbtcLendPool, + getXtzLendPool, +}; diff --git a/src/adaptors/kordfi/index.js b/src/adaptors/kordfi/index.js new file mode 100644 index 0000000000..612ada1b6b --- /dev/null +++ b/src/adaptors/kordfi/index.js @@ -0,0 +1,34 @@ +const { request, gql } = require('graphql-request'); +const { getTzbtcLendPool, getXtzLendPool } = require('./helper'); +const graphUrl = 'https://back-llb-beta.kord.fi/v1/graphql'; + +const DataQuery = gql` + query DataQuery { + contractInfo { + tzbtcDeposit + tzbtcDepositIndex + tzbtcDepositRate + tzbtcGrossCredit + tzbtcGrossCreditIndex + xtzDeposit + xtzDepositIndex + xtzDepositRate + xtzGrossCredit + xtzGrossCreditIndex + } + externalInfo { + tzbtcRate + xtzRate + } + } +`; + +async function getPools() { + const data = await request(graphUrl, DataQuery); + return [getTzbtcLendPool(data), getXtzLendPool(data)]; +} + +module.exports = { + timetravel: false, + apy: getPools, // Main function, returns pools +}; diff --git a/src/adaptors/koyo-finance/index.js b/src/adaptors/koyo-finance/index.js index 8a60c295e3..9acc9ea13a 100644 --- a/src/adaptors/koyo-finance/index.js +++ b/src/adaptors/koyo-finance/index.js @@ -56,4 +56,5 @@ const main = async () => { module.exports = { timetravel: false, apy: main, + url: 'https://koyo.finance/kyo/farms', }; diff --git a/src/adaptors/kyberswap-elastic/index.js b/src/adaptors/kyberswap-elastic/index.js new file mode 100644 index 0000000000..514a2c1f96 --- /dev/null +++ b/src/adaptors/kyberswap-elastic/index.js @@ -0,0 +1,157 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); + +const urlFarm = + 'https://pool-farm.kyberswap.com//api/v1/elastic/farm-pools?page=1&perPage=10000'; + +CHAINS_API = { + ethereum: sdk.graph.modifyEndpoint( + '4U9PxDR4asVvfXyoVy18fhuj6NHnQhLzZkjZ5Bmuc5xk' + ), + arbitrum: sdk.graph.modifyEndpoint( + 'C36tj8jSpEHxcNbjM3z7ayUZHVjrk4HRqnpGMFuRgXs6' + ), + polygon: sdk.graph.modifyEndpoint( + '8g4tJKCJ7eMAHjzZNeRWz9BkYG5U7vDNjdanSXfDXGXT' + ), + avalanche: sdk.graph.modifyEndpoint( + '9oMJfc7CL8uDqqQ3T3NFBnFCz9JMwq2YhH9AqojECFWp' + ), + bsc: sdk.graph.modifyEndpoint('FDEDgycFnTbPZ7PfrnWEZ4iR7T5De6BR69zx1i8gKQRa'), + fantom: sdk.graph.modifyEndpoint( + '9aj6YZFVL647wFBQXnNKM72eiowP4fyzynQKwLrn5axL' + ), + cronos: + 'https://cronos-graph.kyberengineering.io/subgraphs/name/kybernetwork/kyberswap-elastic-cronos', + optimism: sdk.graph.modifyEndpoint( + '3Kpd8i7U94pTz3Mgdb8hyvT5o26fpwT7SUHAbTa6JzfZ' + ), +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + volumeUSD + feeTier + token0 { + symbol + id + } + token1 { + symbol + id + } + totalValueLockedToken0 + totalValueLockedToken1 + } + } +`; + +const queryPrior = gql` + { + pools (first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, url, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + // const [_, blockPrior7d] = await utils.getBlocks( + // chainString, + // timestamp, + // [url], + // 604800 + // ); + + let data = (await request(url, query.replace('', block))) + .pools; + + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pools; + + // const dataPrior7d = ( + // await request(url, queryPrior.replace('', blockPrior7d)) + // ).pools; + + data = data.map((p) => ({ + ...p, + reserve0: p.totalValueLockedToken0, + reserve1: p.totalValueLockedToken1, + feeTier: p.feeTier * 10, + })); + data = await utils.tvl(data, chainString); + + data = data.map((p) => utils.apy(p, dataPrior, [])); + + const farmData = (await axios.get(urlFarm.replace('', chainString))) + .data.data.farmPools; + + return data.map((p) => { + // farmData includes historical reward entries per pool. + // filter to current one + const farm = farmData + .filter((x) => x.pool.id.toLowerCase() === p.id.toLowerCase()) + .sort((a, b) => b.pid - a.pid)[0]; + + const apyReward = farm?.endTime > Date.now() / 1000 ? +farm?.apr : 0; + + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'kyberswap-elastic', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + // apyBase7d: p.apy7d, + apyReward, + rewardTokens: apyReward > 0 ? farm.rewardTokens.map((r) => r.id) : [], + underlyingTokens: [p.token0.id, p.token1.id], + poolMeta: `${p.feeTier / 1e4}%`, + volumeUsd1d: p.volumeUSD1d, + // volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const data = await Promise.allSettled( + Object.entries(CHAINS_API).map(([chain, url]) => + topLvl(chain, url, timestamp) + ) + ); + + return data + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter( + (p) => + utils.keepFinite(p) && + !p.symbol.includes('ANKRBNB') && + p.pool !== '0xfd117d9a917a8990cc8f804c0ce91f40340dacac' + ); +}; + +module.exports = { + apy: main, + timetravel: false, + url: 'https://kyberswap.com/pools', +}; diff --git a/src/adaptors/kyberswap-fairflow/index.js b/src/adaptors/kyberswap-fairflow/index.js new file mode 100644 index 0000000000..d85babe975 --- /dev/null +++ b/src/adaptors/kyberswap-fairflow/index.js @@ -0,0 +1,138 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const CHAIN_CODES = [ + "ethereum", + 'arbitrum', + 'base', + 'optimism', + 'polygon', + 'avalanche', + 'bsc', + 'hyperevm', + 'unichain', + 'linea', + 'ronin', + 'mantle', + 'sonic', + 'berachain' +] +const BASE_URL = 'https://kd-market-service-api.kyberengineering.io/'; + +const topLvl = async (timestamp) => { + try { + const allPools = []; + + // Loop through each chain + for (const chain of CHAIN_CODES) { + try { + // Fetch all pools from the exchange for this chain + const poolsResponse = await axios.get(`${BASE_URL}${chain}/api/v1/pools?exchange=kem_univ4_fairflow%`); + const pools = poolsResponse.data.data; + if (chain === 'bsc') { + // Call pool with exchange = kem_pancake_infinity_cl_fairflow_eg_lm and append to pools + const pancakePoolsResponse = await axios.get(`${BASE_URL}${chain}/api/v1/pools?exchange=kem_pancake_infinity_cl_fairflow_eg_lm`); + const pancakePools = pancakePoolsResponse.data.data; + if (pancakePools.length > 0) { + pools.push(...pancakePools); + } + } + + // Fetch pool state data for each pool + const poolAddresses = pools.map(pool => pool.poolAddress); + + const poolStateResponse = await axios.get(`${BASE_URL}${chain}/api/v1/poolState?addresses=${poolAddresses.join(',')}`); + const poolStates = poolStateResponse.data.data; + + // Create a map for quick lookup + const poolStateMap = {}; + poolStates.forEach(state => { + poolStateMap[state.poolAddress] = state; + }); + + // Process pools for this chain + const chainPools = pools.map(pool => { + const poolState = poolStateMap[pool.poolAddress]; + + if (!poolState) { + return null; + } + + // Extract APY data + const apr = poolState.apr || {}; + const kemLMApr = poolState.kemLMApr || {}; + const kemEGApr = poolState.kemEGApr || {}; + + // Calculate APY values + const apyBase = parseFloat(apr['7d']) || 0; + const apyReward = (parseFloat(kemLMApr['7d']) || 0) + (parseFloat(kemEGApr['7d']) || 0); + + // Get token symbols and addresses + const token0 = poolState.token0 || {}; + const token1 = poolState.token1 || {}; + + let symbol = ''; + let underlyingTokens = []; + + if (token0.symbol && token1.symbol) { + symbol = utils.formatSymbol(`${token0.symbol}-${token1.symbol}`); + underlyingTokens = [token0.address, token1.address]; + } else if (token0.symbol) { + symbol = utils.formatSymbol(token0.symbol); + underlyingTokens = [token0.address]; + } else if (token1.symbol) { + symbol = utils.formatSymbol(token1.symbol); + underlyingTokens = [token1.address]; + } else { + symbol = 'UNKNOWN'; + underlyingTokens = []; + } + + // Get reward tokens if they exist + const rewardTokens = []; + if (poolState.tokenReward && poolState.tokenReward.all && poolState.tokenReward.all.length > 0) { + poolState.tokenReward.all.forEach(reward => { + if (reward.tokenInfo && reward.tokenInfo.address) { + rewardTokens.push(reward.tokenInfo.address); + } + }); + } + + return { + pool: `${pool.poolAddress}-${chain}`, + chain: utils.formatChain(chain), + project: 'kyberswap-fairflow', + symbol, + tvlUsd: parseFloat(pool.tvlUsd) || 0, + apyBase, + apyReward, + rewardTokens: rewardTokens.length > 0 ? rewardTokens : undefined, + underlyingTokens, + poolMeta: 'Univ4 Kyber FairFlow', + }; + }).filter(pool => pool !== null && utils.keepFinite(pool)); + + allPools.push(...chainPools); + } catch (chainError) { + console.error(`Error fetching data for chain ${chain}:`, chainError); + // Continue with other chains even if one fails + continue; + } + } + + return allPools; + } catch (e) { + console.error('Error fetching KyberSwap Fairflow data:', e); + return []; + } +}; + +const main = async (timestamp = null) => { + return await topLvl(timestamp); +}; + +module.exports = { + apy: main, + timetravel: false, + url: 'https://kyberswap.com/pools', +}; diff --git a/src/adaptors/lachain-yield-market/index.js b/src/adaptors/lachain-yield-market/index.js new file mode 100644 index 0000000000..107f33f35a --- /dev/null +++ b/src/adaptors/lachain-yield-market/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils'); + +const url = 'https://farms-info.lachain.io/farms/ladex'; + + +const apy = (dataLadex) => { + const data = []; + + for(const pool of dataLadex){ + data.push({ + pool: pool.id, + chain: 'lachain', + project: 'lachain-yield-market', + symbol: pool.name, + tvlUsd: parseFloat(pool.tvl), + apy: parseFloat(pool.apy)*100 + }); + } + return data; +}; + +const main = async () => { + // pull data + const dataLadex = await utils.getData(url); + // calculate apy + let data = apy(dataLadex); + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://lachain.io/app/yield-market', +}; diff --git a/src/adaptors/lagoon/index.js b/src/adaptors/lagoon/index.js new file mode 100644 index 0000000000..ee9a291391 --- /dev/null +++ b/src/adaptors/lagoon/index.js @@ -0,0 +1,87 @@ +const { request, gql } = require('graphql-request'); + +const GRAPH_URL = 'https://api.lagoon.finance/query'; +const CHAINS = { + ethereum: 1, + base: 8453, + tac: 239, + arbitrum: 42161, + linea: 59144, + plasma: 9745, + avalanche: 43114, +}; + +const gqlQueries = { + vaultsData: gql` + query GetVaultsData($chainId: Int!, $skip: Int!) { + vaults( + first: 100 + skip: $skip + where: { chainId_in: [$chainId], isVisible_eq: true } + ) { + pageInfo { + hasNextPage + } + items { + id + address + chain { + id + } + symbol + asset { + address + decimals + priceUsd + symbol + } + state { + totalAssetsUsd + weeklyApr { + linearNetAprWithoutExtraYields + } + } + } + } + } + `, +}; + +const apy = async () => { + let pools = []; + + for (const [chain, chainId] of Object.entries(CHAINS)) { + // Fetch vaults data with pagination + let allVaults = []; + let skip = 0; + while (true) { + const { vaults } = await request(GRAPH_URL, gqlQueries.vaultsData, { + chainId, + skip, + }); + + allVaults = allVaults.concat(vaults.items); + if (!vaults.pageInfo.hasNextPage) break; + skip += 100; + } + const _pools = allVaults.map((vault) => { + return { + pool: `lagoon-${vault.address}-${chain}`, + chain, + project: 'lagoon', + symbol: vault.symbol, + apyBase: vault.state.weeklyApr.linearNetAprWithoutExtraYields, + tvlUsd: vault.state.totalAssetsUsd || 0, + underlyingTokens: [vault.asset.address], + url: `https://app.lagoon.finance/vault/${vault.chain.id}/${vault.address}`, + }; + }); + pools = pools.concat(_pools); + } + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/landx-finance/index.js b/src/adaptors/landx-finance/index.js new file mode 100644 index 0000000000..2c66da8348 --- /dev/null +++ b/src/adaptors/landx-finance/index.js @@ -0,0 +1,117 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +let oraclePrices = new Map(); +oraclePrices.set('arbitrum', '0x050EF3b1CE0CCE775A224d9712b961A86137aa80'); +oraclePrices.set('ethereum', '0xF49A0863D532E6036D693FBACfd2417Aebda8784'); + +const tokens = { + arbitrum: { + xSOY: '0xaab1f70478E734e972cDcC108c42A7c8915f5606', + xRICE: '0x2D8C8888FBFEa79f63dF39baFFf15E70CE4b66c5', + xCORN: '0x2D09268E7a8271b41CdD3019D97a4980D8110BfA', + xWHEAT: '0xBa5630d57A8DdEf4EB97b5659c2cb9191dBB4Cab', + }, + ethereum: { + xSOY: '0x8A78C1042F24349595f36f1a83091163487f2241', + xRICE: '0x3356328A3CA51D2664620757bd1c475Ca77FFaB5', + xCORN: '0x5074c4FA383d63D62d5F531D1CF92125fb39E859', + xWHEAT: '0x1B2B0FA9283595F5036C007dD99Ed0aA6de8362E', + }, +}; + +const getPrice = async (network, address) => { + let oracle = oraclePrices.get(network); + const price = await sdk.api.abi.call({ + abi: 'function getXTokenPrice(address xToken) public view returns (uint256)', + target: oracle, + params: [address], + chain: network, + }); + return price.output / 1000000; +}; + +const getCropPrice = async (network, crop) => { + let oracle = oraclePrices.get(network); + const price = await sdk.api.abi.call({ + abi: 'function prices(string memory) public view returns (uint256)', + target: oracle, + params: [crop], + chain: network, + }); + return price.output / 1000000000; +}; + +const getLocked = async (network, target) => { + const locked = await sdk.api.abi.call({ + abi: 'function totalSupply() public view returns (uint256)', + target: target, + chain: network, + }); + return locked.output / 1000000; +}; + +const getxbasketTVL = async () => { + const locked = await sdk.api.abi.call({ + abi: 'function calculateTVL() public view returns (uint256)', + target: '0x6fC27F5CC0aAFeC8e2b8bC4E6393aC89e45232d3', + chain: 'ethereum', + }); + return locked.output / 1000000; +}; + +const poolsFunction = async () => { + let pools = []; + let sumEthereumAPY = 0; + let tokensList = Object.values(tokens); + let networks = Object.keys(tokens); + + await Promise.all( + Object.values(networks).map(async (value, key) => { + let tokenNames = Object.keys(tokensList[key]); + let tokenAddresses = Object.values(tokensList[key]); + await Promise.all( + tokenAddresses.map(async (tokenAddress, nameIndex) => { + let price = await getPrice(value, tokenAddress); + let cTokenPrice = await getCropPrice( + value, + tokenNames[nameIndex].replace('x', '') + ); + let locked = await getLocked(value, tokenAddress); + let apy = (cTokenPrice / price) * 100; + if (value == 'ethereum') { + sumEthereumAPY += apy; + } + let pool = { + pool: tokenAddress, + chain: utils.formatChain(value), + project: 'landx-finance', + symbol: tokenNames[nameIndex], + tvlUsd: locked * price, + apy: apy, + }; + pools.push(pool); + }) + ); + }) + ); + + let xbasketTVL = await getxbasketTVL(); + let pool = { + pool: '0x6fC27F5CC0aAFeC8e2b8bC4E6393aC89e45232d3', + chain: utils.formatChain('ethereum'), + project: 'landx-finance', + symbol: 'xBASKET', + tvlUsd: xbasketTVL, + apy: sumEthereumAPY / 4, + }; + pools.push(pool); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://landx.fi/dashboard/xTokens', +}; diff --git a/src/adaptors/latch/index.js b/src/adaptors/latch/index.js new file mode 100644 index 0000000000..d3ef7dc1a6 --- /dev/null +++ b/src/adaptors/latch/index.js @@ -0,0 +1,81 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { GraphQLClient, gql } = require('graphql-request'); + +const atETH = '0xc314b8637B05A294Ae9D9C29300d5f667c748baD'; +const atUSD = '0xc4af68Dd5b96f0A544c4417407773fEFDc97F58d'; +const project = 'latch'; +const symbolU = 'atUSD'; +const symbolE = 'atETH'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const gqlEndpoint = 'https://savings-graphigo.prd.latch.io/query'; +const graphClient = new GraphQLClient(gqlEndpoint); +const NAV = '0x5D3920CCC068039E5B6FE680CaB7Aa09fE8E053C'; +const abi = 'function getNavByTimestamp(address,uint48) view returns (uint256 , uint48 )'; +const eth = '0x0000000000000000000000000000000000000000' +const usdt = '0xdac17f958d2ee523a2206206994597c13d831ec7' + + +const apyQuery = gql` + query GetAPYs($lsdToken: String!) {\n GetAPYs(lsdToken: $lsdToken)\n} +`; + +const timestamp = Math.floor(Date.now() / 1000); + +const apy = async () => { + const tvlUsd = + (await sdk.api.erc20.totalSupply({ target: atUSD, chain: 'gravity' })).output / + 1e18; + const tvlEth = + (await sdk.api.erc20.totalSupply({ target: atETH, chain: 'gravity' })).output / + 1e18; + + + const ethApi = new sdk.ChainApi({ chain: 'ethereum', timestamp: timestamp }); + await Promise.all([ethApi.getBlock()]); + const [usdNav, ethNav] = await Promise.all([ + ethApi.call({ target: NAV, params: [atUSD, timestamp], abi }), + ethApi.call({ target: NAV, params: [atETH, timestamp], abi }), + ]); + const usdNavNum = parseFloat(usdNav[0].toString()); + const ethNavNum = parseFloat(ethNav[0].toString()); + const usdtResult = (tvlUsd * usdNavNum) / Math.pow(10, 18); + const ethResult = (tvlEth * ethNavNum) / Math.pow(10, 18); + + + const ethPriceKey = `ethereum:${eth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${ethPriceKey}`) + ).data.coins[ethPriceKey]?.price; + const usdtPriceKey = `ethereum:${usdt}`; + const usdtPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${usdtPriceKey}`) + ).data.coins[usdtPriceKey]?.price; + + const { GetAPYs: atUsdApy } = await graphClient.request(apyQuery, { lsdToken: atUSD }); + const { GetAPYs: atEthApy } = await graphClient.request(apyQuery, { lsdToken: atETH }); + + + return [ + { + pool: `${atETH}-gravity`, + chain: 'Gravity', + project, + symbol: symbolE, + underlyingTokens: [atETH], + apyBase: Number(atEthApy) * 100, + tvlUsd: ethResult * ethPrice, + }, + { + pool: `${atUSD}-gravity`, + chain: 'Gravity', + project, + symbol: symbolU, + underlyingTokens: [atUSD], + apyBase: Number(atUsdApy) * 100, + tvlUsd: usdtResult * usdtPrice, + }, + ]; +}; + +module.exports = { apy, url: 'https://savings.latch.io/' }; diff --git a/src/adaptors/layerbank/abiCore.json b/src/adaptors/layerbank/abiCore.json new file mode 100644 index 0000000000..2ce285fb05 --- /dev/null +++ b/src/adaptors/layerbank/abiCore.json @@ -0,0 +1,896 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "BorrowCapUpdated", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "newBorrowCap", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CloseFactorUpdated", + "inputs": [ + { + "type": "uint256", + "name": "newCloseFactor", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CollateralFactorUpdated", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "newCollateralFactor", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FlashLoan", + "inputs": [ + { + "type": "address", + "name": "target", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "initiator", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "asset", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "premium", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "KeeperUpdated", + "inputs": [ + { + "type": "address", + "name": "newKeeper", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LABDistributorUpdated", + "inputs": [ + { + "type": "address", + "name": "newLABDistributor", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LeveragerUpdated", + "inputs": [ + { + "type": "address", + "name": "newLeverager", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LiquidationIncentiveUpdated", + "inputs": [ + { + "type": "uint256", + "name": "newLiquidationIncentive", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MarketEntered", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MarketExited", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MarketListed", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MarketRedeem", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "uAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MarketSupply", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "uAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RebateDistributorUpdated", + "inputs": [ + { + "type": "address", + "name": "newRebateDistributor", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SupplyCapUpdated", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "newSupplyCap", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Unpaused", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ValidatorUpdated", + "inputs": [ + { + "type": "address", + "name": "newValidator", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "collateralInUSD", + "internalType": "uint256" + }, + { "type": "uint256", "name": "supplyInUSD", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowInUSD", "internalType": "uint256" } + ], + "name": "accountLiquidityOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address[]", "name": "", "internalType": "address[]" } + ], + "name": "allMarkets", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "borrow", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "borrowBehalf", + "inputs": [ + { "type": "address", "name": "borrower", "internalType": "address" }, + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "checkMembership", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "address", "name": "lToken", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimLab", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimLab", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimLabBehalf", + "inputs": [ + { "type": "address[]", "name": "accounts", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "closeFactor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "compoundLab", + "inputs": [ + { "type": "uint256", "name": "lockDuration", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "enterMarkets", + "inputs": [ + { "type": "address[]", "name": "lTokens", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "exitMarket", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "initialize", + "inputs": [ + { + "type": "address", + "name": "_priceCalculator", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "initialized", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "keeper", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract ILABDistributor" + } + ], + "name": "labDistributor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "leverager", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [], + "name": "liquidateBorrow", + "inputs": [ + { + "type": "address", + "name": "lTokenBorrowed", + "internalType": "address" + }, + { + "type": "address", + "name": "lTokenCollateral", + "internalType": "address" + }, + { "type": "address", "name": "borrower", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "liquidationIncentive", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "listMarket", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address payable" + }, + { "type": "uint256", "name": "supplyCap", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowCap", "internalType": "uint256" }, + { + "type": "uint256", + "name": "collateralFactor", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.MarketInfo", + "components": [ + { "type": "bool", "name": "isListed", "internalType": "bool" }, + { "type": "uint256", "name": "supplyCap", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowCap", "internalType": "uint256" }, + { + "type": "uint256", + "name": "collateralFactor", + "internalType": "uint256" + } + ] + } + ], + "name": "marketInfoOf", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "bool", "name": "isListed", "internalType": "bool" }, + { "type": "uint256", "name": "supplyCap", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowCap", "internalType": "uint256" }, + { + "type": "uint256", + "name": "collateralFactor", + "internalType": "uint256" + } + ], + "name": "marketInfos", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address[]", "name": "", "internalType": "address[]" } + ], + "name": "marketListOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "marketListOfUsers", + "inputs": [ + { "type": "address", "name": "", "internalType": "address" }, + { "type": "uint256", "name": "", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "markets", + "inputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "pause", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "paused", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IPriceCalculator" + } + ], + "name": "priceCalculator", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "rebateDistributor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "redeemToken", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "lAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "redeemUnderlying", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "removeMarket", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address payable" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [], + "name": "repayBorrow", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setCloseFactor", + "inputs": [ + { "type": "uint256", "name": "newCloseFactor", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setCollateralFactor", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { + "type": "uint256", + "name": "newCollateralFactor", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setKeeper", + "inputs": [ + { "type": "address", "name": "_keeper", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setLABDistributor", + "inputs": [ + { + "type": "address", + "name": "_labDistributor", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setLeverager", + "inputs": [ + { "type": "address", "name": "_leverager", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setLiquidationIncentive", + "inputs": [ + { + "type": "uint256", + "name": "newLiquidationIncentive", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setMarketBorrowCaps", + "inputs": [ + { "type": "address[]", "name": "lTokens", "internalType": "address[]" }, + { + "type": "uint256[]", + "name": "newBorrowCaps", + "internalType": "uint256[]" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setMarketSupplyCaps", + "inputs": [ + { "type": "address[]", "name": "lTokens", "internalType": "address[]" }, + { + "type": "uint256[]", + "name": "newSupplyCaps", + "internalType": "uint256[]" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setPriceCalculator", + "inputs": [ + { + "type": "address", + "name": "_priceCalculator", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setRebateDistributor", + "inputs": [ + { + "type": "address", + "name": "_rebateDistributor", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setValidator", + "inputs": [ + { "type": "address", "name": "_validator", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "supply", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "supplyBehalf", + "inputs": [ + { "type": "address", "name": "supplier", "internalType": "address" }, + { "type": "address", "name": "lToken", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { "type": "address", "name": "newOwner", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferTokens", + "inputs": [ + { "type": "address", "name": "spender", "internalType": "address" }, + { "type": "address", "name": "src", "internalType": "address" }, + { "type": "address", "name": "dst", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "unpause", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "usersOfMarket", + "inputs": [ + { "type": "address", "name": "", "internalType": "address" }, + { "type": "address", "name": "", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "validator", + "inputs": [] + } +] diff --git a/src/adaptors/layerbank/abiLABDistributor.json b/src/adaptors/layerbank/abiLABDistributor.json new file mode 100644 index 0000000000..f934b53c55 --- /dev/null +++ b/src/adaptors/layerbank/abiLABDistributor.json @@ -0,0 +1,613 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "Claimed", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Compound", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DistributionSpeedUpdated", + "inputs": [ + { + "type": "address", + "name": "lToken", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "supplySpeed", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "borrowSpeed", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Unpaused", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "BOOST_MAX", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "BOOST_PORTION", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "LAB", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.DistributionAccountInfo", + "components": [ + { + "type": "uint256", + "name": "accuredLAB", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "boostedSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "boostedBorrow", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareBorrow", + "internalType": "uint256" + } + ] + } + ], + "name": "accountDistributionInfoOf", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256", "name": "accuredLAB", "internalType": "uint256" }, + { "type": "uint256", "name": "boostedSupply", "internalType": "uint256" }, + { "type": "uint256", "name": "boostedBorrow", "internalType": "uint256" }, + { + "type": "uint256", + "name": "accPerShareSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareBorrow", + "internalType": "uint256" + } + ], + "name": "accountDistributions", + "inputs": [ + { "type": "address", "name": "", "internalType": "address" }, + { "type": "address", "name": "", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "accuredLAB", + "inputs": [ + { "type": "address[]", "name": "markets", "internalType": "address[]" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "approve", + "inputs": [ + { "type": "address", "name": "_spender", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.DistributionAPY", + "components": [ + { + "type": "uint256", + "name": "apySupplyLab", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "apyBorrowLab", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "apyAccountSupplyLab", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "apyAccountBorrowLab", + "internalType": "uint256" + } + ] + } + ], + "name": "apyDistributionOf", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "boostedSupplyRatio", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "boostedBorrowRatio", + "internalType": "uint256" + } + ], + "name": "boostedRatioOf", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claim", + "inputs": [ + { "type": "address[]", "name": "markets", "internalType": "address[]" }, + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "claimBehalf", + "inputs": [ + { "type": "address[]", "name": "markets", "internalType": "address[]" }, + { "type": "address[]", "name": "accounts", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "compound", + "inputs": [ + { "type": "address[]", "name": "markets", "internalType": "address[]" }, + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "lockDuration", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "compoundMinLockDuration", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address", "name": "", "internalType": "contract ICore" } + ], + "name": "core", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.DistributionInfo", + "components": [ + { + "type": "uint256", + "name": "supplySpeed", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "borrowSpeed", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "totalBoostedSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "totalBoostedBorrow", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareBorrow", + "internalType": "uint256" + }, + { "type": "uint256", "name": "accruedAt", "internalType": "uint256" } + ] + } + ], + "name": "distributionInfoOf", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256", "name": "supplySpeed", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowSpeed", "internalType": "uint256" }, + { + "type": "uint256", + "name": "totalBoostedSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "totalBoostedBorrow", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareSupply", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accPerShareBorrow", + "internalType": "uint256" + }, + { "type": "uint256", "name": "accruedAt", "internalType": "uint256" } + ], + "name": "distributions", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "initialize", + "inputs": [ + { "type": "address", "name": "_lab", "internalType": "address" }, + { "type": "address", "name": "_core", "internalType": "address" }, + { "type": "address", "name": "_xlab", "internalType": "address" }, + { + "type": "address", + "name": "_priceCalculator", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "initialized", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "notifyBorrowUpdated", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" }, + { "type": "address", "name": "user", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "notifySupplyUpdated", + "inputs": [ + { "type": "address", "name": "market", "internalType": "address" }, + { "type": "address", "name": "user", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "notifyTransferred", + "inputs": [ + { "type": "address", "name": "qToken", "internalType": "address" }, + { "type": "address", "name": "sender", "internalType": "address" }, + { "type": "address", "name": "receiver", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "pause", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "paused", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IPriceCalculator" + } + ], + "name": "priceCalculator", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IRewardController" + } + ], + "name": "rewardController", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setCompoundMinLockDuration", + "inputs": [ + { + "type": "uint256", + "name": "newMinLockDuration", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setDistributionSpeed", + "inputs": [ + { "type": "address", "name": "qToken", "internalType": "address" }, + { "type": "uint256", "name": "supplySpeed", "internalType": "uint256" }, + { "type": "uint256", "name": "borrowSpeed", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setPriceCalculator", + "inputs": [ + { + "type": "address", + "name": "_priceCalculator", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setRewardController", + "inputs": [ + { + "type": "address", + "name": "_rewardController", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setXLAB", + "inputs": [ + { "type": "address", "name": "_xlab", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { "type": "address", "name": "newOwner", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "unpause", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateAccountBoostedInfo", + "inputs": [{ "type": "address", "name": "user", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "withdrawReward", + "inputs": [ + { "type": "address", "name": "receiver", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address", "name": "", "internalType": "contract IxLAB" } + ], + "name": "xLAB", + "inputs": [] + } +] diff --git a/src/adaptors/layerbank/abiLToken.json b/src/adaptors/layerbank/abiLToken.json new file mode 100644 index 0000000000..9b796c2706 --- /dev/null +++ b/src/adaptors/layerbank/abiLToken.json @@ -0,0 +1,724 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "type": "address", + "name": "owner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "spender", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Borrow", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "ammount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "accountBorrow", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LiquidateBorrow", + "inputs": [ + { + "type": "address", + "name": "liquidator", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "borrower", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "address", + "name": "lTokenCollateral", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "seizeAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Mint", + "inputs": [ + { + "type": "address", + "name": "minter", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "mintAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Redeem", + "inputs": [ + { + "type": "address", + "name": "account", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "underlyingAmount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "lTokenAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RepayBorrow", + "inputs": [ + { + "type": "address", + "name": "payer", + "internalType": "address", + "indexed": false + }, + { + "type": "address", + "name": "borrower", + "internalType": "address", + "indexed": false + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "accountBorrow", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Transfer", + "inputs": [ + { + "type": "address", + "name": "from", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "to", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "_totalBorrow", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "accInterestIndex", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.AccountSnapshot", + "components": [ + { + "type": "uint256", + "name": "lTokenBalance", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "borrowBalance", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "exchangeRate", + "internalType": "uint256" + } + ] + } + ], + "name": "accountSnapshot", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [ + { + "type": "tuple", + "name": "", + "internalType": "struct Constant.AccountSnapshot", + "components": [ + { + "type": "uint256", + "name": "lTokenBalance", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "borrowBalance", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "exchangeRate", + "internalType": "uint256" + } + ] + } + ], + "name": "accruedAccountSnapshot", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "accruedBorrowBalanceOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "accruedExchangeRate", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "accruedTotalBorrow", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "allowance", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "address", "name": "spender", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "approve", + "inputs": [ + { "type": "address", "name": "spender", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "balanceOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "borrow", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "borrowBalanceOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "borrowBehalf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "address", "name": "borrower", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address", "name": "", "internalType": "contract ICore" } + ], + "name": "core", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint8", "name": "", "internalType": "uint8" }], + "name": "decimals", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "exchangeRate", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getAccInterestIndex", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getCash", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "getOwner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "getRateModel", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "initialize", + "inputs": [ + { "type": "string", "name": "_name", "internalType": "string" }, + { "type": "string", "name": "_symbol", "internalType": "string" }, + { "type": "uint8", "name": "_decimals", "internalType": "uint8" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "initialized", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "lastAccruedTime", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [ + { "type": "uint256", "name": "seizeLAmount", "internalType": "uint256" }, + { "type": "uint256", "name": "rebateLAmount", "internalType": "uint256" }, + { + "type": "uint256", + "name": "liquidatorLAmount", + "internalType": "uint256" + } + ], + "name": "liquidateBorrow", + "inputs": [ + { + "type": "address", + "name": "lTokenCollateral", + "internalType": "address" + }, + { "type": "address", "name": "liquidator", "internalType": "address" }, + { "type": "address", "name": "borrower", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "string", "name": "", "internalType": "string" }], + "name": "name", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "address", "name": "", "internalType": "contract IRateModel" } + ], + "name": "rateModel", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IRebateDistributor" + } + ], + "name": "rebateDistributor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "redeemToken", + "inputs": [ + { "type": "address", "name": "redeemer", "internalType": "address" }, + { "type": "uint256", "name": "lAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "redeemUnderlying", + "inputs": [ + { "type": "address", "name": "redeemer", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "repayBorrow", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "reserveFactor", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "seize", + "inputs": [ + { "type": "address", "name": "liquidator", "internalType": "address" }, + { "type": "address", "name": "borrower", "internalType": "address" }, + { "type": "uint256", "name": "lAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setCore", + "inputs": [ + { "type": "address", "name": "_core", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setRateModel", + "inputs": [ + { "type": "address", "name": "_rateModel", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setRebateDistributor", + "inputs": [ + { + "type": "address", + "name": "_rebateDistributor", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setReserveFactor", + "inputs": [ + { "type": "uint256", "name": "_reserveFactor", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setUnderlying", + "inputs": [ + { "type": "address", "name": "_underlying", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "supply", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "payable", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "supplyBehalf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" }, + { "type": "address", "name": "supplier", "internalType": "address" }, + { "type": "uint256", "name": "uAmount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "string", "name": "", "internalType": "string" }], + "name": "symbol", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "totalBorrow", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "totalReserve", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "totalSupply", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "transfer", + "inputs": [ + { "type": "address", "name": "dst", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "transferFrom", + "inputs": [ + { "type": "address", "name": "src", "internalType": "address" }, + { "type": "address", "name": "dst", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { "type": "address", "name": "newOwner", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferTokensInternal", + "inputs": [ + { "type": "address", "name": "spender", "internalType": "address" }, + { "type": "address", "name": "src", "internalType": "address" }, + { "type": "address", "name": "dst", "internalType": "address" }, + { "type": "uint256", "name": "amount", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "underlying", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "underlyingBalanceOf", + "inputs": [ + { "type": "address", "name": "account", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "withdrawReserves", + "inputs": [] + }, + { "type": "receive", "stateMutability": "payable" } +] diff --git a/src/adaptors/layerbank/abiPriceCalculator.json b/src/adaptors/layerbank/abiPriceCalculator.json new file mode 100644 index 0000000000..7f965ac38c --- /dev/null +++ b/src/adaptors/layerbank/abiPriceCalculator.json @@ -0,0 +1,143 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getUnderlyingPrice", + "inputs": [ + { "type": "address", "name": "lToken", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256[]", "name": "", "internalType": "uint256[]" } + ], + "name": "getUnderlyingPrices", + "inputs": [ + { "type": "address[]", "name": "lTokens", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "keeper", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256", "name": "priceInUSD", "internalType": "uint256" } + ], + "name": "priceOf", + "inputs": [ + { "type": "address", "name": "asset", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256", "name": "valueInUSD", "internalType": "uint256" } + ], + "name": "priceOfETH", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256[]", "name": "", "internalType": "uint256[]" } + ], + "name": "pricesOf", + "inputs": [ + { "type": "address[]", "name": "assets", "internalType": "address[]" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { "type": "uint256", "name": "lastData", "internalType": "uint256" }, + { "type": "uint256", "name": "lastUpdated", "internalType": "uint256" } + ], + "name": "references", + "inputs": [{ "type": "address", "name": "", "internalType": "address" }] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setKeeper", + "inputs": [ + { "type": "address", "name": "_keeper", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setPrices", + "inputs": [ + { "type": "address[]", "name": "assets", "internalType": "address[]" }, + { "type": "uint256[]", "name": "prices", "internalType": "uint256[]" }, + { "type": "uint256", "name": "timestamp", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setTokenFeed", + "inputs": [ + { "type": "address", "name": "asset", "internalType": "address" }, + { "type": "address", "name": "feed", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { "type": "address", "name": "newOwner", "internalType": "address" } + ] + } +] diff --git a/src/adaptors/layerbank/abiRateModelSlope.json b/src/adaptors/layerbank/abiRateModelSlope.json new file mode 100644 index 0000000000..555341b9e4 --- /dev/null +++ b/src/adaptors/layerbank/abiRateModelSlope.json @@ -0,0 +1,110 @@ +[ + { "type": "constructor", "stateMutability": "nonpayable", "inputs": [] }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getBorrowRate", + "inputs": [ + { "type": "uint256", "name": "cash", "internalType": "uint256" }, + { "type": "uint256", "name": "borrows", "internalType": "uint256" }, + { "type": "uint256", "name": "reserves", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "getSupplyRate", + "inputs": [ + { "type": "uint256", "name": "cash", "internalType": "uint256" }, + { "type": "uint256", "name": "borrows", "internalType": "uint256" }, + { "type": "uint256", "name": "reserves", "internalType": "uint256" }, + { "type": "uint256", "name": "reserveFactor", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "initialize", + "inputs": [ + { + "type": "uint256", + "name": "_baseRatePerYear", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_slopePerYearFirst", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_slopePerYearSecond", + "internalType": "uint256" + }, + { "type": "uint256", "name": "_optimal", "internalType": "uint256" } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "bool", "name": "", "internalType": "bool" }], + "name": "initialized", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [{ "type": "address", "name": "", "internalType": "address" }], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { "type": "address", "name": "newOwner", "internalType": "address" } + ] + }, + { + "type": "function", + "stateMutability": "pure", + "outputs": [{ "type": "uint256", "name": "", "internalType": "uint256" }], + "name": "utilizationRate", + "inputs": [ + { "type": "uint256", "name": "cash", "internalType": "uint256" }, + { "type": "uint256", "name": "borrows", "internalType": "uint256" }, + { "type": "uint256", "name": "reserves", "internalType": "uint256" } + ] + } +] diff --git a/src/adaptors/layerbank/index.js b/src/adaptors/layerbank/index.js new file mode 100644 index 0000000000..57832a0f9a --- /dev/null +++ b/src/adaptors/layerbank/index.js @@ -0,0 +1,300 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abiCore = require('./abiCore.json'); +const abiLABDistributor = require('./abiLABDistributor.json'); +const abiLToken = require('./abiLToken.json'); +const abiRateModelSlope = require('./abiRateModelSlope.json'); +const abiPriceCalculator = require('./abiPriceCalculator.json'); +const utils = require('../utils'); + +const MOVEMENT_RPC = 'https://mainnet.movementnetwork.xyz/v1'; + +const CHAINS = { + move: { + pool: '0xf257d40859456809be19dfee7f4c55c4d033680096aeeb4228b7a15749ab68ea', + }, + manta: { + CORE: '0xB7A23Fc0b066051dE58B922dC1a08f33DF748bbf', + LABDistributor: '0x67c10B7b8eEFe92EB4DfdEeedd94263632E483b0', + LAB: '0x20a512dbdc0d006f46e6ca11329034eb3d18c997', + PriceCalculator: '0x38f4384B457F81A4895c93a7503c255eFd0746d2', + }, + linea: { + CORE: '0x43Eac5BFEa14531B8DE0B334E123eA98325de866', + LABDistributor: '0x3df121931dc2e72DC4746dA933126f6d50595605', + LAB: '0x6Bc3EDeeE5D182cd4d5d5b26F54fddA0fAB2b5D1', + PriceCalculator: '0x35A8C6050591C2f65B3e926B4b2eF825E3766bd6', + }, + scroll: { + CORE: '0xEC53c830f4444a8A56455c6836b5D2aA794289Aa', + LABDistributor: '0xF1F897601A525F57c5EA751a1F3ec5f9ADAc0321', + LAB: '0x2A00647F45047f05BDed961Eb8ECABc42780e604', + PriceCalculator: '0x760bd7Fc100F217678D1b521404D2E93Db7Bec5F', + }, +}; + +const apy = async (chain) => { + if (chain === 'move') { + const reservesData = await utils.getData(`${MOVEMENT_RPC}/view`, { + function: `${CHAINS[chain].pool}::ui_pool_data_provider_v3::get_reserves_data`, + type_arguments: [], + arguments: [], + }); + + const [reserves] = reservesData; + + return reserves.map((r) => { + const assetPriceUsd = r.price_in_market_reference_currency / (10 ** 18); + const assetDecimals = r.decimals; + const availableLiquidity = r.available_liquidity / (10 ** assetDecimals); + const totalBorrow = r.total_scaled_variable_debt / (10 ** assetDecimals); + + const liquidityUsd = availableLiquidity * assetPriceUsd; + const totalBorrowUsd = totalBorrow * assetPriceUsd; + const totalSupplyUsd = liquidityUsd + totalBorrowUsd; + + return { + pool: r.a_token_address, + chain, + project: 'layerbank', + symbol: r.name, + tvlUsd: liquidityUsd, + totalSupplyUsd, + totalBorrowUsd, + apyBase: r.liquidity_rate / (10 ** 27) * 100, + apyBaseBorrow: r.variable_borrow_rate / (10 ** 27) * 100, + apyReward: 0, + apyRewardBorrow: 0, + underlyingTokens: [r.underlying_asset], + rewardTokens: [], + ltv: r.base_lt_vas_collateral / (10 ** 5), + }; + }); + } else { + const CORE = CHAINS[chain].CORE; + const LABDistributor = CHAINS[chain].LABDistributor; + const LAB = CHAINS[chain].LAB; + const PriceCalculator = CHAINS[chain].PriceCalculator; + + const allMarkets = ( + await sdk.api.abi.call({ + target: CORE, + chain, + abi: abiCore.find(({ name }) => name === 'allMarkets'), + }) + ).output; + + const marketInfoOf = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiCore.find((n) => n.name === 'marketInfoOf'), + calls: allMarkets.map((m) => ({ + target: CORE, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalSupply'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalBorrow'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const totalReserve = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'totalReserve'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const rateModel = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'rateModel'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const reserveFactor = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'reserveFactor'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const cash = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'getCash'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const borrowRate = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiRateModelSlope.find((n) => n.name === 'getBorrowRate'), + calls: rateModel.map((m, i) => ({ + target: m, + params: [cash[i], totalBorrow[i], totalReserve[i]], + })), + }) + ).output.map((o) => o.output); + + const supplyRate = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiRateModelSlope.find((n) => n.name === 'getSupplyRate'), + calls: rateModel.map((m, i) => ({ + target: m, + params: [cash[i], totalBorrow[i], totalReserve[i], reserveFactor[i]], + })), + }) + ).output.map((o) => o.output); + + const distributions = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLABDistributor.find((n) => n.name === 'distributions'), + calls: allMarkets.map((m) => ({ + target: LABDistributor, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const underlying = ( + await sdk.api.abi.multiCall({ + chain, + abi: abiLToken.find((n) => n.name === 'underlying'), + calls: allMarkets.map((m) => ({ + target: m, + })), + }) + ).output.map((o) => o.output); + + const symbol = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:symbol', + calls: underlying.map((m) => ({ + target: m, + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const decimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: underlying.map((m) => ({ + target: m, + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const priceKeys = underlying.map((t) => `${chain}:${t}`).join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const priceLAB = + chain !== 'manta' + ? ( + await sdk.api.abi.call({ + target: PriceCalculator, + abi: abiPriceCalculator.find((m) => m.name === 'priceOf'), + params: [LAB], + chain, + }) + ).output + : null; + + return allMarkets.map((p, i) => { + const price = prices[`${chain}:${underlying[i]}`]?.price; + const decimal = decimals[i] ?? 18; + + const totalSupplyUsd = (totalSupply[i] / 10 ** decimal) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimal) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = (supplyRate[i] / 1e18) * 86400 * 365 * 100; + const apyBaseBorrow = (borrowRate[i] / 1e18) * 86400 * 365 * 100; + const underlyingTokens = [underlying[i]]; + const ltv = marketInfoOf[i].collateralFactor / 1e18; + + const apyReward = + (((distributions[i].supplySpeed / 1e18) * + 86400 * + 365 * + (priceLAB / 1e18)) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((distributions[i].borrowSpeed / 1e18) * + 86400 * + 365 * + (priceLAB / 1e18)) / + totalBorrowUsd) * + 100; + + return { + pool: p, + chain, + project: 'layerbank', + symbol: symbol[i] ?? 'ETH', + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + apyBase, + apyBaseBorrow, + apyReward, + apyRewardBorrow, + underlyingTokens, + rewardTokens: apyReward > 0 ? [LAB] : [], + ltv, + }; + }); + } +}; + +const main = async () => { + const pools = await Promise.all( + Object.keys(CHAINS).map((chain) => apy(chain)) + ); + return pools.flat().filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + apy: main, + url: 'https://app.layerbank.finance', +}; diff --git a/src/adaptors/lendle-earn/index.js b/src/adaptors/lendle-earn/index.js new file mode 100644 index 0000000000..5aee03aa27 --- /dev/null +++ b/src/adaptors/lendle-earn/index.js @@ -0,0 +1,104 @@ +const axios = require('axios'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const vaultsApi = 'https://lendle-vaults-api-184110952121.europe-west4.run.app'; +const vaultsApy = `${vaultsApi}/apy/breakdown`; +const vaultsData = `${vaultsApi}/vaults`; + +const vaultList = [ + "0x25ddfB3831b5a1099932E4cA9CD2Ea9cB6665F1B", + "0x32294e130181F31c6286B4B5AaA3697f538C3Bd7", + "0x3ad7d10085C7243a19c6589056A58EB94334CB52", + "0x43703b0FD253e1172A0F18e65d097bd7b120B7bf", + "0x4606E0fED3Daa8D175274103e37C070dA70C53F4", + "0x4fD28eabb44474aF1da36c7c4ea5441616D98076", + "0xB2Be0a666d4c34ded06242178E8138F7CEc72100", + "0xB761673116D7B1840CB94bbF7Adb673b4F4a18b4", + "0xD1d9C7be232920BFD971b2F3B83b1C5EFe4B15d8", + "0xD1FC69F097141189A4d46ee84E11992e6be87Cae", + "0xeB244CC3Fc3C3ca391D453def40CF78eaf3B7373", +]; + +const vaultsCampaignApi = 'https://api.merkl.xyz/v4/opportunities?name=lendle'; + +const chains = { + 'mantle': { + chainId: 5000, + }, +}; + +const abis = { + want: "function want() view returns (address)", + balance: "function balance() external view returns (uint256)", +}; + +const getApy = async () => { + const vaults = await Promise.all( + Object.keys(chains).map(async (chain) => { + const chainId = chains[chain].chainId; + + const _vaultsData = (await axios.get(vaultsData)).data; + + const calls = vaultList.map((vault) => ({ target: vault })); + const wants = await sdk.api.abi.multiCall({ abi: abis.want, calls, chain }); + const balances = await sdk.api.abi.multiCall({ abi: abis.balance, calls, chain }); + const { pricesByAddress: prices } = await utils.getPrices( + wants.output.map(({ output }) => output), + chain + ); + + const _vaultsApy = (await axios.get(vaultsApy)).data; + + const _vaultsCampaignApi = (await axios.get(vaultsCampaignApi)).data; + + return vaultList.map((t, i) => { + const config = _vaultsData.find( + (vault) => vault.earnContractAddress === t + ); + if (!config || config.status !== 'active') return null; + + const want = wants.output[i].output; + const balance = balances.output[i].output; + const price = prices[want.toLowerCase()]; + const tvlUsd = price * (balance / 10 ** config.tokenDecimals); + + const apyBase = _vaultsApy[config.id]?.totalApy * 100 || 0; + + const aprData = _vaultsCampaignApi.find( + (item) => + item.status === 'LIVE' && + item.identifier.toLowerCase() === t.toLowerCase() && + item.rewardsRecord.breakdowns[0].token.address !== + '0x0000000000000000000000000000000000000000' + ); + const apyReward = aprData ? aprData.apr : 0; + + const url = `https://app.lendle.xyz/vault/${config.id}`; + + return { + pool: `${t}-${chain}-lendle-earn`.toLowerCase(), + symbol: config.name, + project: 'lendle-earn', + chain, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [config.tokenAddress], + rewardTokens: + aprData && apyReward + ? ['0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8'] + : ['0x0000000000000000000000000000000000000000'], + url, + poolMeta: 'Vault', + }; + }); + }) + ); + + return vaults.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/lendle-pooled-markets/index.js b/src/adaptors/lendle-pooled-markets/index.js new file mode 100644 index 0000000000..2421bff03a --- /dev/null +++ b/src/adaptors/lendle-pooled-markets/index.js @@ -0,0 +1,148 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('../aave-v2/abiLendingPool'); +const abiProtocolDataProvider = require('../aave-v2/abiProtocolDataProvider'); + +const utils = require('../utils'); + +const lendleUrl = 'https://app.lendle.xyz'; +const poolsApr = `${lendleUrl}/api/apr`; + +const chains = { + mantle: { + LendingPool: '0xCFa5aE7c2CE8Fadc6426C1ff872cA45378Fb7cF3', + ProtocolDataProvider: '0x552b9e4bae485C4B7F540777d7D25614CdB84773', + url: 'mantle', + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const _poolsApr = (await axios.get(poolsApr)).data; + + return Promise.all( + reservesList.map(async (t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const apyReward = + _poolsApr.rewards_apy?.[t.toLowerCase()]?.supply * 100 || 0; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + const url = `${lendleUrl}/marketdetail?asset=${ + symbols[i] + }&contract=${t.toLowerCase()}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'lendle-pooled-markets', + chain, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [t], + rewardTokens: ['0x25356aeca4210eF7553140edb9b8026089E49396'], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }) + ); + }) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/lendos/index.js b/src/adaptors/lendos/index.js new file mode 100644 index 0000000000..c1d219be9d --- /dev/null +++ b/src/adaptors/lendos/index.js @@ -0,0 +1,14 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + return ( + await utils.getData('https://app.lendos.org/api/v1/referral/rewards/apy') + ).map((i) => { + const { poolMeta, ...rest } = i; + return rest; + }); +}; + +module.exports = { + apy: poolsFunction, +}; diff --git a/src/adaptors/libre-swap/index.js b/src/adaptors/libre-swap/index.js new file mode 100644 index 0000000000..6892f47ded --- /dev/null +++ b/src/adaptors/libre-swap/index.js @@ -0,0 +1,196 @@ +const axios = require('axios'); + +const CHAIN_URL = `https://lb.libre.org`; + +const precisionAdjustment = 10000; +const satsPerBTC = 100000000; +const blocksPerDay = 172800; +const daysInYear = 365; + +const getRewardSettings = async() => { + const result = await axios + .post(`${CHAIN_URL}/v1/chain/get_table_rows`, { + code: 'reward.libre', + table: 'global', + scope: 'reward.libre', + json: true, + }); + if (!result || !result.data || !result.data.rows) { + throw new Error('Error fetching reward settings'); + } + return result.data.rows[0][1]; +} + +const getAvailablePools = async() => { + const result = await axios + .post(`${CHAIN_URL}/v1/chain/get_table_rows`, { + code: 'reward.libre', + table: 'global', + scope: 'reward.libre', + json: true, + }); + if ( + !result || + !result.data || + !result.data.rows || + !result.data.rows[0] || + !result.data.rows[0][1] + ) { + return []; + } + return result.data.rows[0][1].allowed_pools; +} + +const getPoolStats = async(symbol) => { + const response = await axios + .post(`${CHAIN_URL}/v1/chain/get_table_rows`, { + json: true, + code: 'swap.libre', + scope: symbol, + table: 'stat', + limit: 10, + reverse: false, + show_payer: false, + }); + const row = response.data.rows[0]; + const pool1Amount = Number( + row.pool1.quantity.split(' ')[0] + ); + const pool2Amount = Number( + row.pool2.quantity.split(' ')[0] + ); + const price = Number((pool2Amount / pool1Amount).toFixed(2)); + return { + pool1Amount, + pool2Amount, + price, + supply: Number(row.supply.replace(symbol, '')), + }; +} + +const getLPBalance = async(symbol) => { + const farmLPBalanceResult = await axios + .post(`${CHAIN_URL}/v1/chain/get_currency_balance`, { + code: 'swap.libre', + account: 'farm.libre', + symbol, + }); + try { + return Number( + farmLPBalanceResult.data && farmLPBalanceResult.data.length + ? farmLPBalanceResult.data[0].replace(symbol, '') + : 0, + ); + } catch (e) { + return 0; + } +} + + +const getBTCUSDFarmingStats = async() => { + const rewardSettings = await getRewardSettings(); + const allowedPoolCount = rewardSettings.allowed_pools.length; + + const rewardPerBlock = rewardSettings.reward_per_block; + + const rewardPerFarm = + rewardPerBlock / precisionAdjustment / allowedPoolCount; + + const btcUsdPoolStats = await getPoolStats('BTCUSD'); + const lpTokenValue = + (btcUsdPoolStats.pool2Amount * 2) / btcUsdPoolStats.supply; + + const lpBalance = await getLPBalance('BTCUSD'); + const libreUSDValue = await getLibrePrice(); + const totalFarmValue = lpBalance * lpTokenValue; + + let apy = + (100 * libreUSDValue * blocksPerDay * rewardPerFarm * daysInYear) / + totalFarmValue; + + + apy = Number(apy.toFixed(2)); + + + return { + symbol: 'BTCUSD', + totalValue: totalFarmValue, + farming_staked: lpBalance ?? 0, + apy, + reward_per_farm: rewardPerFarm, + lpTokenValue, + }; +} + +const getLibrePrice = async() => { + const btcLibPrice = await getPoolStats('BTCLIB'); + const librePrice = 1 / btcLibPrice.price; + const btcPrice = await getPoolStats('BTCUSD'); + return librePrice * btcPrice.price; +} + +const getBTCLIBFarmingStats = async() => { + const rewardSettings = await getRewardSettings(); + const allowedPoolCount = rewardSettings.allowed_pools.length; + + const rewardPerBlock = rewardSettings.reward_per_block; + + const rewardPerFarm = + rewardPerBlock / precisionAdjustment / allowedPoolCount; + const btcPrice = (await getPoolStats('BTCUSD')).price; + const btcLibPoolStats = await getPoolStats('BTCLIB'); + const lpTokenValue = + (btcLibPoolStats.pool1Amount * 2 * btcPrice) / btcLibPoolStats.supply; + + const lpBalance = await getLPBalance('BTCLIB'); + const libreUSDValue = await getLibrePrice(); + const totalFarmValue = lpBalance * lpTokenValue; + + let apy = + (100 * libreUSDValue * blocksPerDay * rewardPerFarm * daysInYear) / + totalFarmValue; + + apy = Number(apy.toFixed(2)); + + return { + symbol: 'BTCLIB', + totalValue: totalFarmValue, + farming_staked: lpBalance ?? 0, + apy, + reward_per_farm: rewardPerFarm, + lpTokenValue, + }; +} + +const getAPYs = async () => { + const BTCLIB = await getBTCLIBFarmingStats(); + const BTCUSD = await getBTCUSDFarmingStats(); + return [{ + pool: 'BTCLIB', + chain: 'Libre', + project: 'libre-swap', + symbol: 'BTC-LIB', + apyReward: BTCLIB.apy, + tvlUsd: Number(BTCLIB.totalValue.toFixed(2)), + rewardTokens: ['LIBRE'], + underlyingTokens: ['BTC', 'LIBRE'], + poolMeta: 'BTC - Libre farming pool', + }, { + pool: 'BTCUSD', + chain: 'Libre', + project: 'libre-swap', + symbol: 'BTC-USD', + apyReward: BTCUSD.apy, + tvlUsd: Number(BTCUSD.totalValue.toFixed(2)), + rewardTokens: ['LIBRE'], + underlyingTokens: ['BTC', 'USDT'], + poolMeta: 'BTC - USDT farming pool', + }] +} + +module.exports = { + timetravel: false, + apy: getAPYs, + url: 'https://dashboard.libre.org/farming', +}; + diff --git a/src/adaptors/lido/index.js b/src/adaptors/lido/index.js index 96a3921ea6..78e46872db 100644 --- a/src/adaptors/lido/index.js +++ b/src/adaptors/lido/index.js @@ -1,70 +1,26 @@ const utils = require('../utils'); -const buildPool = (entry, chainString) => { - const newObj = { - pool: `lido-${entry.token}`, - chain: utils.formatChain(chainString), +const topLvl = async () => { + const [tvlData, apyData] = await Promise.all([ + utils.getData('https://eth-api.lido.fi/v1/protocol/steth/stats'), + utils.getData('https://eth-api.lido.fi/v1/protocol/steth/apr/last'), + ]); + + return { + pool: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84-ethereum', + chain: utils.formatChain('ethereum'), project: 'lido', - symbol: utils.formatSymbol(entry.token), - tvlUsd: - chainString === 'ethereum' ? entry.marketCap : entry.totalStaked.usd, - apy: entry.apr, + symbol: utils.formatSymbol('stETH'), + tvlUsd: tvlData.marketCap, + apyBase: Number(apyData.data.apr), + underlyingTokens: ['0x0000000000000000000000000000000000000000'], }; - - return newObj; }; -const topLvl = async (chainString, url, token) => { - if (chainString === 'ethereum') { - dataTvl = await utils.getData(`${url}/short-lido-stats`); - dataApy = await utils.getData(`${url}/steth-apr`); - dataTvl.apr = dataApy; - data = { ...dataTvl }; - } else { - data = await utils.getData(url); - } - data.token = token; - - // apy values from https://solana.lido.fi/api/stats for solana are incorrect - // using other endpoint instead. for more details see https://github.com/DefiLlama/yield-server/issues/6 - if (chainString === 'solana') { - apy = await utils.getData('https://solana.lido.fi/api/apy/apy?days=14'); - data.apr = apy.annual_percentage_yield; - } - - data = buildPool(data, chainString); - - return data; -}; - -const main = async () => { - const data = []; - // for some reason Promise.all often crashes here, so awaiting each individually - const ethereum = await topLvl( - 'ethereum', - 'https://stake.lido.fi/api', - 'stETH' - ); - const polygon = await topLvl( - 'polygon', - 'https://polygon.lido.fi/api/stats', - 'stMATIC' - ); - const solana = await topLvl( - 'solana', - 'https://solana.lido.fi/api/stats', - 'stSOL' - ); - const kusama = await topLvl( - 'kusama', - 'https://kusama.lido.fi/api/stats', - 'stKSM' - ); - data.push(ethereum, polygon, solana, kusama); - return data.flat(); -}; +const main = async () => [await topLvl()]; module.exports = { timetravel: false, apy: main, + url: 'https://lido.fi/#networks', }; diff --git a/src/adaptors/line-token-rewards/config.js b/src/adaptors/line-token-rewards/config.js new file mode 100644 index 0000000000..4c25493c28 --- /dev/null +++ b/src/adaptors/line-token-rewards/config.js @@ -0,0 +1,7 @@ +module.exports.CHAIN = 'Obyte'; +module.exports.PROJECT = 'line-token-rewards'; +module.exports.REWARD_TOKEN = 'GBYTE'; +module.exports.LLAMA_API_URL = 'https://api.llama.fi'; +module.exports.BACKEND_API_URL = 'https://kava.obyte.org/api'; +module.exports.MONTHLY_TOTAL_REWARDS_IN_KAVA = 1_100_000; +module.exports.DISTRIBUTION_SHARE = 0.5; diff --git a/src/adaptors/line-token-rewards/index.js b/src/adaptors/line-token-rewards/index.js new file mode 100644 index 0000000000..c76ac31b60 --- /dev/null +++ b/src/adaptors/line-token-rewards/index.js @@ -0,0 +1,76 @@ +// @see https://kava.obyte.org + +const sdk = require('@defillama/sdk'); +const { default: axios } = require('axios'); +const BigNumber = require('bignumber.js'); +const { ethers } = require('ethers'); +const { startOfMonth, endOfMonth } = require('date-fns'); + +const { LLAMA_API_URL, BACKEND_API_URL, CHAIN, REWARD_TOKEN, MONTHLY_TOTAL_REWARDS_IN_KAVA, DISTRIBUTION_SHARE, PROJECT } = require('./config.js'); + +const apy = async () => { + const period = Date.now(); + const periodStart = Math.floor(startOfMonth(period).getTime() / 1000); + const periodEnd = Math.floor((endOfMonth(period).getTime() + 1) / 1000); + + const [csTvl, lineTvl, kavaGlobalTvl] = await Promise.all([ + axios.get(`${LLAMA_API_URL}/protocol/counterstake`).then(data => data.data.chainTvls.Kava.tvl || []), + axios.get(`${LLAMA_API_URL}/protocol/line-token`).then(data => data.data.chainTvls.Kava.tvl || []), + axios.get(`${LLAMA_API_URL}/v2/historicalChainTvl/Kava`).then(data => data.data), + ]); + + const csFilteredTvl = csTvl.filter((tvl) => tvl.date >= periodStart && tvl.date <= periodEnd); + const csAvgTvlInUsd = csFilteredTvl.reduce((acc, { totalLiquidityUSD }) => acc + totalLiquidityUSD, 0) / csFilteredTvl.length; + + const lineFilteredTvl = lineTvl.filter((tvl) => tvl.date >= periodStart && tvl.date <= periodEnd); + const lineAvgTvlInUSD = lineFilteredTvl.reduce((acc, { totalLiquidityUSD }) => acc + totalLiquidityUSD, 0) / lineFilteredTvl.length; + + const kavaFilteredGlobalTvl = kavaGlobalTvl.filter((tvl) => tvl.date >= periodStart && tvl.date <= periodEnd); + const kavaAvgTvlInUsd = kavaFilteredGlobalTvl.reduce((acc, { tvl }) => acc + tvl, 0) / kavaFilteredGlobalTvl.length; + + const totalTvlInUsd = lineAvgTvlInUSD + csAvgTvlInUsd; + const projectsTvlShare = totalTvlInUsd / kavaAvgTvlInUsd; + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/Kava:${ethers.constants.AddressZero}`) + ).data.coins; + + const kavaPriceInUsd = prices[`Kava:${ethers.constants.AddressZero}`]?.price; + + const totalRewardsInKava = MONTHLY_TOTAL_REWARDS_IN_KAVA * projectsTvlShare * DISTRIBUTION_SHARE; + + const totalMonthlyRewardInUSD = kavaPriceInUsd * totalRewardsInKava; + + const avgBalances = ( + await axios.get(`${BACKEND_API_URL}/average_balances/latest`) + ).data.data; + + const avgTotalEffectiveBalanceInUsd = avgBalances.reduce((currentValue, { effective_usd_balance }) => { + return currentValue + effective_usd_balance; + }, 0); + + const avgTotalBalanceInUsd = avgBalances.reduce((currentValue, { effective_usd_balance = 0, home_symbol }) => { + return currentValue + (effective_usd_balance / (home_symbol === "LINE" ? 2 : 1)); + }, 0); + + const totalBalanceOfLineTokensInUsd = (avgTotalEffectiveBalanceInUsd - avgTotalBalanceInUsd); + + const totalRewardForLineTokens = totalMonthlyRewardInUSD * (totalBalanceOfLineTokensInUsd / avgTotalBalanceInUsd); + + return [{ + chain: CHAIN, + project: PROJECT, + rewardTokens: [REWARD_TOKEN], + apyReward: null, + apyBase: ((1 + (totalRewardForLineTokens / totalBalanceOfLineTokensInUsd)) ** 12 - 1) * 100, + tvlUsd: totalBalanceOfLineTokensInUsd, + pool: `LINE-${CHAIN}`.toLowerCase(), + symbol: 'LINE', + }] +} + +module.exports = { + timetravel: false, + url: 'https://kava.obyte.org', + apy, +}; diff --git a/src/adaptors/line-token/abi/equilibrePairAbi.js b/src/adaptors/line-token/abi/equilibrePairAbi.js new file mode 100644 index 0000000000..7f3ab1871f --- /dev/null +++ b/src/adaptors/line-token/abi/equilibrePairAbi.js @@ -0,0 +1,152 @@ +module.exports = [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, +] \ No newline at end of file diff --git a/src/adaptors/line-token/abi/lineAbi.js b/src/adaptors/line-token/abi/lineAbi.js new file mode 100644 index 0000000000..5a8383bf06 --- /dev/null +++ b/src/adaptors/line-token/abi/lineAbi.js @@ -0,0 +1,300 @@ +module.exports = [ + { + "inputs": [], + "name": "collateral_token_address", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllPools", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "bool", + "name": "exists", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "reward_share10000", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "last_total_reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_pool_reward_per_token", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_staked_in_pool", + "type": "uint256" + } + ], + "internalType": "struct Staking.Pool", + "name": "pool", + "type": "tuple" + }, + { + "internalType": "address", + "name": "pool_address", + "type": "address" + } + ], + "internalType": "struct Staking.PoolInfo[]", + "name": "all_pools", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interest_rate10000", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pool_addresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "bool", + "name": "exists", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "reward_share10000", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "last_total_reward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_pool_reward_per_token", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_staked_in_pool", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "total_debt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "total_interest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "total_reward_share10000", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "new_origination_fee10000", + "type": "uint256" + } + ], + "name": "setOriginationFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "new_interest_rate10000", + "type": "uint256" + } + ], + "name": "setInterestRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "collateral_amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentInterestMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalReward", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/line-token/abi/oracleAbi.js b/src/adaptors/line-token/abi/oracleAbi.js new file mode 100644 index 0000000000..c53b28e5fc --- /dev/null +++ b/src/adaptors/line-token/abi/oracleAbi.js @@ -0,0 +1,15 @@ +module.exports = [ + { + "inputs": [], + "name": "getCurrentPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, +] \ No newline at end of file diff --git a/src/adaptors/line-token/config.js b/src/adaptors/line-token/config.js new file mode 100644 index 0000000000..f0580ebbb7 --- /dev/null +++ b/src/adaptors/line-token/config.js @@ -0,0 +1,6 @@ +module.exports.LINE_CONTRACT_ADDRESS = + '0x31f8d38df6514b6cc3C360ACE3a2EFA7496214f6'; +module.exports.CHAIN = 'kava'; +module.exports.PROJECT = 'line-token'; +module.exports.COLLATERAL_TOKEN_CONTRACT_ADDRESS = + '0x0b93109d05Ef330acD2c75148891cc61D20C3EF1'; diff --git a/src/adaptors/line-token/index.js b/src/adaptors/line-token/index.js new file mode 100644 index 0000000000..25e8019c4b --- /dev/null +++ b/src/adaptors/line-token/index.js @@ -0,0 +1,98 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); + +const { + LINE_CONTRACT_ADDRESS, + CHAIN, + PROJECT, + COLLATERAL_TOKEN_CONTRACT_ADDRESS, +} = require('./config'); +const { + getCurrentLinePrice, + getAllPools, + getTotalDebt, + getInterestRate, + getPoolTokenPriceInUSD, + fetchPriceFromCoingecko, + getSymbol, + getDecimals, +} = require('./utils'); + +const COMMON_DATA = { + chain: CHAIN, + project: PROJECT, + rewardTokens: [LINE_CONTRACT_ADDRESS], +}; + +const apy = async () => { + const pools = await getAllPools(); + const linePriceInCollateralToken = await getCurrentLinePrice(); + const collateralTokenPriceInUSD = await fetchPriceFromCoingecko( + COLLATERAL_TOKEN_CONTRACT_ADDRESS + ); + const lineTokenPriceInUSD = BigNumber(linePriceInCollateralToken) + .multipliedBy(collateralTokenPriceInUSD) + .dividedBy(10 ** 18) + .toNumber(); + const collateralDecimals = await getDecimals( + COLLATERAL_TOKEN_CONTRACT_ADDRESS + ); + const lineDecimals = await getDecimals(LINE_CONTRACT_ADDRESS); + + const totalDebt = await getTotalDebt(); + const interestRate = await getInterestRate(); + + const totalRewardPerYear = BigNumber(interestRate) + .multipliedBy(totalDebt) + .dividedBy('10000') + .dividedBy(10 ** lineDecimals) + .toNumber(); + + const results = []; + + for (const pool of pools) { + const { reward_share10000, total_staked_in_pool, poolContractAddress } = + pool; + const poolTokenDecimals = await getDecimals(poolContractAddress); + + const totalStakedInPool = BigNumber(total_staked_in_pool) + .dividedBy(10 ** poolTokenDecimals) + .toNumber(); + + const poolRewardPerYear = totalRewardPerYear * (reward_share10000 / 1e4); + + const stakedTokenPriceInUSD = await getPoolTokenPriceInUSD( + poolContractAddress, + lineTokenPriceInUSD + ); + + if (!Number(collateralTokenPriceInUSD) || !Number(stakedTokenPriceInUSD)) + continue; + + const poolRewardPerYearInUSD = poolRewardPerYear * lineTokenPriceInUSD; + + const apy = + poolRewardPerYearInUSD / (totalStakedInPool * stakedTokenPriceInUSD); + + const tvlUsd = totalStakedInPool * stakedTokenPriceInUSD; + const symbol = await getSymbol(poolContractAddress); + + results.push({ + apy, + tvlUsd, + ...COMMON_DATA, + pool: `${poolContractAddress}-${CHAIN}`.toLowerCase(), + symbol: utils.formatSymbol(symbol), + }); + } + + return results; +}; + +module.exports = { + timetravel: false, + url: 'https://linetoken.org/staking/all', + apy, +}; diff --git a/src/adaptors/line-token/utils/fetchPriceFromCoingecko.js b/src/adaptors/line-token/utils/fetchPriceFromCoingecko.js new file mode 100644 index 0000000000..5096874735 --- /dev/null +++ b/src/adaptors/line-token/utils/fetchPriceFromCoingecko.js @@ -0,0 +1,13 @@ +const utils = require('../../utils'); + +module.exports = async function fetchPriceFromCoingecko(tokenAddress) { + try { + const data = await utils.getData( + `https://api.coingecko.com/api/v3/coins/kava/contract/${tokenAddress.toLowerCase()}` + ); + + return data?.market_data?.current_price?.usd || 0; + } catch { + return 0; + } +}; diff --git a/src/adaptors/line-token/utils/getAllPools.js b/src/adaptors/line-token/utils/getAllPools.js new file mode 100644 index 0000000000..150170308a --- /dev/null +++ b/src/adaptors/line-token/utils/getAllPools.js @@ -0,0 +1,32 @@ +const sdk = require('@defillama/sdk'); + +const lineAbi = require('../abi/lineAbi'); +const { LINE_CONTRACT_ADDRESS, CHAIN } = require('../config'); + +module.exports = async function getAllPools() { + return ( + await sdk.api.abi.call({ + target: LINE_CONTRACT_ADDRESS, + abi: lineAbi.find((m) => m.name === 'getAllPools'), + chain: CHAIN, + }) + ).output.map( + ([ + [ + exists, + reward_share10000, + last_total_reward, + total_pool_reward_per_token, + total_staked_in_pool, + ], + poolContractAddress, + ]) => ({ + exists, + reward_share10000, + last_total_reward, + total_pool_reward_per_token, + total_staked_in_pool, + poolContractAddress, + }) + ); +}; diff --git a/src/adaptors/line-token/utils/getCurrentLinePrice.js b/src/adaptors/line-token/utils/getCurrentLinePrice.js new file mode 100644 index 0000000000..0c33a51271 --- /dev/null +++ b/src/adaptors/line-token/utils/getCurrentLinePrice.js @@ -0,0 +1,24 @@ +const sdk = require('@defillama/sdk'); + +const oracleAbi = require('../abi/oracleAbi'); +const lineAbi = require('../abi/lineAbi'); + +const { LINE_CONTRACT_ADDRESS, CHAIN } = require('../config'); + +module.exports = async function getCurrentLinePrice() { + return ( + await sdk.api.abi + .call({ + target: LINE_CONTRACT_ADDRESS, + abi: lineAbi.find((m) => m.name === 'oracle'), + chain: CHAIN, + }) + .then(({ output: oracle }) => { + return sdk.api.abi.call({ + target: oracle, + abi: oracleAbi.find((m) => m.name === 'getCurrentPrice'), + chain: CHAIN, + }); + }) + ).output; +}; diff --git a/src/adaptors/line-token/utils/getDecimals.js b/src/adaptors/line-token/utils/getDecimals.js new file mode 100644 index 0000000000..7c4c63fe23 --- /dev/null +++ b/src/adaptors/line-token/utils/getDecimals.js @@ -0,0 +1,13 @@ +const sdk = require('@defillama/sdk'); + +const { CHAIN } = require('../config'); + +module.exports = async function getDecimals(target) { + return ( + await sdk.api.abi.call({ + target, + abi: 'erc20:decimals', + chain: CHAIN, + }) + ).output; +}; diff --git a/src/adaptors/line-token/utils/getInterestRate.js b/src/adaptors/line-token/utils/getInterestRate.js new file mode 100644 index 0000000000..81240d4394 --- /dev/null +++ b/src/adaptors/line-token/utils/getInterestRate.js @@ -0,0 +1,15 @@ +const sdk = require('@defillama/sdk'); + +const { LINE_CONTRACT_ADDRESS, CHAIN } = require('../config'); + +const lineAbi = require('../abi/lineAbi'); + +module.exports = async function getInterestRate() { + return ( + await sdk.api.abi.call({ + target: LINE_CONTRACT_ADDRESS, + abi: lineAbi.find((m) => m.name === 'interest_rate10000'), + chain: CHAIN, + }) + ).output; +}; diff --git a/src/adaptors/line-token/utils/getPoolTokenPriceInUSD.js b/src/adaptors/line-token/utils/getPoolTokenPriceInUSD.js new file mode 100644 index 0000000000..09a21c94c5 --- /dev/null +++ b/src/adaptors/line-token/utils/getPoolTokenPriceInUSD.js @@ -0,0 +1,79 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); + +const { LINE_CONTRACT_ADDRESS, CHAIN } = require('../config'); + +const LineAbi = require('../abi/lineAbi'); +const equilibrePairAbi = require('../abi/equilibrePairAbi'); +const { getData } = require('../../utils'); +const fetchPriceFromCoingecko = require('./fetchPriceFromCoingecko'); +const getDecimals = require('./getDecimals'); + +module.exports = async function getPoolTokenPriceInUSD( + tokenAddress, + lineTokenPriceInUSD +) { + const tokens = await sdk.api.abi + .call({ + target: tokenAddress, + abi: equilibrePairAbi.find((m) => m.name === 'tokens'), + chain: CHAIN, + }) + .then((res) => res.output) + .catch(() => false); + + if (tokens) { + // it's a equilibre pool + const totalSupplyGetter = sdk.api.abi + .call({ + target: tokenAddress, + abi: equilibrePairAbi.find((m) => m.name === 'totalSupply'), + chain: CHAIN, + }) + .then((data) => data.output); + + const reservesGetter = sdk.api.abi + .call({ + target: tokenAddress, + abi: equilibrePairAbi.find((m) => m.name === 'getReserves'), + chain: CHAIN, + }) + .then((data) => data.output); + + const [totalSupplyInPennies, reserves, poolTokenDecimals, token0Decimals] = + await Promise.all([ + totalSupplyGetter, + reservesGetter, + getDecimals(tokenAddress), + getDecimals(tokens[0]), + ]); + + const price0 = + tokens[0] !== LINE_CONTRACT_ADDRESS + ? await fetchPriceFromCoingecko(tokens[0]) + : lineTokenPriceInUSD; + let lpPriceInUSD = 0; + + if (totalSupplyInPennies) { + const reserve0 = BigNumber(reserves[0]) + .dividedBy(10 ** token0Decimals) + .toNumber(); + const totalSupply = BigNumber(totalSupplyInPennies) + .dividedBy(10 ** poolTokenDecimals) + .toNumber(); + + lpPriceInUSD = (reserve0 * 2 * price0) / totalSupply; + } + + return lpPriceInUSD; + } else { + // it's a token + if (tokenAddress === LINE_CONTRACT_ADDRESS) { + return String(lineTokenPriceInUSD); + } else { + return await fetchPriceFromCoingecko(tokenAddress) + .then((price) => String(price)) + .catch(() => 0); + } + } +}; diff --git a/src/adaptors/line-token/utils/getSymbol.js b/src/adaptors/line-token/utils/getSymbol.js new file mode 100644 index 0000000000..db4fa38849 --- /dev/null +++ b/src/adaptors/line-token/utils/getSymbol.js @@ -0,0 +1,13 @@ +const sdk = require('@defillama/sdk'); + +const { CHAIN } = require('../config'); + +module.exports = async function getSymbol(target) { + return ( + await sdk.api.abi.call({ + target, + abi: 'erc20:symbol', + chain: CHAIN, + }) + ).output; +}; diff --git a/src/adaptors/line-token/utils/getTotalDebt.js b/src/adaptors/line-token/utils/getTotalDebt.js new file mode 100644 index 0000000000..62db640eb1 --- /dev/null +++ b/src/adaptors/line-token/utils/getTotalDebt.js @@ -0,0 +1,15 @@ +const sdk = require('@defillama/sdk'); + +const { LINE_CONTRACT_ADDRESS, CHAIN } = require('../config'); + +const LineAbi = require('../abi/lineAbi'); + +module.exports = async function getTotalDebt() { + return ( + await sdk.api.abi.call({ + target: LINE_CONTRACT_ADDRESS, + abi: LineAbi.find((m) => m.name === 'total_debt'), + chain: CHAIN, + }) + ).output; +}; diff --git a/src/adaptors/line-token/utils/index.js b/src/adaptors/line-token/utils/index.js new file mode 100644 index 0000000000..a5d579670b --- /dev/null +++ b/src/adaptors/line-token/utils/index.js @@ -0,0 +1,17 @@ +const getCurrentLinePrice = require('./getCurrentLinePrice'); +const getAllPools = require('./getAllPools'); +const getTotalDebt = require('./getTotalDebt'); +const getInterestRate = require('./getInterestRate'); +const getPoolTokenPriceInUSD = require('./getPoolTokenPriceInUSD'); +const fetchPriceFromCoingecko = require('./fetchPriceFromCoingecko'); +const getSymbol = require('./getSymbol'); +const getDecimals = require('./getDecimals'); + +module.exports.getCurrentLinePrice = getCurrentLinePrice; +module.exports.getAllPools = getAllPools; +module.exports.getTotalDebt = getTotalDebt; +module.exports.getInterestRate = getInterestRate; +module.exports.getPoolTokenPriceInUSD = getPoolTokenPriceInUSD; +module.exports.fetchPriceFromCoingecko = fetchPriceFromCoingecko; +module.exports.getSymbol = getSymbol; +module.exports.getDecimals = getDecimals; diff --git a/src/adaptors/liondex/abis/abi.json b/src/adaptors/liondex/abis/abi.json new file mode 100644 index 0000000000..8cd893e237 --- /dev/null +++ b/src/adaptors/liondex/abis/abi.json @@ -0,0 +1,85 @@ +{ + "getLPPrice": { + "inputs": [], + "name": "getLPPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getLionPrice": { + "inputs": [], + "name": "getLionPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getPrice": { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + + "getUserApr":{ + "inputs":[ + { + "internalType":"uint256", + "name":"pid", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"LPPrice", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"esLionPrice", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"ethPrice", + "type":"uint256" + }, + { + "internalType":"address", + "name":"user","type":"address" + } + ], + "name":"getUserApr", + "outputs":[ + { + "internalType":"uint256[3]", + "name":"ret","type":"uint256[3]" + } + ], + "stateMutability":"view", + "type":"function" + } +} \ No newline at end of file diff --git a/src/adaptors/liondex/index.js b/src/adaptors/liondex/index.js new file mode 100644 index 0000000000..b31fd8f27c --- /dev/null +++ b/src/adaptors/liondex/index.js @@ -0,0 +1,83 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); + +const LP = '0x03229fb11e3D7E8Aca8C758DBD0EA737950d6CD0'; +const LION = '0x8ebb85d53e6955e557b7c53acde1d42fd68561ec'; +const WETH = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'; +const WBTC = '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f'; +const USDC = '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'; + +const vault = "0x8eF99304eb88Af9BDe85d58a35339Cb0e2a557B6"; +const pool = "0x154E2b1dBE9F493fF7938E5d686366138ddCE017"; +const dashboard = "0x951125E1d000Be7e3cc3f51Db5603d56D89CC841"; + + +async function lpPrice() { + return (await sdk.api.abi.call({ target: vault, abi: abi['getLPPrice'], chain: 'arbitrum' })).output; +} + +async function lionPrice() { + return (await sdk.api.abi.call({ target: dashboard, abi: abi['getLionPrice'], chain: 'arbitrum' })).output; +} + +async function ethPrice() { + return (await sdk.api.abi.call({ target: vault, params: [WETH], abi: abi['getPrice'], chain: 'arbitrum' })).output; +} + +async function tokenBalance(token) { + return (await sdk.api.abi.call({ target: token, params: [pool], abi: 'erc20:balanceOf', chain: 'arbitrum'})).output; +} + +async function getAPY(pid, lpPrice, lionPrice, ethPrice) { + return await sdk.api.abi.call( + { + target: pool, + abi: abi['getUserApr'], + chain: 'arbitrum', + params: [pid, lpPrice, lionPrice, ethPrice, "0x0000000000000000000000000000000000000000"] + }); +} + + +const getPools = async () => { + const _lpPrice = Math.round((await lpPrice())/1e12); + const _lionPrice = await lionPrice(); + const _ethPrice = Math.round((await ethPrice())/1e24); + + const apy0 = (await getAPY(0, _lpPrice, _lionPrice, _ethPrice)).output; + const apy1 = (await getAPY(1, _lpPrice, _lionPrice, _ethPrice)).output; + + let pools = []; + pools.push( + { + pool: pool + "-0", + chain: 'arbitrum', + project: 'liondex', + symbol: 'LION', + tvlUsd: (await tokenBalance(LION)) * _lionPrice / 1e18 / 1e6, + apyBase: (Number(apy0[0]) + Number(apy0[1]) + Number(apy0[2]))/1e6, + poolMeta: 'LION pool' + }, + { + pool: pool + "-1", + chain: 'arbitrum', + project: 'liondex', + symbol: 'WBTC-ETH-USDC', + tvlUsd: (await tokenBalance(LP)) * _lpPrice / 1e18 / 1e6, + apyBase: (Number(apy1[0]) + Number(apy1[1]))/ 1e18, + apyReward: Number(apy1[2]) / 1e18, + underlyingTokens: [WBTC, WETH, USDC], + poolMeta: 'LionDEX LP pool', + rewardTokens: [LION] + } + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.liondex.com/earn', +}; \ No newline at end of file diff --git a/src/adaptors/liqee/abi.json b/src/adaptors/liqee/abi.json new file mode 100644 index 0000000000..336d2e7269 --- /dev/null +++ b/src/adaptors/liqee/abi.json @@ -0,0 +1,1175 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "BorrowPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "BorrowedAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "BorrowedRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateralFactor", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowFactor", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supplyCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "distributionFactor", + "type": "uint256" + } + ], + "name": "MarketAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "MintPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldBorrowCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCapacity", + "type": "uint256" + } + ], + "name": "NewBorrowCapacity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldBorrowFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowFactorMantissa", + "type": "uint256" + } + ], + "name": "NewBorrowFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "NewOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPendingOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "NewPendingOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldRewardDistributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_newRewardDistributor", + "type": "address" + } + ], + "name": "NewRewardDistributor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldSupplyCapacity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSupplyCapacity", + "type": "uint256" + } + ], + "name": "NewSupplyCapacity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "iToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "RedeemPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "SeizePaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "TransferPaused", + "type": "event" + }, + { + "inputs": [], + "name": "_acceptOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_collateralFactor", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_borrowFactor", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_supplyCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_distributionFactor", + "type": "uint256" + } + ], + "name": "_addMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllBorrowPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllMintPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setAllRedeemPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newBorrowCapacity", + "type": "uint256" + } + ], + "name": "_setBorrowCapacity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newBorrowFactorMantissa", + "type": "uint256" + } + ], + "name": "_setBorrowFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setBorrowPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setMintPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "newPendingOwner", + "type": "address" + } + ], + "name": "_setPendingOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newOracle", "type": "address" } + ], + "name": "_setPriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setProtocolPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setRedeemPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newRewardDistributor", + "type": "address" + } + ], + "name": "_setRewardDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setSeizePaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_newSupplyCapacity", + "type": "uint256" + } + ], + "name": "_setSupplyCapacity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "_setTransferPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "bool", "name": "_paused", "type": "bool" } + ], + "name": "_setiTokenPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "_borrowedAmount", + "type": "uint256" + } + ], + "name": "afterBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "afterFlashloan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repaidAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_seizedAmount", "type": "uint256" } + ], + "name": "afterLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "uint256", "name": "_mintAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_mintedAmount", "type": "uint256" } + ], + "name": "afterMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_redeemer", "type": "address" }, + { "internalType": "uint256", "name": "_redeemAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_redeemedUnderlying", + "type": "uint256" + } + ], + "name": "afterRedeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_payer", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "afterRepayBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_seizedAmount", "type": "uint256" } + ], + "name": "afterSeize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "afterTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_borrowAmount", "type": "uint256" } + ], + "name": "beforeBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "beforeFlashloan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "beforeLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "uint256", "name": "_mintAmount", "type": "uint256" } + ], + "name": "beforeMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_redeemer", "type": "address" }, + { "internalType": "uint256", "name": "_redeemAmount", "type": "uint256" } + ], + "name": "beforeRedeem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_payer", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_repayAmount", "type": "uint256" } + ], + "name": "beforeRepayBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_seizeAmount", "type": "uint256" } + ], + "name": "beforeSeize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "beforeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "calcAccountEquity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "enterMarketFromiToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_iTokens", "type": "address[]" } + ], + "name": "enterMarkets", + "outputs": [ + { "internalType": "bool[]", "name": "_results", "type": "bool[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_iTokens", "type": "address[]" } + ], + "name": "exitMarkets", + "outputs": [ + { "internalType": "bool[]", "name": "_results", "type": "bool[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAlliTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "_alliTokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getBorrowedAssets", + "outputs": [ + { + "internalType": "address[]", + "name": "_borrowedAssets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getEnteredMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "_accountCollaterals", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasBorrowed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasEnteredMarket", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_iToken", "type": "address" } + ], + "name": "hasiToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isController", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_iTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "_iTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "_seizedTokenCollateral", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowCapacity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCapacity", + "type": "uint256" + }, + { "internalType": "bool", "name": "mintPaused", "type": "bool" }, + { "internalType": "bool", "name": "redeemPaused", "type": "bool" }, + { "internalType": "bool", "name": "borrowPaused", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceOracle", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardDistributor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "seizePaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/liqee/index.ts b/src/adaptors/liqee/index.ts new file mode 100644 index 0000000000..9fa6ea5744 --- /dev/null +++ b/src/adaptors/liqee/index.ts @@ -0,0 +1,87 @@ +const utils = require('../utils'); +const abi = require('./abi.json'); +const sdk = require('@defillama/sdk'); + +const API_URL = 'https://app.liqee.io/pos/markets?network=mainnet'; + +const controller = '0x8f1f15DCf4c70873fAF1707973f6029DEc4164b3'; + +interface Staking { + [addres: string]: number; +} + +interface Market { + address: string; + underlying_symbol: string; + supplyValue: string; + borrowValue: string; + decimals: string; + supplyAPY: string; + borrowAPY: string; + rewardSupplyApy: string; + rewardBorrowApy: string; +} + +interface Underlying { + underlying: string; +} + +interface Markets { + supplyMarkets: Array; + underlyingToken: Array; +} + +const apy = async () => { + const data: Markets = await utils.getData(API_URL); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: 'ethereum', + abi: abi.find((n) => n.name === 'markets'), + calls: data.supplyMarkets.map((m) => ({ + target: controller, + params: [m.address], + })), + }) + ).output.map((o) => o.output); + + const res = data.supplyMarkets.map((market, i) => { + const apyReward = + (Number(market.rewardSupplyApy) / 10 ** Number(market.decimals)) * 100; + + return { + pool: market.address, + chain: utils.formatChain('ethereum'), + project: 'liqee', + symbol: market.underlying_symbol, + tvlUsd: + (Number(market.supplyValue) - Number(market.borrowValue)) / + 10 ** Number(market.decimals), + apyBase: (Number(market.supplyAPY) / 10 ** Number(market.decimals)) * 100, + apyReward, + rewardTokens: apyReward > 0 ? [market.address] : null, + underlyingTokens: + market.underlying_symbol === 'ETH' + ? ['0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'] + : [data.underlyingToken[i].underlying], + // borrow fields + totalSupplyUsd: + Number(market.supplyValue) / 10 ** Number(market.decimals), + totalBorrowUsd: + Number(market.borrowValue) / 10 ** Number(market.decimals), + apyBaseBorrow: + (Number(market.borrowAPY) / 10 ** Number(market.decimals)) * 100, + apyRewardBorrow: + (Number(market.rewardBorrowApy) / 10 ** Number(market.decimals)) * 100, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return res; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.liqee.io/#/lending?AssetsType=Lend¤tPool=pos', +}; diff --git a/src/adaptors/liquid-bolt/abis/factory.json b/src/adaptors/liquid-bolt/abis/factory.json new file mode 100644 index 0000000000..6496469839 --- /dev/null +++ b/src/adaptors/liquid-bolt/abis/factory.json @@ -0,0 +1,42 @@ +[ + { + "constant":true, + "inputs":[], + "name":"allPairsLength", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "payable":false, + "stateMutability":"view", + "type":"function" + }, + { + "constant":true, + "inputs": [ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"allPairs", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "payable":false, + "stateMutability":"view", + "type":"function" + } +] + + + + diff --git a/src/adaptors/liquid-bolt/abis/pair.json b/src/adaptors/liquid-bolt/abis/pair.json new file mode 100644 index 0000000000..7e488ba863 --- /dev/null +++ b/src/adaptors/liquid-bolt/abis/pair.json @@ -0,0 +1,27 @@ +[ + { + "constant":true, + "inputs":[], + "name":"getReserves", + "outputs":[ + { + "internalType":"uint112", + "name":"_reserve0", + "type":"uint112" + }, + { + "internalType":"uint112", + "name":"_reserve1", + "type":"uint112" + }, + { + "internalType":"uint32", + "name":"_blockTimestampLast", + "type":"uint32" + } + ], + "payable":false, + "stateMutability":"view", + "type":"function" + } +] diff --git a/src/adaptors/liquid-bolt/abis/token.json b/src/adaptors/liquid-bolt/abis/token.json new file mode 100644 index 0000000000..ffd9f1f9ed --- /dev/null +++ b/src/adaptors/liquid-bolt/abis/token.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/src/adaptors/liquid-bolt/index.js b/src/adaptors/liquid-bolt/index.js new file mode 100644 index 0000000000..9eed366be8 --- /dev/null +++ b/src/adaptors/liquid-bolt/index.js @@ -0,0 +1,194 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const factoryAbi = require('./abis/factory.json'); +const pairAbi = require('./abis/pair.json'); +const tokenAbi = require('./abis/token.json'); +const BigNumber = require('bignumber.js'); + +const CHAINS = [ + { + chainId: 250, + chain: 'fantom', + factory: '0xdE08A0860B5971201f4d621B6eD4bb5BFed454be', + }, + { + chainId: 56, + chain: 'bsc', + factory: '0xBDEc20d9cdf8E222EDd536268A9883a4C2ca172D', + }, + { + chainId: 137, + chain: 'polygon', + factory: '0xF301aE81800Aa97f68148531D487696EF939170E', + }, + { + chainId: 42161, + chain: 'arbitrum', + factory: '0x3D225a66c4A609634fb2c2d75d30Fd6610EBb1BD', + }, +]; + +const formatReserve = (reserve, tokenAddress, tokenList) => { + const token = tokenList.find((token) => token.address === tokenAddress); + if (token === undefined) return 0; + return BigNumber(reserve) + .div(10 ** token.decimals) + .toNumber(); +}; + +const getLpsTvl = async (chain, factory, lps) => { + // Tokens list + const tokens = []; + for (const lp of lps) { + if (lp.chain_id === chain.chainId) { + if (tokens.indexOf(lp.token0) === -1) { + tokens.push(lp.token0); + } + if (tokens.indexOf(lp.token1) === -1) { + tokens.push(lp.token1); + } + } + } + + // Get token decimals + const resultTokenDecimals = await sdk.api.abi.multiCall({ + chain: chain.chain, + abi: tokenAbi.find((abi) => abi.name === 'decimals'), + calls: tokens.map((address) => ({ + target: address, + })), + permitFailure: true, + }); + + // Format tokens array + let tokenDecimals = []; + for (let i = 0; i < tokens.length; i++) { + tokenDecimals.push({ + address: tokens[i], + decimals: Number(resultTokenDecimals.output[i].output), + }); + } + + // Get pairs number + const resultPair = await sdk.api.abi.multiCall({ + chain: chain.chain, + abi: factoryAbi.find((abi) => abi.name === 'allPairsLength'), + calls: [ + { + target: factory, + }, + ], + permitFailure: true, + }); + + const nbPair = parseInt(resultPair.output[0].output); + + // Get pairs addresses + const resultPairs = await sdk.api.abi.multiCall({ + chain: chain.chain, + abi: factoryAbi.find((abi) => abi.name === 'allPairs'), + calls: [...Array(nbPair).keys()].map((pairIndex) => ({ + target: factory, + params: [pairIndex], + })), + }); + + const pairAddresses = resultPairs.output.map( + (pairResult) => pairResult.output + ); + + // Get pairs reserves + const resultReserves = await sdk.api.abi.multiCall({ + chain: chain.chain, + abi: pairAbi.find((abi) => abi.name === 'getReserves'), + calls: pairAddresses.map((pairAddress) => ({ + target: pairAddress, + })), + permitFailure: true, + }); + + // Mapping results with our lps + const reserves = resultReserves.output.map((pairResult) => ({ + address: pairResult.input.target, + reserve0: pairResult.output._reserve0, + reserve1: pairResult.output._reserve1, + lp: lps.find( + (lp) => + lp.lp_address === pairResult.input.target && + lp.chain_id === chain.chainId + ), + })); + + // Filter unwanted pairs + const reservesFiltered = reserves.filter((item) => item.lp !== undefined); + + // Prepare data for utils.tvl function + const formattedPairsData = reservesFiltered.map((item) => ({ + lpAddress: item.address, + token0: { + id: item.lp.token0.toLowerCase(), + }, + token1: { + id: item.lp.token1.toLowerCase(), + }, + reserve0: formatReserve(item.reserve0, item.lp.token0, tokenDecimals), + reserve1: formatReserve(item.reserve1, item.lp.token1, tokenDecimals), + })); + + // Calculate lps tvl + const poolsTvl = await utils.tvl(formattedPairsData, chain.chain); + + // Return addresses and tvls + return lps.map((lp) => ({ + address: lp.lp_address, + totalValueLockedUSD: Number( + poolsTvl.find((item) => item.lpAddress === lp.lp_address) + ?.totalValueLockedUSD + ), + })); +}; + +const getApy = async () => { + const poolsApy = []; + + const data = await utils.getData( + 'https://stats.liquidbolt.finance/defillama-liquidbolt.json' + ); + + if (data !== undefined) { + for (let lp of data.lps) { + let chain = CHAINS.find((chain) => chain.chainId === lp.chain_id); + if (chain !== undefined) { + poolsApy.push({ + pool: lp.lp_address, + chain: utils.formatChain(chain.chain), + project: 'liquid-bolt', + symbol: lp.name, + tvlUsd: 0, + apyBase: lp.apy_base, + apyBase7d: lp.apy_base_7days, + underlyingTokens: [lp.token0, lp.token1], + rewardTokens: [lp.token0, lp.token1], + }); + } + } + for (const chain of CHAINS) { + let lpTvls = await getLpsTvl(chain, chain.factory, data.lps); + poolsApy.forEach(function (pool) { + const tvl = lpTvls.find((item) => item.address === pool.pool); + pool.tvlUsd = + tvl !== undefined && isFinite(tvl.totalValueLockedUSD) + ? tvl.totalValueLockedUSD + : pool.tvlUsd; + }); + } + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.liquidbolt.finance/', +}; diff --git a/src/adaptors/liquid-collective/abi.json b/src/adaptors/liquid-collective/abi.json new file mode 100644 index 0000000000..16b41da96b --- /dev/null +++ b/src/adaptors/liquid-collective/abi.json @@ -0,0 +1,1754 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_operator", "type": "address" }, + { "internalType": "uint256", "name": "_allowance", "type": "uint256" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "AllowanceTooLow", + "type": "error" + }, + { "inputs": [], "name": "BalanceTooLow", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "Denied", + "type": "error" + }, + { "inputs": [], "name": "EmptyDeposit", "type": "error" }, + { "inputs": [], "name": "ErrorOnDeposit", "type": "error" }, + { "inputs": [], "name": "InconsistentPublicKeys", "type": "error" }, + { "inputs": [], "name": "InconsistentSignatures", "type": "error" }, + { "inputs": [], "name": "InvalidArgument", "type": "error" }, + { "inputs": [], "name": "InvalidCall", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentValidatorsExitedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newValidatorsExitedBalance", + "type": "uint256" + } + ], + "name": "InvalidDecreasingValidatorsExitedBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentValidatorsSkimmedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newValidatorsSkimmedBalance", + "type": "uint256" + } + ], + "name": "InvalidDecreasingValidatorsSkimmedBalance", + "type": "error" + }, + { "inputs": [], "name": "InvalidEmptyString", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "epoch", "type": "uint256" } + ], + "name": "InvalidEpoch", + "type": "error" + }, + { "inputs": [], "name": "InvalidFee", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "version", "type": "uint256" }, + { + "internalType": "uint256", + "name": "expectedVersion", + "type": "uint256" + } + ], + "name": "InvalidInitialization", + "type": "error" + }, + { "inputs": [], "name": "InvalidPublicKeyCount", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "requested", "type": "uint256" }, + { "internalType": "uint256", "name": "received", "type": "uint256" } + ], + "name": "InvalidPulledClFundsAmount", + "type": "error" + }, + { "inputs": [], "name": "InvalidSignatureCount", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "providedValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedValidatorCount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastReportedValidatorCount", + "type": "uint256" + } + ], + "name": "InvalidValidatorCountReport", + "type": "error" + }, + { "inputs": [], "name": "InvalidWithdrawalCredentials", "type": "error" }, + { "inputs": [], "name": "InvalidZeroAddress", "type": "error" }, + { "inputs": [], "name": "NoAvailableValidatorKeys", "type": "error" }, + { "inputs": [], "name": "NotEnoughFunds", "type": "error" }, + { "inputs": [], "name": "NullTransfer", "type": "error" }, + { "inputs": [], "name": "SliceOutOfBounds", "type": "error" }, + { "inputs": [], "name": "SliceOverflow", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "prevTotalEthIncludingExited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postTotalEthIncludingExited", + "type": "uint256" + }, + { "internalType": "uint256", "name": "timeElapsed", "type": "uint256" }, + { + "internalType": "uint256", + "name": "relativeLowerBound", + "type": "uint256" + } + ], + "name": "TotalValidatorBalanceDecreaseOutOfBound", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "prevTotalEthIncludingExited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "postTotalEthIncludingExited", + "type": "uint256" + }, + { "internalType": "uint256", "name": "timeElapsed", "type": "uint256" }, + { + "internalType": "uint256", + "name": "annualAprUpperBound", + "type": "uint256" + } + ], + "name": "TotalValidatorBalanceIncreaseOutOfBound", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "caller", "type": "address" } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "UnauthorizedTransfer", + "type": "error" + }, + { "inputs": [], "name": "ZeroMintedShares", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "validatorCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorTotalBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "roundId", + "type": "bytes32" + } + ], + "name": "ConsensusLayerDataUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "version", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "cdata", + "type": "bytes" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "epoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "validatorsBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsSkimmedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitingBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsCount", + "type": "uint32" + }, + { + "internalType": "uint32[]", + "name": "stoppedValidatorCountPerOperator", + "type": "uint32[]" + }, + { + "internalType": "bool", + "name": "rebalanceDepositToRedeemMode", + "type": "bool" + }, + { + "internalType": "bool", + "name": "slashingContainmentMode", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct IOracleManagerV1.ConsensusLayerReport", + "name": "report", + "type": "tuple" + }, + { + "components": [ + { "internalType": "uint256", "name": "rewards", "type": "uint256" }, + { + "internalType": "uint256", + "name": "pulledELFees", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pulledRedeemManagerExceedingEthBuffer", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pulledCoverageFunds", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct IOracleManagerV1.ConsensusLayerDataReportingTrace", + "name": "trace", + "type": "tuple" + } + ], + "name": "ProcessedConsensusLayerReport", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "pulledSkimmedEthAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pullExitedEthAmount", + "type": "uint256" + } + ], + "name": "PulledCLFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PulledCoverageFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PulledELFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PulledRedeemManagerExceedingEth", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "redeemManagerDemand", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "suppliedRedeemManagerDemand", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "suppliedRedeemManagerDemandInEth", + "type": "uint256" + } + ], + "name": "ReportedRedeemManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_collector", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_oldTotalUnderlyingBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_oldTotalSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newTotalUnderlyingBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newTotalSupply", + "type": "uint256" + } + ], + "name": "RewardsEarned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "SetAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "allowlist", + "type": "address" + } + ], + "name": "SetAllowlist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "SetBalanceCommittedToDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "SetBalanceToDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "SetBalanceToRedeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "annualAprUpperBound", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "relativeLowerBound", + "type": "uint256" + } + ], + "name": "SetBounds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collector", + "type": "address" + } + ], + "name": "SetCollector", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "coverageFund", + "type": "address" + } + ], + "name": "SetCoverageFund", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "depositContract", + "type": "address" + } + ], + "name": "SetDepositContractAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldDepositedValidatorCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDepositedValidatorCount", + "type": "uint256" + } + ], + "name": "SetDepositedValidatorCount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "elFeeRecipient", + "type": "address" + } + ], + "name": "SetELFeeRecipient", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "SetGlobalFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "minNetAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxRelativeAmount", + "type": "uint256" + } + ], + "name": "SetMaxDailyCommittableAmounts", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "metadataURI", + "type": "string" + } + ], + "name": "SetMetadataURI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operatorRegistry", + "type": "address" + } + ], + "name": "SetOperatorsRegistry", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oracleAddress", + "type": "address" + } + ], + "name": "SetOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pendingAdmin", + "type": "address" + } + ], + "name": "SetPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemManager", + "type": "address" + } + ], + "name": "SetRedeemManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "epochsPerFrame", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "slotsPerEpoch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "secondsPerSlot", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "genesisTime", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "epochsToAssumedFinality", + "type": "uint64" + } + ], + "name": "SetSpec", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "SetTotalSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "withdrawalCredentials", + "type": "bytes32" + } + ], + "name": "SetWithdrawalCredentials", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "depositor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "UserDeposit", + "type": "event" + }, + { "stateMutability": "payable", "type": "fallback" }, + { + "inputs": [], + "name": "DEPOSIT_SIZE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PUBLIC_KEY_LENGTH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_LENGTH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_DEPOSIT_SIZE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "address", "name": "_spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_spender", "type": "address" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "balanceOfUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "_redeemRequestIds", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "_withdrawalEventIds", + "type": "uint32[]" + } + ], + "name": "claimRedeemRequests", + "outputs": [ + { "internalType": "uint8[]", "name": "claimStatuses", "type": "uint8[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_spender", "type": "address" }, + { + "internalType": "uint256", + "name": "_subtractableValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_recipient", "type": "address" } + ], + "name": "depositAndTransfer", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_maxCount", "type": "uint256" } + ], + "name": "depositToConsensusLayer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAdmin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllowlist", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalanceToDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalanceToRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCLSpec", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "epochsPerFrame", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "slotsPerEpoch", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "secondsPerSlot", + "type": "uint64" + }, + { "internalType": "uint64", "name": "genesisTime", "type": "uint64" }, + { + "internalType": "uint64", + "name": "epochsToAssumedFinality", + "type": "uint64" + } + ], + "internalType": "struct CLSpec.CLSpecStruct", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCLValidatorCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCLValidatorTotalBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollector", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCommittedBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCoverageFund", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentEpochId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentFrame", + "outputs": [ + { "internalType": "uint256", "name": "_startEpochId", "type": "uint256" }, + { "internalType": "uint256", "name": "_startTime", "type": "uint256" }, + { "internalType": "uint256", "name": "_endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDailyCommittableLimits", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "minDailyNetCommittableAmount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxDailyRelativeCommittableAmount", + "type": "uint128" + } + ], + "internalType": "struct DailyCommittableLimits.DailyCommittableLimitsStruct", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDepositedValidatorCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getELFeeRecipient", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getExpectedEpochId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_epochId", "type": "uint256" } + ], + "name": "getFrameFirstEpochId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGlobalFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastCompletedEpochId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastConsensusLayerReport", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "epoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "validatorsBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsSkimmedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitingBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsCount", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "rebalanceDepositToRedeemMode", + "type": "bool" + }, + { + "internalType": "bool", + "name": "slashingContainmentMode", + "type": "bool" + } + ], + "internalType": "struct IOracleManagerV1.StoredConsensusLayerReport", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMetadataURI", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOperatorsRegistry", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOracle", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPendingAdmin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRedeemManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReportBounds", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "annualAprUpperBound", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "relativeLowerBound", + "type": "uint256" + } + ], + "internalType": "struct ReportBounds.ReportBoundsStruct", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWithdrawalCredentials", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_spender", "type": "address" }, + { + "internalType": "uint256", + "name": "_additionalValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_elFeeRecipientAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_withdrawalCredentials", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_oracleAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_systemAdministratorAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_allowlistAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_operatorRegistryAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_collectorAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "_globalFee", "type": "uint256" } + ], + "name": "initRiverV1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_redeemManager", + "type": "address" + }, + { "internalType": "uint64", "name": "_epochsPerFrame", "type": "uint64" }, + { "internalType": "uint64", "name": "_slotsPerEpoch", "type": "uint64" }, + { "internalType": "uint64", "name": "_secondsPerSlot", "type": "uint64" }, + { "internalType": "uint64", "name": "_genesisTime", "type": "uint64" }, + { + "internalType": "uint64", + "name": "_epochsToAssumedFinality", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "_annualAprUpperBound", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_relativeLowerBound", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "_minDailyNetCommittableAmount_", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_maxDailyRelativeCommittableAmount_", + "type": "uint128" + } + ], + "name": "initRiverV1_1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initRiverV1_2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_epoch", "type": "uint256" } + ], + "name": "isValidEpoch", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newAdmin", "type": "address" } + ], + "name": "proposeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_lsETHAmount", "type": "uint256" }, + { "internalType": "address", "name": "_recipient", "type": "address" } + ], + "name": "requestRedeem", + "outputs": [ + { "internalType": "uint32", "name": "_redeemRequestId", "type": "uint32" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "_redeemRequestIds", + "type": "uint32[]" + } + ], + "name": "resolveRedeemRequests", + "outputs": [ + { + "internalType": "int64[]", + "name": "withdrawalEventIds", + "type": "int64[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sendCLFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "sendCoverageFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "sendELFees", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "sendRedeemManagerExceedingFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newAllowlist", "type": "address" } + ], + "name": "setAllowlist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "epochsPerFrame", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "slotsPerEpoch", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "secondsPerSlot", + "type": "uint64" + }, + { "internalType": "uint64", "name": "genesisTime", "type": "uint64" }, + { + "internalType": "uint64", + "name": "epochsToAssumedFinality", + "type": "uint64" + } + ], + "internalType": "struct CLSpec.CLSpecStruct", + "name": "_newValue", + "type": "tuple" + } + ], + "name": "setCLSpec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_newCollector", "type": "address" } + ], + "name": "setCollector", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "epoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "validatorsBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsSkimmedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "validatorsExitingBalance", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsCount", + "type": "uint32" + }, + { + "internalType": "uint32[]", + "name": "stoppedValidatorCountPerOperator", + "type": "uint32[]" + }, + { + "internalType": "bool", + "name": "rebalanceDepositToRedeemMode", + "type": "bool" + }, + { + "internalType": "bool", + "name": "slashingContainmentMode", + "type": "bool" + } + ], + "internalType": "struct IOracleManagerV1.ConsensusLayerReport", + "name": "_report", + "type": "tuple" + } + ], + "name": "setConsensusLayerData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newCoverageFund", + "type": "address" + } + ], + "name": "setCoverageFund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "minDailyNetCommittableAmount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxDailyRelativeCommittableAmount", + "type": "uint128" + } + ], + "internalType": "struct DailyCommittableLimits.DailyCommittableLimitsStruct", + "name": "_dcl", + "type": "tuple" + } + ], + "name": "setDailyCommittableLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newELFeeRecipient", + "type": "address" + } + ], + "name": "setELFeeRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setGlobalFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "_metadataURI", "type": "string" } + ], + "name": "setMetadataURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_oracleAddress", "type": "address" } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "annualAprUpperBound", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "relativeLowerBound", + "type": "uint256" + } + ], + "internalType": "struct ReportBounds.ReportBoundsStruct", + "name": "_newValue", + "type": "tuple" + } + ], + "name": "setReportBounds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_underlyingAssetAmount", + "type": "uint256" + } + ], + "name": "sharesFromUnderlyingBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnderlyingSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "underlyingBalanceFromShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/liquid-collective/index.js b/src/adaptors/liquid-collective/index.js new file mode 100644 index 0000000000..8acfaf1f3e --- /dev/null +++ b/src/adaptors/liquid-collective/index.js @@ -0,0 +1,83 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.json'); + +const token = '0x8c1bed5b9a0928467c9b1341da1d7bd5e10b6549'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const apy = async () => { + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const _underlyingAssetAmount = 10000; + + const sharesFromUnderlyingBalances = await Promise.all([ + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'sharesFromUnderlyingBalance'), + params: [_underlyingAssetAmount], + }), + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'sharesFromUnderlyingBalance'), + params: [_underlyingAssetAmount], + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'sharesFromUnderlyingBalance'), + params: [_underlyingAssetAmount], + block: block7dayAgo, + }), + ]); + + const exchangeRateNow = + _underlyingAssetAmount / sharesFromUnderlyingBalances[0].output; + const exchangeRate1d = + _underlyingAssetAmount / sharesFromUnderlyingBalances[1].output; + const exchangeRate7d = + _underlyingAssetAmount / sharesFromUnderlyingBalances[2].output; + + const apyBase1d = (exchangeRateNow - exchangeRate1d) * 365 * 100; + const apyBase7d = ((exchangeRateNow - exchangeRate7d) / 7) * 365 * 100; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const tvl = + ( + await sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'totalUnderlyingSupply'), + }) + ).output / 1e18; + + return [ + { + pool: token, + symbol: 'lsETH', + chain: 'Ethereum', + project: 'liquid-collective', + tvlUsd: tvl * ethPrice, + apyBase: apyBase7d, + apyBase7d, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://liquidcollective.io/', +}; diff --git a/src/adaptors/liquidops/index.js b/src/adaptors/liquidops/index.js new file mode 100644 index 0000000000..b5bbbc644e --- /dev/null +++ b/src/adaptors/liquidops/index.js @@ -0,0 +1,122 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const endpoint = 'https://cu.ao-testnet.xyz' +const controllerId = 'SmmMv0rJwfIDVM3RvY2-P729JFYwhdGSeGo2deynbfY' +const redstoneOracleAddress = 'R5rRjBFS90qIGaohtzd1IoyPwZD0qJZ25QXkP7_p5a0' +const chain = 'AO' + + +const apy = async () => { + + const supportedTokensRes = await DryRun(controllerId, "Get-Tokens") + const supportedTokens = JSON.parse(supportedTokensRes.Messages[0].Data) + + const redstoneTickers = JSON.stringify(supportedTokens.map(token => token.ticker)) + const redstonePriceFeedRes = await DryRun(redstoneOracleAddress, "v2.Request-Latest-Data", [["Tickers", redstoneTickers]]); + const redstonePrices = JSON.parse(redstonePriceFeedRes.Messages[0].Data) + + const poolPromises = supportedTokens.map(async poolObject => { + + const getAPRRes = await DryRun(poolObject.oToken, "Get-APR"); + const APRTagsObject = Object.fromEntries( + getAPRRes.Messages[0].Tags.map((tag) => [tag.name, tag.value]) + ); + const borrowAPR = formatBorrowAPR(APRTagsObject) + + const infoRes = await DryRun(poolObject.oToken, "Info"); + const infoTagsObject = Object.fromEntries( + infoRes.Messages[0].Tags.map((tag) => [tag.name, tag.value]) + ); + + const ticker = poolObject.ticker + const tokenUSDPrice = (redstonePrices[ticker]).v + + const totalLends = scaleBalance(infoTagsObject['Cash'], infoTagsObject['Denomination']) + const totalBorrows = scaleBalance(infoTagsObject['Total-Borrows'], infoTagsObject['Denomination']) + const totalSupply = scaleBalance(infoTagsObject['Total-Supply'], infoTagsObject['Denomination']) + + let supplyAPY = formatSupplyAPR(borrowAPR, infoTagsObject, totalBorrows, totalSupply) + + if (supplyAPY.toString() === 'NaN') { + supplyAPY = 0 + } + + const ltv = Number(infoTagsObject['Collateral-Factor']) / 100 + + const tokenID = poolObject.id + const oTokenID = poolObject.oToken + + return { + pool: `${oTokenID}-${chain}`.toLowerCase(), + chain, + project: 'liquidops', + symbol: utils.formatSymbol(`o${ticker}`), + tvlUsd: totalLends * tokenUSDPrice, + apyBase: supplyAPY, + underlyingTokens: [tokenID], + url: `https://liquidops.io/${ticker}`, + apyBaseBorrow: borrowAPR, + totalSupplyUsd: totalSupply * tokenUSDPrice, + totalBorrowUsd: totalBorrows * tokenUSDPrice, + ltv + }; + }); + + const poolsArray = await Promise.all(poolPromises); + + return poolsArray + +} + + +// Access AO on chain data via the node endpoint +async function DryRun(target, action, extraTags = []) { + const response = await axios.post(`${endpoint}/dry-run?process-id=${target}`, { + Id: "1234", + Target: target, + Owner: "1234", + Anchor: "0", + Data: "1234", + Tags: [ + ["Target", target], + ["Action", action], + ["Data-Protocol", "ao"], + ["Type", "Message"], + ["Variant", "ao.TN.1"], + ...extraTags + ].map(([name, value]) => ({ name, value })) + }, { + headers: { + 'Content-Type': 'application/json' + } + }); + await new Promise((resolve) => setTimeout(resolve, 1000)); + return response.data; +} + + +function scaleBalance(amount, denomination) { + const scaledDivider = BigInt(10) ** BigInt(denomination) + const balance = BigInt(amount) / scaledDivider + return Number(balance) +} + +function formatBorrowAPR(aprResponse) { + const apr = parseFloat(aprResponse["Annual-Percentage-Rate"]); + const rateMultiplier = parseFloat(aprResponse["Rate-Multiplier"]); + return apr / rateMultiplier +} + +function formatSupplyAPR(borrowAPR, infoTagsObject, totalBorrows, totalSupply) { + const utilizationRate = totalBorrows / totalSupply + const reserveFactorFract = Number(infoTagsObject['Reserve-Factor']) / 100; + return borrowAPR * utilizationRate * (1 - reserveFactorFract); +} + + +module.exports = { + apy, +}; +// npm run test --adapter=liquidops + diff --git a/src/adaptors/liquidswap/api.js b/src/adaptors/liquidswap/api.js new file mode 100644 index 0000000000..b76f0ca9b5 --- /dev/null +++ b/src/adaptors/liquidswap/api.js @@ -0,0 +1,68 @@ +const utils = require('../utils'); +const { + getPoolTotalLPUrl, + getFarmResourceUrl, + getPoolResourceUrl, +} = require('./utils'); + +async function fetchPoolTotalMintedLP(coinX, coinY, curve, resourceAccount) { + const response = await utils.getData( + getPoolTotalLPUrl(coinX, coinY, curve, resourceAccount) + ); + + return BigInt(response.data.supply.vec[0].integer.vec[0].value); +} + +async function fetchFarmPoolData( + deployedAddress, + coinX, + coinY, + curve, + reward, + resourceAccount +) { + const response = await utils.getData( + getFarmResourceUrl( + deployedAddress, + coinX, + coinY, + curve, + reward, + resourceAccount + ) + ); + + return { + rewardPerSecond: BigInt(response.data.reward_per_sec), + stakeCoins: BigInt(response.data.stake_coins.value), + totalBoosted: BigInt(response.data.total_boosted), + }; +} + +async function fetchLiquidityPoolData( + coinX, + coinY, + curve, + resourceAccount, + moduleAccount +) { + const response = await utils.getData( + getPoolResourceUrl(coinX, coinY, curve, resourceAccount, moduleAccount) + ); + + return { + coinXReserves: BigInt(response.data.coin_x_reserve.value), + coinYReserves: BigInt(response.data.coin_y_reserve.value), + }; +} + +async function getAPRsFromSentio() { + return await utils.getData('https://api.liquidswap.com/sentio/apr') +} + +module.exports = { + fetchFarmPoolData, + fetchLiquidityPoolData, + fetchPoolTotalMintedLP, + getAPRsFromSentio, +}; diff --git a/src/adaptors/liquidswap/constants.js b/src/adaptors/liquidswap/constants.js new file mode 100644 index 0000000000..5f1574fa13 --- /dev/null +++ b/src/adaptors/liquidswap/constants.js @@ -0,0 +1,340 @@ +const LP_DECIMALS = 8; +const LP_STAKING_ACCOUNT = + '0xb247ddeee87e848315caf9a33b8e4c71ac53db888cb88143d62d2370cca0ead2'; + +const RESOURCES_ACCOUNT_0_5 = + '0x61d2c22a6cb7831bee0f48363b0eec92369357aece0d1142062f7d5d85c7bef8'; +const RESOURCES_ACCOUNT_0 = + '0x05a97986a9d031c4567e15b797be516910cfcb4156312482efc6a19c0a30c948'; +const MODULE_ACCOUNT_0_5 = + '0x163df34fccbf003ce219d3f1d9e70d140b60622cb9dd47599c25fb2f797ba6e'; +const MODULE_ACCOUNT_0 = + '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12'; + +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const UNCORRELATED_CURVE = + '0x163df34fccbf003ce219d3f1d9e70d140b60622cb9dd47599c25fb2f797ba6e::curves::Uncorrelated'; +const UNCORRELATED_CURVE_0 = + '0x190d44266241744264b964a37b8f09863167a12d3e70cda39376cfb4e3561e12::curves::Uncorrelated'; +const STABLE_CURVE = + '0x163df34fccbf003ce219d3f1d9e70d140b60622cb9dd47599c25fb2f797ba6e::curves::Stable'; + +const APTOS_TOKEN = '0x1::aptos_coin::AptosCoin'; +const APTOS_COINGECKO_ID = 'aptos'; + +const AMNIS_ST_APT = + '0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a::amapt_token::AmnisApt'; +const AMNIS_APT_COINGECKO_ID = 'amnis-aptos'; + +const LZ_USDC = + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC'; +const LZ_USDC_COINGECKO_ID = 'usd-coin'; + +const LZ_USDT = + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT'; +const LZ_USDT_COINGECKO_ID = 'tether'; + +const DONK_TOKEN = '0xe88ae9670071da40a9a6b1d97aab8f6f1898fdc3b8f1c1038b492dfad738448b::coin::Donk'; +const DONK_COINGECKO_ID = 'donk_apt'; + +// const DUMDUM_TOKEN = '0xbe3c4b493632b4d776d56e19d91dcfb34f591f759f6b57f8632d455360da503c::dumdum_coin::DumdumCoin'; +// const DUMDUM_COINGECKO_ID = 'Dumdum'; + +const WETH_TOKEN = '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WETH' +const WETH_COINGECKO_ID = 'weth' + +const ST_APT_TOKEN = '0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a::stapt_token::StakedApt' +const ST_APT_COINGECKO_ID = 'amnis-staked-aptos-coin' + +const APT_DONK_FARM = { + deployedAddress: '0xd504f16190f067d94ff4aad9b91e53cbe79c6a3f2231b96fdcce3cb7879b6d84', + coinX: { + type: DONK_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: DONK_COINGECKO_ID, + symbol: 'Donk', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: UNCORRELATED_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: DONK_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: DONK_COINGECKO_ID, + symbol: 'Donk', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0xd504f16190f067d94ff4aad9b91e53cbe79c6a3f2231b96fdcce3cb7879b6d84-APT-Donk-UNCORRELATED' +}; + +// const APT_DUMDUM_FARM = { +// deployedAddress: '0xa121de669ff4b668bf1a0410a65faf9c8b1f2ff43f817ef61b6aea1935654209', +// coinX: { +// type: APTOS_TOKEN, +// decimals: LP_DECIMALS, +// coinGeckoId: APTOS_COINGECKO_ID, +// symbol: 'APT', +// }, +// coinY: { +// type: DUMDUM_TOKEN, +// decimals: LP_DECIMALS, +// coinGeckoId: DUMDUM_COINGECKO_ID, +// symbol: 'DUMDUM', +// }, +// curve: UNCORRELATED_CURVE, +// version: 'v0.5', +// rewardTokenInfo: { +// type: DUMDUM_TOKEN, +// decimals: LP_DECIMALS, +// coinGeckoId: DUMDUM_COINGECKO_ID, +// symbol: 'DUMDUM', +// }, +// resourceAccount: RESOURCES_ACCOUNT_0_5, +// moduleAccount: MODULE_ACCOUNT_0_5, +// uniqueFarmKey: '0xa121de669ff4b668bf1a0410a65faf9c8b1f2ff43f817ef61b6aea1935654209-APT-Dumdum-UNCORRELATED' +// }; + +const WETH_APT_FARM = { + deployedAddress: '0xbac870e3aa0bef8b40a8b4845589ef6eb118283fd51d837f15bb95758cfcfe98', + coinX: { + type: WETH_TOKEN, + decimals: 6, + coinGeckoId: WETH_COINGECKO_ID, + symbol: 'zWETH', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: UNCORRELATED_CURVE_0, + version: 'v0', + rewardTokenInfo: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + resourceAccount: RESOURCES_ACCOUNT_0, + moduleAccount: MODULE_ACCOUNT_0, + uniqueFarmKey: '0xbac870e3aa0bef8b40a8b4845589ef6eb118283fd51d837f15bb95758cfcfe98-zWETH-APT-UNCORRELATED' +}; + +const USDC_USDT_FARM = { + deployedAddress: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8', + coinX: { + type: LZ_USDC, + decimals: 6, + coinGeckoId: LZ_USDC_COINGECKO_ID, + symbol: 'zUSDC', + }, + coinY: { + type: LZ_USDT, + decimals: 6, + coinGeckoId: LZ_USDT_COINGECKO_ID, + symbol: 'zUSDT', + }, + curve: STABLE_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8-USDC-USDT-STABLE' +}; + +const USDC_APT_FARM = { + deployedAddress: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8', + coinX: { + type: LZ_USDC, + decimals: 6, + coinGeckoId: LZ_USDC_COINGECKO_ID, + symbol: 'zUSDC', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: UNCORRELATED_CURVE_0, + version: 'v0', + rewardTokenInfo: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + resourceAccount: RESOURCES_ACCOUNT_0, + moduleAccount: MODULE_ACCOUNT_0, + uniqueFarmKey: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8-USDC-APT-UNCORRELATED' +}; + +const USDT_APT_FARM = { + deployedAddress: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8', + coinX: { + type: LZ_USDT, + decimals: 6, + coinGeckoId: LZ_USDT_COINGECKO_ID, + symbol: 'zUSDT', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: UNCORRELATED_CURVE_0, + version: 'v0', + rewardTokenInfo: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + resourceAccount: RESOURCES_ACCOUNT_0, + moduleAccount: MODULE_ACCOUNT_0, + uniqueFarmKey: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8-USDT-APT-UNCORRELATED' +}; + +const AMNIS_APT_APT_FARM = { + deployedAddress: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8', + coinX: { + type: AMNIS_ST_APT, + decimals: LP_DECIMALS, + coinGeckoId: AMNIS_APT_COINGECKO_ID, + symbol: 'amAPT', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: STABLE_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0xf4eceeb8438242ed43e2d6f7b2534e8e2e1e96f12755ebbc345a7b570ec367a8-AMNIS_APT-APT-STABLE' +}; + +const AM_APT_APT_FARM = { + deployedAddress: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880', + coinX: { + type: AMNIS_ST_APT, + decimals: LP_DECIMALS, + coinGeckoId: AMNIS_APT_COINGECKO_ID, + symbol: 'amAPT', + }, + coinY: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + curve: STABLE_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: AMNIS_ST_APT, + decimals: LP_DECIMALS, + coinGeckoId: AMNIS_APT_COINGECKO_ID, + symbol: 'amAPT', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880-AMNIS_APT-APT-STABLE' +}; + +const ST_APT_APT_FARM = { + deployedAddress: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880', + coinX: { + type: APTOS_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: APTOS_COINGECKO_ID, + symbol: 'APT', + }, + coinY: { + type: ST_APT_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: ST_APT_COINGECKO_ID, + symbol: 'stAPT', + }, + curve: UNCORRELATED_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: AMNIS_ST_APT, + decimals: LP_DECIMALS, + coinGeckoId: AMNIS_APT_COINGECKO_ID, + symbol: 'amAPT', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880-ST_APT-APT-UNCORRELATED' +}; + +const USDC_ST_APT_FARM = { + deployedAddress: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880', + coinX: { + type: LZ_USDC, + decimals: 6, + coinGeckoId: LZ_USDC_COINGECKO_ID, + symbol: 'USDC', + }, + coinY: { + type: ST_APT_TOKEN, + decimals: LP_DECIMALS, + coinGeckoId: ST_APT_COINGECKO_ID, + symbol: 'stAPT', + }, + curve: UNCORRELATED_CURVE, + version: 'v0.5', + rewardTokenInfo: { + type: AMNIS_ST_APT, + decimals: LP_DECIMALS, + coinGeckoId: AMNIS_APT_COINGECKO_ID, + symbol: 'amAPT', + }, + resourceAccount: RESOURCES_ACCOUNT_0_5, + moduleAccount: MODULE_ACCOUNT_0_5, + uniqueFarmKey: '0x845a18353b4b5287435f8bf1d831a81cbc054a2314b5d06e3194e353b00ec880-USDC-ST_APT-UNCORRELATED' +}; + +const FARMS = [ + APT_DONK_FARM, + // APT_DUMDUM_FARM, + WETH_APT_FARM, + USDC_USDT_FARM, + USDC_APT_FARM, + USDT_APT_FARM, + AMNIS_APT_APT_FARM, + AM_APT_APT_FARM, + ST_APT_APT_FARM, + USDC_ST_APT_FARM, +]; + +const WEEK_SEC = 7 * 24 * 60 * 60; + +module.exports = { + LP_DECIMALS, + LP_STAKING_ACCOUNT, + NODE_URL, + FARMS, + WEEK_SEC, +}; diff --git a/src/adaptors/liquidswap/index.js b/src/adaptors/liquidswap/index.js new file mode 100644 index 0000000000..2cf4203adf --- /dev/null +++ b/src/adaptors/liquidswap/index.js @@ -0,0 +1,198 @@ +const { BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const axios = require('axios'); +const { + FARMS, + LP_DECIMALS, + UNCORRELATED_CURVE +} = require('./constants'); +const { + getUSDEquivalent, + getPoolTotalLPUrl, + decimalsMultiplier, + getFarmResourceUrl, + getAmountWithDecimal, + calcOutputBurnLiquidity, + calcRewardPerWeekPerOneLp, +} = require('./utils'); +const { + fetchFarmPoolData, + fetchLiquidityPoolData, + fetchPoolTotalMintedLP, + getAPRsFromSentio, +} = require('./api'); + +async function getAPRandTVL(farmPool) { + // calc ARP + const decimalsReward = decimalsMultiplier( + farmPool.rewardTokenInfo.decimals + ).toNumber(); + + const farmData = await fetchFarmPoolData( + farmPool.deployedAddress, + farmPool.coinX.type, + farmPool.coinY.type, + farmPool.curve, + farmPool.rewardTokenInfo.type, + farmPool.resourceAccount + ); + + const rewardPerWeekPerOneLP = calcRewardPerWeekPerOneLp( + farmData, + farmPool.rewardTokenInfo + ); + + const liquidityPoolData = await fetchLiquidityPoolData( + farmPool.coinX.type, + farmPool.coinY.type, + farmPool.curve, + farmPool.resourceAccount, + farmPool.moduleAccount + ); + + const liquidityPoolTotalMintedLPValue = await fetchPoolTotalMintedLP( + farmPool.coinX.type, + farmPool.coinY.type, + farmPool.curve, + farmPool.resourceAccount + ); + + const poolTokensPrices = await utils.getPrices([ + `coingecko:${farmPool.rewardTokenInfo.coinGeckoId}`, + `coingecko:${farmPool.coinX.coinGeckoId}`, + `coingecko:${farmPool.coinY.coinGeckoId}`, + ]); + + const rewardTokenPriceValue = + poolTokensPrices.pricesByAddress[farmPool.rewardTokenInfo.coinGeckoId]; + + const rewardPerWeekHumanReadable = getAmountWithDecimal( + rewardPerWeekPerOneLP, + farmPool.rewardTokenInfo.decimals + ); + + const rewardPerWeekInUSD = getUSDEquivalent( + rewardPerWeekHumanReadable, + rewardTokenPriceValue + ); + + const oneLPHumanReadableValue = decimalsMultiplier(LP_DECIMALS).toNumber(); + + const afterBurnOneLpValue = calcOutputBurnLiquidity({ + xReserve: liquidityPoolData.coinXReserves, + yReserve: liquidityPoolData.coinYReserves, + lpSupply: liquidityPoolTotalMintedLPValue, + toBurn: oneLPHumanReadableValue, + }); + + const oneLpXRateHumanReadableAPR = getAmountWithDecimal( + afterBurnOneLpValue.x, + farmPool.coinX.decimals + ); + + const oneLpYRateHumanReadableAPR = getAmountWithDecimal( + afterBurnOneLpValue.y, + farmPool.coinY.decimals + ); + + const oneLpXRateInUSD = getUSDEquivalent( + oneLpXRateHumanReadableAPR, + poolTokensPrices.pricesByAddress[farmPool.coinX.coinGeckoId] + ); + + const oneLpYRateInUSD = getUSDEquivalent( + oneLpYRateHumanReadableAPR, + poolTokensPrices.pricesByAddress[farmPool.coinY.coinGeckoId] + ); + + const oneLpInUSD = oneLpXRateInUSD + oneLpYRateInUSD; + + const APR = ((rewardPerWeekInUSD / oneLpInUSD) * 100 * 365) / 7; + + // calc TVL + const TVLCalculationData = calcOutputBurnLiquidity({ + xReserve: liquidityPoolData.coinXReserves, + yReserve: liquidityPoolData.coinYReserves, + lpSupply: liquidityPoolTotalMintedLPValue, + toBurn: farmData.stakeCoins, + }); + + const oneLpXRateHumanReadableTVL = getAmountWithDecimal( + TVLCalculationData.x, + farmPool.coinX.decimals + ); + + const oneLpYRateHumanReadableTVL = getAmountWithDecimal( + TVLCalculationData.y, + farmPool.coinY.decimals + ); + + const oneLpXRateInUSDTVL = getUSDEquivalent( + oneLpXRateHumanReadableTVL, + poolTokensPrices.pricesByAddress[farmPool.coinX.coinGeckoId] + ); + + const oneLpYRateInUSDTVL = getUSDEquivalent( + oneLpYRateHumanReadableTVL, + poolTokensPrices.pricesByAddress[farmPool.coinY.coinGeckoId] + ); + + const TVL = oneLpXRateInUSDTVL + oneLpYRateInUSDTVL; + + return { + apr: APR, + tvl: TVL, + }; +} + +async function aptosPools() { + const pools = []; + + for (let farmPool of FARMS) { + const farmPoolInfo = await getAPRandTVL(farmPool); + const { coinX, coinY, uniqueFarmKey } = farmPool; + + pools.push({ + pool: uniqueFarmKey, + chain: utils.formatChain('aptos'), + project: 'liquidswap', + symbol: `${coinX.symbol}-${coinY.symbol}`, + tvlUsd: farmPoolInfo.tvl, + apy: farmPoolInfo.apr, + }); + } + + return pools; +} + +async function movementPools() { + const pools = (await axios.get('https://api.liquidswap.com/pools/registered?networkId=126')).data; + + return pools.filter(pool => pool.tvl !== null).map(pool => { + const [lpID,,curveId] = pool.stats.curve.split('::'); + const poolId = `${lpID}-${pool.coinX.symbol}-${pool.coinY.symbol}-${curveId}`; + + const volumeUsd1d = parseFloat(pool.volume24); + const fee24h = volumeUsd1d * parseFloat(pool.normalizedFee); + + return { + pool: poolId, + chain: utils.formatChain('movement'), + project: 'liquidswap', + symbol: `${pool.coinX.symbol}-${pool.coinY.symbol}`, + tvlUsd: Number(pool.tvl), + apyBase: volumeUsd1d > 0 ? fee24h * 365 * 100 / volumeUsd1d : 0, + volumeUsd1d: volumeUsd1d, + } + }) +} + +async function main() { + return (await aptosPools()).concat(await movementPools()) +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://farms.liquidswap.com/#/stakes', +}; diff --git a/src/adaptors/liquidswap/utils.js b/src/adaptors/liquidswap/utils.js new file mode 100644 index 0000000000..73c17cff07 --- /dev/null +++ b/src/adaptors/liquidswap/utils.js @@ -0,0 +1,93 @@ +const { + FARMS, + NODE_URL, + LP_STAKING_ACCOUNT, + LP_DECIMALS, + WEEK_SEC, +} = require('./constants'); +const { BigNumber } = require('bignumber.js'); + +function getFarmResourceUrl( + deploymentAddress, + coinXType, + coinYType, + curveType, + rewardType, + resourceAccount +) { + return `${NODE_URL}/accounts/${deploymentAddress}/resource/${LP_STAKING_ACCOUNT}::stake::StakePool<${resourceAccount}::lp_coin::LP<${coinXType},${coinYType},${curveType}>,${rewardType}>`; +} + +function getPoolResourceUrl( + coinXType, + coinYType, + curveType, + resourceAccount, + moduleAccount +) { + return `${NODE_URL}/accounts/${resourceAccount}/resource/${moduleAccount}::liquidity_pool::LiquidityPool<${coinXType},${coinYType},${curveType}>`; +} + +function getPoolTotalLPUrl(coinXType, coinYType, curveType, resourceAccount) { + return `${NODE_URL}/accounts/${resourceAccount}/resource/0x1::coin::CoinInfo<${resourceAccount}::lp_coin::LP<${coinXType},${coinYType},${curveType}>>`; +} + +function calcOutputBurnLiquidity({ xReserve, yReserve, lpSupply, toBurn }) { + const xReturn = BigNumber(toBurn).multipliedBy(xReserve).dividedBy(lpSupply); + const yReturn = BigNumber(toBurn).multipliedBy(yReserve).dividedBy(lpSupply); + + if (xReturn.isEqualTo(0) || yReturn.isEqualTo(0)) { + return undefined; + } + + return { + x: Math.trunc(xReturn.toNumber()), + y: Math.trunc(yReturn.toNumber()), + }; +} + +function getAmountWithDecimal(amount, decimal) { + if (amount === undefined) return; + + return +BigNumber(amount) + .dividedBy(decimalsMultiplier(decimal)) + .toFixed(decimal); +} + +function decimalsMultiplier(decimals) { + return BigNumber(10).exponentiatedBy(BigNumber(decimals).absoluteValue()); +} + +function calcRewardPerWeekPerOneLp(farmData, rewardToken) { + const decimalsReward = decimalsMultiplier(rewardToken.decimals).toNumber(); + + const decimalsLP = decimalsMultiplier(LP_DECIMALS).toNumber(); + const numerator = BigNumber(farmData.rewardPerSecond).multipliedBy(WEEK_SEC); + const denominator = BigNumber(farmData.stakeCoins) + .plus(farmData.totalBoosted) + .plus(decimalsLP); + + const estimation = BigNumber(numerator).dividedBy(denominator); + const normalizer = BigNumber(decimalsLP).dividedBy(decimalsReward); + const rewardPerWeekOnLp = estimation + .multipliedBy(normalizer) + .multipliedBy(decimalsReward); + + return rewardPerWeekOnLp.toNumber(); +} + +function getUSDEquivalent(coinAmount, usdRate) { + if (!coinAmount || !usdRate) return 0; + return BigNumber(coinAmount).multipliedBy(BigNumber(usdRate)).toNumber(); +} + +module.exports = { + getUSDEquivalent, + getPoolTotalLPUrl, + decimalsMultiplier, + getFarmResourceUrl, + getPoolResourceUrl, + getAmountWithDecimal, + calcOutputBurnLiquidity, + calcRewardPerWeekPerOneLp, +}; diff --git a/src/adaptors/liquis/abis/BalancerToken.json b/src/adaptors/liquis/abis/BalancerToken.json new file mode 100644 index 0000000000..5c9e9ee493 --- /dev/null +++ b/src/adaptors/liquis/abis/BalancerToken.json @@ -0,0 +1,672 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IVault", + "name": "vault", + "type": "address" + }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "contract IERC20", + "name": "token0", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "normalizedWeight0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "normalizedWeight1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pauseWindowDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodDuration", + "type": "uint256" + }, + { "internalType": "bool", "name": "oracleEnabled", "type": "bool" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "internalType": "struct WeightedPool2Tokens.NewPoolParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "OracleEnabledChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "PausedStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "SwapFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "decreaseApproval", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "selector", "type": "bytes4" } + ], + "name": "getActionId", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthorizer", + "outputs": [ + { "internalType": "contract IAuthorizer", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInvariant", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLargestSafeQueryWindow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getLastInvariant", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IPriceOracle.Variable", + "name": "variable", + "type": "uint8" + } + ], + "name": "getLatest", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMiscData", + "outputs": [ + { "internalType": "int256", "name": "logInvariant", "type": "int256" }, + { "internalType": "int256", "name": "logTotalSupply", "type": "int256" }, + { + "internalType": "uint256", + "name": "oracleSampleCreationTimestamp", + "type": "uint256" + }, + { "internalType": "uint256", "name": "oracleIndex", "type": "uint256" }, + { "internalType": "bool", "name": "oracleEnabled", "type": "bool" }, + { + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNormalizedWeights", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IPriceOracle.Variable", + "name": "variable", + "type": "uint8" + }, + { "internalType": "uint256", "name": "ago", "type": "uint256" } + ], + "internalType": "struct IPriceOracle.OracleAccumulatorQuery[]", + "name": "queries", + "type": "tuple[]" + } + ], + "name": "getPastAccumulators", + "outputs": [ + { "internalType": "int256[]", "name": "results", "type": "int256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPausedState", + "outputs": [ + { "internalType": "bool", "name": "paused", "type": "bool" }, + { + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodEndTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolId", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "getSample", + "outputs": [ + { "internalType": "int256", "name": "logPairPrice", "type": "int256" }, + { "internalType": "int256", "name": "accLogPairPrice", "type": "int256" }, + { "internalType": "int256", "name": "logBptPrice", "type": "int256" }, + { "internalType": "int256", "name": "accLogBptPrice", "type": "int256" }, + { "internalType": "int256", "name": "logInvariant", "type": "int256" }, + { "internalType": "int256", "name": "accLogInvariant", "type": "int256" }, + { "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSwapFeePercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IPriceOracle.Variable", + "name": "variable", + "type": "uint8" + }, + { "internalType": "uint256", "name": "secs", "type": "uint256" }, + { "internalType": "uint256", "name": "ago", "type": "uint256" } + ], + "internalType": "struct IPriceOracle.OracleAverageQuery[]", + "name": "queries", + "type": "tuple[]" + } + ], + "name": "getTimeWeightedAverage", + "outputs": [ + { "internalType": "uint256[]", "name": "results", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalSamples", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getVault", + "outputs": [ + { "internalType": "contract IVault", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "increaseApproval", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "protocolSwapFeePercentage", + "type": "uint256" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "onExitPool", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "protocolSwapFeePercentage", + "type": "uint256" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "onJoinPool", + "outputs": [ + { "internalType": "uint256[]", "name": "amountsIn", "type": "uint256[]" }, + { + "internalType": "uint256[]", + "name": "dueProtocolFeeAmounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "internalType": "struct IPoolSwapStructs.SwapRequest", + "name": "request", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "balanceTokenIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceTokenOut", + "type": "uint256" + } + ], + "name": "onSwap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "protocolSwapFeePercentage", + "type": "uint256" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "queryExit", + "outputs": [ + { "internalType": "uint256", "name": "bptIn", "type": "uint256" }, + { "internalType": "uint256[]", "name": "amountsOut", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "protocolSwapFeePercentage", + "type": "uint256" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "queryJoin", + "outputs": [ + { "internalType": "uint256", "name": "bptOut", "type": "uint256" }, + { "internalType": "uint256[]", "name": "amountsIn", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "paused", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "setSwapFeePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/Booster.json b/src/adaptors/liquis/abis/Booster.json new file mode 100644 index 0000000000..bf07793e97 --- /dev/null +++ b/src/adaptors/liquis/abis/Booster.json @@ -0,0 +1,915 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_staker", "type": "address" }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "address", "name": "_crv", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newArbitrator", + "type": "address" + } + ], + "name": "ArbitratorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "poolid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "rewardFactory", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "stashFactory", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenFactory", + "type": "address" + } + ], + "name": "FactoriesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeDistro", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "FeeInfoChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeDistro", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "lockFees", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + } + ], + "name": "FeeInfoUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newFeeManager", + "type": "address" + } + ], + "name": "FeeManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lockIncentive", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakerIncentive", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "earmarkIncentive", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "platformFee", + "type": "uint256" + } + ], + "name": "FeesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardPool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "stash", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "PoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPoolManager", + "type": "address" + } + ], + "name": "PoolManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + } + ], + "name": "PoolShutdown", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "lockRewards", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "stakerRewards", + "type": "address" + } + ], + "name": "RewardContractsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newTreasury", + "type": "address" + } + ], + "name": "TreasuryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "votingContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "UpdateVotingContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newVoteDelegate", + "type": "address" + } + ], + "name": "VoteDelegateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newVoteManager", + "type": "address" + } + ], + "name": "VoteManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "poolid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MaxFees", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_MULTIPLIER_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_lptoken", "type": "address" }, + { "internalType": "address", "name": "_gauge", "type": "address" }, + { "internalType": "uint256", "name": "_stashVersion", "type": "uint256" } + ], + "name": "addPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bridgeDelegate", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "claimRewards", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "crv", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "bool", "name": "_stake", "type": "bool" } + ], + "name": "deposit", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "bool", "name": "_stake", "type": "bool" } + ], + "name": "depositAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "distributeL2Fees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeToken", "type": "address" } + ], + "name": "earmarkFees", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "earmarkIncentive", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "earmarkRewards", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "feeTokens", + "outputs": [ + { "internalType": "address", "name": "distro", "type": "address" }, + { "internalType": "address", "name": "rewards", "type": "address" }, + { "internalType": "bool", "name": "active", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugeMap", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "getRewardMultipliers", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "l2FeesHistory", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lockIncentive", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lockRewards", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "platformFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "address", "name": "lptoken", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { "internalType": "address", "name": "crvRewards", "type": "address" }, + { "internalType": "address", "name": "stash", "type": "address" }, + { "internalType": "bool", "name": "shutdown", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardArbitrator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_address", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "rewardClaimed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_arb", "type": "address" } + ], + "name": "setArbitrator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgeDelegate", + "type": "address" + } + ], + "name": "setBridgeDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_delegateContract", + "type": "address" + }, + { "internalType": "address", "name": "_delegate", "type": "address" }, + { "internalType": "bytes32", "name": "_space", "type": "bytes32" } + ], + "name": "setDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rfactory", "type": "address" }, + { "internalType": "address", "name": "_sfactory", "type": "address" }, + { "internalType": "address", "name": "_tfactory", "type": "address" } + ], + "name": "setFactories", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeToken", "type": "address" }, + { "internalType": "address", "name": "_feeDistro", "type": "address" } + ], + "name": "setFeeInfo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeM", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_lockFees", "type": "uint256" }, + { "internalType": "uint256", "name": "_stakerFees", "type": "uint256" }, + { "internalType": "uint256", "name": "_callerFees", "type": "uint256" }, + { "internalType": "uint256", "name": "_platform", "type": "uint256" } + ], + "name": "setFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "setGaugeRedirect", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolM", "type": "address" } + ], + "name": "setPoolManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewards", "type": "address" }, + { "internalType": "address", "name": "_stakerRewards", "type": "address" } + ], + "name": "setRewardContracts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardContract", + "type": "address" + }, + { "internalType": "uint256", "name": "multiplier", "type": "uint256" } + ], + "name": "setRewardMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_treasury", "type": "address" } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "_hash", "type": "bytes32" } + ], + "name": "setVote", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voteDelegate", "type": "address" } + ], + "name": "setVoteDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voteManager", "type": "address" } + ], + "name": "setVoteManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "shutdownPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shutdownSystem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staker", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakerIncentive", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakerRewards", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stashFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeToken", "type": "address" }, + { "internalType": "bool", "name": "_active", "type": "bool" } + ], + "name": "updateFeeInfo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_votingContract", + "type": "address" + }, + { "internalType": "bool", "name": "_active", "type": "bool" } + ], + "name": "updateVotingContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "validVotingContracts", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_voteId", "type": "uint256" }, + { + "internalType": "address", + "name": "_votingAddress", + "type": "address" + }, + { "internalType": "bool", "name": "_support", "type": "bool" } + ], + "name": "vote", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "voteDelegate", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauge", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weight", "type": "uint256[]" } + ], + "name": "voteGaugeWeight", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "voteManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "withdrawAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "withdrawTo", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/BunniHub.json b/src/adaptors/liquis/abis/BunniHub.json new file mode 100644 index 0000000000..3e70e2a2fa --- /dev/null +++ b/src/adaptors/liquis/abis/BunniHub.json @@ -0,0 +1,812 @@ +[ + { + "inputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "factory_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "protocolFee_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Compound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "NewBunni", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "PayProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolFee", + "type": "uint256" + } + ], + "name": "SetProtocolFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "bunniKeyHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "compound", + "outputs": [ + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "deployBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IBunniHub.DepositParams", + "name": "params", + "type": "tuple" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "addedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract IUniswapV3Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getBunniToken", + "outputs": [ + { + "internalType": "contract IBunniToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "setProtocolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokenList", + "type": "address[]" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct IBunniHub.WithdrawParams", + "name": "params", + "type": "tuple" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint128", + "name": "removedLiquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/BunniLens.json b/src/adaptors/liquis/abis/BunniLens.json new file mode 100644 index 0000000000..b493afba9c --- /dev/null +++ b/src/adaptors/liquis/abis/BunniLens.json @@ -0,0 +1,118 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBunniHub", + "name": "hub_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hub", + "outputs": [ + { + "internalType": "contract IBunniHub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IUniswapV3Pool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "internalType": "struct BunniKey", + "name": "key", + "type": "tuple" + } + ], + "name": "pricePerFullShare", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/GaugeController.json b/src/adaptors/liquis/abis/GaugeController.json new file mode 100644 index 0000000000..eaee92db1f --- /dev/null +++ b/src/adaptors/liquis/abis/GaugeController.json @@ -0,0 +1,825 @@ +[ + { + "name": "AddType", + "inputs": [ + { + "name": "name", + "type": "string", + "indexed": false + }, + { + "name": "type_id", + "type": "int128", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewTypeWeight", + "inputs": [ + { + "name": "type_id", + "type": "int128", + "indexed": false + }, + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + }, + { + "name": "total_weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewGaugeWeight", + "inputs": [ + { + "name": "gauge_address", + "type": "address", + "indexed": false + }, + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + }, + { + "name": "total_weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "VoteForGauge", + "inputs": [ + { + "name": "time", + "type": "uint256", + "indexed": false + }, + { + "name": "user", + "type": "address", + "indexed": false + }, + { + "name": "gauge_addr", + "type": "address", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewGauge", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": false + }, + { + "name": "gauge_type", + "type": "int128", + "indexed": false + }, + { + "name": "weight", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewPendingAdmin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "name": "new_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_voting_escrow", + "type": "address" + }, + { + "name": "_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voting_escrow", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_exists", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_types", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "gauge_type", + "type": "int128" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "gauge_type", + "type": "int128" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "checkpoint", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "checkpoint_gauge", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_relative_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_relative_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "gauge_relative_weight_write", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_type", + "inputs": [ + { + "name": "_name", + "type": "string" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_type", + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_type_weight", + "inputs": [ + { + "name": "type_id", + "type": "int128" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_gauge_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + }, + { + "name": "weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "vote_for_many_gauge_weights", + "inputs": [ + { + "name": "_gauge_addrs", + "type": "address[8]" + }, + { + "name": "_user_weight", + "type": "uint256[8]" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "vote_for_gauge_weights", + "inputs": [ + { + "name": "_gauge_addr", + "type": "address" + }, + { + "name": "_user_weight", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_gauge_weight", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_type_weight", + "inputs": [ + { + "name": "type_id", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_total_weight", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_weights_sum_per_type", + "inputs": [ + { + "name": "type_id", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_pending_admin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_admin", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "pending_admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_gauge_types", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "n_gauges", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_type_names", + "inputs": [ + { + "name": "arg0", + "type": "int128" + } + ], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauges", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "vote_user_slopes", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "slope", + "type": "uint256" + }, + { + "name": "power", + "type": "uint256" + }, + { + "name": "end", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "vote_user_power", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "last_user_vote", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_weight", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "bias", + "type": "uint256" + }, + { + "name": "slope", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_weight", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_sum", + "inputs": [ + { + "name": "arg0", + "type": "int128" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "bias", + "type": "uint256" + }, + { + "name": "slope", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_sum", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_total", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_total", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "points_type_weight", + "inputs": [ + { + "name": "arg0", + "type": "int128" + }, + { + "name": "arg1", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "time_type_weight", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + } +] diff --git a/src/adaptors/liquis/abis/LiquidityGauge.json b/src/adaptors/liquis/abis/LiquidityGauge.json new file mode 100644 index 0000000000..7f3a098ca9 --- /dev/null +++ b/src/adaptors/liquis/abis/LiquidityGauge.json @@ -0,0 +1,1229 @@ +[ + { + "name": "Deposit", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true + }, + { + "name": "value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateLiquidityLimit", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true + }, + { + "name": "original_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "original_supply", + "type": "uint256", + "indexed": false + }, + { + "name": "working_balance", + "type": "uint256", + "indexed": false + }, + { + "name": "working_supply", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Transfer", + "inputs": [ + { + "name": "_from", + "type": "address", + "indexed": true + }, + { + "name": "_to", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Approval", + "inputs": [ + { + "name": "_owner", + "type": "address", + "indexed": true + }, + { + "name": "_spender", + "type": "address", + "indexed": true + }, + { + "name": "_value", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RewardDistributorUpdated", + "inputs": [ + { + "name": "reward_token", + "type": "address", + "indexed": true + }, + { + "name": "distributor", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "RelativeWeightCapChanged", + "inputs": [ + { + "name": "new_relative_weight_cap", + "type": "uint256", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewPendingAdmin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "name": "new_admin", + "type": "address", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewTokenlessProduction", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "minter", + "type": "address" + }, + { + "name": "uniswap_poor_oracle", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_addr", + "type": "address" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_claim_rewards", + "type": "bool" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_rewards", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_deadline", + "type": "uint256" + }, + { + "name": "_v", + "type": "uint8" + }, + { + "name": "_r", + "type": "bytes32" + }, + { + "name": "_s", + "type": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_added_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_subtracted_value", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "user_checkpoint", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_rewards_receiver", + "inputs": [ + { + "name": "_receiver", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "kick", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit_reward_token", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_reward", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_reward_distributor", + "inputs": [ + { + "name": "_reward_token", + "type": "address" + }, + { + "name": "_distributor", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "makeGaugePermissionless", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "killGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "unkillGauge", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "change_pending_admin", + "inputs": [ + { + "name": "new_pending_admin", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_admin", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_tokenless_production", + "inputs": [ + { + "name": "new_tokenless_production", + "type": "uint8" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimed_reward", + "inputs": [ + { + "name": "_addr", + "type": "address" + }, + { + "name": "_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "claimable_reward", + "inputs": [ + { + "name": "_user", + "type": "address" + }, + { + "name": "_reward_token", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claimable_tokens", + "inputs": [ + { + "name": "addr", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_epoch_time", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "inflation_rate", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool" + } + ] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_lp_token", + "type": "address" + }, + { + "name": "relative_weight_cap", + "type": "uint256" + }, + { + "name": "_voting_escrow_delegation", + "type": "address" + }, + { + "name": "_admin", + "type": "address" + }, + { + "name": "_position_key", + "type": "bytes32" + } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setRelativeWeightCap", + "inputs": [ + { + "name": "relative_weight_cap", + "type": "uint256" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "getRelativeWeightCap", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "getCappedRelativeWeight", + "inputs": [ + { + "name": "time", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "pure", + "type": "function", + "name": "getMaxRelativeWeightCap", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokenless_production", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "pending_admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voting_escrow_delegation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lp_token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_state", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "position_key", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_count", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_data", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "distributor", + "type": "address" + }, + { + "name": "period_finish", + "type": "uint256" + }, + { + "name": "rate", + "type": "uint256" + }, + { + "name": "last_update", + "type": "uint256" + }, + { + "name": "integral", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards_receiver", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_integral_for", + "inputs": [ + { + "name": "arg0", + "type": "address" + }, + { + "name": "arg1", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_balances", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "working_supply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_checkpoint_of", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_fraction", + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "int128" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "reward_tokens", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "period_timestamp", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "integrate_inv_supply", + "inputs": [ + { + "name": "arg0", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256" + } + ] + } +] diff --git a/src/adaptors/liquis/abis/OptionsOracle.json b/src/adaptors/liquis/abis/OptionsOracle.json new file mode 100644 index 0000000000..5cb26c9c0c --- /dev/null +++ b/src/adaptors/liquis/abis/OptionsOracle.json @@ -0,0 +1,225 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBalancerTwapOracle", + "name": "balancerTwapOracle_", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "uint16", + "name": "multiplier_", + "type": "uint16" + }, + { + "internalType": "uint56", + "name": "secs_", + "type": "uint56" + }, + { + "internalType": "uint56", + "name": "ago_", + "type": "uint56" + }, + { + "internalType": "uint128", + "name": "minPrice_", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BalancerOracle__TWAPOracleNotReady", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "multiplier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "secs", + "type": "uint56" + }, + { + "indexed": false, + "internalType": "uint56", + "name": "ago", + "type": "uint56" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "minPrice", + "type": "uint128" + } + ], + "name": "SetParams", + "type": "event" + }, + { + "inputs": [], + "name": "ago", + "outputs": [ + { + "internalType": "uint56", + "name": "", + "type": "uint56" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "balancerTwapOracle", + "outputs": [ + { + "internalType": "contract IBalancerTwapOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPrice", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "multiplier", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "secs", + "outputs": [ + { + "internalType": "uint56", + "name": "", + "type": "uint56" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "multiplier_", + "type": "uint16" + }, + { + "internalType": "uint56", + "name": "secs_", + "type": "uint56" + }, + { + "internalType": "uint56", + "name": "ago_", + "type": "uint56" + }, + { + "internalType": "uint128", + "name": "minPrice_", + "type": "uint128" + } + ], + "name": "setParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/TokenAdmin.json b/src/adaptors/liquis/abis/TokenAdmin.json new file mode 100644 index 0000000000..efab4125bb --- /dev/null +++ b/src/adaptors/liquis/abis/TokenAdmin.json @@ -0,0 +1,390 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20Mintable", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "MiningParametersUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_RATE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_COEFFICIENT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_REDUCTION_TIME", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "available_supply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "futureEpochTimeWrite", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "future_epoch_time_write", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAvailableSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFutureEpochTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInflationRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMiningEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStartEpochTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getToken", + "outputs": [ + { + "internalType": "contract IERC20Mintable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "mintableInTimeframe", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "mintable_in_timeframe", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startEpochTimeWrite", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start_epoch_time_write", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateMiningParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "update_mining_parameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/Vault.json b/src/adaptors/liquis/abis/Vault.json new file mode 100644 index 0000000000..03668f92a5 --- /dev/null +++ b/src/adaptors/liquis/abis/Vault.json @@ -0,0 +1,918 @@ +[ + { + "inputs": [ + { + "internalType": "contract IAuthorizer", + "name": "authorizer", + "type": "address" + }, + { "internalType": "contract IWETH", "name": "weth", "type": "address" }, + { + "internalType": "uint256", + "name": "pauseWindowDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodDuration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "AuthorizerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ExternalBalanceTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IFlashLoanRecipient", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "delta", + "type": "int256" + } + ], + "name": "InternalBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "PausedStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidityProvider", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "int256[]", + "name": "deltas", + "type": "int256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "protocolFeeAmounts", + "type": "uint256[]" + } + ], + "name": "PoolBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "assetManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "cashDelta", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "managedDelta", + "type": "int256" + } + ], + "name": "PoolBalanceManaged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum IVault.PoolSpecialization", + "name": "specialization", + "type": "uint8" + } + ], + "name": "PoolRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "relayer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "RelayerApprovalChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "TokensDeregistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "poolId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "assetManagers", + "type": "address[]" + } + ], + "name": "TokensRegistered", + "type": "event" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { "internalType": "contract IWETH", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "components": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "assetInIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetOutIndex", + "type": "uint256" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "internalType": "struct IVault.BatchSwapStep[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "components": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + }, + { "internalType": "int256[]", "name": "limits", "type": "int256[]" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "name": "batchSwap", + "outputs": [ + { "internalType": "int256[]", "name": "assetDeltas", "type": "int256[]" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "deregisterTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "minAmountsOut", + "type": "uint256[]" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.ExitPoolRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "exitPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFlashLoanRecipient", + "name": "recipient", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "selector", "type": "bytes4" } + ], + "name": "getActionId", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthorizer", + "outputs": [ + { "internalType": "contract IAuthorizer", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDomainSeparator", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getInternalBalance", + "outputs": [ + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getNextNonce", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPausedState", + "outputs": [ + { "internalType": "bool", "name": "paused", "type": "bool" }, + { + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodEndTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" } + ], + "name": "getPool", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { + "internalType": "enum IVault.PoolSpecialization", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "contract IERC20", "name": "token", "type": "address" } + ], + "name": "getPoolTokenInfo", + "outputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "managed", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + }, + { "internalType": "address", "name": "assetManager", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "lastChangeBlock", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProtocolFeesCollector", + "outputs": [ + { + "internalType": "contract ProtocolFeesCollector", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "address", "name": "relayer", "type": "address" } + ], + "name": "hasApprovedRelayer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "components": [ + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "maxAmountsIn", + "type": "uint256[]" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.JoinPoolRequest", + "name": "request", + "type": "tuple" + } + ], + "name": "joinPool", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IVault.PoolBalanceOpKind", + "name": "kind", + "type": "uint8" + }, + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct IVault.PoolBalanceOp[]", + "name": "ops", + "type": "tuple[]" + } + ], + "name": "managePoolBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum IVault.UserBalanceOpKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "contract IAsset", + "name": "asset", + "type": "address" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "sender", "type": "address" }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IVault.UserBalanceOp[]", + "name": "ops", + "type": "tuple[]" + } + ], + "name": "manageUserBalance", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "components": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "uint256", + "name": "assetInIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetOutIndex", + "type": "uint256" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "internalType": "struct IVault.BatchSwapStep[]", + "name": "swaps", + "type": "tuple[]" + }, + { + "internalType": "contract IAsset[]", + "name": "assets", + "type": "address[]" + }, + { + "components": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + } + ], + "name": "queryBatchSwap", + "outputs": [{ "internalType": "int256[]", "name": "", "type": "int256[]" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum IVault.PoolSpecialization", + "name": "specialization", + "type": "uint8" + } + ], + "name": "registerPool", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "assetManagers", + "type": "address[]" + } + ], + "name": "registerTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "setAuthorizer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "paused", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "relayer", "type": "address" }, + { "internalType": "bool", "name": "approved", "type": "bool" } + ], + "name": "setRelayerApproval", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bytes32", "name": "poolId", "type": "bytes32" }, + { + "internalType": "enum IVault.SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "contract IAsset", + "name": "assetIn", + "type": "address" + }, + { + "internalType": "contract IAsset", + "name": "assetOut", + "type": "address" + }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "internalType": "struct IVault.SingleSwap", + "name": "singleSwap", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { + "internalType": "bool", + "name": "fromInternalBalance", + "type": "bool" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "toInternalBalance", + "type": "bool" + } + ], + "internalType": "struct IVault.FundManagement", + "name": "funds", + "type": "tuple" + }, + { "internalType": "uint256", "name": "limit", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "amountCalculated", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/liquis/abis/ViewHelper.json b/src/adaptors/liquis/abis/ViewHelper.json new file mode 100644 index 0000000000..b41aa88e98 --- /dev/null +++ b/src/adaptors/liquis/abis/ViewHelper.json @@ -0,0 +1,647 @@ +[ + { + "inputs": [], + "name": "balancerVault", + "outputs": [ + { + "internalType": "contract IBalancerVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "convertLitToLiq", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_cvxCrvRewards", "type": "address" } + ], + "name": "getCvxCrvRewards", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "address", "name": "lptoken", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { "internalType": "address", "name": "stash", "type": "address" }, + { "internalType": "bool", "name": "shutdown", "type": "bool" }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "address", "name": "uniV3Pool", "type": "address" }, + { + "internalType": "address[]", + "name": "poolTokens", + "type": "address[]" + }, + { "internalType": "int24[]", "name": "ticks", "type": "int24[]" }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { + "internalType": "address", + "name": "rewardsToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + } + ], + "internalType": "struct LiquisViewHelpers.ExtraRewards[]", + "name": "extraRewards", + "type": "tuple[]" + } + ], + "internalType": "struct LiquisViewHelpers.Pool", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "pool", "type": "uint256" }, + { "internalType": "address", "name": "booster", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "getEarmarkingReward", + "outputs": [ + { "internalType": "uint256", "name": "pending", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_locker", "type": "address" } + ], + "name": "getLocker", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "epoch", "type": "uint256" }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lockedSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + } + ], + "internalType": "struct LiquisViewHelpers.Locker", + "name": "locker", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_locker", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getLockerAccount", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint256", "name": "total", "type": "uint256" }, + { + "internalType": "uint256", + "name": "unlockable", + "type": "uint256" + }, + { "internalType": "uint256", "name": "locked", "type": "uint256" }, + { + "internalType": "uint256", + "name": "nextUnlockIndex", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "rewardPerTokenPaid", + "type": "uint128" + }, + { "internalType": "uint128", "name": "rewards", "type": "uint128" }, + { "internalType": "address", "name": "delegate", "type": "address" }, + { "internalType": "uint256", "name": "votes", "type": "uint256" }, + { + "components": [ + { + "internalType": "uint112", + "name": "amount", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "unlockTime", + "type": "uint32" + } + ], + "internalType": "struct LiqLocker.LockedBalance[]", + "name": "lockData", + "type": "tuple[]" + }, + { + "components": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "internalType": "struct LiqLocker.EarnedData[]", + "name": "claimableRewards", + "type": "tuple[]" + } + ], + "internalType": "struct LiquisViewHelpers.LockerAccount", + "name": "lockerAccount", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "pools", "type": "uint256[]" }, + { "internalType": "address", "name": "booster", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "getMultipleEarmarkingRewards", + "outputs": [ + { "internalType": "uint256[]", "name": "pendings", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "lptoken", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { "internalType": "address", "name": "stash", "type": "address" }, + { "internalType": "bool", "name": "shutdown", "type": "bool" } + ], + "internalType": "struct IBooster.PoolInfo", + "name": "poolInfo", + "type": "tuple" + }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getPool", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "address", "name": "lptoken", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { "internalType": "address", "name": "stash", "type": "address" }, + { "internalType": "bool", "name": "shutdown", "type": "bool" }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "address", "name": "uniV3Pool", "type": "address" }, + { + "internalType": "address[]", + "name": "poolTokens", + "type": "address[]" + }, + { "internalType": "int24[]", "name": "ticks", "type": "int24[]" }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { + "internalType": "address", + "name": "rewardsToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + } + ], + "internalType": "struct LiquisViewHelpers.ExtraRewards[]", + "name": "extraRewards", + "type": "tuple[]" + } + ], + "internalType": "struct LiquisViewHelpers.Pool", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardPool", "type": "address" }, + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getPoolBalances", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "uint256", "name": "earned", "type": "uint256" }, + { + "internalType": "uint256[]", + "name": "extraRewardsEarned", + "type": "uint256[]" + }, + { "internalType": "uint256", "name": "staked", "type": "uint256" } + ], + "internalType": "struct LiquisViewHelpers.PoolBalances", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_booster", "type": "address" } + ], + "name": "getPools", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "address", "name": "lptoken", "type": "address" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { "internalType": "address", "name": "stash", "type": "address" }, + { "internalType": "bool", "name": "shutdown", "type": "bool" }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "address", "name": "uniV3Pool", "type": "address" }, + { + "internalType": "address[]", + "name": "poolTokens", + "type": "address[]" + }, + { "internalType": "int24[]", "name": "ticks", "type": "int24[]" }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { + "internalType": "address", + "name": "rewardsToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + } + ], + "internalType": "struct LiquisViewHelpers.RewardsData", + "name": "rewardsData", + "type": "tuple" + } + ], + "internalType": "struct LiquisViewHelpers.ExtraRewards[]", + "name": "extraRewards", + "type": "tuple[]" + } + ], + "internalType": "struct LiquisViewHelpers.Pool[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_booster", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getPoolsBalances", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "uint256", "name": "earned", "type": "uint256" }, + { + "internalType": "uint256[]", + "name": "extraRewardsEarned", + "type": "uint256[]" + }, + { "internalType": "uint256", "name": "staked", "type": "uint256" } + ], + "internalType": "struct LiquisViewHelpers.PoolBalances[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_addresses", "type": "address[]" } + ], + "name": "getTokens", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "addr", "type": "address" }, + { "internalType": "uint8", "name": "decimals", "type": "uint8" }, + { "internalType": "string", "name": "symbol", "type": "string" }, + { "internalType": "string", "name": "name", "type": "string" } + ], + "internalType": "struct LiquisViewHelpers.Token[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liq", + "outputs": [ + { + "internalType": "contract IERC20Detailed", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/liquis/abis/VirtualPool.json b/src/adaptors/liquis/abis/VirtualPool.json new file mode 100644 index 0000000000..31ede7aa03 --- /dev/null +++ b/src/adaptors/liquis/abis/VirtualPool.json @@ -0,0 +1,274 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "deposit_", "type": "address" }, + { "internalType": "address", "name": "reward_", "type": "address" }, + { "internalType": "address", "name": "op_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposits", + "outputs": [ + { "internalType": "contract IDeposit", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "epochRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "historicalRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newRewardRatio", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_rewards", "type": "uint256" } + ], + "name": "queueNewRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "queuedRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/liquis/index.js b/src/adaptors/liquis/index.js new file mode 100644 index 0000000000..6eb90f0b52 --- /dev/null +++ b/src/adaptors/liquis/index.js @@ -0,0 +1,696 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); + +const hub = '0xb5087f95643a9a4069471a28d32c569d9bd57fe4'; +const lens = '0xb73f303472c4fd4ff3b9f59ce0f9b13e47fbfd19'; +const zeroAddress = '0x0000000000000000000000000000000000000000'; +const weth = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const bal = '0xba100000625a3754423978a60c9317c58a424e3D'; + +const rewardPool = { + ethereum: '0x7Ea6930a9487ce8d039f7cC89432435E6D5AcB23', +}; + +const lit80weth20 = { + ethereum: '0x9232a548DD9E81BaC65500b5e0d918F8Ba93675C', +}; + +const voterProxy = { + ethereum: '0x37aeB332D6E57112f1BFE36923a7ee670Ee9278b', +}; + +const viewHelper = { + ethereum: '0xD58dd6deF2d0e8E16ffc537c7f269719e19b9fE4', +}; + +const booster = { + ethereum: '0x631e58246A88c3957763e1469cb52f93BC1dDCF2', +}; + +const admin = { + ethereum: '0x4cc39af0d46b0f66fd33778c6629a696bdc310a0', +}; + +const controller = { + ethereum: '0x901c8aa6a61f74ac95e7f397e22a0ac7c1242218', +}; + +const lit = { + ethereum: '0xfd0205066521550D7d7AB19DA8F72bb004b4C341', +}; + +const liq = { + ethereum: '0xD82fd4D6D62f89A1E50b1db69AD19932314aa408', +}; + +const veLit = { + ethereum: '0xf17d23136B4FeAd139f54fB766c8795faae09660', +}; + +const liqLIT = { + ethereum: '0x03C6F0Ca0363652398abfb08d154F114e61c4Ad8', +}; + +const olit = { + ethereum: '0x627fee87d0d9d2c55098a06ac805db8f98b158aa', +}; + +const oracle = { + ethereum: '0x9d43ccb1ad7e0081cc8a8f1fd54d16e54a637e30', +}; + +const balVirtualPool = { + ethereum: '0x85C0DB72927cf20896ED1332a14C4e2818C1ebA9', +}; + +const wethVirtualPool = { + ethereum: '0x271B96395f53fb14cDD41C654ef15e83DE57dEDf', +}; + +const litLiqStaker = { + ethereum: '0x7Ea6930a9487ce8d039f7cC89432435E6D5AcB23', +}; + +const hubABI = require('./abis/BunniHub.json'); +const lensABI = require('./abis/BunniLens.json'); +const adminABI = require('./abis/TokenAdmin.json'); +const gaugeABI = require('./abis/LiquidityGauge.json'); +const controllerABI = require('./abis/GaugeController.json'); +const oracleABI = require('./abis/OptionsOracle.json'); +const boosterABI = require('./abis/Booster.json'); +const viewHelperABI = require('./abis/ViewHelper.json'); +const virtualPoolABI = require('./abis/VirtualPool.json'); +const balancerTokenABI = require('./abis/BalancerToken.json'); +const vaultABI = require('./abis/Vault.json'); +const { default: bunni } = require('../bunni'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + 'HH4HFj4rFnm5qnkb8MbEdP2V5eD9rZnLJE921YQAs7AV' + ), +}; + +const query = gql` + { + bunniTokens(first: 1000, block: {number: }) { + address + liquidity + pool { + fee + tick + liquidity + totalFeesToken0 + totalFeesToken1 + totalVolumeToken0 + totalVolumeToken1 + } + } + } +`; + +const queryPrior = gql` + { + pools(first: 1000, block: {number: }) { + address + totalFeesToken0 + totalFeesToken1 + totalVolumeToken0 + totalVolumeToken1 + } + } +`; + +const apy = (apr, num_periods) => { + const periodic_rate = apr / num_periods / 100; + const apy = Math.pow(1 + periodic_rate, num_periods) - 1; + return apy * 100; +}; + +const liqLitPool = async (chain, olitprice, liqprice) => { + const keys = [weth, bal, lit[chain]] + .map((token) => `${chain}:${token}`) + .join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${keys}`) + ).body.coins; + const balPrice = prices[`${chain}:${bal}`]?.price; + const wethPrice = prices[`${chain}:${weth}`]?.price; + + // Compute tvl + let tvlUsd = 0; + const { output: veBalance } = await sdk.api.erc20.totalSupply({ + target: rewardPool[chain], + }); + const balancerToken = lit80weth20[chain]; + const owner = veLit[chain]; + const lpSupply = ( + await sdk.api.abi.call({ abi: 'erc20:totalSupply', target: balancerToken }) + )?.output; + const lpTokens = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: balancerToken, + params: owner, + }) + )?.output; + const poolId = ( + await sdk.api.abi.call({ + abi: balancerTokenABI.find((n) => n.name == 'getPoolId'), + target: balancerToken, + }) + )?.output; + const vault = ( + await sdk.api.abi.call({ + abi: balancerTokenABI.find((n) => n.name == 'getVault'), + target: balancerToken, + }) + )?.output; + const pools = ( + await sdk.api.abi.call({ + abi: vaultABI.find((n) => n.name == 'getPoolTokens'), + target: vault, + params: poolId, + }) + )?.output; + pools.tokens.forEach((v, i) => { + tvlUsd += + (pools.balances[i] / lpSupply) * + (veBalance / 1e18) * + prices[`${chain}:${v}`]?.price; + }); + + const balRate = ( + await sdk.api.abi.call({ + target: balVirtualPool[chain], + abi: virtualPoolABI.find((n) => n.name === 'rewardRate'), + chain: chain, + }) + )?.output; + const wethRate = ( + await sdk.api.abi.call({ + target: wethVirtualPool[chain], + abi: virtualPoolABI.find((n) => n.name === 'rewardRate'), + chain: chain, + }) + )?.output; + const olitRate = ( + await sdk.api.abi.call({ + target: litLiqStaker[chain], + abi: virtualPoolABI.find((n) => n.name === 'rewardRate'), + chain: chain, + }) + )?.output; + const liqrate = ( + await sdk.api.abi.call({ + target: viewHelper[chain], + abi: viewHelperABI.find((n) => n.name === 'convertLitToLiq'), + params: [olitRate], + chain: chain, + }) + )?.output; + + const balAmount = (balRate / 1e18) * 60 * 60 * 24 * 365; + const wethAmount = (wethRate / 1e18) * 60 * 60 * 24 * 365; + const olitAmount = (olitRate / 1e18) * 60 * 60 * 24 * 365; + const liqAmount = (liqrate / 1e18) * 60 * 60 * 24 * 365; + + const balUsd = balAmount * balPrice; + const wethUsd = wethAmount * wethPrice; + const olitUsd = olitAmount * olitprice; + const liqUsd = liqAmount * liqprice; + + const apyBase = (balUsd / tvlUsd + wethUsd / tvlUsd) * 100; + const apyReward = (liqUsd / tvlUsd + olitUsd / tvlUsd) * 100; + + return { + pool: liqLIT[chain], + chain: utils.formatChain(chain), + project: 'liquis', + symbol: 'LIQLIT', + tvlUsd, + apyBase, + apyReward, + rewardTokens: [liq[chain], lit[chain]], + underlyingTokens: [lit[chain], weth], + url: `https://www.liquis.app/liqlit`, + }; +}; + +const topLvl = async (chainString, url, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + let [ + dataNowSubgraph, + dataNow, + dataPriorSubgraph, + dataPrior, + { output: protocolFee }, + { output: inflationRate }, + { output: multiplier }, + ] = await Promise.all([ + request(url, query.replace('', block)), + sdk.api.abi.call({ + target: viewHelper[chainString], + abi: viewHelperABI.find((n) => n.name === 'getPools'), + params: [booster[chainString]], + chain: chainString, + block, + }), + request(url, queryPrior.replace('', blockPrior)), + sdk.api.abi.call({ + target: viewHelper[chainString], + abi: viewHelperABI.find((n) => n.name === 'getPools'), + params: [booster[chainString]], + chain: chainString, + block: blockPrior, + }), + sdk.api.abi.call({ + target: hub, + abi: hubABI.find((n) => n.name === 'protocolFee'), + chain: chainString, + }), + + admin[chainString] && + sdk.api.abi.call({ + target: admin[chainString], + abi: adminABI.find((n) => n.name === 'rate'), + chain: chainString, + }), + oracle[chainString] && + sdk.api.abi.call({ + target: oracle[chainString], + abi: oracleABI.find((n) => n.name === 'multiplier'), + chain: chainString, + }), + ]); + + dataNow = dataNow.output.map((b) => ({ + ...b, + ...dataNowSubgraph.bunniTokens.find( + (t) => t.address.toLowerCase() === b.lptoken.toLowerCase() + ), + })); + dataPrior = dataPrior.output.map((b) => ({ + ...b, + ...dataPriorSubgraph.pools.find( + (p) => p.address.toLowerCase() === b.uniV3Pool.toLowerCase() + ), + })); + + dataNow = dataNow + .filter((b) => !b.shutdown) + .filter((b) => b.token != liqLIT[chainString]); + dataPrior = dataPrior + .filter((b) => !b.shutdown) + .filter((b) => b.token != liqLIT[chainString]); + + protocolFee = protocolFee / 1e18; + inflationRate = inflationRate ? inflationRate / 1e18 : null; + multiplier = multiplier ? multiplier / 10000 : null; + + // create a list of unique tokens + let tokens = dataNow.reduce((tokens, b) => { + if (!tokens.includes(b.poolTokens[0])) tokens.push(b.poolTokens[0]); + if (!tokens.includes(b.poolTokens[1])) tokens.push(b.poolTokens[1]); + return tokens; + }, []); + + // add LIT to the token list (used for calculating oLIT price) + if (lit[chainString] && !tokens.includes(lit[chainString])) + tokens.push(lit[chainString]); + + // add LIQ to the token list + if (liq[chainString] && !tokens.includes(liq[chainString])) + tokens.push(liq[chainString]); + + // create of list of gauges + const gauges = dataNow.reduce((gauges, b) => { + if (b.gauge) gauges.push(b.gauge); + return gauges; + }, []); + + const week = 604800 * 1000; + const this_period_timestamp = (Math.floor(Date.now() / week) * week) / 1000; + + const [ + { output: veLITBalance }, + { output: veLITotalSupply }, + { output: tokenSymbols }, + { output: tokenDecimals }, + { output: poolTotalSupplies }, + { output: reserves }, + { output: shares }, + { output: gaugesWorkingSupply }, + { output: gaugesTotalSupply }, + { output: gaugesWorkingBalance }, + { output: gaugesUserLiquidity }, + { output: gaugesTokenlessProduction }, + { output: gaugesIsKilled }, + { output: gaugesRelativeWeight }, + { output: gaugesExists }, + ] = await Promise.all([ + sdk.api.abi.call({ + target: veLit[chainString], + abi: 'erc20:balanceOf', + params: [voterProxy[chainString]], + chain: chainString, + }), + sdk.api.abi.call({ + target: veLit[chainString], + abi: 'erc20:totalSupply', + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((token) => ({ target: token })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((token) => ({ target: token })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: dataNow.map((token) => ({ target: token.lptoken })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: lensABI.find((n) => n.name === 'getReserves'), + target: lens, + calls: dataNow.map((b) => ({ + params: [ + { pool: b.uniV3Pool, tickLower: b.ticks[0], tickUpper: b.ticks[1] }, + ], + })), + chain: chainString, + }), + sdk.api.abi.multiCall({ + abi: lensABI.find((n) => n.name === 'pricePerFullShare'), + target: lens, + calls: dataNow.map((b) => ({ + params: [ + { pool: b.uniV3Pool, tickLower: b.ticks[0], tickUpper: b.ticks[1] }, + ], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'working_supply'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'totalSupply'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'working_balances'), + calls: gauges.map((gauge) => ({ + target: gauge, + params: [voterProxy[chainString]], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'balanceOf'), + calls: gauges.map((gauge) => ({ + target: gauge, + params: [voterProxy[chainString]], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'tokenless_production'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'is_killed'), + calls: gauges.map((gauge) => ({ target: gauge })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: gaugeABI.find((n) => n.name === 'getCappedRelativeWeight'), + calls: gauges.map((gauge) => ({ + target: gauge, + params: [this_period_timestamp], + })), + chain: chainString, + }), + gauges.length && + sdk.api.abi.multiCall({ + abi: controllerABI.find((n) => n.name === 'gauge_exists'), + target: controller[chainString], + calls: gauges.map((gauge) => ({ params: [gauge] })), + chain: chainString, + }), + ]); + + // fetch token prices + const keys = tokens.map((token) => `${chainString}:${token}`).join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${keys}`) + ).body.coins; + + // calculate the price of oLIT + let optionPrice = 0; + if (lit[chainString]) { + const litPrice = prices[`${chainString}:${lit[chainString]}`] + ? prices[`${chainString}:${lit[chainString]}`]?.price + : 0; + optionPrice = litPrice * multiplier; + } + + const liqPrice = prices[`${chainString}:${liq[chainString]}`] + ? prices[`${chainString}:${liq[chainString]}`]?.price + : 0; + + let poolData = []; + poolData.push(liqLitPool(chainString, optionPrice, liqPrice)); + poolData = poolData.concat( + dataNow.map(async (b) => { + // reserve info + const reserve = reserves.find( + (r) => + r.input.params[0].pool == b.uniV3Pool && + r.input.params[0].tickLower == b.ticks[0] && + r.input.params[0].tickUpper == b.ticks[1] + ).output; + + // share info + const share = shares.find( + (s) => + s.input.params[0].pool == b.uniV3Pool && + s.input.params[0].tickLower == b.ticks[0] && + s.input.params[0].tickUpper == b.ticks[1] + ).output; + + // token0 info + const token0Decimals = tokenDecimals.find( + (d) => d.input.target == b.poolTokens[0] + ).output; + const token0Price = prices[`${chainString}:${b.poolTokens[0]}`] + ? prices[`${chainString}:${b.poolTokens[0]}`]?.price + : 0; + const token0Redeem = share.amount0 / Math.pow(10, token0Decimals); + const token0Reserve = reserve.reserve0 / Math.pow(10, token0Decimals); + const token0Symbol = tokenSymbols.find( + (s) => s.input.target == b.poolTokens[0] + ).output; + + // token1 info + const token1Decimals = tokenDecimals.find( + (d) => d.input.target == b.poolTokens[1] + ).output; + const token1Price = prices[`${chainString}:${b.poolTokens[1]}`] + ? prices[`${chainString}:${b.poolTokens[1]}`]?.price + : 0; + const token1Redeem = share.amount1 / Math.pow(10, token1Decimals); + const token1Reserve = reserve.reserve1 / Math.pow(10, token1Decimals); + const token1Symbol = tokenSymbols.find( + (s) => s.input.target == b.poolTokens[1] + ).output; + + // calculate swap fee apr + let baseApr = 0; + + const tickLower = parseInt(b.ticks[0]); + const tickUpper = parseInt(b.ticks[1]); + const tick = parseInt(b.pool.tick); + const poolTotalSupply = poolTotalSupplies.find( + (t) => t.input.target == b.lptoken + ).output; + let tvl = + poolTotalSupply == 0 + ? 0 + : (token0Reserve * token0Price + token1Reserve * token1Price) * + (b.totalSupply / b.liquidity); + + if (b.pool.liquidity > 0 && tickLower <= tick && tick <= tickUpper) { + const prior = dataPrior.find( + (d) => d.address.toLowerCase() === b.uniV3Pool.toLowerCase() + ); + + if (prior) { + const fee0 = + ((b.pool.totalFeesToken0 - prior.totalFeesToken0) / + Math.pow(10, token0Decimals)) * + token0Price; + const fee1 = + ((b.pool.totalFeesToken1 - prior.totalFeesToken1) / + Math.pow(10, token1Decimals)) * + token1Price; + const fee = Math.min(fee0, fee1) * 365; + + baseApr = + ((fee * parseInt(b.liquidity)) / + parseInt(b.pool.liquidity) / + (token0Reserve * token0Price + token1Reserve * token1Price)) * + (1 - protocolFee) * + 100; + } + } + + // calculate reward apr + let rewardApr = null; + let rewardTokens = null; + + if (b.gauge) { + const exists = gaugesExists.find( + (g) => g.input.params[0].toLowerCase() == b.gauge.toLowerCase() + )?.output; + const killed = gaugesIsKilled.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output; + + // we only care about gauges that have been whitelisted and have not been killed + if (exists && !killed) { + const relativeWeight = + gaugesRelativeWeight.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const tokenlessProduction = + gaugesTokenlessProduction.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const workingSupply = + gaugesWorkingSupply.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const workingBalance = + gaugesWorkingBalance.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const totalSupply = + gaugesTotalSupply.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const userLiquidity = + gaugesUserLiquidity.find( + (g) => g.input.target.toLowerCase() == b.gauge.toLowerCase() + )?.output / 1e18; + const veLitBalance = veLITBalance / 1e18; + const veLitTotalSupply = veLITotalSupply / 1e18; + const relativeInflation = inflationRate * relativeWeight; + + // we only care about gauges that receive rewards (ie those that receive votes) + if (relativeInflation > 0 && workingBalance > 0) { + const t = tokenlessProduction / 100; + const T = 1 - t; + const l = userLiquidity; + const L = + (b.liquidity / 1e18) * (veLitBalance / veLitTotalSupply); + const working_balance = Math.min(t * l + T * L, l); + + // calculate the working supply + const working_ratio = workingSupply / totalSupply; + const new_total_liquidity = b.liquidity / 1e18 - totalSupply; + const new_working_supply = working_ratio * new_total_liquidity; + + const working_supply = + workingSupply + + new_working_supply - + workingBalance + + working_balance; + if (working_supply > 0) { + const bunniPrice = + token0Redeem * token0Price + token1Redeem * token1Price; + + const userSupplyUsd = userLiquidity * bunniPrice; + const userAnnualReward = + ((relativeInflation * 86400 * 365) / working_supply) * + working_balance; + const userAnnualRewardUSD = userAnnualReward * optionPrice; + + const userAnnualLiqReward = ( + await sdk.api.abi.call({ + target: viewHelper[chainString], + abi: viewHelperABI.find( + (n) => n.name === 'convertLitToLiq' + ), + params: [(userAnnualReward * 0.75).toFixed(0)], + chain: chainString, + }) + )?.output; + const userAnnualLiqRewardUSD = userAnnualLiqReward * liqPrice; + + rewardApr = + (userAnnualRewardUSD / userSupplyUsd) * 100 * 0.75 + + (userAnnualLiqRewardUSD / userSupplyUsd) * 100; + rewardTokens = [lit[chainString], liq[chainString]]; + } + } + } + } + + return { + pool: b.token, + chain: utils.formatChain(chainString), + project: 'liquis', + symbol: `${token0Symbol}-${token1Symbol}`, + tvlUsd: tvl, + apyBase: apy(baseApr, 365), + ...(rewardApr && { apyReward: rewardApr }), + ...(rewardTokens && { rewardTokens: rewardTokens }), + underlyingTokens: [b.poolTokens[0], b.poolTokens[1]], + poolMeta: `${parseInt(b.pool.fee) / 10000}%`, + url: `https://www.liquis.app/stake/${b.crvRewards}`, + }; + }) + ); + + poolData = await Promise.all(poolData); + return poolData; + } catch (e) { + console.log(e); + return []; + } +}; + +const main = async (timestamp = null) => { + const data = []; + for (const [chain, url] of Object.entries(chains)) { + data.push(await topLvl(chain, url, timestamp)); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: `https://www.liquis.app/stake`, +}; diff --git a/src/adaptors/liquity-v1/index.js b/src/adaptors/liquity-v1/index.js new file mode 100644 index 0000000000..bd909ce451 --- /dev/null +++ b/src/adaptors/liquity-v1/index.js @@ -0,0 +1,85 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const TROVE_MANAGER_ADDRESS = '0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2'; +const LUSD_ADDRESS = '0x5f98805A4E8be255a32880FDeC7F6728C6568bA0'; +const URL = 'https://api.instadapp.io/defi/mainnet/liquity/trove-types'; + +const ABIS = { + getEntireSystemColl: { + inputs: [], + name: 'getEntireSystemColl', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemColl', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [], + name: 'MCR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; +const main = async () => { + const troveEthTvl = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getEntireSystemColl, + chain: 'ethereum', + }) + ).output; + + const mcr = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getMCR, + chain: 'ethereum', + }) + ).output; + + const troveType = (await superagent.get(URL)).body; + + const lusdTotalSupply = ( + await sdk.api.abi.call({ + target: LUSD_ADDRESS, + abi: 'erc20:totalSupply', + chain: 'ethereum', + }) + ).output; + + const key = `ethereum:${LUSD_ADDRESS}`.toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + + const totalSupplyUsd = (Number(lusdTotalSupply) / 1e18) * prices[key].price; + + return [ + { + pool: TROVE_MANAGER_ADDRESS, + project: 'liquity-v1', + symbol: 'ETH', + chain: 'ethereum', + apy: 0, + tvlUsd: (Number(troveEthTvl) / 1e18) * Number(troveType.price), + apyBaseBorrow: Number(troveType.borrowFee) * 100, + totalSupplyUsd: (Number(troveEthTvl) / 1e18) * Number(troveType.price), + totalBorrowUsd: totalSupplyUsd, + ltv: 1 / (mcr / 1e18), + mintedCoin: 'LUSD', + underlyingTokens: ['0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.liquity.org/', +}; diff --git a/src/adaptors/liquity-v2/index.js b/src/adaptors/liquity-v2/index.js new file mode 100644 index 0000000000..36c317f8a3 --- /dev/null +++ b/src/adaptors/liquity-v2/index.js @@ -0,0 +1,506 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { ethers } = require('ethers'); +const { length } = require('../agave/abiIncentivesController'); + +const BOLD_TOKEN = '0x6440f144b7e50d6a8439336510312d2f54beb01d'; +const DAY_IN_SECONDS = 24 * 60 * 60; + +const WETH_BRANCH = { + activePool: '0xeb5a8c825582965f1d84606e078620a84ab16afe', + defaultPool: '0xd4558240d50c2e219a21c9d25afd513bb6e5b1a0', + stabilityPool: '0x5721cbbd64fc7ae3ef44a0a3f9a790a9264cf9bf', + borrowerOperations: '0x0b995602b5a797823f92027e8b40c0f2d97aff1c', + troveManager: '0x7bcb64b2c9206a5b699ed43363f6f98d4776cf5a', + collToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'.toLowerCase(), + symbol: 'ETH' +} + +const WSTETH_BRANCH = { + activePool: '0x531a8f99c70d6a56a7cee02d6b4281650d7919a0', + defaultPool: '0xd796e1648526400386cc4d12fa05e5f11e6a22a1', + stabilityPool: '0x9502b7c397e9aa22fe9db7ef7daf21cd2aebe56b', + borrowerOperations: '0x94c1610a7373919bd9cfb09ded19894601f4a1be', + troveManager: '0xa2895d6a3bf110561dfe4b71ca539d84e1928b22', + collToken: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0'.toLowerCase(), + symbol: 'WSTETH' +} + +const RETH_BRANCH = { + activePool: '0x9074d72cc82dad1e13e454755aa8f144c479532f', + defaultPool: '0x5cc5cefd034fdc4728d487a72ca58a410cddcd6b', + stabilityPool: '0xd442e41019b7f5c4dd78f50dc03726c446148695', + borrowerOperations: '0xa351d5b9cda9eb518727c3ceff02208915fda60d', + troveManager: '0xb2b2abeb5c357a234363ff5d180912d319e3e19e', + collToken: '0xae78736cd615f374d3085123a210448e74fc6393'.toLowerCase(), + symbol: 'RETH' +} + +const branches = [WETH_BRANCH, WSTETH_BRANCH, RETH_BRANCH]; + +const SP_YIELD_SPLIT = 0.75; + +const toNumber = (value) => Number(ethers.utils.formatUnits(value, 18)); + +const STABILITY_POOL_BALANCE_TOPIC = ethers.utils.id( + 'StabilityPoolBoldBalanceUpdated(uint256)' +); +const LIQUIDATION_TOPIC = ethers.utils.id( + 'Liquidation(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)' +); +const LIQUIDATION_EVENT_TYPES = [ + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', + 'uint256', +]; + +const getBlockWindow = async () => { + const latestBlock = await sdk.api.util.getLatestBlock('ethereum'); + const startTimestamp = latestBlock.timestamp - DAY_IN_SECONDS; + const startBlock = await sdk.api.util.lookupBlock(startTimestamp, { chain: 'ethereum' }); + + return { + endBlock: latestBlock.number, + startBlock: startBlock.number, + }; +}; + +const ABIS = { + getTotalBoldDeposits: { + inputs: [], + name: 'getTotalBoldDeposits', + outputs: [ + { + internalType: 'uint256', + name: 'totalBoldDeposits', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getCollBalance: { + inputs: [], + name: 'getCollBalance', + outputs: [ + { + internalType: 'uint256', + name: 'collBalance', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getBoldDebt: { + inputs: [], + name: 'getBoldDebt', + outputs: [ + { + internalType: 'uint256', + name: 'boldDebt', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [], + name: 'MCR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getNewApproxAvgInterestRateFromTroveChange: { + inputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'appliedRedistBoldDebtGain', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'appliedRedistCollGain', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collIncrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collDecrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtIncrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtDecrease', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'newWeightedRecordedDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oldWeightedRecordedDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'upfrontFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'batchAccruedManagementFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'newWeightedRecordedBatchManagementFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'oldWeightedRecordedBatchManagementFee', + type: 'uint256', + }, + ], + internalType: 'struct TroveChange', + name: '_troveChange', + type: 'tuple', + }, + ], + name: 'getNewApproxAvgInterestRateFromTroveChange', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + } + }; + + const getStabilityPoolDepositsAtBlock = async (stabilityPoolAddr, blockNumber) => { + const res = await sdk.api.abi.call({ + target: stabilityPoolAddr, + abi: ABIS.getTotalBoldDeposits, + block: blockNumber, + chain: 'ethereum', + }); + + return toNumber(res.output); + }; + + const getStabilityPoolBalanceUpdates = async (stabilityPoolAddr, startBlock, endBlock) => { + const logs = ( + await sdk.api.util.getLogs({ + target: stabilityPoolAddr, + fromBlock: startBlock, + toBlock: endBlock, + topics: [STABILITY_POOL_BALANCE_TOPIC], + keys: [], + chain: 'ethereum', + }) + ).output; + + return logs + .map((log) => ({ + blockNumber: Number(log.blockNumber), + logIndex: Number(log.logIndex), + balance: toNumber(log.data), + transactionHash: log.transactionHash, + })) + .sort( + (a, b) => + a.blockNumber - b.blockNumber || a.logIndex - b.logIndex + ); + }; + + const getLiquidationEvents = async (troveManagerAddr, startBlock, endBlock) => { + const logs = ( + await sdk.api.util.getLogs({ + target: troveManagerAddr, + fromBlock: startBlock, + toBlock: endBlock, + topics: [LIQUIDATION_TOPIC], + keys: [], + chain: 'ethereum', + }) + ).output; + + return logs + .map((log) => { + const decoded = ethers.utils.defaultAbiCoder.decode(LIQUIDATION_EVENT_TYPES, log.data); + + return { + blockNumber: Number(log.blockNumber), + logIndex: Number(log.logIndex), + transactionHash: log.transactionHash, + debtOffsetBySP: toNumber(decoded[0]), + collSentToSP: toNumber(decoded[4]), + price: toNumber(decoded[9]), + }; + }) + .sort( + (a, b) => + a.blockNumber - b.blockNumber || a.logIndex - b.logIndex + ); + }; + + const isBeforeLog = (a, b) => + a.blockNumber < b.blockNumber || + (a.blockNumber === b.blockNumber && a.logIndex < b.logIndex); + + const calculateLiquidationApyForBranch = async ( + branch, + blockWindow, + boldPrice + ) => { + // Skip until TroveManager addresses are populated. + if (!branch.troveManager || branch.troveManager === '0x0000000000000000000000000000000000000000') { + return 0; + } + + // Fetch all liquidations for the branch in the past 24h. + const liquidations = await getLiquidationEvents( + branch.troveManager, + blockWindow.startBlock, + blockWindow.endBlock + ); + + if (!liquidations.length) return 0; + + // Seed the stability pool balance at the start block and gather later balance updates. + const [startBalance, balanceUpdates] = await Promise.all([ + getStabilityPoolDepositsAtBlock(branch.stabilityPool, blockWindow.startBlock), + getStabilityPoolBalanceUpdates(branch.stabilityPool, blockWindow.startBlock, blockWindow.endBlock), + ]); + + let currentBalance = startBalance; + let balanceIdx = 0; + let dailyReturn = 0; + + const advanceBalance = (target) => { + while ( + balanceIdx < balanceUpdates.length && + isBeforeLog(balanceUpdates[balanceIdx], target) + ) { + currentBalance = balanceUpdates[balanceIdx].balance; + balanceIdx++; + } + }; + + for (const liquidation of liquidations) { + advanceBalance(liquidation); + + // Only process liquidations if there was SP liquidity at that instant + if (currentBalance === 0) continue; + + // Net liquidation gain is collateral sent minus BOLD burned, expressed in USD + const collateralValueUsd = liquidation.collSentToSP * liquidation.price; + const rewardUsd = + collateralValueUsd - liquidation.debtOffsetBySP * boldPrice; + + if (rewardUsd <= 0) continue; + + // Denominator is the SP deposits present just before the liquidation + const depositsUsd = currentBalance * boldPrice; + if (depositsUsd <= 0) continue; + + dailyReturn += rewardUsd / depositsUsd; + } + + // Convert daily return to percentage yearly return + return dailyReturn * 100 * 365; + }; + + const getSPSupplyAndApy = async (spAddr, avgBranchInterestRate, branchBoldSupply) => { + let spSupply = (await sdk.api.abi.call({ + target: spAddr, + abi: ABIS.getTotalBoldDeposits, + chain: 'ethereum', + })).output / 1e18; + + + if (spSupply === 0) return [0, 0] + + // Yield is the branch interest rate amplifyed by ratio of branch supply to the BOLD in the SP + const spApy = avgBranchInterestRate * SP_YIELD_SPLIT * branchBoldSupply / spSupply; + + return [spSupply, spApy]; + } + + const getPrices = async (addresses) => { + const req = addresses.map((address) => `ethereum:${address}`).join(',').toLowerCase(); + const prices = (await superagent.get(`https://coins.llama.fi/prices/current/${req}`)).body.coins; + + const pricesObj = Object.fromEntries( + Object.entries(prices).map(([address, priceData]) => [address.split(':')[1].toLowerCase(), priceData.price]) + ); + + return pricesObj; + } + + const getBranchColl = async (collPools) => { + const results = await sdk.api.abi.multiCall({ + calls: collPools.map((poolAddr) => ({ + target: poolAddr, + params: [], + })), + abi: ABIS.getCollBalance, + chain: 'ethereum', + }); + + const totalColl = results.output.map(x => Number(x.output)).reduce((a, b) => a + b); + return totalColl / 1e18; + } + + const getBranchDebt = async (debtPools) => { + const results = await sdk.api.abi.multiCall({ + calls: debtPools.map((poolAddr) => ({ + target: poolAddr, + params: [], + })), + abi: ABIS.getBoldDebt, + chain: 'ethereum', + }); + + const totalDebt = results.output.map(x => Number(x.output)).reduce((a, b) => a + b); + return totalDebt / 1e18; + } + + const getLTV = async (borrowerOpsAddr) =>{ + const res = (await sdk.api.abi.call({ + target: borrowerOpsAddr, + abi: ABIS.getMCR, + chain: 'ethereum', + }) + ); + + return 1 / (res.output / 1e18); + } + const getNewApproxAvgInterestRateFromTroveChange = async(activePoolAddr) => { + const res = await sdk.api.abi.call({ + target: activePoolAddr, + abi: ABIS.getNewApproxAvgInterestRateFromTroveChange, + params: [ + [0, // appliedRedistBoldDebtGain + 0, // appliedRedistCollGain + 0, // collIncrease + 0, // collDecrease + 0, // debtIncrease + 0, // debtDecrease + 0, // newWeightedRecordedDebt + 0, // oldWeightedRecordedDebt + 0, // upfrontFee + 0, // batchAccruedManagementFee + 0, // newWeightedRecordedBatchManagementFee + 0] // oldWeightedRecordedBatchManagementFee + ], + chain: 'ethereum', + }); + + // convert from 18 decimals and make percentage + return res.output / 1e16; + } + + const main = async () => { + const prices = await getPrices( + [WETH_BRANCH.collToken, + WSTETH_BRANCH.collToken, + RETH_BRANCH.collToken, + BOLD_TOKEN + ] + ); + + WETH_BRANCH.price = prices[WETH_BRANCH.collToken]; + WSTETH_BRANCH.price = prices[WSTETH_BRANCH.collToken]; + RETH_BRANCH.price = prices[RETH_BRANCH.collToken]; + + const pools = []; + const blockWindow = await getBlockWindow(); + const boldPrice = prices[BOLD_TOKEN] ?? 1; + + for (const branch of branches) { + const collPools = [branch.activePool, branch.defaultPool]; + + const totalColl = await getBranchColl(collPools); + const totalCollUsd = totalColl * branch.price + + const ltv = await getLTV(branch.borrowerOperations); + const borrowApy = await getNewApproxAvgInterestRateFromTroveChange(branch.activePool); + + const totalDebt = await getBranchDebt(collPools); + const totalDebtUsd = totalDebt * prices[BOLD_TOKEN]; + + const [spSupply, spApy] = await getSPSupplyAndApy(branch.stabilityPool, borrowApy, totalDebt); + const spSupplyUsd = spSupply * prices[BOLD_TOKEN]; + const liquidationApy = await calculateLiquidationApyForBranch( + branch, + blockWindow, + boldPrice + ); + const totalSpApy = spApy + liquidationApy; + + const spPool = + { + pool: branch.stabilityPool, + project: 'liquity-v2', + symbol: 'BOLD', + chain: 'ethereum', + apy: totalSpApy, + tvlUsd: spSupplyUsd, + underlyingTokens: [BOLD_TOKEN], + rewardTokens: [BOLD_TOKEN, branch.collToken], + poolMeta: `BOLD deposited in the ${branch.symbol} Stability Pool earns continuous BOLD yield and periodic ${branch.symbol} rewards from Trove liquidations` + } + + const borrowPool = + { + pool: branch.activePool, + project: 'liquity-v2', + symbol: branch.symbol, + chain: 'ethereum', + apy: 0, + tvlUsd: totalCollUsd, + apyBaseBorrow: borrowApy, + totalSupplyUsd: totalCollUsd, + totalBorrowUsd: totalDebtUsd, + ltv: ltv, + mintedCoin: 'BOLD', + underlyingTokens: [branch.collToken], + } + + pools.push(spPool, borrowPool); + }; + + return pools; + } + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.liquity.org/', +}; diff --git a/src/adaptors/liqwid/index.js b/src/adaptors/liqwid/index.js new file mode 100644 index 0000000000..a1ac497360 --- /dev/null +++ b/src/adaptors/liqwid/index.js @@ -0,0 +1,74 @@ +const { request, gql } = require('graphql-request'); +const fetch = require('node-fetch'); + +const apy = async () => { + const endpoint = 'https://v2.api.liqwid.finance/graphql'; + + const query = gql` + query { + liqwid { + data { + markets (input: { perPage: 100 }) { + page + results { + id + supplyAPY + supply + liquidity + lqSupplyAPY + borrowAPY + borrow + utilization + asset { + price + } + registry { + actionScriptHash + } + } + } + } + } + } + `; + + const data = await request(endpoint, query); + + // These are the markets that are either disabled or not borrowable, so no yield can be generated + const disableMarkets = ['AGIX', 'WMT', 'POL', 'LQ']; + + const markets = data.liqwid.data.markets.results.filter( + (market) => !disableMarkets.includes(market.id) + ); + + const getPool = (market) => { + return { + pool: market.registry.actionScriptHash, + chain: 'Cardano', + project: 'liqwid', + symbol: market.id, + tvlUsd: market.liquidity * market.asset.price, + apyReward: + market.lqSupplyAPY * 100 > 100 + ? market.lqSupplyAPY + : market.lqSupplyAPY * 100, + apyBase: market.supplyAPY * 100, + rewardTokens: [market.id, 'LQ'], + underlyingTokens: [market.id], + apyBaseBorrow: + market.borrowAPY * 100 > 100 + ? market.borrowAPY + : market.borrowAPY * 100, + totalSupplyUsd: market.supply * market.asset.price, + totalBorrowUsd: market.borrow * market.asset.price, + }; + }; + + return markets.map(getPool).filter((i) => i.pool !== undefined); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://v2.liqwid.finance/', +}; diff --git a/src/adaptors/lista-cdp/config.js b/src/adaptors/lista-cdp/config.js new file mode 100644 index 0000000000..71bff5519d --- /dev/null +++ b/src/adaptors/lista-cdp/config.js @@ -0,0 +1,91 @@ +const toByte32 = (str) => { + const hex = Buffer.from(str).toString('hex'); + return '0x' + hex.padEnd(64, '0'); +}; + +const getIlks = (collateral) => { + // Use custom ilkName if provided, otherwise generate from symbol + return toByte32(collateral.ilkName || collateral.symbol); +}; + +module.exports = { + collateralList: [ + { + symbol: 'BNB', + address: '0x92D8c63E893685Cced567b23916a8726b0CEF3FE', + ilkName: 'ceABNBc', + }, + { + symbol: 'ETH', + address: '0x6C813D1d114d0caBf3F82f9E910BC29fE7f96451', + ilkName: 'cewBETH', + }, + { + symbol: 'slisBNB', + address: '0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B', + ilkName: 'SnBNB', + }, + { + symbol: 'BTCB', + address: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + }, + { + symbol: 'wBETH', + address: '0xa2E3356610840701BDf5611a53974510Ae27E2e1', + }, + { + symbol: 'weETH', + address: '0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A', + }, + { + symbol: 'solvBTC', + address: '0x4aae823a6a0b376De6A78e74eCC5b079d38cBCf7', + }, + { + symbol: 'SolvBTC.BBN', + address: '0x1346b618dC92810EC74163e4c27004c921D446a5', + }, + { + symbol: 'STONE', + address: '0x80137510979822322193fc997d400d5a6c747bf7', + }, + { + symbol: 'sUSDX', + address: '0x7788A3538C5fc7F9c7C8A74EAC4c898fC8d87d92', + }, + { + symbol: 'pumpBTC', + address: '0xc6F28a668b7c18F921ccBA4adc3D8db72BFF0FE2', + originAddress: '0xf9C4FF105803A77eCB5DAE300871Ad76c2794fa4', + ilkName: 'cePumpBTC', + }, + { + symbol: 'wstETH', + address: '0x26c5e01524d2E6280A48F2c50fF6De7e52E9611C', + }, + { + symbol: 'USDT', + address: '0x55d398326f99059fF775485246999027B3197955', + }, + { + symbol: 'FDUSD', + address: '0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409', + }, + { + symbol: 'mBTC', + address: '0x4510aa2b3efd13bBFD78C9BfdE764F224ecc7f50', + ilkName: 'cemBTC', + originAddress: '0x7c1cca5b25fa0bc9af9275fb53cba89dc172b878', + }, + { + symbol: 'mCAKE', + address: '0x581fa684d0ec11ccb46b1d92f1f24c8a3f95c0ca', + ilkName: 'mCAKE', + }, + { + symbol: 'mwBETH', + address: '0x7dc91cbd6cb5a3e6a95eed713aa6bf1d987146c8', + }, + ], + getIlks, +}; diff --git a/src/adaptors/lista-cdp/index.js b/src/adaptors/lista-cdp/index.js new file mode 100644 index 0000000000..488d5c781a --- /dev/null +++ b/src/adaptors/lista-cdp/index.js @@ -0,0 +1,258 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { collateralList, getIlks } = require('./config'); + +// under src/adaptors, run `npm run test --adapter=lisusd` to test the adaptor +const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; +const RAY = new BigNumber(10).pow(27); + +const INTERACTION = { + address: '0xB68443Ee3e828baD1526b3e0Bdf2Dfc6b1975ec4', + abis: { + depositTVL: { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'depositTVL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getNextDuty: { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'getNextDuty', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + collateralTVL: { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'collateralTVL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + collateralRate: { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'collateralRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const DYNAMIC_DUTY_CALCULATOR = { + address: '0x873339A8214657175D9B128dDd57A2f2c23256FA', + abis: { + maxDuty: { + inputs: [], + name: 'maxDuty', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + minDuty: { + inputs: [], + name: 'minDuty', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const JUG = { + address: '0x787BdEaa29A253e40feB35026c3d05C18CbCA7B3', + abis: { + ilks: { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'ilks', + outputs: [ + { internalType: 'uint256', name: 'duty', type: 'uint256' }, + { internalType: 'uint256', name: 'rho', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const VAT = { + address: '0x33A34eAB3ee892D40420507B820347b1cA2201c4', + abis: { + ilks: { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'ilks', + outputs: [ + { internalType: 'uint256', name: 'Art', type: 'uint256' }, + { internalType: 'uint256', name: 'rate', type: 'uint256' }, + { internalType: 'uint256', name: 'spot', type: 'uint256' }, + { internalType: 'uint256', name: 'line', type: 'uint256' }, + { internalType: 'uint256', name: 'dust', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const calcApr = async (collateralAddress) => { + try { + // Get max and min duty rates + const [maxDutyResponse, minDutyResponse] = await Promise.all([ + sdk.api.abi.call({ + target: DYNAMIC_DUTY_CALCULATOR.address, + abi: DYNAMIC_DUTY_CALCULATOR.abis.maxDuty, + chain: 'bsc', + }), + sdk.api.abi.call({ + target: DYNAMIC_DUTY_CALCULATOR.address, + abi: DYNAMIC_DUTY_CALCULATOR.abis.minDuty, + chain: 'bsc', + }), + ]); + + // Get current duty rate using ilk name + const ilkHash = getIlks(collateralAddress); + const jugResponse = await sdk.api.abi.call({ + target: JUG.address, + params: [ilkHash], + abi: JUG.abis.ilks, + chain: 'bsc', + }); + + let _duty = Number(jugResponse.output[0].toString()); + const _maxDuty = Number(maxDutyResponse.output.toString()); + const _minDuty = Number(minDutyResponse.output.toString()); + + console.log('Raw values:'); + console.log('duty:', _duty); + console.log('maxDuty:', _maxDuty); + console.log('minDuty:', _minDuty); + + // Apply min/max constraints + if (_maxDuty != null && _duty >= _maxDuty) { + _duty = _maxDuty; + } + if (_minDuty != null && _duty <= _minDuty) { + _duty = _minDuty; + } + + // Calculate APR + const result = (_duty / 1e27) ** (365 * 24 * 3600) - 1; + + console.log('Final APR:', result * 100); + + return result * 100; // Convert to percentage + } catch (error) { + console.error('Error calculating APR:', error); + return 0; + } +}; + +const getApy = async () => { + try { + // Get token prices + // const tokenAddresses = collateralList.map( + // (c) => `bsc:${c.originAddress || c.address.toLowerCase()}` + // ); + // console.log('Fetching prices for tokens:', tokenAddresses); + + // const pricesResponse = await superagent.get( + // `https://coins.llama.fi/prices/current/${tokenAddresses.join(',')}` + // ); + // const prices = pricesResponse.body.coins; + // console.log('Got prices:', prices); + + const poolData = await Promise.all( + collateralList.map(async (collateral) => { + try { + console.log(`Processing collateral: ${collateral.symbol}`); + + // Get TVL + const tvlResponse = await sdk.api.abi.call({ + target: INTERACTION.address, + params: [collateral.address], + abi: INTERACTION.abis.depositTVL, + chain: 'bsc', + }); + const tvl = tvlResponse.output; + console.log(`TVL for ${collateral.symbol}:`, tvl); + + // Get APR rates - pass entire collateral object + const aprRates = await calcApr(collateral); + console.log(`APR rates for ${collateral.symbol}:`, aprRates); + + // const priceKey = `bsc:${ + // collateral.originAddress || collateral.address.toLowerCase() + // }`; + // if (!prices[priceKey]) { + // console.log(`No price found for ${priceKey}`); + // return null; + // } + + // const tvlUsd = (Number(tvl) / 1e18) * prices[priceKey].price; + + // Get collateral rate and debt + const [collateralRateRes, debtRes] = await Promise.all([ + sdk.api.abi.call({ + target: INTERACTION.address, + params: [collateral.address], + abi: INTERACTION.abis.collateralRate, + chain: 'bsc', + }), + sdk.api.abi.call({ + target: INTERACTION.address, + params: [collateral.address], + abi: INTERACTION.abis.collateralTVL, + chain: 'bsc', + }), + ]); + + const collateralRate = Number(collateralRateRes.output) / 1e18; + const debt = Number(debtRes.output) / 1e18; + + // Get VAT ilks data for debt ceiling + const ilkHash = getIlks(collateral); + const vatIlksRes = await sdk.api.abi.call({ + target: VAT.address, + params: [ilkHash], + abi: VAT.abis.ilks, + chain: 'bsc', + }); + + const debtCeiling = Number(vatIlksRes.output.line) / 1e45; // line is in RAD (45 decimals) + return { + pool: `${collateral.address}-bsc`.toLowerCase(), + chain: 'bsc', + project: 'lista-cdp', + symbol: collateral.symbol, + apy: 0, + tvlUsd: Number(tvl) / 1e18, + + totalSupplyUsd: Number(tvl) / 1e18, + totalBorrowUsd: debt, + debtCeilingUsd: debtCeiling, + mintedCoin: 'lisUSD', + ltv: collateralRate, + apyBaseBorrow: aprRates || 0, + }; + } catch (error) { + console.error(`Error processing ${collateral.symbol}:`, error); + return null; + } + }) + ); + + return poolData.filter(Boolean); + } catch (error) { + console.error('Error in getApy:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://lista.org/', +}; diff --git a/src/adaptors/lista-lending/index.js b/src/adaptors/lista-lending/index.js new file mode 100644 index 0000000000..0787e01ae2 --- /dev/null +++ b/src/adaptors/lista-lending/index.js @@ -0,0 +1,48 @@ +const axios = require('axios'); + +const API_URL = 'https://api.lista.org/api/moolah/vault/list'; +const CHAINS = { + bsc: 56, +}; + +const apy = async () => { + let pools = []; + + for (const [chain, chainId] of Object.entries(CHAINS)) { + const { data } = await axios.get(API_URL, { + params: { + page: 1, + pageSize: 100, + }, + }); + + const earnPools = data.data.list.map((vault) => { + const baseApy = parseFloat(vault.apy); + const emissionApy = parseFloat(vault.emissionApy); + const totalApy = baseApy + emissionApy; + + return { + pool: `lista-lending-${vault.address}-${chain}`, + chain, + project: 'lista-lending', + symbol: vault.assetSymbol, + apyBase: baseApy * 100, + tvlUsd: parseFloat(vault.depositsUsd), + underlyingTokens: [vault.asset], + url: `https://lista.org/lending/vault/${vault.address}`, + apyReward: emissionApy * 100, + rewardTokens: vault.emissionEnabled + ? ['0xFceB31A79F71AC9CBDCF853519c1b12D379EdC46'] + : [], // LISTA + }; + }); + + pools = [...pools, ...earnPools]; + } + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/lista-liquid-staking/index.js b/src/adaptors/lista-liquid-staking/index.js new file mode 100644 index 0000000000..d14a7cd4dc --- /dev/null +++ b/src/adaptors/lista-liquid-staking/index.js @@ -0,0 +1,58 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const STAKING_CONTRACT = '0x1adB950d8bB3dA4bE104211D5AB038628e477fE6'; +const SLISBNB = '0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B'; +const BNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'; + +const abi = { + getTotalPooledBnb: { + inputs: [], + name: 'getTotalPooledBnb', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; + +const apy = async () => { + const [totalPooledBnb, apyData, bnbPrice] = await Promise.all([ + sdk.api.abi.call({ + target: STAKING_CONTRACT, + abi: abi.getTotalPooledBnb, + chain: 'bsc', + }), + axios.get('https://api.lista.org/v1/stakes/latest-apr'), + axios.get( + 'https://coins.llama.fi/prices/current/bsc:0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' + ), + ]); + + const tvlUsd = + (totalPooledBnb.output / 1e18) * + bnbPrice.data.coins['bsc:0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'].price; + const apyBase = + (parseFloat(apyData.data.data.apr) + + parseFloat(apyData.data.data.launchPoolApy)) * + 100; + + return [ + { + pool: SLISBNB, + chain: 'bsc', + project: 'lista-liquid-staking', + symbol: 'slisBNB', + tvlUsd, + apyBase, + underlyingTokens: [SLISBNB], + url: 'https://lista.org/liquid-staking/BNB', + poolMeta: + 'Launchpool rewards require clisBNB staking on Binance Launchpool', + }, + ]; +}; + +module.exports = { + apy, + url: 'https://lista.org/liquid-staking/BNB', +}; diff --git a/src/adaptors/lodestar-v0/abi.js b/src/adaptors/lodestar-v0/abi.js new file mode 100644 index 0000000000..1a4a4d34cb --- /dev/null +++ b/src/adaptors/lodestar-v0/abi.js @@ -0,0 +1,2102 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/lodestar-v0/index.js b/src/adaptors/lodestar-v0/index.js new file mode 100755 index 0000000000..7ff87e21f8 --- /dev/null +++ b/src/adaptors/lodestar-v0/index.js @@ -0,0 +1,238 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x92a62f8c4750D7FbDf9ee1dB268D18169235117B'; +const CHAIN = 'arbitrum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'lodestar-v0'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'LODE', + address: '0xF19547f9ED24aA66b03c3a552D181Ae334FBb8DB'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const lodePrices = await getPrices([`${CHAIN}:${PROTOCOL_TOKEN.address}`]); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = + // for maker + underlyingTokens[i]?.toLowerCase() === + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2' + ? 'MKR' + : underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + lodePrices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const _apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + const apyRewardBorrow = isNaN(_apyRewardBorrow) ? 0 : _apyRewardBorrow; + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + } + return poolReturned; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.lodestarfinance.io/', +}; diff --git a/src/adaptors/lodestar-v1/abi.js b/src/adaptors/lodestar-v1/abi.js new file mode 100644 index 0000000000..1a4a4d34cb --- /dev/null +++ b/src/adaptors/lodestar-v1/abi.js @@ -0,0 +1,2102 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/lodestar-v1/index.js b/src/adaptors/lodestar-v1/index.js new file mode 100755 index 0000000000..37ccb4b945 --- /dev/null +++ b/src/adaptors/lodestar-v1/index.js @@ -0,0 +1,288 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0xa86DD95c210dd186Fa7639F93E4177E97d057576'; +const CHAIN = 'arbitrum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'lodestar-v1'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'LODE', + address: '0xF19547f9ED24aA66b03c3a552D181Ae334FBb8DB'.toLowerCase(), +}; + +const ARB_TOKEN = { + decimals: 18, + symbol: 'ARB', + address: '0x912CE59144191C1204E64559FE8253a0e49E6548'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const lodePrices = await getPrices([`${CHAIN}:${PROTOCOL_TOKEN.address}`]); + const arbPrices = await getPrices([`${CHAIN}:${ARB_TOKEN.address}`]); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = + // for maker + underlyingTokens[i]?.toLowerCase() === + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2' + ? 'MKR' + : underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + lodePrices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + + const baseApyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const _apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + const apyRewardBorrow = isNaN(_apyRewardBorrow) ? 0 : _apyRewardBorrow; + + // Need to math off the total TVL for ARB and supply and borrow rewards are distributed evenly + let totalTvlUsd = 0; + + // Calculate total TVL (sum of supply and borrow for all markets) + allMarkets.forEach((market, i) => { + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = + prices[ + underlyingTokens[i]?.toLowerCase() || + NATIVE_TOKEN.address.toLowerCase() + ]; + if (price === undefined) + price = underlyingSymbols[i]?.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + + totalTvlUsd += totalSupplyUsd + totalBorrowUsd; + }); + + // Calculate ARB APY reward based on total TVL + const calcRewardApyForArb = (denom) => { + return ((arbPrices[ARB_TOKEN.address] * 50892 * 52) / denom) * 100; + }; + + // Define the cut-off date (February 15th, 2024) for the ARB stip rewards + const cutOffDate = new Date('2024-02-15'); + const currentDate = new Date(); + + let arbApyReward = 0; + if (currentDate <= cutOffDate) { + arbApyReward = calcRewardApyForArb(totalTvlUsd); + } + + // Computed total (LODE + ARB rewards) + const apyReward = baseApyReward + arbApyReward; + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: + arbApyReward > 0 + ? [ARB_TOKEN.address, PROTOCOL_TOKEN.address] + : [PROTOCOL_TOKEN.address], + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + } + return poolReturned; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.lodestarfinance.io/', +}; diff --git a/src/adaptors/lombard-lbtc/index.js b/src/adaptors/lombard-lbtc/index.js new file mode 100644 index 0000000000..d05aae241c --- /dev/null +++ b/src/adaptors/lombard-lbtc/index.js @@ -0,0 +1,32 @@ +const axios = require('axios'); + +const token = '0x8236a87084f8B84306f72007F36F2618A5634494'; + +const apy = async () => { + const [{ data: apy }, { data: tvl }, { data: price }] = await Promise.all([ + axios.get( + 'https://mainnet.prod.lombard.finance/api/v1/analytics/estimated-apy?partner_id=' + ), + axios.get( + 'https://ledger-mainnet.lombard-fi.com:1317/lombard-finance/ledger/btcstaking/staking_vault_base_balance' + ), + axios.get(`https://coins.llama.fi/prices/current/ethereum:${token}`), + ]); + + return [ + { + pool: token, + project: 'lombard-lbtc', + chain: 'bitcoin', + symbol: 'lBTC', + tvl: + (Number(tvl.balance) / 1e8) * price.coins[`ethereum:${token}`]?.price, + apy: apy.lbtc_estimated_apy * 100, + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.lombard.finance/app/stake/', +}; diff --git a/src/adaptors/looksrare/abis.json b/src/adaptors/looksrare/abis.json new file mode 100644 index 0000000000..7aa93c260a --- /dev/null +++ b/src/adaptors/looksrare/abis.json @@ -0,0 +1,86 @@ +{ + "currentRewardPerBlock": { + "inputs": [], + "name": "currentRewardPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "rewardToken": { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "rewardPerBlockForStaking": { + "inputs": [], + "name": "rewardPerBlockForStaking", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAmountStaked": { + "inputs": [], + "name": "totalAmountStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "calculateSharesValueInLOOKS": { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "calculateSharesValueInLOOKS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "thresholdAmount": { + "inputs": [], + "name": "thresholdAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/looksrare/index.js b/src/adaptors/looksrare/index.js new file mode 100644 index 0000000000..79cfc80f94 --- /dev/null +++ b/src/adaptors/looksrare/index.js @@ -0,0 +1,141 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const utils = require('../utils'); +abi = require("./abis.json"); + + +const looksrare = '0xf4d2888d29D722226FafA5d9B24F9164c092421E'; +const weth = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + +//contract for current reward per block (in WETH) +const feeSharing = '0xBcD7254A1D759EFA08eC7c3291B2E85c5dCC12ce'; +//contract for number of (LOOKS) tokens that is minted at each block in the current phase and distributed for LOOKS staking +const distributor = '0x465A790B428268196865a3AE2648481ad7e0d3b1'; +// compounding looks pool +const aggregator = '0x3ab16Af1315dc6C95F83Cbf522fecF98D00fd9ba'; + + +const poolInfo = async (chain) => { + //weth reward per block + const rewardPerBlock = (await sdk.api.abi.call({ abi: abi.currentRewardPerBlock, target: feeSharing, chain: chain, })).output; + const rewardToken = (await sdk.api.abi.call({ abi: abi.rewardToken, target: feeSharing, chain: chain, })).output; + // looks balance staked in compounder pool + const aggregatorSharesValueInLooks = (await sdk.api.abi.call({ abi: abi.calculateSharesValueInLOOKS, target: feeSharing, chain: chain, params: aggregator })).output; + const rewardTokens = [rewardToken, looksrare]; + // looks reward per block + const rewardPerBlockForStaking = (await sdk.api.abi.call({ abi: abi.rewardPerBlockForStaking, target: distributor, chain: chain, })).output; + const totalAmountStaked = (await sdk.api.abi.call({ abi: abi.totalAmountStaked, target: distributor, chain: chain, })).output; + const thresholdAmount = (await sdk.api.abi.call({ abi: abi.thresholdAmount, target: aggregator, chain: chain, })).output; + const compounderReserve = aggregatorSharesValueInLooks / 1e18; + const standardReserve = (totalAmountStaked / 1e18) - compounderReserve; + + return { + rewardTokens, + aggregatorSharesValueInLooks, + rewardPerBlock, + rewardPerBlockForStaking, + compounderReserve, + standardReserve, + totalAmountStaked, + thresholdAmount, + }; +} + +function calculateTvl(reserve, price) { + const tvl = reserve * price; + return tvl; +} + +function calculateApr(reward, price, tvl) { + // yearlyReward = reward X price X blocks + // tvl = poolBalance X price + // apy = yearlyReward / tvl + const BLOCK_TIME = 12; + const BLOCKS = 365 * 24 * 60 * 60 / BLOCK_TIME; + const yearlyReward = (reward / 1e18) * price * BLOCKS; + const apr = (yearlyReward / tvl) * 100; + return apr; +} + +function dailyWethCompounds(aggregatorSharesValueInLooks, totalAmountStaked, rewardPerBlock, thresholdAmount) { + // daily estimated compounds = weth rewards emitted per day to aggregator contract divided by the threshold amount + // threshold amount (in rewardToken) to trigger a sale on uniswap v3 + const BLOCK_TIME = 12; + const BLOCKS = 24 * 60 * 60 / BLOCK_TIME; + const aggregatorWethRewardsShare = aggregatorSharesValueInLooks / totalAmountStaked; + const aggregatorWethRewardPerDay = (rewardPerBlock / 1e18) * aggregatorWethRewardsShare * BLOCKS; + const dailyCompounds = aggregatorWethRewardPerDay / (thresholdAmount / 1e18); + + return dailyCompounds; +} + +function calculateApy(wethApr, dailyCompounds) { + // ((1 + r/n )^n) – 1 + const apr = wethApr / 100; + const apy = (((1 + apr / dailyCompounds) ** dailyCompounds) - 1) * 100; + return apy; +} + +function compounderApy(wethApy, looksApr) { + // apy = (1 + WETH apy) * (1 + LOOKS apr) - 1 + const compounderApy = ((1 + (wethApy / 100)) * (1 + (looksApr / 100)) - 1) * 100; + return compounderApy; +} + +const getPrices = async (chain, addresses) => { + const uri = `${addresses.map((address) => `${chain}:${address}`)}`; + const prices = ( + await superagent.get('https://coins.llama.fi/prices/current/' + uri) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +function exportFormatter(poolId, chain, tvlUsd, apyBase, apyReward, rewardTokens, poolMeta) { + return { + pool: `${poolId}-${chain}`.toLowerCase(), + chain, + project: 'looksrare', + symbol: `LOOKS`, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [looksrare], + rewardTokens, + poolMeta, + }; +} + +const getApy = async () => { + let pools = []; + const chain = 'Ethereum'; + + const pool = await poolInfo(chain.toLowerCase()); + const prices = await getPrices(chain.toLowerCase(), pool.rewardTokens); + const standardTvl = calculateTvl(pool.standardReserve, prices[looksrare.toLowerCase()]); + const compounderTvl = calculateTvl(pool.compounderReserve, prices[looksrare.toLowerCase()]); + const dailyCompounds = dailyWethCompounds(pool.aggregatorSharesValueInLooks, pool.totalAmountStaked, pool.rewardPerBlock, pool.thresholdAmount); + const wethApr = calculateApr(pool.rewardPerBlock, prices[weth.toLowerCase()], standardTvl + compounderTvl); + const wethApy = calculateApy(wethApr, dailyCompounds); + const looksApr = calculateApr(pool.rewardPerBlockForStaking, prices[looksrare.toLowerCase()], standardTvl + compounderTvl); + + pools.push(exportFormatter(distributor, chain, standardTvl, wethApr, looksApr, pool.rewardTokens, 'Standard Staking')); + pools.push(exportFormatter(aggregator, chain, compounderTvl, compounderApy(wethApy, looksApr), null, [pool.rewardTokens[1]], 'LOOKS Compounder')); + + return pools; +} + + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://looksrare.org/rewards', +}; \ No newline at end of file diff --git a/src/adaptors/looped-hype/accountantAbi.json b/src/adaptors/looped-hype/accountantAbi.json new file mode 100644 index 0000000000..e2bc125052 --- /dev/null +++ b/src/adaptors/looped-hype/accountantAbi.json @@ -0,0 +1,667 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_owner", + "type": "address", + "internalType": "address" + }, + { + "name": "_vault", + "type": "address", + "internalType": "address" + }, + { + "name": "payoutAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "startingExchangeRate", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "_base", + "type": "address", + "internalType": "address" + }, + { + "name": "allowedExchangeRateChangeUpper", + "type": "uint16", + "internalType": "uint16" + }, + { + "name": "allowedExchangeRateChangeLower", + "type": "uint16", + "internalType": "uint16" + }, + { + "name": "minimumUpdateDelayInSeconds", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "managementFee", + "type": "uint16", + "internalType": "uint16" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "accountantState", + "inputs": [], + "outputs": [ + { + "name": "payoutAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "feesOwedInBase", + "type": "uint128", + "internalType": "uint128" + }, + { + "name": "totalSharesLastUpdate", + "type": "uint128", + "internalType": "uint128" + }, + { + "name": "exchangeRate", + "type": "uint96", + "internalType": "uint96" + }, + { + "name": "allowedExchangeRateChangeUpper", + "type": "uint16", + "internalType": "uint16" + }, + { + "name": "allowedExchangeRateChangeLower", + "type": "uint16", + "internalType": "uint16" + }, + { + "name": "lastUpdateTimestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "isPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "minimumUpdateDelayInSeconds", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "managementFee", + "type": "uint16", + "internalType": "uint16" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "authority", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Authority" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "base", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ERC20" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimFees", + "inputs": [ + { + "name": "feeAsset", + "type": "address", + "internalType": "contract ERC20" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRate", + "inputs": [], + "outputs": [ + { + "name": "rate", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRateInQuote", + "inputs": [ + { + "name": "quote", + "type": "address", + "internalType": "contract ERC20" + } + ], + "outputs": [ + { + "name": "rateInQuote", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRateInQuoteSafe", + "inputs": [ + { + "name": "quote", + "type": "address", + "internalType": "contract ERC20" + } + ], + "outputs": [ + { + "name": "rateInQuote", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRateSafe", + "inputs": [], + "outputs": [ + { + "name": "rate", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pause", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rateProviderData", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ERC20" + } + ], + "outputs": [ + { + "name": "isPeggedToBase", + "type": "bool", + "internalType": "bool" + }, + { + "name": "rateProvider", + "type": "address", + "internalType": "contract IRateProvider" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setAuthority", + "inputs": [ + { + "name": "newAuthority", + "type": "address", + "internalType": "contract Authority" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setRateProviderData", + "inputs": [ + { + "name": "asset", + "type": "address", + "internalType": "contract ERC20" + }, + { + "name": "isPeggedToBase", + "type": "bool", + "internalType": "bool" + }, + { + "name": "rateProvider", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "unpause", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateDelay", + "inputs": [ + { + "name": "minimumUpdateDelayInSeconds", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateExchangeRate", + "inputs": [ + { + "name": "newExchangeRate", + "type": "uint96", + "internalType": "uint96" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateLower", + "inputs": [ + { + "name": "allowedExchangeRateChangeLower", + "type": "uint16", + "internalType": "uint16" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateManagementFee", + "inputs": [ + { + "name": "managementFee", + "type": "uint16", + "internalType": "uint16" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updatePayoutAddress", + "inputs": [ + { + "name": "payoutAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateUpper", + "inputs": [ + { + "name": "allowedExchangeRateChangeUpper", + "type": "uint16", + "internalType": "uint16" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "vault", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract BoringVault" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "AuthorityUpdated", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newAuthority", + "type": "address", + "indexed": true, + "internalType": "contract Authority" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DelayInSecondsUpdated", + "inputs": [ + { + "name": "oldDelay", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "newDelay", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ExchangeRateUpdated", + "inputs": [ + { + "name": "oldRate", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + }, + { + "name": "newRate", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + }, + { + "name": "currentTime", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeesClaimed", + "inputs": [ + { + "name": "feeAsset", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LowerBoundUpdated", + "inputs": [ + { + "name": "oldBound", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + }, + { + "name": "newBound", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ManagementFeeUpdated", + "inputs": [ + { + "name": "oldFee", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + }, + { + "name": "newFee", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Paused", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "PayoutAddressUpdated", + "inputs": [ + { + "name": "oldPayout", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "newPayout", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RateProviderUpdated", + "inputs": [ + { + "name": "asset", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "isPegged", + "type": "bool", + "indexed": false, + "internalType": "bool" + }, + { + "name": "rateProvider", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Unpaused", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "UpperBoundUpdated", + "inputs": [ + { + "name": "oldBound", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + }, + { + "name": "newBound", + "type": "uint16", + "indexed": false, + "internalType": "uint16" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AccountantWithRateProviders__LowerBoundTooLarge", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__ManagementFeeTooLarge", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__OnlyCallableByBoringVault", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__Paused", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__UpdateDelayTooLarge", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__UpperBoundTooSmall", + "inputs": [] + }, + { + "type": "error", + "name": "AccountantWithRateProviders__ZeroFeesOwed", + "inputs": [] + } +] diff --git a/src/adaptors/looped-hype/index.ts b/src/adaptors/looped-hype/index.ts new file mode 100644 index 0000000000..8cbd7a1073 --- /dev/null +++ b/src/adaptors/looped-hype/index.ts @@ -0,0 +1,141 @@ + +const axios = require('axios'); +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const poolAbi = require('./poolAbi.json'); +const accountantAbi = require('./accountantAbi.json'); + +const LHYPE = '0x5748ae796AE46A4F1348a1693de4b50560485562'; +const LHYPE_ACCOUNTANT = '0xcE621a3CA6F72706678cFF0572ae8d15e5F001c3'; +const UNDERLYING = '0x5555555555555555555555555555555555555555'; // WHYPE on Hyperliquid +const CHAIN = 'hyperliquid'; + +/* --------------------------------- + TVL Calculation Section +----------------------------------*/ +const calculateTVL = async (chain = CHAIN) => { + const totalSupplyCall = sdk.api.abi.call({ + target: LHYPE, + abi: poolAbi.find((m) => m.name === 'totalSupply'), + chain, + }); + + const decimalsCall = sdk.api.abi.call({ + target: LHYPE, + abi: poolAbi.find((m) => m.name === 'decimals'), + chain, + }); + + const priceKey = `${chain}:${UNDERLYING}`; + const underlyingPriceCall = axios.get( + `https://coins.llama.fi/prices/current/${priceKey}?searchWidth=24h` + ); + + const currentRateCall = sdk.api.abi.call({ + target: LHYPE_ACCOUNTANT, + abi: accountantAbi.find((m) => m.name === 'getRate'), + chain, + }); + + const [ + totalSupplyResponse, + decimalsResponse, + underlyingPriceResponse, + currentRateResponse, + ] = await Promise.all([ + totalSupplyCall, + decimalsCall, + underlyingPriceCall, + currentRateCall, + ]); + + const decimals = Number(decimalsResponse.output); + const scalingFactor = 10 ** decimals; + + const totalSupply = Number(totalSupplyResponse.output) / scalingFactor; + const currentRate = Number(currentRateResponse.output); + + const priceObj = underlyingPriceResponse.data?.coins?.[priceKey]; + if (!priceObj || typeof priceObj.price !== 'number') { + throw new Error(`No price found for ${priceKey}`); + } + const underlyingPrice = priceObj.price; + const tvlUsd = totalSupply * currentRate * underlyingPrice / scalingFactor; + + return { + tvlUsd, + underlyingPrice, + decimals, + scalingFactor, + totalSupply, + currentRate, + }; +}; + +/* --------------------------------- + APY Calculation Section +----------------------------------*/ +const calculateAPY = async (currentRate, scalingFactor, chain = CHAIN) => { + const now = Math.floor(Date.now() / 1000); + const t1d = now - 86400; + const t7d = now - 86400 * 7; + + const [b1, b7] = await Promise.all([ + axios.get(`https://coins.llama.fi/block/${chain}/${t1d}`), + axios.get(`https://coins.llama.fi/block/${chain}/${t7d}`), + ]); + + const block1d = b1.data?.height; + const block7d = b7.data?.height; + + const [r1, r7] = await Promise.all([ + sdk.api.abi.call({ + target: LHYPE_ACCOUNTANT, + abi: accountantAbi.find((m) => m.name === 'getRate'), + block: block1d, + chain, + }), + sdk.api.abi.call({ + target: LHYPE_ACCOUNTANT, + abi: accountantAbi.find((m) => m.name === 'getRate'), + block: block7d, + chain, + }), + ]); + + const apy1d = ((Number(currentRate) - Number(r1.output)) / scalingFactor) * 365 * 100; + const apy7d = ((Number(currentRate) - Number(r7.output)) / scalingFactor / 7) * 365 * 100; + + return { + apy1d, + apy7d, + }; +}; + +/* --------------------------------- + Adapter Export +----------------------------------*/ +const apy = async () => { + const { tvlUsd, currentRate, scalingFactor } = await calculateTVL(CHAIN); + const { apy1d, apy7d } = await calculateAPY(currentRate, scalingFactor, CHAIN); + + const pool = { + pool: `${LHYPE}-${CHAIN}`.toLowerCase(), + project: 'looped-hype', + chain: utils.formatChain(CHAIN), + symbol: 'LHYPE', + tvlUsd, + apyBase: apy1d, + apyBase7d: apy7d, + underlyingTokens: [UNDERLYING], + }; + + return [pool]; +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.loopingcollective.org/product/lhype', +}; diff --git a/src/adaptors/looped-hype/poolAbi.json b/src/adaptors/looped-hype/poolAbi.json new file mode 100644 index 0000000000..69a73b0ccb --- /dev/null +++ b/src/adaptors/looped-hype/poolAbi.json @@ -0,0 +1,744 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Enter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Exit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "enter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "hook", + "outputs": [ + { + "internalType": "contract BeforeTransferHook", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_hook", + "type": "address" + } + ], + "name": "setBeforeTransferHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/loopring/index.js b/src/adaptors/loopring/index.js new file mode 100644 index 0000000000..4a767b134d --- /dev/null +++ b/src/adaptors/loopring/index.js @@ -0,0 +1,25 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const API_URL = 'https://api.loopring.network/api/v2/amm/poolsStats'; + +const getApy = async () => { + const poolsData = (await axios.get(API_URL)).data; + + const pools = poolsData.data.map((pool) => ({ + pool: `${pool.market}-loopring`, + chain: utils.formatChain('ethereum'), + project: 'loopring', + symbol: pool.market.replace('AMM-', ''), + tvlUsd: Number(pool.liquidityUSD), + apy: Number(pool.apyBips) / 100, + })); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://loopring.io/#/markets', +}; diff --git a/src/adaptors/loopscale/index.js b/src/adaptors/loopscale/index.js new file mode 100644 index 0000000000..f2909e1136 --- /dev/null +++ b/src/adaptors/loopscale/index.js @@ -0,0 +1,32 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getApy = async () => { + const body = {"page": 0,"pageSize": 100}; + const vaultApys = []; + const vaults = (await axios.post(`https://tars.loopscale.com/v1/markets/lending_vaults/stats`, body)).data; + + for (const vault of vaults) { + vaultApys.push({ + pool: vault.vaultAddress, + chain: 'Solana', + project: 'loopscale', + symbol: utils.formatSymbol(vault.vaultSymbol), + underlyingTokens: [vault.principalMint], + tvlUsd: Number(vault.principalDepositsUsd - vault.principalDeployedUsd), + url: `https://app.loopscale.com/vault/${vault.vaultAddress}`, + apyBase: Number(vault.apy), + apyReward: Number(vault.rewardsApy), + totalSupplyUsd: Number(vault.principalDepositsUsd), + totalBorrowUsd: Number(vault.principalDeployedUsd), + rewardTokens: vault.rewardsMints, + }); + } + + return vaultApys; +}; + +module.exports = { + apy: getApy, + url: 'https://app.loopscale.com/', +}; diff --git a/src/adaptors/lore-finance/abiLendingPool.js b/src/adaptors/lore-finance/abiLendingPool.js new file mode 100644 index 0000000000..ddf300738e --- /dev/null +++ b/src/adaptors/lore-finance/abiLendingPool.js @@ -0,0 +1,692 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/lore-finance/abiProtocolDataProvider.js b/src/adaptors/lore-finance/abiProtocolDataProvider.js new file mode 100644 index 0000000000..1c698fcae2 --- /dev/null +++ b/src/adaptors/lore-finance/abiProtocolDataProvider.js @@ -0,0 +1,148 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/lore-finance/abiSimplifiedProtocolDataReader.js b/src/adaptors/lore-finance/abiSimplifiedProtocolDataReader.js new file mode 100644 index 0000000000..6026a78d14 --- /dev/null +++ b/src/adaptors/lore-finance/abiSimplifiedProtocolDataReader.js @@ -0,0 +1,406 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "protocolDataProviderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarderAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "thenaOracle", + "type": "address" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lendingOracleAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "discountExercise", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "DISCOUNT_EXERCISE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ILENDING_ORACLE", + "outputs": [ + { + "internalType": "contract ILendingOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ITHENA_ORACLE", + "outputs": [ + { + "internalType": "contract IThenaOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAYMENT_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PROTOCOL_DATA_PROVIDER", + "outputs": [ + { + "internalType": "contract ProtocolDataProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARDER", + "outputs": [ + { + "internalType": "contract IRewarder0612", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetFullYieldBreakdown", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetRewardsAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getDepositAndBorrowAPRs", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPaymentTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolBalancesUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPoolYearlyRewardsUSD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRawOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRealOTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReceiptTokenAddresses", + "outputs": [ + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardsDataEPS", + "outputs": [ + { + "internalType": "uint256", + "name": "aTokenRewardEPS", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vTokenRewardEPS", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] diff --git a/src/adaptors/lore-finance/index.js b/src/adaptors/lore-finance/index.js new file mode 100644 index 0000000000..739ea145ed --- /dev/null +++ b/src/adaptors/lore-finance/index.js @@ -0,0 +1,185 @@ +const ethers = require('ethers'); +const { JsonRpcProvider } = require('ethers'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +const abiSimplifiedProtocolDataReader = require('./abiSimplifiedProtocolDataReader'); + +const utils = require('../utils'); + +const chains = { + scroll: { + LendingPool: '0x4cE1A1eC13DBd9084B1A741b036c061b2d58dABf', + ProtocolDataProvider: '0xb17844F6E50f4eE8f8FeC7d9BA200B0E034b8236', + url: 'scroll', + SimplifiedProtocolDataReader: '0x8d21d9Cb7B6Bd1acf99C46295A9558bE6DDD2fDe', + rewardTokens: ['0xf270bfe3f97655fff1d89aff50a8e1dc381941b5'] + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain; + const rewardTokens = addresses.rewardTokens; + + const reservesList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: sdkChain, + }) + ).output; + + // try catches incase of safemath error + let rewardsData; + try { + rewardsData = await sdk.api.abi.multiCall({ + calls: reservesList.map((reserve) => ({ + target: addresses.SimplifiedProtocolDataReader, + params: [reserve], + })), + abi: abiSimplifiedProtocolDataReader.find((m) => m.name === 'getAssetRewardsAPR'), + chain: sdkChain, + failOnRevert: false, // Add this option to prevent failing on reverts + }); + } catch (error) { + console.error(`Error fetching rewards data for chain ${chain}:`, error); + // Implement fallback mechanism or use default values + rewardsData = { + output: reservesList.map(() => ({ success: false, output: null })) + }; + } + + // Process the results, handling potential failures + const processedRewardsData = rewardsData.output.map((result, index) => { + if (result.success && Array.isArray(result.output) && result.output.length === 2) { + return { + apyReward: Number(result.output[0]) / 1.893563261 / 1e8, + apyRewardBorrow: Number(result.output[1]) / 1.893563261 / 1e8 + }; + } else { + console.warn(`Failed to get rewards data for reserve ${reservesList[index]} on chain ${chain}`); + return { apyReward: 0, apyRewardBorrow: 0 }; + } + }); + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: sdkChain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${sdkChain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + + const { apyReward, apyRewardBorrow } = processedRewardsData[i]; + + if (!config.isActive) return null; + + const price = prices[`${sdkChain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + // console.log(`Raw reward data for ${symbols[i]}:`, rewardsData.output[i]?.output); + // console.log(`Parsed apyReward for ${symbols[i]}:`, apyReward); + // console.log(`Parsed apyRewardBorrow for ${symbols[i]}:`, apyRewardBorrow); + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + const poolSymbol = symbols[i].toLowerCase() + const url = `https://app.lore.finance/markets/${poolSymbol}`; + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'lore-finance', + chain, + tvlUsd, + apyBase, + // apyReward, + underlyingTokens: [t], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + // apyRewardBorrow, + // rewardTokens, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }); + }) + ); + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/lst-optimizer/abis/kETHStrategy.json b/src/adaptors/lst-optimizer/abis/kETHStrategy.json new file mode 100644 index 0000000000..c2a25cfee1 --- /dev/null +++ b/src/adaptors/lst-optimizer/abis/kETHStrategy.json @@ -0,0 +1,40 @@ +[ + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "total", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "assetsRatio", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "valueInETH", + "type": "uint256" + } + ], + "internalType": "struct KETHStrategy.AssetRatio[]", + "name": "info", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/lst-optimizer/index.js b/src/adaptors/lst-optimizer/index.js new file mode 100644 index 0000000000..4126f0b484 --- /dev/null +++ b/src/adaptors/lst-optimizer/index.js @@ -0,0 +1,120 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { ethers } = require('ethers'); + +const kETHStrategyAbi = require('./abis/kETHStrategy.json'); + +const bigToNum = (bn) => { + if (typeof(bn) == 'string') + ethers.BigNumber.from(bn); + + bn = ethers.utils.formatEther(bn); + return Number(bn); +} + +const queryStakingAprs = async () => { + const rETHResult = (await axios.get('https://dt4w6sqvtl.execute-api.eu-central-1.amazonaws.com/mainnet/')).data; + const beaconChainApr = Number(rETHResult.beaconChainAPR) * 100; + const rETH = Number(rETHResult.rethAPR) * 0.9; + const dETH = (beaconChainApr * 32) / 24; + + const stETHResult = (await axios.get('https://eth-api.lido.fi/v1/protocol/steth/apr/last')).data; + const stETH = Number(stETHResult.data.apr) * 0.9; + + return {stETH, rETH, dETH}; +} + +const topLvl = async (chainString, underlying) => { + + const kETHStrategyAddress = "0xa060a5F83Db8bf08b45Cf56Db370c9383b7B895C"; + const dETHVaultAddress = "0x4c7aF9BdDac5bD3bee9cd2Aa2FeEeeE7610f5a6B"; + const bsnFarmingAddress = "0x5CeCfAf8f8c2983A3336adbe836aF39192a72895"; + + const wstETHTokenAddress = "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0"; + const rETHTokenAddress = "0xae78736Cd615f374D3085123A210448E74Fc6393"; + const dETHTokenAddress = "0x3d1E5Cf16077F349e999d6b21A4f646e83Cd90c5"; + const savETHTokenAddress = "0x00ee7ea7ca2b5cc47908f0cad1f296efbde1402e"; + const gETHTokenAddress = "0xe550adfbcadaa86dfe05d0c67c2e6f27accf5cf1"; + + let kETHTvl = bigToNum((await sdk.api.abi.call({ + abi: kETHStrategyAbi.find(abi => abi.name == "totalAssets"), + target: kETHStrategyAddress + })).output); + + let kETHAssets = (await sdk.api.abi.call({ + abi: kETHStrategyAbi.find(abi => abi.name == "assetsRatio"), + target: kETHStrategyAddress, + })).output; + + const stETHValue = bigToNum( + kETHAssets.find((item) => + item.token.toLowerCase() == wstETHTokenAddress.toLowerCase() + ).valueInETH ) + + + const rETHValue = bigToNum( + kETHAssets.find((item) => + item.token.toLowerCase() == rETHTokenAddress.toLowerCase() + ).valueInETH) + + + const dETHValue = + bigToNum( + kETHAssets.find((item) => + item.token.toLowerCase() == dETHTokenAddress.toLowerCase() + ).valueInETH + ) + + bigToNum( + kETHAssets.find((item) => + item.token.toLowerCase() == savETHTokenAddress.toLowerCase() + ).valueInETH + ) + + bigToNum( + kETHAssets.find((item) => + item.token.toLowerCase() == gETHTokenAddress.toLowerCase() + ).valueInETH + ) + + const ethValue = kETHTvl - stETHValue - rETHValue - dETHValue + + const stakingAprs = await queryStakingAprs(); + + const kETHApr = + (stETHValue * stakingAprs.stETH + + rETHValue * stakingAprs.rETH + + dETHValue * stakingAprs.dETH + + ethValue) / + kETHTvl + + const ethUSDPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:0x0000000000000000000000000000000000000000`) + ).data; + + ethUsd = ethUSDPrice.coins['ethereum:0x0000000000000000000000000000000000000000'].price; + + return [{ + pool: `${kETHStrategyAddress}-${chainString}`.toLowerCase(), + chain: utils.formatChain(chainString), + project: 'lst-optimizer', + symbol: "kETH", + tvlUsd: kETHTvl * ethUsd, + apyBase: kETHApr, + underlyingTokens: [wstETHTokenAddress, rETHTokenAddress, dETHTokenAddress], + }]; +}; + +const main = async () => { + const data = await topLvl ( + 'ethereum', + '0x0000000000000000000000000000000000000000' + ) + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://dapp.getketh.com/home/', +}; diff --git a/src/adaptors/lusd-chickenbonds/abi.ts b/src/adaptors/lusd-chickenbonds/abi.ts new file mode 100644 index 0000000000..2391d3f687 --- /dev/null +++ b/src/adaptors/lusd-chickenbonds/abi.ts @@ -0,0 +1,112 @@ +const abi = { + chickenBondManager: { + calcUpdatedAccrualParameter: { + inputs: [], + name: 'calcUpdatedAccrualParameter', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + CHICKEN_IN_AMM_FEE: { + inputs: [], + name: 'CHICKEN_IN_AMM_FEE', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + calcSystemBackingRatio: { + inputs: [], + name: 'calcSystemBackingRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getPendingLUSD: { + inputs: [], + name: 'getPendingLUSD', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalWeightedStartTimes: { + inputs: [], + name: 'totalWeightedStartTimes', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + targetAverageAgeSeconds: { + inputs: [], + name: 'targetAverageAgeSeconds', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, + curveRegistrySwaps: { + get_exchange_multiple_amount: { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_multiple_amount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + inputs: [ + { + name: '_route', + type: 'address[9]', + }, + { + name: '_swap_params', + type: 'uint256[3][4]', + }, + { + name: '_amount', + type: 'uint256', + }, + ], + }, + }, +}; + +module.exports = abi; diff --git a/src/adaptors/lusd-chickenbonds/addresses.ts b/src/adaptors/lusd-chickenbonds/addresses.ts new file mode 100644 index 0000000000..252a2e095e --- /dev/null +++ b/src/adaptors/lusd-chickenbonds/addresses.ts @@ -0,0 +1,9 @@ +module.exports = { + LUSD_ADDRESS: '0x5f98805A4E8be255a32880FDeC7F6728C6568bA0', + BLUSD_ADDRESS: '0xB9D7DdDca9a4AC480991865EfEf82E01273F79C3', + CRV_ADDRESS: '0xD533a949740bb3306d119CC777fa900bA034cd52', + LUSD_3CRV_POOL_ADDRESS: '0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA', + CHICKEN_BOND_MANAGER_ADDRESS: '0x57619FE9C539f890b19c61812226F9703ce37137', + BLUSD_LUSD_3CRV_POOL_ADDRESS: '0x74ED5d42203806c8CDCf2F04Ca5F60DC777b901c', + CURVE_REGISTRY_SWAPS_ADDRESS: '0x81C46fECa27B31F3ADC2b91eE4be9717d1cd3DD7', +}; diff --git a/src/adaptors/lusd-chickenbonds/helpers.ts b/src/adaptors/lusd-chickenbonds/helpers.ts new file mode 100644 index 0000000000..5797e66c01 --- /dev/null +++ b/src/adaptors/lusd-chickenbonds/helpers.ts @@ -0,0 +1,179 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { lambertW0 } = require('lambert-w-function'); + +const abi = require('./abi'); +const { + LUSD_ADDRESS, + BLUSD_ADDRESS, + BLUSD_LUSD_3CRV_POOL_ADDRESS, + LUSD_3CRV_POOL_ADDRESS, + CHICKEN_BOND_MANAGER_ADDRESS, + CURVE_REGISTRY_SWAPS_ADDRESS, +} = require('./addresses'); + +const getLusdUsdPrice = async () => { + return ( + await superagent.get( + `https://coins.llama.fi/prices/current/ethereum:${LUSD_ADDRESS}` + ) + ).body.coins[`ethereum:${LUSD_ADDRESS}`].price; +}; + +const contractCall = async (address, functionAbi, params = undefined) => { + return ( + await sdk.api.abi.call({ + target: address, + abi: functionAbi, + chain: 'ethereum', + params, + }) + ).output; +}; + +const _getAverageBondAgeInSeconds = async () => { + const totalWeightedStartTimes = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.totalWeightedStartTimes + )) / 1e18; + + const pendingBucketLusd = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.getPendingLUSD + )) / 1e18; + + const averageStartTimeinMilliseconds = + Math.round(totalWeightedStartTimes / pendingBucketLusd) * 1000; + const averageBondAgeInSeconds = + Math.round(Date.now() - averageStartTimeinMilliseconds) / 1000; + + return averageBondAgeInSeconds; +}; + +const _secondsToDays = (seconds) => seconds / 60 / 60 / 24; + +const _getDaysUntilControllerStartsAdjusting = async ( + targetBondAgeInSeconds +) => { + const averageBondAgeInSeconds = (await _getAverageBondAgeInSeconds()) / 1e18; + const secondsUntil = + targetBondAgeInSeconds > averageBondAgeInSeconds + ? targetBondAgeInSeconds - averageBondAgeInSeconds + : 0; + const daysUntil = _secondsToDays(secondsUntil); + return daysUntil; +}; + +const _getControllerAdjustedRebondDays = async (rebondPeriodInDays) => { + const targetBondAgeInSeconds = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.targetAverageAgeSeconds + )) / 1e18; + const daysUntilControllerStartsAdjusting = + await _getDaysUntilControllerStartsAdjusting(targetBondAgeInSeconds); + const rebondDaysRemaining = rebondPeriodInDays; + + if (rebondDaysRemaining < daysUntilControllerStartsAdjusting) { + return rebondDaysRemaining; + } + + const lambertDividend = rebondPeriodInDays * Math.log(0.99); + const lambertDivisor = 0.99 ** daysUntilControllerStartsAdjusting; + const lambertQuotient = lambertW0(-(lambertDividend / lambertDivisor)); + + const formulaDividend = + lambertQuotient + Math.log(0.99) * daysUntilControllerStartsAdjusting; + + const formulaDivisor = Math.log(0.99); + + const controlledAdjustedRebondDays = -(formulaDividend / formulaDivisor); + + return controlledAdjustedRebondDays; +}; + +const _getBLusdMarketPrice = async () => { + const marginalInputAmount = 0x038d7ea4c68000; // == 1/1000 in hex; + + const marginalOutputAmount = await contractCall( + CURVE_REGISTRY_SWAPS_ADDRESS, + abi.curveRegistrySwaps.get_exchange_multiple_amount, + [ + [ + BLUSD_ADDRESS, + BLUSD_LUSD_3CRV_POOL_ADDRESS, + LUSD_3CRV_POOL_ADDRESS, + LUSD_3CRV_POOL_ADDRESS, + LUSD_ADDRESS, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + [ + [0, 1, 3], + [0, 0, 9], + [0, 0, 0], + [0, 0, 0], + ], + marginalInputAmount, + ] + ); + + const marketPrice = marginalOutputAmount / marginalInputAmount; + + return marketPrice; +}; + +const getRebondApy = async () => { + const alphaAccrualFactor = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.calcUpdatedAccrualParameter + )) / + 1e18 / + (24 * 60 * 60); + + const chickenInFee = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.CHICKEN_IN_AMM_FEE + )) / 1e18; + + const floorPrice = + (await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.calcSystemBackingRatio + )) / 1e18; + + const marketPrice = await _getBLusdMarketPrice(); + + const marketPricePremium = (marketPrice / floorPrice) * (1 - chickenInFee); + + const rebondPeriodInDays = + alphaAccrualFactor * + ((1 + Math.sqrt(marketPricePremium)) / (marketPricePremium - 1)); + + const controllerAdjustedRebondPeriodInDays = + await _getControllerAdjustedRebondDays(rebondPeriodInDays); + + const rebondPeriodAccrualFactor = + (1 / floorPrice) * + (rebondPeriodInDays / (rebondPeriodInDays + alphaAccrualFactor)); + + const rebondRoi = + (1 - chickenInFee) * rebondPeriodAccrualFactor * marketPrice - 1; + + const rebondApr = rebondRoi * (365 / controllerAdjustedRebondPeriodInDays); + + const rebondApy = + (1 + rebondApr / (365 / controllerAdjustedRebondPeriodInDays)) ** + (365 / controllerAdjustedRebondPeriodInDays) - + 1; + + return rebondApy * 100; +}; + +module.exports = { getLusdUsdPrice, getRebondApy, contractCall }; diff --git a/src/adaptors/lusd-chickenbonds/index.ts b/src/adaptors/lusd-chickenbonds/index.ts new file mode 100644 index 0000000000..0420bb119c --- /dev/null +++ b/src/adaptors/lusd-chickenbonds/index.ts @@ -0,0 +1,105 @@ +const superagent = require('superagent'); +const abi = require('./abi'); +const { getRebondApy, contractCall, getLusdUsdPrice } = require('./helpers'); +const { + CHICKEN_BOND_MANAGER_ADDRESS, + BLUSD_LUSD_3CRV_POOL_ADDRESS, + LUSD_ADDRESS, + BLUSD_ADDRESS, + LUSD_3CRV_POOL_ADDRESS, + CRV_ADDRESS, +} = require('./addresses'); +import type { + PartialCurvePoolData, + PartialCurvePoolDetails, + ChickenBondsStrategy, + ChickenBondsStrategies, +} from './types'; + +const getBLusdRebondStrategy = async (): Promise => { + const lusdUsdPrice = await getLusdUsdPrice(); + + const tvlUsd = + ((await contractCall( + CHICKEN_BOND_MANAGER_ADDRESS, + abi.chickenBondManager.getPendingLUSD + )) / + 1e18) * + lusdUsdPrice; + + const rebondApy = await getRebondApy(); + + return { + pool: CHICKEN_BOND_MANAGER_ADDRESS, + project: 'lusd-chickenbonds', + symbol: 'bLUSD', + chain: 'ethereum', + tvlUsd, + apyBase: rebondApy, + underlyingTokens: [LUSD_ADDRESS, BLUSD_ADDRESS], + rewardTokens: [LUSD_ADDRESS], + poolMeta: + 'Rebonding bLUSD strategy continuously performs the following steps: create an LUSD bond, claim it at the optimum rebond time, sell the acquired bLUSD back to LUSD, and then bond again.', + }; +}; + +const getBLusdLusd3CrvStrategy = async (): Promise => { + const curvePoolDataResponse = ( + await superagent.get( + 'https://api.curve.finance/api/getPools/ethereum/factory-crypto' + ) + ).body as PartialCurvePoolData; + + const curvePoolDetailsResponse = ( + await superagent.get( + 'https://api.curve.finance/api/getFactoryAPYs?version=crypto' + ) + ).body as PartialCurvePoolDetails; + + const poolData = curvePoolDataResponse.data?.poolData.find( + (pool) => pool.id === 'factory-crypto-134' + ); + + const apyReward = poolData?.gaugeRewards.reduce( + (total, current) => total + current.apy, + 0 + ); + + const apyBase = curvePoolDetailsResponse?.data?.poolDetails?.find( + (pool) => pool.poolAddress === BLUSD_LUSD_3CRV_POOL_ADDRESS + )?.apy; + + const tvlUsd = poolData?.usdTotal; + + return { + pool: BLUSD_LUSD_3CRV_POOL_ADDRESS, + project: 'lusd-chickenbonds', + symbol: 'bLUSD/LUSD-3CRV', + chain: 'ethereum', + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [LUSD_ADDRESS, BLUSD_ADDRESS, LUSD_3CRV_POOL_ADDRESS], + rewardTokens: [ + BLUSD_ADDRESS, + LUSD_3CRV_POOL_ADDRESS, + LUSD_ADDRESS, + CRV_ADDRESS, + ], + poolMeta: + 'Staking bLUSD/LUSD-3CRV LP tokens in the Curve gauge earns yield from trade fees, Curve rewards and LUSD rewards from claimed bonds.', + }; +}; + +const getStrategies = async (): Promise => { + const bLusdRebondStrategy = await getBLusdRebondStrategy(); + const bLusdLusd3CrvPoolStrategy = await getBLusdLusd3CrvStrategy(); + + return [bLusdRebondStrategy, bLusdLusd3CrvPoolStrategy]; +}; + +module.exports = { + timetravel: false, + apy: getStrategies, + url: 'https://chickenbonds.org/', +}; diff --git a/src/adaptors/lusd-chickenbonds/types.ts b/src/adaptors/lusd-chickenbonds/types.ts new file mode 100644 index 0000000000..2e10df0412 --- /dev/null +++ b/src/adaptors/lusd-chickenbonds/types.ts @@ -0,0 +1,38 @@ +export type ChickenBondsStrategy = { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; +}; + +export type ChickenBondsStrategies = Array; + +export type PartialCurvePoolData = Partial<{ + data: { + poolData: Array<{ + id: string; + gaugeRewards: Array<{ apy: number }>; + usdTotal: number; + }>; + }; +}>; + +export type PartialCurvePoolDetails = Partial<{ + data: { + poolDetails: Array<{ poolAddress: string; apy: number }>; + }; +}>; + +module.exports = { + ChickenBondsStrategy, + ChickenBondsStrategies, + PartialCurvePoolData, + PartialCurvePoolDetails, +}; diff --git a/src/adaptors/luxsfi/abi.json b/src/adaptors/luxsfi/abi.json new file mode 100755 index 0000000000..01727b3858 --- /dev/null +++ b/src/adaptors/luxsfi/abi.json @@ -0,0 +1,68 @@ +[ + { + "inputs": [], + "name": "getStrategies", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "getStrategyBalance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + }, + { + "internalType": "int256", + "name": "_n", + "type": "int256" + } + ], + "name": "getStrategyAPR", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/luxsfi/index.js b/src/adaptors/luxsfi/index.js new file mode 100755 index 0000000000..67c50796e2 --- /dev/null +++ b/src/adaptors/luxsfi/index.js @@ -0,0 +1,134 @@ +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const BigNumber = require('bignumber.js'); +const ethers = require('ethers'); +const superagent = require('superagent'); + +const facades = { + polygon: '0x0708542D895C2559001Fa9e4Bc49C3343735e6e2', + arbitrum: '0xE75254f298a5145438595Aa9d6D4327fCD14418D', + bsc: '0xD187937762c6fd4d7a58C71fD810CbfE22E64a84', + optimism: '0x285cAee14514f30bB178FB56c985e43A47d68E75', +}; + +function ethersBNToBN(bn, decimals) { + return new BigNumber(ethers.utils.formatUnits(bn, decimals)); +} + +function aprToAPY(apr, timesCompounded) { + return apr.div(timesCompounded).plus(1).pow(timesCompounded).minus(1); +} + +const getChainPools = async (chain, facade) => { + // -----====== Get Strategies ======----- // + const strategies = ( + await sdk.api.abi.call({ + abi: abi.find((n) => n.name === 'getStrategies'), + params: [], + target: facade, + chain, + }) + ).output; + + // -----====== Get Balances ======----- // + const balancesR = ( + await sdk.api.abi.multiCall({ + abi: abi.find((n) => n.name === 'getStrategyBalance'), + calls: strategies.map((address) => ({ + target: facade, + params: [address], + })), + chain, + }) + ).output; + + // -----====== Get APRs ======----- // + const aprs = ( + await sdk.api.abi.multiCall({ + abi: abi.find((n) => n.name === 'getStrategyAPR'), + calls: strategies.map((address) => ({ + target: facade, + params: [address, 1], + })), + chain, + }) + ).output; + + // -----====== Get Underlying Tokens ======----- // + let priceKeys = []; + const underlyingBalances = {}; + balancesR.map((strategyBalance, index) => { + vaultAddr = strategyBalance.output[0].toLowerCase(); + tokenAddr = strategyBalance.output[1].toLowerCase(); + balance = strategyBalance.output[2]; + + const priceKey = `${chain}:${tokenAddr}`; + const underlyingTokens = `${vaultAddr}:${tokenAddr}`; + + priceKeys.includes(priceKey) ? null : priceKeys.push(priceKey); + + underlyingBalances[underlyingTokens] = balance; + }); + + // -----====== Get Prices ======----- // + const priceKeysQ = priceKeys.join(','); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeysQ}`) + ).body.coins; + + const apys = aprs.map((apr, index) => { + const aprBN = ethersBNToBN(apr.output, 4); + const apy = aprToAPY(aprBN, 365); + return apy.multipliedBy(100); + }); + + // -----====== Prepare Pools ======----- // + const pools = strategies.map((address, index) => { + const vaultAddr = balancesR[index].output[0].toLowerCase(); + const tokenAddr = balancesR[index].output[1].toLowerCase(); + + const priceKey = `${chain}:${tokenAddr}`; + const underlyingTokens = `${vaultAddr}:${tokenAddr}`; + + const symbol = prices[priceKey].symbol; + const decimals = prices[priceKey].decimals; + + const balance = underlyingBalances[underlyingTokens]; + + const tvlUsd = + ethers.utils.formatUnits(balance, decimals) * prices[priceKey].price; + + const apr = aprs[index].output; + const apy = apys[index]; + + return { + pool: `${vaultAddr}-${chain}`.toLowerCase(), + chain: chain, + project: 'luxsfi', + symbol: symbol, + tvlUsd: tvlUsd, + apy: apy.toNumber(), + underlyingTokens: [tokenAddr], + }; + }); + + return pools; +}; + +// -----====== Get Pools ======----- // +const getPools = async () => { + let pools = []; + + for (let chain in facades) { + const chainPools = await getChainPools(chain, facades[chain]); + pools = pools.concat(chainPools); + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.luxs.fi', +}; diff --git a/src/adaptors/lynex-v2/abis/factoryABI.json b/src/adaptors/lynex-v2/abis/factoryABI.json new file mode 100644 index 0000000000..8d9c823afb --- /dev/null +++ b/src/adaptors/lynex-v2/abis/factoryABI.json @@ -0,0 +1,321 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REFERRAL_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dibs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_stable", "type": "bool" }], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_dibs", "type": "address" } + ], + "name": "setDibs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_stable", "type": "bool" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_refFee", "type": "uint256" } + ], + "name": "setReferralFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feehandler", "type": "address" } + ], + "name": "setStakingFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setStakingFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingFeeHandler", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingNFTFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/lynex-v2/abis/gaugeABI.json b/src/adaptors/lynex-v2/abis/gaugeABI.json new file mode 100644 index 0000000000..0e563d7030 --- /dev/null +++ b/src/adaptors/lynex-v2/abis/gaugeABI.json @@ -0,0 +1,712 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_distribution", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isForPair", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DISTRIBUTION", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_VE", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "_balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeRewarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardForDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewarderPid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_distribution", + "type": "address" + } + ], + "name": "setDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeRewarder", + "type": "address" + } + ], + "name": "setGaugeRewarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "setRewarderPid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAllAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/adaptors/lynex-v2/abis/pairAPI.json b/src/adaptors/lynex-v2/abis/pairAPI.json new file mode 100644 index 0000000000..b079438059 --- /dev/null +++ b/src/adaptors/lynex-v2/abis/pairAPI.json @@ -0,0 +1,467 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "Owner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVoter", + "type": "address" + } + ], + "name": "Voter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldWBF", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newWBF", + "type": "address" + } + ], + "name": "WBF", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_EPOCHS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PAIRS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARDS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEEK", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "algebraFactory", + "outputs": [ + { + "internalType": "contract IAlgebraFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "_amounts", "type": "uint256" }, + { "internalType": "uint256", "name": "_offset", "type": "uint256" } + ], + "name": "getAllPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { "internalType": "string", "name": "symbol", "type": "string" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "bool", "name": "stable", "type": "bool" }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { "internalType": "address", "name": "token0", "type": "address" }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserve0", "type": "uint256" }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { "internalType": "address", "name": "token1", "type": "address" }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { "internalType": "address", "name": "fee", "type": "address" }, + { "internalType": "address", "name": "bribe", "type": "address" }, + { "internalType": "uint256", "name": "emissions", "type": "uint256" }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo[]", + "name": "Pairs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { "internalType": "string", "name": "symbol", "type": "string" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "bool", "name": "stable", "type": "bool" }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { "internalType": "address", "name": "token0", "type": "address" }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserve0", "type": "uint256" }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { "internalType": "address", "name": "token1", "type": "address" }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { "internalType": "address", "name": "gauge", "type": "address" }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { "internalType": "address", "name": "fee", "type": "address" }, + { "internalType": "address", "name": "bribe", "type": "address" }, + { "internalType": "uint256", "name": "emissions", "type": "uint256" }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo", + "name": "_pairInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amounts", "type": "uint256" }, + { "internalType": "uint256", "name": "_offset", "type": "uint256" }, + { "internalType": "address", "name": "_pair", "type": "address" } + ], + "name": "getPairBribe", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "epochTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVotes", + "type": "uint256" + }, + { "internalType": "address", "name": "pair", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint8", "name": "decimals", "type": "uint8" }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { "internalType": "string", "name": "symbol", "type": "string" } + ], + "internalType": "struct PairAPI.tokenBribe[]", + "name": "bribes", + "type": "tuple[]" + } + ], + "internalType": "struct PairAPI.pairBribeEpoch[]", + "name": "_pairEpoch", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voter", "type": "address" }, + { + "internalType": "contract IPairFactory", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_algebraFactory", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" }, + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "left", + "outputs": [ + { "internalType": "uint256", "name": "_rewPerEpoch", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFactory", + "outputs": [ + { "internalType": "contract IPairFactory", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voter", "type": "address" }, + { + "internalType": "contract IPairFactory", + "name": "_factory", + "type": "address" + } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { "internalType": "contract IVoter", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/lynex-v2/index.js b/src/adaptors/lynex-v2/index.js new file mode 100644 index 0000000000..c88737cbb1 --- /dev/null +++ b/src/adaptors/lynex-v2/index.js @@ -0,0 +1,251 @@ +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); +const { Web3 } = require('web3'); +const pairAPI = require('./abis/pairAPI.json'); +const factoryAbi = require('./abis/factoryABI.json'); +const { + getPrices, + getTokenPrice, + fetchPeriodFinish, + fetchExtraPoolRewards, + fromWei, + loadActiveStrategies, + fetchGammaInfo, +} = require('./utils'); + +const TEST_ACCOUNT = '0x1111110000000000000000000000000000000000'; + +const getApy = async () => { + const web3 = new Web3('https://rpc.linea.build'); + const pairAPIContract = new web3.eth.Contract( + pairAPI, + '0x6c84329CC8c37376eb32db50a17F3bFc917c3665' + ); + const factoryContract = new web3.eth.Contract( + factoryAbi, + '0xBc7695Fd00E3b32D08124b7a4287493aEE99f9ee' + ); + const lynxAddress = '0x1a51b19ce03dbe0cb44c1528e34a7edd7771e9af'; + const olynxAddress = '0x63349ba5e1f71252ecd56e8f950d1a518b400b60'; + let pairLength = 0; + let poolInfos; + let activeStrategies = []; + + // Load active strategies + try { + activeStrategies = await loadActiveStrategies(); + } catch (error) { + console.log('Error loading active stategies: ', error); + } + + // Fetch pair length + try { + pairLength = await Promise.all([ + factoryContract.methods.allPairsLength().call(), + ]); + } catch (error) { + console.log('Error fetching pairs length: ', error); + return; + } + + // Fetch pool info + try { + const [v2pools, gammaPools] = await Promise.all([ + pairAPIContract.methods + .getAllPair(TEST_ACCOUNT, Number(pairLength), 0) + .call(), + fetchGammaInfo(activeStrategies), + ]); + poolInfos = [...v2pools, ...gammaPools]; + } catch (error) { + console.log('Error fetching Pool Info: ', error); + return; + } + + // Format pool info + const pools = poolInfos.map((pool) => { + const firstSymbol = pool.token0_symbol; + const secondSymbol = pool.token1_symbol; + const poolAddress = String(pool.pair_address).toLowerCase(); + const found = activeStrategies.find( + (item) => item.address.toLowerCase() === poolAddress + ); + const poolMeta = found ? found.title : 'Classic'; + const symbol = found + ? `${firstSymbol}/${secondSymbol}` + : pool.stable + ? `sAMM-${firstSymbol}/${secondSymbol}` + : `vAMM-${firstSymbol}/${secondSymbol}`; + return { + title: found ? `${found.title}` : symbol, + symbol, + decimals: Number(pool.decimals), + address: poolAddress, + isFusion: !!found, + type: found ? found.type : pool.stable ? 'Stable' : 'Volatile', + totalSupply: fromWei(Number(pool.total_supply), Number(pool.decimals)), + token0Address: pool.token0, + token0Symbol: firstSymbol, + token0Decimals: Number(pool.token0_decimals), + token0Reserve: fromWei( + Number(pool.reserve0), + Number(pool.token0_decimals) + ), + token1Address: pool.token1, + token1Symbol: secondSymbol, + token1Decimals: Number(pool.token1_decimals), + token1Reserve: fromWei( + Number(pool.reserve1), + Number(pool.token1_decimals) + ), + gaugeAddress: pool.gauge, + gaugeTotalSupply: fromWei( + Number(pool.gauge_total_supply), + Number(pool.decimals) + ), + gaugeFee: pool.fee, + gaugeBribe: pool.bribe, + gaugeRewardPerSecond: fromWei( + Number(pool.emissions), + Number(pool.emissions_token_decimals) + ), + poolMeta, + }; + }); + + let periodFinishes; + try { + periodFinishes = await fetchPeriodFinish(pools); + } catch (error) { + console.log(`Gauge Period Finish Fetch Error: ${error}`); + return; + } + let poolExtraRewrards; + try { + poolExtraRewrards = await fetchExtraPoolRewards(pools); + } catch (error) { + console.log(`Extra Rewards Fetch Error: ${error}`); + return; + } + + // Get tokens + const tokens = []; + try { + pools.map((pool) => { + if (!tokens.includes(pool.token0Address.toLowerCase())) { + tokens.push(pool.token0Address.toLowerCase()); + } + if (!tokens.includes(pool.token1Address.toLowerCase())) { + tokens.push(pool.token1Address.toLowerCase()); + } + }); + } catch { + console.log('Error getting the pools tokens: ', error); + return; + } + + // Fetch token prices + let prices; + try { + prices = await getPrices(tokens); + } catch { + console.log("Error getting the token's prices: ", error); + return; + } + + // Put all together + const returnData = pools.map((pool, i) => { + let tvl; + let rewardsTokens = [olynxAddress]; + let extraRewardsApy = 0; + let fusionSymbol = ''; + let gaugeTvl = new BigNumber(0); + + // Get TVL + try { + const asset0Price = !pool.token0Address + ? 0 + : prices.get(pool.token0Address.toLowerCase()); + const asset1Price = !pool.token1Address + ? 0 + : prices.get(pool.token1Address.toLowerCase()); + if (asset0Price && asset1Price && asset0Price > 0 && asset1Price > 0) { + tvl = pool.token0Reserve + .times(asset0Price || 0) + .plus(pool.token1Reserve.times(asset1Price)); + } else if (asset0Price > 0) { + tvl = pool.token0Reserve.times(asset0Price).times(2); + } else if (asset1Price > 0) { + tvl = pool.token1Reserve.times(asset1Price).times(2); + } else { + tvl = new BigNumber(0); + } + const lpPrice = pool.totalSupply.isZero() + ? new BigNumber(0) + : tvl.div(pool.totalSupply); + gaugeTvl = pool.gaugeTotalSupply.times(lpPrice); + } catch { + console.log('Error while calculating TVL'); + } + + // Get Extra Rewards + if (poolExtraRewrards[i].length > 0) { + poolExtraRewrards[i].forEach((extraReward) => { + try { + rewardsTokens.push(extraReward.tokenAddress); + const rewardPrice = prices.get( + extraReward.tokenAddress.toLowerCase() + ); + const rewardPerSecond = fromWei(extraReward.rewardRate.toString()); + const apr = + gaugeTvl.isZero() || extraReward.isFinished + ? 0 + : rewardPerSecond + .times(rewardPrice) + .times(86400 * 365) + .div(gaugeTvl) + .times(100) + .toNumber(); + extraRewardsApy += apr; + } catch { + console.log('Error while calculating Extra Rewards: ' + extraReward); + } + }); + } + + // Get APY + let apy = 0; + try { + if (!gaugeTvl.isZero() && !periodFinishes[i] && prices) { + apy = pool.gaugeRewardPerSecond + .times(prices.get(lynxAddress)) + .times(86400 * 365) + .div(gaugeTvl) + .times(100) + .toNumber(); + } + } catch { + console.log('Error while calculating APY'); + } + + return { + pool: `${pool.address}-lynex-fusion`, + chain: utils.formatChain('linea'), + project: 'lynex-v2', + symbol: pool.symbol, + tvlUsd: tvl.toNumber(), + apyBase: apy, + apyReward: extraRewardsApy, + rewardTokens: rewardsTokens, + underlyingTokens: [pool.token0Address, pool.token1Address], + poolMeta: pool.poolMeta ?? null, + }; + }); + return returnData; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.lynex.fi/liquidity', +}; diff --git a/src/adaptors/lynex-v2/utils.js b/src/adaptors/lynex-v2/utils.js new file mode 100644 index 0000000000..fe0272df82 --- /dev/null +++ b/src/adaptors/lynex-v2/utils.js @@ -0,0 +1,226 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const gaugeAbi = require('./abis/gaugeABI.json') +const pairAPI = require('./abis/pairAPI.json'); +const BigNumber = require('bignumber.js'); +const _ = require('lodash'); +const TEST_ACCOUNT = '0x1111110000000000000000000000000000000000' +const DEXSCREENER_ENDPOINT = 'https://api.dexscreener.com/latest/dex/tokens/'; +const DEFILLAMA_ENDPOINT = 'https://coins.llama.fi/prices/current/'; +const lynxAddress = '0x1a51b19ce03dbe0cb44c1528e34a7edd7771e9af'; +const olynxAddress = '0x63349ba5e1f71252ecd56e8f950d1a518b400b60' +const btcs = ['0x5ffce65a40f6d3de5332766fff6a28bf491c868c', '0xe4d584ae9b753e549cae66200a6475d2f00705f7']; +const PROBLEM_POOLS = { '0x8dabf94c7bdd771e448a4ae4794cd71f9f3d7a0d': 0 }; +const strategyUrl = 'https://raw.githubusercontent.com/Lynexfi/lynex-lists/main/config/strategies.json' + +const EXTRA_REWARDTOKENS = { + '0x96b7062cfd1af7e4de5ef513ce66015e9ee6a991': ['0x5fbdf89403270a1846f5ae7d113a989f850d1566', '0x43e8809ea748eff3204ee01f08872f063e44065f', '0x78354f8dccb269a615a7e0a24f9b0718fdc3c7a7'], + '0x72125a1c4a6e663c5e4da0bbfff9ae02b5ef727a': ['0x5fbdf89403270a1846f5ae7d113a989f850d1566', '0x43e8809ea748eff3204ee01f08872f063e44065f', '0x78354f8dccb269a615a7e0a24f9b0718fdc3c7a7'], + '0x68672d332d246508b519defa1beac74e2d2f00b5': ['0x5fbdf89403270a1846f5ae7d113a989f850d1566', '0x43e8809ea748eff3204ee01f08872f063e44065f', '0x78354f8dccb269a615a7e0a24f9b0718fdc3c7a7'], + '0x0cc0439c04760db602ee7ca2cbb4372ba4d28476': ['0x5fbdf89403270a1846f5ae7d113a989f850d1566', '0x43e8809ea748eff3204ee01f08872f063e44065f', '0x78354f8dccb269a615a7e0a24f9b0718fdc3c7a7'], + '0x14af0979e96dea94ad2466dfdf11e85886ce04f9': ['0x5fbdf89403270a1846f5ae7d113a989f850d1566', '0x43e8809ea748eff3204ee01f08872f063e44065f', '0x78354f8dccb269a615a7e0a24f9b0718fdc3c7a7'], +}; + +const getDefillamaPrice = async (address) => { + try { + const chainToken = `linea:${address}`; + const res = await axios.get(DEFILLAMA_ENDPOINT + chainToken); + const items = Object.values(res.data.coins); + if (items.length > 0) { + return items[0].price; + } + return 0; + } catch (error) { + console.log(`Defillama api error: ${address} ${error}`); + return 0; + } +}; + +const getDexScreenerPrice = async (address) => { + try { + const queryUrl = DEXSCREENER_ENDPOINT + address; + const res = await axios.get(queryUrl); + if (res.data.pairs && res.data.pairs.length > 0) { + const found = res.data.pairs.find( + pair => pair.baseToken.address.toLowerCase() === address + ); + if (found) { + return Number(found.priceUsd); + } + } + return 0; + } catch (error) { + console.log(`Dexscreener api error: ${address} ${error}`); + return 0; + } +}; + +const getTokenPrice = async (address) => { + if (lynxAddress.toLowerCase().includes(address.toLowerCase())) { + return getDexScreenerPrice(address); + } + if (btcs.includes(address.toLowerCase())) { + const price = await getDexScreenerPrice( + '0x3aab2285ddcddad8edf438c1bab47e1a9d05a9b4' + ); + if (price) return price; + } + let price = await getDefillamaPrice(address); + if (price === 0) { + price = await getDexScreenerPrice(address); + } + return price; +}; + +const getPrices = async (addresses) => { + const prices = new Map(); + await Promise.all(addresses.map(async (address) => { + if (!prices.has(address)) { + const price = await getTokenPrice(address); + prices.set(address, price); + } + })); + return prices; +}; + +const fetchExtraPoolRewards = async (pools) => { + const filteredPools = pools.filter(pool => pool.gaugeAddress !== '0x0000000000000000000000000000000000000000'); + const rewardRateCalls = []; + const periodCalls = []; + + filteredPools.forEach((pool) => { + const extraRewardTokenAddresses = EXTRA_REWARDTOKENS[pool.gaugeAddress.toLowerCase()]; + if (extraRewardTokenAddresses) { + extraRewardTokenAddresses.forEach((tokenAddress) => { + rewardRateCalls.push({ + target: pool.gaugeAddress, + params: [tokenAddress], + }); + periodCalls.push({ + target: pool.gaugeAddress, + params: [tokenAddress], + }); + }); + } + }); + + const rew = await sdk.api.abi.multiCall({ abi: gaugeAbi.find((m) => m.name === 'rewardRate'), calls: rewardRateCalls, chain: 'linea' }); + const per = await sdk.api.abi.multiCall({ abi: gaugeAbi.find((m) => m.name === 'periodFinish'), calls: periodCalls, chain: 'linea' }); + const rewards = rew.output.map((res) => { return res.output }) + const periods = per.output.map((res) => { return res.output }) + + let index = 0; + const currentTimeStamp = Math.round(new Date().getTime() / 1000); + const result = pools + .map((pool) => { + const processResult = []; + const extraRewardTokenAddresses = EXTRA_REWARDTOKENS[pool.gaugeAddress.toLowerCase()]; + if (pool.gaugeAddress !== '0x0000000000000000000000000000000000000000' && extraRewardTokenAddresses) { + extraRewardTokenAddresses.forEach((tokenAddress) => { + const isFinished = + Number(periods[index]) < currentTimeStamp; + processResult.push({ + isFinished, + rewardRate: rewards[index], + tokenAddress, + periodFinishes: periods[index], + }); + index += 1; + }); + } + return processResult; + }); + return result; +}; + +const fetchPeriodFinish = async (pools) => { + const calls = pools + .filter(pool => pool.gaugeAddress !== '0x0000000000000000000000000000000000000000') + .map(pool => ({ + target: pool.gaugeAddress, + params: [olynxAddress], + })); + const res = await sdk.api.abi.multiCall({ abi: gaugeAbi.find((m) => m.name === 'periodFinish'), calls, chain: 'linea' }); + let index = 0; + const currentTimeStamp = new Date().getTime() / 1000; + return pools + .map((pool) => { + if (pool.gaugeAddress !== '0x0000000000000000000000000000000000000000') { + const isFinished = res[index] < currentTimeStamp; + index += 1; + return isFinished; + } + return true; + }); +}; + +const fromWei = (number, decimals = 18) => new BigNumber(number).div(new BigNumber(10).pow(decimals)); + +const loadActiveStrategies = async () => { + let activeStrategies = [] + try { + const res = await axios.get(strategyUrl) + activeStrategies = res.data['59144']; + const validPools = activeStrategies.filter( + (strat) => PROBLEM_POOLS[strat.address] === undefined, + ); + activeStrategies = validPools; + } catch (e) { + console.log('Error processing strategies', e); + } + return activeStrategies; +} + +const fetchGammaInfo = async (activeStrategies) => { + const calls = activeStrategies + .map((pool) => ({ + target: '0x6c84329CC8c37376eb32db50a17F3bFc917c3665', + name: 'getPair', + params: [pool.address, TEST_ACCOUNT], + })); + const res = await sdk.api.abi.multiCall({ abi: pairAPI.find((m) => m.name === 'getPair'), calls, chain: 'linea' }); + + const processedData = res.output.map(({ output }) => { + return { + pair_address: output[0], + symbol: output[1], + name: output[2], + decimals: output[3], + stable: output[4], + total_supply: output[5], + token0: output[6], + token0_symbol: output[7], + token0_decimals: output[8], + reserve0: output[9], + claimable0: output[10], + token1: output[11], + token1_symbol: output[12], + token1_decimals: output[13], + reserve1: output[14], + claimable1: output[15], + gauge: output[16], + gauge_total_supply: output[17], + fee: output[18], + bribe: output[19], + emissions: output[20], + emissions_token: output[21], + emissions_token_decimals: output[22], + account_lp_balance: output[23], + account_token0_balance: output[24], + account_token1_balance: output[25], + account_gauge_balance: output[26], + account_gauge_earned: output[27] + }; + }); + return processedData; +} + +module.exports = { + getPrices, + getTokenPrice, + fetchExtraPoolRewards, + fetchPeriodFinish, + fromWei, + loadActiveStrategies, + fetchGammaInfo, +}; \ No newline at end of file diff --git a/src/adaptors/lyra-v1/index.js b/src/adaptors/lyra-v1/index.js new file mode 100644 index 0000000000..62cdc51cfc --- /dev/null +++ b/src/adaptors/lyra-v1/index.js @@ -0,0 +1,123 @@ +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const url = + 'https://subgraph.satsuma-prod.com/sw9vuxiQey3c/lyra/optimism-mainnet-newport/api'; + +const SECONDS_IN_MONTH = 2592000; +const MONTHS_IN_YEAR = 12; + +const query = gql` + { + markets{ + id + quoteAddress + liquidityPool{ + id + } + name + marketTotalValueHistory(first: 1 where:{timestamp_gte: } orderBy:timestamp orderDirection: asc){ + timestamp + tokenPrice + NAV + } + } + } +`; + +const queryNow = gql` + { + markets { + id + quoteAddress + liquidityPool { + id + } + name + marketTotalValueHistory( + first: 1 + orderBy: timestamp + orderDirection: desc + ) { + timestamp + tokenPrice + NAV + } + } + } +`; + +const apy = async (timestamp = null) => { + const data = ( + await request( + url, + (timestamp == null ? queryNow : query).replace('', timestamp) + ) + ).markets; + + // note: lyra used 30day window for calculating this...given their options have a 7d window + // it would make more sense to switch to 7day apy values instead... + const priorTimestamp30d = + timestamp == null + ? Math.floor(Date.now() / 1000) - SECONDS_IN_MONTH + : timestamp - SECONDS_IN_MONTH; + + const dataPrior30d = ( + await request(url, query.replace('', priorTimestamp30d)) + ).markets; + + const priorTimestamp7d = Math.floor(Date.now() / 1000) - 604800; + const dataPrior7d = ( + await request(url, query.replace('', priorTimestamp7d)) + ).markets; + + return data + .map((p) => { + const marketTotalValueHistory30d = dataPrior30d.find( + (el) => el.id === p.id + )?.marketTotalValueHistory; + + const marketTotalValueHistory7d = dataPrior7d.find( + (el) => el.id === p.id + )?.marketTotalValueHistory; + + if ( + !marketTotalValueHistory30d?.length || + !marketTotalValueHistory7d?.length + ) + return null; + + const NAV = p.marketTotalValueHistory[0].NAV / 1e18; + const tokenPriceNow = p.marketTotalValueHistory[0].tokenPrice / 1e18; + + const tokenPricePrior30d = + marketTotalValueHistory30d[0].tokenPrice / 1e18; + + const tokenPricePrior7d = marketTotalValueHistory7d[0].tokenPrice / 1e18; + + const return30d = + (tokenPriceNow - tokenPricePrior30d) / tokenPricePrior30d; + + const return7d = (tokenPriceNow - tokenPricePrior7d) / tokenPricePrior7d; + + return { + pool: p.liquidityPool.id, + chain: utils.formatChain('optimism'), + project: 'lyra-v1', + symbol: 'sUSD', + poolMeta: `${p.name}-Vault`, + apyBase: return30d * MONTHS_IN_YEAR * 100, + tvlUsd: NAV, + underlyingTokens: [p.quoteAddress], + il7d: return7d > 0 ? null : return7d * 100, + }; + }) + .filter((p) => p !== null); +}; + +module.exports = { + timetravel: true, + apy, + url: 'https://app.lyra.finance/vaults', +}; diff --git a/src/adaptors/magik-farm/config/index.js b/src/adaptors/magik-farm/config/index.js new file mode 100644 index 0000000000..b8207e273a --- /dev/null +++ b/src/adaptors/magik-farm/config/index.js @@ -0,0 +1,24 @@ +const bscPools = require('./vault/bsc_pools'); +const hecoPools = require('./vault/heco_pools'); +const avalanchePools = require('./vault/avalanche_pools'); +const celoPools = require('./vault/celo_pools'); +const moonriverPools = require('./vault/moonriver_pools'); +const polygonPools = require('./vault/polygon_pools'); +const fantomPools = require('./vault/fantom_pools'); +const auroraPools = require('./vault/aurora_pools'); +const harmonyPools = require('./vault/harmony_pools'); +const arbitrumPools = require('./vault/arbitrum_pools'); +const cronosPools = require('./vault/cronos_pools'); +module.exports = { + bscPools, + hecoPools, + avalanchePools, + celoPools, + moonriverPools, + polygonPools, + fantomPools, + auroraPools, + harmonyPools, + arbitrumPools, + cronosPools, +}; diff --git a/src/adaptors/magik-farm/config/vault/arbitrum_pools.js b/src/adaptors/magik-farm/config/vault/arbitrum_pools.js new file mode 100644 index 0000000000..fec48aca95 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/arbitrum_pools.js @@ -0,0 +1,2 @@ +const arbitrumPools = []; +module.exports = arbitrumPools; diff --git a/src/adaptors/magik-farm/config/vault/aurora_pools.js b/src/adaptors/magik-farm/config/vault/aurora_pools.js new file mode 100644 index 0000000000..5980982a7e --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/aurora_pools.js @@ -0,0 +1,38 @@ +const auroraPools = [ + { + id: 'carbon-carbon-near', + name: 'CARBON-NEAR LP 🔥', + token: 'CARBON-NEAR LP 🔥', + tokenDescription: 'carbon-fi.net - CARBON-NEAR LP AC Auto Burn Vault 🔥', + tokenAddress: '0x98Cf148cdC3E6d546D30717cE034C365ba204A4F', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - CARBON-NEAR LP', + earnedTokenAddress: '0xf81176796308D1154bb6Ed3D0Ca8e07a1E283600', + earnContractAddress: '0xf81176796308D1154bb6Ed3D0Ca8e07a1E283600', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'carbon-carbon-near', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'Carbon', + assets: ['CARBON', 'NEAR'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_HIGH', + 'MCAP_MEDIUM', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + buyTokenUrl: + 'https://www.trisolaris.io/#/swap?inputCurrency=0xC42C30aC6Cc15faC9bD938618BcaA1a1FaE8501d&outputCurrency=0x33ADf08ae486bf89ABc9634f6623A997FFDB66e7', + addLiquidityUrl: + 'https://www.trisolaris.io/#/add/0xC42C30aC6Cc15faC9bD938618BcaA1a1FaE8501d/0x33ADf08ae486bf89ABc9634f6623A997FFDB66e7', + }, +]; + +module.exports = auroraPools; diff --git a/src/adaptors/magik-farm/config/vault/avalanche_pools.js b/src/adaptors/magik-farm/config/vault/avalanche_pools.js new file mode 100644 index 0000000000..7ad1c22b20 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/avalanche_pools.js @@ -0,0 +1,570 @@ +const avalanchePools = [ + { + id: 'cham-avic-usdc', + name: 'AVIC - USDC 🔥', + token: 'AVIC - USDC', + tokenDescription: + 'Championfinance.io - AVIC-USDC LP AC Auto Fee Share Vault 🔥', + tokenAddress: '0x7748456409D4Eee3FaCE6aD0c492DD9853A1CC3d', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - AVIC-USDC LP', + earnedTokenAddress: '0x720Ee1f99eAB68ffB5182510EBC66c365BfD442b', + earnContractAddress: '0x720Ee1f99eAB68ffB5182510EBC66c365BfD442b', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'cham-avic-usdc', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Championfinance', + assets: ['AVIC', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x59B18817CA9f4ad2dEE6FBf30132dF6AEb9D763d/0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x59B18817CA9f4ad2dEE6FBf30132dF6AEb9D763d&outputCurrency=0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e#/', + }, + { + id: 'cham-cham-usdc', + name: 'CHAM - USDC 🔥', + token: 'CHAM - USDC', + tokenDescription: + 'Championfinance.io - CHAM-USDC LP AC Auto Fee Share Vault 🔥', + tokenAddress: '0xd6F18CDe9A52A9D815dd3C03C2325D453E32BDef', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - CHAM-USDC LP', + earnedTokenAddress: '0x24dDB3c0F3B51D832cf43c3b121987b8698e32aD', + earnContractAddress: '0x24dDB3c0F3B51D832cf43c3b121987b8698e32aD', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'cham-cham-usdc', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Championfinance', + assets: ['CHAM', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0xc65bC1E906771e105fBAcBD8dfE3862Ee7BE378E/0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xc65bC1E906771e105fBAcBD8dfE3862Ee7BE378E&outputCurrency=0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e#/', + }, + { + id: 'cham-avic-cham', + name: 'AVIC - CHAM 🔥', + token: 'AVIC - CHAM', + tokenDescription: + 'Championfinance.io - AVIC-CHAM LP AC Auto Fee Share Vault 🔥', + tokenAddress: '0x17f2F59331de85e0b9dCE25EAB48aEBF71C63e46', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - AVIC-CHAM LP', + earnedTokenAddress: '0x2a426A878BB768473AD898aC7f8ee41b0894ee56', + earnContractAddress: '0x2a426A878BB768473AD898aC7f8ee41b0894ee56', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'cham-avic-cham', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Championfinance', + assets: ['CHAM', 'AVIC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x59B18817CA9f4ad2dEE6FBf30132dF6AEb9D763d/0xc65bC1E906771e105fBAcBD8dfE3862Ee7BE378E#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xc65bC1E906771e105fBAcBD8dfE3862Ee7BE378E&outputCurrency=0x59B18817CA9f4ad2dEE6FBf30132dF6AEb9D763d#/', + }, + { + id: 'grape-grapesp-mim', + name: 'SL GRAPE - MIM 🔥', + token: 'SL GRAPE - MIM', + tokenDescription: + '(WINE FARM) - Swapsicle GRAPE - MIM LP AC Auto Burn Vault 🔥', + tokenAddress: '0x9076C15D7b2297723ecEAC17419D506AE320CbF1', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - Sl - Grape - MIM LP', + earnedTokenAddress: '0x0dA1DC567D81925cFf22Df74C6b9e294E9E1c3A5', + earnContractAddress: '0x0dA1DC567D81925cFf22Df74C6b9e294E9E1c3A5', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'grape-grapesp-mim', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Grape', + assets: ['GRAPE', 'MIM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://www.swapsicle.io/add/0x130966628846BFd36ff31a822705796e8cb8C18D/0x5541D83EFaD1f281571B343977648B75d95cdAC2', + buyTokenUrl: + 'https://www.swapsicle.io/swap/0x130966628846bfd36ff31a822705796e8cb8c18d/0x5541d83efad1f281571b343977648b75d95cdac2', + }, + { + id: 'swapsicle-grape-mim', + name: 'Swapsicle GRAPE - MIM 🔥', + token: 'Swapsicle GRAPE - MIM', + tokenDescription: + 'swapsicle.io - Swapsicle GRAPE - MIM LP AC Auto Burn Vault 🔥', + tokenAddress: '0x9076C15D7b2297723ecEAC17419D506AE320CbF1', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - Swapsicle - Grape - MIM LP', + earnedTokenAddress: '0x7c9EeC0e542DF35280224bECf9AF76d2E4cD910f', + earnContractAddress: '0x7c9EeC0e542DF35280224bECf9AF76d2E4cD910f', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'swapsicle-grape-mim', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Swapsicle', + assets: ['GRAPE', 'MIM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://www.swapsicle.io/add/0x130966628846BFd36ff31a822705796e8cb8C18D/0x5541D83EFaD1f281571B343977648B75d95cdAC2', + buyTokenUrl: + 'https://www.swapsicle.io/swap/0x130966628846bfd36ff31a822705796e8cb8c18d/0x5541d83efad1f281571b343977648b75d95cdac2', + }, + { + id: 'grape-grape', + logo: 'single-assets/GRAPE.png', + name: 'GRAPE 🔥', + token: 'GRAPE', + tokenDescription: + 'grapefinance.app - GRAPE Single Stake AC Auto Burn Vault', + tokenAddress: '0x5541D83EFaD1f281571B343977648B75d95cdAC2', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - GRAPE Single Stake', + earnedTokenAddress: '0xDFc0Cc5c036c52131fb351e50ba322b4D00Ce60B', + earnContractAddress: '0xDFc0Cc5c036c52131fb351e50ba322b4D00Ce60B', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'GRAPE', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'Grape', + assets: ['GRAPE'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x130966628846bfd36ff31a822705796e8cb8c18d&outputCurrency=0xc55036b5348cfb45a932481744645985010d3a44#/', + }, + { + id: 'grape-grape-mim', + name: 'GRAPE - MIM 🔥', + token: 'GRAPE - MIM', + tokenDescription: 'grapefinance.app - GRAPE - MIM LP AC Auto Burn Vault 🔥', + tokenAddress: '0xb382247667fe8CA5327cA1Fa4835AE77A9907Bc8', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - Grape - MIM LP', + earnedTokenAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + earnContractAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'grape-grape-mim', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Grape', + assets: ['GRAPE', 'MIM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x130966628846bfd36ff31a822705796e8cb8c18d/0x5541d83efad1f281571b343977648b75d95cdac2#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x130966628846bfd36ff31a822705796e8cb8c18d&outputCurrency=0x5541d83efad1f281571b343977648b75d95cdac2#/', + }, + { + id: 'grape-wine-mim', + name: 'WINE - MIM ', + token: 'WINE - MIM', + tokenDescription: 'grapefinance.app - WINE - MIM LP AC Vault ', + tokenAddress: '0x00cB5b42684DA62909665d8151fF80D1567722c3', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WINE-MIM LP', + earnedTokenAddress: '0x0B2a90132fC171B37c6999845703C90479B7124F', + earnContractAddress: '0x0B2a90132fC171B37c6999845703C90479B7124F', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'grape-wine-mim', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Grape', + assets: ['WINE', 'MIM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x130966628846bfd36ff31a822705796e8cb8c18d/0xc55036b5348cfb45a932481744645985010d3a44#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x130966628846bfd36ff31a822705796e8cb8c18d&outputCurrency=0xc55036b5348cfb45a932481744645985010d3a44#/', + }, + { + id: 'grape-grape-wine', + name: 'GRAPE - WINE ', + token: 'GRAPE - WINE', + tokenDescription: 'grapefinance.app - GRAPE - WINE LP AC Vault ', + tokenAddress: '0xd3d477Df7f63A2623464Ff5Be6746981FdeD026F', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - GRAPE-WINE LP', + earnedTokenAddress: '0x03bC623B17f6D34Fc861d7C4C17D927B50994D7c', + earnContractAddress: '0x03bC623B17f6D34Fc861d7C4C17D927B50994D7c', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'grape-wine-mim', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Grape', + assets: ['GRAPE', 'WINE'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x5541d83efad1f281571b343977648b75d95cdac2/0xc55036b5348cfb45a932481744645985010d3a44#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x5541d83efad1f281571b343977648b75d95cdac2&outputCurrency=0xc55036b5348cfb45a932481744645985010d3a44#/', + }, + { + id: 'joe-wlrs-usdibs', + name: 'WLRS - USDibs 🔥', + token: 'WLRS - USDibs 🔥', + tokenDescription: + 'frozenwalrus.finance - WLRS - USDibs LP AC Auto Burn Vault 🔥', + tokenAddress: '0x26E6E2CbE80A7408573BE67578ee5c10F2984f99', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WLRS - USDIBS', + earnedTokenAddress: '0xda77b161A9aBc0a22406D1B618DcC68D5737Cb9A', + earnContractAddress: '0xda77b161A9aBc0a22406D1B618DcC68D5737Cb9A', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'joe-wlrs-usdibs', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['WLRS', 'USDIBS'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0x0EfA5328FEfCe96C8d10661bd97403764D477853/0x395908aeb53d33A9B8ac35e148E9805D34A555D3#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0x0EfA5328FEfCe96C8d10661bd97403764D477853&outputCurrency=0x395908aeb53d33A9B8ac35e148E9805D34A555D3#/', + }, + { + id: 'joe-nrwl-yusd', + name: 'NRWL - YUSD 🔥', + token: 'NRWL - YUSD 🔥', + tokenDescription: + 'frozenwalrus.finance - NRWL - YUSD LP AC Auto Burn Vault 🔥', + tokenAddress: '0xE4f4f9DD9cD45bC44FD517f4AE490591030274F6', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - NRWL-YUSD', + earnedTokenAddress: '0xCa887Ed67D7031cdEcd93b6670909EE00ccEBB68', + earnContractAddress: '0xCa887Ed67D7031cdEcd93b6670909EE00ccEBB68', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'joe-nrwl-yusd', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['NRWL', 'YUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://www.swapsicle.io/add/0x501012893eE88976AB8B5289B7a78E307d5d9DCb/0x111111111111ed1D73f860F57b2798b683f2d325', + buyTokenUrl: + 'https://www.swapsicle.io/swap/0x501012893eE88976AB8B5289B7a78E307d5d9DCb/0x111111111111ed1D73f860F57b2798b683f2d325', + }, + { + id: 'joe-wlrs-usdc', + name: 'WLRS - USDC.e 🔥', + token: 'WLRS - USDC.e 🔥', + tokenDescription: + 'frozenwalrus.finance - WLRS - USDC.e LP AC Auto Burn Vault 🔥', + tokenAddress: '0x82845B52b53c80595bbF78129126bD3E6Fc2C1DF', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WLRS - USDC', + earnedTokenAddress: '0x92B1B91237388c2611Aa5df29A8059c9C8BE2366', + earnContractAddress: '0x92B1B91237388c2611Aa5df29A8059c9C8BE2366', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'joe-wlrs-usdc', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['WLRS', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664/0x395908aeb53d33A9B8ac35e148E9805D34A555D3#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664&outputCurrency=0x395908aeb53d33A9B8ac35e148E9805D34A555D3#/', + }, + { + id: 'joe-wshare-usdc', + name: 'WSHARE - USDC.e 🔥', + token: 'WSHARE - USDC.e 🔥', + tokenDescription: 'frozenwalrus.finance - WSHARE - USDC.e LP AC Vault 🔥', + tokenAddress: '0x03d15E0451e54Eec95ac5AcB5B0a7ce69638c62A', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WSHARE - USDC', + earnedTokenAddress: '0xFD368aCD61dAFDceB544309a3F793Dab5c615fAe', + earnContractAddress: '0xFD368aCD61dAFDceB544309a3F793Dab5c615fAe', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'joe-wshare-usdc', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['WSHARE', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664/0xe6d1aFea0B76C8f51024683DD27FA446dDAF34B6#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664&outputCurrency=0xe6d1aFea0B76C8f51024683DD27FA446dDAF34B6#/', + }, + { + id: 'piggy-piggy-avax', + name: 'PIGGY - AVAX 🔥', + token: 'PIGGY - AVAX 🔥', + tokenDescription: 'piggyfinance.io - PIGGY - AVAX LP AC Auto Burn Vault 🔥', + tokenAddress: '0x2440885843d8e9f16a4b64933354d1CfBCf7F180', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - PIGGY - AVAX', + earnedTokenAddress: '0xe74131997f5e61a06384a70F2a924fCBDb102035', + earnContractAddress: '0xe74131997f5e61a06384a70F2a924fCBDb102035', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'piggy-piggy-avax', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['PIGGY', 'AVAX'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/AVAX/0x1a877B68bdA77d78EEa607443CcDE667B31B0CdF#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?outputCurrency=0x1a877B68bdA77d78EEa607443CcDE667B31B0CdF', + }, + { + id: 'bam-bam-usdc', + name: 'BAM - USDC 🔥', + token: 'BAM - USDC 🔥', + tokenDescription: 'bamboofinance.app - BAM - USDC LP AC Auto Burn Vault 🔥', + tokenAddress: '0xbe7C737FCC2D6EBA0e4e73A073a0120171287769', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - BAM - USDC', + earnedTokenAddress: '0x12AefAa0c1961d450D5772a5e94D721A9eBAF72c', + earnContractAddress: '0x12AefAa0c1961d450D5772a5e94D721A9eBAF72c', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'bam-bam-usdc', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['BAM', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E/0x5cc339Aa2A582D857F38B85F662Ea3513706a1E7#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E&outputCurrency=0x5cc339Aa2A582D857F38B85F662Ea3513706a1E7#/', + }, + { + id: 'bam-bdao-usdc', + name: 'BDAO - USDC 🔥', + token: 'BDAO - USDC 🔥', + tokenDescription: 'bamboofinance.app - BDAO - USDC LP AC Vault', + tokenAddress: '0x0774F0acC4DD1CA84BC8521FEe6dC2f7D22f133f', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - BDAO - USDC', + earnedTokenAddress: '0xB5E8BB16a8cc347d3671Cb7d855a7776e34c9E35', + earnContractAddress: '0xB5E8BB16a8cc347d3671Cb7d855a7776e34c9E35', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'bam-bdao-usdc', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'JOE', + assets: ['BDAO', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://traderjoexyz.com/pool/0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E/0x83c7412931398502922a35911E5Fab221822f4B6#/', + buyTokenUrl: + 'https://traderjoexyz.com/trade?inputCurrency=0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E&outputCurrency=0x83c7412931398502922a35911E5Fab221822f4B6#/', + }, +]; +module.exports = avalanchePools; diff --git a/src/adaptors/magik-farm/config/vault/bsc_pools.js b/src/adaptors/magik-farm/config/vault/bsc_pools.js new file mode 100644 index 0000000000..329f29ab29 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/bsc_pools.js @@ -0,0 +1,720 @@ +const bscPools = [ + { + id: 'orb-orb-magik', + name: 'MAGIK-WBNB LP 🔥', + token: 'MAGIK-WBNB LP 🔥', + tokenDescription: + 'orbitalswap.com - MAGIK - WBNB LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x3Cd3E322f0112a296192E3Dc2742E96D5107DcF8', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Orb-MAGIK-WBNB', + earnedTokenAddress: '0x929070d727F802aa6b78BDD3E8B06108FE7A20d5', + earnContractAddress: '0x929070d727F802aa6b78BDD3E8B06108FE7A20d5', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-orb-magik', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['MAGIK', 'WBNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/BNB/0xD68F75b3aa54bee23e6Ac3AD4b3C28D3E6319725', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0xD68F75b3aa54bee23e6Ac3AD4b3C28D3E6319725', + createdAt: 1648773316, + }, + { + id: 'dibs-usdibs-busd', + name: 'usDIBS-BUSD LP 🔥', + token: 'usDIBS-BUSD LP 🔥', + tokenDescription: + 'Dibs.Money - usDIBS - BUSD LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xADB3C33d435cEFd6A43e802cae917D9f9EE15A0b', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-usDibs-BUSD', + earnedTokenAddress: '0xa097CE648CaB3a4238a22A826B453f4F173b64a0', + earnContractAddress: '0xa097CE648CaB3a4238a22A826B453f4F173b64a0', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'dibs-usdibs-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'DIBS.MONEY', + assets: ['USDIBS', 'BUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x8d2aa7b23aBE16E7eCa845F64C65A314d4ABa35A/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0x8d2aa7b23aBE16E7eCa845F64C65A314d4ABa35A&outputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + createdAt: 1648773316, + }, + { + id: 'orb-wtytan-busd', + name: 'wTYTAN-BUSD LP 🔥', + token: 'wTYTAN-BUSD LP 🔥', + tokenDescription: + 'orbitalswap.com - wTYTAN - BUSD LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x2f60eFd93B1E1dFA93AEd5899d116d0ddeF6A75F', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Orb-wTYTAN-BUSD', + earnedTokenAddress: '0xE51f32aF3796633dAB6299feAdaF50930c1Fe838', + earnContractAddress: '0xE51f32aF3796633dAB6299feAdaF50930c1Fe838', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-wtytan-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['WTYTAN', 'BUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x3593d409484e36aAd862101054FbDBe1C9a4fC9b/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0x3593d409484e36aAd862101054FbDBe1C9a4fC9b&outputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + createdAt: 1648773316, + }, + { + id: 'orb-orb-usdc', + name: 'ORB-USDC LP 🔥', + token: 'ORB-USDC LP 🔥', + tokenDescription: + 'orbitalswap.com - ORB - USDC LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xaB5d13feE7B4eCC6B2D019BB16793D18ab8c9982', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-USDC', + earnedTokenAddress: '0xb9aC31D4AdA868EE8AF3b755D6b3c0d9DdFf2Ab9', + earnContractAddress: '0xb9aC31D4AdA868EE8AF3b755D6b3c0d9DdFf2Ab9', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-orb-usdc', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['ORB', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d/0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d&outputCurrency=0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + createdAt: 1648773316, + }, + { + id: 'orb-eth-usdc', + name: 'ETH-USDC LP 🔥', + token: 'ETH-USDC LP 🔥', + tokenDescription: + 'orbitalswap.com - ETH - USDC LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x80fBD8Daa1516ac96c26b02798df6CC4919ef354', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ETH-USDC', + earnedTokenAddress: '0x1118d8bA31bb4a69498c80DF2274a440fd756139', + earnContractAddress: '0x1118d8bA31bb4a69498c80DF2274a440fd756139', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-eth-usdc', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['ETH', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d/0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d&outputCurrency=0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + createdAt: 1648773316, + }, + { + id: 'orb-piggy-avax', + name: 'PIGGY-AVAX LP 🔥', + token: 'PIGGY-AVAX LP 🔥', + tokenDescription: + 'orbitalswap.com - PIGGY - AVAX LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xE5FcBAad5c0a22375A3Ee2EC7A85707807eDFd29', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-PIGGY-AVAX', + earnedTokenAddress: '0x506937C41B5dc4C01ED303b304F256493272f498', + earnContractAddress: '0x506937C41B5dc4C01ED303b304F256493272f498', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-piggy-avax', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['PIGGY', 'AVAX'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x31CdD9F5a6a1E39a38A6b073Fc3FaBE6CbfeAc76/0x1CE0c2827e2eF14D5C4f29a091d735A204794041', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0x1CE0c2827e2eF14D5C4f29a091d735A204794041&outputCurrency=0x31CdD9F5a6a1E39a38A6b073Fc3FaBE6CbfeAc76', + createdAt: 1648773316, + }, + { + id: 'orb-drip-busd', + name: 'DRIP-BUSD LP 🔥', + token: 'DRIP-BUSD LP 🔥', + tokenDescription: + 'orbitalswap.com - DRIP - BUSD LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x48ED1d5C8A428c191B94D99bEe674020e8956127', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-DRIP-BUSD', + earnedTokenAddress: '0x4d9CEe6980f2C12bacbf9F1be9dde8281586b5Ee', + earnContractAddress: '0x4d9CEe6980f2C12bacbf9F1be9dde8281586b5Ee', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-drip-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['DRIP', 'BUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/0x20f663CEa80FaCE82ACDFA3aAE6862d246cE0333', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56&outputCurrency=0x20f663CEa80FaCE82ACDFA3aAE6862d246cE0333', + createdAt: 1648773316, + }, + { + id: 'orb-orb-wbnb', + name: 'ORB-WBNB LP 🔥', + token: 'ORB-WBNB LP 🔥', + tokenDescription: + 'orbitalswap.com - ORB - WBNB LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x451a503b59A4DEA428b8eb88D6df27DE8A7fcfe1', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-WBNB', + earnedTokenAddress: '0x00e6EAF4Fc20a0574864D2BAea731DB57DCe6c59', + earnContractAddress: '0x00e6EAF4Fc20a0574864D2BAea731DB57DCe6c59', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-orb-wbnb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['ORB', 'WBNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/BNB/0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + createdAt: 1648773316, + }, + { + id: 'orb-orb-busd', + name: 'ORB-BUSD LP 🔥', + token: 'ORB-BUSD LP 🔥', + tokenDescription: + 'orbitalswap.com - ORB - BUSD LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xE1a104f204c6063B06577d8A7E6C796058494e82', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-BUSD', + earnedTokenAddress: '0xDb2D2dc94A50584FcbE36C279041DAf7B1362570', + earnContractAddress: '0xDb2D2dc94A50584FcbE36C279041DAf7B1362570', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-orb-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['ORB', 'BUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56&outputCurrency=0x42b98A2f73a282D731b0B8F4ACfB6cAF3565496B', + createdAt: 1648773316, + }, + { + id: 'orb-weth-btcb', + name: 'WETH-BTCB LP 🔥', + token: 'WETH-BTCB LP 🔥', + tokenDescription: + 'orbitalswap.com - WETH - BTCB LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x9fb8c330d0804C6Af7cC3E044cE8717021AaEBCE', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Orb-WETH-BTCB', + earnedTokenAddress: '0x01A534dd47e6545d6AAeDbeEB10f70dbf0F4e981', + earnContractAddress: '0x01A534dd47e6545d6AAeDbeEB10f70dbf0F4e981', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-weth-btcb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['WETH', 'BTCB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/0x55d398326f99059fF775485246999027B3197955', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56&outputCurrency=0x55d398326f99059fF775485246999027B3197955', + createdAt: 1648773316, + }, + { + id: 'orb-busd-usdt', + name: 'BUSD-USDT LP 🔥', + token: 'BUSD-USDT LP 🔥', + tokenDescription: + 'orbitalswap.com - BUSD - USDT LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x5cd108dFa59B8a2713FeCf0e3BeaDA5C58BC9f89', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Orb-BUSD-USDT', + earnedTokenAddress: '0x680607930F1071B332Ad5De1f551B027C0Fb7B20', + earnContractAddress: '0x680607930F1071B332Ad5De1f551B027C0Fb7B20', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-busd-usdt', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['BUSD', 'USDT'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/0x55d398326f99059fF775485246999027B3197955', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56&outputCurrency=0x55d398326f99059fF775485246999027B3197955', + createdAt: 1648773316, + }, + { + id: 'orb-avax-wbnb', + name: 'AVAX-WBNB LP 🔥', + token: 'AVAX-WBNB LP 🔥', + tokenDescription: + 'orbitalswap.com - AVAX - WBNB LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x2111849199aA24C83CB462e86b3BF5E44Cf72cc2', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Orb-AVAX-WBNB', + earnedTokenAddress: '0x64839E8CF15587a6A2425e366C0596d625e403F8', + earnContractAddress: '0x64839E8CF15587a6A2425e366C0596d625e403F8', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-avax-wbnb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['AVAX', 'WBNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0x1CE0c2827e2eF14D5C4f29a091d735A204794041/BNB', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0x1CE0c2827e2eF14D5C4f29a091d735A204794041', + createdAt: 1648773316, + }, + { + id: 'orb-weth-wbnb', + name: 'WETH-WBNB LP 🔥', + token: 'WETH-WBNB LP 🔥', + tokenDescription: + 'orbitalswap.com - WETH - WBNB LP - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xc9b39b94a09a1F772CD98fB9DBfC66696C921ab9', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-WETH-WBNB', + earnedTokenAddress: '0x10458bc9d0896294C2BAdecC738D50C884D0f2f2', + earnContractAddress: '0x10458bc9d0896294C2BAdecC738D50C884D0f2f2', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-weth-wbnb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['WETH', 'WBNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/BNB/0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + createdAt: 1648773316, + }, + { + id: 'orb-wbnb-busd', + name: 'WBNB-BUSD LP 🔥', + token: 'WBNB-BUSDLP 🔥', + tokenDescription: + 'orbitalswap.com - WBNB-BUSD - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x57423151Ad2AAFA5378afbA274D30f5fab0d69Df', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-WBNB-BUSD', + earnedTokenAddress: '0xe577DEF19D5D5cfdA3f15194Ab41A3240558736C', + earnContractAddress: '0xe577DEF19D5D5cfdA3f15194Ab41A3240558736C', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-wbnb-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['BUSD', 'BNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + createdAt: 1648773316, + }, + { + id: 'orb-wbnb-usdt', + name: 'WBNB-USDT LP 🔥', + token: 'WBNB-USDT LP 🔥', + tokenDescription: + 'orbitalswap.com - WBNB-USDT - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x6D8163E9dB6c949e92e49C9B3cdB36C69395b680', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-WBNB-USDT', + earnedTokenAddress: '0x58Eb15BB09848E5928132f897Fe2A5FFF0A06953', + earnContractAddress: '0x58Eb15BB09848E5928132f897Fe2A5FFF0A06953', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-wbnb-usdt', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['USDT', 'BNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c/0x55d398326f99059fF775485246999027B3197955', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0x55d398326f99059fF775485246999027B3197955', + createdAt: 1648773316, + }, + { + id: 'orb-wbnb-btcb', + name: 'WBNB-BTCB LP 🔥', + token: 'WBNB-BTCB LP 🔥', + tokenDescription: + 'orbitalswap.com - WBNB-BTCB - AC Auto Fee Share Vault 🔥', + tokenAddress: '0xfeC8Ee2fd97CF04FA7a2013299496E3EdF497EbC', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-WBNB-BTCB', + earnedTokenAddress: '0x5684Eb64B6f3133B522200B661149f4C670ABb19', + earnContractAddress: '0x5684Eb64B6f3133B522200B661149f4C670ABb19', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-wbnb-btcb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['BTCB', 'BNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c/0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + buyTokenUrl: + 'https://orbitalswap.com/swap?outputCurrency=0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + createdAt: 1648773316, + }, + { + id: 'orb-btcb-busd', + name: 'BTCB-BUSD LP 🔥', + token: 'BTCB-BUSD LP 🔥', + tokenDescription: + 'orbitalswap.com - BTCB-BUSD - AC Auto Fee Share Vault 🔥', + tokenAddress: '0x3ec9B8e424486FCf4923d5e1424B838feee628E8', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ORB-BTCB-BUSD', + earnedTokenAddress: '0xC829fD908228996dB938755b30f1A9440803b8Df', + earnContractAddress: '0xC829fD908228996dB938755b30f1A9440803b8Df', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'orb-btcb-busd', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'OrbitalSwap', + assets: ['BTCB', 'BUSD'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://orbitalswap.com/add/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + buyTokenUrl: + 'https://orbitalswap.com/swap?inputCurrency=0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56&outputCurrency=0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + createdAt: 1648773316, + }, + { + id: 'emp-emp-eth', + name: 'EMP-ETH LP 🔥', + token: 'EMP-ETH LP 🔥', + tokenDescription: 'EMP.Money - EMP - ETH LP - AC Auto Burn Vault 🔥', + tokenAddress: '0x84821bb588f049913Dc579Dc511E5e31EB22d5E4', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-EMP-ETH', + earnedTokenAddress: '0x13eb43c8289CC8D7945462FF4fAfe686d4Bf53F6', + earnContractAddress: '0x13eb43c8289CC8D7945462FF4fAfe686d4Bf53F6', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'emp-emp-eth', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'EMP.Money', + assets: ['EMP', 'ETH'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://pancakeswap.finance/add/0x3b248CEfA87F836a4e6f6d6c9b42991b88Dc1d58/0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + buyTokenUrl: + 'https://pancakeswap.finance/swap?inputCurrency=0x2170Ed0880ac9A755fd29B2688956BD959F933F8&outputCurrency=0x3b248CEfA87F836a4e6f6d6c9b42991b88Dc1d58', + createdAt: 1648773316, + }, + { + id: 'emp-eshare-mdb+', + name: 'ESHARE-MDB+ LP', + token: 'ESHARE-MDB+ LP', + tokenDescription: 'EMP.Money - ESHARE - MDB+ LP - AC Fee Share Vault', + tokenAddress: '0x51586182A2031f3e384D080f78C8836D48eBBfFC', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ESHARE-MDB+', + earnedTokenAddress: '0xA8530643faD58BB82378Fd804e10530D39d5d560', + earnContractAddress: '0xA8530643faD58BB82378Fd804e10530D39d5d560', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'emp-eshare-mdb+', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'EMP.Money', + assets: ['ESHARE', 'MDB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_HIGH', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://pancakeswap.finance/add/0xDB20F6A8665432CE895D724b417f77EcAC956550/0x9f8BB16f49393eeA4331A39B69071759e54e16ea', + buyTokenUrl: + 'https://pancakeswap.finance/swap?inputCurrency=0x9f8BB16f49393eeA4331A39B69071759e54e16ea&outputCurrency=0xDB20F6A8665432CE895D724b417f77EcAC956550', + createdAt: 1648773315, + }, + { + id: 'emp-eshare-wbnb', + name: 'ESHARE-BNB LP', + token: 'ESHARE-BNB LP', + tokenDescription: 'EMP.Money - ESHARE - BNB LP - AC Fee Share Vault', + tokenAddress: '0x1747AF98EBF0B22d500014c7dd52985d736337d2', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-ESHARE-BNB', + earnedTokenAddress: '0xc822dE2843cf3a8a0642908F13d9f57E7A6D9011', + earnContractAddress: '0xc822dE2843cf3a8a0642908F13d9f57E7A6D9011', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'emp-eshare-wbnb', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'EMP.Money', + assets: ['ESHARE', 'BNB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_HIGH', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://pancakeswap.finance/add/0xDB20F6A8665432CE895D724b417f77EcAC956550/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + buyTokenUrl: + 'https://pancakeswap.finance/swap?outputCurrency=0xDB20F6A8665432CE895D724b417f77EcAC956550', + createdAt: 1648773315, + }, +]; +module.exports = bscPools; diff --git a/src/adaptors/magik-farm/config/vault/celo_pools.js b/src/adaptors/magik-farm/config/vault/celo_pools.js new file mode 100644 index 0000000000..3f5c13aff3 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/celo_pools.js @@ -0,0 +1,2 @@ +const celoPools = []; +module.exports = celoPools; diff --git a/src/adaptors/magik-farm/config/vault/cronos_pools.js b/src/adaptors/magik-farm/config/vault/cronos_pools.js new file mode 100644 index 0000000000..6646eff319 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/cronos_pools.js @@ -0,0 +1,179 @@ +const cronosPools = [ + { + id: 'gaur-gaur', + logo: 'single-assets/GAUR.png', + name: 'GAUR 🔥', + token: 'GAUR 🔥', + tokenDescription: 'gaur.money - Single Stake AC Auto Burn Vault🔥', + tokenAddress: '0x046cb616d7a52173e4Da9efF1BFd590550aa3228', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - GAUR Single Stake', + earnedTokenAddress: '0xaEF7684b1d5aF45F922dC5AAe937c3a708BF4dbA', + earnContractAddress: '0xaEF7684b1d5aF45F922dC5AAe937c3a708BF4dbA', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'GAUR', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'gaur.money', + assets: ['GAUR'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://www.smxswap.com/#/swap?inputCurrency=0xe44Fd7fCb2b1581822D0c862B68222998a0c299a&outputCurrency=0x046cb616d7a52173e4da9eff1bfd590550aa3228', + }, + { + id: 'gaur-gaur-eth', + name: 'GAUR-WETH LP', + token: 'GAUR-WETH LP ', + tokenDescription: 'gaur.money - GAUR-WETH LP AC Auto Fee Share Vault', + tokenAddress: '0xC92837a46B76c5E79d1c228c15d41334b5fEAA97', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'Magikfarm - GAUR-WETH LP', + earnedTokenAddress: '0xfD04602cB488b05B1a3A6C092B22a96f870Fbb6a', + earnContractAddress: '0xfD04602cB488b05B1a3A6C092B22a96f870Fbb6a', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'gaur-gaur-eth', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'GAUR.MONEY', + assets: ['GAUR', 'WETH'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://www.smxswap.com/#/add/0xe44Fd7fCb2b1581822D0c862B68222998a0c299a/0x046cb616d7a52173e4da9eff1bfd590550aa3228', + buyTokenUrl: + 'https://www.smxswap.com/#/swap?inputCurrency=0xe44Fd7fCb2b1581822D0c862B68222998a0c299a&outputCurrency=0x046cb616d7a52173e4da9eff1bfd590550aa3228', + }, + { + id: 'darkcrystl-darkcrystl-wcro', + name: 'DARKCRYSTL-WCRO LP🔥', + token: 'DARKCRYSTL-WCRO LP', + tokenDescription: + 'cronos.darkcrystl.com - DARKCRYSTL-WCRO LP AC Auto Burn Vault 🔥', + tokenAddress: '0x59505978Dcdb0c820ECf6486AFEB9b2Baa58Ff49', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'Magikfarm - DARKCRYSTL-WCRO LP', + earnedTokenAddress: '0x0344Eff412334A1Cd978507CF3CF9EB667E8Df1b', + earnContractAddress: '0x0344Eff412334A1Cd978507CF3CF9EB667E8Df1b', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'darkcrystl-darkcrystl-wcro', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Darkcrystl', + assets: ['DARKCRYSTL', 'CRO'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://mm.finance/add/0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23/0xEfA1FABC2AB6219174aD1c912F56f7de53cDc1E1', + buyTokenUrl: + 'https://mm.finance/swap?outputCurrency=0xEfA1FABC2AB6219174aD1c912F56f7de53cDc1E1', + }, + { + id: 'darkcrystl-mine-wcro', + name: 'MINE-WCRO LP🔥', + token: 'MINE-WCRO LP', + tokenDescription: + 'cronos.darkcrystl.com - MINE-WCRO LP AC Auto Fee Share Vault 🔥', + tokenAddress: '0x1AA703ecBb80271A0d719E4405D030F0fc46c30E', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'Magikfarm - MINE-WCRO LP', + earnedTokenAddress: '0x0ba923bf767D09817EBcD17d599A4759d79F1966', + earnContractAddress: '0x0ba923bf767D09817EBcD17d599A4759d79F1966', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'darkcrystl-mine-wcro', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Darkcrystl', + assets: ['MINE', 'CRO'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://mm.finance/add/0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23/0x0944d9a8Dea16af1170c51E8DD3921C727A06cBd', + buyTokenUrl: + 'https://mm.finance/swap?outputCurrency=0x0944d9a8Dea16af1170c51E8DD3921C727A06cBd', + }, + { + id: 'darkcrystl-darkcrystl-mine', + name: 'DARKCRYSTL-MINE LP🔥', + token: 'DARKCRYSTL-MINE LP', + tokenDescription: + 'cronos.darkcrystl.com - DARKCRYSTL-MINE LP AC Auto Fee Share Vault 🔥', + tokenAddress: '0xbe4C7893e79028f4956307d2efD2cf8230360c70', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'Magikfarm -DARKCRYSTL-MINE LP', + earnedTokenAddress: '0x515bAF9CbB69A7E9188C526c809f504d87C6C085', + earnContractAddress: '0x515bAF9CbB69A7E9188C526c809f504d87C6C085', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'darkcrystl-darkcrystl-mine', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Darkcrystl', + assets: ['DARKCRYSTL', 'MINE'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://mm.finance/add/0xEfA1FABC2AB6219174aD1c912F56f7de53cDc1E1/0x0944d9a8Dea16af1170c51E8DD3921C727A06cBd', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xEfA1FABC2AB6219174aD1c912F56f7de53cDc1E1&inputCurrency=0x0944d9a8Dea16af1170c51E8DD3921C727A06cBd', + }, +]; +module.exports = cronosPools; diff --git a/src/adaptors/magik-farm/config/vault/fantom_pools.js b/src/adaptors/magik-farm/config/vault/fantom_pools.js new file mode 100644 index 0000000000..390bcca0fc --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/fantom_pools.js @@ -0,0 +1,1119 @@ +const fantomPools = [ + { + id: 'lif3-tomb', + name: 'TOMB LIF3 GP', + logo: 'single-assets/TOMB.png', + token: 'TOMB', + tokenDescription: + ' 1% Deposit Fee Tomb.Finance - Single Stake TOMB LIF3 GP Pool 🔥', + tokenAddress: '0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm TOMB', + earnedTokenAddress: '0xe1198C30021dD700A37C098b2e6a22cdF38A70e4', + earnContractAddress: '0xe1198C30021dD700A37C098b2e6a22cdF38A70e4', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'TOMB', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'TombSwap', + assets: ['TOMB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://swap.tomb.com/#/swap?outputCurrency=0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + }, + { + id: 'spirit-ftm-magik', + name: 'MAGIK-FTM LP🔥', + token: 'MAGIK-FTM LP', + tokenDescription: 'Magik Finance - AC Auto Burn Vault 🔥', + tokenAddress: '0xDc71A6160322ad78DaB0abb47C7A581cFE9709Ee', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MAGIKfarm MAGIK-FTM', + earnedTokenAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + earnContractAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spirit-ftm-magik', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpiritSwap', + assets: ['MAGIK', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://swap.spiritswap.finance/#/add/FTM/0x87a5C9B60A3aaf1064006FE64285018e50e0d020', + buyTokenUrl: + 'https://swap.spiritswap.finance/#/exchange/swap/FTM/0x87a5c9b60a3aaf1064006fe64285018e50e0d020', + }, + { + id: 'spirit-magik', + logo: 'single-assets/MAGIK.png', + name: 'MAGIK🔥', + token: 'MAGIK🔥', + tokenDescription: 'Magik.Finance - Single Stake AC Auto Burn Vault🔥', + tokenAddress: '0x87a5c9b60a3aaf1064006fe64285018e50e0d020', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'magikfarmMAGIK', + earnedTokenAddress: '0x0365b8Aa14D5Eecea962C28e4531D1bc2a22D612', + earnContractAddress: '0x0365b8Aa14D5Eecea962C28e4531D1bc2a22D612', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'MAGIK', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'SpiritSwap', + assets: ['MAGIK'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://swap.spiritswap.finance/#/exchange/swap/0x87a5c9b60a3aaf1064006fe64285018e50e0d020', + }, + { + id: 'spirit-ftm-mshare', + name: 'MSHARE-FTM LP', + token: 'MSHARE-FTM LP', + tokenDescription: 'Magik.Finance - MSHARE - FTM LP', + tokenAddress: '0x392C85cECcf9855986b0044a365A5532aeC6Fa31', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'magikfarmMSHARE-FTM', + earnedTokenAddress: '0x0421D1E6F9728Da90a39c579F4b151198Df43DfB', + earnContractAddress: '0x0421D1E6F9728Da90a39c579F4b151198Df43DfB', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spirit-ftm-mshare', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpiritSwap', + assets: ['MSHARE', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://swap.spiritswap.finance/#/add/FTM/0xC8Ca9026Ad0882133Ef126824F6852567c571A4E', + buyTokenUrl: + 'https://swap.spiritswap.finance/#/exchange/swap/FTM/0xc8ca9026ad0882133ef126824f6852567c571a4e', + }, + { + id: 'spirit-mshare-magik', + name: 'MSHARE-MAGIK LP', + token: 'MSHARE-MAGIK LP', + tokenDescription: 'Magik.Finance - MSHARE-MAGIK LP', + tokenAddress: '0x4d6b28441c8B293A603243431E6E31F3C2632ddD', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'magikfarmMSHARE-MAGIK', + earnedTokenAddress: '0xc948Da8Eae9F65D7B6fD03658f1488a619DBB757', + earnContractAddress: '0xc948Da8Eae9F65D7B6fD03658f1488a619DBB757', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spirit-mshare-magik', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpiritSwap', + assets: ['MSHARE', 'MAGIK'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://swap.spiritswap.finance/#/add/0x87a5C9B60A3aaf1064006FE64285018e50e0d020/0xC8Ca9026Ad0882133Ef126824F6852567c571A4E', + buyTokenUrl: + 'https://swap.spiritswap.finance/#/exchange/swap/MAGIK/0xC8Ca9026Ad0882133Ef126824F6852567c571A4E', + }, + { + id: 'wigo-wigo-ftm', + name: 'WIGO - FTM LP🔥', + token: 'WIGO - FTM LP🔥', + tokenDescription: 'wigoswap.io - WIGO-FTM AC Auto Burn Vault 🔥', + tokenAddress: '0xB66E5c89EbA830B31B3dDcc468dD50b3256737c5', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WIGO - FTM', + earnedTokenAddress: '0x2A1c568D0735a18b562CF2a1bfF06f228f960662', + earnContractAddress: '0x2A1c568D0735a18b562CF2a1bfF06f228f960662', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'wigo-wigo-ftm', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'WigoSwap', + assets: ['WIGO', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://wigoswap.io/add/FTM/0xE992bEAb6659BFF447893641A378FbbF031C5bD6', + buyTokenUrl: + 'https://wigoswap.io/swap?outputCurrency=0xE992bEAb6659BFF447893641A378FbbF031C5bD6', + }, + { + id: 'wigo-usdc-wigo', + name: 'WIGO - USDC LP🔥', + token: 'WIGO - USDC LP🔥', + tokenDescription: 'wigoswap.io - WIGO-USDC AC Auto Burn Vault 🔥', + tokenAddress: '0x96bDF4d9fb8dB9FcD1E0CA146faBD891f2F1A96d', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm - WIGO-USDC LP', + earnedTokenAddress: '0x4926395f7E6F965B2c2e935A2B8bF17f42f45E4c', + earnContractAddress: '0x4926395f7E6F965B2c2e935A2B8bF17f42f45E4c', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'wigo-usdc-wigo', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'WigoSwap', + assets: ['WIGO', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://wigoswap.io/add/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75/0xE992bEAb6659BFF447893641A378FbbF031C5bD6', + buyTokenUrl: + 'https://wigoswap.io/swap?inputCurrency=0x04068DA6C83AFCFA0e13ba15A6696662335D5B75&outputCurrency=0xE992bEAb6659BFF447893641A378FbbF031C5bD6', + }, + // { + // id: 'spooky-wftm-bshare', + // name: 'BSHARE - FTM LP', + // token: 'BSHARE - FTM LP', + // tokenDescription: 'Basedfinance.io - BSHARE - FTM LP AC Vault', + // tokenAddress: '0x6F607443DC307DCBe570D0ecFf79d65838630B56', + // tokenDecimals: 18, + // tokenDescriptionUrl: '#', + // earnedToken: 'MAGIKfarm MAGIK-FTM', + // earnedTokenAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + // earnContractAddress: '0xe8cE63e37bB4B662837144058c298C4e7Fd0b93C', + // pricePerFullShare: 1, + // tvl: 0, + // oracle: 'lps', + // oracleId: 'spooky-wftm-bshare', + // oraclePrice: 0, + // depositsPaused: false, + // partnership: true, + // isMooStaked: true, + // status: 'active', + // platform: 'SpookySwap', + // assets: ['BASED', 'TOMB'], + // risks: ['COMPLEXITY_LOW', 'BATTLE_TESTED', 'IL_LOW', 'AUDIT', 'CONTRACTS_VERIFIED'], + // stratType: 'StratLP', + // addLiquidityUrl: + // 'https://swap.spiritswap.finance/#/add/FTM/0x87a5C9B60A3aaf1064006FE64285018e50e0d020', + // buyTokenUrl: + // 'https://swap.spiritswap.finance/#/exchange/swap/FTM/0x87a5c9b60a3aaf1064006fe64285018e50e0d020', + // }, + { + id: 'spooky-eth-serene', + name: 'Spooky - SRNv2-ETH LP', + token: 'SRNv2-ETH LP', + tokenDescription: + '1% WITHDRAWAL FEE - app.serenitycapital.io - SERENE-ETH LP - AC Vault', + tokenAddress: '0x25A5dd853220e5AF4407843f073a7a0A0e825b23', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-SP-SERENEV2-wETH', + earnedTokenAddress: '0x087D8b7196CF8C136BcceEF5AD17202f685174F5', + earnContractAddress: '0x087D8b7196CF8C136BcceEF5AD17202f685174F5', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-eth-serene', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Spooky', + assets: ['SRN', 'WETH'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spooky.fi/#/add/0x74b23882a30290451A17c44f4F05243b6b58C76d/0x60d8D17D6b824E19f77eACcAf16ED7BA6FB209C2', + buyTokenUrl: + 'https://spooky.fi/#/swap?inputCurrency=0x74b23882a30290451A17c44f4F05243b6b58C76d&outputCurrency=0x60d8D17D6b824E19f77eACcAf16ED7BA6FB209C2', + }, + { + id: 'spooky-eth-pebble', + name: 'Spooky PEBBLE-ETH LP', + token: 'PEBBLE-ETH LP', + tokenDescription: + '1% WITHDRAWAL FEE - app.serenitycapital.io - PEBBLE-ETH LP - AC Vault', + tokenAddress: '0xc064a5d9Acba5741cFF44016B1fAA6207B21AEF6', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-SP-PBL-ETH', + earnedTokenAddress: '0x099Afa97546750Cb1e163EF6CEbD51657246722a', + earnContractAddress: '0x099Afa97546750Cb1e163EF6CEbD51657246722a', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-eth-pebble', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Spooky', + assets: ['PBL', 'WETH'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spooky.fi/#/add/0x74b23882a30290451A17c44f4F05243b6b58C76d/0x9a2d0935E6CC558aaBa4EbD280F03A74b4752ADd', + buyTokenUrl: + 'https://spooky.fi/#/swap?inputCurrency=0x74b23882a30290451A17c44f4F05243b6b58C76d&outputCurrency=0x9a2d0935E6CC558aaBa4EbD280F03A74b4752ADd', + }, + { + id: 'spooky-degen', + logo: 'single-assets/DEGEN.png', + name: 'DEGEN🔥', + token: 'DEGEN🔥', + tokenDescription: 'degenfinance.us - Single Stake AC Auto Burn Vault🔥', + tokenAddress: '0xF61d81d623d9c4a45ff5766EDa5AF224c3dde1A5', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-DEGEN Single Stake', + earnedTokenAddress: '0x5EB2d9f494098e8B470d045AF3bbE0c7F6ec8f41', + earnContractAddress: '0x5EB2d9f494098e8B470d045AF3bbE0c7F6ec8f41', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'DEGEN', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'SpookySwap', + assets: ['DEGEN'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xF61d81d623d9c4a45ff5766EDa5AF224c3dde1A5&inputCurrency=0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + }, + { + id: 'spooky-tomb-degen', + name: 'DEGEN - TOMB LP 🔥', + token: 'DEGEN - TOMB LP 🔥', + tokenDescription: 'degenfinance.us - DEGEN-TOMB LP - AC Auto Burn Vault', + tokenAddress: '0xF6b99c9B6E6bDbFd1B2De21F908189b49F43B9E3', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-DEGEN-TOMB', + earnedTokenAddress: '0xFF33a6d82436ACe973c2636822CeCd27e846b4C9', + earnContractAddress: '0xFF33a6d82436ACe973c2636822CeCd27e846b4C9', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-tomb-degen', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['DEGEN', 'TOMB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x6c021ae822bea943b2e66552bde1d2696a53fbb7/0xF61d81d623d9c4a45ff5766EDa5AF224c3dde1A5', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xF61d81d623d9c4a45ff5766EDa5AF224c3dde1A5&inputCurrency=0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + }, + { + id: 'spooky-tomb-dshare', + name: 'DSHARE - USDC LP', + token: 'DSHARE - USDC LP', + tokenDescription: 'degenfinance.us - DSHARE - USDC LP - AC Vault', + tokenAddress: '0x1b622bB79d25f67e90BD189B5d116e0923Eb4ECB', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-DSHARE-USDC', + earnedTokenAddress: '0xB7C08E0Ca354657B50E923A1408fD2b7635CA638', + earnContractAddress: '0xB7C08E0Ca354657B50E923A1408fD2b7635CA638', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-tomb-dshare', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['DSHARE', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75/0x6E209329A33a63C463dbb65AE2d6655Fe5C98411', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x6E209329A33a63C463dbb65AE2d6655Fe5C98411&inputCurrency=0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + }, + { + id: 'spooky-usdc-mshare', + name: 'MSHARE - USDC LP 🔥', + token: 'MSHARE - USDC LP 🔥', + tokenDescription: + 'app.mvfinance.club - MSHARE - USDC LP - AC Fee Share Vault 50%', + tokenAddress: '0x92A7b2A9ca7D70573E3a0B0BF9e5232c70db8a89', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-MVMSHARE-USDC', + earnedTokenAddress: '0xb9aC31D4AdA868EE8AF3b755D6b3c0d9DdFf2Ab9', + earnContractAddress: '0xb9aC31D4AdA868EE8AF3b755D6b3c0d9DdFf2Ab9', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-mshare', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['MSHAREMV', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x04068da6c83afcfa0e13ba15a6696662335d5b75/0xb011EC534d9175cD7a69aFBfc1bcc9990862c462', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x04068da6c83afcfa0e13ba15a6696662335d5b75&inputCurrency=0xb011EC534d9175cD7a69aFBfc1bcc9990862c462', + }, + { + id: 'spooky-usdc-mvdollar', + name: 'MVDOLLAR-USDC🔥', + token: 'MVDOLLAR-USDC 🔥', + tokenDescription: + 'app.mvfinance.club - MVDOLLAR-USDC - AC Fee Share Vault 50%', + tokenAddress: '0x35bED1E2f3033395a05CD0b1b5900209ECe42774', + tokenDecimals: 18, + tokenDescriptionUrl: + '50% of performance rewards are sent back to the Miniverse Team', + earnedToken: 'MagikFarm-MVDOLLAR-USDC', + earnedTokenAddress: '0x8aA7cE2451D8ab2Ea4B090620ccb1fF67681d676', + earnContractAddress: '0x8aA7cE2451D8ab2Ea4B090620ccb1fF67681d676', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-mvdollar', + oraclePrice: 0, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['MVDOLLAR', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x04068da6c83afcfa0e13ba15a6696662335d5b75/0x57976c467608983513c9355238dc6de1B1aBbcCA', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x57976c467608983513c9355238dc6de1B1aBbcCA&inputCurrency=0x04068da6c83afcfa0e13ba15a6696662335d5b75', + }, + { + id: 'spooky-mvdollar', + logo: 'single-assets/MVDOLLAR.png', + name: 'MVDOLLAR', + token: 'MVDOLLAR', + tokenDescription: 'app.mvfinance.club - MVDOLLAR Single Stake - AC Vault', + tokenAddress: '0x57976c467608983513c9355238dc6de1B1aBbcCA', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-MVDOLLAR-Single Stake', + earnedTokenAddress: '0x5fa6B2c4A999331484a16C865BCA1aBdeD4CF922', + earnContractAddress: '0x5fa6B2c4A999331484a16C865BCA1aBdeD4CF922', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'MVDOLLAR', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'SpookySwap', + assets: ['MVDOLLAR'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x57976c467608983513c9355238dc6de1B1aBbcCA&inputCurrency=0x04068da6c83afcfa0e13ba15a6696662335d5b75', + }, + { + id: 'spooky-ham', + logo: 'single-assets/HAM.png', + name: 'HAM', + token: 'HAM', + tokenDescription: 'Hamster.Money - HAM Single Stake', + tokenAddress: '0x20AC818b34A60117E12ffF5bE6AbbEF68BF32F6d', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Ham-SingleStake', + earnedTokenAddress: '0xcF43b157D0B5654915B48F218bE2ee04e0b6a480', + earnContractAddress: '0xcF43b157D0B5654915B48F218bE2ee04e0b6a480', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'HAM', + oraclePrice: 0, + depositsPaused: false, + status: 'active', + platform: 'SpookySwap', + assets: ['HAM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x20ac818b34a60117e12fff5be6abbef68bf32f6d', + }, + { + id: 'red2omb-2omb-ftm', + name: 'RED 2OMB-FTM🔥', + token: 'RED 2OMB-FTM🔥', + tokenDescription: '2omb.finance Redemption.fi LP - AC Auto Burn Vault', + tokenAddress: '0x3B602C7Ed7F9318926Ffbf767E5dc838cA210085', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Redemption-2omb-FTM ', + earnedTokenAddress: '0xe9f7F029dd4107f481A424552A4A8e04676D86A1', + earnContractAddress: '0xe9f7F029dd4107f481A424552A4A8e04676D86A1', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'red2omb-2omb-ftm', + oraclePrice: 0, + retired: true, + depositsPaused: false, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['2OMB', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://app.redemption.fi/liquidity/forge/0x7a6e4E3CC2ac9924605DCa4bA31d1831c84b44aE/ETH', + buyTokenUrl: + 'https://app.redemption.fi/swap?outputCurrency=0x9b7F7E44904Bb61a9710685c938eA5f867Cb36b2', + }, + + { + id: '2omb-2omb-ftm', + name: 'Spooky 2OMB-FTM🔥', + token: 'Spooky 2OMB-FTM🔥', + tokenDescription: '2omb.finance Spooky LP - AC Auto Burn Vault', + tokenAddress: '0xbdC7DFb7B88183e87f003ca6B5a2F81202343478', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Spooky-2omb-FTM', + earnedTokenAddress: '0xa64aBA2Ed2E6dDb861f901329420e04F6493DED4', + earnContractAddress: '0xa64aBA2Ed2E6dDb861f901329420e04F6493DED4', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: '2omb-2omb-ftm', + oraclePrice: 0, + depositsPaused: true, + retireReason: 'rewards', + partnership: true, + isMooStaked: true, + status: 'eol', + platform: 'SpookySwap', + assets: ['2OMB', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x7a6e4E3CC2ac9924605DCa4bA31d1831c84b44aE/FTM', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x9b7F7E44904Bb61a9710685c938eA5f867Cb36b2', + }, + { + id: '3omb-3omb-ftm', + name: 'Spooky 3OMB-FTM🔥', + token: 'Spooky 3OMB-FTM🔥', + tokenDescription: '3omb.finance Spooky LP - AC Auto Burn Vault', + tokenAddress: '0x83A52eff2E9D112E9B022399A9fD22a9DB7d33Ae', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Spooky-3omb-FTM', + earnedTokenAddress: '0xc16688FFB997a48cf1A1610213C8ADC698c7507E', + earnContractAddress: '0xc16688FFB997a48cf1A1610213C8ADC698c7507E', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: '3omb-3omb-ftm', + oraclePrice: 0, + depositsPaused: true, + retireReason: 'rewards', + partnership: true, + isMooStaked: true, + status: 'eol', + platform: 'SpookySwap', + assets: ['3OMB', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/FTM/0x14DEf7584A6c52f470Ca4F4b9671056b22f4FfDE', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x14DEf7584A6c52f470Ca4F4b9671056b22f4FfDE', + }, + { + id: 'spooky-ftm-rubik', + name: 'RUBIK - FTM LP 🔥', + token: 'RUBIK - FTM LP 🔥', + tokenDescription: 'www.rubik.finance - Rubik-FTM LP - AC Auto Burn Vault', + tokenAddress: '0x9f4cbfa5B43252f3eD06f35C3f1A1D14C36bCeF0', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Rubik-FTM', + earnedTokenAddress: '0x161e9639Ee21e04fd11f50EeC78B638CFfD521d0', + earnContractAddress: '0x161e9639Ee21e04fd11f50EeC78B638CFfD521d0', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-ftm-rubik', + oraclePrice: 0, + depositsPaused: true, + retireReason: 'rewards', + partnership: true, + isMooStaked: true, + status: 'eol', + platform: 'SpookySwap', + assets: ['RUBIK', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/FTM/0xA4Db7f3b07c7Bf1b5E8283Bf9e8aA889569fc2e7', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xA4Db7f3b07c7Bf1b5E8283Bf9e8aA889569fc2e7', + }, + { + id: 'spooky-usdc-rebel', + name: 'REBEL - USDC 🔥', + token: 'REBEL - USDC 🔥', + tokenDescription: 'Ukrainefinance.app - AC Auto Burn Vault', + tokenAddress: '0x1B9a7855Ddf35cc6F5920D3fe6f4A4CA144Ce750', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Spooky-Rebel-USDC ', + earnedTokenAddress: '0xe577DEF19D5D5cfdA3f15194Ab41A3240558736C', + earnContractAddress: '0xe577DEF19D5D5cfdA3f15194Ab41A3240558736C', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-rebel', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['REBEL', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75/0x13E2a52dbC151439B05D774F21e58c4D7E4cF3d7', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x13E2a52dbC151439B05D774F21e58c4D7E4cF3d7&inputCurrency=0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + }, + { + id: 'spooky-usdc-victory', + name: 'VICTORY - USDC', + token: 'VICTORY - USDC', + tokenDescription: 'Ukrainefinance.app - Victory - USDC LP', + tokenAddress: '0x5F7Dd4453cE143F8fB78494aC38aa07E41944204', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Spooky-Victory-USDC ', + earnedTokenAddress: '0x6f93A9045499043A35c9707673772EAe1D611203', + earnContractAddress: '0x6f93A9045499043A35c9707673772EAe1D611203', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-victory', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['VICTORY', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xaA50aD0cD648c64D195c84e3ca0c70124F091995&inputCurrency=0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + buyTokenUrl: + 'https://spookyswap.finance/add/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75/0xaA50aD0cD648c64D195c84e3ca0c70124F091995', + }, + { + id: 'spooky-tomb-based', + name: 'BASED - TOMB LP🔥', + token: 'BASED - TOMB LP🔥', + tokenDescription: 'Basedfinance.io - BASED - TOMB LP AC Auto Burn Vault 🔥', + tokenAddress: '0xaB2ddCBB346327bBDF97120b0dD5eE172a9c8f9E', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MAGIKfarm BASED-TOMB', + earnedTokenAddress: '0xb9ed35590c0A7eb94C32241884ebf2FbBdd48A00', + earnContractAddress: '0xb9ed35590c0A7eb94C32241884ebf2FbBdd48A00', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-tomb-based', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['BASED', 'TOMB'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spooky.fi/#/add/0x8D7d3409881b51466B483B11Ea1B8A03cdEd89ae/0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + buyTokenUrl: + 'https://spooky.fi/#/swap?outputCurrency=0x8D7d3409881b51466B483B11Ea1B8A03cdEd89ae&inputCurrency=0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + }, + { + id: 'spooky-ftm-ham', + name: 'HAM-FTM-LP', + token: 'HAM-FTM-LP', + tokenDescription: 'Hamster.Money - Burn AC Vault', + tokenAddress: '0x8D1963111AA50a9ae9F8ab5006C204cc46bbF4eD', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-HAM-FTM-LP', + earnedTokenAddress: '0x6C3F19d7148a8d56134FBEa1E5F61fbE23FD46Ac', + earnContractAddress: '0x6C3F19d7148a8d56134FBEa1E5F61fbE23FD46Ac', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-ftm-ham', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['HAM', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/FTM/0x20AC818b34A60117E12ffF5bE6AbbEF68BF32F6d', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x20ac818b34a60117e12fff5be6abbef68bf32f6d', + }, + { + id: 'spooky-eagle-freedom', + name: 'FREEDOM - EAGLE LP', + token: 'FREEDOM - EAGLE LP', + tokenDescription: 'murica-money.com - FREEDOM-EAGLE LP - AC Vault', + tokenAddress: '0x695f878265da7D730C9df80Ee55131229A39AbBD', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-FREEDOM-EAGLE-LP', + earnedTokenAddress: '0x8931d9C8Ef9E9a414F11a6a0b69f08ADE5E1Ae7a', + earnContractAddress: '0x8931d9C8Ef9E9a414F11a6a0b69f08ADE5E1Ae7a', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-eagle-freedom', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['EAGLE', 'FREEDOM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0xeb3bA75334A58cB80C45dfBb551f03A5FdE452E6/0x19F72Ffe6f5388523FDc30d785eF79E8132cfFF8', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xeb3bA75334A58cB80C45dfBb551f03A5FdE452E6&inputCurrency=0x19F72Ffe6f5388523FDc30d785eF79E8132cfFF8', + }, + { + id: 'spooky-usdc-eagle', + name: 'EAGLE - USDC LP', + token: 'EAGLE - USDC LP', + tokenDescription: + 'murica-money.com - EAGLE-USDC LP - AC Fee Share Vault 50%', + tokenAddress: '0x38c1aff09b3d759eddac307cc1f74b55ed54177d', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-EAGLE-USDC', + earnedTokenAddress: '0x0A592A4847Ad0a0d23051cBc5cbd4624483a735d', + earnContractAddress: '0x0A592A4847Ad0a0d23051cBc5cbd4624483a735d', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-eagle', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['EAGLE', 'USDC'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75/0xeb3bA75334A58cB80C45dfBb551f03A5FdE452E6', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0xeb3bA75334A58cB80C45dfBb551f03A5FdE452E6&inputCurrency=0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + }, + { + id: 'spooky-ftm-honey', + name: 'HONEY - FTM LP 🔥', + token: 'HONEY - FTM LP 🔥', + tokenDescription: 'thehive.finance - Honey-FTM LP - AC Auto Burn Vault', + tokenAddress: '0x9aF30D7EFBbFC4cd46d6cf973FC1456d8BF6FBC7', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Honey-FTM', + earnedTokenAddress: '0x86db64E1f16D1263302D552454E065B5F26BF557', + earnContractAddress: '0x86db64E1f16D1263302D552454E065B5F26BF557', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-ftm-honey', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['HONEY', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + '5AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/FTM/0x6E3c6B9f44A788026F83B8613B04FDa704C2b9A6', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x6E3c6B9f44A788026F83B8613B04FDa704C2b9A6', + }, + { + id: 'spooky-usdc-rarer', + name: 'RARER-USDC LP', + logo: 'single-assets/rare.png', + token: 'RARER-USDC LP', + tokenDescription: 'RARER-USDC', + tokenAddress: '0x1fe1b2c679Dcc7b4520b8F8A2E4716896523bc72', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'magikfarmRARER-USDC', + earnedTokenAddress: '0x5263a8dB2b242350007B5E3319532186e052A91C', + earnContractAddress: '0x5263a8dB2b242350007B5E3319532186e052A91C', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'spooky-usdc-rarer', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'SpookySwap', + assets: ['USDC', 'RARER'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/0x1078864a3B0E5843995dE00517d871d0A686380b/0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x1078864a3B0E5843995dE00517d871d0A686380b', + }, + { + id: 'spooky-rarer', + logo: 'single-assets/Rarer.png', + name: 'RARER', + token: 'RARER', + tokenDescription: 'RARER Single Stake - 0.5% DEPOSIT FEE', + tokenAddress: '0x1078864a3B0E5843995dE00517d871d0A686380b', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'magikfarmRARER', + earnedTokenAddress: '0xcfc76902271A319370519715Fa485Afcac24AA28', + earnContractAddress: '0xcfc76902271A319370519715Fa485Afcac24AA28', + pricePerFullShare: 1, + tvl: 0, + oracle: 'tokens', + oracleId: 'RARER', + oraclePrice: 0, + depositsPaused: true, + status: 'active', + platform: 'SpookySwap', + assets: ['RARER'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_NONE', + 'MCAP_MICRO', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'SingleStake', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x1078864a3B0E5843995dE00517d871d0A686380b', + }, + // duplicate + // { + // id: 'spooky-ftm-ham', + // name: 'HAM-FTM-LP', + // token: 'HAM-FTM-LP', + // tokenDescription: 'Hamster.Money - Burn AC Vault', + // tokenAddress: '0x8D1963111AA50a9ae9F8ab5006C204cc46bbF4eD', + // tokenDecimals: 18, + // tokenDescriptionUrl: '#', + // earnedToken: 'MagikFarm-HAM-FTM-LP', + // earnedTokenAddress: '0x6C3F19d7148a8d56134FBEa1E5F61fbE23FD46Ac', + // earnContractAddress: '0x6C3F19d7148a8d56134FBEa1E5F61fbE23FD46Ac', + // pricePerFullShare: 1, + // tvl: 0, + // oracle: 'lps', + // oracleId: 'spooky-ftm-ham', + // oraclePrice: 0, + // depositsPaused: true, + // partnership: true, + // isMooStaked: true, + // status: 'active', + // platform: 'SpookySwap', + // assets: ['HAM', 'FTM'], + // risks: [ + // 'COMPLEXITY_LOW', + // 'BATTLE_TESTED', + // 'IL_LOW', + // '5AUDIT', + // 'CONTRACTS_VERIFIED', + // ], + // stratType: 'StratLP', + // addLiquidityUrl: + // 'https://spookyswap.finance/add/FTM/0x20AC818b34A60117E12ffF5bE6AbbEF68BF32F6d', + // buyTokenUrl: + // 'https://spookyswap.finance/swap?outputCurrency=0x20ac818b34a60117e12fff5be6abbef68bf32f6d', + // }, + { + id: 'tomb-tomb-ftm', + name: 'Spooky TOMB-FTM LP🔥', + token: 'Spooky TOMB-FTM LP🔥', + tokenDescription: 'Tomb.Finance - TOMB-FTM LP - AC Auto Burn Vault', + tokenAddress: '0x2A651563C9d3Af67aE0388a5c8F89b867038089e', + tokenDecimals: 18, + tokenDescriptionUrl: '#', + earnedToken: 'MagikFarm-Spooky-TOMB-FTM', + earnedTokenAddress: '0x0dA1DC567D81925cFf22Df74C6b9e294E9E1c3A5', + earnContractAddress: '0x0dA1DC567D81925cFf22Df74C6b9e294E9E1c3A5', + pricePerFullShare: 1, + tvl: 0, + oracle: 'lps', + oracleId: 'tomb-tomb-ftm', + oraclePrice: 0, + depositsPaused: true, + partnership: true, + isMooStaked: true, + status: 'active', + platform: 'Spookyswap', + assets: ['TOMB', 'FTM'], + risks: [ + 'COMPLEXITY_LOW', + 'BATTLE_TESTED', + 'IL_LOW', + 'AUDIT', + 'CONTRACTS_VERIFIED', + ], + stratType: 'StratLP', + addLiquidityUrl: + 'https://spookyswap.finance/add/FTM/0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + buyTokenUrl: + 'https://spookyswap.finance/swap?outputCurrency=0x6c021Ae822BEa943b2E66552bDe1D2696a53fbB7', + }, +]; +module.exports = fantomPools; diff --git a/src/adaptors/magik-farm/config/vault/harmony_pools.js b/src/adaptors/magik-farm/config/vault/harmony_pools.js new file mode 100644 index 0000000000..2af9271c27 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/harmony_pools.js @@ -0,0 +1,2 @@ +const harmonyPools = []; +module.exports = harmonyPools; diff --git a/src/adaptors/magik-farm/config/vault/heco_pools.js b/src/adaptors/magik-farm/config/vault/heco_pools.js new file mode 100644 index 0000000000..e1e1240fa7 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/heco_pools.js @@ -0,0 +1,2 @@ +const hecoPools = []; +module.exports = hecoPools; diff --git a/src/adaptors/magik-farm/config/vault/moonriver_pools.js b/src/adaptors/magik-farm/config/vault/moonriver_pools.js new file mode 100644 index 0000000000..d92a8288a2 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/moonriver_pools.js @@ -0,0 +1,2 @@ +const moonriverPools = []; +module.exports = moonriverPools; diff --git a/src/adaptors/magik-farm/config/vault/polygon_pools.js b/src/adaptors/magik-farm/config/vault/polygon_pools.js new file mode 100644 index 0000000000..a58c980cc4 --- /dev/null +++ b/src/adaptors/magik-farm/config/vault/polygon_pools.js @@ -0,0 +1,2 @@ +const polygonPools = []; +module.exports = polygonPools; diff --git a/src/adaptors/magik-farm/index.js b/src/adaptors/magik-farm/index.js new file mode 100644 index 0000000000..144087f115 --- /dev/null +++ b/src/adaptors/magik-farm/index.js @@ -0,0 +1,196 @@ +// to calculate chain TVL +// 1. Loop through each pool in each chain under ./config/vault +// 2a. get LP prices from e.g. https://magikfarm.herokuapp.com/lps?_=27662323 +// 2b. get token price from e.g. https://magikfarm.herokuapp.com/prices?_=27662323 +// where _= is getApiCacheBuster() +// 3. Get earned Token address and bind the vaultabi. Use balance() function +// 4. Multiply the balance with the price from the LP Price to get the TVL +// to get chain apy +// 1. get apy e.g. https://magikfarm.herokuapp.com/apy/breakdown?_=27662468 +// where _= is getApiCacheBuster() +// 2. look at total apy field + +const utils = require('../utils'); +// make sure that the pool files under ./config/vault are up to date +const magikConfig = require('./config'); + +const protocolSlug = 'magik-farm'; +const urlApy = 'https://magikfarm.herokuapp.com/apy/breakdown'; +const urlLpPrices = 'https://magikfarm.herokuapp.com/lps'; +const urlTokenPrices = 'https://magikfarm.herokuapp.com/prices'; +const sdk = require('@defillama/sdk'); +const { Web3 } = require('web3'); +const networkMapping = { + 10: { + name: 'optimism', + multiCallChainName: 'optimism', + rpcUrls: ['https://mainnet.optimism.io'], + pools: magikConfig.arbitrumPools, + }, + 43114: { + name: 'avalanche', + multiCallChainName: 'avax', + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + pools: magikConfig.avalanchePools, + }, + 1666600000: { + name: 'harmony', + multiCallChainName: 'harmony', + rpcUrls: ['https://api.s0.t.hmny.io/'], + pools: magikConfig.harmonyPools, + }, + 42220: { + name: 'celo', + multiCallChainName: 'celo', + rpcUrls: ['https://forno.celo.org'], + pools: magikConfig.celoPools, + }, + 42161: { + name: 'arbitrum', + multiCallChainName: 'arbitrum', + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + pools: magikConfig.arbitrumPools, + }, + 1285: { + name: 'moonriver', + multiCallChainName: 'moonriver', + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + pools: magikConfig.moonriverPools, + }, + 1088: { + name: 'metis', + multiCallChainName: 'metis', + rpcUrls: [], + pools: [], + }, + 250: { + name: 'fantom', + multiCallChainName: 'fantom', + rpcUrls: ['https://rpc.ftm.tools'], + pools: magikConfig.fantomPools, + }, + 137: { + name: 'polygon', + multiCallChainName: 'polygon', + rpcUrls: ['https://polygon-rpc.com'], + pools: magikConfig.polygonPools, + }, + 128: { + name: 'heco', + multiCallChainName: 'heco', + rpcUrls: ['https://http-mainnet.hecochain.com'], + pools: magikConfig.hecoPools, + }, + 122: { + name: 'fuse', + multiCallChainName: 'fuse', + rpcUrls: [], + pools: [], + }, + 56: { + name: 'binance', + multiCallChainName: 'bsc', + rpcUrls: ['https://bsc-dataseed.binance.org'], + pools: magikConfig.bscPools, + }, + 25: { + name: 'cronos', + multiCallChainName: 'cronos', + rpcUrls: ['https://evm-cronos.crypto.org'], + pools: magikConfig.cronosPools, + }, + 1313161554: { + name: 'aurora', + multiCallChainName: 'aurora', + rpcUrls: ['https://mainnet.aurora.dev/'], + pools: magikConfig.auroraPools, + }, +}; + +const balanceAbi = { + constant: true, + inputs: [], + name: 'balance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', +}; + +// Time-based cache buster +const getApiCacheBuster = () => { + return Math.trunc(Date.now() / (1000 * 60)); +}; + +const apy = async (dataLpPrices, dataTokenPrices, dataApy, networkMapping) => { + let data = []; + for (const chainId of Object.keys(networkMapping)) { + chain = networkMapping[chainId]; + // toDO: add failover logic in the future as util function + const rpcUrl = + chain.rpcUrls && chain.rpcUrls.length > 0 ? chain.rpcUrls[0] : null; + const pools = chain.pools && chain.pools.length > 0 ? chain.pools : 0; + if (rpcUrl != '' && pools.length > 0) { + const web3 = new Web3(rpcUrl); + const vaultCalls = pools.map((pool) => { + return { + target: pool.earnedTokenAddress, + }; + }); + const vaultResult = await sdk.api.abi.multiCall({ + abi: balanceAbi, + calls: vaultCalls, + chain: chain.multiCallChainName.toLowerCase(), + }); + for (let i = 0; i < pools.length; i++) { + const pool = pools[i]; + let price = null; + switch (pool.stratType) { + case 'StratLP': + price = dataLpPrices[pool.oracleId]; + break; + case 'SingleStake': + price = dataTokenPrices[pool.oracleId]; + } + const poolApy = dataApy[pool.id]; + const poolToken = + pool.assets.length > 1 + ? `${pool.assets[0]}-${pool.assets[1]}` + : `${pool.assets[0]}`; + const tokenDecimals = pool.tokenDecimals; + const balance = Number(vaultResult.output[i].output); + if (!isNaN(price) && !isNaN(tokenDecimals) && !isNaN(balance)) { + let poolData = { + pool: `${pool.id}`, + chain: utils.formatChain(chain.name), + project: protocolSlug, + symbol: utils.formatSymbol(poolToken), + tvlUsd: (balance / Math.pow(10, tokenDecimals)) * price, + apy: !isNaN(poolApy?.totalApy) ? poolApy.totalApy * 100 : null, + }; + data.push(poolData); + } + } + } + } + return data.filter((p) => utils.keepFinite(p)); +}; + +const main = async () => { + // pull data + const queryParams = `_=${getApiCacheBuster()}`; + const dataApy = await utils.getData(`${urlApy}?${queryParams}`); + const dataLpPrices = await utils.getData(`${urlLpPrices}?${queryParams}`); + const dataTokenPrices = await utils.getData( + `${urlTokenPrices}?${queryParams}` + ); + // calculate apy and tvl + let data = await apy(dataLpPrices, dataTokenPrices, dataApy, networkMapping); + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://magik.farm/#/fantom', +}; diff --git a/src/adaptors/magma-staking/index.js b/src/adaptors/magma-staking/index.js new file mode 100644 index 0000000000..241f0d58c8 --- /dev/null +++ b/src/adaptors/magma-staking/index.js @@ -0,0 +1,221 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +// Time constants +const SECONDS_PER_DAY = 86400; +const DAYS_PER_YEAR = 365; + +// Contract addresses +const MAGMA_ADDRESS = '0x8498312A6B3CbD158bf0c93AbdCF29E6e4F55081'; +const STAKING_PRECOMPILE = '0x0000000000000000000000000000000000001000'; + +// ABI for contract functions +const MAGMA_ABI = { + coreVault: 'address:coreVault', + gVault: 'address:gVault', + getValidators: 'uint64[]:getValidators', + getDelegator: + 'function getDelegator(uint64 validatorId, address delegator) returns (uint256 stake, uint256 accRewardPerToken, uint256 unclaimedRewards, uint256 deltaStake, uint256 nextDeltaStake, uint64 deltaEpoch, uint64 nextDeltaEpoch)', + totalAssets: 'function totalAssets() external view returns (uint256)', + totalSupply: 'erc20:totalSupply', + symbol: 'erc20:symbol', +}; + +const apy = async () => { + // Get current timestamp + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - SECONDS_PER_DAY; + + // Fetch block numbers for current and 1 day ago + const [blockNow, block1dayAgo] = await Promise.all([ + axios + .get(`https://coins.llama.fi/block/monad/${now}`) + .then((r) => r.data.height), + axios + .get(`https://coins.llama.fi/block/monad/${timestamp1dayAgo}`) + .then((r) => r.data.height), + ]); + + if (!blockNow || !block1dayAgo) { + throw new Error('RPC issue: Failed to fetch block numbers'); + } + + // Get vault addresses from Magma contract + const [coreVaultAddress, gVaultAddress] = await Promise.all([ + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.coreVault, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.gVault, + chain: 'monad', + block: blockNow, + }), + ]); + + const coreVault = coreVaultAddress.output; + const gVault = gVaultAddress.output; + + // Fetch current totalAssets, totalSupply, and symbol for Magma protocol + const [totalAssetsNow, totalSupplyNow, symbol] = await Promise.all([ + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.totalAssets, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.totalSupply, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.symbol, + chain: 'monad', + }), + ]); + + // Fetch 1 day ago totalAssets and totalSupply + const [totalAssets1dayAgo, totalSupply1dayAgo] = await Promise.all([ + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.totalAssets, + chain: 'monad', + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: MAGMA_ADDRESS, + abi: MAGMA_ABI.totalSupply, + chain: 'monad', + block: block1dayAgo, + }), + ]); + + if ( + !totalAssetsNow.output || + !totalSupplyNow.output || + !totalAssets1dayAgo.output || + !totalSupply1dayAgo.output + ) { + throw new Error('RPC issue: Failed to fetch contract data'); + } + + // Calculate share values (multiply by 1e18 to handle decimals) + const shareValueNow = + (BigInt(totalAssetsNow.output) * BigInt(1e18)) / + BigInt(totalSupplyNow.output); + const shareValue1dayAgo = + (BigInt(totalAssets1dayAgo.output) * BigInt(1e18)) / + BigInt(totalSupply1dayAgo.output); + + if (shareValue1dayAgo === 0n) { + throw new Error('RPC issue: Previous share value is zero'); + } + + // Calculate proportion: shareValueNow / shareValue1dayAgo + // Multiply by 1e18 to maintain precision + const proportion = + Number((shareValueNow * BigInt(1e18)) / shareValue1dayAgo) / 1e18; + + if (proportion <= 0) { + throw new Error('RPC issue: Invalid proportion calculated'); + } + + // Calculate APY using the formula: + // APY = ((1 + ((proportion - 1) / 365)) ** 365 - 1) * 100 + // This is equivalent to: APY = (proportion ** 365 - 1) * 100 + const apyBase = (Math.pow(proportion, DAYS_PER_YEAR) - 1) * 100; + + // Calculate TVL using validator staking info (same as DefiLlama TVL adapter) + const vaults = [coreVault, gVault]; + + // Get validators for each vault + const validatorResults = await Promise.all( + vaults.map((vault) => + sdk.api.abi.call({ + target: vault, + abi: MAGMA_ABI.getValidators, + chain: 'monad', + block: blockNow, + }) + ) + ); + + // Build validator calls for staking precompile + const validatorCalls = []; + validatorResults.forEach((result, vaultIndex) => { + if (result.output) { + result.output.forEach((validatorId) => { + validatorCalls.push({ + target: STAKING_PRECOMPILE, + params: [validatorId, vaults[vaultIndex]], + }); + }); + } + }); + + // Get staking info for all validators + let tvlBigInt = 0n; + if (validatorCalls.length > 0) { + const stakingInfoResults = await sdk.api.abi.multiCall({ + calls: validatorCalls, + abi: MAGMA_ABI.getDelegator, + chain: 'monad', + block: blockNow, + }); + + if (stakingInfoResults.output) { + stakingInfoResults.output.forEach((result) => { + if (result.output) { + const { stake, unclaimedRewards, deltaStake, nextDeltaStake } = + result.output; + tvlBigInt += + BigInt(stake || 0) + + BigInt(unclaimedRewards || 0) + + BigInt(deltaStake || 0) + + BigInt(nextDeltaStake || 0); + } + }); + } + } + + // Convert to number (assuming 18 decimals for MON) + const tvlMon = Number(tvlBigInt) / 1e18; + + // Get MON native token price to convert to USD + let tvlUsd; + try { + const monPriceResponse = await axios.get( + 'https://coins.llama.fi/prices/current/coingecko:monad' + ); + const monPrice = + monPriceResponse.data.coins['coingecko:monad']?.price || 1; + tvlUsd = tvlMon * monPrice; + } catch (error) { + // If price lookup fails, use TVL in MON as-is (assuming 1:1 with USD) + tvlUsd = tvlMon; + } + + return [ + { + pool: MAGMA_ADDRESS.toLowerCase(), + chain: 'monad', + project: 'magma-staking', + symbol: symbol.output || 'gMON', + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], // MON + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.magmastaking.xyz/', +}; + diff --git a/src/adaptors/maha.xyz/abi.json b/src/adaptors/maha.xyz/abi.json new file mode 100644 index 0000000000..09ab6b418c --- /dev/null +++ b/src/adaptors/maha.xyz/abi.json @@ -0,0 +1,1686 @@ +[ + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "RewardClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boostedBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boostedTotalSupply", + "type": "uint256" + } + ], + "name": "UpdatedBoost", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DISTRIBUTOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "val", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "approveUnderlyingWithPermit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "boostedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "boostedBalance_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "getRewardDual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken1", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_staking", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken1", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken2", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "contract IOmnichainStaking", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBoostedSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "boostedTotalSupply_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalVotingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "updateRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "votingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/maha.xyz/index.js b/src/adaptors/maha.xyz/index.js new file mode 100644 index 0000000000..c675de7b3a --- /dev/null +++ b/src/adaptors/maha.xyz/index.js @@ -0,0 +1,122 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const poolHelperAbi = require('./uiHelper.json'); +const ethers = require('ethers'); + +const rpcBase = + 'https://base-mainnet.infura.io/v3/13902f653ad545cc8ceeca9fa941cacd'; +const poolHelper = '0x1bC8d0b4CaAC1Fc95C8564897A0DE2bAeE40dCda'; +const stakingPools = { + // ethereum: [ + // '0x154F52B347D8E48b8DbD8D8325Fe5bb45AAdCCDa', + // '0x237efE587f2cB44597063DC8403a4892a60A5a4f', + // '0xeF12d1614eb0e2bC8E8884c7d4C7f15E34164F40', + // ], + base: ['0x1097dFe9539350cb466dF9CA89A5e61195A520B0'], +}; + +const underlyingTokens = { + 'base:0x1097dFe9539350cb466dF9CA89A5e61195A520B0': [ + '0x0A27E060C0406f8Ab7B64e3BEE036a37e5a62853', + '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + ], +}; + +const chainId = { + base: '8453', +}; + +const getMahaPrice = async () => { + try { + const mahaPrice = await axios.get( + 'https://api.coingecko.com/api/v3/simple/price?ids=mahadao&vs_currencies=usd' + ); + + return mahaPrice.data.mahadao.usd; + } catch (error) { + console.log('error fetching maha price'); + } +}; + +const getPoolsData = async () => { + const pools = []; + + for (const [key, value] of Object.entries(stakingPools)) { + const chain = key; + + await Promise.all( + value.map(async (poolAddress) => { + const symbol = ( + await sdk.api.abi.call({ + chain: chain, + abi: abi.find(({ name }) => name === 'symbol'), + target: poolAddress, + }) + ).output; + + const rewardToken1 = ( + await sdk.api.abi.call({ + chain: chain, + abi: abi.find(({ name }) => name === 'rewardToken1'), + target: poolAddress, + }) + ).output; + + const rewardToken2 = ( + await sdk.api.abi.call({ + chain: chain, + abi: abi.find(({ name }) => name === 'rewardToken2'), + target: poolAddress, + }) + ).output; + + const receivedTokenAddress = poolAddress; + + const mahaPrice = await getMahaPrice(); + + const res = ( + await sdk.api.abi.call({ + chain: chain, + abi: poolHelperAbi.find(({ name }) => name === 'getPoolInfo'), + params: [ + poolAddress, + mahaPrice * 1e8, + '0x0000000000000000000000000000000000000000', + ], + target: poolHelper, + }) + ).output; + + const apyReward = (Number(res.mahaAprE8) + Number(res.usdcAprE8)) / 1e6; + + const pool = { + pool: `${receivedTokenAddress}-${chain}`.toLowerCase(), + chain: chain, + project: 'maha.xyz', + symbol: symbol, + tvlUsd: res.poolUsdTVLE8 / 1e8, + apyBase: 0, + apyReward: apyReward, + rewardTokens: [rewardToken1, rewardToken2], + underlyingTokens: underlyingTokens[`${chain}:${poolAddress}`], + url: `https://app.maha.xyz/earn/pool/${chainId[chain]}/${poolAddress}/`, + }; + + pools.push(pool); + }) + ); + } + return pools; + // console.log(pools); +}; + +const apy = async () => { + const pools = await getPoolsData(); + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/maha.xyz/uiHelper.json b/src/adaptors/maha.xyz/uiHelper.json new file mode 100644 index 0000000000..e07f85eb96 --- /dev/null +++ b/src/adaptors/maha.xyz/uiHelper.json @@ -0,0 +1,114 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_maha", + "type": "address" + }, + { + "internalType": "address", + "name": "_zai", + "type": "address" + }, + { + "internalType": "address", + "name": "_usdc", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingPool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_mahaPriceE8", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_who", + "type": "address" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "mahaAprE8", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mahaRewardsPerYearE18", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mahaTotalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mahaUserBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolUsdTVLE8", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "usdcAprE8", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "usdcRewardsPerYearE6", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "usdcTotalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "usdcUserBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "userShareE18", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zaiTotalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zaiUserBalance", + "type": "uint256" + } + ], + "internalType": "struct PoolUIHelper.PoolInfoResponse", + "name": "res", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/mahadao-arth/index.js b/src/adaptors/mahadao-arth/index.js new file mode 100644 index 0000000000..10b96523b9 --- /dev/null +++ b/src/adaptors/mahadao-arth/index.js @@ -0,0 +1,127 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const ABIS = { + getEntireSystemColl: { + inputs: [], + name: 'getEntireSystemColl', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemColl', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getEntireSystemDebt: { + inputs: [], + name: 'getEntireSystemDebt', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemDebt', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [], + name: 'MCR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; + +const troveManagerTVL = async () => { + const TROVE_MANAGER_ADDRESS = '0x8b1da95724b1e376ae49fdb67afe33fe41093af5'; + const LUSD_ADDRESS = '0x8cc0f052fff7ead7f2edcccac895502e884a8a71'; + const URL = 'https://api.instadapp.io/defi/mainnet/liquity/trove-types'; + + const troveEthTvl = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getEntireSystemColl, + chain: 'ethereum', + }) + ).output; + + const mcr = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getMCR, + chain: 'ethereum', + }) + ).output; + + const troveType = (await superagent.get(URL)).body; + + const lusdTotalSupply = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getEntireSystemDebt, + chain: 'ethereum', + }) + ).output; + + const key = `ethereum:${LUSD_ADDRESS}`.toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + + const totalSupplyUsd = (Number(lusdTotalSupply) / 1e18) * prices[key].price; + + return [ + { + pool: TROVE_MANAGER_ADDRESS, + project: 'mahadao-arth', + symbol: 'WETH', + chain: utils.formatChain('ethereum'), + apy: 0, + tvlUsd: (Number(troveEthTvl) / 1e18) * Number(troveType.price), + // apyBaseBorrow: Number(troveType.borrowFee) * 100, + apyBaseBorrow: Number(0) * 100, // atm borrowing fee is 0 + totalSupplyUsd: (Number(troveEthTvl) / 1e18) * Number(troveType.price), + totalBorrowUsd: totalSupplyUsd, + ltv: 1 / (mcr / 1e18), + mintedCoin: 'ARTH', + url: 'https://arth.loans/#/loan/add/ETH?utm_source=defillama&utm_medium=listing&utm_campaign=external', + }, + ]; +}; + +const stabilityEthPool = async (data) => { + return [ + { + pool: `0x910f16455e5eb4605fe639e2846579c228eed3b5-ethereum`.toLowerCase(), + chain: utils.formatChain('ethereum'), + project: 'mahadao-arth', + rewardTokens: ['0x745407c86df8db893011912d3ab28e68b62e49b0', 'ETH'], + underlyingTokens: ['0x8cc0f052fff7ead7f2edcccac895502e884a8a71'], + symbol: utils.formatSymbol('arth'), + tvlUsd: Number(data.tvlUSD), + apy: Number(data.current.min), + url: 'https://arth.loans/#/stability-pool/ETH?utm_source=defillama&utm_medium=listing&utm_campaign=external', + }, + ]; +}; + +const poolsFunction = async () => { + const data = await utils.getData('https://api.arthcoin.com/apr/all'); + + return [ + ...(await stabilityEthPool(data['eth-sp'])), + ...(await troveManagerTVL()), + ]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://farming.mahadao.com?utm_source=defillama&utm_medium=listing&utm_campaign=external', +}; diff --git a/src/adaptors/mahalend/index.js b/src/adaptors/mahalend/index.js new file mode 100755 index 0000000000..e70964d0e7 --- /dev/null +++ b/src/adaptors/mahalend/index.js @@ -0,0 +1,216 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); + +const SECONDS_PER_YEAR = 31536000; + +const chainUrlParam = { + arbitrum: 'proto_arbitrum_v3', +}; + +const getPrices = async (addresses) => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const API_URLS = { + arbitrum: sdk.graph.modifyEndpoint( + 'FPS9fdGYvwyCkFzUqmF5YYYqNKT88K5V5fjnmTNPjd9t' + ), +}; + +const query = gql` + query ReservesQuery { + reserves { + name + borrowingEnabled + aToken { + id + rewards { + id + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + underlyingAssetAddress + underlyingAssetDecimals + } + vToken { + rewards { + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + } + symbol + liquidityRate + variableBorrowRate + baseLTVasCollateral + isFrozen + } + } +`; + +const apy = async () => { + let data = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await request(url, query)).reserves, + ]) + ); + data = data.map(([chain, reserves]) => [ + chain, + reserves.filter((p) => !p.isFrozen), + ]); + + const totalSupply = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: reserves.map((reserve) => ({ + target: reserve.aToken.id, + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingBalances = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: reserves.map((reserve, i) => ({ + target: reserve.aToken.underlyingAssetAddress, + params: [reserve.aToken.id], + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingTokens = data.map(([chain, reserves]) => + reserves.map((pool) => `${chain}:${pool.aToken.underlyingAssetAddress}`) + ); + + const rewardTokens = data.map(([chain, reserves]) => + reserves.map((pool) => + pool.aToken.rewards.map((rew) => `${chain}:${rew.rewardToken}`) + ) + ); + + const { pricesByAddress, pricesBySymbol } = await getPrices( + underlyingTokens.flat().concat(rewardTokens.flat(Infinity)) + ); + + const pools = data.map(([chain, markets], i) => { + const chainPools = markets.map((pool, idx) => { + const supply = totalSupply[i][idx]; + const currentSupply = underlyingBalances[i][idx]; + const totalSupplyUsd = + (supply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const tvlUsd = + (currentSupply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const { rewards } = pool.aToken; + + const rewardPerYear = rewards.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + + const { rewards: rewardsBorrow } = pool.vToken; + const rewardPerYearBorrow = rewardsBorrow.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + totalBorrowUsd = totalBorrowUsd < 0 ? 0 : totalBorrowUsd; + + const supplyRewardEnd = pool.aToken.rewards[0]?.distributionEnd; + const borrowRewardEnd = pool.vToken.rewards[0]?.distributionEnd; + + return { + pool: `${pool.aToken.id}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'mahalend', + symbol: pool.symbol, + tvlUsd, + apyBase: (pool.liquidityRate / 10 ** 27) * 100, + apyReward: + supplyRewardEnd * 1000 > new Date() + ? (rewardPerYear / totalSupplyUsd) * 100 + : null, + rewardTokens: + supplyRewardEnd * 1000 > new Date() + ? rewards.map((rew) => rew.rewardToken) + : null, + underlyingTokens: [pool.aToken.underlyingAssetAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.variableBorrowRate) / 1e25, + apyRewardBorrow: + borrowRewardEnd * 1000 > new Date() + ? (rewardPerYearBorrow / totalBorrowUsd) * 100 + : null, + ltv: Number(pool.baseLTVasCollateral) / 10000, + url: `https://app.mahalend.com/reserve-overview/?underlyingAsset=${pool.aToken.underlyingAssetAddress}&marketName=${chainUrlParam[chain]}&utm_source=defillama&utm_medium=listing&utm_campaign=external`, + borrowable: pool.borrowingEnabled, + }; + }); + + return chainPools; + }); + return pools.flat().filter((p) => !!p.tvlUsd); +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/maia-dao/index.ts b/src/adaptors/maia-dao/index.ts new file mode 100644 index 0000000000..59a411635f --- /dev/null +++ b/src/adaptors/maia-dao/index.ts @@ -0,0 +1,28 @@ +const utils = require('../utils'); + +const API_URL: string = 'http://api.maiadao.io:9090/maia-apr'; +const MAIA: string = "0x72c232D56542Ba082592DEE7C77b1C6CFA758BCD"; +const sMAIA: string = "0xD7a586CE5250bEfaB2cc2239F7226B9602536E6A"; + +const getApy = async () => { + const res = await utils.getData(API_URL); + + const pool = [{ + pool: sMAIA, + chain: utils.formatChain('metis'), + project: 'maia-dao', + symbol: 'MAIA', + tvlUsd: res.tvl, + apyReward: res.currentAPR, + underlyingTokens: [MAIA], + rewardTokens: [res.rewards['0'].token.address, res.rewards['1'].token.address, res.rewards['2'].token.address], + }]; + + return pool; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.maiadao.io/#/stake', +}; diff --git a/src/adaptors/maia-v3/index.js b/src/adaptors/maia-v3/index.js new file mode 100644 index 0000000000..4d45b22495 --- /dev/null +++ b/src/adaptors/maia-v3/index.js @@ -0,0 +1,379 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('../uniswap-v3/estimateFee.ts'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); + +const rewardsUrl = 'https://metis-graph.maiadao.io/uni-v3-staker'; +const baseUrl = 'https://metis-graph.maiadao.io'; +const chains = { + metis: `${baseUrl}/uniswap-v3`, +}; + +const decimalsErc20ABI = { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const queryIncentives = gql` + { + incentives(last: 1000, orderBy: startTime, orderDirection: desc) { + pool + startTime + endTime + reward + rewardToken + } + } +`; + +// calculating apy based pool's reward +const rewardsApy = (pool, rewardToken, rewardUSD, durationInSeconds) => { + pool = { ...pool }; + + if (pool.rewardTokens) { + if (pool.rewardToken.indexOf(rewardToken) == -1) { + pool.rewardToken.push(rewardToken); + } + // annualise + pool.rewardUSD += (rewardUSD * 31536000) / durationInSeconds; + // calc apy + pool.apyReward += (pool.rewardUSD / pool.totalValueLockedUSD) * 100; + } else { + pool['rewardTokens'] = [rewardToken]; + // annualise + pool['rewardUSD'] = (rewardUSD * 31536000) / durationInSeconds; + // calc apy + pool['apyReward'] = (pool.rewardUSD / pool.totalValueLockedUSD) * 100; + } + + return pool; +}; + +function removeDuplicates(arr) { + var seen = {}; + return arr.filter(function (item) { + return seen.hasOwnProperty(item) ? false : (seen[item] = true); + }); +} + +const topTvl = async ( + chainString, + url, + stackingUrl, + query, + queryPrior, + queryIncentives, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + timestamp = + timestamp !== null ? Number(timestamp) : Math.floor(Date.now() / 1000); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // uni v3 subgraph reserves values are wrong! + // instead of relying on subgraph values, gonna pull reserve data from contracts + // new tvl calc + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + }); + + dataNow = dataNow.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0?.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1?.decimals}`, + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // pull incentives data + let dataIncentives = await request(stackingUrl, queryIncentives); + dataIncentives = dataIncentives.incentives; + + const rewardTokens = removeDuplicates( + dataIncentives.map((incentive) => incentive.rewardToken) + ); + + const rewardDecimals = await utils.makeMulticall( + decimalsErc20ABI, + rewardTokens, + chainString + ); + + let rewardPrices = (await utils.getPrices(rewardTokens, chainString)) + .pricesByAddress; + + rewardPrices = Object.entries(rewardPrices).reduce( + (acc, [address, price], i) => ({ + ...acc, + [address]: { price: price, decimals: rewardDecimals[i] }, + }), + {} + ); + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) + dataNow = dataNow.map((el) => { + let pool = el; + dataIncentives + .filter( + (incentive) => + incentive.pool === el.id && + incentive.startTime <= timestamp && + incentive.endTime >= timestamp + ) + .forEach((incentive) => { + pool = rewardsApy( + pool, + incentive.rewardToken, + (incentive.reward / + 10 ** rewardPrices[incentive.rewardToken]?.decimals) * + rewardPrices[incentive.rewardToken]?.price, + incentive.endTime - incentive.startTime + ); + }); + return pool; + }); + + const enableV3Apy = false; + if (enableV3Apy) { + // split up subgraph tick calls into n-batches + // (tick response can be in the thousands per pool) + const skip = 20; + let start = 0; + let stop = skip; + const pages = Math.floor(dataNow.length / skip); + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + let X = []; + for (let i = 0; i <= pages; i++) { + let promises = dataNow.slice(start, stop).map((p) => { + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + return EstimatedFees( + p.id, + priceAssumption, + [ + p.token1_in_token0 * (1 - delta), + p.token1_in_token0 * (1 + delta), + ], + p.price1, + p.price0, + investmentAmount, + p.token0?.decimals, + p.token1?.decimals, + p.feeTier, + url, + p.volumeUSD7d + ); + }); + X.push(await Promise.all(promises)); + start += skip; + stop += skip; + } + const d = {}; + X.flat().forEach((p) => { + d[p.poolAddress] = p.estimatedFee; + }); + + dataNow = dataNow.map((p) => ({ + ...p, + apy7d: ((d[p.id] * 52) / investmentAmount) * 100, + })); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://uni.maiadao.io/#/add/${token0}/${token1}/${feeTier}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'maia-v3', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d * 0.9, // 10% reduction for protocol fees + apyBase7d: p.apy7d * 0.9, // 10% reduction for protocol fees + apyReward: p.apyReward, + rewardTokens: p.rewardTokens, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + data.push( + await topTvl( + chain, + url, + rewardsUrl, + query, + queryPrior, + queryIncentives, + 'v3', + timestamp, + stablecoins + ) + ); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/mainstreet/abis/RewardsWrapper.json b/src/adaptors/mainstreet/abis/RewardsWrapper.json new file mode 100644 index 0000000000..8523072741 --- /dev/null +++ b/src/adaptors/mainstreet/abis/RewardsWrapper.json @@ -0,0 +1,345 @@ +{ + "address": "0x9C58a617ade25B3fc809207B9B7c295517e3a743", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "_initMasterMinter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "MintRewardsFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintToInt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "Unchanged", + "type": "error" + }, + { + "inputs": [], + "name": "VaultBalanceUnchanged", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "newRate", + "type": "int256" + } + ], + "name": "InterestRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "name": "InternalCallFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "MasterMinterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "RATE_HISTORY_LENGTH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAULT", + "outputs": [ + { + "internalType": "contract IStakedmsUSD", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "apr", + "outputs": [ + { + "internalType": "int256", + "name": "_apr", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "getCurrentInterestRate", + "outputs": [ + { + "internalType": "int256", + "name": "currentRate", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "interestRatesHistory", + "outputs": [ + { + "internalType": "uint256", + "name": "currentIndex", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "ema", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "lastRewardsTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterMinter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mintRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMasterMinter", + "type": "address" + } + ], + "name": "updateMasterMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/mainstreet/abis/msUSD.json b/src/adaptors/mainstreet/abis/msUSD.json new file mode 100644 index 0000000000..e18d13e5be --- /dev/null +++ b/src/adaptors/mainstreet/abis/msUSD.json @@ -0,0 +1,1590 @@ +{ + "address": "0x4ba01f22827018b4772CD326C7627FB4956A7C00", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "lzEndpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [], + "name": "CantRenounceOwnership", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "SupplyLimitExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressException", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newMinter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oldMinter", + "type": "address" + } + ], + "name": "MinterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "SetUseCustomAdapterParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newStakedmsUSD", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oldStakedmsUSD", + "type": "address" + } + ], + "name": "StakedmsUSDUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "newSupplyLimit", + "type": "uint256" + } + ], + "name": "SupplyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakedmsUSD", + "type": "address" + } + ], + "name": "setStakedmsUSD", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setSupplyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "useCustomAdapterParams", + "type": "bool" + } + ], + "name": "setUseCustomAdapterParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakedmsUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/mainstreet/index.js b/src/adaptors/mainstreet/index.js new file mode 100644 index 0000000000..d40c76b484 --- /dev/null +++ b/src/adaptors/mainstreet/index.js @@ -0,0 +1,50 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const RewardsWrapper = require('./abis/RewardsWrapper.json'); +const msUSD = require('./abis/msUSD.json'); + +const CHAIN_NAME = 'ethereum'; +const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +const VAULT = '0x890A5122Aa1dA30fEC4286DE7904Ff808F0bd74A'; + +const poolsFunction = async () => { + const totalSupply = await sdk.api.abi + .call({ + target: msUSD.address, + abi: msUSD.abi.find((m) => m.name === 'totalSupply'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const apr = await sdk.api.abi + .call({ + target: RewardsWrapper.address, + abi: RewardsWrapper.abi.find((m) => m.name === 'getCurrentInterestRate'), + params: [VAULT], + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const apy = (Math.pow(1 + apr / 1e18 / 365, 365) - 1) * 100; + + const msUSDPool = { + pool: msUSD.address, + chain: utils.formatChain('ethereum'), + project: 'mainstreet', + symbol: utils.formatSymbol('msUSD'), + tvlUsd: Number(totalSupply) / 1e18, + apyBase: apy, + apyReward: 0, + rewardTokens: [msUSD.address], + underlyingTokens: [USDC], + url: 'https://mainstreet.finance', + }; + + return [msUSDPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/maple/index.ts b/src/adaptors/maple/index.ts new file mode 100644 index 0000000000..8389ada90b --- /dev/null +++ b/src/adaptors/maple/index.ts @@ -0,0 +1,96 @@ +const axios = require('axios'); +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); + +const API_URL = 'https://api.maple.finance/v2/graphql'; + +// Query for Syrup pools only +const query = { + operationName: 'getLendData', + variables: {}, + query: ` + query getLendData { + poolV2S(where: {syrupRouter_not: null}) { + id + name + assets + strategiesDeployed + principalOut + collateralValue + weeklyApy + asset { + id + symbol + decimals + price + } + } + syrupGlobals { + dripsYieldBoost + } + } + `, +}; + +const apy = async () => { + try { + const response = await axios.post(API_URL, query); + const pools = response.data.data.poolV2S; + const syrupGlobals = response.data.data.syrupGlobals; + const dripsYieldBoost = syrupGlobals?.dripsYieldBoost || 0; + + return pools + .map((pool) => { + const assetDecimals = pool.asset.decimals; + const priceDecimals = 8; + + const tokenPrice = new BigNumber(pool.asset.price).dividedBy( + new BigNumber(10).pow(priceDecimals) + ); + + const totalAssets = new BigNumber(pool.assets || 0) + .plus(pool.strategiesDeployed || 0) + .plus(pool.principalOut || 0) + .plus(pool.collateralValue || 0); + + const tvlUsd = totalAssets + .multipliedBy(tokenPrice) + .dividedBy(new BigNumber(10).pow(assetDecimals)) + .toNumber(); + + const apyBase = new BigNumber(pool.weeklyApy) + .dividedBy(new BigNumber(10).pow(28)) + .toNumber(); + const apyReward = new BigNumber(dripsYieldBoost) + .dividedBy(new BigNumber(10).pow(4)) + .toNumber(); + + return { + pool: pool.id, + chain: utils.formatChain('ethereum'), + project: 'maple', + symbol: pool.asset.symbol, + poolMeta: pool.name, + tvlUsd: tvlUsd, + apyBase: apyBase, + apyReward: apyReward, + underlyingTokens: [pool.asset.id], + rewardTokens: + apyReward > 0 ? ['0x643C4E15d7d62Ad0aBeC4a9BD4b001aA3Ef52d66'] : [], // Syrup token + // borrow fields + ltv: 0, // permissioned + url: 'https://app.maple.finance/earn', // Direct to earn page + }; + }) + .filter((p) => p !== null && p.tvlUsd > 0); // Filter out pools with no TVL + } catch (error) { + console.error('Error fetching Maple Finance data:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.maple.finance/earn', +}; diff --git a/src/adaptors/maple/query.ts b/src/adaptors/maple/query.ts new file mode 100644 index 0000000000..e994beb56b --- /dev/null +++ b/src/adaptors/maple/query.ts @@ -0,0 +1,158 @@ +const { gql } = require('graphql-request'); + +module.exports = { + query: gql` + query AllPoolsQuery($filter: Filter) { + results: allPools(filter: $filter) { + list { + ...PoolFields + __typename + } + total + __typename + } + } + + fragment PoolFields on Pool { + _id + hidden + allowedLPs + allowedSLs + balance + currentLoaned + defaultsTotal + delegateFee + farmingApy + lendingApy + liquidity + liquidityAsset { + ...AssetFields + __typename + } + liquidityAssetRecoveredTotal + liquidityCap + liquidityLocker + lockupPeriod + lpApy + mplRewards { + ...RewardFields + __typename + } + name + numActiveLoans + numPositions + openToPublic + ongoingFee + poolDelegate { + ...PoolDelegateFields + __typename + } + poolDelegateFees + poolName + poolPositions { + ...PoolPositionFields + __typename + } + poolTokenTotalSupply + stake + stakeAsset { + ...AssetFields + __typename + } + stakeLocker + stakeLockerFees + stakeLockerLiquidity + stakeLockerOpenToPublic + stakeLockupPeriod + stakeRewards { + ...RewardFields + __typename + } + stakeRewardsApy + stakingApy + stakingFee + state + strategy + symbol + totalFees + totalInterestEarned + totalLoaned + totalLoanOriginations + totalPoolTokensStaked + totalPrincipalRepaid + totalStakeLockerTokensStaked + transactionHash + transaction { + ...TransactionFields + __typename + } + txCount + __typename + } + + fragment AssetFields on Asset { + address + symbol + decimals + price + __typename + } + + fragment PoolDelegateFields on PoolDelegate { + _id + name + website + twitter + aboutBusiness + companyName + owner + allowList + telegram + linkedIn + deckFileUrl + __typename + } + + fragment RewardFields on MplRewards { + id + periodFinish + reward + rewardRate + rewardsDuration + paused + __typename + } + + fragment PoolPositionFields on PoolPosition { + id + poolTokenBalance + poolTokensStaked + claimableInterest + interestEarned + rewardPaid + custodyAllowance + depositDate + withdrawCooldown + recognizableLendingLosses + recognizedLendingLosses + withdrawStatus + stake + stakeLockerTokensStaked + claimableFees + feesEarned + stakeRewardPaid + stakeCustodyAllowance + stakeDate + unstakeCooldown + recognizableCoverLosses + recognizedCoverLosses + __typename + } + + fragment TransactionFields on Transaction { + id + timestamp + __typename + } + `, +}; diff --git a/src/adaptors/mare-finance-v1/abi.js b/src/adaptors/mare-finance-v1/abi.js new file mode 100644 index 0000000000..936de01262 --- /dev/null +++ b/src/adaptors/mare-finance-v1/abi.js @@ -0,0 +1,2815 @@ +module.exports = { + ercDelegator: [{ + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + { internalType: 'address payable', name: 'admin_', type: 'address' }, + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, ], + name: 'ImplementationDidNotChange', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'address', + name: 'oldImplementation', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'NewImplementation', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'adminPart', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'olaBank', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'olaPart', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + constant: true, + inputs: [], + name: 'CErc20DelegatorContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'contractNameHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: 'delegateToImplementation', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: 'delegateToViewImplementation', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAccrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract CTokenInterface', + name: 'cTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'olaReserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bool', name: 'allowResign', type: 'bool' }, + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: 'updateImplementationFromRegistry', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + distributorAbi: [{ + inputs: [ + { internalType: 'address', name: '_comptroller', type: 'address' }, + { internalType: 'address', name: '_admin', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'lnIncentiveToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'blockNumber', + type: 'uint256', + }, + ], + name: 'LnIncentiveTokenUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'SingleAssetDynamicRainMakerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'uint256', name: 'compSupplySpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'compBorrowSpeed', type: 'uint256' }, + ], + name: '_setDynamicCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract CToken[]', + name: '_cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '_compSupplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_compBorrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setDynamicCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'address', + name: 'incentiveTokenAddress', + type: 'address', + }, ], + name: '_setLnIncentiveToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPendingAdmin', type: 'address' }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: '_supportMarket', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'baseUnits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'market', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'connect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'contractNameHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'distributeBorrowerComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'supplier', type: 'address' }, + ], + name: 'distributeSupplierComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getLnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'isListed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRetired', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'lnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'retire', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'retireRainMaker', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'updateCompBorrowIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: 'updateCompSupplyIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + comptrollerAbi: [{ + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralUsage', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralUsage', + type: 'uint256', + }, + ], + name: 'ActiveCollateralUsageChange', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, ], + name: 'LimitBorrowingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, ], + name: 'LimitMintingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newActiveCollateralCap', + type: 'uint256', + }, + ], + name: 'NewActiveCollateralCap', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldAdminBankAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdminBankAddress', + type: 'address', + }, + ], + name: 'NewAdminBankAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldBouncer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBouncer', + type: 'address', + }, + ], + name: 'NewBouncer', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'contract CToken', + name: 'ctoken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'uint256', + name: 'oldMinBorrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMinBorrowAmount', + type: 'uint256', + }, + ], + name: 'NewMinBorrowAmount', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [{ + indexed: false, + internalType: 'address', + name: 'oldRainMaker', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newRainMaker', + type: 'address', + }, + ], + name: 'NewRainMaker', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_afterNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_beforeNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_latestVersionSynced', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newActiveCollateralCaps', + type: 'uint256[]', + }, + ], + name: '_setActiveCollateralCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'address payable', + name: 'newAdminBankAddress', + type: 'address', + }, ], + name: '_setAdminBankAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setBouncer', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitBorrowing', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitMinting', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'uint256', + name: 'minBorrowAmountUsd_', + type: 'uint256', + }, ], + name: '_setMinBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setRainMaker', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'address', name: 'interestRateModel', type: 'address' }, + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: '_supportNewMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'adminBankAddress', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'bouncer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'bytes32', name: '', type: 'bytes32' }, + ], + name: 'existingMarketTypes', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getRegistry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasBouncer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'initializeNewComptroller', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isAccountApproved', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitMinting', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isComped', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'minBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rainMaker', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'registry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unitrollerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, ], + name: 'updateDelegatedImplementations', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; \ No newline at end of file diff --git a/src/adaptors/mare-finance-v1/index.js b/src/adaptors/mare-finance-v1/index.js new file mode 100644 index 0000000000..4205f036d5 --- /dev/null +++ b/src/adaptors/mare-finance-v1/index.js @@ -0,0 +1,226 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator, distributorAbi } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x4804357AcE69330524ceb18F2A647c3c162E1F95'; +const REWARD_DISTRIBUTOR = '0x4804357AcE69330524ceb18F2A647c3c162E1F95'; +const CHAIN = 'kava'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const REWARD_SPEEDS = 'compSupplySpeeds'; +const BORROW_SPEEDS = 'compBorrowSpeeds'; +const TOTAL_BORROWS = 'totalBorrows'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const SECONDS_PER_DAY = 86400; +const BLOCKS_PER_DAY = SECONDS_PER_DAY; + +const PROJECT_NAME = 'mare-finance-v1'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WKAVA', + address: '0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'MARE', + address: '0xd86C8d4279CCaFbec840c782BcC50D201f277419'.toLowerCase(), +}; + +const getRewards = async (markets, isBorrow) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: REWARD_DISTRIBUTOR, + params: [market], + })), + abi: distributorAbi.find( + ({ name }) => name === (isBorrow ? BORROW_SPEEDS : REWARD_SPEEDS) + ), + }) + ).output.map(({ output }) => output); +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + }) + ).output.map(({ output }) => output); +}; + +const lendingApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const marketsInfo = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: allMarkets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: market, + })), + abi: comptrollerAbi.find(({ name }) => name === 'markets'), + }) + ).output.map(({ output }) => output); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const distributeRewards = await getRewards(allMarkets); + const distributeBorrowRewards = await getRewards(allMarkets, true); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .concat([PROTOCOL_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + const token = + symbol === 'KAVA' ? NATIVE_TOKEN.address : underlyingTokens[i]; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const tvlUsd = (marketsCash[i] / 10 ** decimals) * price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const apyReward = + (((distributeRewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((distributeBorrowRewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + SECONDS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalBorrowUsd) * + 100; + + return { + pool: market, + chain: CHAIN, + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward > 0 ? PROTOCOL_TOKEN.address : null].filter( + Boolean + ), + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: marketsInfo[i].collateralFactorMantissa / 10 ** 18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: lendingApy, + url: 'v1.mare.finance', +}; diff --git a/src/adaptors/marginfi-lending/index.js b/src/adaptors/marginfi-lending/index.js new file mode 100644 index 0000000000..30d7262a5a --- /dev/null +++ b/src/adaptors/marginfi-lending/index.js @@ -0,0 +1,17 @@ +const fetch = require('node-fetch'); + +const MARGINFI_URL = 'https://app.marginfi.com'; +const SNAPSHOT_URL = + 'https://marignfi-pools-snapshot.s3.amazonaws.com/snapshot.json'; + +async function main() { + const snapshotResponse = await fetch(SNAPSHOT_URL); + const snapshot = await snapshotResponse.json(); + return snapshot.map((p) => ({ ...p, project: 'marginfi-lending' })); +} + +module.exports = { + timetravel: false, + apy: main, + url: MARGINFI_URL, +}; diff --git a/src/adaptors/marinade-liquid-staking/index.js b/src/adaptors/marinade-liquid-staking/index.js new file mode 100644 index 0000000000..68e69184c0 --- /dev/null +++ b/src/adaptors/marinade-liquid-staking/index.js @@ -0,0 +1,31 @@ +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const MSOL_ADDRESS = 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So'; +const priceKey = `solana:${MSOL_ADDRESS}`; + +const apy = async () => { + const [apyResponse, priceResponse, totalSupply] = await Promise.all([ + axios.get('https://api.marinade.finance/msol/apy/7d'), + axios.get(`https://coins.llama.fi/prices/current/${priceKey}`), + getTotalSupply(MSOL_ADDRESS), + ]); + + const apyValue = apyResponse.data.value; + const currentPrice = priceResponse.data.coins[priceKey].price; + const tvlUsd = totalSupply * currentPrice; + + return [ + { + pool: MSOL_ADDRESS, + chain: 'Solana', + project: 'marinade-liquid-staking', + symbol: 'MSOL', + tvlUsd: tvlUsd, + apyBase: apyValue * 100, + underlyingTokens: [MSOL_ADDRESS], + }, + ]; +}; + +module.exports = { apy, url: 'https://marinade.finance/liquid-staking' }; diff --git a/src/adaptors/mars-lend/index.js b/src/adaptors/mars-lend/index.js new file mode 100644 index 0000000000..545695dc87 --- /dev/null +++ b/src/adaptors/mars-lend/index.js @@ -0,0 +1,205 @@ +const utils = require('../utils'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const chains = ['osmosis', 'neutron']; + +const contractAddresses = { + osmosis: { + params: 'osmo1nlmdxt9ctql2jr47qd4fpgzg84cjswxyw6q99u4y4u4q6c2f5ksq7ysent', + redBank: 'osmo1c3ljch9dfw5kf52nfwpxd2zmj2ese7agnx0p9tenkrryasrle5sqf3ftpg', + oracle: 'osmo1mhznfr60vjdp2gejhyv2gax9nvyyzhd3z0qcwseyetkfustjauzqycsy2g', + }, + neutron: { + params: + 'neutron1x4rgd7ry23v2n49y7xdzje0743c5tgrnqrqsvwyya2h6m48tz4jqqex06x', + redBank: + 'neutron1n97wnm7q6d2hrcna3rqlnyqw2we6k0l8uqvmyqq6gsml92epdu7quugyph', + oracle: + 'neutron1dwp6m7pdrz6rnhdyrx5ha0acsduydqcpzkylvfgspsz60pj2agxqaqrr7g', + perps: 'neutron1g3catxyv0fk8zzsra2mjc0v4s69a7xygdjt85t54l7ym3gv0un4q2xhaf6', + }, +}; + +const restEndpoints = { + osmosis: 'https://osmosis-rest.cosmos-apis.com', + neutron: 'https://neutron-rest.cosmos-apis.com', +}; + +const tokenApis = { + osmosis: 'https://cache.marsprotocol.io/api/osmosis-1/tokens', + neutron: 'https://cache.marsprotocol.io/api/neutron-1/tokens', +}; + +const perpsVaultApi = { + osmosis: 'https://backend.prod.mars-dev.net/v2/perps_vault?chain=osmosis', + neutron: 'https://backend.prod.mars-dev.net/v2/perps_vault?chain=neutron', +}; + +const perpsDenom = { + osmosis: + 'ibc/498A0751C798A0D9A389AA3691123DADA57DAA4FE165D5C75894505B876BA6E4', + neutron: + 'ibc/B559A80D62249C8AA07A380E2A2BEA6E5CA9A6F079C912C3A9E9B494105E4F81', +}; + +async function apy() { + const apyData = []; + const pageLimit = 5; + const oracleDecimals = 6; + + await getApy('osmosis'); + await getApy('neutron'); + + return apyData; + + async function getApy(chain) { + let startAfter = null; + const { params, redBank, oracle, perps } = contractAddresses[chain]; + const api = restEndpoints[chain]; + const tokenInfos = await axios.get(tokenApis[chain]); + + await getApyDataForPerpsVault(chain); + do { + const assetParams = await queryContract(api, params, { + all_asset_params: { limit: pageLimit, start_after: startAfter }, + }); + if (assetParams.length === pageLimit) + startAfter = assetParams[assetParams.length - 1].denom; + else startAfter = null; + await getApyDataForAsset(assetParams, chain); + } while (startAfter); + + async function getApyDataForPerpsVault(chain) { + if (!perps) return; + + const perpsVault = await queryContract(api, perps, { vault: {} }); + + const perpsVaultApyData = await axios.get(perpsVaultApi[chain]); + if (perpsVault) { + const perpsAsset = tokenInfos.data.tokens.find( + (token) => token.denom === perpsDenom[chain] + ); + if (!perpsAsset) return; + const perpsTotalBalance = new BigNumber( + perpsVault.total_balance + ).shiftedBy(-perpsAsset.decimals); + const perpsPriceInfo = await queryContract(api, oracle, { + price: { denom: perpsDenom[chain] }, + }); + const priceDecimalsDifference = perpsAsset.decimals - oracleDecimals; + const price = new BigNumber(perpsPriceInfo.price).shiftedBy( + priceDecimalsDifference + ); + const apyBase = Number(perpsVaultApyData.data.projected_apy); + + const tvlUsd = perpsTotalBalance.times(price).toNumber(); + if (tvlUsd < 10_000) return; + + apyData.push({ + pool: `mars-cpv-${perpsDenom[chain]}-${chain}`.toLowerCase(), + symbol: perpsAsset.symbol, + underlyingTokens: [perpsAsset.denom], + project: 'mars-lend', + chain: `${chain.charAt(0).toUpperCase()}${chain.slice(1)}`, + tvlUsd, + apyBase, + poolMeta: '10 days unstaking', + url: + chain === 'osmosis' + ? 'https://osmosis.marsprotocol.io/perps-vault/' + : 'https://neutron.marsprotocol.io/perps-vault/', + }); + } + } + + async function getApyDataForAsset(assetParams, chain) { + await Promise.all( + assetParams.map(async (currentParams) => { + const asset = tokenInfos.data.tokens.find( + (token) => token.denom === currentParams.denom + ); + if (!asset) return; + + const marketInfo = await queryContract(api, redBank, { + market: { denom: asset.denom }, + }); + const totalDepositInfo = await queryContract(api, params, { + total_deposit: { denom: asset.denom }, + }); + const priceInfo = await queryContract(api, oracle, { + price: { denom: asset.denom }, + }); + const amountScaled = marketInfo['debt_total_scaled']; + const debtInfo = await queryContract(api, redBank, { + underlying_debt_amount: { + denom: asset.denom, + amount_scaled: amountScaled, + }, + }); + + const priceDecimalsDifference = asset.decimals - oracleDecimals; + const price = new BigNumber(priceInfo.price).shiftedBy( + priceDecimalsDifference + ); + + const totalSupplied = new BigNumber( + totalDepositInfo.amount + ).shiftedBy(-asset.decimals); + const totalBorrowed = new BigNumber(debtInfo).shiftedBy( + -asset.decimals + ); + + const depositApr = marketInfo.liquidity_rate * 100; + const borrowApr = marketInfo.borrow_rate * 100; + const tvlUsd = totalSupplied + .minus(totalBorrowed) + .times(price) + .toNumber(); + + if ( + tvlUsd < 10_000 || + !currentParams.credit_manager.whitelisted || + !currentParams.red_bank.deposit_enabled + ) + return; + + apyData.push({ + pool: `mars-${asset.denom}-${chain}`.toLowerCase(), + chain: `${chain.charAt(0).toUpperCase()}${chain.slice(1)}`, + project: 'mars-lend', + symbol: asset.symbol, + tvlUsd: totalSupplied.minus(totalBorrowed).times(price).toNumber(), + apyBase: utils.aprToApy(depositApr, 365), + underlyingTokens: [asset.denom], + totalSupplyUsd: totalSupplied.times(price).toNumber(), + totalBorrowUsd: totalBorrowed.times(price).toNumber(), + apyBaseBorrow: utils.aprToApy(borrowApr, 365), + ltv: Number(currentParams.max_loan_to_value), + url: + chain === 'osmosis' + ? 'https://osmosis.marsprotocol.io/earn/' + : 'https://neutron.marsprotocol.io/earn/', + borrowable: currentParams.red_bank.borrow_enabled, + }); + }) + ); + } + } +} + +async function queryContract(api, contract, data) { + if (typeof data !== 'string') { + data = JSON.stringify(data); + } + const encodedData = Buffer.from(data).toString('base64'); + const endpoint = `${api}/cosmwasm/wasm/v1/contract/${contract}/smart/${encodedData}?x-apikey=7e3642de`; + const result = await await utils.getData(endpoint); + return result.data; +} + +module.exports = { + apy, + timetravel: false, + url: 'https://app.marsprotocol.io/earn/', +}; diff --git a/src/adaptors/matter-defi/index.js b/src/adaptors/matter-defi/index.js new file mode 100644 index 0000000000..23e9acf496 --- /dev/null +++ b/src/adaptors/matter-defi/index.js @@ -0,0 +1,270 @@ +const axios = require('axios'); +const utils = require('../utils'); +const { PromisePool } = require('@supercharge/promise-pool'); +const { BigNumber } = require('bignumber.js'); + +const RPC_ENDPOINT = 'https://api.tzkt.io'; +const SPICY_URL = 'https://spicya.sdaotools.xyz/api/rest'; +const MATTER_CORE = 'KT1K4jn23GonEmZot3pMGth7unnzZ6EaMVjY'; + +let matterPrice, xtzPrice; +let _spicePools, _spiceTokens; + +const fetchXtzPrice = async () => { + return new BigNumber( + (await axios(`${RPC_ENDPOINT}/v1/quotes/last`)).data.usd + ).toFixed(2); +}; +const fetchMatterPrice = async (agg) => { + return ( + await axios( + `${SPICY_URL}/TokenList?_ilike=${MATTER_CORE}:0&day_agg_start=${agg}` + ) + ).data.tokens[0].derivedxtz; +}; +const fetchTokenNameTzkt = async (contract) => { + return (await axios(`${RPC_ENDPOINT}/v1/contracts/${contract}`)).data.alias; +}; +const fetchTokenNameSpicy = async (token) => { + return (await axios(`${SPICY_URL}/TokenList?_ilike=${token}`)).data.tokens[0] + .symbol; +}; +const fetchTokenBalances = async (account) => { + return ( + await axios( + `${RPC_ENDPOINT}/v1/tokens/balances?account=${account}&limit=100&select=balance,token.id%20as%20id,token.contract%20as%20contract,token.standard%20as%20standard,token.tokenId%20as%20token_id` + ) + ).data; +}; + +const fetchSupply = async (contract, id) => { + const req = id + ? `/v1/tokens/?contract=${contract}&tokenId=${id}` + : `/v1/tokens/?contract=${contract}`; + const supply = (await axios(`${RPC_ENDPOINT}${req}`)).data; + + return new BigNumber(supply[0].totalSupply); +}; + +const fetchAllPools = async () => { + if (!_spicePools) _spicePools = axios(`${SPICY_URL}/PoolListAll/`); + const spicyPools = (await _spicePools).data.pair_info; + + return spicyPools.map((pool) => ({ + contract: pool.contract, + reserve: pool.reservextz, + token0: pool.token0, + token1: pool.token1, + })); +}; + +const fetchSpicyTokens = async (agg) => { + if (!_spiceTokens) + _spiceTokens = axios(`${SPICY_URL}/TokenList?day_agg_start=${agg}`); + const spicyTokens = (await _spiceTokens).data.tokens; + + return spicyTokens; +}; + +const fetchMatterFarms = async (pools, tokens) => { + const req = `/v1/contracts/${MATTER_CORE}/bigmaps/farms_internal/keys`; + const farms = (await axios(`${RPC_ENDPOINT}${req}`)).data; + + const req2 = `/v1/contracts/${MATTER_CORE}/storage/`; + const configs = (await axios(`${RPC_ENDPOINT}${req2}`)).data.configs; + + const today = new Date(); + const active = new Date(configs[0].active_time); + + let activeConfig; + + if (today.getTime() >= active.getTime()) { + activeConfig = configs[0].farm_configs; + } else { + activeConfig = configs[1].farm_configs; + } + + const output = farms.reduce((a, p) => { + const uF = activeConfig.find( + (config) => config.key.fa2_address === p.key.fa2_address + ); + const findToken = tokens.find( + (token) => token.tag === `${p.key.fa2_address}:${p.key.token_id}` + ); + const findPool = pools.find( + (pool) => pool.contract === `${p.key.fa2_address}` + ); + + if (uF) { + a.push({ + ...p, + reward: uF.value.reward_per_sec, + decimals: findToken ? findToken.decimals : 18, + symbol: findToken ? findToken.symbol : '', + token0: findPool ? findPool.token0 : uF.key.fa2_address, + token1: findPool ? findPool.token1 : '', + derivedXtz: findToken ? findToken.derivedxtz : 0, + }); + } + + return a; + }, []); + + return output.map((farm) => ({ + key: farm.key, + staked: farm.value.totalStaked, + reward: farm.reward, + decimals: farm.decimals, + token0: farm.token0, + token1: farm.token1, + symbol: farm.symbol, + derivedXtz: farm.derivedXtz, + })); +}; + +const matchToMatter = async (farm, spicyPools) => { + const match = spicyPools.find( + (pool) => pool.contract == farm.key.fa2_address + ); + + if (match) { + const symbol = await fetchTokenNameTzkt(farm.key.fa2_address); + + farm.supply = new BigNumber( + await fetchSupply(farm.key.fa2_address) + ).shiftedBy(-farm.decimals); + farm.reserveXtz = new BigNumber(match.reserve); + farm.staked = new BigNumber(farm.staked).shiftedBy(-farm.decimals); + + if (symbol) { + farm.symbol = symbol.split(' ').slice(1).join(' '); + } else { + const token0Name = await fetchTokenNameSpicy(farm.token0); + const token1Name = await fetchTokenNameSpicy(farm.token1); + + farm.symbol = + token0Name && token1Name ? `${token0Name}/${token1Name}` : 'Unknown'; + } + + farm.apr = poolToApr(farm); + farm.apy = aprToApy(farm.apr); + farm.tvl = lpToTez(farm); + } else { + farm.supply = new BigNumber( + await fetchSupply(farm.key.fa2_address) + ).shiftedBy(-farm.decimals); + farm.staked = new BigNumber(farm.staked).shiftedBy(-farm.decimals); + + farm.apr = tokenToApr(farm); + farm.apy = aprToApy(farm.apr); + farm.tvl = lpToTez(farm); + } + + return farm; +}; + +const fetchSpicyPoolsAndMatch = async (spicyPools, matterFarms, tokens) => { + const { results, errors } = await PromisePool.withConcurrency(10) + .for(matterFarms) + .process(async (farm) => matchToMatter(farm, spicyPools, matterFarms)); + + if (errors && errors.length) { + throw errors[0]; + } + + return results.filter((result) => result); +}; + +const lpToTez = (farm) => { + if (!farm.reserveXtz) { + return new BigNumber(farm.derivedXtz).multipliedBy(farm.staked).toFixed(0); + } else { + const tezPerLp = farm.reserveXtz.dividedBy( + farm.supply.shiftedBy(-farm.decimals) + ); + + return tezPerLp + .multipliedBy(farm.staked.shiftedBy(-farm.decimals)) + .toFixed(0); + } +}; + +const tokenToApr = (token) => { + const rewardPerSec = BigNumber(token.reward).shiftedBy(-12); + const totalStaked = token.staked; + const stakePrice = token.derivedXtz; + const combined = totalStaked.multipliedBy(stakePrice); + + const apr = + combined > 0 + ? new BigNumber( + ((rewardPerSec * matterPrice * 86400 * 365) / combined) * 100 + ) + : new BigNumber(0); + + return apr; +}; + +const poolToApr = (pool) => { + const rewardPerSec = BigNumber(pool.reward).shiftedBy(-12); + const totalStaked = pool.staked; + const stakePrice = pool.reserveXtz + .dividedBy(pool.supply) + .shiftedBy(-pool.decimals); + const combined = totalStaked.multipliedBy(stakePrice); + + const apr = + combined > 0 + ? new BigNumber( + ((rewardPerSec * matterPrice * 86400 * 365) / combined) * 100 + ) + : new BigNumber(0); + + return apr.shiftedBy(-18); +}; + +const aprToApy = (apr) => { + const e = Number(apr / 100); + const h = Math.pow(1 + e / 52, 52) - 1; + + return h > 0 ? (100 * h).toFixed(2) : 0; +}; + +const calculateDayAgg = () => { + let agg_start = new Date(); + agg_start.setDate(agg_start.getDate() - 7); + agg_start = Math.floor(agg_start.getTime() / 1000); + + return agg_start; +}; + +const apy = async () => { + matterPrice = await fetchMatterPrice(calculateDayAgg()); + xtzPrice = await fetchXtzPrice(); + + const matterCoreBalances = await fetchTokenBalances(MATTER_CORE); + const pools = await fetchAllPools(); + const tokens = await fetchSpicyTokens(calculateDayAgg()); + const farms = await fetchMatterFarms(pools, tokens); + + const matchedPools = await fetchSpicyPoolsAndMatch(pools, farms); + + const corePools = matchedPools.map((p) => ({ + pool: `${p.key.fa2_address}`, + chain: 'Tezos', + project: 'matter-defi', + symbol: utils.formatSymbol(p.symbol), + tvlUsd: Number((p.tvl * xtzPrice).toFixed(2)), + apyReward: Number(p.apy), + rewardTokens: [MATTER_CORE], + underlyingTokens: p.token1 ? [p.token0, p.token1] : [p.token0], + })); + + return [...corePools]; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://matterdefi.xyz/#/', +}; diff --git a/src/adaptors/maverick-v1/index.js b/src/adaptors/maverick-v1/index.js new file mode 100644 index 0000000000..ee89cc44f1 --- /dev/null +++ b/src/adaptors/maverick-v1/index.js @@ -0,0 +1,119 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const PROJECT = 'maverick-v1'; + +const SubgraphConfigs = { + ethereum: sdk.graph.modifyEndpoint('H4KMc3uRaRqKrM8dq8GKCt9gwmMQsRRiQRThZCM16KtB'), +} + +const query = function(blockNumber) { + return gql` + { + pools(first: 1000, orderBy: balanceUSD, orderDirection: desc, block: {number: ${blockNumber}}) { + id + tokenA { + id + symbol + } + tokenB { + id + symbol + } + volumeUSD + balanceUSD + fee + } + } + `; +} + +async function fetchPools(subgraph, blockNumber) { + const poolsMap = {} + + const poolsList = (await request(subgraph, query(blockNumber))).pools; + for (const pool of poolsList) { + const poolAddress = String(pool.id).toLowerCase(); + const token0Address = String(pool.tokenA.id).toLowerCase(); + const token1Address = String(pool.tokenB.id).toLowerCase(); + poolsMap[poolAddress] = { + address: poolAddress, + token0: { + address: token0Address, + symbol: pool.tokenA.symbol, + }, + token1: { + address: token1Address, + symbol: pool.tokenB.symbol, + }, + volumeUSD: Number(pool.volumeUSD), + balanceUSD: Number(pool.balanceUSD), + feeRate: Number(pool.fee), + } + } + + return poolsMap +} + +function getPoolLink(chain, poolAddress) { + let chainId = 1 + if (chain === 'arbitrum') chainId = 42161; + if (chain === 'polygon') chainId = 137; + if (chain === 'base') chainId = 42161; + + return `https://app-v1.mav.xyz/pool/${poolAddress}?chain=${chainId}`; +} + +const main = async (unixTimestamp) => { + const yieldPools = [] + + const timestamp = unixTimestamp ? unixTimestamp : Math.floor(new Date().getTime() / 1000); + const currentBlocks = await sdk.blocks.getBlocks(timestamp, Object.keys(SubgraphConfigs)); + const last1DaysBlocks = await sdk.blocks.getBlocks(timestamp - 24 * 60 * 60, Object.keys(SubgraphConfigs)); + const last7DaysBlocks = await sdk.blocks.getBlocks(timestamp - 7 * 24 * 60 * 60, Object.keys(SubgraphConfigs)); + + for (const [chain, subgraph] of Object.entries(SubgraphConfigs)) { + const currentPoolsData = await fetchPools(subgraph, currentBlocks.chainBlocks[chain]); + const last1DaysPoolsData = await fetchPools(subgraph, last1DaysBlocks.chainBlocks[chain]); + const last7DaysPoolsData = await fetchPools(subgraph, last7DaysBlocks.chainBlocks[chain]); + + for (const [address, pool] of Object.entries(currentPoolsData)) { + let volumeUsd1d = 0; + let volumeUsd7d = 0; + let feeUsd1d = 0; + let feeUsd7d = 0; + + if (last1DaysPoolsData[address]) { + volumeUsd1d = currentPoolsData[address].volumeUSD - last1DaysPoolsData[address].volumeUSD; + feeUsd1d = volumeUsd1d * currentPoolsData[address].feeRate; + } + if (last7DaysPoolsData[address]) { + volumeUsd7d = currentPoolsData[address].volumeUSD - last7DaysPoolsData[address].volumeUSD; + feeUsd7d = volumeUsd7d * currentPoolsData[address].feeRate; + } + + yieldPools.push({ + chain: utils.formatChain(chain), + project: PROJECT, + pool: address, + symbol: utils.formatSymbol(`${pool.token0.symbol}-${pool.token1.symbol}`), + underlyingTokens: [pool.token0.address, pool.token1.address], + tvlUsd: pool.balanceUSD, + apyBase: pool.balanceUSD > 0 ? feeUsd1d * 365 * 100 / pool.balanceUSD : 0, + apyBase7d: pool.balanceUSD > 0 ? feeUsd7d * 365 * 100 / 7 / pool.balanceUSD : 0, + volumeUsd1d: volumeUsd1d, + volumeUsd7d: volumeUsd7d, + url: getPoolLink(chain, address), + }) + } + } + + return yieldPools + .filter(pool => pool.tvlUsd > 0); +}; + +module.exports = { + timetravel: true, + apy: main, +}; diff --git a/src/adaptors/maverick-v2/index.js b/src/adaptors/maverick-v2/index.js new file mode 100644 index 0000000000..dd119a0d15 --- /dev/null +++ b/src/adaptors/maverick-v2/index.js @@ -0,0 +1,218 @@ +const superagent = require('superagent'); +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const PROJECT = 'maverick-v2'; + +const FactoryConfigs = { + ethereum: { + factory: '0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e', + fromBlock: 20027237, + }, + // arbitrum: { + // factory: '0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e', + // fromBlock: 219205178, + // }, + // base: { + // factory: '0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e', + // fromBlock: 15321282, + // }, + // bsc: { + // factory: '0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e', + // fromBlock: 39421941, + // }, + // scroll: { + // factory: '0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e', + // fromBlock: 7332349, + // }, + // era: { + // factory: '0x7A6902af768a06bdfAb4F076552036bf68D1dc56', + // fromBlock: 35938168, + // }, +} + +const EventPoolCreated = 'event PoolCreated(address poolAddress, uint8 protocolFeeRatio, uint256 feeAIn, uint256 feeBIn, uint256 tickSpacing, uint256 lookback, int32 activeTick, address tokenA, address tokenB, uint8 kinds, address accessor)'; +const EventPoolSwap = 'event PoolSwap(address sender, address recipient, tuple(uint256 amount, bool tokenAIn, bool exactOutput, int32 tickLimit), uint256 amountIn, uint256 amountOut)'; + +function getPoolLink(chain, poolAddress) { + let chainId = 1 + if (chain === 'arbitrum') chainId = 42161; + if (chain === 'polygon') chainId = 137; + if (chain === 'base') chainId = 42161; + + return `https://app.mav.xyz/pool/${poolAddress}?chain=${chainId}`; +} + +async function fetchPools(chain, currentBlock) { + const events = await sdk.getEventLogs({ + chain: chain, + eventAbi: EventPoolCreated, + target: FactoryConfigs[chain].factory, + fromBlock: FactoryConfigs[chain].fromBlock, + toBlock: currentBlock, + }); + + const pools = {}; + for (const event of events) { + const poolAddress = utils.formatAddress(event.args.poolAddress); + pools[poolAddress] = { + pool: poolAddress, + token0Address: utils.formatAddress(event.args.tokenA), + token1Address: utils.formatAddress(event.args.tokenB), + fee0In: Number(event.args.feeAIn) / 1e18, + fee1In: Number(event.args.feeBIn) / 1e18, + } + } + + return pools; +} + +const main = async (unixTimestamp) => { + const yieldPools = [] + + const timestamp = unixTimestamp ? unixTimestamp : Math.floor(new Date().getTime() / 1000); + const currentBlocks = await sdk.blocks.getBlocks(timestamp, Object.keys(FactoryConfigs)); + const last1DaysBlocks = await sdk.blocks.getBlocks(timestamp - 24 * 60 * 60, Object.keys(FactoryConfigs)); + const last7DaysBlocks = await sdk.blocks.getBlocks(timestamp - 7 * 24 * 60 * 60, Object.keys(FactoryConfigs)); + + for (const [chain, factoryConfig] of Object.entries(FactoryConfigs)) { + const currentBlock = currentBlocks.chainBlocks[chain]; + const last1DaysBlock = last1DaysBlocks.chainBlocks[chain]; + const last7DaysBlock = last7DaysBlocks.chainBlocks[chain]; + + const allTokens = {}; + const allDexPools = {}; + const rawPools = await fetchPools(chain, currentBlock); + + const tokenCalls = []; + const balanceCalls = []; + for (const rawPool of Object.values(rawPools)) { + tokenCalls.push(rawPool.token0Address); + tokenCalls.push(rawPool.token1Address); + balanceCalls.push({ target: rawPool.token0Address, params: [rawPool.pool] }); + balanceCalls.push({ target: rawPool.token1Address, params: [rawPool.pool] }); + } + const [symbols, decimals, balances] = await Promise.all([ + sdk.api2.abi.multiCall({ chain: chain, abi: 'string:symbol', calls: tokenCalls }), + sdk.api2.abi.multiCall({ chain: chain, abi: 'uint8:decimals', calls: tokenCalls }), + sdk.api2.abi.multiCall({ chain: chain, abi: 'function balanceOf(address) view returns (uint256)', calls: balanceCalls }), + ]); + + for (let i = 0; i < Object.values(rawPools).length; i++) { + const rawPool = Object.values(rawPools)[i]; + + const token0 = { address: rawPool.token0Address, symbol: symbols[i * 2], decimals: Number(decimals[i * 2]) } + const token1 = { address: rawPool.token1Address, symbol: symbols[i * 2 + 1], decimals: Number(decimals[i * 2 + 1]) } + + allDexPools[rawPool.pool] = { + pool: rawPool.pool, + fee0In: rawPool.fee0In, + fee1In: rawPool.fee1In, + token0: token0, + token1: token1, + reserve0: Number(balances[i * 2]), + reserve1: Number(balances[i * 2 + 1]), + + // will fill below + tvlUsd: 0, + volumeUsd1d: 0, + volumeUsd7d: 0, + feeUsd1d: 0, + feeUsd7d: 0, + } + + allTokens[rawPool.token0Address] = token0; + allTokens[rawPool.token1Address] = token1; + } + + // get token price from llama coins api + const coinLists = Object.keys(allTokens).map(token => `${chain}:${token}`); + const coinPrices = (await superagent.get(`https://coins.llama.fi/prices/current/${coinLists.toString()}`)).body.coins; + for (const [coinId, coinPrice] of Object.entries(coinPrices)) { + allTokens[utils.formatAddress(coinId.split(':')[1])].price = Number(coinPrice.price); + } + + // cal tvl + for (const [address, dexPool] of Object.entries(allDexPools)) { + const token0Price = allTokens[dexPool.token0.address].price ? allTokens[dexPool.token0.address].price : 0; + const token1Price = allTokens[dexPool.token1.address].price ? allTokens[dexPool.token1.address].price : 0; + const token0Reserve = dexPool.reserve0 * token0Price / 10**dexPool.token0.decimals; + const token1Reserve = dexPool.reserve1 * token1Price / 10**dexPool.token1.decimals; + + // update pool tvl USD + allDexPools[address].tvlUsd = token0Reserve + token1Reserve; + } + + const iface = new ethers.utils.Interface([EventPoolSwap]) + const swapLogs = (await sdk.getEventLogs({ + chain: chain, + eventAbi: EventPoolSwap, + targets: Object.values(allDexPools).filter(pool => pool.tvlUsd > 0).map(pool => pool.pool), + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + })).map(log => { + const event = iface.parseLog({ + topics: log.topics, + data: log.data, + }); + + return { + address: utils.formatAddress(log.address), + blockNumber: Number(log.blockNumber), + args: { + swap0to1: event.args[2].tokenAIn, + amountIn: Number(event.args.amountIn), + amountOut: Number(event.args.amountOut), + } + } + }); + + for (const log of swapLogs) { + let volumeUsd = 0; + let feeUsd = 0; + const dexPool = allDexPools[log.address]; + if (log.args.swap0to1) { + const tokenPrice = allTokens[dexPool.token0.address].price ? allTokens[dexPool.token0.address].price : 0; + volumeUsd = Number(log.args.amountIn) * tokenPrice / 10**dexPool.token0.decimals; + feeUsd = volumeUsd * dexPool.fee0In; + } else { + const tokenPrice = allTokens[dexPool.token1.address].price ? allTokens[dexPool.token1.address].price : 0; + volumeUsd = Number(log.args.amountIn) * tokenPrice / 10**dexPool.token1.decimals; + feeUsd = volumeUsd * dexPool.fee1In; + } + + if (log.blockNumber >= last1DaysBlock) { + allDexPools[log.address].volumeUsd1d += volumeUsd; + allDexPools[log.address].feeUsd1d += feeUsd; + } + allDexPools[log.address].volumeUsd7d += volumeUsd; + allDexPools[log.address].feeUsd7d += feeUsd; + } + + for (const p of Object.values(allDexPools).filter(pool => pool.tvlUsd > 0)) { + yieldPools.push({ + chain: utils.formatChain(chain), + project: PROJECT, + pool: p.pool, + symbol: utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`), + underlyingTokens: [p.token0.address, p.token1.address], + tvlUsd: p.tvlUsd, + apyBase: p.feeUsd1d * 100 * 365 / p.tvlUsd, + apyBase7d: p.feeUsd7d * 100 * 365 / 7 / p.tvlUsd, + volumeUsd1d: p.volumeUsd1d, + volumeUsd7d: p.volumeUsd7d, + url: getPoolLink(chain, p.pool), + }) + } + } + + return yieldPools; +}; + +module.exports = { + timetravel: true, + apy: main, +}; diff --git a/src/adaptors/maxapy/index.js b/src/adaptors/maxapy/index.js new file mode 100644 index 0000000000..62385fe305 --- /dev/null +++ b/src/adaptors/maxapy/index.js @@ -0,0 +1,118 @@ +const utils = require('../utils'); + +const VAULTS = { + ethereum: { + '0x9847c14FCa377305c8e2D10A760349c667c367d4': { + symbol: 'WETH', + underlying: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' + }, + '0x349c996C4a53208b6EB09c103782D86a3F1BB57E': { + symbol: 'USDC', + underlying: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' + } + }, + polygon: { + '0xA02aA8774E8C95F5105E33c2f73bdC87ea45BD29': { + symbol: 'WETH', + underlying: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619' + }, + '0xE7FE898A1EC421f991B807288851241F91c7e376': { + symbol: 'USDC', + underlying: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' + } + }, + base: { + '0xb272e80042634Bca5d3466446b0C48Ba278A8Ae5': { + symbol: 'WETH', + underlying: '0x4200000000000000000000000000000000000006' + }, + '0x7a63e8FC1d0A5E9BE52f05817E8C49D9e2d6efAe': { + symbol: 'USDC', + underlying: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' + } + } +}; + +const CHAIN_IDS = { + ethereum: 1, + polygon: 137, + base: 8453 +}; + +class MaxApyAdapter { + constructor() { + this.baseUrl = 'https://api.maxapy.io'; + this.projectUrl = 'https://app.maxapy.io/vaults'; + } + + createPoolObject(vaultAddress, chain, vaultInfo) { + return { + pool: `${vaultAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'maxapy', + symbol: utils.formatSymbol(vaultInfo.symbol), + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [vaultInfo.underlying], + url: `${this.projectUrl}/${chain}/${vaultInfo.symbol}` + }; + } + + async fetchVaultApy(chainId, vaultAddress) { + try { + return await utils.getData( + `${this.baseUrl}/apys?chainId=${chainId}&vault=${vaultAddress}` + ); + } catch (error) { + console.error( + `Failed to fetch APY for vault ${vaultAddress} on chain ${chainId}:`, + error.message + ); + return null; + } + } + + updatePoolWithApyData(pool, apyData) { + if (!apyData) return pool; + + const strategies = apyData.strategies || []; + + return { + ...pool, + apyBase: apyData.vaultNetWeightedApy * 100, + tvlUsd: strategies.reduce((acc, strategy) => + acc + (strategy.strategyTvlUsd || 0), 0 + ) + }; + } + + async getApy() { + try { + const poolPromises = Object.entries(VAULTS).flatMap(([chain, vaults]) => + Object.entries(vaults).map(async ([vaultAddress, vaultInfo]) => { + // Create initial pool object + const pool = this.createPoolObject(vaultAddress, chain, vaultInfo); + + // Fetch and update APY data + const chainId = CHAIN_IDS[chain]; + const apyData = await this.fetchVaultApy(chainId, vaultAddress); + + return this.updatePoolWithApyData(pool, apyData); + }) + ); + + const pools = await Promise.all(poolPromises); + return pools.filter(utils.keepFinite); + + } catch (error) { + console.error('Failed to fetch APY data:', error); + return []; + } + } +} + +module.exports = { + timetravel: false, + apy: () => new MaxApyAdapter().getApy(), + url: 'https://app.maxapy.io/vaults' +}; \ No newline at end of file diff --git a/src/adaptors/mdex/index.js b/src/adaptors/mdex/index.js new file mode 100644 index 0000000000..429b3f8f00 --- /dev/null +++ b/src/adaptors/mdex/index.js @@ -0,0 +1,71 @@ +const utils = require('../utils'); + +const STAKING_API = 'https://gateway.mdex.one/v3/boardroom/pools?mdex_chainid='; +const LP_API = 'https://gateway.mdex.one/v3/mingpool/lps?mdex_chainid='; + +const CHAINS = { + Binance: 56, + Heco: 128, +}; + +const apy = async () => { + const dataStaking = await Promise.all( + Object.entries(CHAINS).map(async ([chain, id]) => [ + chain, + (await utils.getData(STAKING_API + id)).result, + ]) + ); + const dataLp = await Promise.all( + Object.entries(CHAINS).map(async ([chain, id]) => [ + chain, + (await utils.getData(LP_API + id)).result, + ]) + ); + + const stakingPools = dataStaking.map(([chain, pools]) => { + return Object.entries(pools).map(([name, poolsArr]) => { + return poolsArr.map((pool) => { + const symbol = pool.pool_name.replace('/', '-'); + + return { + pool: `${pool.contract}-${chain}-${symbol}`, + chain, + project: 'mdex', + symbol, + tvlUsd: pool.pool_tvl, + apyReward: pool.pool_apy, + underlyingTokens: [pool.pool_token], + rewardTokens: [pool.earned_address], + }; + }); + }); + }); + + const lpPools = dataLp.map(([chain, pools]) => { + return Object.values(pools).map((pool) => { + if (!pool.token0) return; + const symbol = pool.pool_name.replace('/', '-'); + return { + pool: `${pool.address}-${chain}-${symbol}`, + chain, + project: 'mdex', + symbol, + tvlUsd: pool.pool_tvl, + apyBase: pool.swap_apy * 100, + apyReward: pool.pool_apy * 100, + underlyingTokens: [pool.token0, pool.token1], + rewardTokens: [ + '0x9c65ab58d8d978db963e63f2bfb7121627e3a739', // MDEX + ], + }; + }); + }); + + return lpPools.concat(stakingPools).flat(Infinity).filter(Boolean); +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://mdex.com/#/boardroom', +}; diff --git a/src/adaptors/mellow-yield/abi.js b/src/adaptors/mellow-yield/abi.js new file mode 100644 index 0000000000..b73083868b --- /dev/null +++ b/src/adaptors/mellow-yield/abi.js @@ -0,0 +1,5 @@ +module.exports = { + vaultRegistry:[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"contract IProtocolGovernance","name":"protocolGovernance_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"contract IProtocolGovernance","name":"newProtocolGovernance","type":"address"}],"name":"CommitedProtocolGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"contract IProtocolGovernance","name":"newProtocolGovernance","type":"address"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"}],"name":"StagedProtocolGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"nft","type":"uint256"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"nft","type":"uint256"},{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"VaultRegistered","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commitStagedProtocolGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractNameBytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractVersionBytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"lockNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"nftForVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolGovernance","outputs":[{"internalType":"contract IProtocolGovernance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"registerVault","outputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IProtocolGovernance","name":"newProtocolGovernance","type":"address"}],"name":"stageProtocolGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stagedProtocolGovernance","outputs":[{"internalType":"contract IProtocolGovernance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stagedProtocolGovernanceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"vaultForNft","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaults","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}], + farm:[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"rewardsDistribution","type":"address"},{"internalType":"address","name":"rewardsToken","type":"address"},{"internalType":"address","name":"stakingToken","type":"address"},{"internalType":"address","name":"admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"lpTokenMinted","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"ADMIN_DELEGATE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"strategy","type":"address"},{"internalType":"bool","name":"needToCallCallback","type":"bool"},{"internalType":"contract IFarmingPool","name":"farm","type":"address"}],"name":"addNewStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20RootVault","name":"vault","type":"address"},{"internalType":"uint256[]","name":"tokenAmounts","type":"uint256[]"},{"internalType":"uint256","name":"minLpTokens","type":"uint256"},{"internalType":"bytes","name":"vaultOptions","type":"bytes"}],"name":"depositAndStake","outputs":[{"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositInfo","outputs":[{"internalType":"address","name":"strategy","type":"address"},{"internalType":"bool","name":"needToCallCallback","type":"bool"},{"internalType":"contract IFarmingPool","name":"farm","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDistribution","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsDistribution","type":"address"}],"name":"setRewardsDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}], + rootVault:[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"lpTokenMinted","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"DepositCallbackLog","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address[]","name":"vaultTokens_","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"nft_","type":"uint256"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ManagementFeesCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PerformanceFeesCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProtocolFeesCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"lpTokenBurned","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"WithdrawCallbackLog","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"depositors","type":"address[]"}],"name":"addDepositorsToAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenAmounts","type":"uint256[]"},{"internalType":"uint256","name":"minLpTokens","type":"uint256"},{"internalType":"bytes","name":"vaultOptions","type":"bytes"}],"name":"deposit","outputs":[{"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositorsAllowlist","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft_","type":"uint256"}],"name":"hasSubvault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"helper","outputs":[{"internalType":"contract IERC20RootVaultHelper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft_","type":"uint256"},{"internalType":"address[]","name":"vaultTokens_","type":"address[]"},{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256[]","name":"subvaultNfts_","type":"uint256[]"},{"internalType":"contract IERC20RootVaultHelper","name":"helper_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isVaultToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFeeCharge","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebalanceFlagSet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpPriceHighWaterMarkD18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pullExistentials","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"depositors","type":"address[]"}],"name":"removeDepositorsFromAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setRebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"subvaultAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subvaultNfts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft_","type":"uint256"}],"name":"subvaultOneBasedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalWithdrawnAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWithdrawnAmountsTimestamp","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tvl","outputs":[{"internalType":"uint256[]","name":"minTokenAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxTokenAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultGovernance","outputs":[{"internalType":"contract IVaultGovernance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"lpTokenAmount","type":"uint256"},{"internalType":"uint256[]","name":"minTokenAmounts","type":"uint256[]"},{"internalType":"bytes[]","name":"vaultsOptions","type":"bytes[]"}],"name":"withdraw","outputs":[{"internalType":"uint256[]","name":"actualTokenAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}] +} \ No newline at end of file diff --git a/src/adaptors/mellow-yield/index.js b/src/adaptors/mellow-yield/index.js new file mode 100644 index 0000000000..8f7bf68dde --- /dev/null +++ b/src/adaptors/mellow-yield/index.js @@ -0,0 +1,335 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils'); + +const { vaultRegistry, rootVault, farm } = require('./abi'); + +const config = { + ethereum: { + registry: '0xfd23f971696576331fcf96f80a20b4d3b31ca5b2', + fromBlock: 15237714, + name: 'ethereum' + }, + polygon: { + registry: '0xd3d0e85f225348a2006270daf624d8c46cae4e1f', + fromBlock: 31243728, + name: 'polygon' + } +} + +const getPrices = async (addresses, timestamp) => { + + let request = 'https://coins.llama.fi/prices/historical/' + timestamp + '/'; + addresses.forEach(address => { + request = request + address + ',' + }); + + const prices = ( + await axios.get(request.substr(0, request.length - 1))).data.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const getTvl = async(tvl, tokens, prices, decimals) => { + if (tvl === null) { + return 0; + } + const minTvl = tvl[0]; + let result = 0; + + for (let i = 0; i < tokens.length; ++i) { + result += minTvl[i] * prices[String(tokens[i])] / 10**decimals[tokens[i]]; + } + + return result; + +} + +const transformLink = (link) => { + + let i = 0; + while (link[i] != 'v' || link[i + 1] != '2' || link[i + 2] != '/') { + i += 1; + } + + return link.substr(i + 3, link.length); + +} + +const poolsFunction = async () => { + + const abiA = ["event TokenLocked(address indexed origin, address indexed sender, uint256 indexed nft)"]; + const abiB = ["event VaultRegistered(address indexed origin, address indexed sender, uint256 indexed nft, address vault, address owner)"]; + + const rewardMap = {}; + rewardMap['0x13c7bCc2126d6892eEFd489Ad215A1a09F36AA9f'] = '0xbfafc964361f78754f523343b09b3cb7bb73bdd6'; + rewardMap['0x6A2Dd3B817F0364e7603e781dDA9c62f62c440E1'] = '0x0fd566cda6d6a3ae1760e1eebd22ee400cc79655'; + rewardMap['0x8E024f875f6fDdf1471582bed8504F46CB64487E'] = '0x6955ab1adefa2e48f449b88183a2774a186b7e61'; + + const ldo = '0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32'; + + let pools = []; + + for (let chain in config) { + + const registry = config[chain].registry; + const name = config[chain].name; + + let provider = new ethers.providers.AlchemyProvider( + name == 'ethereum' ? 'homestead' : 'matic', + transformLink(process.env.ALCHEMY_CONNECTION_ETHEREUM) + ); + + let contract = new ethers.Contract(registry, abiB, provider); + const registered = await contract.queryFilter(contract.filters.VaultRegistered(), config[chain].fromBlock); + + const vaultKeys = {}; + const blockKeys = {}; + + registered.forEach(i => vaultKeys[i.args.nft] = i.args.vault); + registered.forEach(i => blockKeys[i.args.vault] = i.blockNumber); + + contract = new ethers.Contract(registry, abiA, provider); + const locked = await contract.queryFilter(contract.filters.TokenLocked(), config[chain].fromBlock); + locked.forEach(i => delete vaultKeys[i.args.nft]); + + const vaults = Object.values(vaultKeys); + const allTokens = new Set(); + + calls = []; + vaults.forEach(element => { + calls.push({target: element, params: []}); + }) + + const tokens = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'vaultTokens'), + chain: name, + permitFailure: true + }); + + tokens.output.forEach(tokensI => { + tokensI.output.forEach(token => { + allTokens.add(token); + }) + }); + + allTokens.add(ldo); + + const allTokensArr = []; + Array.from(allTokens.values()).forEach(element => { + allTokensArr.push(name + ':' + element); + }) + + const currentTimestamp = (await provider.getBlock(await provider.getBlockNumber())).timestamp; + + const prices = await getPrices(allTokensArr, currentTimestamp); + + const decimals = await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: Array.from(allTokens.values()).map((token) => ({ target: token })), + chain: name, + permitFailure: true + }); + + const symbols = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: Array.from(allTokens.values()).map((token) => ({ target: token })), + chain: name, + permitFailure: true + }); + + const tvls = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'tvl'), + chain: name, + permitFailure: true + }); + + const supplys = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'totalSupply'), + chain: name, + permitFailure: true + }); + + let decimalsKTV = {}; + for (let i = 0; i < Array.from(allTokens.values()).length; ++i) { + decimalsKTV[Array.from(allTokens.values())[i]] = decimals.output[i].output; + } + + let symbolKTV = {}; + for (let i = 0; i < Array.from(allTokens.values()).length; ++i) { + symbolKTV[Array.from(allTokens.values())[i]] = symbols.output[i].output; + } + + for (let i = 0; i < tokens.output.length; ++i) { + + const tokensI = tokens.output[i].output; + + let tvlUsd = await getTvl(tvls.output[i].output, tokensI, prices, decimalsKTV); + if (tvlUsd < 10000) { + continue; + } + + let symbol; + if (tokensI.length == 1) { + symbol = symbolKTV[tokensI[0]]; + } + + else { + symbol = symbolKTV[tokensI[0]] + '-' + symbolKTV[tokensI[1]]; + } + + const blockStart = blockKeys[vaults[i]] + 50000; + const timestampStart = (await provider.getBlock(blockStart)).timestamp; + + calls = []; + calls.push({target: vaults[i], params: []}); + + let oldTvls = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'tvl'), + chain: name, + block: blockStart, + permitFailure: true + }); + + let oldSupply = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'totalSupply'), + chain: name, + block: blockStart, + permitFailure: true + }); + + while (!oldTvls.output[0].success) { + oldTvls = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'tvl'), + chain: name, + block: blockStart, + permitFailure: true + }); + } + + while (!oldSupply.output[0].success) { + oldSupply = await sdk.api.abi.multiCall({ + calls: calls, + abi: rootVault.find(({ name }) => name === 'totalSupply'), + chain: name, + block: blockStart, + permitFailure: true + }); + } + + const timePassedShareYear = (currentTimestamp - timestampStart) / (86400 * 365); + + const lpPriceUsdDoNothing = await getTvl(oldTvls.output[0].output, tokensI, prices, decimalsKTV) / oldSupply.output[0].output; + const lpPriceNow = tvlUsd / supplys.output[i].output; + + const apy = 100 * (((1 + (lpPriceNow - lpPriceUsdDoNothing) / lpPriceUsdDoNothing) ** (1 / timePassedShareYear)) - 1); + + let rewardApy = 0; + let rewardToken; + + if (vaults[i] in rewardMap) { + + const farmAddress = rewardMap[vaults[i]]; + + calls = []; + calls.push({target: farmAddress, params: []}); + + const finish = await sdk.api.abi.multiCall({ + calls: calls, + abi: farm.find(({ name }) => name === 'periodFinish'), + chain: name, + permitFailure: true + }); + + if (finish.output[0].output > currentTimestamp) { + + const currentReward = await sdk.api.abi.multiCall({ + calls: calls, + abi: farm.find(({ name }) => name === 'getRewardForDuration'), + chain: name, + permitFailure: true + }); + + const currentDuration = await sdk.api.abi.multiCall({ + calls: calls, + abi: farm.find(({ name }) => name === 'rewardsDuration'), + chain: name, + permitFailure: true + }); + + rewardToken = await sdk.api.abi.multiCall({ + calls: calls, + abi: farm.find(({ name }) => name === 'rewardsToken'), + chain: name, + permitFailure: true + }); + + rewardToken = rewardToken.output[0].output + + const yearlyRewardUsd = (currentReward.output[0].output * (86400 * 365) / currentDuration.output[0].output) * prices[String(rewardToken)] / 10**decimalsKTV[rewardToken]; + rewardApy = 100 * yearlyRewardUsd / tvlUsd; + } + + } + + if (rewardApy == 0) { + + const pool = { + pool: vaults[i], + chain: utils.formatChain(name), + project: 'mellow-yield', + tvlUsd: tvlUsd, + symbol: symbol, + apy: apy, + underlyingTokens: tokens.output[i].output, + }; + + pools.push(pool); + + } + + else { + const pool = { + pool: vaults[i], + chain: utils.formatChain(name), + project: 'mellow-yield', + tvlUsd: tvlUsd, + symbol: symbol, + apyBase: apy, + apyReward: rewardApy, + apy: apy + rewardApy, + rewardTokens: [rewardToken], + underlyingTokens: tokens.output[i].output, + }; + + pools.push(pool); + } + + } + + } + + return pools; + +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.mellow.finance/products', +}; diff --git a/src/adaptors/meme-dollar/abi.json b/src/adaptors/meme-dollar/abi.json new file mode 100644 index 0000000000..b1e59c3b4e --- /dev/null +++ b/src/adaptors/meme-dollar/abi.json @@ -0,0 +1,338 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochsPerDay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxExpansionRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minExpansionRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_expansionRateDivisor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_forgeRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pinausdcRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pinamemeRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_memeethRatio", + "type": "uint256" + } + ], + "name": "setParam", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "getAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getForgeAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getForgeEpochYield", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getForgeTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMEMEETHAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMEMEETHEpochYield", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMemeETHTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOraclePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getParam", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaMEMEAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaMEMEEpochYield", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaMemeTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaUSDCAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaUSDCEpochYield", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPinaUSDCTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pinaExpansionPerEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/meme-dollar/index.js b/src/adaptors/meme-dollar/index.js new file mode 100644 index 0000000000..afbfc2741d --- /dev/null +++ b/src/adaptors/meme-dollar/index.js @@ -0,0 +1,103 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abi.json'); +const BN = require('bignumber.js'); + +const apyhelper = '0xCf059594aE3FF11Bee9d3F3b3506d7Db73da48ff'; + +const poolInfo = async (chain) => { + const getAPR = await sdk.api.abi.multiCall({ + calls: [ + { + target: apyhelper, + }, + ], + abi: abi.find(({ name }) => name === 'getAPR'), + chain: chain, + }); + return getAPR.output; +}; + +const usdctvlInfo = async (chain) => { + const getAPR = await sdk.api.abi.multiCall({ + calls: [ + { + target: apyhelper, + }, + ], + abi: abi.find(({ name }) => name === 'getPinaUSDCTVL'), + chain: chain, + }); + return getAPR.output; +}; + +const usdcAPRInfo = async (chain) => { + const getAPR = await sdk.api.abi.multiCall({ + calls: [ + { + target: apyhelper, + }, + ], + abi: abi.find(({ name }) => name === 'getPinaUSDCAPR'), + chain: chain, + }); + return getAPR.output; +}; + +const poolsFunction = async () => { + const chain = 'Ethereum'; + const pool = await poolInfo(chain.toLowerCase()); + const usdctvl = await usdctvlInfo(chain.toLowerCase()); + const usdcapr = await usdcAPRInfo(chain.toLowerCase()); + + const forge = { + pool: '0x02814F435dD04e254Be7ae69F61FCa19881a780D-ethereum', + chain: chain, + project: 'meme-dollar', + symbol: utils.formatSymbol('PINA'), + tvlUsd: Number(BN(pool[0].output[2]).div(1e18).toString()), + apy: Number(BN(pool[0].output[1]).div(1e6).toString()), + rewardTokens: ['0x02814F435dD04e254Be7ae69F61FCa19881a780D'], + poolMeta: '5day lockup', + }; + + const pina_usdc = { + pool: '0x58624E7a53700cb39772E0267ca0AC70f064078B-ethereum', + chain: chain, + project: 'meme-dollar', + symbol: utils.formatSymbol('PINA-USDC'), + tvlUsd: Number(BN(usdctvl[0].output).div(1e18).toString()), + apy: Number(BN(usdcapr[0].output).div(1e6).toString()), + rewardTokens: ['0x02814F435dD04e254Be7ae69F61FCa19881a780D'], + poolMeta: '3day lockup', + }; + + const pina_meme = { + pool: '0x713afA49478f1A33c3194Ff65dbf3c8058406670-ethereum', + chain: chain, + project: 'meme-dollar', + symbol: utils.formatSymbol('PINA-MEME'), + tvlUsd: Number(BN(pool[0].output[5]).div(1e18).toString()), + apy: Number(BN(pool[0].output[4]).div(1e6).toString()), + rewardTokens: ['0x02814F435dD04e254Be7ae69F61FCa19881a780D'], + poolMeta: '3day lockup', + }; + + const meme_eth = { + pool: '0xb892A4b35F227F27e4B58cc20691B3C671D0beC8-ethereum', + chain: chain, + project: 'meme-dollar', + symbol: utils.formatSymbol('MEME-ETH'), + tvlUsd: Number(BN(pool[0].output[8]).div(1e18).toString()), + apy: Number(BN(pool[0].output[7]).div(1e6).toString()), + rewardTokens: ['0x02814F435dD04e254Be7ae69F61FCa19881a780D'], + poolMeta: '3day lockup', + }; + return [forge, pina_usdc, pina_meme, meme_eth]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://www.dontdiememe.com/pina', +}; diff --git a/src/adaptors/mendi-finance/comptrollerAbi.json b/src/adaptors/mendi-finance/comptrollerAbi.json new file mode 100644 index 0000000000..080f5a61b4 --- /dev/null +++ b/src/adaptors/mendi-finance/comptrollerAbi.json @@ -0,0 +1,1066 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldRewardDistributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newRewardDistributor", + "type": "address" + } + ], + "name": "NewRewardDistributor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSupplyCap", + "type": "uint256" + } + ], + "name": "NewSupplyCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldSupplyCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newSupplyCapGuardian", + "type": "address" + } + ], + "name": "NewSupplyCapGuardian", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { "internalType": "bool", "name": "state", "type": "bool" } + ], + "name": "_setBorrowPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newSupplyCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketSupplyCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { "internalType": "bool", "name": "state", "type": "bool" } + ], + "name": "_setMintPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardDistributor", + "type": "address" + } + ], + "name": "_setRewardDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], + "name": "_setSeizePaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newSupplyCapGuardian", + "type": "address" + } + ], + "name": "_setSupplyCapGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], + "name": "_setTransferPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract CToken", "name": "cToken", "type": "address" } + ], + "name": "_supportMarket", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "accountAssets", + "outputs": [ + { "internalType": "contract CToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allMarkets", + "outputs": [ + { "internalType": "contract CToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "borrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowCaps", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "borrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "contract CToken", "name": "cToken", "type": "address" } + ], + "name": "checkMembership", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "holder", "type": "address" }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "holders", "type": "address[]" }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { "internalType": "bool", "name": "borrowers", "type": "bool" }, + { "internalType": "bool", "name": "suppliers", "type": "bool" } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "holder", "type": "address" } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "cTokens", "type": "address[]" } + ], + "name": "enterMarkets", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cTokenAddress", "type": "address" } + ], + "name": "exitMarket", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { "internalType": "contract CToken[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getAssetsIn", + "outputs": [ + { "internalType": "contract CToken[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "cTokenModify", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract CToken", "name": "cToken", "type": "address" } + ], + "name": "isDeprecated", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "liquidateBorrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { "internalType": "bool", "name": "isListed", "type": "bool" }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { "internalType": "bool", "name": "isComped", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "mintAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "mintGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "mintTokens", "type": "uint256" } + ], + "name": "mintVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { "internalType": "contract PriceOracle", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "redeemAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "redeemVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "repayBorrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "borrowerIndex", "type": "uint256" } + ], + "name": "repayBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardDistributor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seizeAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seizeVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supplyCapGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyCaps", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "transferTokens", "type": "uint256" } + ], + "name": "transferAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "transferTokens", "type": "uint256" } + ], + "name": "transferVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/mendi-finance/index.js b/src/adaptors/mendi-finance/index.js new file mode 100644 index 0000000000..ac4a1fcffd --- /dev/null +++ b/src/adaptors/mendi-finance/index.js @@ -0,0 +1,254 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { ercDelegator } = require('../compound-v2/abi'); +const comptrollerAbi = require('./comptrollerAbi.json'); +const rewardDistributorAbi = require('./rewardDistributorAbi.json'); + +const COMPTROLLER_ADDRESS = '0x1b4d3b0421dDc1eB216D230Bc01527422Fb93103'; +const REWARD_DISTRIBUTOR = '0x3b9B9364Bf69761d308145371c38D9b558013d40'; +const MENDI = '0x43e8809ea748eff3204ee01f08872f063e44065f'; +const CHAIN = 'linea'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400; +const PROJECT_NAME = 'mendi-finance'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'MENDI', + address: MENDI.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const rewardMarketState = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: rewardDistributorAbi.find((n) => n.name === 'rewardMarketState'), + calls: allMarkets.map((m) => ({ + target: REWARD_DISTRIBUTOR, + params: [MENDI, m], + })), + }) + ).output.map((o) => o.output); + + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address, MENDI]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards / 1e18) * 86400 * 365 * prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + + const apyReward = calcRewardApy( + rewardMarketState[i].supplySpeed, + totalSupplyUsd + ); + const apyRewardBorrow = calcRewardApy( + rewardMarketState[i].borrowSpeed, + totalBorrowUsd + ); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + debtCeilingUsd: (borrowCaps[i] / 1e18) * price, + }; + } + return poolReturned; + }); + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://mendi.finance', +}; diff --git a/src/adaptors/mendi-finance/rewardDistributorAbi.json b/src/adaptors/mendi-finance/rewardDistributorAbi.json new file mode 100644 index 0000000000..8f4474e704 --- /dev/null +++ b/src/adaptors/mendi-finance/rewardDistributorAbi.json @@ -0,0 +1,332 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowSpeed", + "type": "uint256" + } + ], + "name": "BorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "deltaAccrued", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAccrued", + "type": "uint256" + } + ], + "name": "RewardAccrued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supplySpeed", + "type": "uint256" + } + ], + "name": "SupplySpeedUpdated", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "_grantReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "rewardToken_", "type": "address" }, + { "internalType": "address[]", "name": "cTokens", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "_updateRewardSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "rewardToken_", "type": "address" } + ], + "name": "_whitelistToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "holders", "type": "address[]" } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardTokens", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "comptroller_", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" } + ], + "name": "notifyBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "notifyBorrower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" }, + { "internalType": "address", "name": "supplier", "type": "address" } + ], + "name": "notifySupplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "cToken", "type": "address" } + ], + "name": "notifySupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "rewardAccountState", + "outputs": [ + { "internalType": "uint256", "name": "rewardAccrued", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardInitialIndex", + "outputs": [{ "internalType": "uint224", "name": "", "type": "uint224" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "rewardMarketState", + "outputs": [ + { "internalType": "uint256", "name": "supplySpeed", "type": "uint256" }, + { "internalType": "uint224", "name": "supplyIndex", "type": "uint224" }, + { "internalType": "uint32", "name": "supplyBlock", "type": "uint32" }, + { "internalType": "uint256", "name": "borrowSpeed", "type": "uint256" }, + { "internalType": "uint224", "name": "borrowIndex", "type": "uint224" }, + { "internalType": "uint32", "name": "borrowBlock", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardTokenExists", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/meridian-amm/index.js b/src/adaptors/meridian-amm/index.js new file mode 100644 index 0000000000..dea03e4106 --- /dev/null +++ b/src/adaptors/meridian-amm/index.js @@ -0,0 +1,69 @@ +const utils = require('../utils'); + +const meridianAddress = + '0xfbdb3da73efcfa742d542f152d65fc6da7b55dee864cd66475213e4be18c9d54'; +const MERIDIAN_DAPP_URL = 'https://app.meridian.money'; +const MERIDIAN_POOL_API_URL = `${MERIDIAN_DAPP_URL}/api/liquidity-pool`; +const MERIDIAN_COIN_INFO_URL = `${MERIDIAN_DAPP_URL}/api/coin-info`; + +const coinInfoCache = {}; + +async function main() { + // We use Meridian's API and not resources on chain as there are too many pools to parse and query + // for TVL, APR, etc. metrics. This way we fetch all our pools with TVL attached, then can filter. + const liquidityPools = (await utils.getData(`${MERIDIAN_POOL_API_URL}s`)) + ?.data; + if (!liquidityPools) { + return []; + } + const filteredPools = liquidityPools.filter((pool) => pool.tvl > 10000); + const v2Pools = filteredPools.filter((pool) => pool.metadata.isV2 === true); + + const tvlArr = []; + for (const liquidityPool of v2Pools) { + const swapFeesApr = liquidityPool.apr.find(item => item.source === 'Swap Fees')?.apr; + const farmingMOVEApr = liquidityPool.apr.find(item => item.source === 'MOVE')?.apr; + const rewardTokens = []; + + // Check and push for MOVE + if (farmingMOVEApr > 0) { + rewardTokens.push('0x1::aptos_coin::AptosCoin'); + } + + const coinInfos = await Promise.all(liquidityPool.metadata.coinAddresses.map(async (address) => await getCoinInfoWithCache(address))); + const coinNames = coinInfos.map((coinInfo) => coinInfo.symbol).join('-'); + tvlArr.push({ + pool: + liquidityPool.metadata.type + '-move', + chain: utils.formatChain('move'), + project: 'meridian-amm', + apyBase: (swapFeesApr ?? 0) * 100, + apyReward: (farmingMOVEApr ?? 0) * 100, + rewardTokens, + symbol: coinNames, + tvlUsd: liquidityPool.tvl, + volumeUsd1d: +liquidityPool.volume1d, + underlyingTokens: liquidityPool.metadata.coinAddresses, + url: `${MERIDIAN_DAPP_URL}/pools/${liquidityPool.metadata.type}`, + }); + } + + return tvlArr; +} + +async function getCoinInfoWithCache(coinAddress) { + if (coinInfoCache[coinAddress]) { + return coinInfoCache[coinAddress]; + } + + const coinInfo = await utils.getData(`${MERIDIAN_COIN_INFO_URL}?coin=${coinAddress}`); + coinInfoCache[coinAddress] = coinInfo?.data; + + return coinInfo?.data; +} + +module.exports = { + timetravel: false, + apy: main, + url: `${MERIDIAN_DAPP_URL}/pools`, +}; diff --git a/src/adaptors/merkl/config.js b/src/adaptors/merkl/config.js new file mode 100644 index 0000000000..6b1e908f1c --- /dev/null +++ b/src/adaptors/merkl/config.js @@ -0,0 +1,14 @@ +exports.networks = { + 1: 'ethereum', + 137: 'polygon', + 10: 'optimism', + 42161: 'arbitrum', + 1101: 'polygon_zkevm', + 8453: 'base', + 60808: 'bob', + 146: 'sonic', + 43114: 'avax', + 80094: 'berachain', + 56: 'bsc', + 42220: 'celo', +}; diff --git a/src/adaptors/merkl/index.js b/src/adaptors/merkl/index.js new file mode 100644 index 0000000000..683f6a3a39 --- /dev/null +++ b/src/adaptors/merkl/index.js @@ -0,0 +1,116 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { networks } = require('./config'); + +// Protocols that should not be listed under Merkl +// as they already have their own adapters. +const protocolsBlacklist = [ + 'euler', + 'crosscurve', + 'aerodrome', + 'gamma', + 'uniswap', +]; + +// Allow specific pools from blacklisted protocols +const poolsWhitelist = [ + // Pool from Aerodrome CL: xPufETH-WETH + '0xCDf927C0F7b81b146C0C9e9323eb5A28D1BFA183', +]; + +async function getRateAngle(token) { + const prices = await utils.getData('https://api.angle.money/v1/prices/'); + const price = prices.filter((p) => p.token == token)[0]?.rate; + return price; +} + +// function getting all the data from the Angle API +const main = async () => { + var poolsData = []; + + const project = 'merkl'; + + for (const chainId of Object.keys(networks)) { + const chain = networks[chainId]; + + let pools = []; + let pageI = 0; + + while (true) { + let data; + try { + data = await utils.getData( + `https://api.merkl.xyz/v4/opportunities?chainId=${chainId}&status=LIVE,PAST&items=100&page=${pageI}` + ); + } catch (err) { + console.log('failed to fetch Merkl data on chain ' + chain); + break; + } + + if (data.length === 0) { + break; + } + + pools.push(...data); + pageI++; + } + + for (const pool of pools.filter( + (x) => + !x.protocol || + !protocolsBlacklist.includes(x.protocol.id) || + poolsWhitelist.includes(x.identifier) + )) { + try { + const poolAddress = pool.identifier; + + let symbol = pool.tokens.map((x) => x.symbol).join('-'); + + if (!symbol.length) { + symbol = ( + await sdk.api.abi.call({ + target: pool.depositUrl.split('/').slice(-1)[0], + chain, + abi: 'erc20:symbol', + }) + ).output; + } + + const underlyingTokens = pool.tokens.map((x) => x.address); + + const tvlUsd = pool.tvl; + + const rewardTokens = + pool.rewardsRecord?.breakdowns.map((x) => x.token.address) || []; + const apyReward = pool.apr; + + const poolData = { + pool: `${poolAddress}-merkl`, + chain: chain, + project: project, + poolMeta: pool.status === 'PAST' ? 'past' : undefined, + symbol: symbol, + tvlUsd: tvlUsd ?? 0, + apyReward: apyReward ?? 0, + rewardTokens: [...new Set(rewardTokens)], + underlyingTokens: underlyingTokens, + }; + poolsData.push(poolData); + } catch {} + } + } + return utils.removeDuplicates(poolsData.filter((p) => utils.keepFinite(p))); +}; + +/* +main().then((data) => { + console.log(data); +}); +*/ + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.merkl.xyz/', +}; diff --git a/src/adaptors/merkl/merkl-additional-reward.js b/src/adaptors/merkl/merkl-additional-reward.js new file mode 100644 index 0000000000..a9e8f07b44 --- /dev/null +++ b/src/adaptors/merkl/merkl-additional-reward.js @@ -0,0 +1,68 @@ +const { networks } = require('./config'); +const { getData } = require('../utils'); + +exports.addMerklRewardApy = async ( + pools, + protocolId, + poolAddressGetter, +) => { + try { + let merklPools = []; + let pageI = 0; + + while(true) { + let data; + try { + data = await getData(`https://api.merkl.xyz/v4/opportunities?mainProtocolId=${protocolId}&status=LIVE&items=100&page=${pageI}`); + } catch (err) { + console.log(`failed to fetch Merkl data for ${protocolId}: ${err}`); + break; + } + + if (data.length === 0) { + break; + } + + merklPools.push(...data); + pageI++; + } + + + const merklPoolsMap = Object.fromEntries(Object.keys(networks).map(id => [networks[id], {}])); + merklPools.forEach(pool => { + if (!networks[pool.chainId]) { + return; + } + + merklPoolsMap[networks[pool.chainId]][pool.identifier.toLowerCase()] = { + apyReward: pool.apr, + rewardTokens: [...new Set(pool.rewardsRecord?.breakdowns.map(x => x.token.address) || [])] + } + }); + + return pools.map(pool => { + const poolAddress = poolAddressGetter ? poolAddressGetter(pool) : pool.pool; + const merklRewards = merklPoolsMap[pool.chain.toLowerCase()]?.[poolAddress.toLowerCase()]; + + if (!merklRewards) { + return pool; + } + + // if the data is already present, don't overwrite it + if (pool.apyReward || (pool.rewardTokens && pool.rewardTokens.length !== 0)) { + console.log('pool already has apyReward or rewardTokens', pool.pool); + return pool; + } + + return { + ...pool, + ...merklRewards, + } + }); + } catch (err) { + console.log(`Failed to add Merkl reward apy to ${protocolId}: ${err}`); + + // If we fail to fetch Merkl data, just return the original pools + return pools; + } +}; \ No newline at end of file diff --git a/src/adaptors/merkle-trade/index.js b/src/adaptors/merkle-trade/index.js new file mode 100644 index 0000000000..f3327af0dc --- /dev/null +++ b/src/adaptors/merkle-trade/index.js @@ -0,0 +1,28 @@ +const utils = require('../utils'); + +const MERKLE_RESOURCE_ACCOUNT = + '0x5ae6789dd2fec1a9ec9cccfb3acaf12e93d432f0a3a42c92fe1a9d490b7bbc06'; + +async function main() { + const result = await utils.getData( + `https://api.prod.merkle.trade/v1/mklp/stats?p=30d` + ); + const tvl = result.usdcBalance; + const apr30d = result.apr; + return [ + { + pool: `${MERKLE_RESOURCE_ACCOUNT}-merkle-trade-mklp`, + chain: utils.formatChain('aptos'), + project: 'merkle-trade', + symbol: utils.formatSymbol('zusdc'), + tvlUsd: tvl, + apyBase: apr30d, + }, + ]; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://merkle.trade', +}; diff --git a/src/adaptors/mero/index.ts b/src/adaptors/mero/index.ts new file mode 100644 index 0000000000..699f19e26c --- /dev/null +++ b/src/adaptors/mero/index.ts @@ -0,0 +1,89 @@ +const utils = require('../utils'); +const superagent = require('superagent'); +const fetch = require('node-fetch'); + +const ENDPOINT = 'https://mero.finance/api/apys'; + +interface MeroPool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; +} + +interface PoolMetadata { + symbol: string; + underlying: string; +} + +interface Apy { + pool: string; + apy: number; + tvl: number; +} + +const poolMetadata: Record = { + '0x4b45ADDfFa952bC7A81ffB73694287643915B050': { + symbol: 'DAI', + underlying: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }, + '0x19C674f7679c33f5c0248D9F736b2726447c41cF': { + symbol: 'ETH', + underlying: '0x0000000000000000000000000000000000000000', + }, + '0xEf251Ac05D180a0ffBcE8AE0FC65f175a09ae02f': { + symbol: 'USDC', + underlying: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + }, + '0x90272940265f21D57A8F9317A8d04a624F063903': { + symbol: 'USDT', + underlying: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + }, + '0x9492a8E34126eC4a8494bA77ec197d6De131d660': { + symbol: 'FRAX', + underlying: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + }, +}; + +const getMeroApys = async (): Promise => { + return (await fetch(ENDPOINT)).json(); +}; + +const getEthPriceUsd = async (): Promise => { + const key = 'ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + return (await superagent.get(`https://coins.llama.fi/prices/current/${key}`)) + .body.coins[key].price; +}; + +const getPools = async (): Promise => { + const [apys, ethPriceUsd] = await Promise.all([ + getMeroApys(), + getEthPriceUsd(), + ]); + + return apys.map((apy: Apy) => { + const metadata = poolMetadata[apy.pool]; + return { + pool: apy.pool, + chain: 'Ethereum', + project: 'mero', + symbol: metadata.symbol, + tvlUsd: metadata.symbol === 'ETH' ? apy.tvl * ethPriceUsd : apy.tvl, + apyBase: apy.apy, + apyReward: 0, + underlyingTokens: [metadata.underlying], + rewardTokens: [], + url: `https://mero.finance/pool/mero${metadata.symbol}`, + }; + }); +}; + +module.exports = { + timetravel: false, + apy: getPools, +}; diff --git a/src/adaptors/meshswap/index.ts b/src/adaptors/meshswap/index.ts new file mode 100644 index 0000000000..3203fbae07 --- /dev/null +++ b/src/adaptors/meshswap/index.ts @@ -0,0 +1,94 @@ +const utils = require('../utils'); + +const API_URL: string = 'https://s.meshswap.fi/stat/recentPoolInfo.min.json'; +const TOKENS_URL = 'https://s.meshswap.fi/stat/tokenInfo.min.json'; +const LENDING_URL = 'https://s.meshswap.fi/stat/leverage.min.json'; + +const MESH_TOKEN = '0x82362Ec182Db3Cf7829014Bc61E9BE8a2E82868a'; + +const csvLikeToObjArr = (csv: Array): Array => { + const headers = csv[0]; + + return csv + .slice(1) + .map((row) => + row.reduce((acc, val, i) => ({ ...acc, [headers[i]]: val }), {}) + ); +}; + +interface Pool { + exchange_address: string; + poolVolume: string; + totalRewardRate: string; + feeRewardRate: string; + token0: string; + token1: string; +} + +interface Token { + address: string; + symbol: string; +} +interface Lending { + address: string; + tokenSymbol: string; + totalDepositVol: string; + totalRewardRate: string; + supplyRate: string; + token: string; +} + +const getApy = async () => { + const { recentPool: farmsRes } = await utils.getData(API_URL); + const tokensRes = await utils.getData(TOKENS_URL); + const { + leveragePool: { single: lendingRes }, + } = await utils.getData(LENDING_URL); + + const farms = csvLikeToObjArr(farmsRes); + const tokens = csvLikeToObjArr(tokensRes); + const lending = csvLikeToObjArr(lendingRes); + tokens; + + const lendingPools = lending.map((market) => { + return { + pool: market.address, + chain: utils.formatChain('polygon'), + project: 'meshswap', + symbol: market.tokenSymbol, + tvlUsd: Number(market.totalDepositVol), + apyBase: Number(market.supplyRate), + apyReward: Number(market.totalRewardRate) - Number(market.supplyRate), + underlyingTokens: [market.token], + rewardTokens: [MESH_TOKEN, market.token], + }; + }); + + const pools = farms.map((farm) => { + const token0 = tokens.find((token) => token.address === farm.token0); + const token1 = tokens.find((token) => token.address === farm.token1); + + return { + pool: farm.exchange_address, + chain: utils.formatChain('polygon'), + project: 'meshswap', + symbol: `${token0.symbol}-${token1.symbol}`, + tvlUsd: Number(farm.poolVolume), + apyReward: Number(farm.totalRewardRate) - Number(farm.feeRewardRate), + apyBase: Number(farm.feeRewardRate), + underlyingTokens: [farm.token0, farm.token1], + rewardTokens: [MESH_TOKEN], + url: `https://meshswap.fi/exchange/pool/detail/${farm.exchange_address}`, + }; + }); + + const res = [...pools, ...lendingPools]; + + return res; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://meshswap.fi/exchange/pool', +}; diff --git a/src/adaptors/meso-finance/index.js b/src/adaptors/meso-finance/index.js new file mode 100644 index 0000000000..0831e36815 --- /dev/null +++ b/src/adaptors/meso-finance/index.js @@ -0,0 +1,107 @@ +const { ContractMissingABIError } = require('web3'); +const utils = require('../utils'); + +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; + +const COINS = [ + ['APT', 'coingecko:aptos', 8, '0x1::aptos_coin::AptosCoin'], + [ + 'amAPT', + 'coingecko:amnis-aptos', + 8, + '0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a::amapt_token::AmnisApt', + ], + [ + 'stAPT', + 'coingecko:amnis-staked-aptos-coin', + 8, + '0x111ae3e5bc816a5e63c2da97d0aa3886519e0cd5e4b046659fa35796bd11542a::stapt_token::StakedApt', + ], + [ + 'zUSDC', + 'coingecko:usd-coin', + 6, + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC', + ], + [ + 'zUSDT', + 'coingecko:tether', + 6, + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT', + ], + [ + 'wUSDC', + 'coingecko:usd-coin', + 6, + '0x5e156f1207d0ebfa19a9eeff00d62a282278fb8719f4fab3a586a0a2c0fffbea::coin::T', + ], + [ + 'WBTC', + 'coingecko:bitcoin', + 6, + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WBTC', + ], + [ + 'zWETH', + 'coingecko:ethereum', + 6, + '0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WETH', + ], + [ + 'CELL', + 'coingecko:cellana-finance', + 8, + '0x2ebb2ccac5e027a87fa0e2e5f656a3a4238d6a48d93ec9b610d570fc0aa0df12', + ], +]; + +async function main() { + const pools = ( + await utils.getData( + `https://api.meso.finance/api/v1/pool?page=1&limit=1000` + ) + ).datas; + const map = new Map(pools.map((pool) => [pool.tokenAddress, pool])); + return await Promise.all( + COINS.map(async (coin) => { + const [coinSymbol, priceId, coinDecimal, coinAddr] = coin; + const pool = map.get(coinAddr); + + const priceRes = await utils.getData( + `${COINS_LLAMA_PRICE_URL}${priceId}` + ); + let coinPrice = priceRes['coins']?.[priceId]?.['price']; + if (!coinPrice) { + const aptosPriceRes = await utils.getData( + `${COINS_LLAMA_PRICE_URL}aptos:${coinAddr}` + ); + coinPrice = aptosPriceRes['coins'][`aptos:${coinAddr}`]?.price; + } + + const res = { + pool: `meso-finance-${coinSymbol}`, + chain: utils.formatChain('aptos'), + project: 'meso-finance', + symbol: utils.formatSymbol(coinSymbol), + tvlUsd: + ((pool.poolSupply - pool.totalDebt) * coinPrice) / + 10 ** pool['token']['decimals'], + apyBase: pool.supplyApy + pool.stakingApr, + }; + + if (pool.incentiveSupplyApy > 0) { + res['apyReward'] = pool.incentiveSupplyApy; + res['rewardTokens'] = ['0x1::aptos_coin::AptosCoin']; + } + + return res; + }) + ); +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.meso.finance/', +}; diff --git a/src/adaptors/meta-pool-eth/abi.json b/src/adaptors/meta-pool-eth/abi.json new file mode 100644 index 0000000000..abbd816607 --- /dev/null +++ b/src/adaptors/meta-pool-eth/abi.json @@ -0,0 +1,1139 @@ +[ + { + "inputs": [ + { + "internalType": "uint16", + "name": "_acceptableUnderlyingChangeSent", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_maxAcceptableUnderlyingChange", + "type": "uint16" + } + ], + "name": "AcceptableUnderlyingChangeTooBig", + "type": "error" + }, + { "inputs": [], "name": "DepositRootMismatch", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "_minAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_amountSent", "type": "uint256" } + ], + "name": "DepositTooLow", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_sentFee", "type": "uint16" }, + { "internalType": "uint16", "name": "_maxFee", "type": "uint16" } + ], + "name": "FeeSentTooBig", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint64", "name": "_from", "type": "uint64" }, + { + "internalType": "uint64", + "name": "_lastEpochReported", + "type": "uint64" + } + ], + "name": "InvalidEpochFrom", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint64", "name": "_from", "type": "uint64" }, + { "internalType": "uint64", "name": "_to", "type": "uint64" } + ], + "name": "InvalidEpochs", + "type": "error" + }, + { + "inputs": [{ "internalType": "bytes", "name": "_pubkey", "type": "bytes" }], + "name": "NodeAlreadyUsed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_stakingBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requestedToPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requestedToWithdrawal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requiredBalance", + "type": "uint256" + } + ], + "name": "NotEnoughETHtoStake", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "_rewardsPerSecondSent", + "type": "int256" + }, + { + "internalType": "int256", + "name": "_maxRewardsPerSecond", + "type": "int256" + } + ], + "name": "RewardsPerSecondTooBig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_unlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_currentTimestamp", + "type": "uint256" + } + ], + "name": "SubmitReportTimelocked", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_currentTotalAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newTotalUnderlying", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_difference", "type": "uint256" }, + { "internalType": "uint256", "name": "_maxDifference", "type": "uint256" } + ], + "name": "UpdateTooBig", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "UserNotWhitelisted", + "type": "error" + }, + { + "inputs": [ + { "internalType": "string", "name": "_address", "type": "string" } + ], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { "internalType": "uint64", "name": "from", "type": "uint64" }, + { "internalType": "uint64", "name": "to", "type": "uint64" }, + { "internalType": "uint256", "name": "rewards", "type": "uint256" }, + { "internalType": "uint256", "name": "penalties", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct Staking.EpochsReport", + "name": "report", + "type": "tuple" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalUnderlying", + "type": "uint256" + } + ], + "name": "ReportEpochs", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "nodeId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "nodeId", + "type": "uint256" + }, + { + "components": [ + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { "internalType": "bytes", "name": "signature", "type": "bytes" }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + } + ], + "indexed": false, + "internalType": "struct Staking.Node", + "name": "data", + "type": "tuple" + } + ], + "name": "UpdateNodeData", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "ACTIVATOR_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ACCEPTABLE_UNDERLYING_CHANGE", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DEPOSIT_FEE", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARDS_FEE", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_DEPOSIT", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUBMIT_REPORT_TIMELOCK", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPDATER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptableUnderlyingChange", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" } + ], + "name": "addToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "convertToAssets", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "convertToShares", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_assets", "type": "uint256" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "deposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositContract", + "outputs": [ + { "internalType": "contract IDeposit", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "depositETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositFee", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "estimatedRewardsPerSecond", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_liquidPool", "type": "address" }, + { "internalType": "address", "name": "_withdrawal", "type": "address" }, + { + "internalType": "address", + "name": "_depositContract", + "type": "address" + }, + { + "internalType": "contract IERC20MetadataUpgradeable", + "name": "_weth", + "type": "address" + }, + { "internalType": "address", "name": "_treasury", "type": "address" }, + { "internalType": "address", "name": "_updater", "type": "address" }, + { "internalType": "address", "name": "_activator", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastEpochReported", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidUnstakePool", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "mint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "name": "nodePubkeyUsed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { "internalType": "bytes", "name": "signature", "type": "bytes" }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + } + ], + "internalType": "struct Staking.Node[]", + "name": "_nodes", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "_requestPoolAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requestWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_depositContractRoot", + "type": "bytes32" + } + ], + "name": "pushToBeacon", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "redeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint64", "name": "from", "type": "uint64" }, + { "internalType": "uint64", "name": "to", "type": "uint64" }, + { "internalType": "uint256", "name": "rewards", "type": "uint256" }, + { "internalType": "uint256", "name": "penalties", "type": "uint256" } + ], + "internalType": "struct Staking.EpochsReport", + "name": "_epochsReport", + "type": "tuple" + }, + { + "internalType": "int256", + "name": "_estimatedRewardsPerSecond", + "type": "int256" + } + ], + "name": "reportEpochs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_requestedETH", "type": "uint256" } + ], + "name": "requestEthFromLiquidPoolToWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsFee", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "submitReportUnlockTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "toggleWhitelistEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalNodesActivated", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_acceptableUnderlyingChange", + "type": "uint16" + } + ], + "name": "updateAcceptableUnderlyingChange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_depositFee", "type": "uint16" } + ], + "name": "updateDepositFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "_estimatedRewardsPerSecond", + "type": "int256" + } + ], + "name": "updateEstimatedRewardsPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_liquidPool", + "type": "address" + } + ], + "name": "updateLiquidPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_rewardsFee", "type": "uint16" } + ], + "name": "updateRewardsFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_withdrawal", + "type": "address" + } + ], + "name": "updateWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistEnabled", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "whitelistedAccounts", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawal", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalCredential", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/meta-pool-eth/index.js b/src/adaptors/meta-pool-eth/index.js new file mode 100644 index 0000000000..ca3766b98d --- /dev/null +++ b/src/adaptors/meta-pool-eth/index.js @@ -0,0 +1,81 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.json'); + +const token = '0x48AFbBd342F64EF8a9Ab1C143719b63C2AD81710'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const apy = async () => { + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const amount = 1000000000000000000n; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'convertToAssets'), + params: [amount], + }), + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'convertToAssets'), + params: [amount], + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'convertToAssets'), + params: [amount], + block: block7dayAgo, + }), + ]); + + const apyBase = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18) * 365 * 100; + + const apyBase7d = + ((exchangeRates[0].output - exchangeRates[2].output) / 1e18 / 7) * + 365 * + 100; + + const totalSupply = + ( + await sdk.api.abi.call({ + target: token, + abi: abi.find((m) => m.name === 'totalSupply'), + }) + ).output / 1e18; + + const k = 'coingecko:ethereum'; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${k}`) + ).data.coins[k].price; + + return [ + { + pool: token, + project: 'meta-pool-eth', + chain: 'ethereum', + symbol: 'mpETH', + tvlUsd: totalSupply * ethPrice, + apyBase, + apyBase7d, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://www.metapool.app/stake?token=ethereum', +}; diff --git a/src/adaptors/metastreet-v2/abi.json b/src/adaptors/metastreet-v2/abi.json new file mode 100644 index 0000000000..be57dbef29 --- /dev/null +++ b/src/adaptors/metastreet-v2/abi.json @@ -0,0 +1,91 @@ +{ + "getPools": "address[]:getPools", + "collateralToken": "address:collateralToken", + "currencyToken": "address:currencyToken", + "name": "string:name", + "liquidityNodes": "function liquidityNodes(uint128 startTick, uint128 endTick) view returns (tuple(uint128 tick, uint128 value, uint128 shares, uint128 available, uint128 pending, uint128 redemptions, uint128 prev, uint128 next)[])", + "liquidityNodeWithAccrual": { + "inputs": [ + { + "internalType": "uint128", + "name": "tick", + "type": "uint128" + } + ], + "name": "liquidityNodeWithAccrual", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "tick", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "value", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "shares", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "available", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "pending", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "redemptions", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "prev", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "next", + "type": "uint128" + } + ], + "internalType": "struct ILiquidity.NodeInfo", + "name": "", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint128", + "name": "accrued", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "rate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + } + ], + "internalType": "struct ILiquidity.AccrualInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } + } + \ No newline at end of file diff --git a/src/adaptors/metastreet-v2/index.js b/src/adaptors/metastreet-v2/index.js new file mode 100644 index 0000000000..a81e4c2724 --- /dev/null +++ b/src/adaptors/metastreet-v2/index.js @@ -0,0 +1,151 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const abi = require('./abi.json'); + +const METASTREET_POOL_FACTORY = { + ethereum: '0x1c91c822F6C5e117A2abe2B33B0E64b850e67095', + base: '0x41cF7ea4Ba650191e829A6bD31B9e2049C78D858', + blast: '0x5F42c24Af1227c3c669035a6cB549579ed0F99dF', +}; +const MAX_UINT_128 = '0xffffffffffffffffffffffffffffffff'; + +const API = sdk.api.abi; + +const getApy = async (chain) => { + const pools = ( + await API.call({ + target: METASTREET_POOL_FACTORY[chain], + abi: abi.getPools, + chain, + }) + ).output; + + const collateralTokens = ( + await API.multiCall({ + calls: pools.map((pool) => ({ + target: pool, + params: [], + })), + abi: abi.collateralToken, + chain, + }) + ).output.map((o) => o.output); + const collateralTokenNames = ( + await API.multiCall({ + abi: abi.name, + calls: collateralTokens.map((token) => ({ target: token, params: [] })), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = ( + await API.multiCall({ + abi: abi.currencyToken, + calls: pools.map((pool) => { + return { + target: pool, + params: [], + }; + }), + chain, + }) + ).output.map((o) => o.output); + const tokenDecimals = ( + await API.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((token) => ({ target: token, params: [] })), + chain, + }) + ).output.map((o) => o.output); + const tokenSymbols = ( + await API.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((token) => ({ target: token, params: [] })), + chain, + }) + ).output.map((o) => o.output); + + const decimalsMap = {}; + tokens.forEach((token, index) => { + decimalsMap[token] = tokenDecimals[index]; + }); + + const pricesArray = tokens.map((t) => `${chain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const poolLiquidityNodes = ( + await API.multiCall({ + abi: abi.liquidityNodes, + calls: pools.map((pool) => ({ + target: pool, + params: [0, MAX_UINT_128], + })), + chain, + }) + ).output.map((o) => o.output); + + return await Promise.all( + poolLiquidityNodes.map(async (liquidityNodes, poolIndex) => { + const pool = pools[poolIndex]; + const collateralToken = collateralTokens[poolIndex]; + const collateralTokenName = collateralTokenNames[poolIndex]; + const token = tokens[poolIndex]; + const tokenSymbol = tokenSymbols[poolIndex]; + const price = prices[`${chain}:${token}`]?.price; + const decimals = decimalsMap[token]; + const scalingFactor = 10 ** (18 - decimals); + const totalValue = liquidityNodes.reduce((partialSum, node) => { + return partialSum + +node.value; + }, 0); + + const apy = await ( + await API.multiCall({ + abi: abi.liquidityNodeWithAccrual, + calls: liquidityNodes.map((node) => { + return { + target: pool, + params: [node.tick], + }; + }), + chain, + permitFailure: true, + }) + ).output + .filter((o) => o.success) + .reduce((bestApy, o) => { + const accrualRate = o.output[1].rate; + const tickValue = o.output[0].value; + const apy = (+accrualRate / +tickValue) * 86400 * 365 * 100; + return bestApy > apy ? bestApy : apy; + }, 0); + + return { + pool: pool, + poolMeta: collateralTokenName, + chain, + project: 'metastreet-v2', + symbol: tokenSymbol, + tvlUsd: (totalValue / scalingFactor / 10 ** decimals) * price, + apy, + }; + }) + ); +}; + +const apy = async () => { + const pools = await Promise.all( + Object.keys(METASTREET_POOL_FACTORY).map(async (chain) => getApy(chain)) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.metastreet.xyz/earn', +}; diff --git a/src/adaptors/metavault.trade/abis/abi.json b/src/adaptors/metavault.trade/abis/abi.json new file mode 100644 index 0000000000..fc9a4e2422 --- /dev/null +++ b/src/adaptors/metavault.trade/abis/abi.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdm": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/metavault.trade/index.js b/src/adaptors/metavault.trade/index.js new file mode 100644 index 0000000000..397abe95af --- /dev/null +++ b/src/adaptors/metavault.trade/index.js @@ -0,0 +1,185 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); + +const polygonMvxAddress = '0x2760e46d9bb43dafcbecaad1f64b93207f9f0ed7'; +const polygonMvlpManagerAddress = '0x13E733dDD6725a8133bec31b2Fc5994FA5c26Ea9'; + +const polygonFeeMvxTrackerAddress = + '0xaCEC858f6397Dd227dD4ed5bE91A5BB180b8c430'; +const polygonInflationMvxTrackerAddress = + '0xE8e2E78D8cA52f238CAf69f020fA961f8A7632e9'; + +const polygonFeeMvlpTrackerAddress = + '0xaBD6c70C41FdF9261dfF15F4eB589b44a37072eB'; +const polygonInflationMvlpTrackerAddress = + '0xA6ca41Bbf555074ed4d041c1F4551eF48116D59A'; + +const secondsPerYear = 31536000; + +async function getAdjustedAmount(pTarget, pChain, pAbi, pParams = []) { + let decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: pChain, + }); + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * secondsPerYear + : supply.output * 10 ** -decimals.output; +} + +async function getMvlpTvl(pChain) { + let tvl = await sdk.api.abi.call({ + target: pChain == 'polygon' ? polygonMvlpManagerAddress : '', + abi: abi['getAumInUsdm'], + chain: pChain, + params: [false], + }); + + return tvl.output * 10 ** -18; +} + +async function getPoolMvx( + pChain, + pInflationTrackerAddress, + pStakedMvx, + pStakedEsMvx, + pFeeMvx, + pInflationMvx, + pPriceData +) { + const tvlMvx = + pPriceData.mvx.price * + (await getAdjustedAmount( + pChain == 'polygon' ? polygonMvxAddress : '', + pChain, + 'erc20:balanceOf', + pChain == 'polygon' ? [polygonInflationMvxTrackerAddress] : [] + )); + + const tvsMvx = pStakedMvx * pPriceData.mvx.price; + const tvsEsMvx = pStakedEsMvx * pPriceData.mvx.price; + + const yearlyFeeMvx = + pChain == 'polygon' ? pFeeMvx * pPriceData.matic.price : 0; + const yearlyInflationMvx = pInflationMvx * pPriceData.mvx.price; + + const apyFee = (yearlyFeeMvx / tvsMvx) * 100; + const apyInflation = (yearlyInflationMvx / tvsEsMvx) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project: 'metavault.trade', + symbol: utils.formatSymbol('MVX'), + tvlUsd: tvlMvx, + apy: apyFee + apyInflation, + }; +} + +async function getPoolMvlp( + pChain, + pTvl, + pInflationTrackerAddress, + pFeeMvlp, + pInflationMvlp, + pPriceData +) { + const yearlyFeeMvlp = + pChain == 'polygon' ? pFeeMvlp * pPriceData.matic.price : 0; + const yearlyInflationMvlp = pInflationMvlp * pPriceData.mvx.price; + const apyFee = (yearlyFeeMvlp / pTvl) * 100; + const apyInflation = (yearlyInflationMvlp / pTvl) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project: 'metavault.trade', + symbol: utils.formatSymbol('MVLP'), + tvlUsd: parseFloat(pTvl), + apy: apyFee + apyInflation, + }; +} + +const getPools = async () => { + let pools = []; + + const priceKeys = ['metavault-trade', 'matic-network'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: priceDataRes } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + const priceData = { + mvx: priceDataRes['coingecko:metavault-trade'] || { price: 0 }, + matic: priceDataRes['coingecko:matic-network'] || { price: 0 }, + }; + + const polygonStakedMvx = await getAdjustedAmount( + polygonFeeMvxTrackerAddress, + 'polygon', + 'erc20:totalSupply' + ); + const polygonStakedEsMvx = await getAdjustedAmount( + polygonInflationMvxTrackerAddress, + 'polygon', + 'erc20:totalSupply' + ); + const polygonFeeMvx = await getAdjustedAmount( + polygonFeeMvxTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + const polygonInflationMvx = await getAdjustedAmount( + polygonInflationMvxTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMvx( + 'polygon', + polygonInflationMvxTrackerAddress, + polygonStakedMvx, + polygonStakedEsMvx, + polygonFeeMvx, + polygonInflationMvx, + priceData + ) + ); + + const polygonFeeMvlp = await getAdjustedAmount( + polygonFeeMvlpTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + const polygonInflationMvlp = await getAdjustedAmount( + polygonInflationMvlpTrackerAddress, + 'polygon', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMvlp( + 'polygon', + await getMvlpTvl('polygon'), + polygonInflationMvlpTrackerAddress, + polygonFeeMvlp, + polygonInflationMvlp, + priceData + ) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://metavault.trade/earn', +}; diff --git a/src/adaptors/meteora/index.js b/src/adaptors/meteora/index.js new file mode 100644 index 0000000000..13c1f46a89 --- /dev/null +++ b/src/adaptors/meteora/index.js @@ -0,0 +1,34 @@ +const standardPools = 'https://app.meteora.ag/amm/pools/v1?page=0&size=100'; +const clPools = + 'https://app.meteora.ag/clmm-api/pair/all_by_groups?page=0&limit=100&unknown=true&sort_key=volume&order_by=desc'; + +const apy = async () => { + const response = await fetch(standardPools); + const data = await response.json(); + return data.data.map((pool) => { + return { + pool: pool.pool_address, + chain: 'Solana', + project: 'meteora', + symbol: pool.pool_name, + underlyingTokens: p.pool_token_mints, + tvlUsd: pool.pool_tvl, + apyBase: pool.day.feeApr, + apyReward, + rewardTokens: + apyReward > 0 + ? pool?.rewardDefaultInfos?.map((r) => r.mint?.address) + : [], + apyBase7d: pool.week.feeApr, + volumeUsd1d: pool.day.volume, + volumeUsd7d: pool.week.volume, + poolMeta: `${pool.type} - ${pool.feeRate * 100}%`, + url: + pool.type.toLowerCase() === 'concentrated' + ? `https://raydium.io/clmm/create-position/?pool_id=${pool.id}` + : `https://raydium.io/liquidity/increase/?mode=add&pool_id=${pool.id}`, + }; + }); +}; + +module.exports = { apy }; diff --git a/src/adaptors/meth-protocol/index.js b/src/adaptors/meth-protocol/index.js new file mode 100644 index 0000000000..251ce850bb --- /dev/null +++ b/src/adaptors/meth-protocol/index.js @@ -0,0 +1,84 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const stakingAbi = require('./stakingAbi.json'); + +const mETH = '0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa'; +const stakingContract = '0xe3cBd06D7dadB3F4e6557bAb7EdD924CD1489E8f'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const amount = 1000000000000000000n; + +const apy = async () => { + const tvl = + ( + await sdk.api.abi.call({ + target: stakingContract, + abi: stakingAbi.find((m) => m.name === 'totalControlled'), + }) + ).output / 1e18; + + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: stakingContract, + abi: stakingAbi.find((m) => m.name === 'mETHToETH'), + params: [amount], + chain: 'ethereum', + }), + sdk.api.abi.call({ + target: stakingContract, + abi: stakingAbi.find((m) => m.name === 'mETHToETH'), + params: [amount], + chain: 'ethereum', + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: stakingContract, + abi: stakingAbi.find((m) => m.name === 'mETHToETH'), + params: [amount], + chain: 'ethereum', + block: block7dayAgo, + }), + ]); + + const apyBase = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18) * 365 * 100; + + const apyBase7d = + ((exchangeRates[0].output - exchangeRates[2].output) / 1e18 / 7) * + 365 * + 100; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: mETH, + chain: 'ethereum', + project: 'meth-protocol', + symbol: 'mETH', + tvlUsd: tvl * ethPrice, + apyBase, + apyBase7d, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://meth.mantle.xyz/stake', +}; diff --git a/src/adaptors/meth-protocol/stakingAbi.json b/src/adaptors/meth-protocol/stakingAbi.json new file mode 100644 index 0000000000..3ffecfe4ab --- /dev/null +++ b/src/adaptors/meth-protocol/stakingAbi.json @@ -0,0 +1,950 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "DoesNotReceiveETH", "type": "error" }, + { "inputs": [], "name": "InvalidConfiguration", "type": "error" }, + { + "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "name": "InvalidDepositRoot", + "type": "error" + }, + { + "inputs": [{ "internalType": "bytes12", "name": "", "type": "bytes12" }], + "name": "InvalidWithdrawalCredentialsNotETH1", + "type": "error" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "InvalidWithdrawalCredentialsWrongAddress", + "type": "error" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "InvalidWithdrawalCredentialsWrongLength", + "type": "error" + }, + { "inputs": [], "name": "MaximumMETHSupplyExceeded", "type": "error" }, + { "inputs": [], "name": "MaximumValidatorDepositExceeded", "type": "error" }, + { "inputs": [], "name": "MinimumStakeBoundNotSatisfied", "type": "error" }, + { "inputs": [], "name": "MinimumUnstakeBoundNotSatisfied", "type": "error" }, + { + "inputs": [], + "name": "MinimumValidatorDepositNotSatisfied", + "type": "error" + }, + { "inputs": [], "name": "NotEnoughDepositETH", "type": "error" }, + { "inputs": [], "name": "NotEnoughUnallocatedETH", "type": "error" }, + { "inputs": [], "name": "NotReturnsAggregator", "type": "error" }, + { "inputs": [], "name": "NotUnstakeRequestsManager", "type": "error" }, + { "inputs": [], "name": "Paused", "type": "error" }, + { "inputs": [], "name": "PreviouslyUsedValidator", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "methAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "expectedMinimum", + "type": "uint256" + } + ], + "name": "StakeBelowMinimumMETHAmount", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "ethAmount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "expectedMinimum", + "type": "uint256" + } + ], + "name": "UnstakeBelowMinimumETHAmount", + "type": "error" + }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AllocatedETHToDeposits", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AllocatedETHToUnstakeRequestsManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "setterSelector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "string", + "name": "setterSignature", + "type": "string" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "name": "ProtocolConfigChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ReturnsReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mETHAmount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "UnstakeRequestClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mETHLocked", + "type": "uint256" + } + ], + "name": "UnstakeRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "operatorID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountDeposited", + "type": "uint256" + } + ], + "name": "ValidatorInitiated", + "type": "event" + }, + { "stateMutability": "payable", "type": "fallback" }, + { + "inputs": [], + "name": "ALLOCATOR_SERVICE_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIATOR_SERVICE_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_ALLOWLIST_MANAGER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_ALLOWLIST_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STAKING_MANAGER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOP_UP_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "allocateToUnstakeRequestsManager", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocateToDeposits", + "type": "uint256" + } + ], + "name": "allocateETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allocatedETHForDeposits", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "unstakeRequestID", + "type": "uint256" + } + ], + "name": "claimUnstakeRequest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositContract", + "outputs": [ + { + "internalType": "contract IDepositContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "ethAmount", "type": "uint256" } + ], + "name": "ethToMETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeAdjustmentRate", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "getRoleMember", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleMemberCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initializationBlockNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "admin", "type": "address" }, + { "internalType": "address", "name": "manager", "type": "address" }, + { + "internalType": "address", + "name": "allocatorService", + "type": "address" + }, + { + "internalType": "address", + "name": "initiatorService", + "type": "address" + }, + { + "internalType": "address", + "name": "returnsAggregator", + "type": "address" + }, + { + "internalType": "address", + "name": "withdrawalWallet", + "type": "address" + }, + { + "internalType": "contract IMETH", + "name": "mETH", + "type": "address" + }, + { + "internalType": "contract IDepositContract", + "name": "depositContract", + "type": "address" + }, + { + "internalType": "contract IOracleReadRecord", + "name": "oracle", + "type": "address" + }, + { + "internalType": "contract IPauserRead", + "name": "pauser", + "type": "address" + }, + { + "internalType": "contract IUnstakeRequestsManager", + "name": "unstakeRequestsManager", + "type": "address" + } + ], + "internalType": "struct Staking.Init", + "name": "init", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "operatorID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositAmount", + "type": "uint256" + }, + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { + "internalType": "bytes", + "name": "withdrawalCredentials", + "type": "bytes" + }, + { "internalType": "bytes", "name": "signature", "type": "bytes" }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + } + ], + "internalType": "struct Staking.ValidatorParams[]", + "name": "validators", + "type": "tuple[]" + }, + { + "internalType": "bytes32", + "name": "expectedDepositRoot", + "type": "bytes32" + } + ], + "name": "initiateValidatorsWithDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isStakingAllowlist", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mETH", + "outputs": [ + { "internalType": "contract IMETH", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "mETHAmount", "type": "uint256" } + ], + "name": "mETHToETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumDepositAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumMETHSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumDepositAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumStakeBound", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumUnstakeBound", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numInitiatedValidators", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract IOracleReadRecord", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [ + { "internalType": "contract IPauserRead", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "receiveFromUnstakeRequestsManager", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "receiveReturns", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "reclaimAllocatedETHSurplus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "returnsAggregator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "exchangeAdjustmentRate_", + "type": "uint16" + } + ], + "name": "setExchangeAdjustmentRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maximumDepositAmount_", + "type": "uint256" + } + ], + "name": "setMaximumDepositAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maximumMETHSupply_", + "type": "uint256" + } + ], + "name": "setMaximumMETHSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minimumDepositAmount_", + "type": "uint256" + } + ], + "name": "setMinimumDepositAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minimumStakeBound_", + "type": "uint256" + } + ], + "name": "setMinimumStakeBound", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minimumUnstakeBound_", + "type": "uint256" + } + ], + "name": "setMinimumUnstakeBound", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "isStakingAllowlist_", "type": "bool" } + ], + "name": "setStakingAllowlist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "withdrawalWallet_", + "type": "address" + } + ], + "name": "setWithdrawalWallet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "minMETHAmount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "topUp", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "totalControlled", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDepositedInValidators", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unallocatedETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint128", "name": "methAmount", "type": "uint128" }, + { "internalType": "uint128", "name": "minETHAmount", "type": "uint128" } + ], + "name": "unstakeRequest", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "unstakeRequestID", + "type": "uint256" + } + ], + "name": "unstakeRequestInfo", + "outputs": [ + { "internalType": "bool", "name": "", "type": "bool" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint128", "name": "methAmount", "type": "uint128" }, + { "internalType": "uint128", "name": "minETHAmount", "type": "uint128" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "unstakeRequestWithPermit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unstakeRequestsManager", + "outputs": [ + { + "internalType": "contract IUnstakeRequestsManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "pubkey", "type": "bytes" }], + "name": "usedValidators", + "outputs": [{ "internalType": "bool", "name": "exists", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalWallet", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/metrom/index.ts b/src/adaptors/metrom/index.ts new file mode 100644 index 0000000000..29e3a308d5 --- /dev/null +++ b/src/adaptors/metrom/index.ts @@ -0,0 +1,211 @@ +const { getData, formatChain, formatSymbol, keepFinite } = require('../utils'); + +const PROJECT = 'metrom'; + +type ByChainTypeAndId = Record>; + +const CHAIN_TYPE_AND_NAMES: ByChainTypeAndId = { + evm: { + 8_453: 'Base', + 167_000: 'Taiko', + 534_352: 'Scroll', + 146: 'Sonic', + 478: 'Form', + 100: 'Gnosis', + 40: 'Telos', + 1_890: 'LightLink', + 1_329: 'Sei', + 1_923: 'Swell', + 43_111: 'Hemi', + 232: 'Lens', + 994_873_017: 'Lumia', + }, + aptos: { + 1: 'Aptos', + }, +}; + +const PAGE_SIZE = 20; + +interface Token { + address: string; + symbol: string; +} + +interface BaseTarget { + chainType: string; + chainId: number; +} + +interface AmmPoolLiquidityTarget extends BaseTarget { + type: 'amm-pool-liquidity'; + id: string; + tokens: Token[]; + usdTvl: number; +} + +interface BaseLiquityV2Target extends BaseTarget { + brand: string; + collateral: Token; +} + +interface LiquityV2DebtTarget extends BaseLiquityV2Target { + type: 'liquity-v2-debt'; +} + +interface LiquityV2StabilityPoolTarget extends BaseLiquityV2Target { + type: 'liquity-v2-stability-pool'; +} + +interface GmxV1LiquidityTarget extends BaseTarget { + type: 'gmx-v1-liquidity'; + brand: string; +} + +interface BaseAaveV3Target extends BaseTarget { + brand: string; + market: string; + collateral: Token; +} + +interface AaveV3SupplyTarget extends BaseAaveV3Target { + type: 'aave-v3-supply'; +} + +interface AaveV3BorrowTarget extends BaseAaveV3Target { + type: 'aave-v3-borrow'; +} + +interface AaveV3NetSupplyTarget extends BaseAaveV3Target { + type: 'aave-v3-net-supply'; +} + +interface Reward extends Token { + amount: string; + remaining: string; +} + +interface Rewards { + assets: Reward[]; +} + +interface Campaign { + chainType: string; + chainId: number; + id: string; + target: + | AmmPoolLiquidityTarget + | LiquityV2DebtTarget + | LiquityV2StabilityPoolTarget + | GmxV1LiquidityTarget + | AaveV3SupplyTarget + | AaveV3BorrowTarget + | AaveV3NetSupplyTarget; + rewards: Rewards; + usdTvl?: number; + apr?: number; +} + +interface CampaignsResponse { + totalItems: number; + campaigns: Campaign[]; +} + +module.exports = { + timetravel: false, + apy: async () => { + const campaigns = []; + + let page = 1; + while (true) { + const response = (await getData( + `https://api.metrom.xyz/v2/campaigns/rewards?page=${page}&pageSize=${PAGE_SIZE}&statuses=active` + )) as CampaignsResponse; + + for (const campaign of response.campaigns) { + const chainType = campaign.chainType; + const byType = CHAIN_TYPE_AND_NAMES[chainType]; + if (!byType) continue; + + const chainId = campaign.chainId; + const chain = byType[chainId]; + + if ( + !chain || + chainId !== campaign.target.chainId || + !campaign.apr || + !campaign.usdTvl + ) + continue; + + let processedCampaign; + try { + processedCampaign = processCampaign(campaign); + } catch (err) { + console.error( + `Could not process campaign with id ${campaign.id}: ${err}` + ); + continue; + } + + campaigns.push({ + ...processedCampaign, + pool: campaign.id.toLowerCase(), + chain: formatChain(chain), + project: PROJECT, + apyReward: campaign.apr, + tvlUsd: campaign.usdTvl, + rewardTokens: campaign.rewards.assets.map((reward) => reward.address), + url: `https://app.metrom.xyz/en/campaigns/${chainType}/${chainId}/${campaign.id}`, + }); + } + + if (response.campaigns.length < PAGE_SIZE) break; + + page++; + } + + return campaigns.filter(keepFinite); + }, +}; + +interface ProcessedCampaign { + symbol: string; + underlyingTokens: string[]; +} + +function processCampaign(campaign: Campaign): ProcessedCampaign | null { + switch (campaign.target.type) { + case 'amm-pool-liquidity': { + return { + symbol: formatSymbol( + campaign.target.tokens.map((token) => token.symbol).join(' - ') + ), + underlyingTokens: campaign.target.tokens.map((token) => token.address), + }; + } + case 'liquity-v2-debt': + case 'liquity-v2-stability-pool': { + return { + symbol: formatSymbol(campaign.target.collateral.symbol), + underlyingTokens: [campaign.target.collateral.symbol], + }; + } + case 'gmx-v1-liquidity': { + // FIXME: for now, with the current API, it's impossible to process GMX v1 + // campaigns, address this later on + return null; + } + case 'aave-v3-supply': + case 'aave-v3-borrow': + case 'aave-v3-net-supply': { + return { + symbol: formatSymbol(campaign.target.collateral.symbol), + underlyingTokens: [campaign.target.collateral.symbol], + }; + } + default: { + return null; + } + } +} diff --git a/src/adaptors/mev-protocol/abi.json b/src/adaptors/mev-protocol/abi.json new file mode 100644 index 0000000000..1abe83638b --- /dev/null +++ b/src/adaptors/mev-protocol/abi.json @@ -0,0 +1,1796 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "authority", + "type": "address" + }, + { + "internalType": "address", + "name": "weth", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyClaimed", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyDeposited", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyFinalised", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "DepositTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "IncorrectWithdrawalCredentials", + "type": "error" + }, + { + "inputs": [], + "name": "IndexExceedsQueueLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPendingMevEthShareVault", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPendingStakingModule", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "NoAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughEth", + "type": "error" + }, + { + "inputs": [], + "name": "NotFinalised", + "type": "error" + }, + { + "inputs": [], + "name": "PrematureMevEthShareVaultUpdateFinalization", + "type": "error" + }, + { + "inputs": [], + "name": "PrematureStakingModuleUpdateFinalization", + "type": "error" + }, + { + "inputs": [], + "name": "SandwichProtection", + "type": "error" + }, + { + "inputs": [], + "name": "StakingPaused", + "type": "error" + }, + { + "inputs": [], + "name": "TransferExceedsAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "UnAuthorizedCaller", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "WithdrawTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "WrongDepositAmount", + "type": "error" + }, + { + "inputs": [], + "name": "WrongWithdrawAmount", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + } + ], + "name": "AdminDeleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "creamAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mevEthAmount", + "type": "uint256" + } + ], + "name": "CreamRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "mevEthShareVault", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "stakingModule", + "type": "address" + } + ], + "name": "MevEthInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldVault", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newVault", + "type": "address" + } + ], + "name": "MevEthShareVaultUpdateCanceled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldVault", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pendingVault", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "eligibleForFinalization", + "type": "uint64" + } + ], + "name": "MevEthShareVaultUpdateCommitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldVault", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newVault", + "type": "address" + } + ], + "name": "MevEthShareVaultUpdateFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newOperator", + "type": "address" + } + ], + "name": "OperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOperator", + "type": "address" + } + ], + "name": "OperatorDeleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Rewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldModule", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pendingModule", + "type": "address" + } + ], + "name": "StakingModuleUpdateCanceled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldModule", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pendingModule", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "eligibleForFinalization", + "type": "uint64" + } + ], + "name": "StakingModuleUpdateCommitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldModule", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newModule", + "type": "address" + } + ], + "name": "StakingModuleUpdateFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "StakingPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "StakingUnpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "stakingModule", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "withdrawal_credentials", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "deposit_data_root", + "type": "bytes32" + } + ], + "indexed": false, + "internalType": "struct IStakingModule.ValidatorData", + "name": "newValidator", + "type": "tuple" + } + ], + "name": "ValidatorCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ValidatorWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "withdrawalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "WithdrawalQueueClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "withdrawalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "WithdrawalQueueOpened", + "type": "event" + }, + { + "inputs": [], + "name": "CREAM_TO_MEV_ETH_PERCENT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_DEPOSIT", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_WITHDRAWAL", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [ + { + "internalType": "contract WETH", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "addAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOperator", + "type": "address" + } + ], + "name": "addOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "admins", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "assetTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "calculateNeededEtherBuffer", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cancelUpdateMevEthShareVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cancelUpdateStakingModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawalId", + "type": "uint256" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMevEthShareVault", + "type": "address" + } + ], + "name": "commitUpdateMevEthShareVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IStakingModule", + "name": "newModule", + "type": "address" + } + ], + "name": "commitUpdateStakingModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "creamToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "withdrawal_credentials", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "deposit_data_root", + "type": "bytes32" + } + ], + "internalType": "struct IStakingModule.ValidatorData", + "name": "newData", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "latestDepositRoot", + "type": "bytes32" + } + ], + "name": "createValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldAdmin", + "type": "address" + } + ], + "name": "deleteAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldOperator", + "type": "address" + } + ], + "name": "deleteOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeUpdateMevEthShareVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "finalizeUpdateStakingModule", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "fraction", + "outputs": [ + { + "internalType": "uint128", + "name": "elastic", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "base", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "grantRewards", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "grantValidatorWithdraw", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialShareVault", + "type": "address" + }, + { + "internalType": "address", + "name": "initialStakingModule", + "type": "address" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "maxAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "maxShares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "maxShares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "maxAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mevEthShareVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "operators", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingMevEthShareVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingMevEthShareVaultCommittedTimestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingStakingModule", + "outputs": [ + { + "internalType": "contract IStakingModule", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingStakingModuleCommittedTimestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newRequestsFinalisedUntil", + "type": "uint256" + } + ], + "name": "processWithdrawalQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "queueLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "creamAmount", + "type": "uint256" + } + ], + "name": "redeemCream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestsFinalisedUntil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "newMinimum", + "type": "uint128" + } + ], + "name": "setMinWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingModule", + "outputs": [ + { + "internalType": "contract IStakingModule", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "totalManagedAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdrawQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalAmountQueued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ticketNumber", + "type": "uint256" + } + ], + "name": "withdrawalQueue", + "outputs": [ + { + "internalType": "bool", + "name": "claimed", + "type": "bool" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "accumulatedAmount", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/mev-protocol/index.js b/src/adaptors/mev-protocol/index.js new file mode 100644 index 0000000000..b20d4c6835 --- /dev/null +++ b/src/adaptors/mev-protocol/index.js @@ -0,0 +1,59 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.json'); +const mevETH = '0x24Ae2dA0f361AA4BE46b48EB19C91e02c5e4f27E'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: mevETH, + abi: abi.find((m) => m.name === 'totalSupply'), + }) + ).output / 1e18; + + const fraction = ( + await sdk.api.abi.call({ + target: mevETH, + abi: abi.find((m) => m.name === 'fraction'), + }) + ).output; + + const mevEthPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:${mevETH}`) + ).data.coins[`ethereum:${mevETH}`].price; + + const elastic = fraction[0]; + const base = fraction[1]; + const rate = elastic / base; + const tvlUsd = totalSupply * rate * mevEthPrice; + const startTime = new Date(1696426103 * 1000); + const endTime = new Date(); + const yearInSeconds = 31536000; + const timeSinceLaunch = (endTime.getTime() - startTime.getTime()) / 1000; + const apyBase = + (100 * + (parseFloat(elastic.toString()) - parseFloat(base.toString())) * + yearInSeconds) / + (timeSinceLaunch * parseFloat(base.toString())); + + return [ + { + pool: mevETH, + project: 'mev-protocol', + chain: 'Ethereum', + symbol: 'mevETH', + tvlUsd, + apyBase, + apyBase7d: apyBase, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://mev.io/stake', +}; diff --git a/src/adaptors/midas-capital/abiComptroller.js b/src/adaptors/midas-capital/abiComptroller.js new file mode 100644 index 0000000000..593a812693 --- /dev/null +++ b/src/adaptors/midas-capital/abiComptroller.js @@ -0,0 +1,1613 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'address payable', + name: '_fuseAdmin', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_functionSelector', + type: 'bytes4', + }, + ], + name: 'ExtensionNotFound', + type: 'error', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_functionSelector', + type: 'bytes4', + }, + { + internalType: 'address', + name: '_currentImpl', + type: 'address', + }, + ], + name: 'FunctionAlreadyAdded', + type: 'error', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_functionSelector', + type: 'bytes4', + }, + ], + name: 'FunctionNotFound', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'rewardsDistributor', + type: 'address', + }, + ], + name: 'AddedRewardsDistributor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'enabled', + type: 'bool', + }, + ], + name: 'AutoImplementationsToggled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'enforce', + type: 'bool', + }, + ], + name: 'WhitelistEnforcementChanged', + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'fallback', + }, + { + inputs: [ + { + internalType: 'address', + name: 'distributor', + type: 'address', + }, + ], + name: '_addRewardsDistributor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_afterNonReentrant', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_becomeImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_beforeNonReentrant', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_borrowGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'isCEther', + type: 'bool', + }, + { + internalType: 'bytes', + name: 'constructorData', + type: 'bytes', + }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_deployMarket', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_listExtensions', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: '_mintGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DiamondExtension', + name: 'extensionToAdd', + type: 'address', + }, + { + internalType: 'contract DiamondExtension', + name: 'extensionToReplace', + type: 'address', + }, + ], + name: '_registerExtension', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'enforce', + type: 'bool', + }, + ], + name: '_setWhitelistEnforcement', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'suppliers', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'statuses', + type: 'bool[]', + }, + ], + name: '_setWhitelistStatuses', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'enabled', + type: 'bool', + }, + ], + name: '_toggleAutoImplementations', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'accountAssets', + outputs: [ + { + internalType: 'contract CTokenInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'adminHasRights', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'allBorrowers', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'allMarkets', + outputs: [ + { + internalType: 'contract CTokenInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'asComptrollerFirstExtension', + outputs: [ + { + internalType: 'contract ComptrollerFirstExtension', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'autoImplementation', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + ], + name: 'borrowAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'borrowCapForAssetForCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowCapGuardian', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'borrowCaps', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'borrowGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'accountBorrowsNew', + type: 'uint256', + }, + ], + name: 'borrowWithinLimits', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'borrowingAgainstCollateralBlacklist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'cTokensByUnderlying', + outputs: [ + { + internalType: 'contract CTokenInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + ], + name: 'checkMembership', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'closeFactorMantissa', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'comptrollerImplementation', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'enforceWhitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'enterMarkets', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cTokenAddress', + type: 'address', + }, + ], + name: 'exitMarket', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'fuseAdmin', + outputs: [ + { + internalType: 'address payable', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'fuseAdminHasRights', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getAccountLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getAssetsIn', + outputs: [ + { + internalType: 'contract CTokenInterface[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenModify', + type: 'address', + }, + { + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'bool', + name: 'isBorrow', + type: 'bool', + }, + ], + name: 'getMaxRedeemOrBorrow', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isComptroller', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract CTokenInterface', + name: 'cToken', + type: 'address', + }, + ], + name: 'isDeprecated', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + ], + name: 'liquidateBorrowAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'markets', + outputs: [ + { + internalType: 'bool', + name: 'isListed', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + ], + name: 'mintAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'mintGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'nonAccruingRewardsDistributors', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracle', + outputs: [ + { + internalType: 'contract PriceOracle', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauseGuardian', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'redeemAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'redeemVerify', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + ], + name: 'repayBorrowAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'rewardsDistributors', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'seizeAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'seizeGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'suppliers', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'supplyCaps', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'src', + type: 'address', + }, + { + internalType: 'address', + name: 'dst', + type: 'address', + }, + { + internalType: 'uint256', + name: 'transferTokens', + type: 'uint256', + }, + ], + name: 'transferAllowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'transferGuardianPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'whitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'whitelistArray', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/midas-capital/abiFlywheelLensRouter.js b/src/adaptors/midas-capital/abiFlywheelLensRouter.js new file mode 100644 index 0000000000..2099df8a43 --- /dev/null +++ b/src/adaptors/midas-capital/abiFlywheelLensRouter.js @@ -0,0 +1,133 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getMarketRewardsInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'underlyingPrice', + type: 'uint256', + }, + { + internalType: 'contract CErc20Token', + name: 'market', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'rewardSpeedPerSecondPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardTokenPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'formattedAPR', + type: 'uint256', + }, + { + internalType: 'address', + name: 'flywheel', + type: 'address', + }, + { + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.RewardsInfo[]', + name: 'rewardsInfo', + type: 'tuple[]', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.MarketRewardsInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract CErc20Token[]', + name: 'markets', + type: 'address[]', + }, + { + internalType: 'contract MidasFlywheelCore[]', + name: 'flywheels', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'accrue', + type: 'bool[]', + }, + ], + name: 'getUnclaimedRewardsByMarkets', + outputs: [ + { + internalType: 'uint256[]', + name: 'rewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract ERC20', + name: 'market', + type: 'address', + }, + { + internalType: 'contract MidasFlywheelCore[]', + name: 'flywheels', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'accrue', + type: 'bool[]', + }, + ], + name: 'getUnclaimedRewardsForMarket', + outputs: [ + { + internalType: 'uint256[]', + name: 'rewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/midas-capital/abiFlywheelLensRouterV2.js b/src/adaptors/midas-capital/abiFlywheelLensRouterV2.js new file mode 100644 index 0000000000..b96e10696c --- /dev/null +++ b/src/adaptors/midas-capital/abiFlywheelLensRouterV2.js @@ -0,0 +1,335 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract FusePoolDirectory', + name: '_fpd', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'claimAllRewardTokens', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract ERC20', + name: 'market', + type: 'address', + }, + { + internalType: 'contract MidasFlywheelCore[]', + name: 'flywheels', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'accrue', + type: 'bool[]', + }, + ], + name: 'claimRewardsForMarket', + outputs: [ + { + internalType: 'contract MidasFlywheelCore[]', + name: '', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'rewardTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'rewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract ERC20[]', + name: 'markets', + type: 'address[]', + }, + { + internalType: 'contract MidasFlywheelCore[]', + name: 'flywheels', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'accrue', + type: 'bool[]', + }, + ], + name: 'claimRewardsForMarkets', + outputs: [ + { + internalType: 'contract MidasFlywheelCore[]', + name: '', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'rewardTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'rewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'claimRewardsForPool', + outputs: [ + { + internalType: 'contract MidasFlywheelCore[]', + name: '', + type: 'address[]', + }, + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + ], + name: 'claimRewardsOfRewardToken', + outputs: [ + { + internalType: 'uint256', + name: 'rewardsClaimed', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'fpd', + outputs: [ + { + internalType: 'contract FusePoolDirectory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllRewardTokens', + outputs: [ + { + internalType: 'address[]', + name: 'uniqueRewardTokens', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ICErc20[]', + name: 'markets', + type: 'address[]', + }, + ], + name: 'getMarketRewardsInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'underlyingPrice', + type: 'uint256', + }, + { + internalType: 'contract ICErc20', + name: 'market', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'rewardSpeedPerSecondPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardTokenPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'formattedAPR', + type: 'uint256', + }, + { + internalType: 'address', + name: 'flywheel', + type: 'address', + }, + { + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.RewardsInfo[]', + name: 'rewardsInfo', + type: 'tuple[]', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.MarketRewardsInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getPoolMarketRewardsInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'underlyingPrice', + type: 'uint256', + }, + { + internalType: 'contract ICErc20', + name: 'market', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'rewardSpeedPerSecondPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardTokenPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'formattedAPR', + type: 'uint256', + }, + { + internalType: 'address', + name: 'flywheel', + type: 'address', + }, + { + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.RewardsInfo[]', + name: 'rewardsInfo', + type: 'tuple[]', + }, + ], + internalType: 'struct MidasFlywheelLensRouter.MarketRewardsInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/midas-capital/abiPoolDirectory.js b/src/adaptors/midas-capital/abiPoolDirectory.js new file mode 100644 index 0000000000..7629d7a43f --- /dev/null +++ b/src/adaptors/midas-capital/abiPoolDirectory.js @@ -0,0 +1,975 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + stateMutability: 'payable', + type: 'fallback', + }, + { + inputs: [], + name: 'admin', + outputs: [ + { + internalType: 'address', + name: 'admin_', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'changeAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'implementation', + outputs: [ + { + internalType: 'address', + name: 'implementation_', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + stateMutability: 'payable', + type: 'receive', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address[]', + name: 'admins', + type: 'address[]', + }, + { + indexed: false, + internalType: 'bool', + name: 'status', + type: 'bool', + }, + ], + name: 'AdminWhitelistUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'NewOwner', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingOwner', + type: 'address', + }, + ], + name: 'NewPendingOwner', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + indexed: false, + internalType: 'struct FusePoolDirectory.FusePool', + name: 'pool', + type: 'tuple', + }, + ], + name: 'PoolRegistered', + type: 'event', + }, + { + inputs: [], + name: '_acceptOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + ], + name: '_deprecatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: '_deprecatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'admins', + type: 'address[]', + }, + { + internalType: 'bool', + name: 'status', + type: 'bool', + }, + ], + name: '_editAdminWhitelist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'deployers', + type: 'address[]', + }, + { + internalType: 'bool', + name: 'status', + type: 'bool', + }, + ], + name: '_editDeployerWhitelist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: '_resetGap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'enforce', + type: 'bool', + }, + ], + name: '_setDeployerWhitelistEnforcement', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newPendingOwner', + type: 'address', + }, + ], + name: '_setPendingOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'adminWhitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'implementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'constructorData', + type: 'bytes', + }, + { + internalType: 'bool', + name: 'enforceWhitelist', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'closeFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationIncentive', + type: 'uint256', + }, + { + internalType: 'address', + name: 'priceOracle', + type: 'address', + }, + ], + name: 'deployPool', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'deployerWhitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'enforceDeployerWhitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getActivePools', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllPools', + outputs: [ + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getPoolsByAccount', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getPoolsOfUser', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPublicPools', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + name: 'getPublicPoolsByVerification', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getVerifiedPoolsOfWhitelistedAccount', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: '_enforceDeployerWhitelist', + type: 'bool', + }, + { + internalType: 'address[]', + name: '_deployerWhitelist', + type: 'address[]', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'poolExists', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'pools', + outputs: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolsCounter', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + ], + name: 'setPoolName', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_logic', + type: 'address', + }, + { + internalType: 'address', + name: 'admin_', + type: 'address', + }, + { + internalType: 'bytes', + name: '_data', + type: 'bytes', + }, + ], + stateMutability: 'payable', + type: 'constructor', + }, +]; diff --git a/src/adaptors/midas-capital/abiPoolLens.js b/src/adaptors/midas-capital/abiPoolLens.js new file mode 100644 index 0000000000..a110c5edf7 --- /dev/null +++ b/src/adaptors/midas-capital/abiPoolLens.js @@ -0,0 +1,1017 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + inputs: [], + name: 'directory', + outputs: [ + { + internalType: 'contract FusePoolDirectory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ICToken', + name: 'asset', + type: 'address', + }, + ], + name: 'getBorrowCapsForAsset', + outputs: [ + { + internalType: 'address[]', + name: 'collateral', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'borrowCapsPerCollateral', + type: 'uint256[]', + }, + { + internalType: 'bool[]', + name: 'collateralBlacklisted', + type: 'bool[]', + }, + { + internalType: 'uint256', + name: 'totalBorrowCap', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getPoolAssetsByUser', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'underlyingToken', + type: 'address', + }, + { + internalType: 'string', + name: 'underlyingName', + type: 'string', + }, + { + internalType: 'string', + name: 'underlyingSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'underlyingDecimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'underlyingBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'membership', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'exchangeRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'underlyingPrice', + type: 'uint256', + }, + { + internalType: 'address', + name: 'oracle', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'adminFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fuseFee', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'borrowGuardianPaused', + type: 'bool', + }, + { + internalType: 'bool', + name: 'mintGuardianPaused', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolAsset[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getPoolAssetsWithData', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'cToken', + type: 'address', + }, + { + internalType: 'address', + name: 'underlyingToken', + type: 'address', + }, + { + internalType: 'string', + name: 'underlyingName', + type: 'string', + }, + { + internalType: 'string', + name: 'underlyingSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'underlyingDecimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'underlyingBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowRatePerBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowBalance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'membership', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'exchangeRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'underlyingPrice', + type: 'uint256', + }, + { + internalType: 'address', + name: 'oracle', + type: 'address', + }, + { + internalType: 'uint256', + name: 'collateralFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'adminFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fuseFee', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'borrowGuardianPaused', + type: 'bool', + }, + { + internalType: 'bool', + name: 'mintGuardianPaused', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolAsset[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getPoolSummary', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + { + internalType: 'string[]', + name: '', + type: 'string[]', + }, + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getPoolsByAccountWithData', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'underlyingTokens', + type: 'address[]', + }, + { + internalType: 'string[]', + name: 'underlyingSymbols', + type: 'string[]', + }, + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getPoolsOfUserWithData', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'underlyingTokens', + type: 'address[]', + }, + { + internalType: 'string[]', + name: 'underlyingSymbols', + type: 'string[]', + }, + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + name: 'getPublicPoolsByVerificationWithData', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'underlyingTokens', + type: 'address[]', + }, + { + internalType: 'string[]', + name: 'underlyingSymbols', + type: 'string[]', + }, + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getPublicPoolsWithData', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'underlyingTokens', + type: 'address[]', + }, + { + internalType: 'string[]', + name: 'underlyingSymbols', + type: 'string[]', + }, + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IComptroller', + name: 'comptroller', + type: 'address', + }, + ], + name: 'getSupplyCapsForPool', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getWhitelistedPoolsByAccount', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'getWhitelistedPoolsByAccountWithData', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + { + components: [ + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'address', + name: 'creator', + type: 'address', + }, + { + internalType: 'address', + name: 'comptroller', + type: 'address', + }, + { + internalType: 'uint256', + name: 'blockPosted', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timestampPosted', + type: 'uint256', + }, + ], + internalType: 'struct FusePoolDirectory.FusePool[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'underlyingTokens', + type: 'address[]', + }, + { + internalType: 'string[]', + name: 'underlyingSymbols', + type: 'string[]', + }, + { + internalType: 'bool', + name: 'whitelistedAdmin', + type: 'bool', + }, + ], + internalType: 'struct FusePoolLens.FusePoolData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract FusePoolDirectory', + name: '_directory', + type: 'address', + }, + { + internalType: 'string', + name: '_name', + type: 'string', + }, + { + internalType: 'string', + name: '_symbol', + type: 'string', + }, + { + internalType: 'address[]', + name: '_hardcodedAddresses', + type: 'address[]', + }, + { + internalType: 'string[]', + name: '_hardcodedNames', + type: 'string[]', + }, + { + internalType: 'string[]', + name: '_hardcodedSymbols', + type: 'string[]', + }, + { + internalType: 'string[]', + name: '_uniswapLPTokenNames', + type: 'string[]', + }, + { + internalType: 'string[]', + name: '_uniswapLPTokenSymbols', + type: 'string[]', + }, + { + internalType: 'string[]', + name: '_uniswapLPTokenDisplayNames', + type: 'string[]', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ICToken', + name: 'cToken', + type: 'address', + }, + { + components: [ + { + internalType: 'bytes', + name: 'block', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'accountProofNodesRlp', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'reserveAndTimestampProofNodesRlp', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'priceAccumulatorProofNodesRlp', + type: 'bytes', + }, + ], + internalType: 'struct UniswapOracle.ProofData', + name: 'proofData', + type: 'tuple', + }, + ], + name: 'verifyPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/midas-capital/index.js b/src/adaptors/midas-capital/index.js new file mode 100644 index 0000000000..e732b3658c --- /dev/null +++ b/src/adaptors/midas-capital/index.js @@ -0,0 +1,305 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); + +const utils = require('../utils'); +const poolDirectoryAbi = require('../midas-capital/abiPoolDirectory'); +const poolLensAbi = require('../midas-capital/abiPoolLens'); +const flywheelLensRouterAbiV1 = require('../midas-capital/abiFlywheelLensRouter'); +const flywheelLensRouterAbiV2 = require('../midas-capital/abiFlywheelLensRouterV2'); + +const CHAINS = { + arbitrum: 'arbitrum', + bsc: 'bsc', + polygon: 'polygon', + fantom: 'fantom', +}; +const CHAIN_NUMBER = { + [CHAINS.bsc]: '56', + [CHAINS.polygon]: '137', + [CHAINS.arbitrum]: '42161', + [CHAINS.fantom]: '250', +}; + +const POOL_DIRECTORY_ADDRESS = { + [CHAINS.bsc]: '0x295d7347606F4bd810C8296bb8d75D657001fcf7', + [CHAINS.polygon]: '0x9A161e68EC0d5364f4d09A6080920DAFF6FFf250', + [CHAINS.arbitrum]: '0x68e8f59eA33FbccA716f56f89F47e53C73d47830', + [CHAINS.fantom]: '0xE622c2967E2885ED04436075889C88696328aBE8', +}; + +const POOL_LENS_ADDRESS = { + [CHAINS.bsc]: '0x47246c2e75409284b6409534d410245Ee48002c7', + [CHAINS.polygon]: '0xa9b97cb26eA3a5f33Fa1b8D88C00962eA4501558', + [CHAINS.arbitrum]: '0x062CEc1fa0F54cccd513c5b8aa86cBead5d1e55d', + [CHAINS.fantom]: '0x79AAb023F3cdCf5a8314E88bfb9EE88ecd3e12e7', +}; + +const MIDAS_FLYWHEEL_LENS_ROUTER = { + [CHAINS.bsc]: '0xb4c8353412633B779893Bb728435930b7d3610C8', + [CHAINS.polygon]: '0xda359cB8c4732C7260CD72dD052CD053765f1Dcf', + [CHAINS.arbitrum]: '0xFe5aF5765A7cCD1538E4ee4B501BC7fe93ec8EBa', + [CHAINS.fantom]: '0xFe5aF5765A7cCD1538E4ee4B501BC7fe93ec8EBa', +}; + +const CG_KEY = { + [CHAINS.bsc]: 'coingecko:binancecoin', + [CHAINS.polygon]: 'coingecko:matic-network', + [CHAINS.arbitrum]: 'coingecko:ethereum', + [CHAINS.fantom]: 'coingecko:fantom', +}; + +const BLOCKS_PER_MIN = { + [CHAINS.bsc]: 20, + [CHAINS.polygon]: 26, + [CHAINS.arbitrum]: 4, + [CHAINS.fantom]: 60, +}; + +const GET_ACTIVE_POOLS = 'getActivePools'; +const POOLS = 'pools'; +const GET_POOL_ASSETS_WITH_DATA = 'getPoolAssetsWithData'; +const GET_MARKET_REWARDS_INFO = 'getMarketRewardsInfo'; +const GET_MARKET_REWARDS_INFO_ARBITRUM = 'getPoolMarketRewardsInfo'; + +const PROJECT_NAME = 'midas-capital'; +const PROJECT_URL = 'https://development.midascapital.xyz'; + +const ratePerBlockToAPY = (ratePerBlock, blocksPerMin) => { + const blocksPerDay = blocksPerMin * 60 * 24; + const daysPerYear = 365; + const rateAsNumber = Number(ethers.utils.formatUnits(ratePerBlock, 18)); + + return (Math.pow(rateAsNumber * blocksPerDay + 1, daysPerYear) - 1) * 100; +}; + +const getPluginRewards = async (pluginAddress, chain) => { + if (pluginAddress) { + const res = ( + await superagent.get( + `${PROJECT_URL}/api/public/rewards?chainId=${CHAIN_NUMBER[chain]}&pluginAddress=${pluginAddress}` + ) + ).body; + + return res; + } else { + return undefined; + } +}; + +const main = async () => { + const markets = []; + + for (const chain of Object.keys(CHAINS)) { + const [poolIndexes, pools] = ( + await sdk.api.abi.call({ + target: POOL_DIRECTORY_ADDRESS[chain], + chain: chain, + abi: poolDirectoryAbi.find(({ name }) => name === GET_ACTIVE_POOLS), + }) + ).output; + + const allMarkets = []; + + for (const [index, poolId] of poolIndexes.entries()) { + try { + const { comptroller } = ( + await sdk.api.abi.call({ + target: POOL_DIRECTORY_ADDRESS[chain], + chain: chain, + abi: poolDirectoryAbi.find(({ name }) => name === POOLS), + params: [Number(poolId)], + }) + ).output; + const flywheelLensRouterAbi = + chain === 'arbitrum' + ? flywheelLensRouterAbiV2 + : flywheelLensRouterAbiV1; + + const marketRewards = ( + await sdk.api.abi + .call({ + target: MIDAS_FLYWHEEL_LENS_ROUTER[chain], + chain: chain, + abi: flywheelLensRouterAbi.find( + ({ name }) => + name === + (chain === 'arbitrum' + ? GET_MARKET_REWARDS_INFO_ARBITRUM + : GET_MARKET_REWARDS_INFO) + ), + params: [comptroller], + }) + .catch((e) => { + return { output: [] }; + }) + ).output; + + const adaptedMarketRewards = marketRewards + .map((marketReward) => ({ + underlyingPrice: marketReward.underlyingPrice, + market: marketReward.market, + rewardsInfo: marketReward.rewardsInfo.filter( + (info) => + Number( + ethers.utils.formatUnits(info.rewardSpeedPerSecondPerToken) + ) > 0 + ), + })) + .filter((marketReward) => marketReward.rewardsInfo.length > 0); + + const assets = ( + await sdk.api.abi + .call({ + target: POOL_LENS_ADDRESS[chain], + chain: chain, + abi: poolLensAbi.find( + ({ name }) => name === GET_POOL_ASSETS_WITH_DATA + ), + params: [comptroller], + }) + .catch((e) => {}) + ).output.map((obj) => { + return Object.fromEntries( + Object.entries(obj).filter(([k]) => isNaN(k)) + ); + }); + + const assetsWithPoolInfo = assets.map((asset) => { + asset.poolName = pools[index].name; + + const reward = adaptedMarketRewards.find( + (reward) => reward.market === asset.cToken + ); + + if (reward) { + asset.rewardsFromContract = reward; + } + + return asset; + }); + + allMarkets.push(...assetsWithPoolInfo); + } catch (e) {} + } + + const price = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${CG_KEY[chain]}` + ) + ).body.coins[CG_KEY[chain]].price; + + for (const market of allMarkets) { + if (market.mintGuardianPaused && market.borrowGuardianPaused) continue; + + const totalSupplyUsd = + Number( + ethers.utils.formatUnits( + market.totalSupply, + market.underlyingDecimals + ) + ) * + Number(ethers.utils.formatUnits(market.underlyingPrice, 18)) * + price; + + const totalBorrowUsd = + Number( + ethers.utils.formatUnits( + market.totalBorrow, + market.underlyingDecimals + ) + ) * + Number(ethers.utils.formatUnits(market.underlyingPrice, 18)) * + price; + + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + const apyBase = ratePerBlockToAPY( + market.supplyRatePerBlock, + BLOCKS_PER_MIN[chain] + ); + const apyBaseBorrow = ratePerBlockToAPY( + market.borrowRatePerBlock, + BLOCKS_PER_MIN[chain] + ); + + const pluginAddress = ( + await superagent.get( + `${PROJECT_URL}/api/public/plugins?chainId=${CHAIN_NUMBER[chain]}&marketAddress=${market.cToken}` + ) + ).body; + + const pluginRewards = await getPluginRewards(pluginAddress, chain); + const allRewards = + pluginRewards && pluginRewards.length > 0 ? [...pluginRewards] : []; + const rewardTokens = + pluginRewards && pluginRewards.length > 0 + ? [pluginRewards[0].plugin] + : []; + + if (market.rewardsFromContract) { + const flywheelsInPluginResponse = pluginRewards + ? pluginRewards + .map((pluginReward) => + 'flywheel' in pluginReward + ? pluginReward.flywheel.toLowerCase() + : null + ) + .filter((f) => !!f) + : []; + + for (const info of market.rewardsFromContract.rewardsInfo) { + if ( + !flywheelsInPluginResponse.includes(info.flywheel.toLowerCase()) + ) { + allRewards.push({ + flywheel: info.flywheel, + apy: info.formattedAPR + ? Number(ethers.utils.formatUnits(info.formattedAPR)) + : undefined, + token: info.rewardToken, + }); + + if (!rewardTokens.includes(info.rewardToken)) { + rewardTokens.push(info.rewardToken); + } + } + } + } + + const apyReward = allRewards.reduce( + (apy, obj) => + obj.status !== 'paused' && obj.apy !== undefined + ? apy + Number(obj.apy) * 100 + : apy, + 0 + ); + + markets.push({ + pool: market.cToken.toLowerCase(), + chain: utils.formatChain(chain), + project: PROJECT_NAME, + symbol: market.underlyingSymbol.toLowerCase(), + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [market.underlyingToken], + rewardTokens, + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: undefined, + ltv: Number(ethers.utils.formatUnits(market.collateralFactor)), + borrowable: !market.borrowGuardianPaused, + poolMeta: `${market.poolName} pool in ${chain}`, + }); + } + } + + return markets; +}; + +module.exports = { + timetravel: false, + apy: main, + url: PROJECT_URL, +}; diff --git a/src/adaptors/midas-rwa/abi/basicDatafeedAbi.json b/src/adaptors/midas-rwa/abi/basicDatafeedAbi.json new file mode 100644 index 0000000000..f89fce1abe --- /dev/null +++ b/src/adaptors/midas-rwa/abi/basicDatafeedAbi.json @@ -0,0 +1,509 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "int256", + "name": "current", + "type": "int256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + } + ], + "name": "AnswerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "startedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + } + ], + "name": "NewRound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aggregator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "confirmAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRound", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "phaseAggregators", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "phaseId", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "proposeAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedAggregator", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "proposedGetRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedLatestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/midas-rwa/abi/dataFeedAbi.json b/src/adaptors/midas-rwa/abi/dataFeedAbi.json new file mode 100644 index 0000000000..b98e1edd8f --- /dev/null +++ b/src/adaptors/midas-rwa/abi/dataFeedAbi.json @@ -0,0 +1,61 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "changeAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getDataInBase18", + "outputs": [ + { + "internalType": "uint256", + "name": "answer", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ac", + "type": "address" + }, + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_healthyDiff", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "_minExpectedAnswer", + "type": "int256" + }, + { + "internalType": "int256", + "name": "_maxExpectedAnswer", + "type": "int256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/midas-rwa/abi/erc20Abi.json b/src/adaptors/midas-rwa/abi/erc20Abi.json new file mode 100644 index 0000000000..904b92690d --- /dev/null +++ b/src/adaptors/midas-rwa/abi/erc20Abi.json @@ -0,0 +1,188 @@ +[ + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ] + }, + { + "type": "event", + "name": "Transfer", + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ] + }, + { + "type": "function", + "name": "allowance", + "stateMutability": "view", + "inputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "spender", + "type": "address" + } + ], + "outputs": [ + { + "type": "uint256" + } + ] + }, + { + "type": "function", + "name": "approve", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "spender", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "outputs": [ + { + "type": "bool" + } + ] + }, + { + "type": "function", + "name": "balanceOf", + "stateMutability": "view", + "inputs": [ + { + "name": "account", + "type": "address" + } + ], + "outputs": [ + { + "type": "uint256" + } + ] + }, + { + "type": "function", + "name": "decimals", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "type": "uint8" + } + ] + }, + { + "type": "function", + "name": "name", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "type": "string" + } + ] + }, + { + "type": "function", + "name": "symbol", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "type": "string" + } + ] + }, + { + "type": "function", + "name": "totalSupply", + "stateMutability": "view", + "inputs": [], + "outputs": [ + { + "type": "uint256" + } + ] + }, + { + "type": "function", + "name": "transfer", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "recipient", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "outputs": [ + { + "type": "bool" + } + ] + }, + { + "type": "function", + "name": "transferFrom", + "stateMutability": "nonpayable", + "inputs": [ + { + "name": "sender", + "type": "address" + }, + { + "name": "recipient", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "outputs": [ + { + "type": "bool" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/midas-rwa/addresses.js b/src/adaptors/midas-rwa/addresses.js new file mode 100644 index 0000000000..79a4a8c55a --- /dev/null +++ b/src/adaptors/midas-rwa/addresses.js @@ -0,0 +1,135 @@ +const { getAddress } = require('ethers/lib/utils'); + +const BASE_ASSET_ORACLES = { + BTC: { + address: '0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c', + chain: 'ethereum', + decimals: 8, + }, // BTC/USD on Ethereum + SOL: { + address: '0x4ffC43a60e009B551865A93d232E33Fce9f01507', + chain: 'ethereum', + decimals: 8, + }, // SOL/USD on Ethereum + // XRP: { + // address: '0xb549a837f95a79b83B3DA47fb64aAa9507Ee799C', + // chain: 'xrplevm', + // decimals: 18, + // }, // XRP/USD on Xrplevm +}; + +const contractAddresses = { + ethereum: { + mTBILL: { + address: getAddress('0xDD629E5241CbC5919847783e6C96B2De4754e438'), + dataFeed: getAddress('0xfCEE9754E8C375e145303b7cE7BEca3201734A2B'), + url: 'https://midas.app/mtbill', + }, + mBASIS: { + address: getAddress('0x2a8c22E3b10036f3AEF5875d04f8441d4188b656'), + dataFeed: getAddress('0x1615cBC603192ae8A9FF20E98dd0e40a405d76e4'), + url: 'https://midas.app/mbasis', + }, + mBTC: { + address: getAddress('0x007115416AB6c266329a03B09a8aa39aC2eF7d9d'), + dataFeed: getAddress('0x9987BE0c1dc5Cd284a4D766f4B5feB4F3cb3E28e'), + denomination: 'BTC', + url: 'https://midas.app/mbtc', + }, + mEDGE: { + address: getAddress('0xbB51E2a15A9158EBE2b0Ceb8678511e063AB7a55'), + dataFeed: getAddress('0x20cd58F72cF1727a2937eB1816593390cf8d91cB'), + url: 'https://midas.app/medge', + }, + mMEV: { + address: getAddress('0x030b69280892c888670EDCDCD8B69Fd8026A0BF3'), + dataFeed: getAddress('0x9BF00b7CFC00D6A7a2e2C994DB8c8dCa467ee359'), + url: 'https://midas.app/mmev', + }, + mAPOLLO: { + address: getAddress('0x7CF9DEC92ca9FD46f8d86e7798B72624Bc116C05'), + dataFeed: getAddress('0x9aEBf5d6F9411BAc355021ddFbe9B2c756BDD358'), + url: 'https://midas.app/mapollo', + }, + msyrupUSD: { + address: getAddress('0x20226607b4fa64228ABf3072Ce561d6257683464'), + dataFeed: getAddress('0x81c097e86842051B1ED4299a9E4d213Cb07f6f42'), + url: 'https://midas.app/msyrupusd', + }, + msyrupUSDp: { + address: getAddress('0x2fE058CcF29f123f9dd2aEC0418AA66a877d8E50'), + dataFeed: getAddress('0x7833397dA276d6B588e76466C14c82b2d733Cfb6'), + url: 'https://midas.app/msyrupusdp', + }, + mRe7YIELD: { + address: getAddress('0x87C9053C819bB28e0D73d33059E1b3DA80AFb0cf'), + dataFeed: getAddress('0x7E8C632ab231479886AF1Bc02B9D646e4634Da93'), + url: 'https://midas.app/mre7yield', + }, + mRe7BTC: { + address: getAddress('0x9FB442d6B612a6dcD2acC67bb53771eF1D9F661A'), + dataFeed: getAddress('0xB5D6483c556Bc6810b55B983315016Fcb374186D'), + denomination: 'BTC', + url: 'https://midas.app/mre7btc', + }, + mWildUSD: { + address: getAddress('0x605A84861EE603e385b01B9048BEa6A86118DB0a'), + dataFeed: getAddress('0xe604a420388Fbf2693F2250db0DC84488EE99aA1'), + url: 'https://midas.app/mwildusd', + }, + mFARM: { + address: getAddress('0xA19f6e0dF08a7917F2F8A33Db66D0AF31fF5ECA6'), + dataFeed: getAddress('0x9f49B0980B141b539e2A94Ec0864Faf699fF9524'), + url: 'https://midas.app/mfarm', + }, + mHYPER: { + address: getAddress('0x9b5528528656DBC094765E2abB79F293c21191B9'), + dataFeed: getAddress('0x92004DCC5359eD67f287F32d12715A37916deCdE'), + url: 'https://midas.app/mhyper', + }, + mFONE: { + address: getAddress('0x238a700eD6165261Cf8b2e544ba797BC11e466Ba'), + dataFeed: getAddress('0xCF4e49f5e750Af8F2f9Aa1642B68E5839D9c1C00'), + url: 'https://midas.app/mfone', + }, + }, + base: { + mBASIS: { + address: getAddress('0x1C2757c1FeF1038428b5bEF062495ce94BBe92b2'), + dataFeed: getAddress('0xD48D38Ec56CDB44c4281068129038A37F5Df04e5'), + url: 'https://midas.app/mbasis', + }, + mTBILL: { + address: getAddress('0xDD629E5241CbC5919847783e6C96B2De4754e438'), + dataFeed: getAddress('0xcbCf1e67F1988e2572a2A620321Aef2ff73369f0'), + url: 'https://midas.app/mtbill', + }, + mEDGE: { + address: getAddress('0x4089dC8b6637218f13465d28950A82a7E90cBE27'), + dataFeed: getAddress('0xA7aB67Aa19F6b387BA12FcEdB6d1447E0c25897c'), + url: 'https://midas.app/medge', + }, + mMEV: { + address: getAddress('0x141f0E9ed8bA2295254C9DF9476ccE7bC29172B1'), + dataFeed: getAddress('0x2E0357e38FC7fAE9C29050AEf3744D4055490adA'), + url: 'https://midas.app/mmev', + }, + }, + sapphire: { + mTBILL: { + address: getAddress('0xDD629E5241CbC5919847783e6C96B2De4754e438'), + dataFeed: getAddress('0x1075762cb143B495dbccE139712add38Eff19dAb'), + url: 'https://midas.app/mtbill', + }, + }, + // xprlevm: { + // mXRP: { + // address: getAddress('0x06e0B0F1A644Bb9881f675Ef266CeC15a63a3d47'), + // dataFeed: getAddress('0xed4ff96DAF37a0A44356E81A3cc22908B3f06B40'), + // denomination: 'XRP', + // url: 'https://midas.app/mxrp', + // }, + // }, +}; + +module.exports = { contractAddresses, BASE_ASSET_ORACLES }; diff --git a/src/adaptors/midas-rwa/chainlinkHelpers.js b/src/adaptors/midas-rwa/chainlinkHelpers.js new file mode 100644 index 0000000000..1580142ed2 --- /dev/null +++ b/src/adaptors/midas-rwa/chainlinkHelpers.js @@ -0,0 +1,185 @@ +const sdk = require('@defillama/sdk'); +const basicDataFeedAbi = require('./abi/basicDatafeedAbi.json'); +const utils = require('../utils'); + +const SECONDS_PER_DAY = 86400; + +// Get aggregator address from data feed contract +async function getAggregatorAddress(dataFeedAddress, chain) { + try { + const result = await sdk.api.abi.call({ + target: dataFeedAddress, + abi: 'function aggregator() view returns (address)', + chain: chain, + }); + + return result.output; + } catch (error) { + console.warn( + `MidasRWA: Failed to get aggregator address for ${dataFeedAddress} on ${chain}:`, + error.message + ); + return null; + } +} + +// Get latest round data from aggregator +async function getLatestRound(aggregatorAddress, chain) { + const result = await sdk.api.abi.call({ + target: aggregatorAddress, + abi: basicDataFeedAbi.find((m) => m.name === 'latestRoundData'), + chain: chain, + }); + + if (!result.output) { + return null; + } + + const [roundId, answer, , updatedAt] = result.output; + return { + roundId: Number(roundId), + answer: BigInt(answer), + updatedAt: Number(updatedAt), + }; +} + +// Get round data at specific block +async function getRoundAtBlock(aggregatorAddress, chain, block) { + const result = await sdk.api.abi.call({ + target: aggregatorAddress, + abi: basicDataFeedAbi.find((m) => m.name === 'latestRoundData'), + chain: chain, + block: block, + }); + + if (!result.output) { + return null; + } + + const [roundId, answer, , updatedAt] = result.output; + return { + roundId: Number(roundId), + answer: BigInt(answer), + updatedAt: Number(updatedAt), + }; +} + +// Get specific round by ID +async function getRoundById(aggregatorAddress, chain, roundId) { + const result = await sdk.api.abi.call({ + target: aggregatorAddress, + abi: basicDataFeedAbi.find((m) => m.name === 'getRoundData'), + chain: chain, + params: [roundId], + }); + + if (!result.output) { + return null; + } + + const [, answer, , updatedAt] = result.output; + return { + answer: BigInt(answer), + updatedAt: Number(updatedAt), + }; +} + +// Get historical price data with fallback +async function getHistoricalPrice(aggregatorAddress, chain, latestRound) { + const historicalTimestamp = latestRound.updatedAt - 6 * SECONDS_PER_DAY; + const [historicalBlock] = await utils.getBlocksByTime( + [historicalTimestamp], + chain + ); + + try { + const historicalData = await getRoundAtBlock( + aggregatorAddress, + chain, + historicalBlock + ); + + if (!historicalData) { + console.warn( + `MidasRWA: No historical price data available at block ${historicalBlock} for ${aggregatorAddress}` + ); + return null; + } + + // If same roundId, try previous round + if (historicalData.roundId === latestRound.roundId) { + console.warn( + `MidasRWA: Same roundId (${historicalData.roundId}) at historical block, trying previous round` + ); + + const previousRoundId = latestRound.roundId - 1; + const previousRound = await getRoundById( + aggregatorAddress, + chain, + previousRoundId + ); + + if (!previousRound) { + console.warn( + `MidasRWA: No previous round data available for round ${previousRoundId}` + ); + return null; + } + + return previousRound; + } + + return historicalData; + } catch (error) { + console.warn( + `MidasRWA: Failed to fetch historical price data at block ${historicalBlock} for ${aggregatorAddress}:`, + error.message + ); + return null; + } +} + +// Get latest and historical price data for APY calculation +async function getPriceData(aggregatorAddress, chain) { + try { + const latestRound = await getLatestRound(aggregatorAddress, chain); + + if (!latestRound) { + return null; + } + + // Skip if only first round available + if (latestRound.roundId === 1) { + console.warn( + `MidasRWA: Skipping ${aggregatorAddress} - only first round available (roundId: 1), no historical data` + ); + return null; + } + + const historicalRound = await getHistoricalPrice( + aggregatorAddress, + chain, + latestRound + ); + + if (!historicalRound) { + return null; + } + + return { + latest: latestRound, + historical: historicalRound, + }; + } catch (error) { + console.warn( + `MidasRWA: Failed to fetch price data for ${aggregatorAddress}:`, + error.message + ); + return null; + } +} + +module.exports = { + getAggregatorAddress, + getPriceData, +}; diff --git a/src/adaptors/midas-rwa/computeAPY.js b/src/adaptors/midas-rwa/computeAPY.js new file mode 100644 index 0000000000..26a369b1d2 --- /dev/null +++ b/src/adaptors/midas-rwa/computeAPY.js @@ -0,0 +1,29 @@ +const { formatUnits } = require('ethers/lib/utils'); + +const SECONDS_PER_DAY = 86400; + +function computeAPY(tokenData) { + try { + const current = Number(formatUnits(tokenData.currentPrice, 18)); + const historical = Number(formatUnits(tokenData.historicalPrice, 18)); + + if (historical === 0) return 0; + + const growth = current / historical; + const days = + (tokenData.currentTimestamp - tokenData.historicalTimestamp) / + SECONDS_PER_DAY; + + if (days <= 0) return 0; + if (growth < 1) return 0; + + const annualizationFactor = 365 / days; + const apy = (Math.pow(growth, annualizationFactor) - 1) * 100; + + return Number(apy.toFixed(2)); + } catch (error) { + return 0; + } +} + +module.exports = { computeAPY }; diff --git a/src/adaptors/midas-rwa/convertPriceToUSD.js b/src/adaptors/midas-rwa/convertPriceToUSD.js new file mode 100644 index 0000000000..e944ce9c85 --- /dev/null +++ b/src/adaptors/midas-rwa/convertPriceToUSD.js @@ -0,0 +1,31 @@ +const { parseUnits } = require('ethers/lib/utils'); + +/** + * Converts token price from denomination to USD + * @param {string|BigInt} price - The price value (in base18 format) + * @param {string} denomination - The denomination (default: 'USD') + * @param {Object} baseAssetPrices - Base asset prices lookup + * @returns {BigInt} Converted price in USD (in base18 format) + */ +function convertPriceToUSD( + price, + denomination = 'USD', + baseAssetPrices = null +) { + const priceBigInt = BigInt(price); + + if (denomination === 'USD') { + return priceBigInt; + } + + if (baseAssetPrices && baseAssetPrices[denomination]) { + const basePriceBigInt = BigInt( + parseUnits(baseAssetPrices[denomination].toString(), 18) + ); + return (priceBigInt * basePriceBigInt) / BigInt(10 ** 18); + } + + return priceBigInt; +} + +module.exports = { convertPriceToUSD }; diff --git a/src/adaptors/midas-rwa/fetchBaseAssetPrices.js b/src/adaptors/midas-rwa/fetchBaseAssetPrices.js new file mode 100644 index 0000000000..de441c7afb --- /dev/null +++ b/src/adaptors/midas-rwa/fetchBaseAssetPrices.js @@ -0,0 +1,71 @@ +const sdk = require('@defillama/sdk'); +const { BASE_ASSET_ORACLES } = require('./addresses'); +const basicDataFeedAbi = require('./abi/basicDatafeedAbi.json'); +const { formatUnits } = require('ethers/lib/utils'); + +async function fetchBaseAssetPrices() { + const prices = {}; + + const oraclesByChain = Object.entries(BASE_ASSET_ORACLES).reduce( + (acc, [asset, config]) => { + if (!acc[config.chain]) { + acc[config.chain] = []; + } + acc[config.chain].push({ + asset, + address: config.address, + decimals: config.decimals, + }); + return acc; + }, + {} + ); + + const chainPromises = Object.entries(oraclesByChain).map( + async ([chain, oracles]) => { + try { + const multicallResult = await sdk.api.abi.multiCall({ + abi: basicDataFeedAbi.find((m) => m.name === 'latestRoundData'), + calls: oracles.map((oracle) => ({ + target: oracle.address, + })), + chain, + permitFailure: true, + }); + + const chainPrices = {}; + multicallResult.output.forEach((result, index) => { + const oracle = oracles[index]; + if (result.success && result.output && result.output[1]) { + const price = Number( + formatUnits(result.output[1], oracle.decimals) + ); + chainPrices[oracle.asset] = price; + } else { + console.warn( + `MidasRWA: Failed to fetch price for ${oracle.asset} on ${chain}` + ); + } + }); + + return chainPrices; + } catch (error) { + console.warn( + `MidasRWA: Failed to fetch prices for chain ${chain}:`, + error.message + ); + return {}; + } + } + ); + + const chainResults = await Promise.all(chainPromises); + + chainResults.forEach((chainPrices) => { + Object.assign(prices, chainPrices); + }); + + return prices; +} + +module.exports = { fetchBaseAssetPrices }; diff --git a/src/adaptors/midas-rwa/fetchTokenData.js b/src/adaptors/midas-rwa/fetchTokenData.js new file mode 100644 index 0000000000..968614f1a4 --- /dev/null +++ b/src/adaptors/midas-rwa/fetchTokenData.js @@ -0,0 +1,54 @@ +const { contractAddresses } = require('./addresses'); +const { fetchCurrentData, processToken } = require('./tokenHelpers'); + +// Fetch all token data for APY calculation +async function fetchTokenData(basePrices = null) { + const data = {}; + + const chainPromises = Object.entries(contractAddresses).map( + async ([chain, tokens]) => { + if (Object.keys(tokens).length === 0) { + return { chain, data: {} }; + } + + const { priceResults, supplyResults } = await fetchCurrentData( + chain, + tokens + ); + const chainData = {}; + + const tokenPromises = Object.entries(tokens).map( + async ([token, tokenData], index) => { + return processToken( + token, + tokenData, + chain, + priceResults.output[index], + supplyResults.output[index], + basePrices + ); + } + ); + + const tokenResults = await Promise.all(tokenPromises); + + tokenResults.forEach((result) => { + if (result) { + chainData[result.token] = result.data; + } + }); + + return { chain, data: chainData }; + } + ); + + const chainResults = await Promise.all(chainPromises); + + chainResults.forEach(({ chain, data: chainData }) => { + data[chain] = chainData; + }); + + return data; +} + +module.exports = { fetchTokenData }; diff --git a/src/adaptors/midas-rwa/index.js b/src/adaptors/midas-rwa/index.js new file mode 100644 index 0000000000..92b94428d9 --- /dev/null +++ b/src/adaptors/midas-rwa/index.js @@ -0,0 +1,53 @@ +const { computeAPY } = require('./computeAPY'); +const { contractAddresses } = require('./addresses'); +const { fetchBaseAssetPrices } = require('./fetchBaseAssetPrices'); +const { fetchTokenData } = require('./fetchTokenData'); +const { formatUnits } = require('ethers/lib/utils'); + +const poolsFunction = async () => { + try { + const baseAssetPrices = await fetchBaseAssetPrices(); + const data = await fetchTokenData(baseAssetPrices); + const results = []; + + for (const [chain, tokens] of Object.entries(contractAddresses)) { + for (const [token, tokenConfig] of Object.entries(tokens)) { + const tokenData = data[chain]?.[token]; + + if (!tokenData) { + console.warn(`MidasRWA: Missing data for ${token} on ${chain}`); + continue; + } + + const apy = computeAPY(tokenData); + + const rawTvl = + (tokenData.supply * tokenData.currentPrice) / BigInt(1e18); + const tvlUsd = Number(formatUnits(rawTvl, 18)); + + const result = { + pool: `${tokenConfig.address.toLowerCase()}-${chain.toLowerCase()}`, + chain, + project: 'midas-rwa', + symbol: token, + tvlUsd, + apyBase: apy, + url: tokenConfig.url, + }; + + results.push(result); + } + } + + return results; + } catch (error) { + console.error('MidasRWA: Error in poolsFunction:', error); + throw error; + } +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://midas.app/', +}; diff --git a/src/adaptors/midas-rwa/tokenHelpers.js b/src/adaptors/midas-rwa/tokenHelpers.js new file mode 100644 index 0000000000..a81e5121e6 --- /dev/null +++ b/src/adaptors/midas-rwa/tokenHelpers.js @@ -0,0 +1,120 @@ +const sdk = require('@defillama/sdk'); +const { convertPriceToUSD } = require('./convertPriceToUSD'); +const { getAggregatorAddress, getPriceData } = require('./chainlinkHelpers'); +const dataFeedAbi = require('./abi/dataFeedAbi.json'); +const erc20Abi = require('./abi/erc20Abi.json'); + +const PRICE_SCALE_FACTOR = BigInt(10 ** 10); + +// Fetch current prices and supply data +async function fetchCurrentData(chain, tokens) { + const priceCalls = []; + const supplyCalls = []; + + for (const [token, tokenData] of Object.entries(tokens)) { + priceCalls.push({ + target: tokenData.dataFeed, + params: [], + token, + }); + + supplyCalls.push({ + target: tokenData.address, + params: [], + token, + }); + } + + const [priceResults, supplyResults] = await Promise.all([ + sdk.api.abi.multiCall({ + abi: dataFeedAbi.find((m) => m.name === 'getDataInBase18'), + calls: priceCalls, + chain, + permitFailure: true, + }), + sdk.api.abi.multiCall({ + abi: erc20Abi.find((m) => m.name === 'totalSupply'), + calls: supplyCalls, + chain, + permitFailure: true, + }), + ]); + + return { priceResults, supplyResults }; +} + +// Convert Chainlink price to USD +function convertPrice(rawAnswer, denomination, basePrices) { + const priceBase18 = BigInt(rawAnswer.toString()) * PRICE_SCALE_FACTOR; + return convertPriceToUSD(priceBase18, denomination, basePrices); +} + +// Process single token data +async function processToken( + token, + tokenData, + chain, + priceResult, + supplyResult, + basePrices +) { + if (!priceResult?.success || !supplyResult?.success) { + console.warn( + `MidasRWA: Failed to fetch current data for ${token} on ${chain}, skipping` + ); + return null; + } + + const denomination = tokenData.denomination ?? 'USD'; + const currentPrice = convertPriceToUSD( + priceResult.output, + denomination, + basePrices + ); + const supply = BigInt(supplyResult.output); + + const aggregatorAddress = await getAggregatorAddress( + tokenData.dataFeed, + chain + ); + + if (!aggregatorAddress) { + console.warn( + `MidasRWA: No aggregator address found for ${token} on ${chain}, skipping` + ); + return null; + } + + const priceData = await getPriceData(aggregatorAddress, chain); + + if (!priceData) { + console.warn( + `MidasRWA: No price data found for ${token} on ${chain}, skipping` + ); + return null; + } + + return { + token, + data: { + currentPrice: convertPrice( + priceData.latest.answer, + denomination, + basePrices + ), + historicalPrice: convertPrice( + priceData.historical.answer, + denomination, + basePrices + ), + supply, + currentTimestamp: priceData.latest.updatedAt, + historicalTimestamp: priceData.historical.updatedAt, + }, + }; +} + +module.exports = { + fetchCurrentData, + processToken, +}; diff --git a/src/adaptors/mim-swap/index.ts b/src/adaptors/mim-swap/index.ts new file mode 100644 index 0000000000..f13835370a --- /dev/null +++ b/src/adaptors/mim-swap/index.ts @@ -0,0 +1,47 @@ +import type { MultiRewardFarmsApy } from '../abracadabra-spell/common'; +const { multiRewardFarmsApy } = require('../abracadabra-spell/common') as { multiRewardFarmsApy: MultiRewardFarmsApy }; + + +module.exports = { + timetravel: false, + apy: () => multiRewardFarmsApy({ + arbitrum: { + "0xc30911b52b5752447aB08615973e434c801CD652": { + pool: { + project: 'mim-swap', + underlyingTokens: [ + "0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A", // MIM + "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", // USDT + ], + symbol: 'MIM-USDT', + url: "https://app.abracadabra.money/#/pool/1/42161", + }, + }, + "0x280c64c4C4869CF2A6762EaDD4701360C1B11F97": { + pool: { + project: 'mim-swap', + underlyingTokens: [ + "0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A", // MIM + "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC + ], + symbol: 'MIM-USDC', + url: "https://app.abracadabra.money/#/pool/2/42161", + }, + }, + }, + kava: { + "0xcF4f8E9A113433046B990980ebce5c3fA883067f": { + pool: { + project: 'mim-swap', + underlyingTokens: [ + "0x471EE749bA270eb4c1165B5AD95E614947f6fCeb", // MIM + "0x919C1c267BC06a7039e03fcc2eF738525769109c", // USDT + ], + symbol: 'MIM-USDT', + url: "https://app.abracadabra.money/#/pool/1/2222", + }, + }, + }, + }), + url: 'https://app.abracadabra.money', +}; diff --git a/src/adaptors/minswap/index.js b/src/adaptors/minswap/index.js new file mode 100644 index 0000000000..cca3265961 --- /dev/null +++ b/src/adaptors/minswap/index.js @@ -0,0 +1,26 @@ +const axios = require('axios'); + +const API_URL = 'https://api-mainnet-prod.minswap.org/defillama/yield-server'; + +const apy = async () => { + const data = (await axios.get(API_URL)).data; + return data.map((d) => { + return { + pool: `${d.pool}-cardano`, + chain: "Cardano", + project: "minswap", + symbol: d.symbol, + tvlUsd: d.tvlUsd, + apyBase: d.apyBase, + apyReward: d.apyReward, + rewardTokens: d.rewardTokens, + poolMeta: d.poolMeta + }; + }); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.minswap.org/farm', +}; diff --git a/src/adaptors/minterest/index.js b/src/adaptors/minterest/index.js new file mode 100644 index 0000000000..18d1da1960 --- /dev/null +++ b/src/adaptors/minterest/index.js @@ -0,0 +1,242 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('../compound-v2/abi'); + +const COMPTROLLER_ADDRESS = '0xe53a90EFd263363993A3B41Aa29f7DaBde1a932D'; +const CHAIN = 'mantle'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'minterest'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'COMP', + address: '0xc00e94Cb662C3520282E6f5717214004A7f26888'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = + // for maker + underlyingTokens[i]?.toLowerCase() === + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2' + ? 'MKR' + : underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd) ?? null; + const apyRewardBorrow = + calcRewardApy(extraRewardsBorrow, totalBorrowUsd) ?? null; + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + + return poolReturned; + }); + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://mantle.minterest.com/', +}; diff --git a/src/adaptors/minto/index.js b/src/adaptors/minto/index.js new file mode 100644 index 0000000000..1fda6aa0fe --- /dev/null +++ b/src/adaptors/minto/index.js @@ -0,0 +1,48 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const staking = '0xe742FCE58484FF7be7835D95E350c23CE55A7E12'; +const minto = '0x410a56541bd912f9b60943fcb344f1e3d6f09567'; + +const poolsFunction = async () => { + const apyData = await utils.getData( + 'https://bsc-prod.minto.org/v1/stats/rewards' + ); + const totalStaked = + ( + await sdk.api.abi.call({ + target: staking, + abi: { + inputs: [], + name: 'totalStake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + chain: 'bsc', + }) + ).output / 1e18; + + const priceKey = `bsc:${minto}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const pool = { + pool: staking, + chain: utils.formatChain('binance'), + project: 'minto', + symbol: utils.formatSymbol('staking'), + tvlUsd: totalStaked * price, + apy: apyData.apy['365'], + }; + + return [pool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://minto.finance/staking', +}; diff --git a/src/adaptors/mixswap-finance/abis/lp.json b/src/adaptors/mixswap-finance/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/mixswap-finance/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/mixswap-finance/abis/masterchef.json b/src/adaptors/mixswap-finance/abis/masterchef.json new file mode 100644 index 0000000000..f9a03832ac --- /dev/null +++ b/src/adaptors/mixswap-finance/abis/masterchef.json @@ -0,0 +1,832 @@ +[ + { + "inputs": [ + { + "internalType": "contract MixSwapToken", + "name": "_MXS", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_devAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_marketingAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_marketingFeeBP", + "type": "uint16" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "commissionAmount", + "type": "uint256" + } + ], + "name": "ReferralCommissionPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetDevAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetFeeAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetMarketingAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "marketingFeeBP", + "type": "uint16" + } + ], + "name": "SetMarketingFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IMixSwapReferral", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetReferralAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mxsPerBlock", + "type": "uint256" + } + ], + "name": "UpdateEmissionRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAXIMUM_MARKETING_FEE_RATE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAXIMUM_REFERRAL_COMMISSION_RATE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MXS", + "outputs": [ + { + "internalType": "contract MixSwapToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_referrer", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marketingAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marketingFeeBP", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mxsPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingMxs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBEP20", + "name": "", + "type": "address" + } + ], + "name": "poolExistence", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accMxsPerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referral", + "outputs": [ + { + "internalType": "contract IMixSwapReferral", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referralCommissionRate", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devAddress", + "type": "address" + } + ], + "name": "setDevAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeAddress", + "type": "address" + } + ], + "name": "setFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_marketingAddress", + "type": "address" + } + ], + "name": "setMarketingAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_marketingFeeBP", + "type": "uint16" + } + ], + "name": "setMarketingFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMixSwapReferral", + "name": "_referral", + "type": "address" + } + ], + "name": "setReferralAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_referralCommissionRate", + "type": "uint16" + } + ], + "name": "setReferralCommissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_mxsPerBlock", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + } + ], + "name": "updateStartBlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/mixswap-finance/index.js b/src/adaptors/mixswap-finance/index.js new file mode 100644 index 0000000000..8577b56e09 --- /dev/null +++ b/src/adaptors/mixswap-finance/index.js @@ -0,0 +1,222 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const MXS_TOKEN = '0xb8b9e96e9576af04480ff26ee77d964b1996216e'; +const MASTERCHEF_ADDRESS = '0x775eead1076b149d5eb81065fcd18a3a5717085a'; +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = Math.floor((60 / BSC_BLOCK_TIME) * 60 * 24 * 365); + +const getMxsPriceBUSD = (reserves) => { + return reserves[1] / reserves[0]; +}; + +const getPairInfo = async (pair, tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + mxsPerBlock, + mxsPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const mxsPerYear = BLOCKS_PER_YEAR * mxsPerBlock; + return ((poolWeight * mxsPerYear * mxsPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const mxsPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'mxsPerBlock'), + }); + const normalizedmxsPerBlock = mxsPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter((e) => e.lpToken !== '0xB8b9e96E9576Af04480ff26eE77D964B1996216e'); + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const mxsPrice = getMxsPriceBUSD(reservesData[0]); + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + const poolsApy = []; + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedmxsPerBlock, + mxsPrice, + masterChefReservesUsd + ); + + poolsApy.push({ + pool: pool.lpToken, + chain: utils.formatChain('binance'), + project: 'mixswap-finance', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [MXS_TOKEN], + }); + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://mixswap.finance/', +}; diff --git a/src/adaptors/mm-finance-polygon/abis/lp.json b/src/adaptors/mm-finance-polygon/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/mm-finance-polygon/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/mm-finance-polygon/abis/masterchef.json b/src/adaptors/mm-finance-polygon/abis/masterchef.json new file mode 100644 index 0000000000..03c585ac8d --- /dev/null +++ b/src/adaptors/mm-finance-polygon/abis/masterchef.json @@ -0,0 +1,1011 @@ +[ + { + "inputs": [ + { + "internalType": "contract IMeerkatToken", + "name": "_meerkat", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_meerkatPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "DisableWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EnableWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "commissionAmount", + "type": "uint256" + } + ], + "name": "ReferralCommissionPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "meerkatPerBlock", + "type": "uint256" + } + ], + "name": "UpdateEmissionRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "UpdateGaugeController", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "controller", + "type": "uint256" + } + ], + "name": "UpdateNFTBoostRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "UpdateNFTController", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "whitelist", + "type": "bool" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAXIMUM_REFERRAL_COMMISSION_RATE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract NFTController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_referrer", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_nft", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_slot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "depositNFT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "disable", + "type": "bool" + } + ], + "name": "disableWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "flipWhitelistAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "gauge", + "outputs": [ + { + "internalType": "contract GaugeController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getBoostGauge", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getSlots", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getTokenIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "isWhitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "meerkat", + "outputs": [ + { + "internalType": "contract IMeerkatToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "meerkatPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "meerkatReferral", + "outputs": [ + { + "internalType": "contract IMeerkatReferral", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nftBoostRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingMeerkat", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBEP20", + "name": "", + "type": "address" + } + ], + "name": "poolExistence", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accMeerkatPerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxy", + "outputs": [ + { + "internalType": "contract ProxyMeerkat", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referralCommissionRate", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "setGaugeController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMeerkatReferral", + "name": "_meerkatReferral", + "type": "address" + } + ], + "name": "setMeerkatReferral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rate", + "type": "uint256" + } + ], + "name": "setNftBoostRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "setNftController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_referralCommissionRate", + "type": "uint16" + } + ], + "name": "setReferralCommissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "bool", + "name": "_on", + "type": "bool" + } + ], + "name": "setWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_meerkatPerBlock", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_slot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "withdrawNFT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/mm-finance-polygon/index.js b/src/adaptors/mm-finance-polygon/index.js new file mode 100644 index 0000000000..f8b46628bb --- /dev/null +++ b/src/adaptors/mm-finance-polygon/index.js @@ -0,0 +1,300 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const MMF_TOKEN = '0x22a31bD4cB694433B6de19e0aCC2899E553e9481'; +const MASTERCHEF_ADDRESS = '0xa2B417088D63400d211A4D5EB3C4C5363f834764'; +const BLOCK_TIME = 2.3; +const BLOCKS_PER_YEAR = Math.floor((60 / BLOCK_TIME) * 60 * 24 * 365); +const WEEKS_PER_YEAR = 52; +const FEE_RATE = 0.0017; + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint( + 'HTJcrXUUtrVFKyNHZH99ywRx3TQm5ChSFVbn3oBiqGq6' +); +const { request, gql, batchRequests } = require('graphql-request'); +const { chunk } = require('lodash'); +const pairQuery = gql` + query pairQuery($id_in: [ID!]) { + pairs(where: { id_in: $id_in }) { + id + token0 { + symbol + decimals + id + } + token1 { + symbol + decimals + id + } + } + } +`; + +const getPairInfo = async (pairs) => { + const pairInfo = await Promise.all( + chunk(pairs, 7).map((tokens) => + request(SUBGRAPH_URL, pairQuery, { + id_in: tokens.map((pair) => pair.toLowerCase()), + }) + ) + ); + + return pairInfo + .map(({ pairs }) => pairs) + .flat() + .reduce((acc, pair) => ({ ...acc, [pair.id.toLowerCase()]: pair }), {}); +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `polygon:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + rewardPerBlock, + rewardPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const rewardPerYear = BLOCKS_PER_YEAR * rewardPerBlock; + return ((poolWeight * rewardPerYear * rewardPrice) / reserveUSD) * 100; +}; + +const calculateApy2 = ( + poolInfo, + totalAllocPoint, + rewardPerBlock, + rewardPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const rewardPerYear = BLOCKS_PER_YEAR * (rewardPerBlock / 0.115); + return ((poolWeight * rewardPerYear * rewardPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, id: token0Address } = token0; + const { decimals: token1Decimals, id: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'polygon', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'polygon', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const mmoPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'polygon', + abi: masterChefABI.find((e) => e.name === 'meerkatPerBlock'), + }); + const normalizedmmoPerBlock = mmoPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'polygon', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter( + (e) => + e.lpToken !== '0x22a31bD4cB694433B6de19e0aCC2899E553e9481' && + e.lpToken !== '0x8b6828c1Bc28Ad187A4aB05f41F2AAC547d85132' && + e.lpToken !== '0x0d5665A2319526A117E68E38EBEA4610aA8298F8' && + e.lpToken !== '0x8C9a93e198BC02ef48E8d7AEC3c042c5b00a4Ad3' + ); + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'polygon', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'polygon', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1, MMF_TOKEN]); + + const pairsInfo = await getPairInfo(lpTokens); + + const lpChunks = chunk(lpTokens, 10); + + const pairVolumes = await Promise.all( + lpChunks.map((lpsChunk) => + request( + SUBGRAPH_URL, + gql` + query volumesQuery { + ${lpsChunk + .slice(0, 10) + .map( + (token, i) => `token_${token.toLowerCase()}:pairDayDatas( + orderBy: date + orderDirection: desc + first: 7 + where: { pairAddress: "${token.toLowerCase()}" } + ) { + dailyVolumeUSD + }` + ) + .join('\n')} + + } + ` + ) + ) + ); + + const volumesMap = pairVolumes.flat().reduce( + (acc, curChunk) => ({ + ...acc, + ...Object.entries(curChunk).reduce((innerAcc, [key, val]) => ({ + ...innerAcc, + [key.split('_')[1]]: val, + })), + }), + {} + ); + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairsInfo[pool.lpToken.toLowerCase()]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + ?.div(1e18) + .toString(); + + const lpReservesUsd = calculateReservesUSD( + reserves, + 1, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + ?.div(1e18) + .toString(); + + const lpFees7D = + (volumesMap[pool.lpToken.toLowerCase()] || []).reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * FEE_RATE; + const apyBase = ((lpFees7D * WEEKS_PER_YEAR) / lpReservesUsd) * 100; + + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizedmmoPerBlock, + tokensPrices[MMF_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + return { + pool: pool.lpToken, + chain: utils.formatChain('polygon'), + project: 'mm-finance-polygon', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyBase, + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [MMF_TOKEN], + }; + }); + + return res.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://polymm.finance/farms', +}; diff --git a/src/adaptors/mmo-finance/MEtherInterfaceFull.json b/src/adaptors/mmo-finance/MEtherInterfaceFull.json new file mode 100644 index 0000000000..01a0c3d59b --- /dev/null +++ b/src/adaptors/mmo-finance/MEtherInterfaceFull.json @@ -0,0 +1,2150 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint240", + "name": "mTokenCollateral", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastBlockOfGracePeriod", + "type": "uint256" + } + ], + "name": "GracePeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mTokenBorrowed", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmountUnderlying", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mTokenCollateral", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmountUnderlying", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mTokenMinted", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountTokensMinted", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newAuctionGracePeriod", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPreferredLiquidatorHeadstart", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMinimumOfferMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidatorAuctionFeeMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolAuctionFeeMantissa", + "type": "uint256" + } + ], + "name": "NewGlobalAuctionParameters", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newInitialExchangeRateMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolSeizeShareMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowFeeMantissa", + "type": "uint256" + } + ], + "name": "NewGlobalProtocolParameters", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract MtrollerInterface", + "name": "oldMtroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract MtrollerInterface", + "name": "newMtroller", + "type": "address" + } + ], + "name": "NewMtroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract TokenAuction", + "name": "oldTokenAuction", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract TokenAuction", + "name": "newTokenAuction", + "type": "address" + } + ], + "name": "NewTokenAuction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingRedeemAmount", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountTokens", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": false, + "inputs": [], + "name": "_addReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + }, + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "_reduceReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_auctionGracePeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_preferredLiquidatorHeadstart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minimumOfferMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_liquidatorAuctionFeeMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_protocolAuctionFeeMantissa", + "type": "uint256" + } + ], + "name": "_setGlobalAuctionParameters", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_initialExchangeRateMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserveFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_protocolSeizeShareMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowFeeMantissa", + "type": "uint256" + } + ], + "name": "_setGlobalProtocolParameters", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "_setInterestRateModel", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract MtrollerInterface", + "name": "newMtroller", + "type": "address" + } + ], + "name": "_setMtroller", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract TokenAuction", + "name": "newTokenAuction", + "type": "address" + } + ], + "name": "_setTokenAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenContract", + "type": "address" + } + ], + "name": "_sweepERC20", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenID", + "type": "uint256" + } + ], + "name": "_sweepERC721", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "auctionGracePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "auctionMaxGracePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "auctionMinGracePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "borrowFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getAdmin", + "outputs": [ + { + "internalType": "address payable", + "name": "admin", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getProtocolAuctionFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getTokenType", + "outputs": [ + { + "internalType": "enum MTokenIdentifier.MTokenType", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "implementedSelectors", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "implementedSelectorsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract MtrollerInterface", + "name": "mtroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reserveFactorMantissa_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "protocolSeizeShareMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isMDelegatorAdminImplementation", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isMDelegatorUserImplementation", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "lastBlockGracePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mTokenCollateral", + "type": "uint240" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "liquidatorAuctionFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "liquidatorAuctionFeeMaxMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "mDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "mName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "mSymbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mTokenFromUnderlying", + "outputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "minimumOfferMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "minimumOfferMaxMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + } + ], + "name": "mintTo", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "mtroller", + "outputs": [ + { + "internalType": "contract MtrollerInterface", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "preferredLiquidator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "preferredLiquidatorHeadstart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "preferredLiquidatorMaxHeadstart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "protocolAuctionFeeMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "protocolAuctionFeeMaxMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint240", + "name": "mTokenBorrowed", + "type": "uint240" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint240", + "name": "mTokenCollateral", + "type": "uint240" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "thisFungibleMToken", + "outputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tokenAuction", + "outputs": [ + { + "internalType": "contract TokenAuction", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint240", + "name": "mToken", + "type": "uint240" + } + ], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "totalCashUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalCreatedMarkets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "underlyingContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint240", + "name": "", + "type": "uint240" + } + ], + "name": "underlyingIDs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/mmo-finance/index.js b/src/adaptors/mmo-finance/index.js new file mode 100644 index 0000000000..fb551bd4c2 --- /dev/null +++ b/src/adaptors/mmo-finance/index.js @@ -0,0 +1,128 @@ +const sdk = require('@defillama/sdk'); +const mEtherABI = require('./MEtherInterfaceFull.json'); +const superagent = require('superagent'); + +const mEtherAddresses = { + Glasses: '0xDdf26F3529CA4dC30f484b4F9d3A7ce0b7BD1562', + Milady: '0x9EAA40e8084F3C54B6E69C0A2ECaCF38cBf9b780', + Pudgy: '0x3bca3a1e6a573ca87cddf10eb49bb508a8188cb6', +}; + +const ETHAddr = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async (block) => { + const thisFungibleMTokenABI = mEtherABI.find( + (i) => i.name === 'thisFungibleMToken' + ); + + const mEtherIDCalls = Object.values(mEtherAddresses).map((mEtherAddr) => ({ + target: mEtherAddr, + })); + + const mEtherIDs = await sdk.api.abi.multiCall({ + abi: thisFungibleMTokenABI, + calls: mEtherIDCalls, + block: block, + }); + + const totalSupplyABI = mEtherABI.find((i) => i.name === 'totalSupply'); + + const totalSupplyCalls = Object.values(mEtherAddresses).map( + (mEtherAddr, idx) => ({ + target: mEtherAddr, + params: mEtherIDs.output[idx].output, + }) + ); + + const totalSupply = await sdk.api.abi.multiCall({ + abi: totalSupplyABI, + calls: totalSupplyCalls, + block: block, + }); + + const exchangeRateABI = mEtherABI.find( + (i) => i.name === 'exchangeRateStored' + ); + + const exchangeRateCalls = Object.values(mEtherAddresses).map( + (mEtherAddr, idx) => ({ + target: mEtherAddr, + params: mEtherIDs.output[idx].output, + }) + ); + + const exchangeRate = await sdk.api.abi.multiCall({ + abi: exchangeRateABI, + calls: exchangeRateCalls, + block: block, + }); + + const supplyAPYABI = mEtherABI.find((i) => i.name === 'supplyRatePerBlock'); + + const APYCalls = Object.values(mEtherAddresses).map((mEtherAddr, idx) => ({ + target: mEtherAddr, + params: mEtherIDs.output[idx].output, + })); + + const APY = await sdk.api.abi.multiCall({ + abi: supplyAPYABI, + calls: APYCalls, + block: block, + }); + + // pull token prices + const key = `ethereum:${ETHAddr}`.toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + + const ETHPrice = Number(prices[key].price); + + return [ + { + pool: mEtherAddresses.Glasses, + chain: 'Ethereum', + project: 'mmo-finance', + symbol: `Glasses-mETH`, + tvlUsd: + (((Number(totalSupply.output[0].output) / 10 ** 18) * + Number(exchangeRate.output[0].output)) / + 10 ** 18) * + ETHPrice, + apy: ((Number(APY.output[0].output) * 2102400) / 10 ** 18) * 100, + underlyingTokens: [mEtherAddresses.Glasses], + }, + { + pool: mEtherAddresses.Milady, + chain: 'Ethereum', + project: 'mmo-finance', + symbol: `Milady-mETH`, + tvlUsd: + (((Number(totalSupply.output[1].output) / 10 ** 18) * + Number(exchangeRate.output[1].output)) / + 10 ** 18) * + ETHPrice, + apy: ((Number(APY.output[1].output) * 2102400) / 10 ** 18) * 100, + underlyingTokens: [mEtherAddresses.Milady], + }, + { + pool: mEtherAddresses.Pudgy, + chain: 'Ethereum', + project: 'mmo-finance', + symbol: `Pudgy-mETH`, + tvlUsd: + (((Number(totalSupply.output[2].output) / 10 ** 18) * + Number(exchangeRate.output[2].output)) / + 10 ** 18) * + ETHPrice, + apy: ((Number(APY.output[2].output) * 2102400) / 10 ** 18) * 100, + underlyingTokens: [mEtherAddresses.Pudgy], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://mmo.finance/supply', +}; diff --git a/src/adaptors/moar-market/index.js b/src/adaptors/moar-market/index.js new file mode 100644 index 0000000000..44236f7f87 --- /dev/null +++ b/src/adaptors/moar-market/index.js @@ -0,0 +1,97 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const MOAR_APP_URL = 'https://app.moar.market'; +const MOAR_ADDRESS = "0xa3afc59243afb6deeac965d40b25d509bb3aebc12f502b8592c283070abc2e07"; +const MOAR_PACKAGE_OWNER_ADDRESS = "0x37e9ce6910ceadd16b0048250a33dac6342549acf31387278ea0f95c9057f110"; + +async function apy() { + const poolsConfig = await getAptosResource(MOAR_PACKAGE_OWNER_ADDRESS, `${MOAR_ADDRESS}::pool::PoolConfigs`) + const poolAddresses = poolsConfig['data']['all_pools']['inline_vec'].map(x => x['inner']) + + const pools = []; + let poolIndex = 0; + for (const poolAddress of poolAddresses) { + const poolData = (await getAptosResource(poolAddress, `${MOAR_ADDRESS}::pool::Pool`)).data + const underlyingAsset = poolData.underlying_asset.inner; + const rewardTokens = []; + let apyReward = null; + + const [faSymbol, interestRateResponse, incentivesEnabled] = await Promise.all([ + aptosView({ + functionStr: "0x1::fungible_asset::symbol", + type_arguments: ["0x1::fungible_asset::Metadata"], + args: [underlyingAsset]}), + aptosView({ + functionStr: `${MOAR_ADDRESS}::pool::get_interest_rate`, + type_arguments: [], + args: [poolIndex.toString()]}), + aptosView({ + functionStr: `${MOAR_ADDRESS}::farming::is_farming_enabled`, + type_arguments: [], + args: [`${poolAddress}-${poolIndex}`]}) + ]) + + if (incentivesEnabled) { + const incentiveRate = await aptosView({ + functionStr: `${MOAR_ADDRESS}::pool::get_farming_pool_apy`, + type_arguments: [], + args: [poolIndex.toString(), "APT-1"]}); + apyReward = Number(incentiveRate) / 1e6; + rewardTokens.push("0xa"); + } + const interestRate = interestRateResponse[0]; + + pools.push({ + pool: `${poolAddress}_aptos`, + chain: 'aptos', + project: 'moar-market', + apyBase: (interestRate / 1e8 * (1 - poolData.fee_on_interest_bps / 1e4)) * 100, + apyReward: apyReward, + apyBaseBorrow: interestRate / 1e8 * 100, + apyRewardBorrow: null, + totalSupplyUsd: await getUSDValue(poolData.total_deposited, underlyingAsset), + totalBorrowUsd: await getUSDValue(poolData.total_borrows, underlyingAsset), + rewardTokens: rewardTokens, + symbol: faSymbol, + tvlUsd: await getUSDValue(poolData.total_deposited - poolData.total_borrows, underlyingAsset), + underlyingTokens: [underlyingAsset], + url: `${MOAR_APP_URL}/lend/${faSymbol.toLowerCase()}`, + }) + poolIndex++; + } + + return pools; +} + +async function getUSDValue(amount, asset) { + const chainApi = new sdk.ChainApi({ chain: 'aptos' }) + chainApi.addToken(asset, amount) + const usdValue = await chainApi.getUSDValue() + return usdValue +} + +async function getAptosResource(address, resource) { + const response = await axios.get(`https://api.mainnet.aptoslabs.com/v1/accounts/${address}/resource/${resource}`) + return response.data +} + +async function aptosView({ functionStr, type_arguments = [], args = [], ledgerVersion = undefined }) { + let path = `https://api.mainnet.aptoslabs.com/v1/view` + if (ledgerVersion !== undefined) path += `?ledger_version=${ledgerVersion}` + const response = await axios.post(path, + { "function": functionStr, "type_arguments": type_arguments, arguments: args }, + { + headers: { + 'Content-Type': 'application/json', + }, + } + ) + return response.data.length === 1 ? response.data[0] : response.data +} + +module.exports = { + timetravel: true, + apy: apy, + url: `${MOAR_APP_URL}/lend`, +}; diff --git a/src/adaptors/mole/index.js b/src/adaptors/mole/index.js index 6b34c7d579..090ac71594 100644 --- a/src/adaptors/mole/index.js +++ b/src/adaptors/mole/index.js @@ -1,5 +1,5 @@ /* - * @Description: + * @Description: * @Autor: Econiche * @Date: 2022-06-06 09:36:02 * @LastEditors: Econiche @@ -8,10 +8,11 @@ const axios = require('axios'); const utils = require('../utils'); -axios.interceptors.request.use(config => { - config.headers["key"] = 'PgYaEZwSmjCQB74KIFN3f58LcuOoUhdv2t1XipJzWVnkrMGRT9H6exl0bqyDAs'; +axios.interceptors.request.use((config) => { + config.headers['key'] = + 'PgYaEZwSmjCQB74KIFN3f58LcuOoUhdv2t1XipJzWVnkrMGRT9H6exl0bqyDAs'; return config; -}) +}); function formatSymbol(sourceName) { const space = sourceName.indexOf(' '); @@ -23,21 +24,19 @@ function formatSymbol(sourceName) { async function apy(chain) { const response = ( - await axios.get( - `https://app.mole.fi/api/${chain}/data.json` - ) + await axios.get(`https://app.mole.fi/api/${chain}/data.json`) ).data; - const fairLaunchStakingPools = response.pools.filter( - (p) => !p.key.includes('debt') - ).map((p) => ({ - pool: `${p.address}-staking`, - chain: utils.formatChain(chainMapping[chain]), - project: 'mole', - symbol: utils.formatSymbol(p.symbol), - tvlUsd: Number(p.tvl), - apy: Number(p.apy) * 100, - })); + const fairLaunchStakingPools = response.pools + .filter((p) => !p.key.includes('debt')) + .map((p) => ({ + pool: `${p.address}-staking`, + chain: utils.formatChain(chainMapping[chain]), + project: 'mole', + symbol: utils.formatSymbol(p.symbol), + tvlUsd: Number(p.tvl), + apy: Number(p.apy) * 100, + })); const fundPools = response.funds.map((p) => ({ pool: `${p.key}-fund-pool`, @@ -55,7 +54,7 @@ async function apy(chain) { symbol: formatSymbol(p.sourceName), tvlUsd: Number(p.tvl), apy: utils.aprToApy( - (Number(p.farmRewardApr) + Number(p.tradingFeeApr)) / p.leverage * 100 + ((Number(p.farmRewardApr) + Number(p.tradingFeeApr)) / p.leverage) * 100 ), })); @@ -77,15 +76,16 @@ async function apy(chain) { } const chainMapping = { - '43114': 'avalanche', + 43114: 'avalanche', }; const main = async () => { const [avax] = await Promise.all([apy('43114')]); - return [...avax]; + return [...avax].filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: false, apy: main, -}; \ No newline at end of file + url: 'https://app.mole.fi/', +}; diff --git a/src/adaptors/molecular/index.js b/src/adaptors/molecular/index.js new file mode 100644 index 0000000000..5bfeae2da0 --- /dev/null +++ b/src/adaptors/molecular/index.js @@ -0,0 +1,74 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const POOL_APY_INFO_ADDRESS = '0xFa91728CD4E0E6aD91494118c922c9d68302DE37'; + +async function apy() { + let chain = 'arbitrum'; + let allPools = ( + await sdk.api.abi.call({ + target: POOL_APY_INFO_ADDRESS, + abi: abi.getAllPoolInfo, + chain, + }) + ).output; + + let coinsKey = allPools.map((pool) => `${chain}:${pool.asset}`); + let { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${coinsKey}` + ); + + let farmToTvls = {}; + let farmAddresses = {}; + allPools + .map((item) => item.farmAddress) + .forEach((item) => { + farmAddresses[item] = {}; + }); + + for (let item of Object.keys(farmAddresses)) { + let result = ( + await sdk.api.abi.call({ + target: item, + abi: abi.getPoolTotalTvl, + chain, + }) + ).output; + farmToTvls[item.toLowerCase()] = result; + } + + let d = allPools + .map((pool) => { + let tvlInfo = farmToTvls[pool.farmAddress.toLowerCase()].find( + (item) => item.pid == pool.pid + ); + let tvl = tvlInfo.tvl / 10 ** pool.assetDecimals; + let price = coins[`${chain}:${pool.asset}`].price; + let tvlPrice = tvl * price; + let apy = pool.apy / 10 ** 16; + return { + chain, + pool: `${pool.farmAddress}-${pool.asset}`, + symbol: pool.assetSymbol, + underlyingTokens: [pool.asset], + tvlUsd: tvlPrice, + apyBase: apy, + url: `https://molecular.finance/vault/${pool.farmAddress}/${pool.asset}`, + project: 'molecular', + }; + }) + .filter((item) => item.tvlUsd > 10000); + return d; +} + +let abi = { + getPoolTotalTvl: + 'function getPoolTotalTvl() view returns (tuple(uint256 pid, address assets, uint256 tvl)[])', + getAllPoolInfo: + 'function getAllPoolInfo() view returns (tuple(uint256 pid, address farmAddress, address asset, string assetSymbol, uint256 assetDecimals, address reward, uint256 apy)[])', +}; + +module.exports = { + apy: apy, + url: 'https://molecular.finance/vault', +}; diff --git a/src/adaptors/moola-market/index.js b/src/adaptors/moola-market/index.js new file mode 100644 index 0000000000..78dac1311e --- /dev/null +++ b/src/adaptors/moola-market/index.js @@ -0,0 +1,80 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + let poolData = []; + //Moola pools data + let apyData = await utils.getData( + 'https://v2-srv-data-frm-smrt-cntract.herokuapp.com/get/getReserveData' + ); + + const priceKeys = ['celo', 'celo-dollar', 'celo-euro', 'moola-market'] + .map((t) => `coingecko:${t}`) + .join(','); + let { coins: coinprices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + // Moola-Market API for cREAL price. + let mooPrices = await utils.getData( + 'https://v2-mooapi.herokuapp.com/get/getExchangeRates?userPublicKey=765DE816845861e75A25fCA122bb6898B8B1282a' + ); + + // Calcul cReal vs USD + let cRealPrice = + mooPrices['cREAL']['cUSD'] * coinprices['coingecko:celo-dollar'].price; + coinprices['celo-real'] = { usd: cRealPrice }; + + for (let coin in apyData.data) { + let newPool = {}; + newPool.chain = utils.formatChain('celo'); + newPool.project = 'moola-market'; + newPool.apyBase = apyData.data[coin].apy; + switch (apyData.data[coin].currency) { + case 'Celo': + newPool.tvlUsd = + Number(apyData.data[coin].availableLiquidity) * + coinprices['coingecko:celo'].price; + newPool.pool = '0x7D00cd74FF385c955EA3d79e47BF06bD7386387D'; + newPool.symbol = utils.formatSymbol('Celo'); + break; + case 'cUSD': + newPool.tvlUsd = + Number(apyData.data[coin].availableLiquidity) * + coinprices['coingecko:celo-dollar'].price; + newPool.pool = '0x918146359264C492BD6934071c6Bd31C854EDBc3'; + newPool.symbol = utils.formatSymbol('cUSD'); + break; + case 'cEUR': + newPool.tvlUsd = + Number(apyData.data[coin].availableLiquidity) * + coinprices['coingecko:celo-euro'].price; + newPool.pool = '0xE273Ad7ee11dCfAA87383aD5977EE1504aC07568'; + newPool.symbol = utils.formatSymbol('cEUR'); + break; + case 'cREAL': + newPool.tvlUsd = + Number(apyData.data[coin].availableLiquidity) * + coinprices['celo-real']['usd']; + newPool.pool = '0x9802d866fdE4563d088a6619F7CeF82C0B991A55'; + newPool.symbol = utils.formatSymbol('cREAL'); + break; + case 'Moo': + newPool.tvlUsd = + Number(apyData.data[coin].availableLiquidity) * + coinprices['coingecko:moola-market'].price; + newPool.pool = '0x3A5024E3AAB31A1d3184127B52b0e4B4E9ADcC34'; + newPool.symbol = utils.formatSymbol('Moo'); + break; + default: + break; + } + poolData.push(newPool); + } + return poolData; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.moola.market/', +}; diff --git a/src/adaptors/mooncake-finance/index.js b/src/adaptors/mooncake-finance/index.js new file mode 100755 index 0000000000..dd528fec83 --- /dev/null +++ b/src/adaptors/mooncake-finance/index.js @@ -0,0 +1,217 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const SECONDS_PER_YEAR = 31536000; + +const chainUrlParam = { + base: 'proto_base_v3', +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const API_URLS = { + base: 'https://api.studio.thegraph.com/query/51428/mooncakefi-base/version/latest', +}; + +const query = gql` + query ReservesQuery { + reserves(where: { name_not: "" }) { + name + borrowingEnabled + aToken { + id + rewards { + id + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + underlyingAssetAddress + underlyingAssetDecimals + } + vToken { + rewards { + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + } + symbol + liquidityRate + variableBorrowRate + baseLTVasCollateral + isFrozen + } + } +`; + +const apy = async () => { + let data = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await request(url, query)).reserves, + ]) + ); + + data = data.map(([chain, reserves]) => [ + chain, + reserves.filter((p) => !p.isFrozen), + ]); + + const totalSupply = await Promise.all( + data.map(async ([chain, reserves]) => { + return ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: reserves.map((reserve) => ({ + target: reserve.aToken.id, + })), + }) + ).output.map(({ output }) => output); + }) + ).catch((e) => console.log('err', e)); + + const underlyingBalances = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: reserves.map((reserve, i) => ({ + target: reserve.aToken.underlyingAssetAddress, + params: [reserve.aToken.id], + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingTokens = data.map(([chain, reserves]) => + reserves.map((pool) => `${chain}:${pool.aToken.underlyingAssetAddress}`) + ); + + const rewardTokens = data.map(([chain, reserves]) => + reserves.map((pool) => + pool.aToken.rewards.map((rew) => `${chain}:${rew.rewardToken}`) + ) + ); + + const { pricesByAddress, pricesBySymbol } = await getPrices( + underlyingTokens.flat().concat(rewardTokens.flat(Infinity)) + ); + + const pools = data.map(([chain, markets], i) => { + const chainPools = markets.map((pool, idx) => { + const supply = totalSupply[i][idx]; + const currentSupply = underlyingBalances[i][idx]; + const totalSupplyUsd = + (supply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const tvlUsd = + (currentSupply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const { rewards } = pool.aToken; + + const rewardPerYear = rewards.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + + const { rewards: rewardsBorrow } = pool.vToken; + const rewardPerYearBorrow = rewardsBorrow.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + totalBorrowUsd = totalBorrowUsd < 0 ? 0 : totalBorrowUsd; + + const supplyRewardEnd = pool.aToken.rewards[0]?.distributionEnd; + const borrowRewardEnd = pool.vToken.rewards[0]?.distributionEnd; + + return { + pool: `${pool.aToken.id}-${chain}`.toLowerCase(), + chain: utils.formatChain('base'), + project: 'mooncake-finance', + symbol: pool.symbol, + tvlUsd, + apyBase: (pool.liquidityRate / 10 ** 27) * 100, + apyReward: + supplyRewardEnd * 1000 > new Date() + ? (rewardPerYear / totalSupplyUsd) * 100 + : null, + rewardTokens: + supplyRewardEnd * 1000 > new Date() + ? rewards.map((rew) => rew.rewardToken) + : null, + underlyingTokens: [pool.aToken.underlyingAssetAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.variableBorrowRate) / 1e25, + apyRewardBorrow: + borrowRewardEnd * 1000 > new Date() + ? (rewardPerYearBorrow / totalBorrowUsd) * 100 + : null, + ltv: Number(pool.baseLTVasCollateral) / 10000, + url: `https://mooncake.fi/reserve-overview/?underlyingAsset=${pool.aToken.underlyingAssetAddress}&marketName=${chainUrlParam[chain]}&utm_source=defillama&utm_medium=listing&utm_campaign=external`, + borrowable: pool.borrowingEnabled, + }; + }); + + return chainPools; + }); + + return pools.flat().filter((p) => !!p.tvlUsd); +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/moonwell-apollo/abi.js b/src/adaptors/moonwell-apollo/abi.js new file mode 100644 index 0000000000..32aa68bf5b --- /dev/null +++ b/src/adaptors/moonwell-apollo/abi.js @@ -0,0 +1,2417 @@ +module.exports = { + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'rewardToken', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowRewardSpeed', + type: 'uint256', + }, + ], + name: 'BorrowRewardSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorWellSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'wellDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'wellBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'tokenType', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'wellDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'wellSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'oldGasAmount', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'newGasAmount', + type: 'uint16', + }, + ], + name: 'NewGasAmount', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'rewardToken', + type: 'uint8', + }, + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSupplyRewardSpeed', + type: 'uint256', + }, + ], + name: 'SupplyRewardSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WellGranted', + type: 'event', + }, + { payable: true, stateMutability: 'payable', type: 'fallback' }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address payable', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantWell', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint16', name: 'newGasAmount', type: 'uint16' }, + ], + name: '_setGasAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract MToken[]', + name: 'mTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + { internalType: 'uint256', name: 'supplyRewardSpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowRewardSpeed', type: 'uint256' }, + ], + name: '_setRewardSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract MToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract MToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'borrowRewardSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract MToken', name: 'mToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { internalType: 'address payable', name: 'holder', type: 'address' }, + { + internalType: 'contract MToken[]', + name: 'mTokens', + type: 'address[]', + }, + ], + name: 'claimReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint8', name: 'rewardType', type: 'uint8' }, + { + internalType: 'address payable[]', + name: 'holders', + type: 'address[]', + }, + { + internalType: 'contract MToken[]', + name: 'mTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimReward', + outputs: [], + payable: true, + stateMutability: 'payable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'mTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'gasAmount', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract MToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract MToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'mTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialIndexConstant', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'mTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'mTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'mTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'mTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isWelled', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rewardGlmr', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rewardWell', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'mTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'mTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newWellAddress', type: 'address' }, + ], + name: 'setWellAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'uint8', name: '', type: 'uint8' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'supplyRewardSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'wellAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + ercDelegator: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'mTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldProtocolSeizeShareMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: 'NewProtocolSeizeShare', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSeizeShareMantissa', + type: 'uint256', + }, + ], + name: '_setProtocolSeizeShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isMToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract MTokenInterface', + name: 'mTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/moonwell-apollo/index.js b/src/adaptors/moonwell-apollo/index.js new file mode 100644 index 0000000000..431fda110e --- /dev/null +++ b/src/adaptors/moonwell-apollo/index.js @@ -0,0 +1,285 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0x0b7a0EAA884849c6Af7a129e899536dDDcA4905E'; +const CHAIN = 'moonriver'; +const PRICING_CHAIN = 'moonriver:'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'supplyRewardSpeeds'; +const REWARD_SPEED_BORROW = 'borrowRewardSpeeds'; +const SUPPLY_RATE = 'supplyRatePerTimestamp'; +const BORROW_RATE = 'borrowRatePerTimestamp'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400; +const PROJECT_NAME = 'moonwell-apollo'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'MOVR', + address: '0x98878b06940ae243284ca214f92bb71a2b032b8a'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'MFAM', + address: '0xBb8d88bcD9749636BC4D2bE22aaC4Bb3B01A58F1'.toLowerCase(), +}; + +const ETH_TOKENS = { + WETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + FRAX: '0x853d955acef822db058eb8505911ed77f175b99e', + WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', +}; + +const ETH_TOKENS_LIST = Object.values(ETH_TOKENS).map( + (token) => `ethereum:${token}` +); + +const REWARD_TYPES = { + PROTOCOL_TOKEN: 0, + NATIVE_TOKEN: 1, +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardType, rewardSpeedMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [rewardType, market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardSpeedMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const getApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + // supply side + const protocolRewards = await getRewards( + allMarkets, + REWARD_TYPES.PROTOCOL_TOKEN, + REWARD_SPEED + ); + const nativeRewards = await getRewards( + allMarkets, + REWARD_TYPES.NATIVE_TOKEN, + REWARD_SPEED + ); + + // borrow side + const protocolRewardsBorrow = await getRewards( + allMarkets, + REWARD_TYPES.PROTOCOL_TOKEN, + REWARD_SPEED_BORROW + ); + const nativeRewardsBorrow = await getRewards( + allMarkets, + REWARD_TYPES.NATIVE_TOKEN, + REWARD_SPEED_BORROW + ); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([PROTOCOL_TOKEN.address, NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + .concat(ETH_TOKENS_LIST) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') + ? 1 + : prices[ETH_TOKENS[symbol]]; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const apyReward = + (((protocolRewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalSupplyUsd) * + 100; + + const apyNativeReward = + (((nativeRewards[i] / 10 ** NATIVE_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[NATIVE_TOKEN.address]) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((protocolRewardsBorrow[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + totalBorrowUsd) * + 100; + + const apyNativeRewardBorrow = + (((nativeRewardsBorrow[i] / 10 ** NATIVE_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[NATIVE_TOKEN.address]) / + totalBorrowUsd) * + 100; + + return { + pool: market, + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward: apyReward + apyNativeReward, + underlyingTokens: [token], + rewardTokens: [ + apyReward ? PROTOCOL_TOKEN.address : null, + apyNativeReward ? NATIVE_TOKEN.address : null, + ].filter(Boolean), + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: apyRewardBorrow + apyNativeRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return pools.filter(({ tvlUsd }) => !!tvlUsd); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://moonwell.fi/apollo/MOVR', +}; diff --git a/src/adaptors/moonwell-lending/abi.js b/src/adaptors/moonwell-lending/abi.js new file mode 100644 index 0000000000..4c44f0dd0a --- /dev/null +++ b/src/adaptors/moonwell-lending/abi.js @@ -0,0 +1,1882 @@ +module.exports = { + VIEWS_ABI: [ + { + "type": "function", + "name": "comptroller", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Comptroller" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getAllMarketsInfo", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Market[]", + "components": [ + { + "name": "market", + "type": "address", + "internalType": "address" + }, + { + "name": "isListed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mintPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "collateralFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "underlyingPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalBorrows", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalReserves", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "reserveFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "incentives", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.MarketIncentives[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "supplyIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getGovernanceTokenPrice", + "inputs": [], + "outputs": [ + { + "name": "_result", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getMarketIncentives", + "inputs": [ + { + "name": "market", + "type": "address", + "internalType": "contract MToken" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.MarketIncentives[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "supplyIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getMarketInfo", + "inputs": [ + { + "name": "_mToken", + "type": "address", + "internalType": "contract MToken" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Market", + "components": [ + { + "name": "market", + "type": "address", + "internalType": "address" + }, + { + "name": "isListed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mintPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "collateralFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "underlyingPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalBorrows", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalReserves", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "reserveFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "incentives", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.MarketIncentives[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "supplyIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getMarketsInfo", + "inputs": [ + { + "name": "_mTokens", + "type": "address[]", + "internalType": "contract MToken[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Market[]", + "components": [ + { + "name": "market", + "type": "address", + "internalType": "address" + }, + { + "name": "isListed", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyCap", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mintPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "borrowPaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "collateralFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "underlyingPrice", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalBorrows", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalReserves", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "cash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "exchangeRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "reserveFactor", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyRate", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "incentives", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.MarketIncentives[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "supplyIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowIncentivesPerSec", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getNativeTokenPrice", + "inputs": [], + "outputs": [ + { + "name": "_result", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getProtocolInfo", + "inputs": [], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.ProtocolInfo", + "components": [ + { + "name": "seizePaused", + "type": "bool", + "internalType": "bool" + }, + { + "name": "transferPaused", + "type": "bool", + "internalType": "bool" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getStakingInfo", + "inputs": [], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.StakingInfo", + "components": [ + { + "name": "cooldown", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "unstakeWindow", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "distributionEnd", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "emissionPerSecond", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "lastUpdateTimestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getTokensBalances", + "inputs": [ + { + "name": "_tokens", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Balances[]", + "components": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserBalances", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Balances[]", + "components": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserBorrowsBalances", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Balances[]", + "components": [ + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserClaimsVotingPower", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserMarketsMemberships", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Memberships[]", + "components": [ + { + "name": "membership", + "type": "bool", + "internalType": "bool" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserRewards", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct BaseMoonwellViews.Rewards[]", + "components": [ + { + "name": "market", + "type": "address", + "internalType": "address" + }, + { + "name": "rewardToken", + "type": "address", + "internalType": "address" + }, + { + "name": "supplyRewardsAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowRewardsAmount", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserStakingInfo", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.UserStakingInfo", + "components": [ + { + "name": "cooldown", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "pendingRewards", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalStaked", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserStakingVotingPower", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserTokensVotingPower", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUserVotingPower", + "inputs": [ + { + "name": "_user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_result", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.UserVotes", + "components": [ + { + "name": "claimsVotes", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + }, + { + "name": "stakingVotes", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + }, + { + "name": "tokenVotes", + "type": "tuple", + "internalType": "struct BaseMoonwellViews.Votes", + "components": [ + { + "name": "delegatedVotingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "votingPower", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "delegates", + "type": "address", + "internalType": "address" + } + ] + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "governanceToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Well" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_comptroller", + "type": "address", + "internalType": "address" + }, + { + "name": "tokenSaleDistributor", + "type": "address", + "internalType": "address" + }, + { + "name": "safetyModule", + "type": "address", + "internalType": "address" + }, + { + "name": "_governanceToken", + "type": "address", + "internalType": "address" + }, + { + "name": "nativeMarket", + "type": "address", + "internalType": "address" + }, + { + "name": "governanceTokenLP", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + } + ], + MRD_ABI: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalAccrued', + type: 'uint256' + } + ], + name: 'DisbursedBorrowerRewards', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalAccrued', + type: 'uint256' + } + ], + name: 'DisbursedSupplierRewards', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256' + } + ], + name: 'FundsRescued', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newIndex', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint32', + name: 'newTimestamp', + type: 'uint32' + } + ], + name: 'GlobalBorrowIndexUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSupplyIndex', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint32', + name: 'newSupplyGlobalTimestamp', + type: 'uint32' + } + ], + name: 'GlobalSupplyIndexUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8' + } + ], + name: 'Initialized', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address payable', + name: 'user', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'rewardToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256' + } + ], + name: 'InsufficientTokensToEmit', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldRewardSpeed', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRewardSpeed', + type: 'uint256' + } + ], + name: 'NewBorrowRewardSpeed', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'supplySpeed', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowSpeed', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'endTime', + type: 'uint256' + } + ], + name: 'NewConfigCreated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldEmissionCap', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newEmissionCap', + type: 'uint256' + } + ], + name: 'NewEmissionCap', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'currentOwner', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'NewEmissionConfigOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address' + } + ], + name: 'NewPauseGuardian', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'currentEndTime', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newEndTime', + type: 'uint256' + } + ], + name: 'NewRewardEndTime', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract MToken', + name: 'mToken', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldRewardSpeed', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRewardSpeed', + type: 'uint256' + } + ], + name: 'NewSupplyRewardSpeed', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address' + } + ], + name: 'Paused', + type: 'event' + }, + { anonymous: false, inputs: [], name: 'RewardsPaused', type: 'event' }, + { anonymous: false, inputs: [], name: 'RewardsUnpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address' + } + ], + name: 'Unpaused', + type: 'event' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' }, + { + internalType: 'uint256', + name: '_supplyEmissionPerSec', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_borrowEmissionsPerSec', + type: 'uint256' + }, + { internalType: 'uint256', name: '_endTime', type: 'uint256' } + ], + name: '_addEmissionConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: '_pauseRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_tokenAddress', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' } + ], + name: '_rescueFunds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_newEmissionCap', type: 'uint256' } + ], + name: '_setEmissionCap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_newPauseGuardian', type: 'address' } + ], + name: '_setPauseGuardian', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: '_unpauseRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' }, + { internalType: 'uint256', name: '_newBorrowSpeed', type: 'uint256' } + ], + name: '_updateBorrowSpeed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' }, + { internalType: 'uint256', name: '_newEndTime', type: 'uint256' } + ], + name: '_updateEndTime', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' }, + { internalType: 'address', name: '_newOwner', type: 'address' } + ], + name: '_updateOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' }, + { internalType: 'uint256', name: '_newSupplySpeed', type: 'uint256' } + ], + name: '_updateSupplySpeed', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'comptroller', + outputs: [ + { internalType: 'contract Comptroller', name: '', type: 'address' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_borrower', type: 'address' }, + { internalType: 'bool', name: '_sendTokens', type: 'bool' } + ], + name: 'disburseBorrowerRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_supplier', type: 'address' }, + { internalType: 'bool', name: '_sendTokens', type: 'bool' } + ], + name: 'disburseSupplierRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'emissionCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' } + ], + name: 'getAllMarketConfigs', + outputs: [ + { + components: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'emissionToken', type: 'address' }, + { internalType: 'uint256', name: 'endTime', type: 'uint256' }, + { + internalType: 'uint224', + name: 'supplyGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'supplyGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint224', + name: 'borrowGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'borrowGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint256', + name: 'supplyEmissionsPerSec', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'borrowEmissionsPerSec', + type: 'uint256' + } + ], + internalType: 'struct MultiRewardDistributorCommon.MarketConfig[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' } + ], + name: 'getConfigForMarket', + outputs: [ + { + components: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'emissionToken', type: 'address' }, + { internalType: 'uint256', name: 'endTime', type: 'uint256' }, + { + internalType: 'uint224', + name: 'supplyGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'supplyGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint224', + name: 'borrowGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'borrowGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint256', + name: 'supplyEmissionsPerSec', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'borrowEmissionsPerSec', + type: 'uint256' + } + ], + internalType: 'struct MultiRewardDistributorCommon.MarketConfig', + name: '', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getCurrentEmissionCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_emissionToken', type: 'address' } + ], + name: 'getCurrentOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'uint256', name: 'index', type: 'uint256' } + ], + name: 'getGlobalBorrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { internalType: 'uint256', name: 'index', type: 'uint256' } + ], + name: 'getGlobalSupplyIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_user', type: 'address' } + ], + name: 'getOutstandingRewardsForUser', + outputs: [ + { + components: [ + { internalType: 'address', name: 'emissionToken', type: 'address' }, + { internalType: 'uint256', name: 'totalAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'supplySide', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowSide', type: 'uint256' } + ], + internalType: 'struct MultiRewardDistributorCommon.RewardInfo[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'getOutstandingRewardsForUser', + outputs: [ + { + components: [ + { internalType: 'address', name: 'mToken', type: 'address' }, + { + components: [ + { + internalType: 'address', + name: 'emissionToken', + type: 'address' + }, + { + internalType: 'uint256', + name: 'totalAmount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'supplySide', + type: 'uint256' + }, + { internalType: 'uint256', name: 'borrowSide', type: 'uint256' } + ], + internalType: 'struct MultiRewardDistributorCommon.RewardInfo[]', + name: 'rewards', + type: 'tuple[]' + } + ], + internalType: + 'struct MultiRewardDistributorCommon.RewardWithMToken[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'initialIndexConstant', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_comptroller', type: 'address' }, + { internalType: 'address', name: '_pauseGuardian', type: 'address' } + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' } + ], + name: 'marketConfigs', + outputs: [ + { + components: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'emissionToken', type: 'address' }, + { internalType: 'uint256', name: 'endTime', type: 'uint256' }, + { + internalType: 'uint224', + name: 'supplyGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'supplyGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint224', + name: 'borrowGlobalIndex', + type: 'uint224' + }, + { + internalType: 'uint32', + name: 'borrowGlobalTimestamp', + type: 'uint32' + }, + { + internalType: 'uint256', + name: 'supplyEmissionsPerSec', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'borrowEmissionsPerSec', + type: 'uint256' + } + ], + internalType: 'struct MultiRewardDistributorCommon.MarketConfig', + name: 'config', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' } + ], + name: 'updateMarketBorrowIndex', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_borrower', type: 'address' }, + { internalType: 'bool', name: '_sendTokens', type: 'bool' } + ], + name: 'updateMarketBorrowIndexAndDisburseBorrowerRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' } + ], + name: 'updateMarketSupplyIndex', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'contract MToken', name: '_mToken', type: 'address' }, + { internalType: 'address', name: '_supplier', type: 'address' }, + { internalType: 'bool', name: '_sendTokens', type: 'bool' } + ], + name: 'updateMarketSupplyIndexAndDisburseSupplierRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } + ] +} diff --git a/src/adaptors/moonwell-lending/index.js b/src/adaptors/moonwell-lending/index.js new file mode 100644 index 0000000000..4ba710d68a --- /dev/null +++ b/src/adaptors/moonwell-lending/index.js @@ -0,0 +1,742 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { request, gql, batchRequests } = require('graphql-request'); +const { MRD_ABI, VIEWS_ABI } = require('./abi'); +const axios = require('axios'); + +const BASE_MRD_CONTRACT = '0xe9005b078701e2A0948D2EaC43010D35870Ad9d2'; +const OPTIMISM_MRD_CONTRACT = '0xF9524bfa18C19C3E605FbfE8DFd05C6e967574Aa'; +const MOONBEAM_VIEWS_CONTRACT = '0xe76C8B8706faC85a8Fbdcac3C42e3E7823c73994'; +const BASE_VIEWS_CONTRACT = '0x821Ff3a967b39bcbE8A018a9b1563EAf878bad39'; +const OPTIMISM_VIEWS_CONTRACT = '0xD6C66868f937f00604d0FB860241970D6CC2CBfE'; + +const SECONDS_PER_DAY = 86400; +const DAYS_PER_YEAR = 365; +const NOW = new Date().getTime() / 1000; + +const getPrices = async (addresses) => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: { + decimals: price.decimals, + symbol: price.symbol, + price: price.price, + }, + }), + {} + ); + + return pricesByAddress; +}; + +const multicallMRD = async (markets, network) => { + return ( + await sdk.api.abi.multiCall({ + chain: network, + calls: markets.map((market) => ({ + target: network == 'base' ? BASE_MRD_CONTRACT : OPTIMISM_MRD_CONTRACT, + params: [market], + })), + abi: MRD_ABI.find(({ name }) => name === 'getAllMarketConfigs'), + }) + ).output.map(({ output }) => output); +}; + +const multicallViews = async (network) => { + return ( + await sdk.api.abi.multiCall({ + chain: network, + calls: [ + { + target: + network == 'moonbeam' + ? MOONBEAM_VIEWS_CONTRACT + : network == 'base' + ? BASE_VIEWS_CONTRACT + : OPTIMISM_VIEWS_CONTRACT, + params: [], + }, + ], + abi: VIEWS_ABI.find(({ name }) => name === 'getAllMarketsInfo'), + }) + ).output.map(({ output }) => output); +}; + +const API_URL = 'https://ponder.moonwell.fi/'; + +const query = gql` + { + markets(limit: 1000) { + items { + id + address + chainId + collateralFactor + interestRateModelAddress + priceFeedAddress + reserveFactor + underlyingTokenAddress + } + } + tokens(limit: 1000) { + items { + id + address + chainId + symbol + decimals + } + } + } +`; + +const getApy = async () => { + const ponder_markets_res = await request(API_URL, query); + + const ponder_markets = ponder_markets_res.markets.items; + const ponder_tokens = ponder_markets_res.tokens.items; + + const moonbeam_markets = await multicallViews('moonbeam'); + let moonbeamResults; + + if (moonbeam_markets && moonbeam_markets.length == 1) { + const moonbeam_markets_data = moonbeam_markets[0]; + + moonbeamResults = moonbeam_markets_data + .filter((pool) => pool.isListed) + .map((pool) => { + const { + market, + collateralFactor, + underlyingPrice, + totalSupply, + totalBorrows, + exchangeRate, + borrowRate, + supplyRate, + } = pool; + + const market_info = ponder_markets.find( + (r) => + r.address.toLowerCase() == market.toLowerCase() && r.chainId == 1284 + ); + if ( + !market_info || + typeof market_info.underlyingTokenAddress !== 'string' + ) + return null; + + const token_info = ponder_tokens.find( + (r) => + r.address.toLowerCase() == + market_info.underlyingTokenAddress.toLowerCase() && + r.chainId == 1284 + ); + if ( + !token_info || + token_info.decimals === undefined || + token_info.decimals === null + ) + return null; + + const totalSupplyScaled = Number(totalSupply) / Math.pow(10, 8); + const totalBorrowsScaled = + Number(totalBorrows) / Math.pow(10, token_info.decimals); + const exchangeRateScaled = + Number(exchangeRate) / Math.pow(10, token_info.decimals + 10); + const underlyingPriceScaled = + Number(underlyingPrice) / Math.pow(10, 36 - token_info.decimals); + + const totalSupplyUsd = + Number(totalSupplyScaled) * + Number(exchangeRateScaled) * + underlyingPriceScaled; + const totalBorrowUsd = + Number(totalBorrowsScaled) * underlyingPriceScaled; + + const supplyRateScaled = Number(supplyRate) / Math.pow(10, 18); + const borrowRateScaled = Number(borrowRate) / Math.pow(10, 18); + const collateralFactorScaled = + Number(collateralFactor) / Math.pow(10, 18); + + const supplyApy = + ((supplyRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + const borrowApy = + ((borrowRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + + return { + pool: `${market.toLowerCase()}-moonbeam`, + chain: utils.formatChain('moonbeam'), + project: 'moonwell-lending', + symbol: token_info.symbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyApy, + apyReward: 0, + underlyingTokens: [ + market_info.underlyingTokenAddress.toLowerCase() === + '0x0000000000000000000000000000000000000000' + ? '0xAcc15dC74880C9944775448304B263D191c6077F'.toLowerCase() + : market_info.underlyingTokenAddress.toLowerCase(), + ], + rewardTokens: [ + '0x511ab53f793683763e5a8829738301368a2411e3', + '0xacc15dc74880c9944775448304b263d191c6077f', + ], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: borrowApy, + apyRewardBorrow: 0, + ltv: collateralFactorScaled, + incentives: [], //helper + }; + }) + .filter(Boolean) + .filter((e) => e.ltv); + } + + moonbeamResults = moonbeamResults || []; + + let moonbeam_incentives = {}; + if (moonbeam_markets && moonbeam_markets.length == 1) { + const moonbeam_markets_data = moonbeam_markets[0]; + for (const _market of moonbeam_markets_data) { + const _incentives = _market[17]; // incentives + moonbeam_incentives[_market[0].toLowerCase()] = _incentives.map((i) => { + return { + rewardToken: i[0].toLowerCase(), + supplyIncentivesPerSec: i[1], + borrowIncentivesPerSec: i[2], + }; + }); + } + } + + const moonbeam_prices_id = Object.values(moonbeam_incentives) + .flat() + .reduce((prev, curr) => { + let _emissionToken = curr.rewardToken; + let lookup; + if ( + _emissionToken.toLowerCase() == + '0xff8adec2221f9f4d8dfbafa6b9a297d17603493d' + ) { + //WELL base -> WELL moonbeam + lookup = `moonbeam:0x511ab53f793683763e5a8829738301368a2411e3`; + } else { + lookup = `moonbeam:${_emissionToken}`; + } + return { + ...prev, + [_emissionToken]: lookup, + }; + }, {}); + + const moonbeam_prices = await getPrices(Object.values(moonbeam_prices_id)); + + for (let market of moonbeamResults) { + let marketRewards = moonbeam_incentives[market.pool.split('-')[0]]; + + for (let marketWithRewards of marketRewards) { + const { + rewardToken: _emissionToken, + supplyIncentivesPerSec: _supplyEmissionsPerSec, + borrowIncentivesPerSec: _borrowEmissionsPerSec, + } = marketWithRewards; + + let token_info = moonbeam_prices[_emissionToken.toLowerCase()]; + + if (!token_info) continue; + let price = token_info.price; + let decimals = token_info.decimals; + let symbol = token_info.symbol; + + const supplyRewardsPerDay = + (_supplyEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const supplyRewardsPerDayUSD = supplyRewardsPerDay * price; + + const borrowRewardsPerDay = + (_borrowEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const borrowRewardsPerDayUSD = borrowRewardsPerDay * price; + + market.incentives.push({ + address: _emissionToken, + supplyRewardsAPR: + market.totalSupplyUsd > 0 + ? (supplyRewardsPerDayUSD / market.totalSupplyUsd) * + DAYS_PER_YEAR * + 100 + : 0, + borrowRewardsAPR: + market.totalBorrowUsd > 0 + ? (borrowRewardsPerDayUSD / market.totalBorrowUsd) * + DAYS_PER_YEAR * + 100 + : 0, + }); + } + } + + for (let market of moonbeamResults) { + const supplyIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.supplyRewardsAPR, + 0 + ); + + const borrowIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.borrowRewardsAPR, + 0 + ); + + market.rewardTokens = market.incentives.map((r) => r.address); + market.apyReward = supplyIncentivesAPR; + market.apyRewardBorrow = parseFloat( + Math.abs(borrowIncentivesAPR).toFixed(6) + ); + + delete market.incentives; + } + + const base_markets = await multicallViews('base'); + let baseResults; + + if (base_markets && base_markets.length == 1) { + const base_markets_data = base_markets[0]; + + baseResults = base_markets_data + .filter((pool) => pool.isListed) + .map((pool) => { + const { + market, + collateralFactor, + underlyingPrice, + totalSupply, + totalBorrows, + exchangeRate, + borrowRate, + supplyRate, + } = pool; + + const market_info = ponder_markets.find( + (r) => + r.address.toLowerCase() == market.toLowerCase() && r.chainId == 8453 + ); + if ( + !market_info || + typeof market_info.underlyingTokenAddress !== 'string' + ) + return null; + + const token_info = ponder_tokens.find( + (r) => + r.address.toLowerCase() == + market_info.underlyingTokenAddress.toLowerCase() && + r.chainId == 8453 + ); + if ( + !token_info || + token_info.decimals === undefined || + token_info.decimals === null + ) + return null; + + const totalSupplyScaled = Number(totalSupply) / Math.pow(10, 8); + const totalBorrowsScaled = + Number(totalBorrows) / Math.pow(10, token_info.decimals); + const exchangeRateScaled = + Number(exchangeRate) / Math.pow(10, token_info.decimals + 10); + const underlyingPriceScaled = + Number(underlyingPrice) / Math.pow(10, 36 - token_info.decimals); + + const totalSupplyUsd = + Number(totalSupplyScaled) * + Number(exchangeRateScaled) * + underlyingPriceScaled; + const totalBorrowUsd = + Number(totalBorrowsScaled) * underlyingPriceScaled; + + const supplyRateScaled = Number(supplyRate) / Math.pow(10, 18); + const borrowRateScaled = Number(borrowRate) / Math.pow(10, 18); + const collateralFactorScaled = + Number(collateralFactor) / Math.pow(10, 18); + + const supplyApy = + ((supplyRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + const borrowApy = + ((borrowRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + + return { + pool: `${market.toLowerCase()}-base`, + chain: utils.formatChain('base'), + project: 'moonwell-lending', + symbol: token_info.symbol == 'WETH' ? 'ETH' : token_info.symbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyApy, + apyReward: 0, + underlyingTokens: [token_info.address], + rewardTokens: [], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: borrowApy, + apyRewardBorrow: 0, + ltv: Number(collateralFactorScaled), + incentives: [], //helper + }; + }) + .filter(Boolean) + .filter((e) => e.ltv); + } + + baseResults = baseResults || []; + + const mrd_markets = await multicallMRD( + baseResults.map((r) => r.pool.split('-')[0]), + 'base' + ); + + const prices_id = mrd_markets.flat().reduce((prev, curr) => { + const [ + _owner, + _emissionToken, + _endTime, + _supplyGlobalIndex, + _supplyGlobalTimestamp, + _borrowGlobalIndex, + _borrowGlobalTimestamp, + _supplyEmissionsPerSec, + _borrowEmissionsPerSec, + ] = curr; + + let lookup; + if ( + _emissionToken.toLowerCase() == + '0xff8adec2221f9f4d8dfbafa6b9a297d17603493d' + ) { + //WELL base -> WELL moonbeam + lookup = `moonbeam:0x511ab53f793683763e5a8829738301368a2411e3`; + } else { + lookup = `base:${_emissionToken}`; + } + return { + ...prev, + [_emissionToken]: lookup, + }; + }, {}); + + const mrd_prices = await getPrices(Object.values(prices_id)); + + let marketIdx = 0; + for (let market of baseResults) { + let marketRewards = mrd_markets[marketIdx]; + for (let marketWithRewards of marketRewards) { + const [ + _owner, + _emissionToken, + _endTime, + _supplyGlobalIndex, + _supplyGlobalTimestamp, + _borrowGlobalIndex, + _borrowGlobalTimestamp, + _supplyEmissionsPerSec, + _borrowEmissionsPerSec, + ] = marketWithRewards; + + let token_info; + if ( + _emissionToken.toLowerCase() == + '0xff8adec2221f9f4d8dfbafa6b9a297d17603493d' + ) { + //WELL base -> WELL moonbeam + token_info = mrd_prices['0x511ab53f793683763e5a8829738301368a2411e3']; + } else { + token_info = mrd_prices[_emissionToken.toLowerCase()]; + } + + if (!token_info) continue; + + let price = token_info.price; + let decimals = token_info.decimals; + let symbol = token_info.symbol; + + //only active + if (_endTime > NOW) { + const supplyRewardsPerDay = + (_supplyEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const supplyRewardsPerDayUSD = supplyRewardsPerDay * price; + + const borrowRewardsPerDay = + (_borrowEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const borrowRewardsPerDayUSD = borrowRewardsPerDay * price; + + market.incentives.push({ + address: _emissionToken, + supplyRewardsAPR: + market.totalSupplyUsd > 0 + ? (supplyRewardsPerDayUSD / market.totalSupplyUsd) * + DAYS_PER_YEAR * + 100 + : 0, + borrowRewardsAPR: + market.totalBorrowUsd > 0 + ? (borrowRewardsPerDayUSD / market.totalBorrowUsd) * + DAYS_PER_YEAR * + 100 + : 0, + }); + } + } + marketIdx++; + } + + for (let market of baseResults) { + const supplyIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.supplyRewardsAPR, + 0 + ); + + const borrowIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.borrowRewardsAPR, + 0 + ); + + market.rewardTokens = market.incentives.map((r) => r.address); + market.apyReward = supplyIncentivesAPR; + market.apyRewardBorrow = parseFloat( + Math.abs(borrowIncentivesAPR).toFixed(6) + ); + + delete market.incentives; + } + + //Optimism + const optimism_markets = await multicallViews('optimism'); + let optimismResults; + + if (optimism_markets && optimism_markets.length == 1) { + const optimism_markets_data = optimism_markets[0]; + + optimismResults = optimism_markets_data + .filter((pool) => pool.isListed) + .map((pool) => { + const { + market, + collateralFactor, + underlyingPrice, + totalSupply, + totalBorrows, + exchangeRate, + borrowRate, + supplyRate, + } = pool; + + const market_info = ponder_markets.find( + (r) => + r.address.toLowerCase() == market.toLowerCase() && r.chainId == 10 + ); + if ( + !market_info || + typeof market_info.underlyingTokenAddress !== 'string' + ) + return null; + + const token_info = ponder_tokens.find( + (r) => + r.address.toLowerCase() == + market_info.underlyingTokenAddress.toLowerCase() && + r.chainId == 10 + ); + if ( + !token_info || + token_info.decimals === undefined || + token_info.decimals === null + ) + return null; + + const totalSupplyScaled = Number(totalSupply) / Math.pow(10, 8); + const totalBorrowsScaled = + Number(totalBorrows) / Math.pow(10, token_info.decimals); + const exchangeRateScaled = + Number(exchangeRate) / Math.pow(10, token_info.decimals + 10); + const underlyingPriceScaled = + Number(underlyingPrice) / Math.pow(10, 36 - token_info.decimals); + + const totalSupplyUsd = + Number(totalSupplyScaled) * + Number(exchangeRateScaled) * + underlyingPriceScaled; + const totalBorrowUsd = + Number(totalBorrowsScaled) * underlyingPriceScaled; + + const supplyRateScaled = Number(supplyRate) / Math.pow(10, 18); + const borrowRateScaled = Number(borrowRate) / Math.pow(10, 18); + const collateralFactorScaled = + Number(collateralFactor) / Math.pow(10, 18); + + const supplyApy = + ((supplyRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + const borrowApy = + ((borrowRateScaled * SECONDS_PER_DAY + 1) ** DAYS_PER_YEAR - 1) * 100; + + return { + pool: `${market.toLowerCase()}-optimism`, + chain: utils.formatChain('optimism'), + project: 'moonwell-lending', + symbol: token_info.symbol == 'WETH' ? 'ETH' : token_info.symbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyApy, + apyReward: 0, + underlyingTokens: [token_info.address], + rewardTokens: [], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: borrowApy, + apyRewardBorrow: 0, + ltv: Number(collateralFactorScaled), + incentives: [], //helper + }; + }) + .filter(Boolean) + .filter((e) => e.ltv); + } + + optimismResults = optimismResults || []; + + const optimism_mrd_markets = await multicallMRD( + optimismResults.map((r) => r.pool.split('-')[0]), + 'optimism' + ); + + const optimism_prices_id = optimism_mrd_markets + .flat() + .reduce((prev, curr) => { + const [ + _owner, + _emissionToken, + _endTime, + _supplyGlobalIndex, + _supplyGlobalTimestamp, + _borrowGlobalIndex, + _borrowGlobalTimestamp, + _supplyEmissionsPerSec, + _borrowEmissionsPerSec, + ] = curr; + + let lookup; + if ( + _emissionToken.toLowerCase() == + '0xa88594d404727625a9437c3f886c7643872296ae' + ) { + //WELL optimism -> WELL base + lookup = `base:${_emissionToken}`; + } else { + lookup = `optimism:${_emissionToken}`; + } + return { + ...prev, + [_emissionToken]: lookup, + }; + }, {}); + + const optimism_mrd_prices = await getPrices( + Object.values(optimism_prices_id) + ); + + let optimismMarketIdx = 0; + for (let market of optimismResults) { + let marketRewards = optimism_mrd_markets[optimismMarketIdx]; + for (let marketWithRewards of marketRewards) { + const [ + _owner, + _emissionToken, + _endTime, + _supplyGlobalIndex, + _supplyGlobalTimestamp, + _borrowGlobalIndex, + _borrowGlobalTimestamp, + _supplyEmissionsPerSec, + _borrowEmissionsPerSec, + ] = marketWithRewards; + + let token_info = optimism_mrd_prices[_emissionToken.toLowerCase()]; + + if (!token_info) continue; + + let price = token_info.price; + let decimals = token_info.decimals; + let symbol = token_info.symbol; + + //only active + if (_endTime > NOW) { + const supplyRewardsPerDay = + (_supplyEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const supplyRewardsPerDayUSD = supplyRewardsPerDay * price; + + const borrowRewardsPerDay = + (_borrowEmissionsPerSec / Math.pow(-10, decimals)) * SECONDS_PER_DAY; + + const borrowRewardsPerDayUSD = borrowRewardsPerDay * price; + + market.incentives.push({ + address: _emissionToken, + supplyRewardsAPR: + market.totalSupplyUsd > 0 + ? (supplyRewardsPerDayUSD / market.totalSupplyUsd) * + DAYS_PER_YEAR * + 100 + : 0, + borrowRewardsAPR: + market.totalBorrowUsd > 0 + ? (borrowRewardsPerDayUSD / market.totalBorrowUsd) * + DAYS_PER_YEAR * + 100 + : 0, + }); + } + } + optimismMarketIdx++; + } + + for (let market of optimismResults) { + const supplyIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.supplyRewardsAPR, + 0 + ); + + const borrowIncentivesAPR = market.incentives.reduce( + (prev, curr) => prev + curr.borrowRewardsAPR, + 0 + ); + + market.rewardTokens = market.incentives.map((r) => r.address); + market.apyReward = supplyIncentivesAPR; + market.apyRewardBorrow = parseFloat( + Math.abs(borrowIncentivesAPR).toFixed(6) + ); + + delete market.incentives; + } + + return [...moonbeamResults, ...baseResults, ...optimismResults]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://moonwell.fi/markets', +}; diff --git a/src/adaptors/more-markets/incentiveDataAbi.js b/src/adaptors/more-markets/incentiveDataAbi.js new file mode 100644 index 0000000000..f68cd560ea --- /dev/null +++ b/src/adaptors/more-markets/incentiveDataAbi.js @@ -0,0 +1,265 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract IPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "getReservesIncentivesData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardOracleAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissionPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "incentivesLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionEndTimestamp", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "precision", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.RewardInfo[]", + "name": "rewardsTokenInformation", + "type": "tuple[]" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.IncentiveData", + "name": "aIncentiveData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardOracleAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissionPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "incentivesLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionEndTimestamp", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "precision", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.RewardInfo[]", + "name": "rewardsTokenInformation", + "type": "tuple[]" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.IncentiveData", + "name": "vIncentiveData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "incentiveControllerAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "rewardTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardOracleAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissionPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "incentivesLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenIncentivesIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionEndTimestamp", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardPriceFeed", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "rewardTokenDecimals", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "precision", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "priceFeedDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.RewardInfo[]", + "name": "rewardsTokenInformation", + "type": "tuple[]" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.IncentiveData", + "name": "sIncentiveData", + "type": "tuple" + } + ], + "internalType": "struct IUiIncentiveDataProviderV3.AggregatedReserveIncentiveData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/more-markets/index.js b/src/adaptors/more-markets/index.js new file mode 100644 index 0000000000..c2c2651e5a --- /dev/null +++ b/src/adaptors/more-markets/index.js @@ -0,0 +1,305 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const poolAbi = require('./poolAbi'); +const incentiveDataAbi = require('./incentiveDataAbi'); + +const protocolDataProvider = '0x2148e6253b23122Ee78B3fa6DcdDbefae426EB78'; +const incentiveDataProvider = '0x7b589494de15C30FBBA49B2b478cBEcC561f5A87'; +const provider = '0x1830a96466d1d108935865c75B0a9548681Cfd9A'; + +const apy = async () => { + const chain = 'flow'; + + // Fetch weekly merkle-distributed rewards (external source) + let merkleRewards = []; + try { + const resp = await axios.get( + 'https://rewards-distributor.vercel.app/api/markets/apy' + ); + merkleRewards = Array.isArray(resp.data) ? resp.data : []; + } catch (e) { + // Continue gracefully if the external service is unavailable + } + + const nowTs = Math.floor(Date.now() / 1000); + merkleRewards = merkleRewards.filter((r) => { + const hasEmission = Number(r?.emission_wei_per_second || 0) > 0; + const startsOk = !r?.start_timestamp || nowTs >= Number(r.start_timestamp); + const endsOk = !r?.end_timestamp || nowTs <= Number(r.end_timestamp); + return hasEmission && startsOk && endsOk; + }); + + // Group merkle rewards by the tracked token address (aToken or variableDebt token) + const merkleByTracked = merkleRewards.reduce((acc, r) => { + const key = (r?.tracked_token_address || '').toLowerCase(); + if (!key) return acc; + if (!acc[key]) acc[key] = []; + acc[key].push(r); + return acc; + }, {}); + + const getReservesDataAbi = poolAbi.find((m) => m.name === 'getReservesData'); + const reservesData = await sdk.api.abi.call({ + target: protocolDataProvider, + abi: getReservesDataAbi, + params: [provider], + chain, + }); + + const reserves = reservesData.output?.[0] || []; + if (reserves.length === 0) return []; + + // Get incentive data + let incentivesData = []; + try { + const getReservesIncentivesDataAbi = incentiveDataAbi.find( + (m) => m.name === 'getReservesIncentivesData' + ); + const incentivesResult = await sdk.api.abi.call({ + target: incentiveDataProvider, + abi: getReservesIncentivesDataAbi, + params: [provider], + chain, + }); + incentivesData = incentivesResult.output || []; + } catch (error) { + // Continue without incentive data if unavailable + } + + // Get token prices + const underlyingTokens = reserves.map((reserve) => reserve.underlyingAsset); + const rewardTokenAddresses = Array.from( + new Set( + merkleRewards + .map((r) => (r?.reward_token_address || '').toLowerCase()) + .filter(Boolean) + ) + ); + const priceTokens = [...underlyingTokens, ...rewardTokenAddresses]; + const priceKeys = priceTokens.map((addr) => `${chain}:${addr}`).join(','); + const prices = priceKeys + ? ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins + : {}; + + // Helper function to calculate reward APY + const calculateRewardAPY = ( + incentiveData, + totalSupplyOrBorrow, + underlyingTokenPrice, + underlyingDecimals + ) => { + if ( + !incentiveData || + !incentiveData.rewardsTokenInformation || + incentiveData.rewardsTokenInformation.length === 0 + ) { + return { apyReward: 0, rewardTokens: [] }; + } + + let totalRewardAPY = 0; + const rewardTokens = []; + + incentiveData.rewardsTokenInformation.forEach((reward) => { + const { + rewardTokenAddress, + emissionPerSecond, + rewardPriceFeed, + rewardTokenDecimals, + priceFeedDecimals, + emissionEndTimestamp, + } = reward; + + // Skip if emissions have ended + const currentTimestamp = Math.floor(Date.now() / 1000); + if (emissionEndTimestamp > 0 && currentTimestamp > emissionEndTimestamp) { + return; + } + + // Skip if no emissions + if (!emissionPerSecond || emissionPerSecond === '0') { + return; + } + + // Calculate reward token price + const rewardPrice = + rewardPriceFeed > 0 + ? Number(rewardPriceFeed) / 10 ** Number(priceFeedDecimals) + : 0; + + if ( + rewardPrice > 0 && + totalSupplyOrBorrow > 0 && + underlyingTokenPrice > 0 + ) { + // Calculate annual reward emissions + const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; + const annualRewardTokens = + (Number(emissionPerSecond) / 10 ** Number(rewardTokenDecimals)) * + SECONDS_PER_YEAR; + const annualRewardUSD = annualRewardTokens * rewardPrice; + + // Calculate total pool value in USD + const poolValueUSD = totalSupplyOrBorrow * underlyingTokenPrice; + + // Calculate reward APY as a percentage + const rewardAPY = (annualRewardUSD / poolValueUSD) * 100; + + totalRewardAPY += rewardAPY; + rewardTokens.push(rewardTokenAddress); + } + }); + + return { apyReward: totalRewardAPY, rewardTokens }; + }; + + const pools = reserves.map((reserve) => { + const { + underlyingAsset, + name, + symbol, + decimals, + liquidityRate, + variableBorrowRate, + availableLiquidity, + totalScaledVariableDebt, + baseLTVasCollateral, + borrowingEnabled, + isActive, + isPaused, + aTokenAddress, + variableDebtTokenAddress, + } = reserve; + + // Get price using chain:address format + const priceKey = `${chain}:${underlyingAsset}`; + const tokenPrice = prices[priceKey]; + + // Calculate APYs (rates are in Ray format) + const RAY = 10 ** 27; + const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; + + const supplyAPY = + liquidityRate > 0 + ? (Math.pow( + 1 + liquidityRate / RAY / SECONDS_PER_YEAR, + SECONDS_PER_YEAR + ) - + 1) * + 100 + : 0; + + const borrowAPY = + variableBorrowRate > 0 + ? (Math.pow( + 1 + variableBorrowRate / RAY / SECONDS_PER_YEAR, + SECONDS_PER_YEAR + ) - + 1) * + 100 + : 0; + + // Calculate TVL and borrow amounts + const liquidity = Number(availableLiquidity) / 10 ** Number(decimals); + const borrowed = Number(totalScaledVariableDebt) / 10 ** Number(decimals); + + const liquidityUsd = tokenPrice?.price ? liquidity * tokenPrice.price : 0; + const borrowedUsd = tokenPrice?.price ? borrowed * tokenPrice.price : 0; + const totalSupplyUsd = liquidityUsd + borrowedUsd; + const tvlUsd = liquidityUsd; + + // Find matching incentive data for this reserve + const matchingIncentive = incentivesData.find( + (inc) => + inc.underlyingAsset.toLowerCase() === underlyingAsset.toLowerCase() + ); + + // Calculate supply rewards (aToken incentives) + const supplyRewards = matchingIncentive + ? calculateRewardAPY( + matchingIncentive.aIncentiveData, + liquidity + borrowed, // total supply = available liquidity + borrowed + tokenPrice?.price || 0, + Number(decimals) + ) + : { apyReward: 0, rewardTokens: [] }; + + // Calculate borrow rewards (variable debt token incentives) + const borrowRewards = matchingIncentive + ? calculateRewardAPY( + matchingIncentive.vIncentiveData, + borrowed, // total borrowed + tokenPrice?.price || 0, + Number(decimals) + ) + : { apyReward: 0, rewardTokens: [] }; + + // Add merkle-distributed rewards (external feed) + let merkleSupplyApy = 0; + let merkleSupplyRewardTokens = []; + let merkleBorrowApy = 0; + + // For supply side: match by aToken address OR underlying asset and type 'supply' + const merkleSupplyEntries = [ + ...(merkleByTracked[aTokenAddress.toLowerCase()] || []), + ...(merkleByTracked[underlyingAsset.toLowerCase()] || []), + ].filter((r) => (r?.tracked_token_type || '').toLowerCase() === 'supply'); + for (const r of merkleSupplyEntries) { + const rewardPrice = prices[`${chain}:${r.reward_token_address.toLowerCase()}`]?.price || 0; + if (rewardPrice > 0 && totalSupplyUsd > 0) { + const emissionPerSecondTokens = Number(r.emission_wei_per_second) / 1e18; + const annualRewardUsd = emissionPerSecondTokens * SECONDS_PER_YEAR * rewardPrice; + merkleSupplyApy += (annualRewardUsd / totalSupplyUsd) * 100; + merkleSupplyRewardTokens.push(r.reward_token_address.toLowerCase()); + } + } + + // For borrow side: match by variableDebt token OR underlying asset and type 'borrow' + const merkleBorrowEntries = [ + ...(merkleByTracked[variableDebtTokenAddress?.toLowerCase?.() || ''] || []), + ...(merkleByTracked[underlyingAsset.toLowerCase()] || []), + ].filter((r) => (r?.tracked_token_type || '').toLowerCase() === 'borrow'); + for (const r of merkleBorrowEntries) { + const rewardPrice = prices[`${chain}:${r.reward_token_address.toLowerCase()}`]?.price || 0; + if (rewardPrice > 0 && borrowedUsd > 0) { + const emissionPerSecondTokens = Number(r.emission_wei_per_second) / 1e18; + const annualRewardUsd = emissionPerSecondTokens * SECONDS_PER_YEAR * rewardPrice; + merkleBorrowApy += (annualRewardUsd / borrowedUsd) * 100; + } + } + + const url = `https://app.more.markets/markets/${underlyingAsset.toLowerCase()}`; + + return { + pool: aTokenAddress.toLowerCase(), + chain, + project: 'more-markets', + symbol, + tvlUsd, + apyBase: supplyAPY, + apyReward: supplyRewards.apyReward + merkleSupplyApy, + rewardTokens: Array.from( + new Set([...(supplyRewards.rewardTokens || []), ...merkleSupplyRewardTokens]) + ), + underlyingTokens: [underlyingAsset], + totalSupplyUsd, + totalBorrowUsd: borrowedUsd, + debtCeilingUsd: null, + apyBaseBorrow: borrowAPY, + apyRewardBorrow: borrowRewards.apyReward + merkleBorrowApy, + ltv: Number(baseLTVasCollateral) / 10000, + url, + borrowable: borrowingEnabled && isActive && !isPaused, + mintedCoin: null, + poolMeta: `${name} on Flow EVM`, + }; + }); + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/more-markets/poolAbi.js b/src/adaptors/more-markets/poolAbi.js new file mode 100644 index 0000000000..570f9adb78 --- /dev/null +++ b/src/adaptors/more-markets/poolAbi.js @@ -0,0 +1,320 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract IPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "getReservesData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseLTVasCollateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactor", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowingEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isFrozen", + "type": "bool" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "liquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "stableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPrincipalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableDebtLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalScaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInMarketReferenceCurrency", + "type": "uint256" + }, + { + "internalType": "address", + "name": "priceOracle", + "type": "address" + }, + { + "internalType": "uint256", + "name": "variableRateSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableRateSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableRateSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableRateSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseVariableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "optimalUsageRatio", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isSiloedBorrowing", + "type": "bool" + }, + { + "internalType": "uint128", + "name": "accruedToTreasury", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "unbacked", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "isolationModeTotalDebt", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "flashLoanEnabled", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "debtCeiling", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debtCeilingDecimals", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "eModeCategoryId", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "eModeLtv", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "eModeLiquidationThreshold", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "eModeLiquidationBonus", + "type": "uint16" + }, + { + "internalType": "address", + "name": "eModePriceSource", + "type": "address" + }, + { + "internalType": "string", + "name": "eModeLabel", + "type": "string" + }, + { + "internalType": "bool", + "name": "borrowableInIsolation", + "type": "bool" + } + ], + "internalType": "struct IUiPoolDataProviderV3.AggregatedReserveData[]", + "name": "", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "marketReferenceCurrencyUnit", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "marketReferenceCurrencyPriceInUsd", + "type": "int256" + }, + { + "internalType": "int256", + "name": "networkBaseTokenPriceInUsd", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "networkBaseTokenPriceDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUiPoolDataProviderV3.BaseCurrencyInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/morfi/config.js b/src/adaptors/morfi/config.js new file mode 100644 index 0000000000..6938905025 --- /dev/null +++ b/src/adaptors/morfi/config.js @@ -0,0 +1,9 @@ +const coreUrl = 'https://subgraph.morfi.io/subgraphs/name/morfi/core'; +const farmUrl = 'https://subgraph.morfi.io/subgraphs/name/morfi/farming'; +const blocksUrl = 'https://subgraph.morfi.io/subgraphs/name/morfi/blocks'; + +module.exports = { + coreUrl, + farmUrl, + blocksUrl +} \ No newline at end of file diff --git a/src/adaptors/morfi/farming.js b/src/adaptors/morfi/farming.js new file mode 100644 index 0000000000..81bcdb5cfd --- /dev/null +++ b/src/adaptors/morfi/farming.js @@ -0,0 +1,108 @@ +const { SubgraphService } = require('./subgraph'); +const axios = require('axios'); + +const tickToSqrtPrice = (tick) => { + return Math.sqrt(Math.pow(1.0001, tick)); +}; + +const getAmounts = (liquidity, tickLower, tickUpper, currentTick) => { + const currentPrice = tickToSqrtPrice(currentTick); + const lowerPrice = tickToSqrtPrice(tickLower); + const upperPrice = tickToSqrtPrice(tickUpper); + + let amount0, amount1; + if (currentPrice < lowerPrice) { + amount1 = 0; + amount0 = liquidity * (1 / lowerPrice - 1 / upperPrice); + } else if (lowerPrice <= currentPrice && currentPrice <= upperPrice) { + amount1 = liquidity * (currentPrice - lowerPrice); + amount0 = liquidity * (1 / currentPrice - 1 / upperPrice); + } else { + amount1 = liquidity * (upperPrice - lowerPrice); + amount0 = 0; + } + return [amount0, amount1]; +}; + +class FarmingService { + subgraphService; + + constructor() { + this.subgraphService = new SubgraphService(); + } + + async update() { + await this.updateEternalFarmingsApr(2818); + } + + async getEternalFarmingsApr() { + const farmings = await this.subgraphService.getEternalFarmingInfo(); + + return Promise.all( + farmings.map(async (farming) => { + const deposits = + await this.subgraphService.getPositionsInEternalFarming( + farming.id, + ); + const positionIds = deposits.map((deposit) => deposit.id); + + const token0Info = await this.subgraphService.getTokenInfoByAddress( + farming.rewardToken, + ); + + const positions = + await this.subgraphService.getPositionsByIds(positionIds); + + const totalNativeAmount = positions.reduce((acc, position) => { + const [amount0, amount1] = getAmounts( + parseInt(position.liquidity, 10), + parseInt(position.tickLower.tickIdx, 10), + parseInt(position.tickUpper.tickIdx, 10), + parseInt(position.pool.tick, 10), + ); + const amount0InEth = + (amount0 * parseFloat(position.pool.token0.derivedEth)) / + Math.pow(10, parseInt(position.pool.token0.decimals, 10)); + const amount1InEth = + (amount1 * parseFloat(position.pool.token1.derivedEth)) / + Math.pow(10, parseInt(position.pool.token1.decimals, 10)); + return acc + amount0InEth + amount1InEth; + }, 0); + + let rewardPerSecond = + (parseInt(farming.rewardRate) * + parseFloat(token0Info.derivedEth)) / + Math.pow(10, parseInt(token0Info.decimals, 10)); + + if (farming.bonusRewardToken !== '0x0000000000000000000000000000000000000000') { + const token1Info = + await this.subgraphService.getTokenInfoByAddress( + farming.bonusRewardToken, + ); + rewardPerSecond += + (parseInt(farming.bonusRewardRate) * + parseFloat(token1Info.derivedEth)) / + Math.pow(10, parseInt(token1Info.decimals, 10)); + } + + const apr = + totalNativeAmount > 0 + ? (rewardPerSecond * 86400 * 365 * 100) / totalNativeAmount + : 0; + + return { + pool: farming.pool, + apyReward: apr, + rewardTokens: [ + farming.rewardToken, + ...(farming.bonusRewardToken !== '0x0000000000000000000000000000000000000000' ? [farming.bonusRewardToken] : []) + ] + } + }), + ); + } + } + +module.exports = { + FarmingService +} \ No newline at end of file diff --git a/src/adaptors/morfi/gql-requests.js b/src/adaptors/morfi/gql-requests.js new file mode 100644 index 0000000000..e3f2a22280 --- /dev/null +++ b/src/adaptors/morfi/gql-requests.js @@ -0,0 +1,155 @@ +const { gql } = require('graphql-request'); + + const findToken = gql` + query findToken($address: String!) { + token(id: $address) { + derivedEth + decimals + } + } +`; + + const getPositionsByIds = gql` + query getPositionsByIds($id_in: [ID!], $first: Int, $skip: Int) { + positions(where: { id_in: $id_in }, first: $first, skip: $skip) { + id + liquidity + tickLower { + tickIdx + } + tickUpper { + tickIdx + } + pool { + token0 { + name + decimals + derivedEth + } + token1 { + name + decimals + derivedEth + } + tick + } + } + } +`; + + const getPositionsByPoolId = gql` + query getPositionsByPoolId($pool: String!) { + poolPositions(where: { pool: $pool }) { + lowerTick { + tickIdx + } + upperTick { + tickIdx + } + liquidity + pool { + id + token0Price + } + } + } +`; + + const getPoolsByBlockNumber = gql` + query getPoolsByBlockNumber($blockNumber: Int!) { + pools(block: { number: $blockNumber }, first: 1000, orderBy: id) { + feesToken0 + feesToken1 + liquidity + id + token0 { + decimals + name + } + token1 { + decimals + name + } + token0Price + tick + } + } +`; + + const getPools = gql` + query getPools { + pools(first: 1000, orderBy: id) { + feesToken0 + feesToken1 + liquidity + plugin + id + token0 { + decimals + name + symbol + } + token1 { + decimals + name + symbol + } + token0Price + tick + totalValueLockedUSD + } + } +`; + + const findEternalFarmingInfos = gql` + query findEternalFarmingInfos { + eternalFarmings { + id + pool + rewardToken + bonusRewardToken + rewardRate + bonusRewardRate + } + } +`; + + const getPositionsInEternalFarming = gql` + query getPositionsInEternalFarming( + $eternalFarming: String! + $first: Int + $skip: Int + ) { + deposits( + where: { eternalFarming: $eternalFarming } + first: $first + skip: $skip + ) { + id + } + } +`; + + const getPreviousBlockNumber = gql` + query getPreviousBlockNumber($timestampLt: BigInt!, $timestampGt: BigInt!) { + blocks( + first: 1 + orderBy: timestamp + orderDirection: desc + where: { timestamp_lt: $timestampLt, timestamp_gt: $timestampGt } + ) { + number + } + } +`; + +module.exports = { + findToken, + getPositionsByIds, + getPositionsByPoolId, + getPoolsByBlockNumber, + getPools, + findEternalFarmingInfos, + getPositionsInEternalFarming, + getPreviousBlockNumber +} \ No newline at end of file diff --git a/src/adaptors/morfi/index.js b/src/adaptors/morfi/index.js new file mode 100644 index 0000000000..a3fd77b10a --- /dev/null +++ b/src/adaptors/morfi/index.js @@ -0,0 +1,34 @@ +const { FarmingService } = require('./farming'); +const { PoolService } = require('./pool'); + +const main = async (timestamp = null) => { + const farmingService = new FarmingService(); + const poolService = new PoolService(); + + const farmings = await farmingService.getEternalFarmingsApr(); + const pools = await poolService.getPoolsApr(); + + // Merge APY data from farming and pool based on contract address + const mergedData = pools.map(poolData => { + const farmingData = farmings?.find(farming => farming.pool === poolData.pool); + return { + project: 'morfi', + chain: 'Morph', + pool: poolData.pool, // Add pool address + symbol: poolData.symbol, // Add pool symbol + tvlUsd: Number(poolData.tvlUsd), // Add TVL + url: poolData.url, // Add URL + apyBase: poolData.apyBase || 0, + apyReward: farmingData?.apyReward || 0, + ...(farmingData?.rewardTokens?.length > 0 && { rewardTokens: farmingData.rewardTokens }) + }; + }); + + return mergedData; + } + +module.exports = { + timetravel: false, + apy: main, + }; + \ No newline at end of file diff --git a/src/adaptors/morfi/pool.js b/src/adaptors/morfi/pool.js new file mode 100644 index 0000000000..db5b388c3f --- /dev/null +++ b/src/adaptors/morfi/pool.js @@ -0,0 +1,108 @@ +const { SubgraphService } = require('./subgraph'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const tickToSqrtPrice = (tick) => { + return Math.sqrt(Math.pow(1.0001, tick)); + }; + +const getAmounts = (liquidity, tickLower, tickUpper, currentTick) => { + const currentPrice = tickToSqrtPrice(currentTick); + const lowerPrice = tickToSqrtPrice(tickLower); + const upperPrice = tickToSqrtPrice(tickUpper); + + let amount0, amount1; + if (currentPrice < lowerPrice) { + amount1 = 0; + amount0 = liquidity * (1 / lowerPrice - 1 / upperPrice); + } else if (lowerPrice <= currentPrice && currentPrice <= upperPrice) { + amount1 = liquidity * (currentPrice - lowerPrice); + amount0 = liquidity * (1 / currentPrice - 1 / upperPrice); + } else { + amount1 = liquidity * (upperPrice - lowerPrice); + amount0 = 0; + } + return [amount0, amount1]; + }; + + class PoolService { + subgraphService; + + constructor() { + this.subgraphService = new SubgraphService(); + } + + calculateLastApr(poolCurrentTvl, poolFee) { + + return poolCurrentTvl ? (poolFee * 365 * 100) / poolCurrentTvl : 0; + } + + async getPoolsApr() { + const fetchedPools = await this.subgraphService.getCurrentPoolsInfo(); + + + const poolsTick = {}; + const poolsCurrentTvl = {}; + const poolsFees = {}; + + await Promise.all( + fetchedPools.map(async (fetchedPool) => { + poolsTick[fetchedPool.id] = parseInt(fetchedPool.tick, 10); + poolsCurrentTvl[fetchedPool.id] = 0; + poolsFees[fetchedPool.id] = poolsFees[fetchedPool.id] + ? poolsFees[fetchedPool.id] + parseFloat(fetchedPool.feesToken0) + : parseFloat(fetchedPool.feesToken0); + poolsFees[fetchedPool.id] += + parseFloat(fetchedPool.feesToken1) * + parseFloat(fetchedPool.token0Price); + + const positionInfos = await this.subgraphService.getPositionsByPoolId( + fetchedPool.id, + ); + + positionInfos.forEach((position) => { + const currentTick = poolsTick[position.pool.id]; + if ( + parseInt(position.lowerTick.tickIdx, 10) < currentTick && + currentTick < parseInt(position.upperTick.tickIdx, 10) + ) { + const [amount0, amount1] = getAmounts( + parseInt(position.liquidity, 10), + parseInt(position.lowerTick.tickIdx, 10), + parseInt(position.upperTick.tickIdx, 10), + currentTick, + ); + poolsCurrentTvl[position.pool.id] += + amount0 / Math.pow(10, parseInt(fetchedPool.token0.decimals, 10)); + poolsCurrentTvl[position.pool.id] += + (amount1 / + Math.pow(10, parseInt(fetchedPool.token1.decimals, 10))) * + parseFloat(fetchedPool.token0Price); + } + }); + }), + ); + + return Promise.all( + fetchedPools.map(async (pool) => { + const apr = poolsCurrentTvl[pool.id] + ? this.calculateLastApr( + poolsCurrentTvl[pool.id], + poolsFees[pool.id], + ) + : 0; + return { + pool: pool.id, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd: pool.totalValueLockedUSD, + url: `https://app.morfi.io/pool/${pool.id}`, + apyBase: apr + } + }), + ); + } +} + +module.exports = { + PoolService +} \ No newline at end of file diff --git a/src/adaptors/morfi/subgraph.js b/src/adaptors/morfi/subgraph.js new file mode 100644 index 0000000000..c66abc712d --- /dev/null +++ b/src/adaptors/morfi/subgraph.js @@ -0,0 +1,115 @@ +const axios = require('axios'); +const { coreUrl, farmUrl, blocksUrl } = require('./config'); +const { findToken, findEternalFarmingInfos, getPositionsInEternalFarming, getPreviousBlockNumber, getPools, getPositionsByIds, getPositionsByPoolId, getPoolsByBlockNumber } = require('./gql-requests'); + +const APR_DELTA = 86400; + +const BLOCK_DELTA = 60; + +class SubgraphService { + async sendGqlRequest(url, query, params) { + const response = await axios.post(url, { query, variables: params }); + return response.data; + } + + async getTokenInfoByAddress(address) { + const response = await this.sendGqlRequest(coreUrl, findToken, { + address, + }); + return response.data.token; + } + + async getEternalFarmingInfo() { + const response = await this.sendGqlRequest( + farmUrl, + findEternalFarmingInfos, + ); + return response.data.eternalFarmings; + } + + async getPositionsInEternalFarming( + eternalFarmingId, + ){ + const response = await this.sendGqlRequest( + farmUrl, + getPositionsInEternalFarming, + { + eternalFarming: eternalFarmingId, + }, + ); + return response.data.deposits; + } + + async getPositionsByIds(positionIds) { + const response = await this.sendGqlRequest(coreUrl, getPositionsByIds, { + id_in: positionIds, + }); + return response.data.positions; + } + + async getPositionsByPoolId(poolId) { + const response = await this.sendGqlRequest(coreUrl, getPositionsByPoolId, { + pool: poolId, + }); + return response.data.poolPositions; + } + + async getCurrentPoolsInfo() { + const previousBlockNumber = await this.getPreviousBlockNumber(); + const previousPoolsResponse = await this.sendGqlRequest( + coreUrl, + getPoolsByBlockNumber, + { + blockNumber: previousBlockNumber, + }, + ); + const previousPools = previousPoolsResponse.data.pools; + const currentPoolsResponse = await this.sendGqlRequest(coreUrl, getPools); + const currentPools = currentPoolsResponse.data.pools; + const poolMap = previousPools.reduce((acc, pool) => { + acc[pool.id] = { + feesToken0: parseFloat(pool.feesToken0), + feesToken1: parseFloat(pool.feesToken1), + liquidity: pool.liquidity, + }; + return acc; + }, {}); + const updatedPools = currentPools.map((pool) => { + const previousPool = poolMap[pool.id]; + if (previousPool) { + pool.feesToken0 = ( + parseFloat(pool.feesToken0) - previousPool.feesToken0 + ).toString(); + pool.feesToken1 = ( + parseFloat(pool.feesToken1) - previousPool.feesToken1 + ).toString(); + } else { + pool.feesToken0 = parseFloat(pool.feesToken0).toString(); + pool.feesToken1 = parseFloat(pool.feesToken1).toString(); + } + return pool; + }); + return updatedPools; + } + + async getPreviousBlockNumber() { + const previousDate = Math.floor(Date.now() / 1000) - APR_DELTA; + const timestampLt = previousDate; + const timestampGt = previousDate - BLOCK_DELTA; + const response = await this.sendGqlRequest( + blocksUrl, + getPreviousBlockNumber, + { timestampLt, timestampGt }, + ); + const blocks = response.data.blocks; + if (!blocks || blocks.length === 0) { + throw new Error(ErrorMessage.MSG_BLOCK_NOT_FOUND); + } + const blockNumber = parseInt(blocks[0].number); + return blockNumber; + } + } + +module.exports = { + SubgraphService +} \ No newline at end of file diff --git a/src/adaptors/morphex-v2/abis/abi.json b/src/adaptors/morphex-v2/abis/abi.json new file mode 100644 index 0000000000..61291d0ce0 --- /dev/null +++ b/src/adaptors/morphex-v2/abis/abi.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/morphex-v2/index.js b/src/adaptors/morphex-v2/index.js new file mode 100644 index 0000000000..cfc807740f --- /dev/null +++ b/src/adaptors/morphex-v2/index.js @@ -0,0 +1,280 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); + +const project = 'morphex-v2'; + +// Fantom +const tokenAddressMPXFantom = '0x66eEd5FF1701E6ed8470DC391F05e27B1d0657eb'; +const mlpManagerAddressFantom = '0x3A15Bac2D87C89F08147353fc9aE27080631b73d'; + +const feeMpxTrackerAddressFantom = '0x2D5875ab0eFB999c1f49C798acb9eFbd1cfBF63c'; +const stakedMpxTrackerAddressFantom = + '0xa4157E273D88ff16B3d8Df68894e1fd809DbC007'; + +const feeMlpTrackerAddressFantom = '0x0Af7E9F3396423C30a4dF4a79882d118ea89e2F2'; +const stakedMlpTrackerAddressFantom = + '0xB30A97548551Ac8b185685FC25bF3564cE6E716D'; + +// BNB Chain +const tokenAddressMPXBSC = '0x94C6B279b5df54b335aE51866d6E2A56BF5Ef9b7'; +const mlpManagerAddressBSC = '0x749DA3a34A6E1b098F3BFaEd23DAD2b7D7846b9B'; + +const feeMpxTrackerAddressBSC = '0xfAEdbA0E97D5DCD7A29fB6778D7e17b1be35c0b8'; +const stakedMpxTrackerAddressBSC = '0x13d2bBAE955c54Ab99F71Ff70833dE64482519B1'; + +const feeMlpTrackerAddressBSC = '0x1Fc9aB3b7bEE66fC29167AB205777537898ff235'; +const stakedMlpTrackerAddressBSC = '0x4e0e48b787E308049d0CA6bfAA84D5c61c5a4A1e'; + +const secondsPerYear = 31536000; + +async function getAdjustedAmount(pTarget, pChain, pAbi, pParams = []) { + let decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: pChain, + }); + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: pChain, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * secondsPerYear + : supply.output * 10 ** -decimals.output; +} + +async function getMlpTVL(pChain) { + let tvl = await sdk.api.abi.call({ + target: pChain == 'fantom' ? mlpManagerAddressFantom : mlpManagerAddressBSC, + abi: abi['getAumInUsdg'], + chain: pChain, + params: [false], + }); + + return tvl.output * 10 ** -18; +} + +async function getPoolMPX( + pChain, + pInflationTrackerAddress, + pStakedMpx, + pStakedEsMpx, + pFeeMpx, + pInflationMpx, + pPriceData +) { + const tvlMpx = + pPriceData.mpx.price * + (await getAdjustedAmount( + pChain == 'fantom' ? tokenAddressMPXFantom : tokenAddressMPXBSC, + pChain, + 'erc20:balanceOf', + pChain == 'fantom' + ? [stakedMpxTrackerAddressFantom] + : [stakedMpxTrackerAddressBSC] + )); + + const tvsMpx = pStakedMpx * pPriceData.mpx.price; + const tvsEsMpx = pStakedEsMpx * pPriceData.mpx.price; + + const yearlyFeeMpx = + pChain == 'fantom' + ? pFeeMpx * pPriceData.fantom.price + : pFeeMpx * pPriceData.bsc.price; + const yearlyInflationMpx = pInflationMpx * pPriceData.mpx.price; + + const apyFee = (yearlyFeeMpx / tvsMpx) * 100; + const apyInflation = (yearlyInflationMpx / tvsEsMpx) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project, + symbol: utils.formatSymbol('MPX'), + tvlUsd: tvlMpx, + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + pChain === 'fantom' ? [tokenAddressMPXFantom] : [tokenAddressMPXBSC], + underlyingTokens: [ + pChain === 'fantom' ? tokenAddressMPXFantom : tokenAddressMPXBSC, + ], + }; +} + +async function getPoolMLP( + pChain, + pTvl, + pInflationTrackerAddress, + pFeeMlp, + pInflationMlp, + pPriceData +) { + const yearlyFeeMlp = + pChain == 'fantom' + ? pFeeMlp * pPriceData.fantom.price + : pFeeMlp * pPriceData.bsc.price; + const yearlyInflationMlp = pInflationMlp * pPriceData.mpx.price; + const apyFee = (yearlyFeeMlp / pTvl) * 100; + const apyInflation = (yearlyInflationMlp / pTvl) * 100; + + return { + pool: pInflationTrackerAddress, + chain: utils.formatChain(pChain), + project, + symbol: + pChain === 'fantom' + ? utils.formatSymbol('MLP (FTM-BTC-ETH-USDC-USDT-DAI)') + : utils.formatSymbol('MLP (BNB-BTC-ETH-XRP-ADA-USDT-USDC)'), + tvlUsd: parseFloat(pTvl), + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: + pChain === 'fantom' ? [tokenAddressMPXFantom] : [tokenAddressMPXBSC], + + underlyingTokens: [ + pChain === 'fantom' ? tokenAddressMPXFantom : tokenAddressMPXBSC, + ], + underlyingTokens: [ + pChain === 'fantom' + ? '0xF476F7F88E70470c976d9DF7c5C003dB1E1980Cb' + : '0xbd1dCEc2103675C8F3953c34aE40Ed907E1DCAC2', + ], + }; +} + +const getPools = async () => { + let pools = []; + + const priceKeys = ['fantom', 'binancecoin', 'mpx'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const priceData = { + mpx: prices['coingecko:mpx'], + fantom: prices['coingecko:fantom'], + bsc: prices['coingecko:binancecoin'], + }; + + // Fantom + const fantomStakedMpx = await getAdjustedAmount( + feeMpxTrackerAddressFantom, + 'fantom', + 'erc20:totalSupply' + ); + const fantomStakedEsMpx = await getAdjustedAmount( + stakedMpxTrackerAddressFantom, + 'fantom', + 'erc20:totalSupply' + ); + const fantomFeeMpx = await getAdjustedAmount( + feeMpxTrackerAddressFantom, + 'fantom', + abi['tokensPerInterval'] + ); + const fantomInflationMpx = await getAdjustedAmount( + stakedMpxTrackerAddressFantom, + 'fantom', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMPX( + 'fantom', + stakedMpxTrackerAddressFantom, + fantomStakedMpx, + fantomStakedEsMpx, + fantomFeeMpx, + fantomInflationMpx, + priceData + ) + ); + + const fantomFeeMlp = await getAdjustedAmount( + feeMlpTrackerAddressFantom, + 'fantom', + abi['tokensPerInterval'] + ); + const fantomInflationMlp = await getAdjustedAmount( + stakedMlpTrackerAddressFantom, + 'fantom', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMLP( + 'fantom', + await getMlpTVL('fantom'), + stakedMlpTrackerAddressFantom, + fantomFeeMlp, + fantomInflationMlp, + priceData + ) + ); + + // BSC + const bscStakedMpx = await getAdjustedAmount( + feeMpxTrackerAddressBSC, + 'bsc', + 'erc20:totalSupply' + ); + const bscStakedEsMpx = await getAdjustedAmount( + stakedMpxTrackerAddressBSC, + 'bsc', + 'erc20:totalSupply' + ); + const bscFeeMpx = await getAdjustedAmount( + feeMpxTrackerAddressBSC, + 'bsc', + abi['tokensPerInterval'] + ); + const bscInflationMpx = await getAdjustedAmount( + stakedMpxTrackerAddressBSC, + 'bsc', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMPX( + 'bsc', + stakedMpxTrackerAddressBSC, + bscStakedMpx, + bscStakedEsMpx, + bscFeeMpx, + bscInflationMpx, + priceData + ) + ); + + const bscFeeMlp = await getAdjustedAmount( + feeMlpTrackerAddressBSC, + 'bsc', + abi['tokensPerInterval'] + ); + const bscInflationMlp = await getAdjustedAmount( + stakedMlpTrackerAddressBSC, + 'bsc', + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMLP( + 'bsc', + await getMlpTVL('bsc'), + stakedMlpTrackerAddressBSC, + bscFeeMlp, + bscInflationMlp, + priceData + ) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://www.morphex.trade/earn', +}; diff --git a/src/adaptors/morpho-v0-aavev2/index.js b/src/adaptors/morpho-v0-aavev2/index.js new file mode 100644 index 0000000000..4f5c3fd4f4 --- /dev/null +++ b/src/adaptors/morpho-v0-aavev2/index.js @@ -0,0 +1,147 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const subgraphMorphoAave = sdk.graph.modifyEndpoint( + 'FKVL7B5yEHvz1GKB9hFpwp64YLN5KXS27aWpQLngyECx' +); + +const SECONDS_PER_YEAR = 3600 * 24 * 365; +const usdcToken = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; +const query = gql` + query GetYieldsData { + markets(first: 128) { + address + p2pIndexCursor + reserveData { + borrowPoolIndex + supplyPoolIndex + borrowPoolRate + supplyPoolRate + eth + ltv + isBorrowingEnabled + } + p2pData { + p2pSupplyIndex + p2pBorrowIndex + } + token { + address + decimals + symbol + } + metrics { + borrowBalanceOnPool + supplyBalanceOnPool + borrowBalanceInP2P + supplyBalanceInP2P + totalSupplyOnPool + totalBorrowOnPool + } + } + } +`; +const rateToAPY = (ratePerYear) => + Math.pow(1 + ratePerYear / SECONDS_PER_YEAR, SECONDS_PER_YEAR) - 1; + +const apy = async () => { + const data = (await request(subgraphMorphoAave, query)).markets; + const usdcMarket = data.find((market) => market.token.address === usdcToken); + // ETH / USDC price used to convert ETH to USD later + const ethPrice = usdcMarket.reserveData.eth / 1e18; + + return data.map((marketFromGraph) => { + // supplied amount which is waiting to be matched + const totalSupplyOnPool = + (+marketFromGraph.metrics.supplyBalanceOnPool * + +marketFromGraph.reserveData.supplyPoolIndex) / + `1e${27 + marketFromGraph.token.decimals}`; + + // supplied amount which is matched p2p + const totalSupplyP2P = + (+marketFromGraph.metrics.supplyBalanceInP2P * + +marketFromGraph.p2pData.p2pSupplyIndex) / + `1e${27 + marketFromGraph.token.decimals}`; + + // borrowed amount from underlying aave pool + const totalBorrowOnPool = + (+marketFromGraph.metrics.borrowBalanceOnPool * + +marketFromGraph.reserveData.borrowPoolIndex) / + `1e${27 + marketFromGraph.token.decimals}`; + + // borrowed amount which is matched p2p + const totalBorrowP2P = + (+marketFromGraph.metrics.borrowBalanceInP2P * + +marketFromGraph.p2pData.p2pBorrowIndex) / + `1e${27 + marketFromGraph.token.decimals}`; + + const totalSupply = totalSupplyOnPool + totalSupplyP2P; + const totalBorrow = totalBorrowOnPool + totalBorrowP2P; + + // in morpho's case we use total supply as tvl instead of available liq (cause borrow on morhpo can be greater + // than supply (delta is routed to underlying aave pool) + const totalSupplyUsd = + (totalSupply * (marketFromGraph.reserveData.eth / 1e18)) / ethPrice; + const totalBorrowUsd = + (totalBorrow * (marketFromGraph.reserveData.eth / 1e18)) / ethPrice; + + // aave base apy's + const poolSupplyAPY = rateToAPY( + +marketFromGraph.reserveData.supplyPoolRate / 1e27 + ); + const poolBorrowAPY = rateToAPY( + +marketFromGraph.reserveData.borrowPoolRate / 1e27 + ); + + const spread = poolBorrowAPY - poolSupplyAPY; + + // p2pSupplyAPY = morpho p2p apy + const p2pIndexCursor = +marketFromGraph.p2pIndexCursor / 1e4; + const p2pSupplyAPY = poolSupplyAPY + spread * p2pIndexCursor; + // p2p APY on supply is the same on borrow side + const p2pBorrowAPY = p2pSupplyAPY; + + // morpho displays both P2P apy and aave apy's on their UI separately. on our end, we use a scaled + // average of the two values (scaling by matched/unmatched supply & borrow components) + // eg. if DAI on morhpo has $10mil supplied, but only $10k borrowed, then the avg apy + // will be very close to the aave apy; reason is that the majority of supplied dai on + // morpho haven't been matched p2p because of low borrow amount but instead been routed to + // the underlying aave pool. + const avgSupplyAPY = + totalSupply === 0 + ? 0 + : ((totalSupplyOnPool * poolSupplyAPY + totalSupplyP2P * p2pSupplyAPY) * + 100) / + totalSupply; + + const avgBorrowAPY = + totalBorrow === 0 + ? 0 + : ((totalBorrowOnPool * poolBorrowAPY + totalBorrowP2P * p2pBorrowAPY) * + 100) / + totalBorrow; + + return { + pool: `morpho-aave-${marketFromGraph.token.address}`, + chain: 'ethereum', + project: 'morpho-v0-aavev2', + symbol: utils.formatSymbol(marketFromGraph.token.symbol), + apyBase: avgSupplyAPY, + tvlUsd: totalSupplyUsd, + underlyingTokens: [marketFromGraph.token.address], + apyBaseBorrow: avgBorrowAPY, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd, + ltv: marketFromGraph.reserveData.ltv / 1e4, + borrowable: marketFromGraph.reserveData.isBorrowingEnabled, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://aave.morpho.xyz/?network=mainnet', +}; diff --git a/src/adaptors/morpho-v0-compoundv2/index.js b/src/adaptors/morpho-v0-compoundv2/index.js new file mode 100755 index 0000000000..b8593bc207 --- /dev/null +++ b/src/adaptors/morpho-v0-compoundv2/index.js @@ -0,0 +1,208 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const subgraphMorphoCompound = sdk.graph.modifyEndpoint( + sdk.graph.modifyEndpoint('R7SWGbEtAH11a4PXdtLPiVgWtyKWBkExnST1FVaaFQ8') +); + +const BLOCKS_PER_DAY = 7200; +const SECONDS_PER_DAY = 3600 * 24; +const apxBlockSpeedInSeconds = 12; // in 1e4 units +const compToken = '0xc00e94cb662c3520282e6f5717214004a7f26888'.toLowerCase(); +const query = gql` + query GetYieldsData { + markets(first: 128) { + address + p2pIndexCursor + reserveData { + borrowPoolIndex + supplyPoolIndex + borrowPoolRate + supplyPoolRate + supplySpeeds + borrowSpeeds + usd + collateralFactor + } + p2pData { + p2pSupplyIndex + p2pBorrowIndex + } + token { + address + decimals + symbol + } + metrics { + borrowBalanceOnPool + supplyBalanceOnPool + borrowBalanceInP2P + supplyBalanceInP2P + totalSupplyOnPool + totalBorrowOnPool + } + } + } +`; +const rateToAPY = (rate) => Math.pow(1 + rate, 365) - 1; + +const computeCompRewardsAPY = (marketFromGraph, compPrice, supply) => { + const poolCompSpeed = supply + ? +marketFromGraph.reserveData.supplySpeeds / 1e18 + : +marketFromGraph.reserveData.borrowSpeeds / 1e18; + const compDistributedEachDays = + (poolCompSpeed * SECONDS_PER_DAY) / apxBlockSpeedInSeconds; + + const price = + marketFromGraph.reserveData.usd / + Math.pow(10, 18 * 2 - marketFromGraph.token.decimals); + const totalPoolUsd = supply + ? ((marketFromGraph.metrics.totalSupplyOnPool * + marketFromGraph.reserveData.supplyPoolIndex) / + Math.pow(10, 18 + marketFromGraph.token.decimals)) * + price + : ((marketFromGraph.metrics.totalBorrowOnPool * + marketFromGraph.reserveData.borrowPoolIndex) / + Math.pow(10, 18 + marketFromGraph.token.decimals)) * + price; + const compRate = (compDistributedEachDays * compPrice) / totalPoolUsd; + return rateToAPY(compRate); +}; + +const apy = async () => { + const data = (await request(subgraphMorphoCompound, query)).markets; + const compMarket = data.find((market) => market.token.address === compToken); + const compPrice = compMarket.reserveData.usd / 1e18; + + return data.map((marketFromGraph) => { + // supplied amount which is waiting to be matched + const totalSupplyOnPool = + (+marketFromGraph.metrics.supplyBalanceOnPool * + +marketFromGraph.reserveData.supplyPoolIndex) / + `1e${18 + marketFromGraph.token.decimals}`; + + // supplied amount which is matched p2p + const totalSupplyP2P = + (+marketFromGraph.metrics.supplyBalanceInP2P * + +marketFromGraph.p2pData.p2pSupplyIndex) / + `1e${18 + marketFromGraph.token.decimals}`; + + // borrowed amount from underlying compound pool + const totalBorrowOnPool = + (+marketFromGraph.metrics.borrowBalanceOnPool * + +marketFromGraph.reserveData.borrowPoolIndex) / + `1e${18 + marketFromGraph.token.decimals}`; + + // borrowed amount which is matched p2p + const totalBorrowP2P = + (+marketFromGraph.metrics.borrowBalanceInP2P * + +marketFromGraph.p2pData.p2pBorrowIndex) / + `1e${18 + marketFromGraph.token.decimals}`; + + const totalSupply = totalSupplyOnPool + totalSupplyP2P; + const totalBorrow = totalBorrowOnPool + totalBorrowP2P; + + // in morpho's case we use total supply as tvl instead of available liq (cause borrow on morhpo can be greater + // than supply (delta is routed to underlying compound pool) + const totalSupplyUsd = + totalSupply * + (marketFromGraph.reserveData.usd / + `1e${18 * 2 - marketFromGraph.token.decimals}`); + const totalBorrowUsd = + totalBorrow * + (marketFromGraph.reserveData.usd / + `1e${18 * 2 - marketFromGraph.token.decimals}`); + + // compound base apy's + // note: using 7200 blocks per day results in larger values + // compared to what is shown on the UI (but I think thats the correct value) + const poolSupplyAPY = rateToAPY( + (+marketFromGraph.reserveData.supplyPoolRate / 1e18) * BLOCKS_PER_DAY + ); + const poolBorrowAPY = rateToAPY( + (+marketFromGraph.reserveData.borrowPoolRate / 1e18) * BLOCKS_PER_DAY + ); + + const spread = poolBorrowAPY - poolSupplyAPY; + + // p2pSupplyAPY = morpho p2p apy + const p2pIndexCursor = +marketFromGraph.p2pIndexCursor / 1e4; + const p2pSupplyAPY = poolSupplyAPY + spread * p2pIndexCursor; + // p2p APY on supply is the same on borrow side + const p2pBorrowAPY = p2pSupplyAPY; + + // morpho displays both P2P apy and compound's apy's on their UI separately. on our end, we use a scaled + // average of the two values (scaling by matched/unmatched supply & borrow components) + // eg. if DAI on morhpo has $10mil supplied, but only $10k borrowed, then the avg apy + // will be very close to the compound apy; reason is that the majority of supplied dai on + // morpho haven't been matched p2p because of low borrow amount but instead been routed to + // the underlying compound pool. + const avgSupplyAPY = + totalSupply === 0 + ? 0 + : ((totalSupplyOnPool * poolSupplyAPY + totalSupplyP2P * p2pSupplyAPY) * + 100) / + totalSupply; + + const avgBorrowAPY = + totalBorrow === 0 + ? 0 + : ((totalBorrowOnPool * poolBorrowAPY + totalBorrowP2P * p2pBorrowAPY) * + 100) / + totalBorrow; + + // note: compAPY matches the compound base apy, however, the compBorrowAPY doesn't (the values are all lower compared to + // what compound shows (and what we have too for compound apyRewardBorrow)) + const compAPY = computeCompRewardsAPY(marketFromGraph, compPrice, true); + const compBorrowAPY = computeCompRewardsAPY( + marketFromGraph, + compPrice, + false + ); + + // Morpho redistributes comp rewards to users on Pool + const avgCompSupplyAPY = + totalSupply === 0 ? 0 : (compAPY * totalSupplyOnPool * 100) / totalSupply; + + const avgCompBorrowAPY = + totalBorrow === 0 + ? 0 + : (compBorrowAPY * totalBorrowOnPool * 100) / totalBorrow; + + // some of the markets on compound have higher apy (base + reward) than the p2p apy + // on morpho. in such cases -> display the compound rates + const conditionBase = (poolSupplyAPY + compAPY) * 100 > avgSupplyAPY; + const apyBase = conditionBase ? poolSupplyAPY * 100 : avgSupplyAPY; + + const conditionBaseBorrow = + -(-poolBorrowAPY + compBorrowAPY) * 100 < avgBorrowAPY; + const apyBaseBorrow = conditionBaseBorrow + ? poolBorrowAPY * 100 + : avgBorrowAPY; + + return { + pool: `morpho-compound-${marketFromGraph.token.address}`, + chain: 'ethereum', + project: 'morpho-v0-compoundv2', + symbol: utils.formatSymbol(marketFromGraph.token.symbol), + apyBase, + apyReward: conditionBase ? compAPY * 100 : null, + rewardTokens: conditionBase ? [compToken] : null, + tvlUsd: totalSupplyUsd, + underlyingTokens: [marketFromGraph.token.address], + apyBaseBorrow, + apyRewardBorrow: conditionBaseBorrow ? compBorrowAPY * 100 : null, + totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + ltv: marketFromGraph.reserveData.collateralFactor / 1e18, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://compound.morpho.xyz/?network=mainnet', +}; diff --git a/src/adaptors/morpho-v1/index.js b/src/adaptors/morpho-v1/index.js new file mode 100644 index 0000000000..dd926b7af6 --- /dev/null +++ b/src/adaptors/morpho-v1/index.js @@ -0,0 +1,405 @@ +const { request, gql } = require('graphql-request'); + +const GRAPH_URL = 'https://api.morpho.org/graphql'; +const CHAINS = { + ethereum: 1, + base: 8453, + optimism: 10, + hyperliquid: 999, + katana: 747474, + arbitrum: 42161, + unichain: 130, + polygon: 137, + monad: 143, +}; + +/** + * IMPORTANT: This adapter handles the morpho-v1 related protocol which includes: + * - Morpho Market V1 (formerly Morpho Blue markets) → borrow pools + * - Morpho Vault V1 (formerly MetaMorpho vaults) → earn pools + * - Morpho Vault V2 allocating into either Morpho Vault V1 or Morpho Market V1 → earn pools + * + * Morpho Vault V2 allocates through adapters to Vault V1 and Market V1 ONLY for now. + * + * For more details on field definitions, see: https://api.morpho.org/graphql + */ + +const gqlQueries = { + marketsData: gql` + query GetYieldsData($chainId: Int!, $skip: Int!) { + markets( + first: 100 + skip: $skip + orderBy: SupplyAssetsUsd + orderDirection: Desc + where: { chainId_in: [$chainId], whitelisted: true } + ) { + items { + uniqueKey + lltv + loanAsset { + address + symbol + priceUsd + decimals + } + collateralAsset { + address + symbol + priceUsd + decimals + } + state { + supplyApy + borrowApy + netSupplyApy + netBorrowApy + supplyAssets + borrowAssets + collateralAssets + collateralAssetsUsd + supplyAssetsUsd + borrowAssetsUsd + rewards { + borrowApr + asset { + address + } + } + } + } + } + } + `, + metaMorphoVaults: gql` + query GetVaultsData($chainId: Int!, $skip: Int!) { + vaults( + first: 100 + skip: $skip + orderBy: TotalAssetsUsd + orderDirection: Desc + where: { chainId_in: [$chainId], whitelisted: true } + ) { + items { + chain { + id + } + address + name + symbol + asset { + address + } + state { + totalAssets + totalAssetsUsd + apy + netApy + fee + totalSupply + allocation { + supplyAssetsUsd + market { + uniqueKey + state { + rewards { + asset { + address + } + supplyApr + } + } + } + } + } + } + } + } + `, + vaultV2s: gql` + query GetVaultV2Data($chainId: Int!, $skip: Int!) { + vaultV2s( + first: 100 + skip: $skip + where: { chainId_in: [$chainId], whitelisted: true } + ) { + items { + address + symbol + name + asset { + address + } + chain { + id + } + totalAssetsUsd + avgApy + avgNetApy + performanceFee + managementFee + maxRate + rewards { + asset { + address + } + supplyApr + } + adapters { + items { + type + } + } + } + } + } + `, +}; + +const isNegligible = (part, total, threshold = 0.01) => { + // "part is negligible relative to total" <=> |part| / |total| < threshold + const denom = Math.abs(total); + if (denom === 0) { + // If total is 0, treat any non-zero part as non-negligible. + return Math.abs(part) === 0; + } + return Math.abs(part) / denom < threshold; +}; + +// Allowed adapter types for Vault V2 +// Vault V2 only allocates to Vault V1 (MetaMorpho) and Market V1 +const ALLOWED_ADAPTER_TYPES = ['MetaMorpho', 'MorphoMarketV1']; + +const buildVaultV2Pools = (earnV2, chain) => + earnV2 + // Filter vaults to only include those with allowed adapter types + .filter((vault) => { + // Check if vault has adapters + if (!vault.adapters?.items || vault.adapters.items.length === 0) { + return false; + } + // Check if all adapters are of allowed types + return vault.adapters.items.every((adapter) => + ALLOWED_ADAPTER_TYPES.includes(adapter.type) + ); + }) + .map((vault) => { + // (a) Aggregate reward APRs from all positive supplyApr entries. + // This is the "rewards" side as exposed by the API. + const totalRewardApr = + vault.rewards?.reduce( + (sum, reward) => sum + (reward.supplyApr > 0 ? reward.supplyApr : 0), + 0 + ) || 0; + + // (b) Decide whether to surface rewards separately. + // We call them negligible if they are < 1% of the total net APY. + const rewardsAreNegligible = isNegligible(totalRewardApr, vault.avgNetApy); + + const rewardTokens = rewardsAreNegligible + ? [] + : (vault.rewards || []) + .filter((reward) => reward.supplyApr > 0) + .map((reward) => reward.asset.address.toLowerCase()); + + // (c) Split avgNetApy (after fees, with rewards) into base + rewards. + // + // Definitions: + // - avgNetApy: realized average net APY of the vault + // (after fees, including rewards). + // - totalRewardApr: sum of all reward APRs from rewards.supplyApr. + // + // We want: + // totalAPY (what user earns) = apyBase + apyReward + // ≈ avgNetApy + // + // So we define (in decimal form): + // rewardComponent = rewardsAreNegligible ? 0 : totalRewardApr + // baseComponent = avgNetApy - rewardComponent + // + // And convert both to percentages for DefiLlama: + const rewardComponent = rewardsAreNegligible ? 0 : totalRewardApr; + + const apyReward = rewardComponent * 100; + const apyBase = (vault.avgNetApy - rewardComponent) * 100; + + return { + pool: `morpho-vault-v2-${vault.address}-${chain}`, + chain, + project: 'morpho-v1', + symbol: vault.symbol, + // Base APY: net yield from the strategy + underlying asset, after fees, + // excluding explicit reward APRs. + apyBase, + tvlUsd: vault.totalAssetsUsd || 0, + underlyingTokens: [vault.asset.address], + url: `https://app.morpho.org/${chain}/vault/${vault.address}`, + + // Reward APY: sum of reward APRs from rewards.supplyApr, + // hidden when negligible vs avgNetApy. + apyReward, + rewardTokens, + }; + }); + +const apy = async () => { + let pools = []; + + for (const [chain, chainId] of Object.entries(CHAINS)) { + // Fetch Vault V1 (MetaMorpho) data with pagination + let allVaults = []; + let skip = 0; + while (true) { + const { vaults } = await request(GRAPH_URL, gqlQueries.metaMorphoVaults, { + chainId, + skip, + }); + + if (!vaults.items.length) break; + + allVaults = [...allVaults, ...vaults.items]; + skip += 100; + } + + // Fetch Vault V2 data with pagination + let allVaultV2s = []; + skip = 0; + while (true) { + const { vaultV2s } = await request(GRAPH_URL, gqlQueries.vaultV2s, { + chainId, + skip, + }); + + if (!vaultV2s.items.length) break; + + allVaultV2s = [...allVaultV2s, ...vaultV2s.items]; + skip += 100; + } + + // Fetch markets data with pagination + let allMarkets = []; + skip = 0; + while (true) { + const { markets } = await request(GRAPH_URL, gqlQueries.marketsData, { + chainId, + skip, + }); + + if (!markets.items.length) break; + + allMarkets = [...allMarkets, ...markets.items]; + skip += 100; + } + + const earnV1 = allVaults; + const earnV2 = allVaultV2s; + const borrow = allMarkets; + + // Transform Vault V1 (MetaMorpho) pools + const earnV1Pools = earnV1.map((vault) => { + // fetch reward token addresses from allocation data + let additionalRewardTokens = new Set(); + vault.state.allocation.forEach((allocatedMarket) => { + const allocationUsd = allocatedMarket.supplyAssetsUsd; + if (allocationUsd > 0) { + // For each reward from the allocated market + allocatedMarket.market.state.rewards?.forEach((rw) => { + if (rw.supplyApr > 0) { + additionalRewardTokens.add(rw.asset.address.toLowerCase()); + } + }); + } + }); + + // net = including rewards, apy = baseApy + const rewardsApy = Math.max(vault.state.netApy - vault.state.apy, 0); + const isNegligibleApy = isNegligible(rewardsApy, vault.state.netApy); + let rewardTokens = isNegligibleApy ? [] : [...additionalRewardTokens]; + let apyReward = rewardTokens.length === 0 ? 0 : rewardsApy * 100; + + // override and add OP rewards to this pool + if ( + vault.address.toLowerCase() === + '0xc30ce6a5758786e0f640cc5f881dd96e9a1c5c59' + ) { + rewardTokens = ['0x4200000000000000000000000000000000000042']; + apyReward = rewardsApy * 100; + } + + return { + pool: `morpho-vault-v1-${vault.address}-${chain}`, + chain, + project: 'morpho-v1', + symbol: vault.symbol, + apyBase: vault.state.apy * 100, + tvlUsd: vault.state.totalAssetsUsd || 0, + underlyingTokens: [vault.asset.address], + url: `https://app.morpho.org/${chain}/vault/${vault.address}`, + apyReward, + rewardTokens, + }; + }); + + // Transform Vault V2 pools + // Note: avgNetApy is the realized average net APY (after fees, with rewards) + // rewards.supplyApr contains the reward APRs from the API + // as per the GraphQL schema definition, see: https://api.morpho.org/graphql + // The API already applies maxRate capping when calculating these from share price evolution + // We filter to only include vaults with MetaMorpho or MorphoMarketV1 adapters + const earnV2Pools = buildVaultV2Pools(earnV2, chain); + + const borrowPools = borrow.map((market) => { + if (!market.collateralAsset?.symbol) return null; + const rewardTokens = market.state.rewards + .filter((reward) => reward.borrowApr > 0) + .map((reward) => reward.asset.address); + + const apyRewardBorrow = + Math.max( + 0, + (market.state.borrowApy || 0) - (market.state.netBorrowApy || 0) + ) * 100; + + return { + pool: `morpho-blue-${market.uniqueKey}-${chain}`, + chain, + project: 'morpho-v1', + symbol: market.collateralAsset?.symbol, + apy: 0, + tvlUsd: market.state.collateralAssetsUsd || 0, + underlyingTokens: [market.collateralAsset.address], + apyBaseBorrow: market.state.borrowApy * 100, + totalSupplyUsd: market.state.collateralAssetsUsd ?? 0, + totalBorrowUsd: market.state.borrowAssetsUsd ?? 0, + debtCeilingUsd: + market.state.supplyAssetsUsd - market.state.borrowAssetsUsd, + ltv: market.lltv / 1e18, + mintedCoin: market.loanAsset?.symbol, + url: `https://app.morpho.org/market?id=${market.uniqueKey}&network=${chain}`, + apyRewardBorrow, + rewardTokens: apyRewardBorrow > 0 ? rewardTokens : [], + }; + }); + + pools = [...pools, ...earnV1Pools, ...earnV2Pools, ...borrowPools]; + } + + const uniquePools = Array.from( + pools + .reduce((map, pool) => { + if (!pool) return map; + const key = pool.pool; // pool.pool already contains the full unique ID + if (!map.has(key) || pool.tvlUsd > map.get(key).tvlUsd) { + map.set(key, pool); + } + return map; + }, new Map()) + .values() + ); + + return uniquePools.filter(Boolean); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/mortgagefi/index.js b/src/adaptors/mortgagefi/index.js new file mode 100644 index 0000000000..efaca65cbf --- /dev/null +++ b/src/adaptors/mortgagefi/index.js @@ -0,0 +1,163 @@ + + +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + + +//Calculate APR function uses the last 45 days of rewards to calculate yield +//Yield token is traded 1:1 with the stablecoin and is not dual sided. + +const PoolHolder = [ + { + chain: 'Base', + vaultName: 'USDC (MORTGAGEFI-USDC-WETH)', + poolAddress: '0x1bE87D273d47C3832Ab7853812E9A995A4DE9EEA', + stableAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + stableDecimals: 6, + collateralAddress: '0x4200000000000000000000000000000000000006', + collateralDecimals: 18, + }, + { + chain: 'Base', + vaultName: 'USDC (MORTGAGEFI-USDC-cbBTC)', + poolAddress: '0xE93131620945A1273b48F57f453983d270b62DC7', + stableAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + stableDecimals: 6, + collateralAddress: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', + collateralDecimals: 8, + }, + { + chain: 'Arbitrum', + vaultName: 'USDT (MORTGAGEFI-USDT-WBTC)', + poolAddress: '0x9Be2Cf73E62DD3b5dF4334D9A36888394822A33F', + stableAddress: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + stableDecimals: 6, + collateralAddress: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + collateralDecimals: 8, + } +] +const aprAbi = { + "inputs": [], + "name": "calculateAPR", + "outputs": [ + { + "internalType": "uint256", + "name": "apr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" +} + +const apy = async () => { + let baseCalls = []; + let arbitrumCalls = []; + let usdcWethVault = PoolHolder[0]; + let usdcCbBtcVault = PoolHolder[1]; + let usdtWbtcVault = PoolHolder[2]; + const allPrices = await axios.get(`https://coins.llama.fi/prices/current/base:${usdcWethVault.collateralAddress},base:${usdcWethVault.stableAddress},base:${usdcCbBtcVault.collateralAddress},base:${usdcCbBtcVault.stableAddress},arbitrum:${usdtWbtcVault.collateralAddress},arbitrum:${usdtWbtcVault.stableAddress}`); + + baseCalls.push({ + target: usdcCbBtcVault.poolAddress, + }, + { + target: usdcWethVault.poolAddress, + }, + ); + arbitrumCalls.push({ + target: usdtWbtcVault.poolAddress, + }); + + let baseBalanceCalls = []; + let arbitrumBalanceCalls = []; + baseBalanceCalls.push( + { + target: usdcCbBtcVault.collateralAddress, + params: usdcCbBtcVault.poolAddress, + }, + { + target: usdcCbBtcVault.stableAddress, + params: usdcCbBtcVault.poolAddress, + }, + { + target: usdcWethVault.collateralAddress, + params: usdcWethVault.poolAddress, + }, + { + target: usdcWethVault.stableAddress, + params: usdcWethVault.poolAddress, + }); + + arbitrumBalanceCalls.push({ + target: usdtWbtcVault.collateralAddress, + params: usdtWbtcVault.poolAddress, + }, { + target: usdtWbtcVault.stableAddress, + params: usdtWbtcVault.poolAddress, + }); + const baseBalances = await sdk.api.abi.multiCall({ + calls: baseBalanceCalls, + abi: 'erc20:balanceOf', + chain: 'base', + }); + const arbitrumBalances = await sdk.api.abi.multiCall({ + calls: arbitrumBalanceCalls, + abi: 'erc20:balanceOf', + chain: 'arbitrum', + }); + const baseApys = await sdk.api.abi.multiCall({ + calls: baseCalls, + abi: aprAbi, + chain: 'base', + }); + const arbitrumApys = await sdk.api.abi.multiCall({ + calls: arbitrumCalls, + abi: aprAbi, + chain: 'arbitrum', + }); + + const wethCollateralBalance = allPrices.data.coins[`base:${usdcWethVault.collateralAddress}`].price * (Number(baseBalances.output[2].output) / 10 ** usdcWethVault.collateralDecimals); + const wethStableBalance = allPrices.data.coins[`base:${usdcWethVault.stableAddress}`].price * (Number(baseBalances.output[3].output) / 10 ** usdcWethVault.stableDecimals); + const wethTVL = wethCollateralBalance + wethStableBalance; + const cbBtcCollateralBalance = allPrices.data.coins[`base:${usdcCbBtcVault.collateralAddress}`].price * (Number(baseBalances.output[0].output) / 10 ** usdcCbBtcVault.collateralDecimals); + const cbBtcStableBalance = allPrices.data.coins[`base:${usdcCbBtcVault.stableAddress}`].price * (Number(baseBalances.output[1].output) / 10 ** usdcCbBtcVault.stableDecimals); + const cbBtcTVL = cbBtcCollateralBalance + cbBtcStableBalance; + const wbtcCollateralBalance = allPrices.data.coins[`arbitrum:${usdtWbtcVault.collateralAddress}`].price * (Number(arbitrumBalances.output[0].output) / 10 ** usdtWbtcVault.collateralDecimals); + const wbtcStableBalance = allPrices.data.coins[`arbitrum:${usdtWbtcVault.stableAddress}`].price * (Number(arbitrumBalances.output[1].output) / 10 ** usdtWbtcVault.stableDecimals); + const wbtcTVL = wbtcCollateralBalance + wbtcStableBalance; + + const pools = [ + { + pool: `${usdcWethVault.poolAddress}-base`, + chain: 'Base', + project: 'mortgagefi', + symbol: 'USDC', + tvlUsd: wethTVL, + apy: baseApys.output[1].output / 100, + }, + { + pool: `${usdcCbBtcVault.poolAddress}-base`, + chain: 'Base', + project: 'mortgagefi', + symbol: 'USDC', + tvlUsd: cbBtcTVL, + apy: baseApys.output[0].output / 100, + }, + { + pool: `${usdtWbtcVault.poolAddress}-arbitrum`, + chain: 'Arbitrum', + project: 'mortgagefi', + symbol: 'USDT', + tvlUsd: wbtcTVL, + apy: arbitrumApys.output[0].output / 100, + } + ] + return pools +} + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://mortgagefi.app/markets', +} diff --git a/src/adaptors/mosaic-amm/index.js b/src/adaptors/mosaic-amm/index.js new file mode 100644 index 0000000000..ae09fdf9f7 --- /dev/null +++ b/src/adaptors/mosaic-amm/index.js @@ -0,0 +1,113 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const MOSAIC_AMM_LIQUIDITY_POOL_URL = 'https://app.mosaic.ag/liquidity'; +const MOSAIC_AMM_POOL_STATS_URL = 'https://stats.mosaic.ag/v1/public/pools'; + +async function apy() { + const pools = (await utils.getData(MOSAIC_AMM_POOL_STATS_URL))?.data?.pools; + const tokens = pools.flatMap((pool) => [ + pool.metadata.token_x, + pool.metadata.token_y, + ]); + const uniqueTokens = [...new Set(tokens)]; + const tokensInfo = await getTokensInfo(uniqueTokens); + + return pools + .map((pool) => { + const tokenXInfo = tokensInfo[pool.metadata.token_x]; + const tokenYInfo = tokensInfo[pool.metadata.token_y]; + + const symbol = + tokenXInfo && tokenYInfo + ? `${tokenXInfo?.symbol}-${tokenYInfo?.symbol}` + : 'UNKNOWN'; + + const rewardTokens = pool.active_farms.map( + (farm) => farm.metadata.reward_token + ); + + return { + pool: pool.pool_address + '-move', + chain: utils.formatChain('move'), + project: 'mosaic-amm', + symbol: symbol, + tvlUsd: pool.stats.tvl_usd, + apyBase: pool.stats.apr_fees, + apyReward: pool.stats.apr_farming_rewards, + volumeUsd1d: +pool.stats.volume_24h_usd, + rewardTokens: rewardTokens, + underlyingTokens: [pool.metadata.token_x, pool.metadata.token_y], + url: `${MOSAIC_AMM_LIQUIDITY_POOL_URL}/add?pool=${pool.pool_address}`, + }; + }) + .filter((item) => !!item); +} + +// Return a mapping of token addresses to their info +async function getTokensInfo(tokenAddresses) { + const normalizedAddressToAddress = {}; + for (const address of tokenAddresses) { + const normalizedAddress = normalizeTokenAddress(address); + normalizedAddressToAddress[normalizedAddress] = address; + } + const normalizedAddresses = Object.keys(normalizedAddressToAddress); + + const response = await axios.post( + `https://indexer.mainnet.movementnetwork.xyz/v1/graphql`, + { + query: ` + query GetTokensInfo($addresses: [String!]) { + fungible_asset_metadata( + where: {asset_type: {_in: $addresses}} + ) { + asset_type + symbol + } + } + `, + variables: { + addresses: normalizedAddresses, + }, + }, + { + headers: { + 'Content-Type': 'application/json', + }, + } + ); + + const tokensInfo = {}; + for (const tokenInfo of response.data.data.fungible_asset_metadata) { + const normalizedAddress = normalizeTokenAddress(tokenInfo.asset_type); + const tokenAddress = normalizedAddressToAddress[normalizedAddress]; + if (!tokenAddress) { + continue; + } + + tokensInfo[tokenAddress] = tokenInfo; + } + + return tokensInfo; +} + +// Format of normalized address is `0xadc..def` with 66 characters in total (2 for 0x + 64 for address) +function normalizeTokenAddress(address) { + let addressWithoutPrefix = address; + if (address.startsWith('0x')) { + addressWithoutPrefix = address.slice(2); + } + + if (addressWithoutPrefix.length < 64) { + // Add leading zeros to make it 64 characters long + addressWithoutPrefix = addressWithoutPrefix.padStart(64, '0'); + } + + return `0x${addressWithoutPrefix}`; +} + +module.exports = { + timetravel: false, + apy: apy, + url: `${MOSAIC_AMM_LIQUIDITY_POOL_URL}/explore`, +}; diff --git a/src/adaptors/mover/abis/savings_plus_pool_abi.json b/src/adaptors/mover/abis/savings_plus_pool_abi.json new file mode 100644 index 0000000000..4ca3c03751 --- /dev/null +++ b/src/adaptors/mover/abis/savings_plus_pool_abi.json @@ -0,0 +1,28 @@ +{ + "totalAssetAmount": { + "inputs": [], + "name": "totalAssetAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getDailyAPY": { + "inputs": [], + "name": "getDailyAPY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/mover/abis/savings_pool_abi.json b/src/adaptors/mover/abis/savings_pool_abi.json new file mode 100644 index 0000000000..1fc68429b1 --- /dev/null +++ b/src/adaptors/mover/abis/savings_pool_abi.json @@ -0,0 +1,30 @@ +{ + "getDailyAPY": { + "inputs": [], + "name": "getDailyAPY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + "totalAssetAmount": { + "inputs": [], + "name": "totalAssetAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + } +} \ No newline at end of file diff --git a/src/adaptors/mover/index.js b/src/adaptors/mover/index.js new file mode 100644 index 0000000000..0d2d7fb0d4 --- /dev/null +++ b/src/adaptors/mover/index.js @@ -0,0 +1,121 @@ +const superagent = require('superagent'); + +const utils = require('../utils'); + +const savingsPool = '0xAF985437DCA19DEFf89e61F83Cd526b272523719'; +const savingsPlusPolygonPool = '0x77D5333d97A092cA01A783468E53E550C379dc3C'; +const USDCinPolygon = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174'; + +const { default: BigNumber } = require('bignumber.js'); + +const savingsPoolABI = require('./abis/savings_pool_abi.json'); +const savingsPlusPoolAbi = require('./abis/savings_plus_pool_abi.json'); + +const sdk = require('@defillama/sdk'); + +const projectName = 'mover'; + +const savings = async () => { + const chain = 'ethereum'; + + // get asset price in usd + const key = 'ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; + const usdcInUSDEth = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + + let tvl = new BigNumber( + ( + await sdk.api.abi.call({ + target: savingsPool, + abi: savingsPoolABI.totalAssetAmount, + }) + ).output + ); + + tvl = tvl.div(1e6).multipliedBy(usdcInUSDEth); + + let apy = new BigNumber( + ( + await sdk.api.abi.call({ + target: savingsPool, + abi: savingsPoolABI.getDailyAPY, + }) + ).output + ); + + apy = apy.multipliedBy(365).div(new BigNumber(1e18)); + + return { + pool: savingsPool, + chain: utils.formatChain(chain), + project: projectName, + symbol: utils.formatSymbol('USDC'), + tvlUsd: parseInt(tvl.toFixed(0)), + apy: parseFloat(apy.toFixed(2)), + }; +}; + +const savingsPlus = async () => { + const chain = 'polygon'; + + // get asset price in usd + const key = `polygon:${USDCinPolygon}`.toLowerCase(); + const usdcInUSDPolygon = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + + let tvl = new BigNumber( + ( + await sdk.api.abi.call({ + chain: 'polygon', + target: savingsPlusPolygonPool, + abi: savingsPlusPoolAbi.totalAssetAmount, + }) + ).output + ); + + tvl = tvl.div(1e6).multipliedBy(usdcInUSDPolygon); + + let apy = new BigNumber( + ( + await sdk.api.abi.call({ + chain: 'polygon', + target: savingsPlusPolygonPool, + abi: savingsPlusPoolAbi.getDailyAPY, + }) + ).output + ); + + // 1651230270 - April 29 - pool started + // after 20 days - first strategy + const inceptionTimestamp = 1651230270; + const koef = + (Date.now() / 1000 - inceptionTimestamp) / + (Date.now() / 1000 - inceptionTimestamp - 20 * 24 * 3600); + + apy = apy + .multipliedBy(new BigNumber(koef)) + .div(new BigNumber(1e18)) + .multipliedBy(365); + + return { + pool: savingsPlusPolygonPool, + chain: utils.formatChain(chain), + project: projectName, + symbol: utils.formatSymbol('USDC'), + tvlUsd: parseInt(tvl.toFixed(0)), + apy: parseFloat(apy.toFixed(2)), + }; +}; + +const main = async () => { + const data = await Promise.all([savings(), savingsPlus()]); + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.viamover.com/', +}; diff --git a/src/adaptors/mstable-yield/index.js b/src/adaptors/mstable-yield/index.js new file mode 100644 index 0000000000..f7f396f1f2 --- /dev/null +++ b/src/adaptors/mstable-yield/index.js @@ -0,0 +1,100 @@ +const BN = require('bignumber.js'); +const { request, gql } = require('graphql-request'); + +const { formatChain } = require('../utils'); + +const DHEDGE_API_URL = 'https://api-v2.dhedge.org/graphql'; + +const MSTABLE_POOL_ADDRESSES = ['0x9c6de13d4648a6789017641f6b1a025816e66228']; + +const MSTABLE_VAULT_BASE_URL = 'https://yield.mstable.org/vault/'; + +const FUNDS_QUERY = gql` + query GetAllFundsByAddresses($addresses: [String]!) { + allFundsByAddresses(addresses: $addresses) { + address + blockchainCode + blockTime + fundComposition { + amount + tokenAddress + } + performanceMetrics { + week + month + quarter + halfyear + year + } + symbol + totalValue + apy { + monthly + weekly + } + } + } +`; + +const formatValue = (value) => new BN(value).shiftedBy(-18).toNumber(); + +const getDaysSincePoolCreation = (blockTime) => + Math.round((Date.now() / 1000 - +blockTime) / 86400); + +// APY with fallback calculation simply based on pool's past performance +const calcApy = (apy, blockTime, metrics) => { + if (apy) { + return Math.max(...Object.values(apy)); + } + + const daysActive = getDaysSincePoolCreation(blockTime); + return daysActive >= 360 + ? (formatValue(metrics.year) - 1) * 100 + : daysActive >= 180 + ? (formatValue(metrics.halfyear) - 1) * 2 * 100 + : daysActive >= 90 + ? (formatValue(metrics.quarter) - 1) * 4 * 100 + : daysActive >= 30 + ? (formatValue(metrics.month) - 1) * 12 * 100 + : (formatValue(metrics.week) - 1) * 52 * 100; +}; +const poolsFunction = async () => { + try { + const { allFundsByAddresses } = await request(DHEDGE_API_URL, FUNDS_QUERY, { + addresses: MSTABLE_POOL_ADDRESSES, + }); + + return allFundsByAddresses.map( + ({ + address, + blockchainCode, + symbol, + totalValue, + performanceMetrics, + blockTime, + fundComposition, + apy, + }) => ({ + pool: address, + chain: formatChain(blockchainCode.toLowerCase()), + project: 'mstable-yield', + symbol, + tvlUsd: formatValue(totalValue), + apyBase: calcApy(apy, blockTime, performanceMetrics), + underlyingTokens: fundComposition + .filter(({ amount }) => amount !== '0') + .map(({ tokenAddress }) => tokenAddress), + url: `${MSTABLE_VAULT_BASE_URL}${address}`, + }) + ); + } catch (error) { + console.error('Failed to fetch mStable pools', error); + + return []; + } +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/mu-digital/index.js b/src/adaptors/mu-digital/index.js new file mode 100644 index 0000000000..785b139d2b --- /dev/null +++ b/src/adaptors/mu-digital/index.js @@ -0,0 +1,346 @@ +/* + Yield assets: + - loAZND (ERC4626 vault): + tvlUsd = totalAssets * price(asset) / 10^assetDecimals; + apyBase = (convertToAssets(1 share)_today / convertToAssets(1 share)_yesterday) ^ 365 - 1. + - muBOND (rebase/index token; PriceUpdated is per-share/index/NAV): + tvlUsd = totalSupply * price / 10^decimals; + apyBase = (price_now / price_prev) ^ (52 / gapWeeks) - 1. (Default: gapWeeks = 1, price updates once a week). +*/ +const path = require('path'); +const axios = require('axios'); +// Prefer the repo-level SDK since nested node_modules can be out of date. +const sdk = (() => { + const rootSdkPath = path.resolve( + __dirname, + '../../..', + 'node_modules', + '@defillama', + 'sdk' + ); + try { + return require(rootSdkPath); + } catch (error) { + return require('@defillama/sdk'); + } +})(); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const { formatChain, formatSymbol } = utils; + +const CONFIG = { + monad: { + vaults: ['0x9c82eB49B51F7Dc61e22Ff347931CA32aDc6cd90'], + muBond: '0x336D414754967C6682B5A665C7DAF6F1409E63e8', + priceFeed: '0x8B9670C5E4D9F1C14f1F9fe625Dd099924aD4D4f', + url: 'https://mudigital.net/', + }, +}; + +const AZND_ADDRESS = '0x4917a5ec9fcb5e10f47cbb197abe6ab63be81fe8'; + +const VAULT_ABI = { + asset: 'function asset() view returns (address)', +}; + +const PRICE_FEED_ABI = { + getPrice: 'function getPrice(address token) view returns (uint256,uint8)', +}; + +const CONVERT_TO_ASSETS_ABI = + 'function convertToAssets(uint256 shares) external view returns (uint256)'; + +const MU_BOND_APY_MIN_WEEKS = 1; +const MU_BOND_APY_MAX_WEEKS = 12; +const MU_BOND_APY_PERIODS_PER_YEAR = 52; +const VAULT_APY_PERIODS_PER_YEAR = 365; +const SECONDS_PER_WEEK = 7 * 24 * 60 * 60; +const DAY_IN_SECONDS = 24 * 60 * 60; +const MS_PER_SECOND = 1000; +const toUnit = (decimals) => `1${'0'.repeat(decimals)}`; +const pow10 = (decimals) => new BigNumber(10).pow(decimals); + +const annualizeRatio = (ratio, periodsPerYear) => { + const apyBN = ratio.pow(periodsPerYear).minus(1).times(100); + return apyBN.isFinite() ? apyBN.toNumber() : 0; +}; + +const annualizeRatioByWeeks = (ratio, gapWeeks) => { + const periods = MU_BOND_APY_PERIODS_PER_YEAR / gapWeeks; + if (Number.isInteger(periods)) { + return annualizeRatio(ratio, periods); + } + const ratioNum = ratio.toNumber(); + if (!Number.isFinite(ratioNum) || ratioNum <= 0) return 0; + const apy = (Math.pow(ratioNum, periods) - 1) * 100; + return Number.isFinite(apy) ? apy : 0; +}; + +const calcTvlUsd = (amountRaw, decimals, price) => { + if (!price || price.isZero()) return 0; + return price + .times(new BigNumber(amountRaw)) + .div(pow10(decimals)) + .toNumber(); +}; + +const getErc20Value = async (target, abi, chain) => { + const { output } = await sdk.api.abi.call({ + target, + abi, + chain, + }); + return output; +}; + +const getErc20Decimals = async (target, chain) => + Number(await getErc20Value(target, 'erc20:decimals', chain)); + +const getErc20Symbol = async (target, chain) => + getErc20Value(target, 'erc20:symbol', chain); + +const getErc20TotalSupply = async (target, chain) => + getErc20Value(target, 'erc20:totalSupply', chain); + +const getTokenPrice = async (tokenAddress, chain) => { + const priceKey = `${chain}:${tokenAddress.toLowerCase()}`; + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + return data.coins?.[priceKey]?.price ?? 0; +}; + +const getPriceFromFeed = async (priceFeed, asset, chain) => { + const priceRes = await sdk.api.abi.call({ + target: priceFeed, + abi: PRICE_FEED_ABI.getPrice, + params: [asset], + chain, + }); + + const [priceRaw, priceDecimals] = Array.isArray(priceRes.output) + ? priceRes.output + : ['0', 0]; + + if (!priceRaw || priceRaw === '0') return null; + + return new BigNumber(priceRaw).div(pow10(priceDecimals)); +}; + +const getPriceWithFallback = async (priceFeed, asset, chain) => { + const priceFromFeed = await getPriceFromFeed(priceFeed, asset, chain); + if (priceFromFeed) return priceFromFeed; + return new BigNumber(await getTokenPrice(asset, chain)); +}; + +const getPriceRawAtBlock = async (priceFeed, token, chain, block) => { + const res = await sdk.api.abi.call({ + target: priceFeed, + abi: PRICE_FEED_ABI.getPrice, + params: [token], + chain, + block, + }); + const [priceRaw, priceDecimals] = Array.isArray(res.output) + ? res.output + : ['0', 0]; + return { + priceRaw: priceRaw ?? '0', + priceDecimals: priceDecimals ?? 0, + }; +}; + +const getMuBondPool = async (chain, muBond, priceFeed, url) => { + try { + const [totalSupplyRes, decimalsRes, symbolRes, price] = + await Promise.all([ + getErc20TotalSupply(muBond, chain), + getErc20Decimals(muBond, chain), + getErc20Symbol(muBond, chain), + getPriceWithFallback(priceFeed, muBond, chain), + ]); + + const tokenDecimals = Number(decimalsRes); + const tvlUsd = calcTvlUsd(totalSupplyRes, tokenDecimals, price); + + let apyBase = 0; + const latest = await sdk.api.util.getLatestBlock(chain); + const { priceRaw: priceNowRaw } = await getPriceRawAtBlock( + priceFeed, + muBond, + chain, + latest.block + ); + const priceNow = new BigNumber(priceNowRaw.toString()); + if (!priceNow.isZero()) { + for ( + let gapWeeks = MU_BOND_APY_MIN_WEEKS; + gapWeeks <= MU_BOND_APY_MAX_WEEKS; + gapWeeks += 1 + ) { + const lookbackSeconds = gapWeeks * SECONDS_PER_WEEK; + const targetTimestamp = latest.timestamp - lookbackSeconds; + if (targetTimestamp <= 0) break; + + const prevBlock = await sdk.api.util.lookupBlock(targetTimestamp, { + chain, + }); + const { priceRaw: pricePrevRaw } = await getPriceRawAtBlock( + priceFeed, + muBond, + chain, + prevBlock.block + ); + const pricePrev = new BigNumber(pricePrevRaw.toString()); + if (pricePrev.isZero()) continue; + if (pricePrev.eq(priceNow)) continue; + + const ratio = priceNow.div(pricePrev); + apyBase = annualizeRatioByWeeks(ratio, gapWeeks); + break; + } + } + + return { + pool: `${muBond}-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'mu-digital', + symbol: formatSymbol(symbolRes), + tvlUsd, + apyBase, + url, + }; + } catch (error) { + console.error(`Error fetching muBOND data for ${muBond}:`, error); + return { + pool: `${muBond}-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'mu-digital', + symbol: 'muBOND', + tvlUsd: 0, + apyBase: 0, + url, + }; + } +}; + +const getERC4626InfoSafe = async (vault, chain, timestamp, assetUnit) => { + try { + const latest = await sdk.api.util.getLatestBlock(chain); + const now = timestamp || Math.floor(Date.now() / MS_PER_SECOND); + const safeTimestamp = Math.min(latest.timestamp, now); + const [blockNow, blockYesterday] = await Promise.all([ + sdk.api.util.lookupBlock(safeTimestamp, { chain }), + sdk.api.util.lookupBlock(safeTimestamp - DAY_IN_SECONDS, { chain }), + ]); + const [tvl, priceNow, priceYesterday] = await Promise.all([ + sdk.api.abi.call({ + target: vault, + block: blockNow.block, + abi: 'uint:totalAssets', + chain, + }), + sdk.api.abi.call({ + target: vault, + block: blockNow.block, + abi: CONVERT_TO_ASSETS_ABI, + params: [assetUnit], + chain, + }), + sdk.api.abi.call({ + target: vault, + block: blockYesterday.block, + abi: CONVERT_TO_ASSETS_ABI, + params: [assetUnit], + chain, + }), + ]); + const priceNowBN = new BigNumber(priceNow.output); + const priceYesterdayBN = new BigNumber(priceYesterday.output); + if (priceNowBN.isZero() || priceYesterdayBN.isZero()) { + return { tvl: tvl.output, apyBase: 0 }; + } + const ratio = priceNowBN.div(priceYesterdayBN); + const apy = annualizeRatio(ratio, VAULT_APY_PERIODS_PER_YEAR); + return { tvl: tvl.output, apyBase: apy }; + } catch (error) { + return null; + } +}; + +const getVaultData = async (chain, vault, priceFeed, timestamp, url) => { + try { + const [assetRes, shareDecimalsRes, vaultSymbolRes] = await Promise.all([ + sdk.api.abi.call({ + target: vault, + abi: VAULT_ABI.asset, + chain, + }), + getErc20Decimals(vault, chain), + getErc20Symbol(vault, chain), + ]); + + const asset = assetRes.output; + const shareDecimals = Number(shareDecimalsRes); + const assetUnit = toUnit(shareDecimals); + + const assetDecimals = await getErc20Decimals(asset, chain); + const erc4626Info = + (await getERC4626InfoSafe(vault, chain, timestamp, assetUnit)) || + (await sdk.api.abi + .call({ + target: vault, + abi: 'uint:totalAssets', + chain, + }) + .then((res) => ({ tvl: res.output, apyBase: 0 }))); + const price = await getPriceWithFallback(priceFeed, asset, chain); + const tvlUsd = calcTvlUsd(erc4626Info?.tvl ?? 0, assetDecimals, price); + + return { + pool: `${vault}-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'mu-digital', + symbol: formatSymbol(vaultSymbolRes), + tvlUsd, + apyBase: erc4626Info?.apyBase ?? 0, + underlyingTokens: [asset], + poolMeta: 'loAZND Vault', + url, + }; + } catch (error) { + console.error(`Error fetching mu-digital vault data for ${vault}:`, error); + return { + pool: `${vault}-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'mu-digital', + symbol: 'loAZND', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [AZND_ADDRESS], + poolMeta: 'loAZND Vault', + url, + }; + } +}; + +const apy = async (timestamp) => { + const poolPromises = Object.entries(CONFIG).flatMap(([chain, cfg]) => { + const pools = cfg.vaults.map((vault) => + getVaultData(chain, vault, cfg.priceFeed, timestamp, cfg.url) + ); + if (cfg.muBond) { + pools.push(getMuBondPool(chain, cfg.muBond, cfg.priceFeed, cfg.url)); + } + return pools; + }); + + const pools = await Promise.all(poolPromises); + return pools.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://mudigital.net/', +}; diff --git a/src/adaptors/multipli.fi/index.js b/src/adaptors/multipli.fi/index.js new file mode 100644 index 0000000000..1f82cef3fa --- /dev/null +++ b/src/adaptors/multipli.fi/index.js @@ -0,0 +1,20 @@ +const axios = require("axios") + +async function apy() { + const response = await axios.get('https://api.multipli.fi/multipli/v1/external-aggregator/defillama/yield/') + + const data = response.data.payload + + return data.map(item => ({ + ...item, + project: item.project.toLowerCase(), + tvlUsd: parseFloat(item.tvlUsd), + apy: parseFloat(item.apy) + })) +} + + +module.exports = { + apy, + url: 'https://www.multipli.fi/', +}; \ No newline at end of file diff --git a/src/adaptors/muuu-finance/abi.json b/src/adaptors/muuu-finance/abi.json new file mode 100644 index 0000000000..07598af201 --- /dev/null +++ b/src/adaptors/muuu-finance/abi.json @@ -0,0 +1,249 @@ +{ + "poolInfo": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "kglRewards", + "type": "address" + }, + { + "internalType": "address", + "name": "stash", + "type": "address" + }, + { + "internalType": "bool", + "name": "shutdown", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolLength": { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "get_pool_from_lp_token": { + "inputs": [ + { + "name": "arg0", + "type": "address" + } + ], + "name": "get_pool_from_lp_token", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "get_virtual_price": { + "inputs": [], + "name": "get_virtual_price", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "rewardRate": { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalSupply": { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "tokenCount": { + "inputs": [], + "name": "tokenCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "tokenList": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenList", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "tokenInfo": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenInfo", + "outputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "name": { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + "reductionPerCliff": { + "inputs": [], + "name": "reductionPerCliff", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalCliffs": { + "inputs": [], + "name": "totalCliffs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "maxSupply": { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/muuu-finance/functions.js b/src/adaptors/muuu-finance/functions.js new file mode 100644 index 0000000000..81b22761c8 --- /dev/null +++ b/src/adaptors/muuu-finance/functions.js @@ -0,0 +1,370 @@ +const sdk = require('@defillama/sdk'); +const BigNumberJs = require('bignumber.js'); +const ABI = require('./abi.json'); +const utils = require('../utils'); + +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +const REGISTRY_ADDRESS = '0xda820e20a89928e43794645b9a9770057d65738b'; +const BOOSTER_ADDRESS = '0x6d12e3de6dacdba2779c4947c0f718e13b78cff4'; + +const KGL_TOKEN = '0x257f1a047948f73158dadd03eb84b34498bcdc60'; +const MUUU_TOKEN = '0xc5bcac31cf55806646017395ad119af2441aee37'; +const LAY_TOKEN = '0xc4335b1b76fa6d52877b3046eca68f6e708a27dd'; +const WASTR_TOKEN = '0xaeaaf0e2c81af264101b9129c00f4440ccf0f720'; + +const MUKGL_REWARDS = '0x27e1076e8a9264718d5ef6824fb010ab6b7543b3'; +const MUUU_REWARDS = '0xb2ae0cf4819f2be89574d3dc46d481cf80c7a255'; + +const KGL_API_BASE_URL = 'https://api.kagla.finance/api/kagla/'; +const DEFAULT_DECIMALS = 18; +const MUUU_REWARD_MULTIPLIER = new BigNumberJs('0.0825'); +const BN_ZERO = new BigNumberJs('0'); + +const getPoolInfo = async () => { + const poolLength = ( + await sdk.api.abi.call({ + target: BOOSTER_ADDRESS, + abi: ABI.poolLength, + chain: 'astar', + }) + ).output; + + const poolInfo = []; + const calldata = []; + for (let i = 0; i < poolLength; i++) { + calldata.push({ + target: BOOSTER_ADDRESS, + params: [i], + }); + } + const returnData = await sdk.api.abi.multiCall({ + abi: ABI.poolInfo, + calls: calldata, + chain: 'astar', + }); + for (let i = 0; i < poolLength; i++) { + const pdata = returnData.output[i].output; + if (pdata.shutdown) continue; + poolInfo.push({ + lptoken: pdata.lptoken, + token: pdata.token, + gauge: pdata.gauge, + kglRewards: pdata.kglRewards, + stash: pdata.stash, + }); + } + + return poolInfo; +}; + +const getKaglaInfo = async () => { + const { pools: kaglaPools } = await utils.getData(KGL_API_BASE_URL + 'pools'); + const kaglaCoins = await utils.getData(KGL_API_BASE_URL + 'coins'); + + return { kaglaPools, kaglaCoins }; +}; + +const getMarketPrices = async () => { + const assets = { + ASTR: `astar:${WASTR_TOKEN}`, + LAY: `astar:${LAY_TOKEN}`, + KGL: `astar:${KGL_TOKEN}`, + MUUU: `astar:${MUUU_TOKEN}`, + }; + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${Object.entries(assets)}` + ); + + return { + [WASTR_TOKEN]: prices[assets.ASTR].price, + [KGL_TOKEN]: prices[assets.KGL].price, + [LAY_TOKEN]: prices[assets.LAY].price, + [MUUU_TOKEN]: prices[assets.MUUU].price, + }; +}; + +const getRewardPools = async (poolInfo) => { + const poolRewardPools = [ + MUKGL_REWARDS, + MUUU_REWARDS, + ...poolInfo.map((v) => v.kglRewards.toLowerCase()), + ]; + + const callData = poolRewardPools.map((rewardPool) => ({ + target: rewardPool, + })); + const rewardRates = ( + await sdk.api.abi.multiCall({ + abi: ABI.rewardRate, + chain: 'astar', + calls: callData, + }) + ).output; + const totalSupplies = ( + await sdk.api.abi.multiCall({ + abi: ABI.totalSupply, + chain: 'astar', + calls: callData, + }) + ).output; + + return poolRewardPools.reduce((res, pool, index) => { + return { + ...res, + [pool]: { + rewardRate: new BigNumberJs( + rewardRates[index].output / 10 ** DEFAULT_DECIMALS + ), + totalSupply: new BigNumberJs( + totalSupplies[index].output / 10 ** DEFAULT_DECIMALS + ), + }, + }; + }, {}); +}; + +const getExtraRewardInfos = async (poolInfo) => { + const stashes = poolInfo.map((pool) => pool.stash); + + const callData = stashes.map((stash) => ({ target: stash })); + const tokenCounts = ( + await sdk.api.abi.multiCall({ + abi: ABI.tokenCount, + chain: 'astar', + calls: callData, + }) + ).output; + + const tokenCountsInStashes = stashes.map((stash, index) => ({ + stash, + tokenCount: Number(tokenCounts[index].output), + })); + + const tokenInfoLists = await Promise.all( + tokenCountsInStashes.map(async (stash) => { + const tokenList = + stash.tokenCount > 0 + ? ( + await sdk.api.abi.multiCall({ + abi: ABI.tokenList, + calls: [...Array(stash.tokenCount)].map((_, idx) => ({ + target: stash.stash, + params: [idx], + })), + chain: 'astar', + }) + ).output + : []; + + const tokenInfo = + stash.tokenCount > 0 + ? ( + await sdk.api.abi.multiCall({ + abi: ABI.tokenInfo, + calls: tokenList.map((token) => ({ + target: stash.stash, + params: [token.output], + })), + chain: 'astar', + }) + ).output + : []; + + const rewardRates = + stash.tokenCount > 0 + ? ( + await sdk.api.abi.multiCall({ + abi: ABI.rewardRate, + chain: 'astar', + calls: tokenInfo.map((token) => ({ + target: token.output.rewardAddress, + })), + }) + ).output + : []; + + return { + ...stash, + tokenInfo: tokenList.map((token, index) => ({ + rewardTokenAddress: token.output, + rewardAddress: tokenInfo[index].output.rewardAddress, + rewardRate: new BigNumberJs( + rewardRates[index].output / 10 ** DEFAULT_DECIMALS + ), + })), + }; + }) + ); + + return tokenInfoLists.reduce( + (res, cur) => ({ + ...res, + [cur.stash]: cur.tokenInfo, + }), + {} + ); +}; + +const getExtraRewardTokenStaticDatas = async (stashes) => { + const tokens = Object.values(stashes).flatMap((stashValue) => + stashValue.map((v) => v.rewardTokenAddress) + ); + + const callData = tokens.map((token) => ({ target: token })); + + const names = ( + await sdk.api.abi.multiCall({ + abi: ABI.name, + chain: 'astar', + calls: callData, + }) + ).output; + + const symbols = ( + await sdk.api.abi.multiCall({ + abi: ABI.symbol, + chain: 'astar', + calls: callData, + }) + ).output; + + const decimals = ( + await sdk.api.abi.multiCall({ + abi: ABI.decimals, + chain: 'astar', + calls: callData, + }) + ).output; + + return tokens.reduce( + (res, token, index) => ({ + ...res, + [token]: { + name: names[index].output, + symbol: symbols[index].output, + decimals: decimals[index].output, + }, + }), + {} + ); +}; + +const getMuuuToken = async () => { + const MUUU_TOKEN_FIELDS = [ + 'reductionPerCliff', + 'totalCliffs', + 'maxSupply', + 'totalSupply', + 'decimals', + ]; + + const [reductionPerCliff, totalCliffs, maxSupply, totalSupply, decimals] = + await Promise.all( + MUUU_TOKEN_FIELDS.map( + async (field) => + ( + await sdk.api.abi.call({ + abi: ABI[field], + target: MUUU_TOKEN, + chain: 'astar', + }) + ).output + ) + ); + + return { + address: MUUU_TOKEN, + reductionPerCliff: new BigNumberJs(reductionPerCliff), + totalCliffs: new BigNumberJs(totalCliffs), + maxSupply: new BigNumberJs(maxSupply), + totalSupply: new BigNumberJs(totalSupply), + decimals: new BigNumberJs(decimals), + }; +}; + +const findKaglaPoolFromPoolInfo = (gaugeAddress, kaglaPools) => { + const matched = kaglaPools + .map((p) => { + if (!p.gauges) return null; + const matchedGauges = p.gauges.filter( + (gauge) => gauge.address.toLowerCase() == gaugeAddress.toLowerCase() + ); + if (matchedGauges.length != 1) return null; + return { + pool: p, + gauge: matchedGauges[0], + }; + }) + .filter((v) => v != null); + return matched.length == 1 ? matched[0] : null; +}; + +const attachSymbolToCoinAddresses = (coins, kaglaCoins) => { + const _coins = []; + for (const c of coins) { + const finded = kaglaCoins.find( + (kaglaC) => kaglaC.address.toLowerCase() == c.address.toLowerCase() + ); + if (finded == undefined) return null; + _coins.push({ + address: c.address, + symbol: finded.symbol, + }); + } + return _coins; +}; + +const AssetType = { + USD: '0', + ASTR: '5', + KGL: '6', + LAY: '7', +}; +const convertLpTokenPriceToUsd = (assetType, lpTokenPrice, prices) => { + const _lpTokenPrice = new BigNumberJs(lpTokenPrice / 10 ** DEFAULT_DECIMALS); + if (assetType == AssetType.USD) return _lpTokenPrice; + if (assetType == AssetType.ASTR) + return _lpTokenPrice.multipliedBy(prices.astr); + if (assetType == AssetType.KGL) return _lpTokenPrice.multipliedBy(prices.kgl); + if (assetType == AssetType.LAY) return _lpTokenPrice.multipliedBy(prices.lay); + return null; +}; + +const calcurateMuuuEarned = (rewardEarned, muuuInfo) => { + const { totalSupply, reductionPerCliff, totalCliffs, maxSupply } = muuuInfo; + const currentCliff = totalSupply.dividedBy(reductionPerCliff); + if (currentCliff.gte(totalCliffs)) return BN_ZERO; + const remaining = totalCliffs.minus(currentCliff); + const muuuEarned = rewardEarned + .multipliedBy(MUUU_REWARD_MULTIPLIER) + .multipliedBy(remaining) + .dividedBy(totalCliffs); + const amountTillMax = maxSupply.minus(totalSupply); + + return muuuEarned.gt(amountTillMax) ? amountTillMax : muuuEarned; +}; + +const convertAPR2APY = (apr) => { + return (apy = Math.pow(apr / 12 + 1, 12) - 1); +}; + +module.exports = { + getPoolInfo, + getKaglaInfo, + getMarketPrices, + getRewardPools, + getExtraRewardInfos, + getExtraRewardTokenStaticDatas, + getMuuuToken, + findKaglaPoolFromPoolInfo, + attachSymbolToCoinAddresses, + convertLpTokenPriceToUsd, + calcurateMuuuEarned, + convertAPR2APY, + KGL_TOKEN, + MUUU_TOKEN, + LAY_TOKEN, + WASTR_TOKEN, + BN_ZERO, +}; diff --git a/src/adaptors/muuu-finance/index.js b/src/adaptors/muuu-finance/index.js new file mode 100644 index 0000000000..2628952db6 --- /dev/null +++ b/src/adaptors/muuu-finance/index.js @@ -0,0 +1,122 @@ +const sdk = require('@defillama/sdk'); +const BigNumberJs = require('bignumber.js'); +const ABI = require('./abi.json'); +const utils = require('../utils'); +const { + getExtraRewardInfos, + getExtraRewardTokenStaticDatas, + getKaglaInfo, + getMarketPrices, + getPoolInfo, + getRewardPools, + getMuuuToken, + findKaglaPoolFromPoolInfo, + attachSymbolToCoinAddresses, + convertLpTokenPriceToUsd, + calcurateMuuuEarned, + convertAPR2APY, + KGL_TOKEN, + MUUU_TOKEN, + LAY_TOKEN, + WASTR_TOKEN, + BN_ZERO, +} = require('./functions'); +const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; + +const getApy = async (param) => { + const poolInfo = await getPoolInfo(); + const { kaglaPools, kaglaCoins } = await getKaglaInfo(); + const rawMarketPrices = await getMarketPrices(); + const rewardPools = await getRewardPools(poolInfo); + const stashes = await getExtraRewardInfos(poolInfo); + const extraRewardTokens = await getExtraRewardTokenStaticDatas(stashes); + const muuuToken = await getMuuuToken(); + + const kglPrice = rawMarketPrices[KGL_TOKEN]; + const muuuPrice = rawMarketPrices[MUUU_TOKEN]; + const astrPrice = rawMarketPrices[WASTR_TOKEN]; + const layPrice = rawMarketPrices[LAY_TOKEN]; + + return poolInfo + .map((v, _idx) => { + const finded = findKaglaPoolFromPoolInfo(v.gauge, kaglaPools); + if (finded == null) return null; + const { pool: kaglaPool, gauge } = finded; + + const poolCoins = attachSymbolToCoinAddresses( + kaglaPool.coins, + kaglaCoins + ); + if (poolCoins == null) return null; + const lpTokenUSDPrice = convertLpTokenPriceToUsd( + kaglaPool.assetType, + kaglaPool.lpToken.virtualPrice, + { astr: astrPrice, kgl: kglPrice, lay: layPrice } + ); + if (lpTokenUSDPrice == null) return null; + + const rewardPool = rewardPools[v.kglRewards.toLowerCase()]; + if (rewardPool == undefined) return null; + + const tvl = rewardPool.totalSupply.multipliedBy(lpTokenUSDPrice); + const rewardAmountPerYear = + rewardPool.rewardRate.multipliedBy(SECONDS_PER_YEAR); + const kglApr = rewardAmountPerYear.multipliedBy(kglPrice).dividedBy(tvl); + const muuuApr = calcurateMuuuEarned(rewardAmountPerYear, { + ...muuuToken, + totalSupply: muuuToken.totalSupply, + }) + .multipliedBy(muuuPrice) + .dividedBy(tvl); + const extraRewardsPools = + stashes && extraRewardTokens && stashes[v.stash] + ? stashes[v.stash].map((val) => { + const _tokenPrice = + rawMarketPrices[val.rewardTokenAddress.toLowerCase()]; + const _apr = _tokenPrice + ? val.rewardRate + .multipliedBy(SECONDS_PER_YEAR) + .multipliedBy(_tokenPrice) + .dividedBy(tvl) + : null; + const _symbol = extraRewardTokens[val.rewardTokenAddress] + ? extraRewardTokens[val.rewardTokenAddress].symbol + : null; + return { + rewardPoolAddress: val.rewardPoolAddress, + rewardToken: { + address: val.rewardTokenAddress, + symbol: _symbol, + }, + apr: _apr, + }; + }) + : []; + const extraRewardsApr = extraRewardsPools.reduce( + (previous, current) => + current.apr ? previous.plus(current.apr) : previous, + BN_ZERO + ); + + return { + pool: v.token, + chain: 'astar', + project: 'muuu-finance', + symbol: poolCoins.map((coin) => coin.symbol).join('-'), + tvlUsd: tvl.toNumber(), + apyBase: convertAPR2APY(gauge.minAPR) * 100, + apyReward: + convertAPR2APY( + BigNumberJs.sum(muuuApr, kglApr, extraRewardsApr).toNumber() + ) * 100, + underlyingTokens: kaglaPool.coins.map((coin) => coin.address), + rewardTokens: [v.kglRewards], + }; + }) + .filter((v) => v != null); +}; + +module.exports = { + apy: getApy, + url: 'https://muuu.finance/app/stake', +}; diff --git a/src/adaptors/mycelium-perpetual-swaps/abis/abi.json b/src/adaptors/mycelium-perpetual-swaps/abis/abi.json new file mode 100644 index 0000000000..cf8b23ce3c --- /dev/null +++ b/src/adaptors/mycelium-perpetual-swaps/abis/abi.json @@ -0,0 +1,124 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "pendingDeposits": { + "inputs": [], + "name": "pendingDeposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "cycle": { + "inputs": [], + "name": "cycle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "cycleCumulativeEthRewards": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "cycleCumulativeEthRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalSupply": { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalDepositSupply": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalDepositSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/mycelium-perpetual-swaps/index.js b/src/adaptors/mycelium-perpetual-swaps/index.js new file mode 100644 index 0000000000..53dd995d2b --- /dev/null +++ b/src/adaptors/mycelium-perpetual-swaps/index.js @@ -0,0 +1,192 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abi = require('./abis/abi.json'); +const { ethers } = require('ethers'); + +const convertToBigNumberWithDecimals = (balance) => + ethers.BigNumber.from(balance); + +const arbitrumMyc = '0xc74fe4c715510ec2f8c61d70d397b32043f55abe'; +const arbitrumEsMyc = '0x7CEC785fba5ee648B48FBffc378d74C8671BB3cb'; +const arbitrumMlp = '0x752b746426b6D0c3188bb530660374f92FD9cf7c'; +const arbitrumMlpManager = '0x2DE28AB4827112Cd3F89E5353Ca5A8D80dB7018f'; +const arbitrumFeeMycTracker = '0x0cA0147c21F9DB9D4627e6a996342A11D25972C5'; +const arbitrumInflationMycTracker = + '0x2BC8E28f5d41a4b112BC62EB7Db1B757c85f37Ff'; +const arbitrumFeeMlpTracker = '0xF0BFB95087E611897096982c33B6934C8aBfA083'; +const arbitrumInflationMlpTracker = + '0xF7Bd2ed13BEf9C27a2188f541Dc5ED85C5325306'; +const arbitrumMycStaking = '0xF9B003Ee160dA9677115Ad3c5bd6BB6dADcB2F93'; + +const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; +const CHAIN_STRING = 'arbitrum'; +const MYC_TOKEN_DECIMALS = 18; + +const projectSlug = 'mycelium-perpetual-swaps'; + +const getAdjustedAmount = async (pTarget, pAbi, pParams = []) => { + const decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: CHAIN_STRING, + }); + const supply = await sdk.api.abi.call({ + target: pTarget, + abi: pAbi, + chain: CHAIN_STRING, + params: pParams, + }); + + return pAbi == abi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * SECONDS_PER_YEAR + : supply.output * 10 ** -decimals.output; +}; + +const getMlpTvl = async () => { + const tvl = await sdk.api.abi.call({ + target: arbitrumMlpManager, + abi: abi['getAumInUsdg'], + chain: CHAIN_STRING, + params: [false], + }); + + return tvl.output * 10 ** -18; +}; + +const getStakingApr = async (pPriceData) => { + const tokensPerInterval = await sdk.api.abi.call({ + target: arbitrumMycStaking, + abi: abi['tokensPerInterval'], + chain: CHAIN_STRING, + }); + + const amountMycStaked = await sdk.api.abi.call({ + target: arbitrumMycStaking, + abi: abi['totalDepositSupply'], + chain: CHAIN_STRING, + params: [arbitrumMyc], + }); + + const amountEsMycStaked = await sdk.api.abi.call({ + target: arbitrumMycStaking, + abi: abi['totalDepositSupply'], + chain: CHAIN_STRING, + params: [arbitrumEsMyc], + }); + + const ethUsdPrice = pPriceData['coingecko:ethereum'].price; + const mycUsdPrice = pPriceData['coingecko:mycelium'].price; + + const tokensPerIntervalBN = ethers.BigNumber.from(tokensPerInterval.output); + const amountMycStakedBN = ethers.BigNumber.from(amountMycStaked.output); + const amountEsMycStakedBN = ethers.BigNumber.from(amountEsMycStaked.output); + + const totalDepositTokens = amountMycStakedBN.add(amountEsMycStakedBN); + const annualRewardsUsd = tokensPerIntervalBN + .mul(SECONDS_PER_YEAR) + .mul(ethers.utils.parseEther(ethUsdPrice.toString())); + const totalDepositUsd = totalDepositTokens.mul( + ethers.utils.parseEther(mycUsdPrice.toString()) + ); + const apr = (annualRewardsUsd / totalDepositUsd) * 100; + return apr; +}; + +const getStakingTvl = async () => { + const totalStaked = await sdk.api.abi.call({ + target: arbitrumMycStaking, + abi: abi['totalSupply'], + chain: CHAIN_STRING, + }); + + const totalAssetsBN = ethers.BigNumber.from(totalStaked.output); + + return totalAssetsBN * 10 ** -18; +}; + +const getPoolMlp = async ( + pTvl, + pInflationTracker, + pFeeMlp, + pInflationMlp, + pPriceData +) => { + const yearlyFeeMlp = pFeeMlp * pPriceData['coingecko:ethereum'].price; + const yearlyInflationMlp = + pInflationMlp * pPriceData['coingecko:mycelium'].price; + const apyFee = (yearlyFeeMlp / pTvl) * 100; + const apyInflation = (yearlyInflationMlp / pTvl) * 100; + + return { + pool: pInflationTracker, + chain: utils.formatChain(CHAIN_STRING), + project: projectSlug, + symbol: utils.formatSymbol('MLP'), + tvlUsd: parseFloat(pTvl), + apyBase: apyFee, + apyReward: apyInflation, + rewardTokens: [arbitrumMyc], + underlyingTokens: [arbitrumMyc], + underlyingTokens: [arbitrumMlp], + }; +}; + +const getPoolMyc = async (pTvl, pApy, pStaking, pPriceData) => { + return { + pool: pStaking, + chain: utils.formatChain(CHAIN_STRING), + project: projectSlug, + symbol: utils.formatSymbol('MYC'), + tvlUsd: pTvl * pPriceData['coingecko:mycelium'].price, + apyBase: pApy, + rewardTokens: [arbitrumMyc], + underlyingTokens: [arbitrumMyc], + underlyingTokens: [arbitrumMlp], + }; +}; + +const getPools = async () => { + const pools = []; + + const priceKeys = ['mycelium', 'ethereum'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const arbitrumFeeMlp = await getAdjustedAmount( + arbitrumFeeMlpTracker, + abi['tokensPerInterval'] + ); + const arbitrumInflationMlp = await getAdjustedAmount( + arbitrumInflationMlpTracker, + abi['tokensPerInterval'] + ); + pools.push( + await getPoolMlp( + await getMlpTvl(), + arbitrumInflationMlpTracker, + arbitrumFeeMlp, + arbitrumInflationMlp, + priceData + ) + ); + + pools.push( + await getPoolMyc( + await getStakingTvl(), + await getStakingApr(priceData), + arbitrumMycStaking, + priceData + ) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://swaps.mycelium.xyz/', +}; diff --git a/src/adaptors/myso-v1/index.js b/src/adaptors/myso-v1/index.js new file mode 100644 index 0000000000..abeaeb38e7 --- /dev/null +++ b/src/adaptors/myso-v1/index.js @@ -0,0 +1,376 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const zlib = require('zlib'); +const utils = require('../utils'); +const { BigNumber } = require('ethers'); +const ethers = require('ethers'); + +const PROJECT_NAME = 'myso-v1'; +const POOL_INFO_ABI = { + inputs: [], + name: 'getPoolInfo', + outputs: [ + { + internalType: 'address', + name: '_loanCcyToken', + type: 'address', + }, + { + internalType: 'address', + name: '_collCcyToken', + type: 'address', + }, + { + internalType: 'uint256', + name: '_maxLoanPerColl', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_minLoan', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_loanTenor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_totalLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_totalLpShares', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_baseAggrBucketSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_loanIdx', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const PRECISION = BigNumber.from(10).pow(18); +const YEAR_IN_SECONDS = BigNumber.from(365 * 86400); + +const mapChainIdToChainName = { + 1: 'ethereum', + 42161: 'arbitrum', +}; + +const getBalances = async ({ + poolAddress, + chain, + tokenAddress, + tokenDecimals, +}) => { + const balanceOf = ( + await sdk.api.abi.call({ + target: tokenAddress, + abi: 'erc20:balanceOf', + chain, + params: [poolAddress], + }) + ).output; + + return balanceOf / 10 ** Number(tokenDecimals); +}; + +const getPoolInfo = async ({ poolAddress }) => { + const poolInfo = await sdk.api.abi.call({ + abi: POOL_INFO_ABI, + target: poolAddress, + chain: 'ethereum', + }); + + return poolInfo.output; +}; + +const getRate = (liquidity, liqBnd_1, liqBnd_2, rate_1, rate_2) => { + if (liquidity.isZero()) return BigNumber.from(0); + + if (liquidity.lt(liqBnd_1)) { + return rate_1.mul(liqBnd_1).div(liquidity); + } else if (liquidity.lt(liqBnd_2)) { + const liquidityDelta = liqBnd_2.sub(liquidity); + const rateDelta = rate_1.sub(rate_2); + const rateNumerator = rateDelta.mul(liquidityDelta); + const rateDenominator = liqBnd_2.sub(liqBnd_1); + const ratePart_2 = rateNumerator.div(rateDenominator); + return rate_2.add(ratePart_2); + } else { + return rate_2; + } +}; + +const calculateApr = (currTotalLiquidity, pool) => { + return ethers.utils.formatUnits( + getRate( + BigNumber.from(currTotalLiquidity), + BigNumber.from(pool.lBnd1), + BigNumber.from(pool.lBnd2), + BigNumber.from(pool.r1), + BigNumber.from(pool.r2) + ) + .mul(1000000) + .mul(YEAR_IN_SECONDS) + .div(pool.loanTenor) + .div(PRECISION), + 4 + ); +}; + +const calculateBorrowApr = (totalLiquidity, pool) => { + const postLiquidity = BigNumber.from(totalLiquidity).sub(pool.minLoan); + + const avgRate = getRate( + BigNumber.from(totalLiquidity), + BigNumber.from(pool.lBnd1), + BigNumber.from(pool.lBnd2), + BigNumber.from(pool.r1), + BigNumber.from(pool.r2) + ) + .add( + getRate( + BigNumber.from(postLiquidity), + BigNumber.from(pool.lBnd1), + BigNumber.from(pool.lBnd2), + BigNumber.from(pool.r1), + BigNumber.from(pool.r2) + ) + ) + .div(2); + + const rawRate = avgRate.add(PRECISION); + const repaymentAmount = BigNumber.from(pool.minLoan) + .mul(rawRate) + .div(PRECISION); + + const numeratorAPR = repaymentAmount + .sub(pool.minLoan) + .mul(YEAR_IN_SECONDS) + .mul(10000); + + const denominatorAPR = BigNumber.from(pool.minLoan).mul(pool.loanTenor); + const APR = !denominatorAPR.isZero() + ? numeratorAPR.div(denominatorAPR) + : BigNumber.from(0); + + return APR.toNumber() / 100; +}; + +const getLTV = ( + _maxLoanPerColl, + loanTokenDecimals, + priceLoanCcy, + priceCollCcy +) => { + try { + const maxLoanPerColl = BigNumber.from(_maxLoanPerColl); + + if (maxLoanPerColl.isZero()) { + return '0'; + } + if (priceCollCcy * priceLoanCcy === 0) { + return '0'; + } + const collCcyPriceInCentsPowerNegFour = Math.round(1000000 * priceCollCcy); + const loanCcyPriceInCentsPowerNegFour = Math.round(1000000 * priceLoanCcy); + const collCcyPledgeValue = BigNumber.from(collCcyPriceInCentsPowerNegFour); + const maxLoanAmountValue = maxLoanPerColl + .mul(loanCcyPriceInCentsPowerNegFour) + .div(BigNumber.from(10).pow(loanTokenDecimals)); + // max LTV to 3 decimal places + return maxLoanAmountValue.mul(1000).div(collCcyPledgeValue); + } catch (e) { + console.log(e); + return '0'; + } +}; + +const getTokenSymbolByAddress = async ({ address, chain }) => { + return ( + await sdk.api.abi.call({ + target: address, + abi: 'erc20:symbol', + chain: chain, + }) + ).output; +}; + +const brotliDecode = (stream) => { + return new Promise((resolve, reject) => { + let responseBuffer = []; + + stream.on('data', function handleStreamData(chunk) { + responseBuffer.push(chunk); + }); + + stream.on('error', function handleStreamError(err) { + reject(err); + }); + + stream.on('end', function handleStreamEnd() { + let responseData = Buffer.concat(responseBuffer); + + responseData = responseData.toString('utf8'); + + resolve(JSON.parse(responseData)); + }); + }); +}; + +const allPools = async () => { + return ( + await Promise.all( + Object.keys(mapChainIdToChainName).map(async (chainId) => { + const response = await axios.get( + `https://api.myso.finance/chainIds/${chainId}/pools`, + { + decompress: false, + responseType: 'stream', + transformResponse: (data) => { + return data.pipe(zlib.createBrotliDecompress()); + }, + } + ); + + const chainPools = (await brotliDecode(response.data)).pools; + + if (!chainPools.length) return []; + + const { pricesByAddress: prices } = await utils.getPrices( + chainPools + .map((pool) => { + return [pool.loanTokenAddress, pool.collTokenAddress]; + }) + .flat(), + mapChainIdToChainName[chainId] + ); + + for (const key in prices) { + prices[key.toLowerCase()] = prices[key]; + } + + chainPools.forEach((pool) => { + pool.collTokenPrice = prices[pool.collTokenAddress.toLowerCase()]; + pool.loanTokenPrice = prices[pool.loanTokenAddress.toLowerCase()]; + }); + + return chainPools; + }) + ) + ).flat(); +}; + +const main = async () => { + const pools = await Promise.all( + ( + await allPools() + ).map(async (pool, i) => { + const chain = mapChainIdToChainName[pool.chainId]; + + const poolInfo = await getPoolInfo({ + poolAddress: pool.poolAddress, + }); + + const currentTotalLiquidityBalance = + poolInfo._totalLiquidity / 10 ** pool.loanTokenDecimals; + + const currentTotalLiquidityBalanceInUsd = + currentTotalLiquidityBalance * pool.loanTokenPrice; + + const currentCollTokenBalance = await getBalances({ + poolAddress: pool.poolAddress, + chain, + tokenAddress: pool.collTokenAddress, + tokenDecimals: pool.collTokenDecimals, + }); + + const currentCollTokenBalanceInUsd = + currentCollTokenBalance * pool.collTokenPrice; + + const loanTokenSymbol = await getTokenSymbolByAddress({ + address: pool.loanTokenAddress, + chain, + }); + + const collTokenSymbol = await getTokenSymbolByAddress({ + address: pool.collTokenAddress, + chain, + }); + + const ltv = + Number( + ethers.utils.formatUnits( + getLTV( + poolInfo._maxLoanPerColl, + pool.loanTokenDecimals, + pool.loanTokenPrice, + pool.collTokenPrice + ), + 1 + ) + ) / 100; + + const apyBaseBorrow = calculateBorrowApr(poolInfo._totalLiquidity, pool); + + return [ + { + pool: pool.poolAddress.toLowerCase(), + chain: utils.formatChain(chain), + project: PROJECT_NAME, + symbol: loanTokenSymbol, + tvlUsd: currentTotalLiquidityBalanceInUsd, + apyBase: Number(calculateApr(poolInfo._totalLiquidity, pool)), + underlyingTokens: [pool.loanTokenAddress, pool.collTokenAddress], + poolMeta: `Fixed interest for borrowers, ${ + Math.round(Number(pool.loanTenor) / (360 * 24)) / 10 + }days loan tenor`, + // borrow fields + totalSupplyUsd: + currentTotalLiquidityBalanceInUsd + currentCollTokenBalanceInUsd, + totalBorrowUsd: currentCollTokenBalanceInUsd, + apyBaseBorrow, + ltv, + borrowable: pool.loanVersion > '1.0', + }, + { + pool: `${pool.poolAddress.toLowerCase()}-borrow`, + chain: utils.formatChain(chain), + project: PROJECT_NAME, + symbol: collTokenSymbol, + tvlUsd: currentCollTokenBalanceInUsd, + apyBase: 0, + underlyingTokens: [pool.collTokenAddress], + poolMeta: `Fixed interest for borrowers, ${ + Math.round(Number(pool.loanTenor) / (360 * 24)) / 10 + }days loan tenor`, + totalSupplyUsd: currentCollTokenBalanceInUsd, + totalBorrowUsd: 0, + apyBaseBorrow, + ltv, + mintedCoin: loanTokenSymbol, + }, + ]; + }) + ); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.myso.finance', +}; diff --git a/src/adaptors/nabla-finance/index.js b/src/adaptors/nabla-finance/index.js new file mode 100644 index 0000000000..29ba11066e --- /dev/null +++ b/src/adaptors/nabla-finance/index.js @@ -0,0 +1,230 @@ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); + +const graphUrls = { + arbitrum: + 'https://subgraph.satsuma-prod.com/9b84d9926bf3/nabla-finance--3958960/nabla-mainnetAlpha-arbitrum/api', + base: 'https://subgraph.satsuma-prod.com/9b84d9926bf3/nabla-finance--3958960/nabla-mainnetAlpha-base/api', + berachain: + 'https://subgraph.satsuma-prod.com/9b84d9926bf3/nabla-finance--3958960/nabla-mainnetAlpha-berachain-public/api', + hyperliquid: + 'https://api.goldsky.com/api/public/project_cm7aautkjfpbg01v47kya5470/subgraphs/nabla-mainnetAlpha-hyperliquid/v0.0.3/gn', +}; + +const nablaIndexerUrls = { + monad: + 'https://indexer.nabla.fi/bsps/0x11B06EF8Adc5ea73841023CB39Be614f471213cc', +}; + +const query = gql` + query getSwapPools { + swapPools { + id + liabilities + apr7d + token { + id + } + } + } +`; + +const getPriceKey = (address, chain) => `${chain}:${address}`; + +// APR → APY conversion (7-day APR assumed, converted to daily then compounded yearly) +const apr7dToApy = (apr) => { + const aprDay = apr / 365; + return (1 + aprDay) ** 365 - 1; +}; + +// Process Nabla indexer response +const getNablaIndexerPoolsMetrics = async (chain) => { + try { + const response = await superagent.get(nablaIndexerUrls[chain]); + const data = response.body; + + if (!data.bsps || data.bsps.length === 0) { + console.log(`No BSPs found for chain: ${chain}`); + return []; + } + + const allPools = []; + + for (const bsp of data.bsps) { + const coveredPools = bsp.coveredSwapPools || []; + + if (coveredPools.length === 0) continue; + + // Collect all unique token addresses + const tokens = [...new Set(coveredPools.map((pool) => pool.asset))]; + + const priceKeys = tokens.map((address) => getPriceKey(address, chain)); + + let usdPrices = {}; + try { + const priceResponse = await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys + .join(',') + .toLowerCase()}` + ); + usdPrices = priceResponse.body.coins || {}; + } catch (err) { + console.error(`Failed fetching prices for chain ${chain}:`, err); + continue; + } + + for (const pool of coveredPools) { + const { + address: poolAddress, + asset: tokenAddress, + asset_symbol, + asset_decimals, + total_liabilities, + weekly_apr, + } = pool; + + const key = getPriceKey(tokenAddress, chain).toLowerCase(); + const priceData = usdPrices[key]; + + if (!priceData) { + console.log(`No price data found for token: ${key}`); + continue; + } + + const { price } = priceData; + const decimals = asset_decimals || 18; + + // Calculate TVL from total_liabilities + const tvlNormalized = BigNumber(total_liabilities || 0).div( + 10 ** decimals + ); + const tvlUsd = tvlNormalized.times(price).toNumber(); + + // Convert weekly APR to APY (weekly_apr is already in %) + const aprDecimal = Number(weekly_apr || 0) / 100; + const apyBase = apr7dToApy(aprDecimal) * 100; + + allPools.push({ + pool: `${poolAddress}-${chain}`, + chain: utils.formatChain(chain), + project: 'nabla-finance', + symbol: utils.formatSymbol(asset_symbol), + underlyingTokens: [tokenAddress], + tvlUsd: tvlUsd, + apyBase: apyBase, + }); + } + } + + return allPools; + } catch (error) { + console.error( + `Error fetching pools from Monad indexer for chain ${chain}:`, + error + ); + return []; + } +}; + +const getGraphPoolsMetrics = async (chain) => { + try { + const swapPools = (await request(graphUrls[chain], query)).swapPools; + + if (!swapPools || swapPools.length === 0) { + console.log(`No swap pools found for chain: ${chain}`); + return []; + } + + const tokens = [...new Set(swapPools.map((swapPool) => swapPool.token.id))]; + + const priceKeys = tokens.map((address) => getPriceKey(address, chain)); + + let usdPrices = {}; + try { + const priceResponse = await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys + .join(',') + .toLowerCase()}` + ); + usdPrices = priceResponse.body.coins || {}; + } catch (err) { + console.error(`Failed fetching prices for chain ${chain}:`, err); + return []; + } + + return swapPools + .map((swapPool) => { + const { id: pool, liabilities: tvl, apr7d, token } = swapPool; + const tokenAddress = token.id; + + const key = getPriceKey(tokenAddress, chain).toLowerCase(); + const priceData = usdPrices[key]; + + if (!priceData) { + console.log(`No price data found for token: ${key}`); + return null; + } + + const { decimals, symbol, price } = priceData; + + const tvlNormalized = BigNumber(tvl).div(10 ** (decimals || 18)); + const tvlUsd = tvlNormalized.times(price).toNumber(); + + const aprNormalized = Number(apr7d || 0) / 10 ** (decimals || 18); + const apyBase = apr7dToApy(aprNormalized) * 100; + + return { + pool: `${pool}-${chain}`, + chain: utils.formatChain(chain), + project: 'nabla-finance', + symbol: utils.formatSymbol(symbol), + underlyingTokens: [tokenAddress], + tvlUsd: tvlUsd, + apyBase: apyBase, + }; + }) + .filter(Boolean); + } catch (error) { + console.error(`Error fetching pools for chain ${chain}:`, error); + return []; + } +}; + +const poolsOnAllChains = async () => { + const graphChains = Object.keys(graphUrls); + const nablaIndexerChains = Object.keys(nablaIndexerUrls); + + // Fetch from GraphQL subgraphs + const graphPoolsPromises = graphChains.map((chain) => + getGraphPoolsMetrics(chain).catch((error) => { + console.error(`Failed to fetch pools for chain ${chain}:`, error); + return []; + }) + ); + + // Fetch from Nabla indexer + const nablaIndexerPoolsPromises = nablaIndexerChains.map((chain) => + getNablaIndexerPoolsMetrics(chain).catch((error) => { + console.error( + `Failed to fetch pools from indexer for chain ${chain}:`, + error + ); + return []; + }) + ); + + const allPoolsPromises = [ + ...graphPoolsPromises, + ...nablaIndexerPoolsPromises, + ]; + const allPools = await Promise.all(allPoolsPromises); + return allPools.flat(); +}; + +module.exports = { + timetravel: false, + apy: poolsOnAllChains, + url: 'https://app.nabla.fi/pools', +}; diff --git a/src/adaptors/napier/index.js b/src/adaptors/napier/index.js new file mode 100644 index 0000000000..5e478f9332 --- /dev/null +++ b/src/adaptors/napier/index.js @@ -0,0 +1,124 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const chains = { + 1: { + name: 'ethereum', + slug: 'mainnet', + }, + 8453: { + name: 'base', + slug: 'base', + }, + 42161: { + name: 'arbitrum', + slug: 'arbitrum', + }, + 10: { + name: 'optimism', + slug: 'optimism', + }, + 146: { + name: 'sonic', + slug: 'sonic', + }, + 5000: { + name: 'mantle', + slug: 'mantle', + }, + 56: { + name: 'bsc', + slug: 'binance', + }, + 137: { + name: 'polygon', + slug: 'polygon', + }, + 43114: { + name: 'avax', + slug: 'avalanche', + }, + 252: { + name: 'fraxtal', + slug: 'fraxtal', + }, + 999: { + name: 'hyperliquid', + slug: 'hyperliquid', + }, +}; + +const api = `https://api-v2.napier.finance/v1/market?minimumTvlUsd=0&orderBy=totalTvlInUsd&orderDirection=desc&skip=0&take=10000`; + +const formatMaturity = (maturity) => + new Date(Number(maturity) * 1000).toDateString('en-US'); + +const tokenId = (address, chainId) => + `${address}-${chains[chainId].name}`.toLowerCase(); + +async function apy() { + const res = await axios.get(api); + const markets = res.data; + + const apys = markets + .filter((m) => !m.status.isMatured) + .map((market) => { + const chainId = market.metadata.chainId; + const chain = chains[chainId]; + + const rewardTokens = + market.metrics.underlyingRewards + ?.filter((r) => r?.rewardToken?.address) + ?.map((r) => r.rewardToken.address) || []; + const rewardApy = market.metrics.underlyingRewardsApy || 0; + + // LP Pool APY + const lpApy = { + pool: tokenId(market.tokens.poolToken.address, chainId), + chain: utils.formatChain(chain.name), + project: 'napier', + symbol: utils.formatSymbol(market.tokens.targetToken.symbol), + tvlUsd: Number(market.metrics.poolTvlInUsdFmt), + apyBase: Number(market.metrics.poolBaseApy), + apyReward: Number(rewardApy), + rewardTokens, + underlyingTokens: [ + market.tokens.principalToken.address, + market.tokens.targetToken.address, + ], + poolMeta: `LP Pool | Maturity ${formatMaturity( + market.maturityTimestamp + )}`, + url: `https://app.napier.finance/user/pool/${chainId}/${market.tokens.principalToken.address}/zap/add`, + }; + + // Fixed Rate (Principal Token) APY + const ptApy = { + pool: tokenId(market.tokens.principalToken.address, chainId), + chain: utils.formatChain(chain.name), + project: 'napier', + symbol: utils.formatSymbol(market.tokens.targetToken.symbol), + tvlUsd: Number(market.metrics.ptTvlInUsdFmt), + apyBase: Number(market.metrics.impliedApy), + apyReward: Number(rewardApy), + rewardTokens, + underlyingTokens: [market.tokens.targetToken.address], + poolMeta: `Principal Token | Maturity ${formatMaturity( + market.maturityTimestamp + )}`, + url: `https://app.napier.finance/user/mint/${chainId}/${market.tokens.principalToken.address}/mint`, + }; + + return [lpApy, ptApy]; + }) + .flat() + .filter((p) => utils.keepFinite(p)) + .sort((a, b) => b.tvlUsd - a.tvlUsd); + + return apys; +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/native-credit-pool/index.js b/src/adaptors/native-credit-pool/index.js new file mode 100644 index 0000000000..3f2bcd8415 --- /dev/null +++ b/src/adaptors/native-credit-pool/index.js @@ -0,0 +1,298 @@ +const utils = require('../utils'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const API_KEY = '9985778c880fe83f15135345e0726f4bd33e728c'; +const CHAINS = ['ethereum', 'bsc', 'arbitrum', 'base']; + +// Chain ID mapping for URLs +const CHAIN_IDS = { + ethereum: 1, + bsc: 56, + arbitrum: 42161, + base: 8453, +}; + +// ABI for totalUnderlying function +const totalUnderlyingABI = { + constant: true, + inputs: [], + name: 'totalUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', +}; + +/** + * Fetch APY data from Native API for a specific chain + */ +const fetchApyData = async (chain) => { + try { + const response = await axios.get( + `https://v2.api.native.org/swap-api-v2/v2/lend/historical-apy?chain=${chain}`, + { + headers: { + apiKey: API_KEY, + }, + } + ); + // Ensure we always return an array + const data = response.data; + if (!Array.isArray(data)) { + console.warn( + `API returned non-array data for ${chain}:`, + typeof data, + data + ); + return []; + } + return data; + } catch (error) { + console.error( + `Error fetching APY data for ${chain}:`, + error.message, + error.response?.status, + error.response?.data + ); + return []; + } +}; + +/** + * Batch fetch total underlying amounts for all LP tokens on a chain + */ +const batchFetchTotalUnderlying = async (lpTokenAddresses, chain) => { + if (lpTokenAddresses.length === 0) return {}; + + try { + const results = await sdk.api.abi.multiCall({ + calls: lpTokenAddresses.map((address) => ({ target: address })), + abi: totalUnderlyingABI, + chain: chain, + permitFailure: true, + }); + + const tvlMap = {}; + results.output.forEach((result, index) => { + const address = lpTokenAddresses[index].toLowerCase(); + tvlMap[address] = result.output ? BigInt(result.output) : BigInt(0); + }); + + return tvlMap; + } catch (error) { + console.error( + `Error batch fetching totalUnderlying for ${chain}:`, + error.message + ); + return {}; + } +}; + +/** + * Batch fetch token symbols and decimals for all tokens on a chain + */ +const batchFetchTokenInfo = async (tokenAddresses, chain) => { + if (tokenAddresses.length === 0) return {}; + + try { + const [symbolResults, decimalsResults] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: tokenAddresses.map((address) => ({ target: address })), + abi: 'erc20:symbol', + chain: chain, + requery: true, + permitFailure: true, + }), + sdk.api.abi.multiCall({ + calls: tokenAddresses.map((address) => ({ target: address })), + abi: 'erc20:decimals', + chain: chain, + requery: true, + permitFailure: true, + }), + ]); + + const tokenInfoMap = {}; + tokenAddresses.forEach((address, index) => { + const addr = address.toLowerCase(); + tokenInfoMap[addr] = { + symbol: + symbolResults.output[index]?.output || 'UNKNOWN', + decimals: decimalsResults.output[index]?.output || 18, + }; + }); + + return tokenInfoMap; + } catch (error) { + console.error(`Error batch fetching token info for ${chain}:`, error.message); + return {}; + } +}; + +/** + * Batch fetch token prices from DefiLlama + * Chunks requests to avoid API limits (max 100 tokens per request) + */ +const batchFetchTokenPrices = async (tokenAddresses, chain) => { + if (tokenAddresses.length === 0) return {}; + + const MAX_TOKENS_PER_REQUEST = 100; + const pricesMap = {}; + + try { + // Chunk token addresses into batches + for (let i = 0; i < tokenAddresses.length; i += MAX_TOKENS_PER_REQUEST) { + const batch = tokenAddresses.slice(i, i + MAX_TOKENS_PER_REQUEST); + const priceKeys = batch + .map((addr) => `${chain}:${addr}`.toLowerCase()) + .join(','); + + const response = await axios.get( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + batch.forEach((address) => { + const priceKey = `${chain}:${address}`.toLowerCase(); + const priceData = response.data?.coins?.[priceKey]; + pricesMap[address.toLowerCase()] = priceData?.price || 0; + }); + } + + return pricesMap; + } catch (error) { + console.error( + `Error batch fetching prices for ${chain}:`, + error.message + ); + return pricesMap; + } +}; + +/** + * Calculate TVL in USD + */ +const calculateTvlUsd = (totalUnderlying, decimals, price) => { + const totalUnderlyingDecimal = Number(totalUnderlying) / 10 ** decimals; + return totalUnderlyingDecimal * price; +}; + +/** + * Main function to fetch all pools + */ +const apy = async () => { + const pools = []; + + // Fetch APY data for all chains in parallel + const apyDataPromises = CHAINS.map((chain) => fetchApyData(chain)); + const apyDataResults = await Promise.all(apyDataPromises); + + // Process each chain's data + for (let chainIndex = 0; chainIndex < CHAINS.length; chainIndex++) { + const chain = CHAINS[chainIndex]; + const apyData = apyDataResults[chainIndex]; + + // Ensure apyData is an array + if (!Array.isArray(apyData) || apyData.length === 0) { + console.warn(`No APY data found for chain: ${chain}`); + continue; + } + + // Filter valid pools and collect unique addresses + const validPools = apyData.filter( + (pool) => pool.lpTokenAddress && pool.address + ); + + if (validPools.length === 0) { + continue; + } + + // Collect unique addresses for batching + const lpTokenAddresses = [ + ...new Set(validPools.map((p) => p.lpTokenAddress.toLowerCase())), + ]; + const underlyingTokenAddresses = [ + ...new Set(validPools.map((p) => p.address.toLowerCase())), + ]; + + // Batch fetch all data for this chain + const [tvlMap, tokenInfoMap, pricesMap] = await Promise.all([ + batchFetchTotalUnderlying(lpTokenAddresses, chain), + batchFetchTokenInfo(underlyingTokenAddresses, chain), + batchFetchTokenPrices(underlyingTokenAddresses, chain), + ]); + + // Process each pool using the batched data + for (const poolData of validPools) { + try { + const { address, lpTokenAddress, fundingAPY } = poolData; + const lpAddr = lpTokenAddress.toLowerCase(); + const underlyingAddr = address.toLowerCase(); + + // Get data from batched results + const totalUnderlying = tvlMap[lpAddr] || BigInt(0); + const tokenInfo = tokenInfoMap[underlyingAddr] || { + symbol: 'UNKNOWN', + decimals: 18, + }; + const tokenPrice = pricesMap[underlyingAddr] || 0; + + // Calculate TVL + const tvlUsd = calculateTvlUsd( + totalUnderlying, + tokenInfo.decimals, + tokenPrice + ); + + // Skip pools with zero or invalid TVL + if (!tvlUsd || tvlUsd <= 0 || !Number.isFinite(tvlUsd)) { + continue; + } + + // Format symbol with 'n' prefix + const symbol = `n${utils.formatSymbol(tokenInfo.symbol)}`; + + // Format pool identifier + const poolId = `${lpAddr}-${chain}`; + + // Format chain name + const formattedChain = utils.formatChain(chain); + + // Get chain ID and underlying ticker for URL + const chainId = CHAIN_IDS[chain]; + const underlyingTicker = utils.formatSymbol(tokenInfo.symbol); + + // Build individual pool URL + const poolUrl = `https://native.org/app/credit-pool/?chainId=${chainId}&action=deposit&token0=${underlyingTicker}`; + + pools.push({ + pool: poolId, + chain: formattedChain, + project: 'native-credit-pool', + symbol: symbol, + tvlUsd: tvlUsd, + apyBase: fundingAPY || 0, + underlyingTokens: [underlyingAddr], + poolMeta: 'single-side, no-loss LP', + url: poolUrl, + }); + } catch (error) { + console.error( + `Error processing pool on ${chain}:`, + error.message, + poolData + ); + } + } + } + + // Final filter to ensure no pools with zero or invalid TVL + return pools.filter((pool) => pool.tvlUsd > 0 && Number.isFinite(pool.tvlUsd)); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://native.org', +}; + diff --git a/src/adaptors/navi-lending/index.js b/src/adaptors/navi-lending/index.js new file mode 100644 index 0000000000..3c22c84cce --- /dev/null +++ b/src/adaptors/navi-lending/index.js @@ -0,0 +1,37 @@ +const axios = require('axios'); +const baseUrl = 'https://open-api.naviprotocol.io/api/poolsinfo'; + +const poolsFunction = async () => { + const response = await axios.get(baseUrl); + const data = response.data.pools; + const arr = []; + + Object.keys(data).forEach((key) => { + const pool = data[key]; + const supplyUsd = parseFloat(pool.total_supply) * parseFloat(pool.tokenPrice); + const borrowUsd = parseFloat(pool.total_borrow) * parseFloat(pool.tokenPrice); + arr.push({ + chain: 'Sui', + project: 'navi-lending', + pool: pool.pool, + symbol: pool.symbol, + tvlUsd: supplyUsd - borrowUsd, + apyBase: parseFloat(pool.base_supply_rate), + apyReward: pool.boosted_supply_rate ? parseFloat(pool.boosted_supply_rate) : null, + rewardTokens: pool.rewardTokenAddress ? pool.rewardTokenAddress : [], + totalSupplyUsd: supplyUsd, + totalBorrowUsd: borrowUsd, + apyBaseBorrow: parseFloat(pool.base_borrow_rate), + }); + }); + + return arr; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.naviprotocol.io/', +}; + +//poolsFunction().then(res => console.log(res)); \ No newline at end of file diff --git a/src/adaptors/nayms/index.js b/src/adaptors/nayms/index.js new file mode 100644 index 0000000000..18a0e83e8e --- /dev/null +++ b/src/adaptors/nayms/index.js @@ -0,0 +1,76 @@ +const superagent = require('superagent'); + +const chainNames = { + 1: 'Ethereum', + 8453: 'Base', +}; + +const formatString = (inputArray) => + inputArray + .map((str) => + str + .split(/_|(?=[A-Z])/) + .map( + (word) => + `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}` + ) + .join(' ') + ) + .join(', '); + +const fetchData = async (chainId) => { + try { + const { + body: { data }, + } = await superagent + .get('https://api.nayms.com/opportunity/public') + .accept('application/json') + .set({ + 'X-Nayms-Network-Id': chainId.toString(), + Origin: 'https://app.nayms.com', + }); + + return data + .filter(({ cellStatus }) => cellStatus !== 'CLOSED') + .map( + ({ + id, + participationTokenSymbol, + paidInCapital, + targetRoiMin, + assetToken, + businessTypes, + cellStatus, + }) => ({ + pool: id, + chain: chainNames[chainId] ?? 'Unknown Chain', + project: 'nayms', + symbol: assetToken?.symbol, + tvlUsd: paidInCapital, + apy: targetRoiMin, + underlyingTokens: [assetToken?.address], + poolMeta: `${participationTokenSymbol}, ${formatString( + businessTypes + )} (Status: ${cellStatus})`, + }) + ); + } catch (err) { + throw new Error( + `Network response was not ok: ${err.status ?? 'unknown'} - ${ + err.response?.text ?? err.message ?? 'No response text' + }` + ); + } +}; + +const apy = async () => { + const chainsToFetch = [1, 8453]; + const data = await Promise.all(chainsToFetch.map(fetchData)); + return data.flat().filter((i) => i.symbol); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.nayms.com/opportunities', +}; diff --git a/src/adaptors/nerveswap/index.js b/src/adaptors/nerveswap/index.js new file mode 100644 index 0000000000..bd85a4a6ee --- /dev/null +++ b/src/adaptors/nerveswap/index.js @@ -0,0 +1,30 @@ +const axios = require('axios'); +const utils = require('../utils'); +const { BigNumber } = require("bignumber.js"); +const baseURL = "https://api.swap.nerve.network/swap"; + +const getApy = async () => { + let pools = (await axios.get(baseURL + '/pools')).data.data.list; + pools = pools.map((p) => { + const apyReward = Number(p.lpMintingAPR); + return { + pool: p.address, + chain: 'Nuls', + project: 'nerveswap', + symbol: utils.formatSymbol(`${p.token0Symbol}-${p.token1Symbol}`), + tvlUsd: Number(new BigNumber(p.reserveUsdtValue).shiftedBy(-18).toFixed(6)), + apyBase: p.feeUsdtValueARP / 100, + apyReward: apyReward > 0 ? apyReward : null, + rewardTokens: apyReward > 0 ? [p.lpMintingToken] : [], + volumeUsd1d: Number(new BigNumber(p.amountUsdtValue24H).shiftedBy(-18).toFixed(6)), + volumeUsd7d: Number(new BigNumber(p.amountUsdtValue7D).shiftedBy(-18).toFixed(6)), + poolMeta: null + }; + }); + return pools; +}; + +module.exports = { + apy: getApy, + url: 'https://nerve.network/info/pools', +}; diff --git a/src/adaptors/nest-credit/index.js b/src/adaptors/nest-credit/index.js new file mode 100644 index 0000000000..e7ba3c2c5b --- /dev/null +++ b/src/adaptors/nest-credit/index.js @@ -0,0 +1,57 @@ +// adapters/nest-vaults.js +const utils = require('../utils'); + +const DETAILS_URL = 'https://api.nest.credit/v1/vaults/details?live=true'; +const PLUME_CHAIN_KEY = 'plume'; +const PLUME_CHAIN_ID = 98866; + +const poolsFunction = async () => { + const res = await utils.getData(DETAILS_URL); + const vaults = Array.isArray(res?.data) ? res.data : []; + + const pools = vaults.map((v) => { + const address = (v.vaultAddress || '').toLowerCase(); + + // Calculate 7-day APY, fallback to 0 if empty + const apy7dSrc = v?.apy?.rolling7d; + let apyBase = 0; // Default to 0 if empty + + if (apy7dSrc !== undefined && apy7dSrc !== null && apy7dSrc !== '') { + const apy7day = Number(apy7dSrc) * 100; + if (Number.isFinite(apy7day)) { + apyBase = apy7day; + } + } + + // Prefer Plume-native underlying tokens + const underlyingTokens = (v.liquidAssets || []) + .filter((a) => a?.chainId === PLUME_CHAIN_ID && a?.contractAddress) + .map((a) => a.contractAddress.toLowerCase()); + + const pool = { + // ✅ pool = vault address (lowercased) + pool: address, + chain: utils.formatChain(PLUME_CHAIN_KEY), + project: 'nest-credit', + symbol: utils.formatSymbol(v.symbol || 'NEST'), + tvlUsd: Number(v.tvl || 0), + apyBase: apyBase, + url: `https://app.nest.credit/vaults/${v.slug}`, + }; + + // Set underlying tokens if available + if (underlyingTokens.length) { + pool.underlyingTokens = [...new Set(underlyingTokens)]; + } + + return pool; + }); + + return pools.filter((p) => p.pool && p.chain && Number.isFinite(p.tvlUsd)); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.nest.credit', +}; diff --git a/src/adaptors/neutra-finance/abis/camelotPool.json b/src/adaptors/neutra-finance/abis/camelotPool.json new file mode 100644 index 0000000000..9d223436cf --- /dev/null +++ b/src/adaptors/neutra-finance/abis/camelotPool.json @@ -0,0 +1,682 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "DrainWrongToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "token0FeePercent", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "token1FeePercent", + "type": "uint16" + } + ], + "name": "FeePercentUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "SetPairTypeImmutable", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "prevStableSwap", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stableSwap", + "type": "bool" + } + ], + "name": "SetStableSwap", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Skim", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE_PERCENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "drainWrongToken", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint112", "name": "_reserve0", "type": "uint112" }, + { "internalType": "uint112", "name": "_reserve1", "type": "uint112" }, + { + "internalType": "uint16", + "name": "_token0FeePercent", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_token1FeePercent", + "type": "uint16" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "initialized", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "pairTypeImmutable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "precisionMultiplier0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "precisionMultiplier1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint16", + "name": "newToken0FeePercent", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "newToken1FeePercent", + "type": "uint16" + } + ], + "name": "setFeePercent", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "setPairTypeImmutable", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "bool", "name": "stable", "type": "bool" }, + { + "internalType": "uint112", + "name": "expectedReserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "expectedReserve1", + "type": "uint112" + } + ], + "name": "setStableSwap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "stableSwap", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" }, + { "internalType": "address", "name": "referrer", "type": "address" } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0FeePercent", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1FeePercent", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/neutra-finance/abis/nUSDC.json b/src/adaptors/neutra-finance/abis/nUSDC.json new file mode 100644 index 0000000000..78787bf1be --- /dev/null +++ b/src/adaptors/neutra-finance/abis/nUSDC.json @@ -0,0 +1,888 @@ +[ + { + "name": "Transfer", + "inputs": [ + { "name": "sender", "type": "address", "indexed": true }, + { "name": "receiver", "type": "address", "indexed": true }, + { "name": "value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Approval", + "inputs": [ + { "name": "owner", "type": "address", "indexed": true }, + { "name": "spender", "type": "address", "indexed": true }, + { "name": "value", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Deposit", + "inputs": [ + { "name": "recipient", "type": "address", "indexed": true }, + { "name": "shares", "type": "uint256", "indexed": false }, + { "name": "amount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Withdraw", + "inputs": [ + { "name": "recipient", "type": "address", "indexed": true }, + { "name": "shares", "type": "uint256", "indexed": false }, + { "name": "amount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "Sweep", + "inputs": [ + { "name": "token", "type": "address", "indexed": true }, + { "name": "amount", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "LockedProfitDegradationUpdated", + "inputs": [{ "name": "value", "type": "uint256", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyAdded", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "debtRatio", "type": "uint256", "indexed": false }, + { "name": "minDebtPerHarvest", "type": "uint256", "indexed": false }, + { "name": "maxDebtPerHarvest", "type": "uint256", "indexed": false }, + { "name": "performanceFee", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyReported", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "gain", "type": "uint256", "indexed": false }, + { "name": "loss", "type": "uint256", "indexed": false }, + { "name": "debtPaid", "type": "uint256", "indexed": false }, + { "name": "totalGain", "type": "uint256", "indexed": false }, + { "name": "totalLoss", "type": "uint256", "indexed": false }, + { "name": "totalDebt", "type": "uint256", "indexed": false }, + { "name": "debtAdded", "type": "uint256", "indexed": false }, + { "name": "debtRatio", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "FeeReport", + "inputs": [ + { "name": "management_fee", "type": "uint256", "indexed": false }, + { "name": "performance_fee", "type": "uint256", "indexed": false }, + { "name": "strategist_fee", "type": "uint256", "indexed": false }, + { "name": "duration", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "WithdrawFromStrategy", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "totalDebt", "type": "uint256", "indexed": false }, + { "name": "loss", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateGovernance", + "inputs": [{ "name": "governance", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateManagement", + "inputs": [{ "name": "management", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateRewards", + "inputs": [{ "name": "rewards", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateDepositLimit", + "inputs": [{ "name": "depositLimit", "type": "uint256", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdatePerformanceFee", + "inputs": [ + { "name": "performanceFee", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateManagementFee", + "inputs": [ + { "name": "managementFee", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateGuardian", + "inputs": [{ "name": "guardian", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "EmergencyShutdown", + "inputs": [{ "name": "active", "type": "bool", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "UpdateWithdrawalQueue", + "inputs": [{ "name": "queue", "type": "address[20]", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyUpdateDebtRatio", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "debtRatio", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyUpdateMinDebtPerHarvest", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "minDebtPerHarvest", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyUpdateMaxDebtPerHarvest", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "maxDebtPerHarvest", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyUpdatePerformanceFee", + "inputs": [ + { "name": "strategy", "type": "address", "indexed": true }, + { "name": "performanceFee", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyMigrated", + "inputs": [ + { "name": "oldVersion", "type": "address", "indexed": true }, + { "name": "newVersion", "type": "address", "indexed": true } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyRevoked", + "inputs": [{ "name": "strategy", "type": "address", "indexed": true }], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyRemovedFromQueue", + "inputs": [{ "name": "strategy", "type": "address", "indexed": true }], + "anonymous": false, + "type": "event" + }, + { + "name": "StrategyAddedToQueue", + "inputs": [{ "name": "strategy", "type": "address", "indexed": true }], + "anonymous": false, + "type": "event" + }, + { + "name": "NewPendingGovernance", + "inputs": [ + { "name": "pendingGovernance", "type": "address", "indexed": true } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "token", "type": "address" }, + { "name": "governance", "type": "address" }, + { "name": "rewards", "type": "address" }, + { "name": "nameOverride", "type": "string" }, + { "name": "symbolOverride", "type": "string" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "token", "type": "address" }, + { "name": "governance", "type": "address" }, + { "name": "rewards", "type": "address" }, + { "name": "nameOverride", "type": "string" }, + { "name": "symbolOverride", "type": "string" }, + { "name": "guardian", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "token", "type": "address" }, + { "name": "governance", "type": "address" }, + { "name": "rewards", "type": "address" }, + { "name": "nameOverride", "type": "string" }, + { "name": "symbolOverride", "type": "string" }, + { "name": "guardian", "type": "address" }, + { "name": "management", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "pure", + "type": "function", + "name": "apiVersion", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "DOMAIN_SEPARATOR", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setName", + "inputs": [{ "name": "name", "type": "string" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setSymbol", + "inputs": [{ "name": "symbol", "type": "string" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setGovernance", + "inputs": [{ "name": "governance", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "acceptGovernance", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setManagement", + "inputs": [{ "name": "management", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setRewards", + "inputs": [{ "name": "rewards", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setLockedProfitDegradation", + "inputs": [{ "name": "degradation", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setDepositLimit", + "inputs": [{ "name": "limit", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setPerformanceFee", + "inputs": [{ "name": "fee", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setManagementFee", + "inputs": [{ "name": "fee", "type": "uint256" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setGuardian", + "inputs": [{ "name": "guardian", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setEmergencyShutdown", + "inputs": [{ "name": "active", "type": "bool" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "setWithdrawalQueue", + "inputs": [{ "name": "queue", "type": "address[20]" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transfer", + "inputs": [ + { "name": "receiver", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "transferFrom", + "inputs": [ + { "name": "sender", "type": "address" }, + { "name": "receiver", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "approve", + "inputs": [ + { "name": "spender", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "increaseAllowance", + "inputs": [ + { "name": "spender", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "decreaseAllowance", + "inputs": [ + { "name": "spender", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "permit", + "inputs": [ + { "name": "owner", "type": "address" }, + { "name": "spender", "type": "address" }, + { "name": "amount", "type": "uint256" }, + { "name": "expiry", "type": "uint256" }, + { "name": "signature", "type": "bytes" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalAssets", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [{ "name": "_amount", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deposit", + "inputs": [ + { "name": "_amount", "type": "uint256" }, + { "name": "recipient", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "maxAvailableShares", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [{ "name": "maxShares", "type": "uint256" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { "name": "maxShares", "type": "uint256" }, + { "name": "recipient", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "withdraw", + "inputs": [ + { "name": "maxShares", "type": "uint256" }, + { "name": "recipient", "type": "address" }, + { "name": "maxLoss", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "pricePerShare", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "addStrategy", + "inputs": [ + { "name": "strategy", "type": "address" }, + { "name": "debtRatio", "type": "uint256" }, + { "name": "minDebtPerHarvest", "type": "uint256" }, + { "name": "maxDebtPerHarvest", "type": "uint256" }, + { "name": "performanceFee", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "updateStrategyDebtRatio", + "inputs": [ + { "name": "strategy", "type": "address" }, + { "name": "debtRatio", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "updateStrategyMinDebtPerHarvest", + "inputs": [ + { "name": "strategy", "type": "address" }, + { "name": "minDebtPerHarvest", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "updateStrategyMaxDebtPerHarvest", + "inputs": [ + { "name": "strategy", "type": "address" }, + { "name": "maxDebtPerHarvest", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "updateStrategyPerformanceFee", + "inputs": [ + { "name": "strategy", "type": "address" }, + { "name": "performanceFee", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "migrateStrategy", + "inputs": [ + { "name": "oldVersion", "type": "address" }, + { "name": "newVersion", "type": "address" } + ], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "revokeStrategy", + "inputs": [], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "revokeStrategy", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "addStrategyToQueue", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "removeStrategyFromQueue", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debtOutstanding", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debtOutstanding", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "creditAvailable", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "creditAvailable", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "availableDepositLimit", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "expectedReturn", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "expectedReturn", + "inputs": [{ "name": "strategy", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "report", + "inputs": [ + { "name": "gain", "type": "uint256" }, + { "name": "loss", "type": "uint256" }, + { "name": "_debtPayment", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "sweep", + "inputs": [{ "name": "token", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "sweep", + "inputs": [ + { "name": "token", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "name", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [{ "name": "", "type": "string" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "balanceOf", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "allowance", + "inputs": [ + { "name": "arg0", "type": "address" }, + { "name": "arg1", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "token", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "governance", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "management", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "guardian", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "strategies", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { "name": "performanceFee", "type": "uint256" }, + { "name": "activation", "type": "uint256" }, + { "name": "debtRatio", "type": "uint256" }, + { "name": "minDebtPerHarvest", "type": "uint256" }, + { "name": "maxDebtPerHarvest", "type": "uint256" }, + { "name": "lastReport", "type": "uint256" }, + { "name": "totalDebt", "type": "uint256" }, + { "name": "totalGain", "type": "uint256" }, + { "name": "totalLoss", "type": "uint256" } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "withdrawalQueue", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "emergencyShutdown", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "depositLimit", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "debtRatio", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalIdle", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "totalDebt", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lastReport", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "activation", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lockedProfit", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "lockedProfitDegradation", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "managementFee", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "performanceFee", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "nonces", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }] + } +] diff --git a/src/adaptors/neutra-finance/abis/snUSDC.json b/src/adaptors/neutra-finance/abis/snUSDC.json new file mode 100644 index 0000000000..17df0c543b --- /dev/null +++ b/src/adaptors/neutra-finance/abis/snUSDC.json @@ -0,0 +1,1019 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "averageStakedAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "claim", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "claimForAccount", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimables", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "cumulativeRewardPerTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "cumulativeRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "depositBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "esNeu", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateClaimingMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateStakingMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inPrivateTransferMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_depositTokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_distributor", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isDepositToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isHandler", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "previousCumulatedRewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isDepositToken", + "type": "bool" + } + ], + "name": "setDepositToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_distributor", + "type": "address" + } + ], + "name": "setDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_handler", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_handler", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_isActive", + "type": "bool[]" + } + ], + "name": "setHandlers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateClaimingMode", + "type": "bool" + } + ], + "name": "setInPrivateClaimingMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateStakingMode", + "type": "bool" + } + ], + "name": "setInPrivateStakingMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_inPrivateTransferMode", + "type": "bool" + } + ], + "name": "setInPrivateTransferMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_fundingAccount", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stakeForAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "stakedAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalDepositSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "unstakeForAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/src/adaptors/neutra-finance/abis/strategyVault.json b/src/adaptors/neutra-finance/abis/strategyVault.json new file mode 100644 index 0000000000..b84189c1b3 --- /dev/null +++ b/src/adaptors/neutra-finance/abis/strategyVault.json @@ -0,0 +1,1733 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "StrategyVaultV2", + "sourceName": "contracts/StrategyVaultV2.sol", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "adjustAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prepaidGmxFee", + "type": "uint256" + } + ], + "name": "AdjustPrepaidGmxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BuyGlp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "BuyNeuGlp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "alpha", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastCollect", + "type": "uint256" + } + ], + "name": "CollectManagementFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcFundingFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pendingPositionFeeInfo", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prepaidGmxFee", + "type": "uint256" + } + ], + "name": "ConfirmFundingFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lastUpdatedFundingRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcFundingRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethFundingRate", + "type": "uint256" + } + ], + "name": "ConfirmFundingRates", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "hasDebt", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "delta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prepaidGmxFee", + "type": "uint256" + } + ], + "name": "ConfirmRebalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_collateralDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "DecreaseShortPosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcCollateralDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcSizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethCollateralDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethSizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "shouldRepayWbtc", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "shouldRepayWeth", + "type": "bool" + } + ], + "name": "DecreaseShortPositionsWithCallback", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "insuranceFund", + "type": "uint256" + } + ], + "name": "DepositInsuranceFund", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeReserves", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + } + ], + "name": "IncreaseShortPosition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcAmountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcSizeDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethAmountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethSizeDelta", + "type": "uint256" + } + ], + "name": "IncreaseShortPositionsWithCallback", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fundingFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prePaidGmxFee", + "type": "uint256" + } + ], + "name": "InstantRepayFundingFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBuy", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "hasWbtcIncrease", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "hasWbtcDecrease", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "hasWethIncrease", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "hasWethDecrease", + "type": "bool" + } + ], + "name": "RebalanceActions", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "usdgAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feeBasisPoints", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSizeDelta", + "type": "uint256" + } + ], + "name": "RebalanceFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "wbtcFundingFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wethFundingFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "prepaidGmxFee", + "type": "uint256" + } + ], + "name": "RepayFundingFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "unpaidFundingFeeWbtc", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unpaidFundingFeeWeth", + "type": "uint256" + } + ], + "name": "RepayUnpaidFundingFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "SellGlp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "SellNeuGlp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "indexToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fundingFee", + "type": "uint256" + } + ], + "name": "SetFundingFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "gov", + "type": "address" + } + ], + "name": "SetGov", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "Settle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawEth", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "WithdrawFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "WithdrawInsuranceFund", + "type": "event" + }, + { + "inputs": [], + "name": "activateManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "adjustPrepaidGmxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_spender", + "type": "address" + } + ], + "name": "approveToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "buyGlp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "callbackTarget", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "confirmCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "confirmList", + "outputs": [ + { + "internalType": "bool", + "name": "hasDecrease", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "beforeWantBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "confirmRebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "confirmed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deactivateManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_collateralDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "decreaseShortPosition", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_wbtcCollateralDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wbtcSizeDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wethCollateralDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wethSizeDelta", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_shouldRepayWbtc", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_shouldRepayWeth", + "type": "bool" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "_callbackTarget", + "type": "address" + } + ], + "name": "decreaseShortPositionsWithCallback", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositInsuranceFund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyConfrim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "executionFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exitStrategy", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "exited", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fsGlp", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "glpRewardRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gmxHelper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gmxRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gov", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_sizeDelta", + "type": "uint256" + } + ], + "name": "increaseShortPosition", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_wbtcAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wbtcSizeDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wethAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_wethSizeDelta", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_callbackTarget", + "type": "address" + } + ], + "name": "increaseShortPositionsWithCallback", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_indexToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_callbackTarget", + "type": "address" + } + ], + "name": "instantRepayFundingFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "insuranceFund", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "keepers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastCollect", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "management", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "managementFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marginFeeBasisPoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + }, + { + "internalType": "bytes[]", + "name": "_params", + "type": "bytes[]" + } + ], + "name": "minimiseDeltaWithBuyGlp", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4[]", + "name": "_selectors", + "type": "bytes4[]" + }, + { + "internalType": "bytes[]", + "name": "_params", + "type": "bytes[]" + } + ], + "name": "minimiseDeltaWithSellGlp", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "nGlp", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPositionFeeInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "fundingRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wbtcFundingFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "wethFundingFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "positionRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "prepaidGmxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referralCode", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referralStorage", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_text", + "type": "string" + } + ], + "name": "registerAndSetReferralCode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "repayFundingFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "repayUnpaidFundingFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRouter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "routers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "sellGlp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_callbackTarget", + "type": "address" + } + ], + "name": "setCallbackTarget", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_helper", + "type": "address" + } + ], + "name": "setGmxHelper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gov", + "type": "address" + } + ], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_keeper", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setKeeper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_management", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setManagement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_bps", + "type": "uint256" + } + ], + "name": "setMarginFeeBasisPoints", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_router", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isActive", + "type": "bool" + } + ], + "name": "setRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_router", + "type": "address" + } + ], + "name": "setUniSwapRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "settle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenAmount", + "type": "uint256" + } + ], + "name": "tokenToUsdMin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "unpaidFundingFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_usdAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isCeil", + "type": "bool" + } + ], + "name": "usdToTokenMax", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "want", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdrawInsuranceFund", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/src/adaptors/neutra-finance/contract.js b/src/adaptors/neutra-finance/contract.js new file mode 100644 index 0000000000..6f06c2d329 --- /dev/null +++ b/src/adaptors/neutra-finance/contract.js @@ -0,0 +1,107 @@ +const { getProvider } = require('@defillama/sdk/build/general'); +const { ethers, Contract, BigNumber } = require('ethers'); +const nusdcABI = require('./abis/nUSDC.json'); +const snusdcABI = require('./abis/snUSDC.json'); +const poolABI = require('./abis/camelotPool.json'); +const strategyVaultABI = require('./abis/strategyVault.json'); + +const nUSDCAddress = '0x2a958665bC9A1680135241133569C7014230Cb21'; +const snUSDCAddress = '0x1B872bb0080159F9BDb77E5b1B006c6cb70D718a'; +const xGrailAddress = '0x3CAaE25Ee616f2C8E13C74dA0813402eae3F496b'; +const grailUSDCAddress = '0x87425D8812f44726091831a9A109f4bDc3eA34b4'; +const esNeuUSDCAddress = '0x4E94703760323534A0Ed949ae4d21De17b90e0Bb'; +const strategyVaultAddress = '0x6Bfa4F1DfAfeb9c37E4E8d436E1d0C5973E47e25'; +const esNeuAddress = '0x22F4730e21e40Dc751c08826d93010A64185e53f'; + +const USDC_DECIMAL = 6; +const NEUTRA_BASE_DECIMAL = 18; +const SECONDS_PER_YEAR = 31536000; + +const rpcUrl = 'https://rpc.ankr.com/arbitrum'; + +const simpleRpcProvider = new ethers.providers.JsonRpcProvider(rpcUrl); + +exports.getApy = async function () { + const nusdcContract = new Contract(nUSDCAddress, nusdcABI, simpleRpcProvider); + const snusdcContract = new Contract( + snUSDCAddress, + snusdcABI.abi, + simpleRpcProvider + ); + const grailUSDCPoolContract = new Contract( + grailUSDCAddress, + poolABI, + simpleRpcProvider + ); + + const esNeuUsdcPoolContract = new Contract( + esNeuUSDCAddress, + poolABI, + simpleRpcProvider + ); + + let xGrailReserves = await grailUSDCPoolContract.getReserves(); + const xGrailPrice = xGrailReserves[1] / xGrailReserves[0]; + + let esNeuReserves = await esNeuUsdcPoolContract.getReserves(); + let esNeuPrice = esNeuReserves[1] / esNeuReserves[0]; + + const snUsdcTotalSupply = await nusdcContract.totalSupply(); + const nUsdcPrice = await nusdcContract.pricePerShare(); + const totalValueLocked = snUsdcTotalSupply + .mul(nUsdcPrice) + .div(expandDecimals(1, USDC_DECIMAL)); + const totalValueLocedInUsd = Number(totalValueLocked); + + const xGrailPerInterval = await snusdcContract.tokensPerInterval( + xGrailAddress + ); + + const grailPrice = + xGrailPrice * expandDecimals(1, NEUTRA_BASE_DECIMAL - USDC_DECIMAL); // 18 + const xGrailAnnualReward = + ((xGrailPerInterval * SECONDS_PER_YEAR * grailPrice) / + expandDecimals(1, NEUTRA_BASE_DECIMAL)) * + expandDecimals(1, 12); + const xGrailAnnualRewardUsd = Number(xGrailAnnualReward); + const parsedxGrailApr = + xGrailAnnualRewardUsd === 0 + ? 0 + : (xGrailAnnualRewardUsd / totalValueLocedInUsd) * 100; + + const esNeuPerInterval = await snusdcContract.tokensPerInterval(esNeuAddress); + const esNeuAnnualReward = + ((esNeuPerInterval * SECONDS_PER_YEAR * esNeuPrice) / totalValueLocked) * + 100; + + const xGrailApy = parsedxGrailApr / 1e6; + return xGrailApy + esNeuAnnualReward; +}; + +exports.getTvl = async function () { + const strategyVaultContract = new Contract( + strategyVaultAddress, + strategyVaultABI.abi, + simpleRpcProvider + ); + + const nusdcContract = new Contract(nUSDCAddress, nusdcABI, simpleRpcProvider); + + const nusdcTvl = (await nusdcContract.totalAssets()) / 1e6; + const nglpTvl = (await strategyVaultContract.totalValue()) / 1e30; + + return [nusdcTvl, nglpTvl]; +}; + +function bigNumberify(n) { + try { + return BigNumber.from(n); + } catch (e) { + console.error('bigNumberify error', e); + return BigNumber.from('0'); + } +} + +function expandDecimals(n, decimals) { + return bigNumberify(n).mul(bigNumberify(10).pow(decimals)); +} diff --git a/src/adaptors/neutra-finance/index.js b/src/adaptors/neutra-finance/index.js new file mode 100644 index 0000000000..11ff37b5f6 --- /dev/null +++ b/src/adaptors/neutra-finance/index.js @@ -0,0 +1,79 @@ +const utils = require('../utils'); +const { gql, default: request } = require('graphql-request'); +const { getTvl } = require('./contract'); +const { getApy } = require('./contract'); + +const ARKIVER_GRAPHQL_URL = + 'https://data.arkiver.net/s_battenally/vaults/graphql'; +const VAULT_STATS_URL = + 'https://api.thegraph.com/subgraphs/name/xayaneu/neutra-vault-migration'; + +const poolsFunction = async () => { + const nGlpQuery = gql` + { + vaults(first: 1, orderDirection: desc) { + id + nGlpPrice + esNeuApr + nGlpApr + } + } + `; + + const nUSDCQuery = gql` + query GetVaultApy { + VaultApy( + filter: { vault: "0x2a958665bC9A1680135241133569C7014230Cb21" } + sort: TIMESTAMP_DESC + ) { + apy1d + apy7d + } + } + `; + + let nusdcAPY = await request(ARKIVER_GRAPHQL_URL, nUSDCQuery); + + let nGlpAPY = await request(VAULT_STATS_URL, nGlpQuery); + + const tvl = await getTvl(); + const getAPY = await getApy(); + + const GlpPool = { + pool: '0x6Bfa4F1DfAfeb9c37E4E8d436E1d0C5973E47e25', + chain: utils.formatChain('arbitrum'), + project: 'neutra-finance', + symbol: utils.formatSymbol('DAI'), + tvlUsd: Number(tvl[1]), + apyReward: + (Number(nGlpAPY.vaults[0].esNeuApr) + Number(nGlpAPY.vaults[0].nGlpApr)) / + 1e18, + rewardTokens: [ + '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + '0x22F4730e21e40Dc751c08826d93010A64185e53f', + ], + }; + + const nUSDCPool = { + pool: '0x2a958665bC9A1680135241133569C7014230Cb21', + chain: utils.formatChain('arbitrum'), + project: 'neutra-finance', + symbol: utils.formatSymbol('USDC'), + tvlUsd: Number(tvl[0]), + apyReward: getAPY, + apyBase: nusdcAPY.VaultApy.apy1d * 100, + apyBase7d: nusdcAPY.VaultApy.apy7d * 100, + rewardTokens: [ + '0x22F4730e21e40Dc751c08826d93010A64185e53f', + '0x3CAaE25Ee616f2C8E13C74dA0813402eae3F496b', + ], + }; + + return [GlpPool, nUSDCPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://neutra.finance', +}; diff --git a/src/adaptors/neverland/abi.js b/src/adaptors/neverland/abi.js new file mode 100644 index 0000000000..5ae9bfcdf5 --- /dev/null +++ b/src/adaptors/neverland/abi.js @@ -0,0 +1,70 @@ +module.exports = { + dustRewardsControllerAbi: [ + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getRewardsByAsset', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'reward', type: 'address' }, + ], + name: 'getRewardsData', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + dustLockAbi: [ + { + inputs: [], + name: 'supply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], + revenueRewardAbi: [ + { + inputs: [], + name: 'getRewardTokens', + outputs: [ + { internalType: 'address[]', name: 'tokens', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'tokenRewardsPerEpoch', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/neverland/index.js b/src/adaptors/neverland/index.js new file mode 100644 index 0000000000..16b11e3e38 --- /dev/null +++ b/src/adaptors/neverland/index.js @@ -0,0 +1,423 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); +const { + dustRewardsControllerAbi, + dustLockAbi, + revenueRewardAbi, +} = require('./abi'); + +const NEVERLAND_CHAIN = 'monad'; + +const protocolDataProvider = '0xfd0b6b6F736376F7B99ee989c749007c7757fDba'; +const rewardsController = '0x57ea245cCbFAb074baBb9d01d1F0c60525E52cec'; +const dustLock = '0xBB4738D05AD1b3Da57a4881baE62Ce9bb1eEeD6C'; +const revenueReward = '0xff20ac10eb808B1e31F5CfCa58D80eDE2Ba71c43'; + +const calculateRewardApy = ( + rewardsData, + rewardDecimals, + prices, + chain, + baseUsd +) => { + let totalApy = 0; + for (const rewardData of rewardsData) { + const emissionPerSecond = Number(rewardData.emissionPerSecond); + const rewardTokenAddress = rewardData.rewardToken; + const rewardPrice = prices[`${chain}:${rewardTokenAddress}`]?.price; + const rewardDecimal = rewardDecimals[rewardTokenAddress]; + + if (emissionPerSecond > 0 && rewardPrice && rewardDecimal && baseUsd > 0) { + const emissionPerYear = + (emissionPerSecond / 10 ** rewardDecimal) * 365.25 * 24 * 60 * 60; + const emissionValueUsd = emissionPerYear * rewardPrice; + totalApy += (emissionValueUsd / baseUsd) * 100; + } + } + return totalApy; +}; + +const getApy = async () => { + const chain = NEVERLAND_CHAIN; + + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const reserveTokensAddresses = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveTokensAddresses'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const rewardsByAsset = ( + await sdk.api.abi.multiCall({ + chain, + calls: aTokens.map((t) => ({ + target: rewardsController, + params: [t.tokenAddress], + })), + abi: dustRewardsControllerAbi.find((m) => m.name === 'getRewardsByAsset'), + }) + ).output.map((o) => o.output); + + const rewardsByDebtAsset = ( + await sdk.api.abi.multiCall({ + chain, + calls: reserveTokensAddresses.map((t) => ({ + target: rewardsController, + params: [t.variableDebtTokenAddress], + })), + abi: dustRewardsControllerAbi.find((m) => m.name === 'getRewardsByAsset'), + }) + ).output.map((o) => o.output); + + const allRewardTokens = [ + ...new Set([...rewardsByAsset.flat(), ...rewardsByDebtAsset.flat()]), + ]; + + const rewardsDataCalls = []; + for (let i = 0; i < aTokens.length; i++) { + const rewards = rewardsByAsset[i] || []; + for (const reward of rewards) { + rewardsDataCalls.push({ + target: rewardsController, + params: [aTokens[i].tokenAddress, reward], + assetIndex: i, + rewardToken: reward, + isDebt: false, + }); + } + } + + for (let i = 0; i < reserveTokensAddresses.length; i++) { + const rewards = rewardsByDebtAsset[i] || []; + for (const reward of rewards) { + rewardsDataCalls.push({ + target: rewardsController, + params: [reserveTokensAddresses[i].variableDebtTokenAddress, reward], + assetIndex: i, + rewardToken: reward, + isDebt: true, + }); + } + } + + const rewardsData = + rewardsDataCalls.length > 0 + ? ( + await sdk.api.abi.multiCall({ + chain, + calls: rewardsDataCalls.map((c) => ({ + target: c.target, + params: c.params, + })), + abi: dustRewardsControllerAbi.find( + (m) => m.name === 'getRewardsData' && m.inputs.length === 2 + ), + }) + ).output.map((o, idx) => { + const [ + index, + emissionPerSecond, + lastUpdateTimestamp, + distributionEnd, + ] = o.output; + return { + index, + emissionPerSecond, + lastUpdateTimestamp, + distributionEnd, + assetIndex: rewardsDataCalls[idx].assetIndex, + rewardToken: rewardsDataCalls[idx].rewardToken, + isDebt: rewardsDataCalls[idx].isDebt, + }; + }) + : []; + + const rewardDecimals = + allRewardTokens.length > 0 + ? ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: allRewardTokens.map((token) => ({ + target: token, + })), + }) + ).output.reduce((acc, o, idx) => { + acc[allRewardTokens[idx]] = o.output; + return acc; + }, {}) + : {}; + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .concat(allRewardTokens.map((t) => `${chain}:${t}`)) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens + .map((pool, i) => { + const config = poolsReservesConfigurationData[i]; + const frozen = config.isFrozen; + if (frozen || !config.isActive) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price; + + if (!price) return null; + + const supply = totalSupply[i]; + const totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + const tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + const totalBorrowUsd = totalSupplyUsd - tvlUsd; + + const apyBase = (p.liquidityRate / 10 ** 27) * 100; + const apyBaseBorrow = Number(p.variableBorrowRate) / 1e25; + + const rewardsAddresses = rewardsByAsset[i] || []; + + const assetRewardsData = rewardsData.filter( + (r) => r.assetIndex === i && !r.isDebt + ); + const apyReward = calculateRewardApy( + assetRewardsData, + rewardDecimals, + prices, + chain, + totalSupplyUsd + ); + + const debtRewardsData = rewardsData.filter( + (r) => r.assetIndex === i && r.isDebt + ); + const apyRewardBorrow = calculateRewardApy( + debtRewardsData, + rewardDecimals, + prices, + chain, + totalBorrowUsd + ); + + const url = `https://app.neverland.money/markets?asset=${pool.symbol}`; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'neverland', + symbol: pool.symbol, + tvlUsd, + apyBase, + apyReward: assetRewardsData.length > 0 ? apyReward : null, + rewardTokens: rewardsAddresses.length > 0 ? rewardsAddresses : null, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: debtRewardsData.length > 0 ? apyRewardBorrow : null, + ltv: config.ltv / 10000, + url, + borrowable: config.borrowingEnabled, + }; + }) + .filter((p) => utils.keepFinite(p)); +}; + +const getVeDustPool = async (chain, prices, rewardTokensList) => { + try { + const [dustSupply, dustToken, veDustSupply] = await Promise.all([ + sdk.api.abi.call({ + target: dustLock, + abi: dustLockAbi.find((m) => m.name === 'supply'), + chain, + }), + sdk.api.abi.call({ + target: dustLock, + abi: dustLockAbi.find((m) => m.name === 'token'), + chain, + }), + sdk.api.abi.call({ + target: dustLock, + abi: dustLockAbi.find((m) => m.name === 'totalSupply'), + chain, + }), + ]); + + const dustPrice = prices[`${chain}:${dustToken.output}`]?.price; + if (!dustPrice || !dustSupply.output || dustSupply.output === '0') + return null; + + const tvlUsd = (Number(dustSupply.output) / 1e18) * dustPrice; + const veDustPowerUsd = (Number(veDustSupply.output) / 1e18) * dustPrice; + + if (!rewardTokensList || rewardTokensList.length === 0) return null; + + const WEEK = 7 * 24 * 60 * 60; + const currentTime = Math.floor(Date.now() / 1000); + const currentEpoch = Math.floor(currentTime / WEEK) * WEEK; + const nextEpoch = currentEpoch + WEEK; + + const nextEpochRewardsCalls = rewardTokensList.map((token) => ({ + target: revenueReward, + params: [token, nextEpoch], + })); + + const [nextEpochRewardsData, rewardDecimalsData] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls: nextEpochRewardsCalls, + abi: revenueRewardAbi.find((m) => m.name === 'tokenRewardsPerEpoch'), + }), + sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: rewardTokensList.map((token) => ({ target: token })), + }), + ]); + + const totalApyReward = rewardTokensList.reduce((acc, token, i) => { + const rewardPrice = prices[`${chain}:${token}`]?.price; + const weeklyRewardsRaw = nextEpochRewardsData.output[i]?.output; + const decimals = rewardDecimalsData.output[i]?.output; + + if (rewardPrice && weeklyRewardsRaw && decimals) { + const weeklyRewards = + Number(weeklyRewardsRaw) / Math.pow(10, Number(decimals)); + const annualRewardsUsd = weeklyRewards * rewardPrice * 52; + return acc + (annualRewardsUsd / veDustPowerUsd) * 100; + } + return acc; + }, 0); + + return { + pool: `${dustLock}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'neverland', + symbol: 'veDUST', + tvlUsd, + apyReward: totalApyReward, + rewardTokens: rewardTokensList, + underlyingTokens: [dustToken.output], + url: 'https://app.neverland.money', + }; + } catch (error) { + console.error('Error fetching veDUST pool:', error.message); + return null; + } +}; + +const apy = async () => { + const chain = NEVERLAND_CHAIN; + const [lendingPools, rewardTokensList] = await Promise.all([ + getApy(), + sdk.api.abi.call({ + target: revenueReward, + abi: revenueRewardAbi.find((m) => m.name === 'getRewardTokens'), + chain, + }), + ]); + + const priceKeys = [ + ...lendingPools.flatMap((p) => p.underlyingTokens), + ...lendingPools.flatMap((p) => p.rewardTokens || []), + ...(rewardTokensList.output || []), + ] + .map((t) => `${chain}:${t}`) + .join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const veDustPool = await getVeDustPool( + chain, + prices, + rewardTokensList.output + ); + + return veDustPool ? [...lendingPools, veDustPool] : lendingPools; +}; + +module.exports = { + apy, + url: 'https://app.neverland.money', +}; diff --git a/src/adaptors/neverland/poolAbi.js b/src/adaptors/neverland/poolAbi.js new file mode 100644 index 0000000000..af9e3cb014 --- /dev/null +++ b/src/adaptors/neverland/poolAbi.js @@ -0,0 +1,105 @@ +module.exports = [ + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/nftx/abis/ERC20.json b/src/adaptors/nftx/abis/ERC20.json new file mode 100644 index 0000000000..405d6b3648 --- /dev/null +++ b/src/adaptors/nftx/abis/ERC20.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] diff --git a/src/adaptors/nftx/abis/UniswapV2Pair.json b/src/adaptors/nftx/abis/UniswapV2Pair.json new file mode 100644 index 0000000000..8357a38c71 --- /dev/null +++ b/src/adaptors/nftx/abis/UniswapV2Pair.json @@ -0,0 +1,402 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint112", "name": "_reserve0", "type": "uint112" }, + { "internalType": "uint112", "name": "_reserve1", "type": "uint112" }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "kLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/nftx/index.js b/src/adaptors/nftx/index.js new file mode 100644 index 0000000000..3eb5adefa1 --- /dev/null +++ b/src/adaptors/nftx/index.js @@ -0,0 +1,157 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); +const uniswapV2PairAbi = require('./abis/UniswapV2Pair.json'); +const erc20Abi = require('./abis/ERC20.json'); + +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const NFTX_LP_STAKING = '0x688c3E4658B5367da06fd629E41879beaB538E37'; +const NFTX_VAULTS_SUBGRAPH = + 'https://graph-proxy.nftx.xyz/gateway/api/f0149ced5dcb5d0f0fc2b6270039fc57/subgraphs/id/4gZf3atMXjYDh4g48Zr83NFX3rkvZED86VqMNhgEXgLc'; +const NFTX_VAULT_APR_API = 'https://data.nftx.xyz/vaultdata'; + +const query = gql` + { + vaults( + first: 1000 + where: { isFinalized: true, totalHoldings_gt: 10, shutdownDate: 0 } + ) { + id + vaultId + token { + symbol + } + totalHoldings + inventoryStakingPool { + id + } + lpStakingPool { + id + stakingToken { + id + } + } + } + } +`; + +const calculatedStakedLiquidityValue = (reserves, token0, vaultId) => { + // ensure order is TOKEN-WETH + const tokenWethReserves = + token0.toLowerCase() === WETH ? reserves.slice().reverse() : reserves; + + return tokenWethReserves[1] * 2; +}; + +const poolsFunction = async () => { + const vaultsData = await request(NFTX_VAULTS_SUBGRAPH, query); + + const aprAndPriceData = await utils.getData(NFTX_VAULT_APR_API); + + const liquidVaults = aprAndPriceData + .map((data) => { + // filter out illiquid vaults + if (data.estimatedPriceImpact > 20 || !data.spotPriceEth) { + return false; + } + + const vault = vaultsData.vaults.find( + (v) => Number(v.vaultId) === data.vaultId + ); + + // make sure we have staking pools + if (vault && vault.inventoryStakingPool && vault.lpStakingPool) { + return { + vault, + data, + }; + } + + return false; + }) + .filter(Boolean); + + // how much liquidity is staked? + const [reservesRes, token0Res] = await Promise.all( + ['getReserves', 'token0'].map((method) => + sdk.api.abi.multiCall({ + abi: uniswapV2PairAbi.filter(({ name }) => name === method)[0], + calls: liquidVaults.map(({ vault }) => ({ + target: vault.lpStakingPool.stakingToken.id, + params: null, + })), + chain: 'ethereum', + requery: true, + }) + ) + ); + + const reserves = reservesRes.output.map((res) => [ + Number(res.output[0]) / 1e18, + Number(res.output[1]) / 1e18, + ]); + const token0 = token0Res.output.map((res) => res.output); + + // how much inventory is staked? + const [inventoryBalancesRes] = await Promise.all( + ['balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: erc20Abi.filter(({ name }) => name === method)[0], + calls: liquidVaults.map(({ vault }) => ({ + target: vault.id, + params: vault.inventoryStakingPool.id, + })), + chain: 'ethereum', + requery: true, + }) + ) + ); + + const inventoryBalances = inventoryBalancesRes.output.map( + (res) => Number(res.output) / 1e18 + ); + + const poolsData = liquidVaults.map(({ vault, data }, i) => { + const inventoryTvl = + inventoryBalances[i] * data.spotPriceEth * data.ethPriceUsd; + + const liquidityEthTvl = calculatedStakedLiquidityValue( + reserves[i], + token0[i], + vault.vaultId + ); + + return [ + // liquidity + { + pool: vault.lpStakingPool.id, + chain: utils.formatChain('ethereum'), + project: 'nftx', + symbol: `${vault.token.symbol}-WETH`, + apy: data.liquidityApr * 100, + tvlUsd: liquidityEthTvl * data.ethPriceUsd, + rewardTokens: [vault.id], + underlyingTokens: [vault.id, WETH], + }, + // inventory + { + pool: vault.inventoryStakingPool.id, + chain: utils.formatChain('ethereum'), + project: 'nftx', + symbol: vault.token.symbol, + apy: data.inventoryApr * 100, + tvlUsd: inventoryTvl, + rewardTokens: [vault.id], + underlyingTokens: [vault.id], + }, + ]; + }); + + return poolsData.flat(); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://yield.nftx.io/', +}; diff --git a/src/adaptors/nimbora-yield/index.js b/src/adaptors/nimbora-yield/index.js new file mode 100644 index 0000000000..0764bb1073 --- /dev/null +++ b/src/adaptors/nimbora-yield/index.js @@ -0,0 +1,50 @@ +const { parseAddress } = require('../../helper/starknet'); +const axios = require('axios'); + + +const strk ='0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'; +const slup = 'nimbora-yield'; +const chain = 'Starknet' +const api = 'https://stats.nimbora.io/yield-dex/strategies' + +async function apy() { + const config = { + headers: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + } + }; + + try { + const response = await axios.get(api, config); + return response.data.map((strategy) => { + const underlyingToken = parseAddress(strategy.underlying); + const underlyingTokenSymbol = strategy.underlyingSymbol + const tokenManager = parseAddress(strategy.tokenManager); + const pool = (tokenManager + '-starknet').toLowerCase(); + const apyBase = +strategy.aprBreakdown.base; + const apyReward = +strategy.aprBreakdown.boost + +strategy.aprBreakdown.incentives + const tvlUsd = +strategy.tvl + + return { + pool, + project: slup, + symbol: underlyingTokenSymbol, + chain, + apyBase: apyBase, + apyReward: apyReward, + rewardTokens: apyReward !== 0 ? [strk] : [], + tvlUsd, + underlyingTokens: [underlyingToken], + url: 'https://app.nimbora.io/', + poolMeta: strategy.symbol, + }; + }) + } catch (error) { + console.error('Error:', error); + } +} + +module.exports = { + apy, + url: 'https://app.nimbora.io/', +}; diff --git a/src/adaptors/nitron/helper.js b/src/adaptors/nitron/helper.js new file mode 100644 index 0000000000..6b5e6fd821 --- /dev/null +++ b/src/adaptors/nitron/helper.js @@ -0,0 +1,306 @@ +const BigNumber = require('bignumber.js'); +const { default: axios } = require('axios'); +const dayjs = require('dayjs'); + +const BN_ZERO = new BigNumber(0); +const BN_ONE = new BigNumber(1); +const modAddress = 'swth1wq9ts6l7atfn45ryxrtg4a2gwegsh3xh7w83xl'; +const cdpModAddress = 'swth1zkmw9w5j0ew57hzsvcwautrsfpcq7z5zffvaqe'; + +const secondsInMinBN = new BigNumber(60); +const secondsInHourBN = secondsInMinBN.multipliedBy(60); +const secondsInDayBN = secondsInHourBN.multipliedBy(24); +const secondsInYearBN = secondsInDayBN.multipliedBy(365); + +const bnOrZero = (number) => { + return new BigNumber(number ?? 0); +}; + +function getRewardSchemeKey(denom, type) { + return `${denom}:${type}`; +} + +function getProjectedRewardsOwed(rewardScheme, tokenPrices) { + const rewardUsdValue = tokenPrices[rewardScheme.reward_denom]?.usd ?? 1; + const rewardAmountPerSecond = bnOrZero(rewardScheme.reward_amount_per_second); + const projectedRewardsOwed = rewardAmountPerSecond.times(secondsInYearBN); + return projectedRewardsOwed.times(rewardUsdValue); +} + +const getRewardMap = async (rewardSchemes, tokenPrices) => { + const schemesArr = Object.values(rewardSchemes); + const activeSchemes = schemesArr.filter((rewardScheme) => { + const start = Math.floor( + new Date(rewardScheme.start_time).getTime() / 1000 + ); + const end = Math.floor(new Date(rewardScheme.end_time).getTime() / 1000); + const now = Math.floor(Date.now() / 1000); + return now >= start && now < end; + }); + const rewardsUSDMap = {}; + for (let ii = 0; ii < activeSchemes.length; ii++) { + const indivScheme = activeSchemes[ii]; + // get projected rewards earned in 1 year + const projectedRewardsOwedRaw = getProjectedRewardsOwed( + indivScheme, + tokenPrices + ); + let underlyingDenom = indivScheme.asset_denom.replace('cibt/', ''); + + const schemeKey = `${underlyingDenom}:${indivScheme.reward_type}`; + if (!rewardsUSDMap[schemeKey]) { + rewardsUSDMap[schemeKey] = {}; + } + + if (rewardsUSDMap[schemeKey][indivScheme.reward_denom]) { + rewardsUSDMap[schemeKey] = { + ...rewardsUSDMap[schemeKey], + [indivScheme.reward_denom]: rewardsUSDMap[schemeKey][ + indivScheme.reward_denom + ].plus(projectedRewardsOwedRaw), + }; + } else { + rewardsUSDMap[schemeKey] = { + ...rewardsUSDMap[schemeKey], + [indivScheme.reward_denom]: projectedRewardsOwedRaw, + }; + } + } + return rewardsUSDMap; +}; + +module.exports.getTokenAprArr = async ( + rewardSchemes, + tokenPrices, + tokens, + type, + underlyingDenom, + totalSharesUSD +) => { + const addRewardsUsd = await getRewardMap(rewardSchemes, tokenPrices); + const schemeKey = `${underlyingDenom}:${type}`; + const rewardsMap = addRewardsUsd[schemeKey] ?? {}; + const totalSharesUSDBN = new BigNumber(totalSharesUSD); + let totalRewardUsd = BN_ZERO; + const tokenAprArr = Object.keys(rewardsMap).reduce((prev, rewardKey) => { + const newPrev = [...prev]; + const rewardDecimals = tokens.find((o) => o.denom === rewardKey).decimals; + const rewardUsd = (rewardsMap[rewardKey] ?? BN_ZERO).shiftedBy( + -rewardDecimals + ); + totalRewardUsd = totalRewardUsd.plus(rewardUsd); + newPrev.push({ + denom: rewardKey, + apr: totalSharesUSDBN.isZero() + ? BN_ZERO + : rewardUsd.div(totalSharesUSDBN), + }); + return newPrev; + }, []); + return { + tokenAprArr: tokenAprArr, + overallRewardApr: totalSharesUSDBN.isZero() + ? BN_ZERO + : totalRewardUsd.div(totalSharesUSDBN), + }; +}; + +module.exports.getAllBorrowAssets = async () => { + const allAssets = ( + await axios.get('https://api.carbon.network/carbon/cdp/v1/asset') + ).data.asset_params_all; + return allAssets; +}; +module.exports.getDebtInfos = async () => { + const debtInfos = ( + await axios.get('https://api.carbon.network/carbon/cdp/v1/token_debt') + ).data.debt_infos_all; + return debtInfos; +}; +module.exports.getModBalances = async () => { + const modBalances = ( + await axios.get( + `https://api.carbon.network/carbon/coin/v1/balances/${modAddress}` + ) + ).data.token_balances; + return modBalances; +}; + +module.exports.getCdpModBalances = async () => { + const cdpModBalances = ( + await axios.get( + `https://api.carbon.network/carbon/coin/v1/balances/${cdpModAddress}` + ) + ).data.token_balances; + return cdpModBalances; +}; + +module.exports.getCdpTotalSupply = async () => { + const cdpTotalSupply = ( + await axios.get( + `https://api.carbon.network/cosmos/bank/v1beta1/supply?pagination.limit=100000` + ) + ).data.supply; + return cdpTotalSupply; +}; + +module.exports.getAllStrats = async () => { + const allStrategies = ( + await axios.get(`https://api.carbon.network/carbon/cdp/v1/rate_strategy`) + ).data.rate_strategy_params_all; + return allStrategies; +}; + +module.exports.getParams = async () => { + const params = ( + await axios.get(`https://api.carbon.network/carbon/cdp/v1/params`) + ).data.params; + return params; +}; + +module.exports.getRewardSchemes = async () => { + const rewardSchemes = ( + await axios.get(`https://api.carbon.network/carbon/cdp/v1/reward_schemes`) + ).data.reward_schemes; + return rewardSchemes; +}; + +module.exports.getUSDValues = async (assets, denomToGeckoIdMap) => { + const priceKeys = [ + ...new Set(assets.map((a) => `coingecko:${denomToGeckoIdMap[a.denom]}`)), + ].filter((i) => i !== undefined); + + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${priceKeys.join(',')}` + ) + ).data.coins; + + const pricingsFromOracle = ( + await axios.get('https://api.carbon.network/carbon/pricing/v1/token_price') + ).data?.token_prices; + + let result = {}; + assets.forEach((asset) => { + const denomtInGeckoId = denomToGeckoIdMap[asset.denom]; + let usd = prices[`coingecko:${denomtInGeckoId}`]?.price; + if (!usd) + usd = Number( + pricingsFromOracle.find((o) => o.denom === asset.denom)?.twap + ); + result[asset.denom] = { ...asset, usd }; + }); + return result; +}; + +module.exports.calculateInterestAPY = (debtInfo, rateStrategy) => { + const utilizationRate = bnOrZero(debtInfo.utilization_rate); + const optimalUsage = bnOrZero(rateStrategy.optimal_usage).shiftedBy(-4); + const variableRate1 = bnOrZero(rateStrategy.variable_rate_slope_1).shiftedBy( + -4 + ); + const variableRate2 = bnOrZero(rateStrategy.variable_rate_slope_2).shiftedBy( + -4 + ); + const baseVariableBorrowRate = bnOrZero( + rateStrategy.base_variable_borrow_rate + ).shiftedBy(-4); + if (utilizationRate.lte(optimalUsage)) { + const vRate = utilizationRate + .times(variableRate1) + .div(optimalUsage) + .dp(4, BigNumber.ROUND_CEIL); + return vRate.plus(baseVariableBorrowRate); + } else { + const ratio = utilizationRate + .minus(optimalUsage) + .div(BN_ONE.minus(optimalUsage)); + const vRate = ratio + .times(variableRate2) + .plus(variableRate1) + .dp(4, BigNumber.ROUND_CEIL); + return vRate.plus(baseVariableBorrowRate); + } +}; + +module.exports.calculateLendAPY = (borrowInterest, debtInfo, params) => { + const interestFeeRate = bnOrZero(params.interest_fee).div( + new BigNumber(10000) + ); + const utilizationRate = bnOrZero(debtInfo.utilization_rate); + return borrowInterest + .times(utilizationRate) + .times(BN_ONE.minus(interestFeeRate)); +}; + +const calculateInterestForTimePeriod = (offsetSeconds, debtInfo, borrowAPY) => { + const interestAPY = new BigNumber(borrowAPY); + + const now = dayjs().add(offsetSeconds, 'seconds').toDate(); + const lastDate = debtInfo.last_updated_time ?? now; + const diffMs = end.getTime() - start.getTime(); + if (diffMs <= 0) { + return BN_ZERO; + } + const diffSeconds = new BigNumber(diffMs) + .shiftedBy(-3) + .dp(0, BigNumber.ROUND_CEIL); + const secondsAYear = bnOrZero(31536000); + const numPeriods = secondsAYear.div(diffSeconds).dp(18); + return interestAPY.div(numPeriods).dp(18); // carbon backend sdk.dec max 18 dp +}; + +const getTotalDebt = (offsetSeconds, debtInfo, params, borrowAPY) => { + if (debtInfo) return BN_ZERO; + const totalUnderlyingPrincipal = bnOrZero(debtInfo.total_principal); + const interestRate = calculateInterestForTimePeriod(offsetSeconds); + const accumInterest = bnOrZero(debtInfo.total_accumulated_interest); + + const newInterest = totalUnderlyingPrincipal + .times(interestRate) + .plus(accumInterest.times(BN_ONE.plus(interestRate))); + const interest = newInterest.times(BN_ONE.minus(params.interest_fee)).dp(0); + return totalUnderlyingPrincipal.plus(interest); +}; + +const getCdpRatio = ( + debtInfo, + params, + borrowAPY, + cdpModuleUnderlyingBalance, + cdpTotalSupply +) => { + const totalDebt = getTotalDebt( + (offsetSeconds = 0), + debtInfo, + params, + borrowAPY + ); + const totalUnderlying = BigNumber.sum(cdpModuleUnderlyingBalance, totalDebt); + const cdpRatio = totalUnderlying.isZero() + ? BN_ONE + : cdpTotalSupply.div(totalUnderlying); + return cdpRatio; +}; + +module.exports.getTotalCdpSharesUSD = ( + debtInfo, + params, + borrowAPY, + decimals, + totalSupplyBN, + cdpModBalances, + usd +) => { + const cdpRatio = getCdpRatio( + debtInfo, + params, + borrowAPY, + cdpModBalances, + totalSupplyBN + ); + const underlyingAmount = !cdpRatio.isFinite() + ? totalSupplyBN.div(cdpRatio) + : totalSupplyBN; + return underlyingAmount.times(usd).shiftedBy(-decimals); +}; diff --git a/src/adaptors/nitron/index.js b/src/adaptors/nitron/index.js new file mode 100644 index 0000000000..d40be370b2 --- /dev/null +++ b/src/adaptors/nitron/index.js @@ -0,0 +1,133 @@ +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { default: axios } = require('axios'); +const { + getTotalCdpSharesUSD, + getCdpTotalSupply, + getCdpModBalances, + getRewardSchemes, + getAllBorrowAssets, + getDebtInfos, + getModBalances, + getUSDValues, + getAllStrats, + calculateInterestAPY, + calculateLendAPY, + getParams, + getTokenAprArr, +} = require('./helper'); + +const bnOrZero = (number) => { + return new BigNumber(number ?? 0); +}; + +const apr = async () => { + const tokens = await ( + await utils.getData( + 'https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000' + ) + ).tokens; + const allAssets = await getAllBorrowAssets(); + const debtInfos = await getDebtInfos(); + const modAccBalances = await getModBalances(); + const cdpModAccBalances = await getCdpModBalances(); + const allStrats = await getAllStrats(); + const denomToGeckoIdMap = ( + await axios.get(`https://api-insights.carbon.network/info/denom_gecko_map`) + ).data.result.gecko; + const usdValues = await getUSDValues(tokens, denomToGeckoIdMap); + const params = await getParams(); + const cdpTotalSupplies = await getCdpTotalSupply(); + const rewardSchemes = await getRewardSchemes(); + const result = []; + for (const asset of allAssets) { + const tokenInfo = tokens.find((o) => o.denom === asset.denom); + const strategy = allStrats.find((o) => o.name === asset.rate_strategy_name); + const usdValue = new BigNumber(usdValues[asset.denom]?.usd ?? 0); + const symbol = tokenInfo.symbol.toUpperCase(); + const debtInfo = debtInfos.find((o) => o.denom === asset.denom); + const assetBalance = modAccBalances.find((o) => o.denom === asset.denom); + const cdpAssetBalance = + cdpModAccBalances.find((o) => o.denom === `cibt/${asset.denom}`) + ?.available ?? 0; + const cdpTotalSupply = + cdpTotalSupplies.find((o) => o.denom === `cibt/${asset.denom}`)?.amount ?? + 0; + + const { total_principal, utilization_rate } = debtInfo; + const totalSupplied = new BigNumber(total_principal ?? 0).plus( + new BigNumber(assetBalance?.available ?? 0) + ); + const totalSuppliedUSD = totalSupplied + .multipliedBy(usdValue) + .shiftedBy(-Number(tokenInfo.decimals)) + .toNumber(); + const totalBorrowedUSD = new BigNumber(total_principal) + .multipliedBy(usdValue) + .shiftedBy(-Number(tokenInfo.decimals)) + .toNumber(); + const tvl = totalSuppliedUSD - totalBorrowedUSD; + // Borrow APY + const borrowAPY = calculateInterestAPY(debtInfo, strategy); + // Supply APY + const supplyAPY = calculateLendAPY(borrowAPY, debtInfo, params); + // get reward apy + const totalCdpTokenUSD = getTotalCdpSharesUSD( + debtInfo, + params, + borrowAPY, + tokenInfo.decimals, + bnOrZero(cdpTotalSupply), + cdpAssetBalance, + usdValue + ); + const { + tokenAprArr: tokenSupplyRewardArr, + overallRewardApr: overallSupplyRewardApr, + } = await getTokenAprArr( + rewardSchemes, + usdValues, + tokens, + 'lend', + asset.denom, + totalCdpTokenUSD + ); + const { tokenAprArr, overallRewardApr } = await getTokenAprArr( + rewardSchemes, + usdValues, + tokens, + 'borrow', + asset.denom, + totalBorrowedUSD + ); + const rewardTokensSupply = tokenSupplyRewardArr?.map((o) => o.denom); + const rewardTokensBorrow = tokenAprArr?.map((o) => o.denom); + result.push({ + pool: asset.denom.toString(), + chain: utils.formatChain('Carbon'), + project: 'nitron', + symbol: symbol, + // Supply and Borrowing + tvlUsd: tvl, // totalSuppliedUSD - totalBorrowedUSD + apyBase: supplyAPY.shiftedBy(2).toNumber(), // supplying in % + apyReward: overallSupplyRewardApr?.shiftedBy(2)?.toNumber() ?? 0, // APY from rewards in % + rewardTokens: [ + ...new Set([...rewardTokensSupply, ...rewardTokensBorrow]), + ], + underlyingTokens: [asset.denom], + apyBaseBorrow: borrowAPY.shiftedBy(2).toNumber(), + apyRewardBorrow: overallRewardApr?.shiftedBy(2)?.toNumber() ?? 0, + totalSupplyUsd: totalSuppliedUSD, + totalBorrowUsd: totalBorrowedUSD, + ltv: new BigNumber(asset.loan_to_value).shiftedBy(-2).toNumber() / 100, + }); + } + return result.filter((p) => p.pool !== 'clpt/104'); +}; + +module.exports = { + timetravel: false, + apy: apr, + url: 'https://app.dem.exchange/nitron', +}; diff --git a/src/adaptors/nodedao/abiStakingPool.json b/src/adaptors/nodedao/abiStakingPool.json new file mode 100644 index 0000000000..eda765285f --- /dev/null +++ b/src/adaptors/nodedao/abiStakingPool.json @@ -0,0 +1,1329 @@ +[ + { "inputs": [], "name": "AssignMustSameOperator", "type": "error" }, + { "inputs": [], "name": "InsufficientFunds", "type": "error" }, + { "inputs": [], "name": "InsufficientMargin", "type": "error" }, + { "inputs": [], "name": "InvalidAmount", "type": "error" }, + { "inputs": [], "name": "InvalidDaoVaultAddr", "type": "error" }, + { "inputs": [], "name": "InvalidParameter", "type": "error" }, + { "inputs": [], "name": "InvalidWithdrawalCredentials", "type": "error" }, + { "inputs": [], "name": "OperatorHasArrears", "type": "error" }, + { "inputs": [], "name": "OperatorLoanFailed", "type": "error" }, + { "inputs": [], "name": "PermissionDenied", "type": "error" }, + { "inputs": [], "name": "RequireBlacklistOperator", "type": "error" }, + { "inputs": [], "name": "RequireOperatorTrusted", "type": "error" }, + { "inputs": [], "name": "TotalEthIsZero", "type": "error" }, + { "inputs": [], "name": "UnstakeEthNoQuota", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "vaultManagerContractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_consensusVaultContract", + "type": "address" + } + ], + "name": "ConsensusVaultContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_oldDao", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_dao", + "type": "address" + } + ], + "name": "DaoAddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "DaoClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_oldDaoVaultAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_daoVaultAddress", + "type": "address" + } + ], + "name": "DaoVaultAddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldFeeRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_feeRate", + "type": "uint256" + } + ], + "name": "DepositFeeRateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + } + ], + "name": "EthStake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "targetOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "ender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "EthUnstake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "_oldLiquidStakingWithdrawalCredentials", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_liquidStakingWithdrawalCredentials", + "type": "bytes" + } + ], + "name": "LiquidStakingWithdrawalCredentialsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "exitBlockNumbers", + "type": "uint256[]" + } + ], + "name": "NftExitBlockNumberSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_count", + "type": "uint256" + } + ], + "name": "NftStake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_oldNodeOperatorRegistryContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_nodeOperatorRegistryContract", + "type": "address" + } + ], + "name": "NodeOperatorRegistryContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_blacklistOperatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_totalAmount", + "type": "uint256" + } + ], + "name": "OperatorAssigned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "operatorCanLoanAmounts", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newCanloadAmounts", + "type": "uint256" + } + ], + "name": "OperatorCanLoanAmountsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "OperatorClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "OperatorReinvestClRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "OperatorReinvestElRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOperatorSlashContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_operatorSlashContract", + "type": "address" + } + ], + "name": "OperatorSlashContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "RewardsReceive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Transferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "_tokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "UserClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_pubkey", + "type": "bytes" + } + ], + "name": "ValidatorRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "vaultManagerContractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_vaultManagerContract", + "type": "address" + } + ], + "name": "VaultManagerContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_oldWithdrawOracleContractSet", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_withdrawOracleContractSetAddress", + "type": "address" + } + ], + "name": "WithdrawOracleContractSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_withdrawalRequestContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_withdrawalRequestContractAddress", + "type": "address" + } + ], + "name": "WithdrawalRequestContractSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_totalRequestNethAmount", + "type": "uint256" + }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "LargeWithdrawalRequestBurnNeth", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "addPenaltyFundToStakePool", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_assignOperatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "assignOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_daoVaultAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_nodeOperatorRegistryContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawOracleContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_operatorSlashContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawalRequestContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_vaultManagerContract", + "type": "address" + } + ], + "name": "changeCountractSetting", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_operatorIds", + "type": "uint256[]" + }, + { "internalType": "uint256[]", "name": "_rewards", "type": "uint256[]" } + ], + "name": "claimRewardsOfDao", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { + "internalType": "address[]", + "name": "_rewardAddresses", + "type": "address[]" + }, + { "internalType": "uint256[]", "name": "_rewards", "type": "uint256[]" } + ], + "name": "claimRewardsOfOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { "internalType": "uint256[]", "name": "_tokenIds", "type": "uint256[]" }, + { + "internalType": "uint256", + "name": "_totalNftRewards", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_gasHeight", "type": "uint256" }, + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "claimRewardsOfUser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "consensusVaultContract", + "outputs": [ + { + "internalType": "contract IConsensusVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dao", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "daoVaultAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositContract", + "outputs": [ + { + "internalType": "contract IDepositContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositFeeRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "fastUnstakeNFT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nethAmountIn", "type": "uint256" } + ], + "name": "getEthOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getExchangeRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_ethAmountIn", "type": "uint256" } + ], + "name": "getNethOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "getOperatorNethUnstakePoolAmounts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalEthValue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" } + ], + "name": "getUnstakeQuota", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "operatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "quota", "type": "uint256" } + ], + "internalType": "struct LiquidStaking.StakeInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_dao", "type": "address" }, + { + "internalType": "address", + "name": "_daoVaultAddress", + "type": "address" + }, + { "internalType": "bytes", "name": "_withdrawalCreds", "type": "bytes" }, + { + "internalType": "address", + "name": "_nodeOperatorRegistryContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_nETHContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_nVNFTContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawOracleContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_depositContractAddress", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_operatorIds", + "type": "uint256[]" + }, + { "internalType": "address[]", "name": "_users", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "_nethAmounts", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "_consensusVaultContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_vaultManagerContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawalRequestContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_operatorSlashContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_withdrawOracleContractAddress", + "type": "address" + } + ], + "name": "initializeV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "largeWithdrawalUnstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidStakingWithdrawalCredentials", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nETHContract", + "outputs": [ + { "internalType": "contract INETH", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_tokenIds", "type": "uint256[]" }, + { + "internalType": "uint256[]", + "name": "_exitBlockNumbers", + "type": "uint256[]" + } + ], + "name": "nftExitHandle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nodeOperatorRegistryContract", + "outputs": [ + { + "internalType": "contract INodeOperatorsRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operatorCanLoanAmounts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "operatorLoadBlockNumbers", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "operatorLoanRecords", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "operatorNftPoolBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "operatorPoolBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operatorSlashContract", + "outputs": [ + { + "internalType": "contract IOperatorSlash", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "reAssignRecords", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_rewards", "type": "uint256" } + ], + "name": "receiveRewards", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "_pubkeys", "type": "bytes[]" }, + { "internalType": "bytes[]", "name": "_signatures", "type": "bytes[]" }, + { + "internalType": "bytes32[]", + "name": "_depositDataRoots", + "type": "bytes32[]" + } + ], + "name": "registerValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_operatorIds", + "type": "uint256[]" + }, + { "internalType": "uint256[]", "name": "_amounts", "type": "uint256[]" }, + { "internalType": "uint256", "name": "_totalAmount", "type": "uint256" } + ], + "name": "reinvestClRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_operatorIds", + "type": "uint256[]" + }, + { "internalType": "uint256[]", "name": "_amounts", "type": "uint256[]" } + ], + "name": "reinvestElRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_dao", "type": "address" } + ], + "name": "setDaoAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_feeRate", "type": "uint256" } + ], + "name": "setDepositFeeRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_liquidStakingWithdrawalCredentials", + "type": "bytes" + } + ], + "name": "setLiquidStakingWithdrawalCredentials", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newCanLoanAmounts", + "type": "uint256" + } + ], + "name": "setOperatorCanLoanAmounts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "stakeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { + "internalType": "address", + "name": "withdrawalCredentialsAddress", + "type": "address" + } + ], + "name": "stakeNFT", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amounts", "type": "uint256" } + ], + "name": "unstakeETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "vNFTContract", + "outputs": [ + { "internalType": "contract IVNFT", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultManagerContractAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawOracleContract", + "outputs": [ + { + "internalType": "contract IWithdrawOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalRequestContract", + "outputs": [ + { + "internalType": "contract IWithdrawalRequest", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/nodedao/index.js b/src/adaptors/nodedao/index.js new file mode 100644 index 0000000000..c93941b8be --- /dev/null +++ b/src/adaptors/nodedao/index.js @@ -0,0 +1,84 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiStakingPool = require('./abiStakingPool'); + +const filHubPool = '0xfeB16A48dbBB0E637F68215b19B4DF5b12449676'; +const sdkChain = 'filecoin'; +const url = 'https://www.nodedao.com/'; + +const ethStakingPool = '0x8103151E2377e78C04a3d2564e20542680ed3096'; +const ethSdkChain = 'ethereum'; + +const getApy = async () => { + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: ethStakingPool, + abi: abiStakingPool.find((m) => m.name === 'getExchangeRate'), + chain: 'ethereum', + }), + sdk.api.abi.call({ + target: ethStakingPool, + abi: abiStakingPool.find((m) => m.name === 'getExchangeRate'), + chain: 'ethereum', + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: ethStakingPool, + abi: abiStakingPool.find((m) => m.name === 'getExchangeRate'), + chain: 'ethereum', + block: block7dayAgo, + }), + ]); + + const apyBase = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18) * 365 * 100; + + const apyBase7d = + ((exchangeRates[0].output - exchangeRates[2].output) / 1e18 / 7) * + 365 * + 100; + + const ethPriceKey = `coingecko:ethereum`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${ethPriceKey}`) + ).data.coins[ethPriceKey]?.price; + + const totalEthValue = ( + await sdk.api.abi.call({ + abi: abiStakingPool.find((m) => m.name === 'getTotalEthValue'), + target: ethStakingPool, + }) + ).output; + + const totalEthDecimal = totalEthValue / 1e18; + + const ethTvlUsd = totalEthDecimal * ethPrice; + + const ethereumAPY = { + pool: `${ethStakingPool}-${ethSdkChain}`, // unique identifier for the pool in the form of: `${ReceivedTokenAddress}-${chain}`.toLowerCase() + chain: `${ethSdkChain}`, // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) + project: 'nodedao', // protocol (using the slug again) + symbol: 'ETH', // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP + tvlUsd: ethTvlUsd, // number representing current USD TVL in pool + apyBase, // APY from pool fees/supplying in % + apyBase7d, + url, + }; + + return [ethereumAPY]; +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/nolus-protocol/index.js b/src/adaptors/nolus-protocol/index.js new file mode 100644 index 0000000000..35eaea0125 --- /dev/null +++ b/src/adaptors/nolus-protocol/index.js @@ -0,0 +1,112 @@ +const utils = require('../utils') +const _ = require('lodash') +const BigNumber = require('bignumber.js'); + +// Osmosis Noble USDC Protocol Contracts (OSMOSIS-OSMOSIS-USDC_NOBLE) pirin-1 +const osmosisUsdcOracleAddr = 'nolus1vjlaegqa7ssm2ygf2nnew6smsj8ref9cmurerc7pzwxqjre2wzpqyez4w6' +const osmosisUsdcLppAddr = 'nolus1ueytzwqyadm6r0z8ajse7g6gzum4w3vv04qazctf8ugqrrej6n4sq027cf' + +// Osmosis allBTC Protocol Contracts (OSMOSIS-OSMOSIS-ALL_BTC) pirin-1 +const osmosisAllBtcOracleAddr = 'nolus1y0nlrnw25mh2vxhaupamwca4wdvuxs26tq4tnxgjk8pw0gxevwfq5ry07c' +const osmosisAllBtcLppAddr = 'nolus1w2yz345pqheuk85f0rj687q6ny79vlj9sd6kxwwex696act6qgkqfz7jy3' + +// Osmosis allSOL Protocol Contracts (OSMOSIS-OSMOSIS-ALL_SOL) pirin-1 +const osmosisAllSolOracleAddr = 'nolus153kmhl85vavd03r9c7ardw4fgydge6kvvhrx5v2uvec4eyrlwthsejc6ce' +const osmosisAllSolLppAddr = 'nolus1qufnnuwj0dcerhkhuxefda6h5m24e64v2hfp9pac5lglwclxz9dsva77wm' + +// Astroport USDC Protocol Contracts (NEUTRON-ASTROPORT-USDC_NOBLE) pirin-1 +const astroportUsdcOracleAddr = 'nolus1vhzdx9lqexuqc0wqd48c5hc437yzw7jy7ggum9k25yy2hz7eaatq0mepvn' +const astroportUsdcLppAddr = 'nolus17vsedux675vc44yu7et9m64ndxsy907v7sfgrk7tw3xnjtqemx3q6t3xw6' + +// Osmosis stATOM Protocol Contracts (OSMOSIS-OSMOSIS-ST_ATOM) pirin-1 +//Note: APY is 0% atm, so not worth adding, but might in the future +//const osmosisStAtomOracleAddr = 'nolus1mtcv0vhpt94s82mcemj5sc3v94pq3k2g62yfa5p82npfnd3xqx8q2w8c5f' +//const osmosisStAtomLppAddr = 'nolus1jufcaqm6657xmfltdezzz85quz92rmtd88jk5x0hq9zqseem32ysjdm990' + +// Osmosis AKT Protocol Contracts (OSMOSIS-OSMOSIS-AKT) pirin-1 +//Note: APY is 0% atm, so not worth adding, but might in the future +//const osmosisAktOracleAddr = 'nolus12sx0kr60rptp846z2wvuwyxn47spg55dcnzwrhl4f7nfdduzsrxq7rfetn' +//const osmosisAktLppAddr = 'nolus1lxr7f5xe02jq6cce4puk6540mtu9sg36at2dms5sk69wdtzdrg9qq0t67z' + +// Osmosis ATOM Protocol Contracts (OSMOSIS-OSMOSIS-ATOM) pirin-1 +//Note: APY is 0% atm, so not worth adding, but might in the future +//const osmosisAtomOracleAddr = 'nolus16xt97qd5mc2zkya7fs5hvuavk92cqds82qjuq6rf7p7akxfcuxcs5u2280' +//const osmosisAtomLppAddr = 'nolus1u0zt8x3mkver0447glfupz9lz6wnt62j70p5fhhtu3fr46gcdd9s5dz9l6' + +const contracts = [ + { lpp: osmosisUsdcLppAddr, oracle: osmosisUsdcOracleAddr, symbol: 'USDC', protocolName: 'OSMOSIS-OSMOSIS-USDC_NOBLE', meta: ''}, + { lpp: osmosisAllBtcLppAddr, oracle: osmosisAllBtcOracleAddr, symbol: 'BTC', protocolName: 'OSMOSIS-OSMOSIS-ALL_BTC', meta: ''}, + { lpp: osmosisAllSolLppAddr, oracle: osmosisAllSolOracleAddr, symbol: 'SOL', protocolName: 'OSMOSIS-OSMOSIS-ALL_SOL', meta: ''}, + { lpp: astroportUsdcLppAddr, oracle: astroportUsdcOracleAddr, symbol: 'USDC', protocolName: 'NEUTRON-ASTROPORT-USDC_NOBLE', meta: ''} +] + +// nolus node rest api +const api = 'https://lcd.nolus.network' +// ETL(extract transform load) rest api +const etlAddress = 'https://etl.nolus.network' +// api/earn-apr?protocol={protocol_name} +const earnApyBase = 'api/earn-apr' + +const queryContract = async function (contract, data) { + if (typeof data !== 'string') { + data = JSON.stringify(data) + } + let encodedData = Buffer.from(data).toString('base64'); + let endpoint = `${api}/cosmwasm/wasm/v1/contract/${contract}/smart/${encodedData}` + const response = await fetch(endpoint) + const out = await response.json() + return out +} + +const getApy = async () => { + let result = [] + for (let i = 0; i < contracts.length; i++) { + const c = contracts[i]; + let lppTickerData = await queryContract(c.lpp, { 'lpn': [] }) + let oracleCurrenciesData = await queryContract(c.oracle, { 'currencies': {} }) + let oraclePriceData = await queryContract(c.oracle, { 'stable_price': {'currency': lppTickerData.data} }) + let currencyData = _.find(oracleCurrenciesData.data, (n) => n.ticker == lppTickerData.data) + let lppBalanceData = await queryContract(c.lpp, { 'lpp_balance': [] }) + let earnApy = await utils.getData(`${etlAddress}/${earnApyBase}?protocol=${c.protocolName}`) + + // Calculate asset price with BigNumber + const amount = new BigNumber(oraclePriceData.data.amount.amount); + const amountQuote = new BigNumber(oraclePriceData.data.amount_quote.amount); + let price = amountQuote.div(amount); + + // Adjust price for decimal differences + const decimalsAdjustment = { + USDC: 1, + BTC: 1, + SOL: 1000 // 9 - 6 = 3 decimal places difference, 10^3 = 1000 + }; + price = price.times(decimalsAdjustment[c.symbol] || 1); // Default to 1 if symbol is not in the map + + // Calculate TVL in USD + const balance = new BigNumber(lppBalanceData.data.balance.amount); + const tvlUsd = balance.div(new BigNumber(10).pow(currencyData.decimal_digits)).times(price); + + result.push({ + pool: c.lpp, + chain: 'Nolus', + project: 'nolus-protocol', + symbol: c.symbol, + tvlUsd: tvlUsd.toNumber(), + apyBase: parseFloat(earnApy.earn_apr), + // apyReward: null, TODO: add NLS rewards + underlyingTokens: [currencyData.bank_symbol, currencyData.dex_symbol], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + // rewardTokens: ['0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'], TODO: add NLS rewards + poolMeta: c.meta, + }) + } + + return result +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.nolus.io/earn', +} + +// cd src/adaptors && npm run test --adapter=nolus-protocol \ No newline at end of file diff --git a/src/adaptors/nostra-money-market/abis/AssetToken.js b/src/adaptors/nostra-money-market/abis/AssetToken.js new file mode 100644 index 0000000000..00c8bfe96f --- /dev/null +++ b/src/adaptors/nostra-money-market/abis/AssetToken.js @@ -0,0 +1,34 @@ +const assetToken = [ + { + name: 'underlyingAsset', + type: 'function', + inputs: [], + outputs: [ + { + name: '_underlyingAsset', + type: 'felt', + }, + ], + stateMutability: 'view', + customType: 'address', + }, + { + name: 'totalSupply', + type: 'function', + inputs: [], + outputs: [ + { + name: 'totalSupply', + type: 'Uint256', + }, + ], + stateMutability: 'view', + }, +]; + +const assetTokenAbi = {}; +assetToken.forEach((i) => (assetTokenAbi[i.name] = i)); + +module.exports = { + assetTokenAbi, +}; diff --git a/src/adaptors/nostra-money-market/abis/InterestRateModel.js b/src/adaptors/nostra-money-market/abis/InterestRateModel.js new file mode 100644 index 0000000000..7d3d673e1c --- /dev/null +++ b/src/adaptors/nostra-money-market/abis/InterestRateModel.js @@ -0,0 +1,736 @@ +const interestRateModel = [ + { + name: 'Uint256', + size: 2, + type: 'struct', + members: [ + { + name: 'low', + type: 'felt', + offset: 0, + }, + { + name: 'high', + type: 'felt', + offset: 1, + }, + ], + }, + { + name: 'InterestStateEntity', + size: 9, + type: 'struct', + members: [ + { + name: 'lendingRate', + type: 'Uint256', + offset: 0, + }, + { + name: 'borrowingRate', + type: 'Uint256', + offset: 2, + }, + { + name: 'lastUpdateTimestamp', + type: 'felt', + offset: 4, + }, + { + name: 'lendingIndex', + type: 'Uint256', + offset: 5, + }, + { + name: 'borrowingIndex', + type: 'Uint256', + offset: 7, + }, + ], + }, + { + name: 'InterestRateConfigEntity', + size: 13, + type: 'struct', + members: [ + { + name: 'optimalUtilizationRate', + type: 'Uint256', + offset: 0, + }, + { + name: 'baseBorrowingRate', + type: 'Uint256', + offset: 2, + }, + { + name: 'rateSlope1', + type: 'Uint256', + offset: 4, + }, + { + name: 'rateSlope2', + type: 'Uint256', + offset: 6, + }, + { + name: 'generalProtocolFee', + type: 'Uint256', + offset: 8, + }, + { + name: 'feesRecipient', + type: 'felt', + offset: 10, + }, + { + name: 'interestBearingToken', + type: 'felt', + offset: 11, + }, + { + name: 'interestBearingCollateralToken', + type: 'felt', + offset: 12, + }, + ], + }, + { + data: [ + { + name: 'previousOwner', + type: 'felt', + }, + { + name: 'newOwner', + type: 'felt', + }, + ], + keys: [], + name: 'OwnershipTransferred', + type: 'event', + }, + { + data: [ + { + name: 'currentOwner', + type: 'felt', + }, + { + name: 'newOwner', + type: 'felt', + }, + ], + keys: [], + name: 'OwnershipProposed', + type: 'event', + }, + { + data: [ + { + name: 'caller', + type: 'felt', + }, + { + name: 'pending_owner', + type: 'felt', + }, + ], + keys: [], + name: 'OwnershipProposalCancelled', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'optimalUtilizationRate', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestRateConfigSetOptimalUtilizationRate', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'baseBorrowingRate', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestRateConfigSetBaseBorrowingRate', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'rateSlope1', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestRateConfigSetRateSlope1', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'rateSlope2', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestRateConfigSetRateSlope2', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'generalProtocolFee', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestRateConfigSetGeneralProtocolFee', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'interestBearingToken', + type: 'felt', + }, + ], + keys: [], + name: 'InterestRateConfigSetInterestBearingToken', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'interestBearingCollateralToken', + type: 'felt', + }, + ], + keys: [], + name: 'InterestRateConfigSetInterestBearingCollateralToken', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'lendingRate', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestStateSetLendingRate', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'borrowingRate', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestStateSetBorrowingRate', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'lastUpdateTimestamp', + type: 'felt', + }, + ], + keys: [], + name: 'InterestStateSetLastUpdateTimestamp', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'lendingIndex', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestStateSetLendingIndex', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'borrowingIndex', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestStateSetBorrowingIndex', + type: 'event', + }, + { + data: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'account', + type: 'felt', + }, + { + name: 'sender', + type: 'felt', + }, + ], + keys: [], + name: 'RoleGranted', + type: 'event', + }, + { + data: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'account', + type: 'felt', + }, + { + name: 'sender', + type: 'felt', + }, + ], + keys: [], + name: 'RoleRevoked', + type: 'event', + }, + { + data: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'previousAdminRole', + type: 'felt', + }, + { + name: 'newAdminRole', + type: 'felt', + }, + ], + keys: [], + name: 'RoleAdminChanged', + type: 'event', + }, + { + data: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'lendingRate', + type: 'Uint256', + }, + { + name: 'borrowingRate', + type: 'Uint256', + }, + { + name: 'lendingIndex', + type: 'Uint256', + }, + { + name: 'borrowingIndex', + type: 'Uint256', + }, + ], + keys: [], + name: 'InterestStateUpdated', + type: 'event', + }, + { + name: 'getInterestState', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [ + { + name: 'interestState', + type: 'InterestStateEntity', + }, + ], + stateMutability: 'view', + }, + { + name: 'getInterestRateConfig', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [ + { + name: 'interestRateConfig', + type: 'InterestRateConfigEntity', + }, + ], + stateMutability: 'view', + }, + { + name: 'getBorrowingIndex', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [ + { + name: 'borrowingIndex', + type: 'Uint256', + }, + ], + stateMutability: 'view', + }, + { + name: 'getLendingIndex', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [ + { + name: 'lendingIndex', + type: 'Uint256', + }, + ], + stateMutability: 'view', + }, + { + name: 'hasRole', + type: 'function', + inputs: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'user', + type: 'felt', + }, + ], + outputs: [ + { + name: 'hasRole', + type: 'felt', + }, + ], + stateMutability: 'view', + }, + { + name: 'owner', + type: 'function', + inputs: [], + outputs: [ + { + name: 'owner', + type: 'felt', + }, + ], + stateMutability: 'view', + }, + { + name: 'pendingOwner', + type: 'function', + inputs: [], + outputs: [ + { + name: 'pending_owner', + type: 'felt', + }, + ], + stateMutability: 'view', + }, + { + name: 'constructor', + type: 'constructor', + inputs: [ + { + name: 'owner', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'replaceClass', + type: 'function', + inputs: [ + { + name: 'class_hash', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'initMarket', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'interestBearingToken', + type: 'felt', + }, + { + name: 'interestBearingCollateralToken', + type: 'felt', + }, + { + name: 'optimalUtilizationRate', + type: 'Uint256', + }, + { + name: 'baseBorrowingRate', + type: 'Uint256', + }, + { + name: 'rateSlope1', + type: 'Uint256', + }, + { + name: 'rateSlope2', + type: 'Uint256', + }, + { + name: 'generalProtocolFee', + type: 'Uint256', + }, + { + name: 'feesRecipient', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'configureDebt', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'optimalUtilizationRate', + type: 'Uint256', + }, + { + name: 'baseBorrowingRate', + type: 'Uint256', + }, + { + name: 'rateSlope1', + type: 'Uint256', + }, + { + name: 'rateSlope2', + type: 'Uint256', + }, + { + name: 'generalProtocolFee', + type: 'Uint256', + }, + { + name: 'feesRecipient', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'accrueInterest', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'onLiquidityChange', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'releaseUnderlying', + type: 'function', + inputs: [ + { + name: 'debtToken', + type: 'felt', + }, + { + name: 'recipient', + type: 'felt', + }, + { + name: 'amount', + type: 'Uint256', + }, + ], + outputs: [], + }, + { + name: 'grantRole', + type: 'function', + inputs: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'user', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'revokeRole', + type: 'function', + inputs: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'user', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'renounceRole', + type: 'function', + inputs: [ + { + name: 'role', + type: 'felt', + }, + { + name: 'user', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'transferOwnership', + type: 'function', + inputs: [ + { + name: 'pendingOwner', + type: 'felt', + }, + ], + outputs: [], + }, + { + name: 'acceptOwnership', + type: 'function', + inputs: [], + outputs: [], + }, + { + name: 'cancelOwnershipProposal', + type: 'function', + inputs: [], + outputs: [], + }, +]; + +const interestRateModelAbi = {}; +interestRateModel.forEach((i) => (interestRateModelAbi[i.name] = i)); + +module.exports = { + interestRateModelAbi, +}; diff --git a/src/adaptors/nostra-money-market/abis/Oracle.js b/src/adaptors/nostra-money-market/abis/Oracle.js new file mode 100644 index 0000000000..00c8bfe96f --- /dev/null +++ b/src/adaptors/nostra-money-market/abis/Oracle.js @@ -0,0 +1,34 @@ +const assetToken = [ + { + name: 'underlyingAsset', + type: 'function', + inputs: [], + outputs: [ + { + name: '_underlyingAsset', + type: 'felt', + }, + ], + stateMutability: 'view', + customType: 'address', + }, + { + name: 'totalSupply', + type: 'function', + inputs: [], + outputs: [ + { + name: 'totalSupply', + type: 'Uint256', + }, + ], + stateMutability: 'view', + }, +]; + +const assetTokenAbi = {}; +assetToken.forEach((i) => (assetTokenAbi[i.name] = i)); + +module.exports = { + assetTokenAbi, +}; diff --git a/src/adaptors/nostra-money-market/index.js b/src/adaptors/nostra-money-market/index.js new file mode 100644 index 0000000000..d231182bc2 --- /dev/null +++ b/src/adaptors/nostra-money-market/index.js @@ -0,0 +1,255 @@ +const axios = require('axios'); +const { uint256 } = require('starknet'); +const { call } = require('../../helper/starknet'); +const { assetTokenAbi } = require('./abis/AssetToken'); +const { interestRateModelAbi } = require('./abis/InterestRateModel'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + +const interestRateModel = + '0x59a943ca214c10234b9a3b61c558ac20c005127d183b86a99a8f3c60a08b4ff'; +const oracle = + '0x07b05e8dc9c770b72befcf09599132093cf9e57becb2d1b3e89514e1f9bdf0ab'; +const markets = { + WBTC: { + address: + '0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac', + decimals: 8, + supplyTokens: [ + '0x0735d0f09a4e8bf8a17005fa35061b5957dcaa56889fc75df9e94530ff6991ea', + '0x05b7d301fa769274f20e89222169c0fad4d846c366440afc160aafadd6f88f0c', + '0x073132577e25b06937c64787089600886ede6202d085e6340242a5a32902e23e', + '0x036b68238f3a90639d062669fdec08c4d0bdd09826b1b6d24ef49de6d8141eaa', + ], + debtToken: + '0x0491480f21299223b9ce770f23a2c383437f9fbf57abc2ac952e9af8cdb12c97', + }, + ETH: { + address: + '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + decimals: 18, + supplyTokens: [ + '0x01fecadfe7cda2487c66291f2970a629be8eecdcb006ba4e71d1428c2b7605c7', + '0x057146f6409deb4c9fa12866915dd952aa07c1eb2752e451d7f3b042086bdeb8', + '0x07170f54dd61ae85377f75131359e3f4a12677589bb7ec5d61f362915a5c0982', + '0x044debfe17e4d9a5a1e226dabaf286e72c9cc36abbe71c5b847e669da4503893', + ], + debtToken: + '0x00ba3037d968790ac486f70acaa9a1cab10cf5843bb85c986624b4d0e5a82e74', + }, + USDC: { + address: + '0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8', + decimals: 6, + supplyTokens: [ + '0x002fc2d4b41cc1f03d185e6681cbd40cced61915d4891517a042658d61cba3b1', + '0x05dcd26c25d9d8fd9fc860038dcb6e4d835e524eb8a85213a8cda5b7fff845f6', + '0x06eda767a143da12f70947192cd13ee0ccc077829002412570a88cd6539c1d85', + '0x05f296e1b9f4cf1ab452c218e72e02a8713cee98921dad2d3b5706235e128ee4', + ], + debtToken: + '0x063d69ae657bd2f40337c39bf35a870ac27ddf91e6623c2f52529db4c1619a51', + }, + DAI: { + address: + '0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3', + decimals: 18, + supplyTokens: [ + '0x022ccca3a16c9ef0df7d56cbdccd8c4a6f98356dfd11abc61a112483b242db90', + '0x04f18ffc850cdfa223a530d7246d3c6fc12a5969e0aa5d4a88f470f5fe6c46e9', + '0x02b5fd690bb9b126e3517f7abfb9db038e6a69a068303d06cf500c49c1388e20', + '0x005c4676bcb21454659479b3cd0129884d914df9c9b922c1c649696d2e058d70', + ], + debtToken: + '0x066037c083c33330a8460a65e4748ceec275bbf5f28aa71b686cbc0010e12597', + }, + USDT: { + address: + '0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8', + decimals: 6, + supplyTokens: [ + '0x0360f9786a6595137f84f2d6931aaec09ceec476a94a98dcad2bb092c6c06701', + '0x0453c4c996f1047d9370f824d68145bd5e7ce12d00437140ad02181e1d11dc83', + '0x06669cb476aa7e6a29c18b59b54f30b8bfcfbb8444f09e7bbb06c10895bf5d7b', + '0x0514bd7ee8c97d4286bd481c54aa0793e43edbfb7e1ab9784c4b30469dcf9313', + ], + debtToken: + '0x024e9b0d6bc79e111e6872bb1ada2a874c25712cf08dfc5bcf0de008a7cca55f', + }, + wstETH: { + address: + '0x042b8f0484674ca266ac5d08e4ac6a3fe65bd3129795def2dca5c34ecc5f96d2', + decimals: 18, + supplyTokens: [ + '0x00ca44c79a77bcb186f8cdd1a0cd222cc258bebc3bec29a0a020ba20fdca40e9', + '0x009377fdde350e01e0397820ea83ed3b4f05df30bfb8cf8055d62cafa1b2106a', + '0x07e2c010c0b381f347926d5a203da0335ef17aefee75a89292ef2b0f94924864', + '0x05eb6de9c7461b3270d029f00046c8a10d27d4f4a4c931a4ea9769c72ef4edbb', + ], + debtToken: + '0x0348cc417fc877a7868a66510e8e0d0f3f351f5e6b0886a86b652fcb30a3d1fb', + }, + LORDS: { + address: + '0x0124aeb495b947201f5fac96fd1138e326ad86195b98df6dec9009158a533b49', + decimals: 18, + supplyTokens: [ + '0x0507eb06dd372cb5885d3aaf18b980c41cd3cd4691cfd3a820339a6c0cec2674', + '0x0739760bce37f89b6c1e6b1198bb8dc7166b8cf21509032894f912c9d5de9cbd', + '0x000d294e16a8d24c32eed65ea63757adde543d72bad4af3927f4c7c8969ff43d', + '0x02530a305dd3d92aad5cf97e373a3d07577f6c859337fb0444b9e851ee4a2dd4', + ], + debtToken: + '0x035778d24792bbebcf7651146896df5f787641af9e2a3db06480a637fbc9fff8', + }, + STRK: { + address: + '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', + decimals: 18, + supplyTokens: [ + '0x026c5994c2462770bbf940552c5824fb0e0920e2a8a5ce1180042da1b3e489db', + '0x07c2e1e733f28daa23e78be3a4f6c724c0ab06af65f6a95b5e0545215f1abc1b', + '0x07c535ddb7bf3d3cb7c033bd1a4c3aac02927a4832da795606c0f3dbbc6efd17', + '0x040f5a6b7a6d3c472c12ca31ae6250b462c6d35bbdae17bd52f6c6ca065e30cf', + ], + debtToken: + '0x001258eae3eae5002125bebf062d611a772e8aea3a1879b64a19f363ebd00947', + }, + nstSTRK: { + address: + '0x04619e9ce4109590219c5263787050726be63382148538f3f936c22aa87d2fc2', + decimals: 18, + supplyTokens: [ + '0x078a40c85846e3303bf7982289ca7def68297d4b609d5f588208ac553cff3a18', + '0x067a34ff63ec38d0ccb2817c6d3f01e8b0c4792c77845feb43571092dcf5ebb5', + '0x04b11c750ae92c13fdcbe514f9c47ba6f8266c81014501baa8346d3b8ba55342', + '0x0142af5b6c97f02cac9c91be1ea9895d855c5842825cb2180673796e54d73dc5', + ], + debtToken: + '0x0292be6baee291a148006db984f200dbdb34b12fb2136c70bfe88649c12d934b', + }, + UNO: { + address: + '0x0719b5092403233201aa822ce928bd4b551d0cdb071a724edd7dc5e5f57b7f34', + decimals: 18, + supplyTokens: [ + '0x1325caf7c91ee415b8df721fb952fa88486a0fc250063eafddd5d3c67867ce7', + '0x2a3a9d7bcecc6d3121e3b6180b73c7e8f4c5f81c35a90c8dd457a70a842b723', + '0x6757ef9960c5bc711d1ba7f7a3bff44a45ba9e28f2ac0cc63ee957e6cada8ea', + '0x7d717fb27c9856ea10068d864465a2a8f9f669f4f78013967de06149c09b9af', + ], + debtToken: + '0x4b036839a8769c04144cc47415c64b083a2b26e4a7daa53c07f6042a0d35792', + }, + NSTR: { + address: + '0x00c530f2c0aa4c16a0806365b0898499fba372e5df7a7172dc6fe9ba777e8007', + decimals: 18, + supplyTokens: [ + '0x2b674ffda238279de5550d6f996bf717228d316555f07a77ef0a082d925b782', + '0x6f8ad459c712873993e9ffb9013a469248343c3d361e4d91a8cac6f98575834', + '0x2589fc11f60f21af6a1dda3aeb7a44305c552928af122f2834d1c3b1a7aa626', + '0x46ab56ec0c6a6d42384251c97e9331aa75eb693e05ed8823e2df4de5713e9a4', + ], + debtToken: + '0x3e0576565c1b51fcac3b402eb002447f21e97abb5da7011c0a2e0b465136814', + }, +}; +const starknetFoundationIncentivesEndpoint = + 'https://kx58j6x5me.execute-api.us-east-1.amazonaws.com/starknet/fetchFile?file=prod-api/lending/lending_strk_grant.json'; + +async function getTokenPrice(token) { + const networkTokenPair = `starknet:${token}`; + return ( + await axios.get(`https://coins.llama.fi/prices/current/${networkTokenPair}`) + ).data.coins[networkTokenPair]?.price; +} + +async function getApys(debtToken) { + const state = await call({ + abi: interestRateModelAbi.getInterestState, + target: interestRateModel, + params: [debtToken], + allAbi: [ + interestRateModelAbi.Uint256, + interestRateModelAbi.InterestStateEntity, + ], + }); + return [ + BigNumber(uint256.uint256ToBN(state.lendingRate).toString()) + .times(100) + .div(1e18) + .toNumber(), + BigNumber(uint256.uint256ToBN(state.borrowingRate).toString()) + .times(100) + .div(1e18) + .toNumber(), + ]; +} + +async function getStarknetFoundationIncentives() { + const { data } = await axios.get(starknetFoundationIncentivesEndpoint); + return data['Nostra']; +} + +async function getSupply(tokens) { + const supplies = await Promise.all( + tokens.map( + async (token) => + await call({ + abi: assetTokenAbi.totalSupply, + target: token, + }) + ) + ); + return supplies + .reduce( + (acc, supply) => BigNumber(acc).plus(supply.toString()), + BigNumber(0) + ) + .toNumber(); +} + +async function apy() { + const incentives = await getStarknetFoundationIncentives(); + + const pools = await Promise.all( + Object.entries(markets).map( + async ([name, { address, decimals, supplyTokens, debtToken }]) => { + const price = await getTokenPrice(address); + const totalSupply = await getSupply(supplyTokens); + const totalBorrow = await getSupply([debtToken]); + const totalSupplyUsd = (totalSupply * price) / 10 ** decimals; + const totalBorrowUsd = (totalBorrow * price) / 10 ** decimals; + const [lendingApy, borrowApy] = await getApys(debtToken); + const tokenIncentive = incentives[name]; + + return { + pool: debtToken.toLowerCase(), + project: 'nostra-money-market', + symbol: name, + chain: 'Starknet', + apyBase: lendingApy, + apyReward: + tokenIncentive && tokenIncentive.length > 0 + ? 100 * + tokenIncentive[tokenIncentive.length - 1]['strk_grant_apr_nrs'] + : 0, + rewardTokens: tokenIncentive ? [markets.STRK.address] : [], + tvlUsd: totalSupplyUsd - totalBorrowUsd, + underlyingTokens: [address], + apyBaseBorrow: borrowApy, + totalSupplyUsd, + totalBorrowUsd, + url: `https://app.nostra.finance/lend-borrow/${name}/deposit`, + }; + } + ) + ); + return pools.filter((i) => utils.keepFinite(i)); +} + +module.exports = { + apy, + url: 'https://app.nostra.finance', +}; diff --git a/src/adaptors/nostra-pools/abi.js b/src/adaptors/nostra-pools/abi.js new file mode 100644 index 0000000000..b37c21d2c5 --- /dev/null +++ b/src/adaptors/nostra-pools/abi.js @@ -0,0 +1,27 @@ +const factoryAbi = [ + { + name: 'all_pairs', + type: 'function', + inputs: [], + outputs: [ + // Cairo 0 workaround since the used Starknet.js doesn't support Cairo 2 types + { + name: 'pairs_len', + type: 'felt', + }, + { + name: 'pairs', + type: 'felt*', + }, + ], + state_mutability: 'view', + }, +]; + +const factory = {}; +factoryAbi.forEach((i) => (factory[i.name] = i)); + +module.exports = { + factory, + factoryAbi, +}; diff --git a/src/adaptors/nostra-pools/index.js b/src/adaptors/nostra-pools/index.js new file mode 100644 index 0000000000..691c6226bf --- /dev/null +++ b/src/adaptors/nostra-pools/index.js @@ -0,0 +1,53 @@ +const axios = require('axios'); +const { addAddressPadding } = require('starknet'); +const { call } = require('../../helper/starknet'); +const abi = require('./abi'); + +const factory = + '0x02a93ef8c7679a5f9b1fcf7286a6e1cadf2e9192be4bcb5cb2d1b39062697527'; +const strk = + '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'; +const api = 'https://api.nostra.finance/query/pool_aprs'; + +async function apy() { + const { pairs } = await call({ + target: factory, + abi: abi.factory.all_pairs, + }); + const { data: pools_data } = await axios.get(api); + + return pairs + .map((pair) => { + const pairAddress = addAddressPadding(`0x${pair.toString(16)}`); + const pool_data = pools_data[pairAddress]; + + if (!pool_data) { + return null; + } + + const { id, tokenAAddress, tokenBAddress, tvl, baseApr, rewardApr } = + pool_data; + + return { + pool: pairAddress, + project: 'nostra-pools', + symbol: id === 'UNOPSM' ? 'UNO-USDC' : id.replace('-DEGEN', ''), + chain: 'Starknet', + apyBase: +baseApr * 100, + apyReward: +rewardApr * 100, + rewardTokens: rewardApr !== '0' ? [strk] : [], + tvlUsd: +tvl, + underlyingTokens: [tokenAAddress, tokenBAddress], + url: + id === 'UNOPSM' + ? 'https://app.nostra.finance/uno' + : `https://app.nostra.finance/pools/${id}/deposit`, + }; + }) + .filter((x) => x !== null); +} + +module.exports = { + apy, + url: 'https://app.nostra.finance', +}; diff --git a/src/adaptors/notional-v2/index.js b/src/adaptors/notional-v2/index.js new file mode 100644 index 0000000000..37a98da7ea --- /dev/null +++ b/src/adaptors/notional-v2/index.js @@ -0,0 +1,24 @@ +const utils = require('../utils'); +const main = async () => { + let data = await utils.getData( + 'https://classic.notional.finance/.netlify/functions/yields' + ); + data = data.map((p) => { + const name = p.symbol.split(' '); + return { + ...p, + project: 'notional-v2', + pool: `${p.symbol.replace(/\s/g, '-')}-notional`, + symbol: name[0], + poolMeta: name.length > 1 ? name.slice(1).join(' ') : null, + url: `https://www.notional.finance/lend/${name}`, + }; + }); + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/notional-v3/index.js b/src/adaptors/notional-v3/index.js new file mode 100644 index 0000000000..55310a20f9 --- /dev/null +++ b/src/adaptors/notional-v3/index.js @@ -0,0 +1,403 @@ +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); + +const API = (chain) => + chain === 'ethereum' + ? `https://registry.notional.finance/mainnet/yields` + : `https://registry.notional.finance/${chain}/yields`; +const NOTE_Mainnet = '0xCFEAead4947f0705A14ec42aC3D44129E1Ef3eD5'; + +const SUBGRAPHS = { + arbitrum: sdk.graph.modifyEndpoint( + 'DnghsCNvJ4xmp4czX8Qn7UpkJ8HyHjy7cFN4wcH91Nrx' + ), + ethereum: sdk.graph.modifyEndpoint( + '4oVxkMtN4cFepbiYrSKz1u6HWnJym435k5DQRAFt2vHW' + ), +}; + +const query = gql` + query GetYieldsData { + oracles( + where: { + matured: false + oracleType_in: [ + nTokenToUnderlyingExchangeRate + nTokenBlendedInterestRate + nTokenFeeRate + nTokenIncentiveRate + nTokenSecondaryIncentiveRate + ] + } + first: 1000 + ) { + base { + id + } + quote { + id + symbol + } + decimals + oracleType + latestRate + } + NOTE: tokens(where: { tokenType: NOTE }) { + id + } + # Use this to calculate the nToken TVL + nTokens: tokens(where: { tokenType: nToken }) { + id + symbol + totalSupply + currencyId + underlying { + id + symbol + decimals + } + } + activeMarkets { + pCashMarket { + underlying { + id + symbol + decimals + } + primeCash { + id + symbol + decimals + } + primeDebt { + id + symbol + decimals + } + current { + totalPrimeCashInUnderlying + totalPrimeDebtInUnderlying + supplyInterestRate + debtInterestRate + } + } + fCashMarkets { + maturity + underlying { + id + symbol + decimals + } + fCash { + id + symbol + decimals + } + current { + lastImpliedRate + totalfCashPresentValue + totalPrimeCashInUnderlying + totalfCashDebtOutstandingPresentValue + } + } + } + incentives { + id + currentSecondaryReward { + id + } + } + } +`; + +async function getUSDPrice(chain, address) { + // price of base token in USD terms + const key = `${chain}:${address}`; + const priceRes = await superagent.get( + `https://coins.llama.fi/prices/current/${key}` + ); + const price = priceRes.body.coins[key]; + return price ? price.price : 0; +} + +const defaultLeverageRatio = 3.5; + +function unique(arr) { + return arr.filter((el, index, source) => source.indexOf(el) === index); +} + +const getPools = async (chain) => { + let results = await request(SUBGRAPHS[chain], query); + const project = 'notional-v3'; + const NOTE = results['NOTE'][0].id; + const NOTEPriceUSD = await getUSDPrice('ethereum', NOTE_Mainnet); + const notionalChain = chain === 'ethereum' ? 'mainnet' : chain; + + const nTokens = await Promise.all( + results['nTokens'].map(async (n) => { + const oracles = results['oracles'].filter( + ({ quote: { symbol } }) => symbol === n.symbol + ); + const nTokenExRate = oracles.find( + ({ oracleType }) => oracleType === 'nTokenToUnderlyingExchangeRate' + ).latestRate; + const nTokenBlendedRate = oracles.find( + ({ oracleType }) => oracleType === 'nTokenBlendedInterestRate' + ).latestRate; + const nTokenFeeRate = oracles.find( + ({ oracleType }) => oracleType === 'nTokenFeeRate' + ).latestRate; + + // NOTE incentive rate + const nTokenIncentiveRate = + oracles.find(({ oracleType }) => oracleType === 'nTokenIncentiveRate') + ?.latestRate || 0; + const underlyingDecimals = BigInt(10) ** BigInt(n.underlying.decimals); + const tvlUnderlying = + (BigInt(n.totalSupply) * BigInt(nTokenExRate)) / BigInt(1e9); + const underlyingPrice = await getUSDPrice(chain, n.underlying.id); + const tvlUsd = (Number(tvlUnderlying) / 1e8) * underlyingPrice; + const NOTEPriceInUnderlying = NOTEPriceUSD / underlyingPrice; + + let apyReward = + (Number(nTokenIncentiveRate) * NOTEPriceInUnderlying * 100) / 1e9; + + const secondaryIncentiveToken = results['incentives'].find( + (i) => i.id === `${n.currencyId}` + ); + const nTokenSecondaryIncentiveRate = + oracles.find( + ({ oracleType }) => oracleType === 'nTokenSecondaryIncentiveRate' + )?.latestRate || 0; + const rewardTokens = [NOTE]; + + if ( + secondaryIncentiveToken.currentSecondaryReward !== null && + nTokenSecondaryIncentiveRate + ) { + const token = secondaryIncentiveToken.currentSecondaryReward.id; + rewardTokens.push(token); + const rewardPriceUSD = await getUSDPrice(chain, token); + const PriceInUnderlying = rewardPriceUSD / underlyingPrice; + const apySecondary = + (Number(nTokenSecondaryIncentiveRate) * PriceInUnderlying * 100) / + 1e17; + apyReward = apyReward + apySecondary; + } + + return { + pool: `${n.id}-${chain}`, + chain, + project, + symbol: n.symbol, + rewardTokens, + underlyingTokens: [n.underlying.id], + poolMeta: 'Liquidity Token', + url: `https://notional.finance/liquidity-variable/${notionalChain}/${n.underlying.symbol}`, + tvlUsd, + apyBase: + ((Number(nTokenBlendedRate) + Number(nTokenFeeRate)) * 100) / 1e9, + apyReward, + }; + }) + ); + + const primeCash = await Promise.all( + results['activeMarkets'].map(async ({ pCashMarket: p }) => { + const underlyingDecimals = BigNumber(10).pow(p.underlying.decimals); + const totalSupplyUnderlying = BigNumber( + p.current.totalPrimeCashInUnderlying + ).div(underlyingDecimals); + const totalDebtUnderlying = BigNumber( + p.current.totalPrimeDebtInUnderlying || 0 + ).div(underlyingDecimals); + const tvlUnderlying = totalSupplyUnderlying.minus(totalDebtUnderlying); + const underlyingPrice = await getUSDPrice(chain, p.underlying.id); + const tvlUsd = tvlUnderlying.times(underlyingPrice).toNumber(); + const totalSupplyUsd = totalSupplyUnderlying + .times(underlyingPrice) + .toNumber(); + const totalBorrowUsd = totalDebtUnderlying + .times(underlyingPrice) + .toNumber(); + + return { + pool: `${p.primeCash.id}-${chain}`, + chain, + project, + symbol: p.primeCash.symbol, + underlyingTokens: [p.underlying.id], + poolMeta: 'Variable Lend', + url: `https://notional.finance/lend-variable/${notionalChain}/${p.underlying.symbol}`, + tvlUsd, + apyBase: (Number(p.current.supplyInterestRate) * 100) / 1e9, + apyBaseBorrow: (Number(p.current.debtInterestRate) * 100) / 1e9, + totalSupplyUsd, + totalBorrowUsd, + }; + }) + ); + + const fCash = await Promise.all( + results['activeMarkets'].flatMap(({ fCashMarkets }) => { + return fCashMarkets + .filter(({ maturity }) => Number(maturity) * 1000 > Date.now()) + .map(async (f) => { + const underlyingDecimals = BigNumber(10).pow(f.underlying.decimals); + const totalfCashUnderlying = BigNumber( + f.current.totalfCashPresentValue + ).div(underlyingDecimals); + const totalDebtUnderlying = BigNumber( + f.current.totalfCashDebtOutstandingPresentValue + ).div(-underlyingDecimals); + const tvlUnderlying = totalfCashUnderlying + .plus(BigNumber(f.current.totalPrimeCashInUnderlying)) + .div(underlyingDecimals); + + const underlyingPrice = await getUSDPrice(chain, f.underlying.id); + const tvlUsd = tvlUnderlying.times(underlyingPrice).toNumber(); + const totalSupplyUsd = totalfCashUnderlying + .times(underlyingPrice) + .toNumber(); + const totalBorrowUsd = totalDebtUnderlying + .times(underlyingPrice) + .toNumber(); + const date = new Date(Number(f.maturity) * 1000) + .toISOString() + .split('T')[0]; + + return { + pool: `${f.fCash.id}-${chain}`, + chain, + project, + symbol: `f${f.underlying.symbol}`, + underlyingTokens: [f.underlying.id], + poolMeta: `Fixed Lend Maturing On ${date}`, + url: `https://notional.finance/lend-fixed/${notionalChain}/${f.underlying.symbol}`, + tvlUsd, + apyBase: (Number(f.current.lastImpliedRate) * 100) / 1e9, + apyBaseBorrow: (Number(f.current.lastImpliedRate) * 100) / 1e9, + totalSupplyUsd, + totalBorrowUsd, + }; + }); + }) + ); + + const leveragedLiquidity = nTokens.map((n) => { + const lowestBorrow = primeCash + .concat(fCash) + .filter( + ({ underlyingTokens }) => underlyingTokens[0] === n.underlyingTokens[0] + ) + .reduce((l, b) => { + if (!l || (l && b.apyBaseBorrow < l.apyBaseBorrow)) return b; + else return l; + }); + const apyBase = + n.apyBase + + (n.apyBase - lowestBorrow.apyBaseBorrow) * defaultLeverageRatio; + // Borrow rates are applied to the apyBase only + const apyReward = n.apyReward + n.apyReward * defaultLeverageRatio; + const underlyingSymbol = results['nTokens'].find( + (d) => d.symbol == n.symbol + )?.underlying.symbol; + + return { + pool: `${n.pool}-leveraged`, + chain: n.chain, + project: n.project, + symbol: n.symbol, + rewardTokens: n.rewardTokens, + underlyingTokens: n.underlyingTokens, + poolMeta: 'Leveraged Liquidity Token', + url: `https://notional.finance/liquidity-leveraged/${notionalChain}/CreateLeveragedNToken/${underlyingSymbol}`, + tvlUsd: n.tvlUsd, + // "base" apy is the total leveraged apy minus the reward apy + apyBase, + apyReward, + }; + }); + + // NOTE: internal API results are only used for vaults, which often have off-chain custom + // calculations to get the current APY + const apiResults = await (await fetch(API(chain))).json(); + const vaultAddresses = unique( + apiResults + .filter((r) => Number(r.token.maturity) * 1000 > Date.now()) + .filter((r) => r.token.tokenType === 'VaultShare' && !!r['leveraged']) + .map((r) => r.token.vaultAddress) + ); + + const vaults = await Promise.all( + vaultAddresses.map(async (vaultAddress) => { + const maturities = apiResults.filter( + (r) => r.token.vaultAddress === vaultAddress && !!r['leveraged'] + ); + const tvlUnderlying = maturities.reduce( + (tvl, m) => tvl.plus(new BigNumber(m.tvl.hex)), + new BigNumber(0) + ); + const highestYield = maturities.reduce((h, m) => { + if (!h || (h && h.totalAPY < m.totalAPY)) return m; + else return h; + }); + + const underlyingPrice = await getUSDPrice( + chain, + highestYield.underlying.id + ); + const tvlUsd = tvlUnderlying + .div(new BigNumber(10).pow(highestYield.underlying.decimals)) + .times(underlyingPrice) + .toNumber(); + + return { + pool: `${vaultAddress}-${chain}`, + chain, + project, + symbol: highestYield.vaultName, + underlyingTokens: [highestYield.underlying.id], + poolMeta: 'Leveraged Vault', + url: `https://notional.finance/vaults/${notionalChain}/${vaultAddress}`, + tvlUsd, + apyBase: highestYield.totalAPY, + }; + }) + ); + + return nTokens + .concat(primeCash) + .concat(fCash) + .concat(leveragedLiquidity) + .concat(vaults) + .filter( + (i) => i.pool !== '0xc87a900078f04c45b7f14e46c520d4a6f37296b0-ethereum' + ); +}; + +const main = async () => { + const chains = Object.keys(SUBGRAPHS); + const results = await Promise.allSettled( + chains.map((chain) => getPools(chain)) + ); + + return results.reduce((acc, result, index) => { + if (result.status === 'fulfilled') { + return acc.concat(result.value); + } + console.error( + `Notional-v3 subgraph request failed for ${chains[index]}:`, + result.reason + ); + return acc; + }, []); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/nucleon/abis/lp.json b/src/adaptors/nucleon/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/nucleon/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/nucleon/abis/masterchef.json b/src/adaptors/nucleon/abis/masterchef.json new file mode 100644 index 0000000000..c9e8deb589 --- /dev/null +++ b/src/adaptors/nucleon/abis/masterchef.json @@ -0,0 +1,918 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_sushi", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startDistributingTimestamp", + "type": "uint256" + }, + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + }, + { + "internalType": "uint256", + "name": "_maxTransferrableTokens", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "LogInit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IRewarder", + "name": "rewarder", + "type": "address" + } + ], + "name": "LogPoolAddition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IRewarder", + "name": "rewarder", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "overwrite", + "type": "bool" + } + ], + "name": "LogSetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accSushiPerShare", + "type": "uint256" + } + ], + "name": "LogUpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PoolLPSum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUSHI", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "calls", + "type": "bytes[]" + }, + { + "internalType": "bool", + "name": "revertOnFail", + "type": "bool" + } + ], + "name": "batch", + "outputs": [ + { + "internalType": "bool[]", + "name": "successes", + "type": "bool[]" + }, + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "emissionSchedule", + "outputs": [ + { + "internalType": "uint128", + "name": "startTimeOffset", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardsPerSecond", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "pids", + "type": "uint256[]" + } + ], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxTransferrableTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "migrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "migrator", + "outputs": [ + { + "internalType": "contract IMigratorChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingSushi", + "outputs": [ + { + "internalType": "uint256", + "name": "pending", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "accSushiPerShare", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "allocPoint", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "pools", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewarder", + "outputs": [ + { + "internalType": "contract IRewarder", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IRewarder", + "name": "_rewarder", + "type": "address" + }, + { + "internalType": "bool", + "name": "overwrite", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMigratorChef", + "name": "_migrator", + "type": "address" + } + ], + "name": "setMigrator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startDistributingTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "direct", + "type": "bool" + }, + { + "internalType": "bool", + "name": "renounce", + "type": "bool" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferredTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "accSushiPerShare", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "allocPoint", + "type": "uint64" + } + ], + "internalType": "struct MasterChefV2.PoolInfo", + "name": "pool", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardDebt", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/nucleon/index.js b/src/adaptors/nucleon/index.js new file mode 100644 index 0000000000..13b9b13d50 --- /dev/null +++ b/src/adaptors/nucleon/index.js @@ -0,0 +1,438 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const NUT_TOKEN = '0xfe197e7968807b311d476915db585831b43a7e3b'; +const MASTERCHEF_ADDRESS = '0xeced26633b5c2d7124b5eae794c9c32a8b8e7df2'; +const CONFLUX_BLOCK_TIME = 1; +const BLOCKS_PER_YEAR = Math.floor((60 / CONFLUX_BLOCK_TIME) * 60 * 24 * 365); + +const getPairInfo = async (pair, tokenAddress) => { + const tokenDecimals0 = await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: tokenAddress[0], + chain: 'conflux', + requery: true, + }); + + const tokenDecimals1 = await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: tokenAddress[1], + chain: 'conflux', + requery: true, + }); + + const tokenDecimals = [tokenDecimals0.output, tokenDecimals1.output]; + + const tokenSymbol0 = await sdk.api.abi.call({ + abi: 'erc20:symbol', + target: tokenAddress[0], + chain: 'conflux', + requery: true, + }); + + const tokenSymbol1 = await sdk.api.abi.call({ + abi: 'erc20:symbol', + target: tokenAddress[1], + chain: 'conflux', + requery: true, + }); + + const tokenSymbol = [tokenSymbol0.output, tokenSymbol1.output]; + + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol[0], + decimals: tokenDecimals[0], + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol[1], + decimals: tokenDecimals[1], + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `conflux:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + NUTPerBlock, + NUTPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const NUTPerYear = BLOCKS_PER_YEAR * NUTPerBlock; + return ((poolWeight * NUTPerYear * NUTPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const NUTPerSecond = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'conflux', + abi: masterChefABI.find((e) => e.name === 'rewardsPerSecond'), + }); + const normalizedNUTPerBlock = + (NUTPerSecond.output / 1e18) * CONFLUX_BLOCK_TIME; + + const poolsRes0 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: 0, + chain: 'conflux', + requery: true, + }); + + const poolsRes1 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: 1, + chain: 'conflux', + requery: true, + }); + + const poolsRes2 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: 2, + chain: 'conflux', + requery: true, + }); + + const poolsRes3 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: 3, + chain: 'conflux', + requery: true, + }); + + const poolsRes4 = await sdk.api.abi.call({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + target: MASTERCHEF_ADDRESS, + params: 4, + chain: 'conflux', + requery: true, + }); + + const poolsRes = [poolsRes0.output, poolsRes1.output, poolsRes2.output, poolsRes3.output, poolsRes4.output]; + + const pools = poolsRes; + const lpTokens = [ + '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + ]; + + const masterChefBalancesRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + const masterChefBalancesRes1 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + const masterChefBalancesRes2 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + const masterChefBalancesRes3 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + const masterChefBalancesRes4 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'balanceOf')[0], + target: '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + chain: 'conflux', + params: MASTERCHEF_ADDRESS, + requery: true, + }); + + + const masterChefBalancesRes = [ + masterChefBalancesRes0.output, + masterChefBalancesRes1.output, + masterChefBalancesRes2.output, + masterChefBalancesRes3.output, + masterChefBalancesRes4.output, + ]; + + const supplyRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + chain: 'conflux', + requery: true, + }); + const supplyRes1 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + chain: 'conflux', + requery: true, + }); + const supplyRes2 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + chain: 'conflux', + requery: true, + }); + const supplyRes3 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + chain: 'conflux', + requery: true, + }); + const supplyRes4 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'totalSupply')[0], + target: '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + chain: 'conflux', + requery: true, + }); + + const supplyRes = [supplyRes0.output, supplyRes1.output, supplyRes2.output, supplyRes3.output, supplyRes4.output]; + + const reservesRes0 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + chain: 'conflux', + requery: true, + }); + const reservesRes1 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + chain: 'conflux', + requery: true, + }); + const reservesRes2 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + chain: 'conflux', + requery: true, + }); + const reservesRes3 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + chain: 'conflux', + requery: true, + }); + const reservesRes4 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + chain: 'conflux', + requery: true, + }); + const reservesRes = [ + reservesRes0.output, + reservesRes1.output, + reservesRes2.output, + reservesRes3.output, + reservesRes4.output, + ]; + + const underlyingToken00 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + chain: 'conflux', + requery: true, + }); + const underlyingToken01 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + chain: 'conflux', + requery: true, + }); + const underlyingToken02 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + chain: 'conflux', + requery: true, + }); + const underlyingToken03 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + chain: 'conflux', + requery: true, + }); + const underlyingToken04 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token0')[0], + target: '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + chain: 'conflux', + requery: true, + }); + + const underlyingToken0 = [ + underlyingToken00.output, + underlyingToken01.output, + underlyingToken02.output, + underlyingToken03.output, + underlyingToken04.output, + ]; + + const underlyingToken10 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0xd9d5748cb36a81fe58f91844f4a0412502fd3105', + chain: 'conflux', + requery: true, + }); + const underlyingToken11 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0x949b78ef2c8d6979098e195b08f27ff99cb20448', + chain: 'conflux', + requery: true, + }); + const underlyingToken12 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0x2899e1bec55e7dda574e80e8ef55f17b79df2f1d', + chain: 'conflux', + requery: true, + }); + const underlyingToken13 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0xbeebccc7420fff17d1108ec12bbce1adc15c6b6c', + chain: 'conflux', + requery: true, + }); + const underlyingToken14 = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'token1')[0], + target: '0x413039955c96b7fc4e4aa61786de577c3d5c126b', + chain: 'conflux', + requery: true, + }); + + const underlyingToken1 = [ + underlyingToken10.output, + underlyingToken11.output, + underlyingToken12.output, + underlyingToken13.output, + underlyingToken14.output, + ]; + + const reservesData = reservesRes; + const supplyData = supplyRes; + const masterChefBalData = masterChefBalancesRes; + const tokens0 = underlyingToken0; + const tokens1 = underlyingToken1; + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + const poolsApy = []; + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedNUTPerBlock, + tokensPrices[NUT_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + poolsApy.push({ + pool: lpTokens[i], + chain: utils.formatChain('conflux'), + project: 'nucleon', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward: apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [NUT_TOKEN], + }); + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.nucleon.space/', +}; diff --git a/src/adaptors/nucleus/index.js b/src/adaptors/nucleus/index.js new file mode 100644 index 0000000000..0829eacdd1 --- /dev/null +++ b/src/adaptors/nucleus/index.js @@ -0,0 +1,52 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const vaultData = async () => { + const vaults = await utils.getData( + 'https://backend.nucleusearn.io/v1/protocol/markets' + ); + const tokens = await utils.getData( + 'https://backend.nucleusearn.io/v1/protocol/tokens' + ); + + let pools = []; + await Promise.all( + Object.keys(vaults).map(async (vaultAddress) => { + try { + const vaultApyQuery = await utils.getData( + `https://backend.nucleusearn.io/v1/vaults/apy?token_address=${vaultAddress}&lookback_days=14` + ); + const vaultSymbol = await sdk.api2.erc20.symbol(vaultAddress); + + const ethereumApi = new sdk.ChainApi({ chain: 'ethereum' }); + const vaultBalances = await ethereumApi.sumTokens({ + owner: vaultAddress, + tokens: tokens, + }); + const usdBalance = await ethereumApi.getUSDValue(); + console.log('Vault TVL: ', usdBalance); + + console.log('Vault Symbol: ', vaultSymbol); + const pool = { + pool: `${vaultAddress}-ethereum`, + chain: 'Ethereum', + project: 'nucleus', + symbol: vaultSymbol.output, + tvlUsd: usdBalance, + apy: vaultApyQuery.apy, // 14 days apy + }; + pools.push(pool); + } catch (error) { + console.error(`Error processing vault: ${vaultAddress}`, error); + } + }) + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: vaultData, + url: 'https://app.nucleusearn.io/dashboard', +}; diff --git a/src/adaptors/nudes/index.js b/src/adaptors/nudes/index.js new file mode 100644 index 0000000000..9487139ff8 --- /dev/null +++ b/src/adaptors/nudes/index.js @@ -0,0 +1,15 @@ +const utils = require('../utils'); + +const poolsFunction = async () => { + const poolsData = await utils.getData( + 'https://api-v2-de1.nudes.army/project-info/defillama-yields' + ); + + return poolsData.pools +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://nudes.army/single-stake' +}; \ No newline at end of file diff --git a/src/adaptors/nuls-pocm/index.js b/src/adaptors/nuls-pocm/index.js new file mode 100644 index 0000000000..606ea12e62 --- /dev/null +++ b/src/adaptors/nuls-pocm/index.js @@ -0,0 +1,29 @@ +const axios = require('axios'); +const { BigNumber } = require("bignumber.js"); +const baseURL = "https://pocm.nuls.io/api/pocm"; + +const main = async () => { + let pools = (await axios.get(baseURL + '/pools')).data.data; + const priceKey = 'enuls:0x0000000000000000000000000000000000000000'; + const nulsPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + pools = pools.map((p) => { + const deposit = new BigNumber(p.totalDeposit).shiftedBy(-8); + return { + pool: p.id + '-' + p.contractAddress, + chain: 'Nuls', + project: 'nuls-pocm', + symbol: p.name, + tvlUsd: Number(deposit.multipliedBy(nulsPrice).toFixed(6)), + apyBase: Number(p.apr) + }; + }); + return pools; +}; + +module.exports = { + apy: main, + url: 'https://pocm.nuls.io/pocm/Projects/ProjectsList', +}; diff --git a/src/adaptors/nx-finance/index.js b/src/adaptors/nx-finance/index.js new file mode 100644 index 0000000000..cc609ffcab --- /dev/null +++ b/src/adaptors/nx-finance/index.js @@ -0,0 +1,34 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getApy = async () => { + const reserveApys = []; + const reserves = (await axios.get(`https://nxfinance.io/linux/api/data/pool-info`)).data.data; + + reserveApys.push( + ...reserves.map((r) => { + + const totalSupplyUsd = Number(r.lendingPoolInfo[0].totalSupplyUsd) + const totalBorrowUsd = Number(r.lendingPoolInfo[0].totalBorrowUsd) + return { + pool: r.poolAddress, + chain: 'Solana', + project: 'nx-finance', + symbol: utils.formatSymbol(r.symbol), + tvlUsd: totalSupplyUsd - totalBorrowUsd, + url: `https://nxfinance.io/lend/`, + apyBase: Number(r.lendingPoolInfo[0].APR) * 100, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + apyBaseBorrow: Number(r.lendingPoolInfo[0].borrowAPR) * 100, + }; + }) + ); + + return reserveApys; +}; + +module.exports = { + apy: getApy, + url: 'https://nxfinance.io/', +}; diff --git a/src/adaptors/o3-swap/abis/multiShareStaking.json b/src/adaptors/o3-swap/abis/multiShareStaking.json new file mode 100644 index 0000000000..7f96dedecc --- /dev/null +++ b/src/adaptors/o3-swap/abis/multiShareStaking.json @@ -0,0 +1,500 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_o3Token", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_shareTokens", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "_startStakingBlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startClaimBlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_endProfitBlockTimestamp", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "sig", + "type": "bytes4" + }, + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "LOG_CALL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "profit", + "type": "uint256[]" + } + ], + "name": "LOG_CLAIM_PROFITS", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakeAmount", + "type": "uint256" + } + ], + "name": "LOG_STAKE", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "LOG_UNSTAKE", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "O3Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "StakingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "endProfitBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "shareTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startClaimBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startStakingBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getShareTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "getTotalProfit", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "getStakingAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSharePerSecondArray", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "setStakingToke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sharePerSecond", + "type": "uint256" + } + ], + "name": "setSharePerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "indexes", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "sharePerSecondArray", + "type": "uint256[]" + } + ], + "name": "setSharePerSecondBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startClaimBlockTimestamp", + "type": "uint256" + } + ], + "name": "setStartClaimBlockTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseUnstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseUnstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseClaimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseClaimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "rescue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/o3-swap/abis/pool.json b/src/adaptors/o3-swap/abis/pool.json new file mode 100644 index 0000000000..5518c300b5 --- /dev/null +++ b/src/adaptors/o3-swap/abis/pool.json @@ -0,0 +1,889 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "_coins", + "type": "address[]" + }, + { + "internalType": "uint8[]", + "name": "decimals", + "type": "uint8[]" + }, + { + "internalType": "string", + "name": "lpTokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "lpTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_swapFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_adminFee", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "fees", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "invariant", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "AddLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newAdminFee", + "type": "uint256" + } + ], + "name": "NewAdminFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSwapFee", + "type": "uint256" + } + ], + "name": "NewSwapFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "initialTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "futureTime", + "type": "uint256" + } + ], + "name": "RampA", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "RemoveLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "fees", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "invariant", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "RemoveLiquidityImbalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boughtId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensBought", + "type": "uint256" + } + ], + "name": "RemoveLiquidityOne", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "currentA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "StopRampA", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensSold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensBought", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "soldId", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "boughtId", + "type": "uint128" + } + ], + "name": "TokenSwap", + "type": "event" + }, + { + "inputs": [], + "name": "A_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_A", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ADMIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adminFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "coins", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "futureA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "futureATime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialATime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract LPToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "swapFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTokenIndex", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVirtualPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "tokenIndex", + "type": "uint8" + } + ], + "name": "calculateWithdrawOneToken", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tokenIndexFrom", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "tokenIndexTo", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "dx", + "type": "uint256" + } + ], + "name": "calculateSwap", + "outputs": [ + { + "internalType": "uint256", + "name": "dy", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "calculateRemoveLiquidity", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bool", + "name": "deposit", + "type": "bool" + } + ], + "name": "calculateTokenAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getAdminBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tokenIndexFrom", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "tokenIndexTo", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "dx", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minDy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minToMint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "minAmounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "tokenIndex", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityOneToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "maxBurnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityImbalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newSwapFee", + "type": "uint256" + } + ], + "name": "applySwapFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newAdminFee", + "type": "uint256" + } + ], + "name": "applyAdminFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "withdrawAdminFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_futureA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_futureTime", + "type": "uint256" + } + ], + "name": "rampA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stopRampA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/o3-swap/abis/staking.json b/src/adaptors/o3-swap/abis/staking.json new file mode 100644 index 0000000000..f5dafcb4d2 --- /dev/null +++ b/src/adaptors/o3-swap/abis/staking.json @@ -0,0 +1,465 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_o3Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startStakingBlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startUnstakeBlockTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startClaimBlockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "sig", + "type": "bytes4" + }, + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "LOG_CALL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "profit", + "type": "uint256" + } + ], + "name": "LOG_CLAIM_PROFIT", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakeAmount", + "type": "uint256" + } + ], + "name": "LOG_STAKE", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "LOG_UNSTAKE", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "O3Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "ONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "StakingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startClaimBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "startStakingBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "startUnstakeBlockTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "getTotalProfit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [ + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "getStakingAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [], + "name": "getSharePerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "constant": true + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "setStakingToke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "sharePerSecond", + "type": "uint256" + } + ], + "name": "setSharePerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startUnstakeBlockTimestamp", + "type": "uint256" + } + ], + "name": "setStartUnstakeBlockTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startClaimBlockTimestamp", + "type": "uint256" + } + ], + "name": "setStartClaimBlockTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseUnstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseUnstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseClaimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseClaimProfit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "collect", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/o3-swap/chains.js b/src/adaptors/o3-swap/chains.js new file mode 100644 index 0000000000..9d9290a660 --- /dev/null +++ b/src/adaptors/o3-swap/chains.js @@ -0,0 +1,71 @@ +const CHAINS = { + Ethereum: 'Ethereum', + BNBChain: 'Binance', + Polygon: 'Polygon', + Arbitrum: 'Arbitrum', + Gnosis: 'xDai', + Fantom: 'Fantom', + Avalanche: 'Avalanche', + Optimism: 'Optimism', + Cube: 'Cube', + Metis: 'Metis', + Celo: 'Celo', + KCC: 'Kucoin', + Astar: 'Astar', +}; + +const CHAIN_ENUM = { + [CHAINS.Ethereum]: 1, + [CHAINS.BNBChain]: 56, + [CHAINS.Polygon]: 137, + [CHAINS.Arbitrum]: 42161, + [CHAINS.Gnosis]: 100, + [CHAINS.Avalanche]: 43114, + [CHAINS.Optimism]: 10, + [CHAINS.Fantom]: 250, + [CHAINS.Cube]: 1818, + [CHAINS.Metis]: 1088, + [CHAINS.Celo]: 42220, + [CHAINS.KCC]: 321, + [CHAINS.Astar]: 592, +}; + +const RATES_CHAIN = { + [CHAINS.Ethereum]: 'eth', + [CHAINS.BNBChain]: 'bnbchain', + [CHAINS.Polygon]: 'polygon', + [CHAINS.Arbitrum]: 'arbitrum', + [CHAINS.Gnosis]: 'gnosis', + [CHAINS.Avalanche]: 'avalanche', + [CHAINS.Optimism]: 'optimism', + [CHAINS.Fantom]: 'fantom', + [CHAINS.Cube]: 'cube', + [CHAINS.Metis]: 'metis', + [CHAINS.Celo]: 'celo', + [CHAINS.KCC]: 'kcc', + [CHAINS.Astar]: 'astar', +}; + +const CHAIN_RPC_HOST = { + [CHAINS.Ethereum]: + 'https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161', + [CHAINS.BNBChain]: 'https://bsc-dataseed1.ninicoin.io', + [CHAINS.Polygon]: 'https://polygon-rpc.com', + [CHAINS.Arbitrum]: 'https://arb1.arbitrum.io/rpc', + [CHAINS.Gnosis]: 'https://rpc.gnosischain.com', + [CHAINS.Avalanche]: 'https://api.avax.network/ext/bc/C/rpc', + [CHAINS.Optimism]: 'https://1rpc.io/op', + [CHAINS.Fantom]: 'https://rpc.ftm.tools', + [CHAINS.Cube]: 'https://http-mainnet.cube.network', + [CHAINS.Metis]: 'https://andromeda.metis.io', + [CHAINS.Celo]: 'https://forno.celo.org', + [CHAINS.KCC]: 'https://rpc-mainnet.kcc.network', + [CHAINS.Astar]: 'https://rpc.astar.network:8545', +}; + +module.exports = { + CHAINS, + CHAIN_ENUM, + RATES_CHAIN, + CHAIN_RPC_HOST, +}; diff --git a/src/adaptors/o3-swap/index.js b/src/adaptors/o3-swap/index.js new file mode 100644 index 0000000000..535f8c943c --- /dev/null +++ b/src/adaptors/o3-swap/index.js @@ -0,0 +1,304 @@ +const { Web3 } = require('web3'); +const axios = require('axios'); +const poolAbi = require('./abis/pool.json'); +const stakingAbi = require('./abis/staking.json'); +const multiShareStakingAbi = require('./abis/multiShareStaking.json'); +const BigNumber = require('bignumber.js'); +const { CHAINS, CHAIN_ENUM, CHAIN_RPC_HOST, RATES_CHAIN } = require('./chains'); +const { o3SwapPools } = require('./pools'); + +const web3 = new Web3(); + +function getAssetRate() { + return new Promise((resolve) => { + axios.get('https://hub-v2.o3.network/v2/crypto/rates').then((res) => { + resolve(res.data.data); + }); + }); +} + +function getPoolBalancData(address, tokenIndex, chain) { + if (address === '') { + return null; + } + const poolContract = new web3.eth.Contract(poolAbi); + const data = poolContract.methods.balances(tokenIndex).encodeABI(); + return { + jsonrpc: '2.0', + id: CHAIN_ENUM[chain], + method: 'eth_call', + params: [ + { + to: address, + data, + }, + 'latest', + ], + }; +} +function getPoolBalance() { + const poolBalance = {}; + return new Promise((resolve) => { + const CHAIN_LIST = Object.values(CHAINS); + CHAIN_LIST.forEach((chain) => { + const postDatas = []; + const pools = o3SwapPools.filter((item) => item.chain === chain); + for (const poolItem of pools) { + const poolAddress = poolItem.pool.split('-')[0]; + const data1 = getPoolBalancData(poolAddress, 0, chain); + const data2 = getPoolBalancData(poolAddress, 1, chain); + postDatas.push(data1); + postDatas.push(data2); + } + if (postDatas.length <= 0) { + poolBalance[chain] = {}; + if (Object.keys(poolBalance).length === CHAIN_LIST.length) { + resolve(poolBalance); + } + return; + } + axios + .post(CHAIN_RPC_HOST[chain], postDatas) + .then((response) => { + const res = response.data; + poolBalance[chain] = {}; + if (!res.length) { + if (Object.keys(poolBalance).length === CHAIN_LIST.length) { + resolve(poolBalance); + } + } + res.forEach((resItem, _index) => { + const balance = resItem.result; + const index = parseInt((_index / 2).toString()); + const poolSymbol = pools[index].symbol; + const tokenDecimals = pools[index].tokenDecimals[_index % 2]; + if ( + balance && + !new BigNumber(balance).isNaN() && + new BigNumber(balance).comparedTo(0) >= 0 + ) { + const tempBalance = new BigNumber( + poolBalance[chain][poolSymbol] + ).isNaN() + ? '0' + : poolBalance[chain][poolSymbol]; + poolBalance[chain][poolSymbol] = new BigNumber(balance) + .shiftedBy(-tokenDecimals) + .plus(new BigNumber(tempBalance)) + .toFixed(); + } + }); + if (Object.keys(poolBalance).length === CHAIN_LIST.length) { + resolve(poolBalance); + } + }) + .catch((_) => { + poolBalance[chain] = {}; + if (Object.keys(poolBalance).length === CHAIN_LIST.length) { + resolve(poolBalance); + } + }); + }); + }); +} + +function getO3StakingSharePerSecondData(pool) { + const contractHash = pool.stakingContract; + let contract; + let data; + if (pool.rewardTokens.length && pool.rewardTokens.length > 1) { + contract = new web3.eth.Contract(multiShareStakingAbi); + data = contract.methods.getSharePerSecondArray().encodeABI(); + } else { + contract = new web3.eth.Contract(stakingAbi); + data = contract.methods.getSharePerSecond().encodeABI(); + } + return { + jsonrpc: '2.0', + id: CHAIN_ENUM[pool.chain], + method: 'eth_call', + params: [ + { + to: contractHash, + data, + }, + 'latest', + ], + }; +} +function getO3StakingTotalStaked(pool) { + const contractHash = pool.stakingContract; + let contract; + let data; + if (pool.rewardTokens.length && pool.rewardTokens.length > 1) { + contract = new web3.eth.Contract(multiShareStakingAbi); + data = contract.methods.totalStaked().encodeABI(); + } else { + contract = new web3.eth.Contract(stakingAbi); + data = contract.methods.totalStaked().encodeABI(); + } + return { + jsonrpc: '2.0', + id: CHAIN_ENUM[pool.chain], + method: 'eth_call', + params: [ + { + to: contractHash, + data, + }, + 'latest', + ], + }; +} +function getProfitTokensData(rewardTokenDecimals, hexString) { + const decodeTypes = + rewardTokenDecimals.length === 1 + ? ['uint256'] + : new Array(rewardTokenDecimals.length + 2).fill('uint256'); + if (hexString) { + return Object.values(web3.eth.abi.decodeParameters(decodeTypes, hexString)) + .filter((item) => typeof item === 'string') + .slice(rewardTokenDecimals.length === 1 ? 0 : 2) + .map((resultNumber, index) => { + return resultNumber + ? new BigNumber(resultNumber) + .shiftedBy(-rewardTokenDecimals[index]) + .toFixed() + : '--'; + }); + } + return new Array(rewardTokenDecimals.length); +} +function getO3StakingInfo() { + const result = {}; + return new Promise((resolve) => { + const CHAIN_LIST = Object.values(CHAINS); + CHAIN_LIST.forEach((chain) => { + const postDatas = []; + const pools = o3SwapPools.filter((item) => item.chain === chain); + for (const poolItem of pools) { + const data = getO3StakingSharePerSecondData(poolItem); + const totalStakedData = getO3StakingTotalStaked(poolItem); + postDatas.push(data); + postDatas.push(totalStakedData); + } + axios + .post(CHAIN_RPC_HOST[chain], postDatas) + .then((response) => { + const res = response.data; + result[chain] = {}; + if (!res.length) { + if (Object.keys(result).length === CHAIN_LIST.length) { + resolve(result); + } + } + for (let i = 0; i < parseInt((res.length / 2).toString()); i++) { + const strartIndex = i * 2; + const pool = pools[i]; + const poolSymbol = pools[i].symbol; + result[chain][poolSymbol] = { + sharePerSecond: getProfitTokensData( + pool.rewardTokenDecimals, + res[strartIndex]?.result + ), + totalStaked: res[strartIndex + 1].result + ? new BigNumber(res[strartIndex + 1].result) + .shiftedBy(-18) + .toFixed() + : '0', + }; + } + if (Object.keys(result).length === CHAIN_LIST.length) { + resolve(result); + } + }) + .catch((_) => { + result[chain] = {}; + if (Object.keys(result).length === CHAIN_LIST.length) { + resolve(result); + } + }); + }); + }); +} + +function getTvlUsd(pool, balance, rates) { + const price = + rates[RATES_CHAIN[pool.chain]][pool.underlyingTokens[0].toLowerCase()] + ?.price; + return new BigNumber(price).times(balance).dp(2).toNumber(); +} +function getStakingAPR(pool, stakingInfo, rates) { + const yearSecond = new BigNumber('31536000'); + if (stakingInfo?.totalStaked === undefined) return 0; + const totalStaked = stakingInfo.totalStaked; + const sharePerSecond = stakingInfo.sharePerSecond; + const tokenPrice = + rates[RATES_CHAIN[pool.chain]][pool.underlyingTokens[0].toLowerCase()] + ?.price; + let yearProfits = new BigNumber(0); + pool.rewardTokens.forEach((hash, index) => { + const rewardTokenPrice = + rates[RATES_CHAIN[pool.chain]][hash.toLowerCase()]?.price; + yearProfits = yearProfits.plus( + yearSecond + .times(new BigNumber(sharePerSecond[index])) + .times(new BigNumber(rewardTokenPrice)) + ); + }); + + const result = yearProfits + .div(totalStaked) + .div(new BigNumber(tokenPrice || '1')) + .times(100) + .dp(2); + if (result.isNaN()) { + return 0; + } + return result.toNumber(); +} + +async function main() { + return new Promise((resolve) => { + try { + Promise.all([getAssetRate(), getPoolBalance(), getO3StakingInfo()]).then( + (result) => { + const rates = result[0] || {}; + const poolBalances = result[1]; + const stakingInfo = result[2]; + resolve( + o3SwapPools.map((poolItem) => { + const tvlUsd = getTvlUsd( + poolItem, + poolBalances[poolItem.chain][poolItem.symbol], + rates + ); + return { + pool: poolItem.pool, + symbol: poolItem.symbol, + chain: poolItem.chain, + project: poolItem.project, + rewardTokens: poolItem.rewardTokens, + underlyingTokens: poolItem.underlyingTokens, + tvlUsd: Number.isFinite(tvlUsd) ? tvlUsd : 0, + apyReward: getStakingAPR( + poolItem, + stakingInfo[poolItem.chain][poolItem.symbol], + rates + ), + }; + }) + ); + } + ); + } catch (error) { + console.log('error'); + } + }); +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://o3swap.com', +}; diff --git a/src/adaptors/o3-swap/pools.js b/src/adaptors/o3-swap/pools.js new file mode 100644 index 0000000000..95e7c6abca --- /dev/null +++ b/src/adaptors/o3-swap/pools.js @@ -0,0 +1,1232 @@ +const o3SwapPools = [ + { + pool: '0x6b00d7877a5ffee3f986205fe6201c3541af9aa8-ethereum', + symbol: 'USDT', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xdac17f958d2ee523a2206206994597c13d831ec7', + '0xbf19e64269ac14dc8786c33d1c9ace7dfd7fe9fa', + ], + stakingContract: '0x3B6ae6c6e549758aeD035937B30a9f0ec5A2E72e', + rewardTokenDecimals: [18], + }, + { + pool: '0x7a25f1231cf2f617458828b4392c7303edceb29c-ethereum', + symbol: 'USDC', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + '0xd60929c3a153ddfee363c957490a305b1122e0d9', + ], + stakingContract: '0x4b73b31D2Eb9b91A950394e709C7dBE569cd8bB0', + rewardTokenDecimals: [18], + }, + { + pool: '0x36349a67473870eef6df5f4600bc995fb39c668f-ethereum', + symbol: 'BTC', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + '0x188a5bac8f60b5099fae332de383b48507d0df8f', + ], + stakingContract: '0x30103114DB17ce02f27E003d9099b714b5bCe560', + rewardTokenDecimals: [18], + }, + { + pool: '0xf65c984f166553942c66bcc1fe74cfd3f26523e6-ethereum', + symbol: 'ETH', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0x64109A5eaD8c48B77176CC78a477Ec60fcdC0CbE', + rewardTokenDecimals: [18], + }, + { + pool: '0xb07ba87f2c52af9e2a0f21c341886ea534713e3a-ethereum', + symbol: 'O3', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0xfdb40b73010e4476d18d2528dc94459584a44e56', + ], + stakingContract: '0x100091Df5d4CD3F674e55a5452Ed3C1B06d96db7', + rewardTokenDecimals: [18], + }, + { + pool: '0xa9cf9a24877283ed2251ffe254e058f28eeeeebf-ethereum', + symbol: 'MATIC', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0', + '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c', + ], + stakingContract: '0x76A8B3D0F321aD1202C0a489B8bd314977d38fFe', + rewardTokenDecimals: [18], + }, + { + pool: '0x6209d43b4555e17fdd2167c89aae559a3b1ffd89-ethereum', + symbol: 'FTM', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x4e15361fd6b4bb609fa63c81a2be19d873717870', + '0x59414459c6c9883480983ef9888334d9376431f3', + ], + stakingContract: '0xd2aF680c375892488b721D3981d460b7986f100d', + rewardTokenDecimals: [18], + }, + { + pool: '0x5dbdd037e6f10fef42cac6d9129588fd49e2c0d9-ethereum', + symbol: 'DAI', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x6b175474e89094c44da98b954eedeac495271d0f', + '0xe77ca468659c92f6deb63dd46720a30ea48ebcea', + ], + stakingContract: '0xF54360fbC0De71BC6269755C3c8cB8F838700624', + rewardTokenDecimals: [18], + }, + { + pool: '0x2397c5abe26aa48e1a8a645e46b508b26bd498c0-ethereum', + symbol: 'Cube', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x6df241103f89983b1fb86244c8601e44ea55368c', + '0x1f5b49fbd97db95d9e296c06d992753c162cbce3', + ], + stakingContract: '0xeAce0bd866b819693F9c56424EFC55920375c8B6', + rewardTokenDecimals: [18], + }, + { + pool: '0x1fe970be3e34ba07e29575b0dd61edb537ff849a-ethereum', + symbol: 'ATA', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xa2120b9e674d3fc3875f415a7df52e382f141225', + '0xcdfec50de0427c18547890911068740b15c67969', + ], + stakingContract: '0x2Ed2332F5B3084B5a0986E2D8ed54A2850B544c8', + rewardTokenDecimals: [18], + }, + { + pool: '0xefe947d0a4d4b4a0d03af5d013e6146de42dea53-ethereum', + symbol: 'RACA', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x12bb890508c125661e03b09ec06e404bc9289040', + '0x1ccb779bdd1c0bd92cf60d21dcb0926bc1776e3b', + ], + stakingContract: '0x20c698B6ec20873f2ECC2B558046d6952Cd69a1F', + rewardTokenDecimals: [18], + }, + { + pool: '0x5180272e315286a96a41a047c54d0b70626fb730-ethereum', + symbol: 'ROOBEE', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xa31b1767e09f842ecfd4bc471fe44f830e3891aa', + '0x489f4d95aa0819b84040473ab6c676ed6583ecea', + ], + stakingContract: '0xa9619cCaC572541A007aA1d486daA4eD8a044c79', + rewardTokenDecimals: [18], + }, + { + pool: '0xc500172e0fe1d60437badcc5ceba912ac81d6e4b-ethereum', + symbol: 'WING', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [9, 18], + underlyingTokens: [ + '0xdb0f18081b505a7de20b18ac41856bcb4ba86a1a', + '0xfb631ec582d087e079d5d9d9c4eb92215a29adbb', + ], + stakingContract: '0x6fE2FccAcac242F0B1EEA18016a1D14CF3124fd6', + rewardTokenDecimals: [18], + }, + { + pool: '0x14f774ae8aca292f81ded5f932e56f79ab201f86-ethereum', + symbol: 'Metis', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x9e32b13ce7f2e80a01932b42553652e053d6ed8e', + '0xacfe701efdddaa9a8aae6cf4ac301381b841acb2', + ], + stakingContract: '0x35d9446007041F7141FC6fEe355063E11122EfAF', + rewardTokenDecimals: [18], + }, + { + pool: '0x663d7af498eccb0dee04e72f1203eb6878b0a9c0-ethereum', + symbol: 'CELL', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x26c8afbbfe1ebaca03c2bb082e69d0476bffe099', + '0xa1e720f0293a3464a98202487d92fdc8085213fa', + ], + stakingContract: '0xd7209c97F9f3BBf6790BDd9D01CF8277Bf63b43D', + rewardTokenDecimals: [18], + }, + { + pool: '0xab3841a70b00eb5ad1cec4c1022ff5fa90ec1719-ethereum', + symbol: 'GM', + chain: 'Ethereum', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x35609dc59e15d03c5c865507e1348fa5abb319a8', + ], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x35609dc59e15d03c5c865507e1348fa5abb319a8', + '0x8fb05429b692e549f369919168fe956c25b82a51', + ], + stakingContract: '0xd394acEfF6790b2321c597B358902e0b41235a31', + rewardTokenDecimals: [18, 8], + }, + { + pool: '0x84baa3a0247380f27edbb93ec5d89e516bb31729-optimism', + symbol: 'USDC', + chain: 'Optimism', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0xb3b0A476CcCaa41aA499a08B48C14eE668E8588A', + rewardTokenDecimals: [18], + }, + { + pool: '0xd9fb513766e60a569697d1f17ae466b0cb887454-optimism', + symbol: 'ETH', + chain: 'Optimism', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x4200000000000000000000000000000000000006', + '0xa05b26ebbee2a2ccb7c30be499d26a3686e9f03c', + ], + stakingContract: '0xe77Ca468659C92f6dEB63DD46720a30EA48ebCEA', + rewardTokenDecimals: [18], + }, + { + pool: '0x88f8c6d4d94daa32795a7d18002db73a7ed0b72d-optimism', + symbol: 'O3', + chain: 'Optimism', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x3a5292101a26c1dc75f97965b9091d4761a5d1e3', + ], + stakingContract: '0x12682669700109AE1F3B326D74f2A5bDB63549E3', + rewardTokenDecimals: [18], + }, + { + pool: '0x27ab099efb251d5e9377b747c01140045c8f8fcf-optimism', + symbol: 'DAI', + chain: 'Optimism', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + '0x8a2ae0cf4674e8f83a1d823f57dc5735c5677c21', + ], + stakingContract: '0xBf19e64269Ac14DC8786c33D1C9ace7dFD7FE9fA', + rewardTokenDecimals: [18], + }, + { + pool: '0xd92370ec2256457935fd580c900bf25c5e7139bf-optimism', + symbol: 'ROOBEE', + chain: 'Optimism', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xb12c13e66ade1f72f71834f2fc5082db8c091358', + '0xc39b6d561cb3c3e6b9e95a7b455073da2a9ff122', + ], + stakingContract: '0x6209D43b4555E17FdD2167c89AaE559a3b1fFD89', + rewardTokenDecimals: [18], + }, + { + pool: '0x5f5737403c8b30288299e51d94d007a826f9d593-binance', + symbol: 'USDT', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x55d398326f99059ff775485246999027b3197955', + '0xd9fb513766e60a569697d1f17ae466b0cb887454', + ], + stakingContract: '0x58Ce907edF4D8418e27Aaa7d0674D0C7995FD69f', + rewardTokenDecimals: [18], + }, + { + pool: '0x426223eef2e4f577767533aa1854e8b980b1df5f-binance', + symbol: 'USDC', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', + '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c', + ], + stakingContract: '0x2471d31B744279eA7e9756ed5f1a8c9dE4420D6D', + rewardTokenDecimals: [18], + }, + { + pool: '0xc0b69439815f2473f543a71f68a8aebd08982d7d-binance', + symbol: 'BTC', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c', + '0xa039b0529560fa8030df0fc9fc44e2a6d9aedec9', + ], + stakingContract: '0xca7E3d6E6B997b083fcF24435e527792FB74E55A', + rewardTokenDecimals: [18], + }, + { + pool: '0x5e5922c5a2e1c137d1d4cc3bf9374021a1002db2-binance', + symbol: 'ETH', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x2170ed0880ac9a755fd29b2688956bd959f933f8', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0xeCF2B548e5c21028B0b60363207700fA421B6EcB', + rewardTokenDecimals: [18], + }, + { + pool: '0xa63705460d4d907d6233684c5ce7ceb586b0f284-binance', + symbol: 'O3', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0xd5ca47bf3e075b5446401a56d04492425e798e82', + ], + stakingContract: '0xdfE162A73e340Ca577fdc1a919EBcE6BEd7f4F40', + rewardTokenDecimals: [18], + }, + { + pool: '0x4b73b31d2eb9b91a950394e709c7dbe569cd8bb0-binance', + symbol: 'AVAX', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x1ce0c2827e2ef14d5c4f29a091d735a204794041', + '0xe0e10ef7971d78f8ce1c6b16dbc1b8d64add3672', + ], + stakingContract: '0x3027f36903F225A94b07922aF66C6ff237E9235C', + rewardTokenDecimals: [18], + }, + { + pool: '0xddaeb30f3da1612900e1e26386a009f4576a175c-binance', + symbol: 'ATA', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xa2120b9e674d3fc3875f415a7df52e382f141225', + '0xca2462c4203259e0ae1c21c0849e3fed71be6cc6', + ], + stakingContract: '0x3204c9Da277ED387b542309A2677820c58C54667', + rewardTokenDecimals: [18], + }, + { + pool: '0xf54360fbc0de71bc6269755c3c8cb8f838700624-binance', + symbol: 'RACA', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x12bb890508c125661e03b09ec06e404bc9289040', + '0x678c51edffff68d183e95185d972708cf6afe7d8', + ], + stakingContract: '0x90bD07EA90Ed2008c6f7d61D4FBf1e4c70241aEA', + rewardTokenDecimals: [18], + }, + { + pool: '0xc9483ea9f0abdacc7d313a0148767dc8d259a621-binance', + symbol: 'ROOBEE', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0xf77351d8f4ee853135961a936bb8d2e4ffa75f9d', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xf77351d8f4ee853135961a936bb8d2e4ffa75f9d', + '0xa28958ec4219e5fb33e57eeeb2ca5ee4fb4cc31d', + ], + stakingContract: '0xA683E5644C680f062B59f8EcF9025e0e29822B60', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0x76a8b3d0f321ad1202c0a489b8bd314977d38ffe-binance', + symbol: 'WING', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [9, 18], + underlyingTokens: [ + '0x3cb7378565718c64ab86970802140cc48ef1f969', + '0x64109a5ead8c48b77176cc78a477ec60fcdc0cbe', + ], + stakingContract: '0xc841cc7AFDfba26f6eFaee3B11120f15130c5Ef9', + rewardTokenDecimals: [18], + }, + { + pool: '0x487487661d1ce8a626a0ba28b50819393043aadc-binance', + symbol: 'CELL', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xf3e1449ddb6b218da2c9463d4594ceccc8934346', + '0x76e0dc400280dc04d999d52887024a1f313f03f6', + ], + stakingContract: '0x489F4d95Aa0819b84040473ab6C676ed6583eCeA', + rewardTokenDecimals: [18], + }, + { + pool: '0xb5e311a5a43120fff4c38ccf88502e17dec6f2f0-binance', + symbol: 'STACK', + chain: 'Binance', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x6855f7bb6287f94ddcc8915e37e73a3c9fee5cf3', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x6855f7bb6287f94ddcc8915e37e73a3c9fee5cf3', + '0x3d56b181b321628309f207dda6f38f5f129dfd89', + ], + stakingContract: '0x0689be64c84299622b3744c32af5Bc9b3E45e2D5', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0xd60929c3a153ddfee363c957490a305b1122e0d9-xdai', + symbol: 'USDC', + chain: 'xDai', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xddafbb505ad214d7b80b1f830fccc89b60fb7a83', + '0xd9fb513766e60a569697d1f17ae466b0cb887454', + ], + stakingContract: '0x7850D9dF61564A41e0393B741FadDe99d61A068c', + rewardTokenDecimals: [18], + }, + { + pool: '0xd5ca558f1a444500ddd728475fc48db30e3768cb-xdai', + symbol: 'ETH', + chain: 'xDai', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x6a023ccd1ff6f2045c3309768ead9e68f978f6e1', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0xA01C3B0D7AE5423764e390275735FFc369f809e2', + rewardTokenDecimals: [18], + }, + { + pool: '0x3fb5672652c96c47d547fead6ce24ea8f4e7a222-xdai', + symbol: 'O3', + chain: 'xDai', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x0a8890939f6e9b3686b464a70056e15c7503b925', + ], + stakingContract: '0xb8A3A70c9DA2B34260DFa6e23a35eD05bC84627A', + rewardTokenDecimals: [18], + }, + { + pool: '0x19b15c74dc578b3dfdfe7e1dbe0a57d5198f7a78-xdai', + symbol: 'DAI', + chain: 'xDai', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', + '0x8a2ae0cf4674e8f83a1d823f57dc5735c5677c21', + ], + stakingContract: '0x0cB54506309dd9330545cB78cC3899262828D182', + rewardTokenDecimals: [18], + }, + { + pool: '0x12682669700109ae1f3b326d74f2a5bdb63549e3-polygon', + symbol: 'USDT', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', + '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c', + ], + stakingContract: '0xA0Bc160D3451b0E5C150eb8d231f484bd7972b6e', + rewardTokenDecimals: [18], + }, + { + pool: '0x446eb3ac5e6267931ed1198203b12cafcd2e6240-polygon', + symbol: 'USDC', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', + '0x86e28ce4a17b28dfb03830e6542c143d437c2456', + ], + stakingContract: '0x92cfa6DF293B66671c7c3D51e614fAE9F66e07B5', + rewardTokenDecimals: [18], + }, + { + pool: '0xccb7a45e36f22ede66b6222a0a55c547e6d516d7-polygon', + symbol: 'ETH', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0x78abC57267acD53C42B9780Fb6a7e8BaB2da99a1', + rewardTokenDecimals: [18], + }, + { + pool: '0x678c51edffff68d183e95185d972708cf6afe7d8-polygon', + symbol: 'O3', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x68f5e5357377d4de24ab721765c1e26e6be34fc3', + ], + stakingContract: '0x68E3286BC7C612F89B41d05147E6690B447aa2c4', + rewardTokenDecimals: [18], + }, + { + pool: '0x06d8b2a805cc6b3fce771783dabc56ffab557840-polygon', + symbol: 'MATIC', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270', + '0x8a2ae0cf4674e8f83a1d823f57dc5735c5677c21', + ], + stakingContract: '0xca7E3d6E6B997b083fcF24435e527792FB74E55A', + rewardTokenDecimals: [18], + }, + { + pool: '0x88f8c6d4d94daa32795a7d18002db73a7ed0b72d-polygon', + symbol: 'DAI', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063', + '0xd9fb513766e60a569697d1f17ae466b0cb887454', + ], + stakingContract: '0x8C140cB521F09af2Ef776D3191f350C661171958', + rewardTokenDecimals: [18], + }, + { + pool: '0xd2af680c375892488b721d3981d460b7986f100d-polygon', + symbol: 'ATA', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x0df0f72ee0e5c9b7ca761ecec42754992b2da5bf', + '0x4b73b31d2eb9b91a950394e709c7dbe569cd8bb0', + ], + stakingContract: '0x3204c9Da277ED387b542309A2677820c58C54667', + rewardTokenDecimals: [18], + }, + { + pool: '0x114d91614af98a98d466500e4558c47781851eff-polygon', + symbol: 'ROOBEE', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xfafa220145dfa5c3ec85b6fa8a75aee2451cde5e', + '0xc9483ea9f0abdacc7d313a0148767dc8d259a621', + ], + stakingContract: '0x90bD07EA90Ed2008c6f7d61D4FBf1e4c70241aEA', + rewardTokenDecimals: [18], + }, + { + pool: '0x2c71ce0dfa6ced779814a7b1d1e35b9cc690ea6f-polygon', + symbol: 'GM', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x6a335ac6a3cdf444967fe03e7b6b273c86043990', + ], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x6a335ac6a3cdf444967fe03e7b6b273c86043990', + '0xc59ac0f66fd97ddb29e2ec7e99edfb5bf661f348', + ], + stakingContract: '0x295b9E1581B410bd2C5dceC2086200E01C66D856', + rewardTokenDecimals: [18, 8], + }, + { + pool: '0x22a211f3caa396bc712bb0b44f4ba4b46272e471-polygon', + symbol: 'STACK', + chain: 'Polygon', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x980111ae1b84e50222c8843e3a7a038f36fecd2b', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x980111ae1b84e50222c8843e3a7a038f36fecd2b', + '0xb07ba87f2c52af9e2a0f21c341886ea534713e3a', + ], + stakingContract: '0xb91e4A4f33D176e2d8fcbE2a34d5948602633730', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0x322c4c02bab59f61389010feb9de6047e6b20f6d-fantom', + symbol: 'USDC', + chain: 'Fantom', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c', + ], + stakingContract: '0xC0B69439815f2473f543a71f68A8aebD08982D7D', + rewardTokenDecimals: [18], + }, + { + pool: '0xb5c37095e038728e9bc8732cc89fcdfdb3ed9513-fantom', + symbol: 'ETH', + chain: 'Fantom', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x74b23882a30290451a17c44f4f05243b6b58c76d', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0xA0Bc160D3451b0E5C150eb8d231f484bd7972b6e', + rewardTokenDecimals: [18], + }, + { + pool: '0x985f9ef7dc52f16a4b51abea986f855dc2a4f079-fantom', + symbol: 'O3', + chain: 'Fantom', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x498ec5659bb72acb8c90a9eced7de243c03f6113', + ], + stakingContract: '0xE0e10EF7971d78F8Ce1C6b16DbC1b8D64ADd3672', + rewardTokenDecimals: [18], + }, + { + pool: '0x5f5737403c8b30288299e51d94d007a826f9d593-fantom', + symbol: 'FTM', + chain: 'Fantom', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + '0x8a2ae0cf4674e8f83a1d823f57dc5735c5677c21', + ], + stakingContract: '0x43212c4594a3b26185326F78b0970cf4685eF647', + rewardTokenDecimals: [18], + }, + { + pool: '0x426223eef2e4f577767533aa1854e8b980b1df5f-fantom', + symbol: 'DAI', + chain: 'Fantom', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + '0xd9fb513766e60a569697d1f17ae466b0cb887454', + ], + stakingContract: '0xca7E3d6E6B997b083fcF24435e527792FB74E55A', + rewardTokenDecimals: [18], + }, + { + pool: '0x27ab099efb251d5e9377b747c01140045c8f8fcf-kucoin', + symbol: 'USDC', + chain: 'Kucoin', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x980a5afef3d17ad98635f6c5aebcbaeded3c3430', + '0x01fc120633213c7826704dee7137d919d7250805', + ], + stakingContract: '0xe77Ca468659C92f6dEB63DD46720a30EA48ebCEA', + rewardTokenDecimals: [18], + }, + { + pool: '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c-kucoin', + symbol: 'O3', + chain: 'Kucoin', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0xa7ba356f3976d0ff7da9b4cb4979073949fd8588', + ], + stakingContract: '0x697ff44992788bbEF0219864F51A9b535bFA9Ccd', + rewardTokenDecimals: [18], + }, + { + pool: '0x69f078f27c7f8bfbac7000aa700701064797a48c-astar', + symbol: 'USDC', + chain: 'Astar', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0x6a2d262d56735dba19dd70682b39f6be9a931d98', + '0xa05b26ebbee2a2ccb7c30be499d26a3686e9f03c', + ], + stakingContract: '0x84BAA3a0247380f27EDBb93eC5D89E516BB31729', + rewardTokenDecimals: [18], + }, + { + pool: '0xa7ba356f3976d0ff7da9b4cb4979073949fd8588-astar', + symbol: 'O3', + chain: 'Astar', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0x27Ab099EfB251D5E9377B747c01140045C8F8fcf', + rewardTokenDecimals: [18], + }, + { + pool: '0x5db3b24f10366ce9031029c70759362a2f2b5e7b-metis', + symbol: 'USDT', + chain: 'Metis', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xbb06dca3ae6887fabf931640f67cab3e3a16f4dc', + '0x70d2c8c01e535d90243abf181dd059baac9d0a6a', + ], + stakingContract: '0x7BB9709Ec786Ea549eE67AE02E8B0c75DDE77f48', + rewardTokenDecimals: [18], + }, + { + pool: '0xb3b0a476cccaa41aa499a08b48c14ee668e8588a-metis', + symbol: 'USDC', + chain: 'Metis', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xea32a96608495e54156ae48931a7c20f0dcc1a21', + '0x27ab099efb251d5e9377b747c01140045c8f8fcf', + ], + stakingContract: '0x446eb3aC5e6267931eD1198203B12CAfcd2E6240', + rewardTokenDecimals: [18], + }, + { + pool: '0x697ff44992788bbef0219864f51a9b535bfa9ccd-metis', + symbol: 'ETH', + chain: 'Metis', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x420000000000000000000000000000000000000a', + '0xa7ba356f3976d0ff7da9b4cb4979073949fd8588', + ], + stakingContract: '0x88f8c6D4d94daa32795A7d18002DB73a7ED0b72d', + rewardTokenDecimals: [18], + }, + { + pool: '0xbf19e64269ac14dc8786c33d1c9ace7dfd7fe9fa-metis', + symbol: 'O3', + chain: 'Metis', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x66ba1d90d03ffe3a5234d98085f9bac4ddde7778', + ], + stakingContract: '0x42D65E1182EE163E199f292022D52ED2dA3077C1', + rewardTokenDecimals: [18], + }, + { + pool: '0xe77ca468659c92f6deb63dd46720a30ea48ebcea-metis', + symbol: 'Metis', + chain: 'Metis', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', + '0xbe20a422f3b0d05887b3f4b7b59eca92023404b9', + ], + stakingContract: '0xCCB7a45E36f22eDE66b6222A0A55c547E6D516D7', + rewardTokenDecimals: [18], + }, + { + pool: '0x6bba09a54a9ac72ce74cbeb8afa93daf94ca1ce3-cube', + symbol: 'USDT', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x79f1520268a20c879ef44d169a4e3812d223c6de', + '0x1b905480b7ef8559f698665abf7a60ad26f686e8', + ], + stakingContract: '0x5F8517D606580D30c3bf210Fa016B8916c685be8', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0xd5ca558f1a444500ddd728475fc48db30e3768cb-cube', + symbol: 'USDC', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x00f0d8595797943c12605cd59bc0d9f63d750ccf', + '0x59414459c6c9883480983ef9888334d9376431f3', + ], + stakingContract: '0x7372C0e9336bEfB28Cef589F587026F5bfA34940', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0xbf19e64269ac14dc8786c33d1c9ace7dfd7fe9fa-cube', + symbol: 'BTC', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x040ea5c10e6ba4badb6c433a365ccc4968697230', + '0x84baa3a0247380f27edbb93ec5d89e516bb31729', + ], + stakingContract: '0xc39b6D561cB3C3E6B9E95a7b455073DA2a9fF122', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0x5db3b24f10366ce9031029c70759362a2f2b5e7b-cube', + symbol: 'ETH', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x57eea49ec1087695274a9c4f341e414eb64328c2', + '0x69f078f27c7f8bfbac7000aa700701064797a48c', + ], + stakingContract: '0xDc6722E9c3251e7972Cad6B213415A7220284E17', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0x7a25f1231cf2f617458828b4392c7303edceb29c-cube', + symbol: 'O3', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x5dbdd037e6f10fef42cac6d9129588fd49e2c0d9', + ], + stakingContract: '0x476d1c442394337556176d251bA02C6a99b4e47b', + rewardTokenDecimals: [18], + }, + { + pool: '0x5e5922c5a2e1c137d1d4cc3bf9374021a1002db2-cube', + symbol: 'DAI', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x3a1f6e3e6f26e92bb0d07841eb68f8e84f39751e', + '0xe20e662aa4a48428e5f002aa8d43a8443dff84e6', + ], + stakingContract: '0xf65c984f166553942C66BCc1FE74cFD3f26523e6', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0xb3b0a476cccaa41aa499a08b48c14ee668e8588a-cube', + symbol: 'Cube', + chain: 'Cube', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + ], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x9d3f61338d6eb394e378d28c1fd17d5909ac6591', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0x30E39786F0dd700DA277a54BD9c07F7894cB5aBa', + rewardTokenDecimals: [18, 18], + }, + { + pool: '0xb5c37095e038728e9bc8732cc89fcdfdb3ed9513-arbitrum', + symbol: 'USDT', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + '0xd9fb513766e60a569697d1f17ae466b0cb887454', + ], + stakingContract: '0x625Ba679174DE19B1e3588a0977c845419705dfc', + rewardTokenDecimals: [18], + }, + { + pool: '0x3a5292101a26c1dc75f97965b9091d4761a5d1e3-arbitrum', + symbol: 'USDC', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', + '0xe1443912860ed8baa2841cd4e6bb84337ccf6e4c', + ], + stakingContract: '0xA039b0529560Fa8030df0Fc9fc44e2A6d9AEdeC9', + rewardTokenDecimals: [18], + }, + { + pool: '0x1c557de77b6746d846e7c9a6c02609055a770d82-arbitrum', + symbol: 'BTC', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + '0xa63705460d4d907d6233684c5ce7ceb586b0f284', + ], + stakingContract: '0x4af3246ADca72CcdFb5afc31BDf7F17F91fa712c', + rewardTokenDecimals: [18], + }, + { + pool: '0x426223eef2e4f577767533aa1854e8b980b1df5f-arbitrum', + symbol: 'ETH', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + '0x4c66a27ecec5af2e87ad8c8ce5fb4cfc30437ec3', + ], + stakingContract: '0xa5c17e5B45f22B15086c8d0246B98ebBC0edA05f', + rewardTokenDecimals: [18], + }, + { + pool: '0x7742b1a272f24e306a1555c188643bc9d16723a8-arbitrum', + symbol: 'O3', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0xca2462c4203259e0ae1c21c0849e3fed71be6cc6', + ], + stakingContract: '0x678C51edffFF68d183E95185d972708cF6Afe7d8', + rewardTokenDecimals: [18], + }, + { + pool: '0x322c4c02bab59f61389010feb9de6047e6b20f6d-arbitrum', + symbol: 'DAI', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + '0x8a2ae0cf4674e8f83a1d823f57dc5735c5677c21', + ], + stakingContract: '0x7BB89E76b42676128607cfdec5eED854b3f0448c', + rewardTokenDecimals: [18], + }, + { + pool: '0xf54360fbc0de71bc6269755c3c8cb8f838700624-arbitrum', + symbol: 'ROOBEE', + chain: 'Arbitrum', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x3bd2dfd03bc7c3011ed7fb8c4d0949b382726cee', + '0x92af8d1bdcc9d876d08e5de841c439bb17b79bb8', + ], + stakingContract: '0xf8f64cE3ca82AAF864d9e81b9AEF2871868bE6f7', + rewardTokenDecimals: [18], + }, + { + pool: '0x70d2c8c01e535d90243abf181dd059baac9d0a6a-celo', + symbol: 'USDC', + chain: 'Celo', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x765de816845861e75a25fca122bb6898b8b1282a', + '0x69f078f27c7f8bfbac7000aa700701064797a48c', + ], + stakingContract: '0x66bA1D90D03Ffe3A5234d98085F9baC4DDdE7778', + rewardTokenDecimals: [18], + }, + { + pool: '0x86e28ce4a17b28dfb03830e6542c143d437c2456-celo', + symbol: 'O3', + chain: 'Celo', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x84baa3a0247380f27edbb93ec5d89e516bb31729', + ], + stakingContract: '0xE20e662aA4A48428e5F002aA8D43a8443dFF84e6', + rewardTokenDecimals: [18], + }, + { + pool: '0xd5ca558f1a444500ddd728475fc48db30e3768cb-avalanche', + symbol: 'USDC', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [6, 18], + underlyingTokens: [ + '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e', + '0x27ab099efb251d5e9377b747c01140045c8f8fcf', + ], + stakingContract: '0x12682669700109AE1F3B326D74f2A5bDB63549E3', + rewardTokenDecimals: [18], + }, + { + pool: '0x6bba09a54a9ac72ce74cbeb8afa93daf94ca1ce3-avalanche', + symbol: 'BTC', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x50b7545627a5162f82a992c33b87adc75187b218', + '0xa7ba356f3976d0ff7da9b4cb4979073949fd8588', + ], + stakingContract: '0x06D8B2A805Cc6B3fCE771783dABc56FfAb557840', + rewardTokenDecimals: [18], + }, + { + pool: '0xbf19e64269ac14dc8786c33d1c9ace7dfd7fe9fa-avalanche', + symbol: 'ETH', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', + '0x01fc120633213c7826704dee7137d919d7250805', + ], + stakingContract: '0x3A5292101A26c1dC75f97965B9091D4761A5d1E3', + rewardTokenDecimals: [18], + }, + { + pool: '0xd60929c3a153ddfee363c957490a305b1122e0d9-avalanche', + symbol: 'O3', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x66ba1d90d03ffe3a5234d98085f9bac4ddde7778', + ], + stakingContract: '0x30E39786F0dd700DA277a54BD9c07F7894cB5aBa', + rewardTokenDecimals: [18], + }, + { + pool: '0x19b15c74dc578b3dfdfe7e1dbe0a57d5198f7a78-avalanche', + symbol: 'DAI', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xd586e7f844cea2f87f50152665bcbc2c279d8d70', + '0x70d2c8c01e535d90243abf181dd059baac9d0a6a', + ], + stakingContract: '0x2d743c7cd4025FA86672B8361a26cC51474EE30C', + rewardTokenDecimals: [18], + }, + { + pool: '0x5db3b24f10366ce9031029c70759362a2f2b5e7b-avalanche', + symbol: 'AVAX', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', + '0x5ab509c40580d3b6291f0d1f951e8893dd31f665', + ], + stakingContract: '0x322C4C02baB59f61389010FEb9dE6047E6B20f6d', + rewardTokenDecimals: [18], + }, + { + pool: '0xbae8d41d1c0a997080420c4bae89475fbc6a5d33-avalanche', + symbol: 'ROOBEE', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: ['0xee9801669c6138e84bd50deb500827b776777d28'], + tokenDecimals: [18, 18], + underlyingTokens: [ + '0x4036f3d9c45a20f44f0b8b85dd6ca33005ff9654', + '0xe77ca468659c92f6deb63dd46720a30ea48ebcea', + ], + stakingContract: '0xDc6722E9c3251e7972Cad6B213415A7220284E17', + rewardTokenDecimals: [18], + }, + { + pool: '0x68868a5c9e6e3656b694f064abae62b24e0f76d3-avalanche', + symbol: 'GM', + chain: 'Avalanche', + project: 'o3-swap', + rewardTokens: [ + '0xee9801669c6138e84bd50deb500827b776777d28', + '0x0b53b5da7d0f275c31a6a182622bdf02474af253', + ], + tokenDecimals: [8, 18], + underlyingTokens: [ + '0x0b53b5da7d0f275c31a6a182622bdf02474af253', + '0x2471d31b744279ea7e9756ed5f1a8c9de4420d6d', + ], + stakingContract: '0xF7a9FE22149aD2a077eb40a90f316a8A47525EC3', + rewardTokenDecimals: [18, 8], + }, +]; + +module.exports = { + o3SwapPools, +}; diff --git a/src/adaptors/olympus-dao/abis/liquidityRegistryAbi.json b/src/adaptors/olympus-dao/abis/liquidityRegistryAbi.json new file mode 100644 index 0000000000..4fa348e500 --- /dev/null +++ b/src/adaptors/olympus-dao/abis/liquidityRegistryAbi.json @@ -0,0 +1,193 @@ +[ + { + "inputs": [ + { + "internalType": "contract Kernel", + "name": "kernel_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller_", + "type": "address" + } + ], + "name": "KernelAdapter_OnlyKernel", + "type": "error" + }, + { + "inputs": [], + "name": "LQREG_RemovalMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "policy_", + "type": "address" + } + ], + "name": "Module_PolicyNotPermitted", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "VaultAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "VaultRemoved", + "type": "event" + }, + { + "inputs": [], + "name": "INIT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "KEYCODE", + "outputs": [ + { + "internalType": "Keycode", + "name": "", + "type": "bytes5" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint8", + "name": "major", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "minor", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "activeVaultCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "activeVaults", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault_", + "type": "address" + } + ], + "name": "addVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Kernel", + "name": "newKernel_", + "type": "address" + } + ], + "name": "changeKernel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "kernel", + "outputs": [ + { + "internalType": "contract Kernel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "vault_", + "type": "address" + } + ], + "name": "removeVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/olympus-dao/abis/vaultManagerAbi.json b/src/adaptors/olympus-dao/abis/vaultManagerAbi.json new file mode 100644 index 0000000000..3887452c2b --- /dev/null +++ b/src/adaptors/olympus-dao/abis/vaultManagerAbi.json @@ -0,0 +1,748 @@ +[ + { + "inputs": [ + { + "internalType": "contract Kernel", + "name": "kernel_", + "type": "address" + }, + { + "components": [ + { "internalType": "address", "name": "ohm", "type": "address" }, + { "internalType": "address", "name": "pairToken", "type": "address" }, + { "internalType": "address", "name": "aura", "type": "address" }, + { "internalType": "address", "name": "bal", "type": "address" } + ], + "internalType": "struct IBLVaultManagerLido.TokenData", + "name": "tokenData_", + "type": "tuple" + }, + { + "components": [ + { "internalType": "address", "name": "vault", "type": "address" }, + { + "internalType": "address", + "name": "liquidityPool", + "type": "address" + }, + { + "internalType": "address", + "name": "balancerHelper", + "type": "address" + } + ], + "internalType": "struct IBLVaultManagerLido.BalancerData", + "name": "balancerData_", + "type": "tuple" + }, + { + "components": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { + "internalType": "address", + "name": "auraBooster", + "type": "address" + }, + { + "internalType": "address", + "name": "auraRewardPool", + "type": "address" + } + ], + "internalType": "struct IBLVaultManagerLido.AuraData", + "name": "auraData_", + "type": "tuple" + }, + { + "internalType": "address", + "name": "auraMiningLib_", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint48", + "name": "updateThreshold", + "type": "uint48" + } + ], + "internalType": "struct IBLVaultManagerLido.OracleFeed", + "name": "ohmEthPriceFeed_", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint48", + "name": "updateThreshold", + "type": "uint48" + } + ], + "internalType": "struct IBLVaultManagerLido.OracleFeed", + "name": "ethUsdPriceFeed_", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { + "internalType": "uint48", + "name": "updateThreshold", + "type": "uint48" + } + ], + "internalType": "struct IBLVaultManagerLido.OracleFeed", + "name": "stethUsdPriceFeed_", + "type": "tuple" + }, + { + "internalType": "address", + "name": "implementation_", + "type": "address" + }, + { "internalType": "uint256", "name": "ohmLimit_", "type": "uint256" }, + { "internalType": "uint64", "name": "fee_", "type": "uint64" }, + { + "internalType": "uint48", + "name": "minWithdrawalDelay_", + "type": "uint48" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "BLManagerLido_AlreadyActive", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_AlreadyInactive", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_BadPriceFeed", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_Inactive", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_InvalidFee", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_InvalidLimit", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_InvalidLpAmount", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_InvalidVault", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_LimitViolation", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_NoUserVault", "type": "error" }, + { "inputs": [], "name": "BLManagerLido_VaultAlreadyExists", "type": "error" }, + { "inputs": [], "name": "CreateFail", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "caller_", "type": "address" } + ], + "name": "KernelAdapter_OnlyKernel", + "type": "error" + }, + { + "inputs": [ + { "internalType": "Keycode", "name": "keycode_", "type": "bytes5" } + ], + "name": "Policy_ModuleDoesNotExist", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "fee", + "type": "uint64" + } + ], + "name": "VaultDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "BLREG", + "outputs": [ + { "internalType": "contract BLREGv1", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTR", + "outputs": [ + { "internalType": "contract MINTRv1", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ROLES", + "outputs": [ + { "internalType": "contract ROLESv1", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TRSRY", + "outputs": [ + { "internalType": "contract TRSRYv1", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "aura", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auraData", + "outputs": [ + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "address", "name": "auraBooster", "type": "address" }, + { "internalType": "address", "name": "auraRewardPool", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auraMiningLib", + "outputs": [ + { + "internalType": "contract IAuraMiningLib", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bal", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "balancerData", + "outputs": [ + { "internalType": "address", "name": "vault", "type": "address" }, + { "internalType": "address", "name": "liquidityPool", "type": "address" }, + { "internalType": "address", "name": "balancerHelper", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "burnOhmFromVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user_", "type": "address" } + ], + "name": "canWithdraw", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Kernel", + "name": "newKernel_", + "type": "address" + } + ], + "name": "changeKernel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint48", + "name": "ohmEthUpdateThreshold_", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "ethUsdUpdateThreshold_", + "type": "uint48" + }, + { + "internalType": "uint48", + "name": "stethUsdUpdateThreshold_", + "type": "uint48" + } + ], + "name": "changeUpdateThresholds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingOhmBurned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "configureDependencies", + "outputs": [ + { + "internalType": "Keycode[]", + "name": "dependencies", + "type": "bytes5[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentFee", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deactivate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "decreaseTotalLp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deployVault", + "outputs": [ + { "internalType": "address", "name": "vault", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deployedOhm", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "emergencyBurnOhm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ethUsdPriceFeed", + "outputs": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { "internalType": "uint48", "name": "updateThreshold", "type": "uint48" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeName", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "getExpectedLpAmount", + "outputs": [ + { "internalType": "uint256", "name": "bptAmount", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "lpAmount_", "type": "uint256" } + ], + "name": "getExpectedPairTokenOutUser", + "outputs": [ + { + "internalType": "uint256", + "name": "expectedTknAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "lpAmount_", "type": "uint256" } + ], + "name": "getExpectedTokensOutProtocol", + "outputs": [ + { + "internalType": "uint256[]", + "name": "expectedTokenAmounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user_", "type": "address" } + ], + "name": "getLpBalance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaxDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOhmSupplyChangeData", + "outputs": [ + { "internalType": "uint256", "name": "poolOhmShare", "type": "uint256" }, + { "internalType": "uint256", "name": "mintedOhm", "type": "uint256" }, + { "internalType": "uint256", "name": "netBurnedOhm", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOhmTknPoolPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOhmTknPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user_", "type": "address" } + ], + "name": "getOutstandingRewards", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "outstandingRewards", + "type": "uint256" + } + ], + "internalType": "struct RewardsData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolOhmShare", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "rewardToken_", "type": "address" } + ], + "name": "getRewardRate", + "outputs": [ + { "internalType": "uint256", "name": "rewardRate", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardTokens", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTknOhmPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user_", "type": "address" } + ], + "name": "getUserPairShare", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { "internalType": "contract BLVaultLido", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "increaseTotalLp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isActive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isLidoBLVaultActive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "kernel", + "outputs": [ + { "internalType": "contract Kernel", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minWithdrawalDelay", + "outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount_", "type": "uint256" } + ], + "name": "mintOhmToVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ohm", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ohmEthPriceFeed", + "outputs": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { "internalType": "uint48", "name": "updateThreshold", "type": "uint48" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ohmLimit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "requestPermissions", + "outputs": [ + { + "components": [ + { "internalType": "Keycode", "name": "keycode", "type": "bytes5" }, + { "internalType": "bytes4", "name": "funcSelector", "type": "bytes4" } + ], + "internalType": "struct Permissions[]", + "name": "permissions", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint64", "name": "newFee_", "type": "uint64" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newLimit_", "type": "uint256" } + ], + "name": "setLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint48", "name": "newDelay_", "type": "uint48" } + ], + "name": "setWithdrawalDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stethUsdPriceFeed", + "outputs": [ + { + "internalType": "contract AggregatorV3Interface", + "name": "feed", + "type": "address" + }, + { "internalType": "uint48", "name": "updateThreshold", "type": "uint48" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalLp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userVaults", + "outputs": [ + { "internalType": "contract BLVaultLido", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract BLVaultLido", "name": "", "type": "address" } + ], + "name": "vaultOwners", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/olympus-dao/index.js b/src/adaptors/olympus-dao/index.js new file mode 100644 index 0000000000..a6f21b6c8e --- /dev/null +++ b/src/adaptors/olympus-dao/index.js @@ -0,0 +1,281 @@ +const { gql, default: request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const liquidityRegistry = require('./abis/liquidityRegistryAbi.json'); +const vaultManager = require('./abis/vaultManagerAbi.json'); +const utils = require('../utils'); + +const OLYMPUS_LIQUIDITY_REGISTRY = '0x375E06C694B5E50aF8be8FB03495A612eA3e2275'; +const AURA_ADDRESS = '0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF'.toLowerCase(); +const BAL_ADDRESS = '0xba100000625a3754423978a60c9317c58a424e3D'.toLowerCase(); +const WSTETH_ADDRESS = + '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0'.toLowerCase(); +const OHM_ADDRESS = '0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5'; + +const AURA_API = + 'https://graph.aura.finance/subgraphs/name/aura/aura-mainnet-v2'; +const BAL_API = sdk.graph.modifyEndpoint('C4ayEZP2yTXRAB8vSaTrgN4m9anTe9Mdm2ViyiAuV9TV'); +const SWAP_APR_API = 'https://cache.aura.finance/aura/aprs-deprecated'; +const AURA_TVL_API = 'https://cache.aura.finance/aura/tvl-deprecated'; + +const balBoolsQuery = gql` + query Pools($address_in: [Bytes!] = "") { + pools(where: { address_in: $address_in }) { + id + symbol + address + tokens { + address + token { + symbol + } + cashBalance + balance + decimals + symbol + } + } + } +`; + +const auraPoolsQuery = gql` + query Pools($id: Int = 0) { + pools(where: { id: $id }) { + id + lpToken { + name + symbol + id + } + rewardData { + rewardRate + token { + name + id + } + } + totalSupply + totalStaked + gauge { + balance + totalSupply + workingSupply + } + } + } +`; + +const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; + +const getAuraMintAmount = (balEarned, auraSupply) => { + const auraUnitsMinted = + (((500 - (auraSupply - 50000000) / 100000) * 2.5 + 700) / 500) * balEarned; + return auraUnitsMinted; +}; + +/** + * Return an array of active vault addresses + */ +const getActiveVaults = async () => { + const activeVaultsCount = ( + await sdk.api.abi.call({ + target: OLYMPUS_LIQUIDITY_REGISTRY, + abi: liquidityRegistry.find((n) => n.name === 'activeVaultCount'), + chain: 'ethereum', + }) + ).output; + + /* we only care about the count, so we can fill an array with 0s and map over it */ + const countArray = Array.from({ length: activeVaultsCount }).fill(0); + + const addresses = await Promise.all( + countArray.map(async (value, position) => { + const address = ( + await sdk.api.abi.call({ + target: OLYMPUS_LIQUIDITY_REGISTRY, + abi: liquidityRegistry.find((n) => n.name === 'activeVaults'), + params: position, + chain: 'ethereum', + }) + ).output; + return address; + }) + ); + return addresses; +}; + +const getAuraVaultTVL = async (vaultAddress, pairToken) => { + const pricePerDepositToken = + ( + await sdk.api.abi.call({ + target: vaultAddress, + abi: vaultManager.find((n) => n.name === 'getExpectedLpAmount'), + params: '1000000000000000000', + chain: 'ethereum', + }) + ).output / 1e18; + + const totalLp = + ( + await sdk.api.abi.call({ + target: vaultAddress, + abi: vaultManager.find((n) => n.name === 'totalLp'), + chain: 'ethereum', + }) + ).output / 1e18; + + const { pricesByAddress: prices } = await utils.getPrices( + [pairToken, OHM_ADDRESS], + 'ethereum' + ); + + //Price for 1 LP Token in deposit token (converted to USD) + const usdPricePerDepositToken = + prices[pairToken.toLowerCase()] / pricePerDepositToken; + + //Price for 1 Deposit Token in OHM + const ohmPricePerDepositToken = + usdPricePerDepositToken / prices[OHM_ADDRESS.toLowerCase()]; + + //Price for 1 OHM Deposit Token in USD + const usdPricePerOhm = + prices[OHM_ADDRESS.toLowerCase()] * ohmPricePerDepositToken; + + const lpTokenPrice = usdPricePerDepositToken + usdPricePerOhm; + const tvlUsd = lpTokenPrice * totalLp; + + return tvlUsd; +}; + +/** + * Use the same method as Aura to calculate the APY. + * Return TVL of the Vault. + * Boost the reward APY by 2 to account for single sided deposit. + */ +const getAuraAPY = async (address, swapAprs, prices, auraSupply) => { + try { + const auraPool = ( + await sdk.api.abi.call({ + target: address, + abi: vaultManager.find((n) => n.name === 'auraData'), + chain: 'ethereum', + }) + ).output; + + const pairToken = ( + await sdk.api.abi.call({ + target: address, + abi: vaultManager.find((n) => n.name === 'pairToken'), + chain: 'ethereum', + }) + ).output; + + const contractFee = ( + await sdk.api.abi + .call({ + target: address, + abi: vaultManager.find((n) => n.name === 'currentFee'), + chain: 'ethereum', + }) + .catch(() => { + return { output: 0 }; //handle case of no fee + }) + ).output; + const fee = contractFee / 1e4; + + const { pools } = await request(AURA_API, auraPoolsQuery, { + id: +auraPool.pid, + }); + + const pool = pools[0]; + + const { pools: balPools } = await request(BAL_API, balBoolsQuery, { + address_in: [pool.lpToken.id], + }); + + const balPool = balPools[0]; + if (!balPool) return; + + const swapApr = swapAprs.find(({ id }) => id === balPool.id); + if (!swapApr?.poolAprs) return; + + const vaultTvlUsd = await getAuraVaultTVL(address, pairToken); + + const balRewards = pool.rewardData.find( + ({ token }) => token.id === BAL_ADDRESS + ); + + const auraExtraRewards = pool.rewardData.find( + ({ token }) => token.id === AURA_ADDRESS + ); + const { + balancer: { breakdown: auraTvl }, + } = await utils.getData(AURA_TVL_API); + const tvlUsd = auraTvl[pool.lpToken.id] || 0; + const balPerYear = (balRewards.rewardRate / 1e18) * SECONDS_PER_YEAR; + const balFee = balPerYear * fee; + const apyBal = + ((balPerYear - balFee) / tvlUsd) * 100 * prices[BAL_ADDRESS] || 0; + const auraPerYear = getAuraMintAmount(balPerYear, auraSupply); + const auraFee = auraPerYear * fee; + const apyAura = + ((auraPerYear - auraFee) / tvlUsd) * 100 * prices[AURA_ADDRESS] || 0; + const auraExtraApy = auraExtraRewards + ? (((auraExtraRewards.rewardRate / 1e18) * SECONDS_PER_YEAR) / tvlUsd) * + 100 * + prices[AURA_ADDRESS] + : 0; + //make sure to account for stETH rewards on certain pools + const wstETHApy = swapApr.poolAprs.tokens.breakdown[WSTETH_ADDRESS] || 0; + + const rewardTokens = [BAL_ADDRESS, AURA_ADDRESS]; + + return { + pool: address, + symbol: balPool.tokens.map(({ symbol }) => symbol).join('-'), + chain: utils.formatChain('ethereum'), + tvlUsd: vaultTvlUsd, + apyBase: Number(swapApr.poolAprs.swap) + wstETHApy * 2, //boosted + apyReward: (apyBal + apyAura + auraExtraApy) * 2, //boosted + underlyingTokens: balPool.tokens.map(({ address }) => address), + rewardTokens, + }; + } catch (e) { + console.log(e); + return; + } +}; + +/** + * Olympus Boosted Liquidity Pools are single sided deposit pools. + * Depositor deposits deposit token, Olympus matches deposit with OHM. + * Rewards from underlying pool are 2x, due to the single sided deposit and match. + */ +const main = async () => { + const addresses = await getActiveVaults(); + const { pools: swapAprs } = await utils.getData(SWAP_APR_API); + const auraSupply = + ( + await sdk.api.abi.call({ + target: AURA_ADDRESS, + abi: 'erc20:totalSupply', + chain: 'ethereum', + }) + ).output / 1e18; + const { pricesByAddress: prices } = await utils.getPrices( + [AURA_ADDRESS, BAL_ADDRESS], + 'ethereum' + ); + const apyInfo = await Promise.all( + addresses.map(async (address) => { + const info = await getAuraAPY(address, swapAprs, prices, auraSupply); + return info ? { project: 'olympus-dao', ...info } : undefined; + }) + ); + return apyInfo.filter((info) => info); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.olympusdao.finance/', +}; diff --git a/src/adaptors/omnidex-lend/abiLendingPool.js b/src/adaptors/omnidex-lend/abiLendingPool.js new file mode 100644 index 0000000000..ce3abc15a7 --- /dev/null +++ b/src/adaptors/omnidex-lend/abiLendingPool.js @@ -0,0 +1,691 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveOToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'oTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'oTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveOToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; \ No newline at end of file diff --git a/src/adaptors/omnidex-lend/abiProtocolDataProvider.js b/src/adaptors/omnidex-lend/abiProtocolDataProvider.js new file mode 100644 index 0000000000..f769b953ed --- /dev/null +++ b/src/adaptors/omnidex-lend/abiProtocolDataProvider.js @@ -0,0 +1,147 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllOTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'oTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentOTokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; \ No newline at end of file diff --git a/src/adaptors/omnidex-lend/index.js b/src/adaptors/omnidex-lend/index.js new file mode 100644 index 0000000000..2ff1663618 --- /dev/null +++ b/src/adaptors/omnidex-lend/index.js @@ -0,0 +1,171 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const superagent = require('superagent'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); + +const utils = require('../utils'); +const address = require('../paraspace-lending-v1/address'); + +const rewardToken = '0xD102cE6A4dB07D247fcc28F366A623Df0938CA9E'; + +const chains = { + ethereum: { + LendingPool: '0x6eC35d6B345DF1FAdBD3E3B2A8C4c4CAe84A5E26', + ProtocolDataProvider: '0x1D59555398c5dDbE98A7BcfE572D3597F24eE969', + IncentivesDataProvider: '0xdbAb1Ca8C13d8feB7567721D06C0BD394c20D0b4', + url: 'telos', + } +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain === 'avalanche' ? 'avax' : chain; + + const reserveList = ( + await sdk.api.abi.call({ + target: addresses.LendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain: 'telos', + }) + ).output; + reservesList = reserveList.filter(e => e !== '0x7C598c96D02398d89FbCb9d41Eab3DF0C16F227D'); + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: addresses.LendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain: 'telos', + }) + ).output.map((o) => o.output); + + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].oTokenAddress + : null, + })), + chain: 'telos', + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + let symbols = symbolsRes.output.map((o) => o.output); + // maker symbol is null + const mkrIdx = symbols.findIndex((s) => s === null); + symbols[mkrIdx] = 'MKR'; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: 'telos', + }) + ).output.map((o) => o.output); + + const assetPrice = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: 'telos', + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: addresses.ProtocolDataProvider, + params: t, + })), + chain: 'telos', + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + rewardsDataURL = "https://omnidex.bmaa3ajd1gjri.eu-west-2.cs.amazonlightsail.com/yields"; + const rewardAPYs = (await utils.getData(rewardsDataURL)); + + const pricesArray = reservesList.map((t) => `${'telos'}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + try { + lendingReward = rewardAPYs[symbols[i]].apyReward; + borrowingReward = rewardAPYs[symbols[i]].apyRewardBorrow; + } + catch { + lendingReward = 0; + borrowingReward = 0; + } + + const price = prices[`${'telos'}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + const url = `https://lending.omnidex.finance/markets`; + + return { + pool: `${reserveData[i].oTokenAddress}`.toLowerCase(), + symbol: symbols[i], + project: 'omnidex-lend', + chain: "telos", + tvlUsd, + apyBase, + apyReward: lendingReward, + rewardTokens: [rewardToken], + underlyingTokens: [t], + url, + // borrow fields + apyBaseBorrow, + apyRewardBorrow: borrowingReward, + totalSupplyUsd, + totalBorrowUsd, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + + }); + }) + ); + + return pools.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; \ No newline at end of file diff --git a/src/adaptors/onering-v2/index.js b/src/adaptors/onering-v2/index.js new file mode 100644 index 0000000000..289ac936ac --- /dev/null +++ b/src/adaptors/onering-v2/index.js @@ -0,0 +1,216 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { ethers } = require('ethers'); + +function sumValuesWithDifferentDecimals( + amount0, + decimals0, + amount1, + decimals1 +) { + const amount0Formatted = ethers.utils.formatUnits( + amount0.toString(), + decimals0 + ); + const amount1Formatted = ethers.utils.formatUnits( + amount1.toString(), + decimals1 + ); + + const value0Balance = ethers.utils.parseUnits(amount0Formatted, decimals0); + const value1Balance = ethers.utils.parseUnits(amount1Formatted, decimals1); + + // Determine the maximum decimal places + const maxDecimals = Math.max(decimals0, decimals1); + + // Adjust the balances to have the same decimal places + const adjustedValue0Balance = value0Balance.mul( + 10 ** (maxDecimals - decimals0) + ); + const adjustedValue1Balance = value1Balance.mul( + 10 ** (maxDecimals - decimals1) + ); + + // Sum the adjusted balances + const total = adjustedValue0Balance.add(adjustedValue1Balance); + + // Format the total balance with the desired decimal places + const totalFormatted = ethers.utils.formatUnits(total, maxDecimals); + + return Number(totalFormatted); +} + +const getPools = async (pools) => { + const poolsList = []; + + await Promise.all( + pools.map(async (pool) => { + const totalStaked = await sdk.api2.abi.call({ + abi: 'uint256:totalStaked', + target: pool.address, + chain: pool.chain, + }); + const ts = Number(ethers.utils.formatEther(totalStaked)); + + const rewardsPerSecond = await sdk.api2.abi.call({ + abi: 'uint256:REWARDS_PER_SECOND', + target: pool.address, + chain: pool.chain, + }); + const rewardsPerDay = + Number(ethers.utils.formatEther(rewardsPerSecond)) * 86400; + + const rewardsToken = await sdk.api2.abi.call({ + abi: 'address:REWARDS_TOKEN', + target: pool.address, + chain: pool.chain, + }); + + const lpToken = await sdk.api2.abi.call({ + abi: 'address:LP_TOKEN', + target: pool.address, + chain: pool.chain, + }); + + const lpToken0 = await sdk.api2.abi.call({ + abi: 'address:token0', + target: lpToken, + chain: pool.chain, + }); + + const lpToken1 = await sdk.api2.abi.call({ + abi: 'address:token1', + target: lpToken, + chain: pool.chain, + }); + + const lpTotalSupply = await sdk.api2.abi.call({ + abi: 'erc20:totalSupply', + target: lpToken, + chain: pool.chain, + }); + + const lpTs = Number(ethers.utils.formatEther(lpTotalSupply)); + + const gauge = await sdk.api2.abi.call({ + abi: 'address:GAUGE', + target: pool.address, + chain: pool.chain, + }); + + const lpBalance = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: gauge, + params: [pool.address], + chain: pool.chain, + }) + ).output; + + const lpBal = Number(ethers.utils.formatEther(lpBalance)); + + const lpBalanceToken0 = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: lpToken0, + params: [lpToken], + chain: pool.chain, + }) + ).output; + + const lpToken0Decimals = ( + await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: lpToken0, + chain: pool.chain, + }) + ).output; + + const lpBalanceToken1 = ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: lpToken1, + params: [lpToken], + chain: pool.chain, + }) + ).output; + + const lpToken1Decimals = ( + await sdk.api.abi.call({ + abi: 'erc20:decimals', + target: lpToken1, + chain: pool.chain, + }) + ).output; + + const totalBalance = sumValuesWithDifferentDecimals( + lpBalanceToken0, + lpToken0Decimals, + lpBalanceToken1, + lpToken1Decimals + ); + + const rewardsTokenPrice = ( + await axios.get( + `https://coins.llama.fi/prices/current/${pool.chain}:${rewardsToken}` + ) + ).data; + + const rewardsTokenUsd = + rewardsTokenPrice.coins[`${pool.chain}:${rewardsToken}`].price; + + const tvl = (ts / lpTs) * totalBalance; + const apy = + tvl === 0 ? 0 : ((rewardsPerDay * rewardsTokenUsd * 365) / tvl) * 100; + + poolsList.push({ + pool: pool.address, + chain: pool.chain, + symbol: pool.symbol, + meta: pool.meta, + tvl: tvl, + apy: apy, + rewardsToken: rewardsToken, + underlyingToken: lpToken, + }); + }) + ); + + return poolsList; +}; + +const main = async () => { + const poolsToReturn = []; + const poolsList = [ + { + address: '0x33ff52D1c4b6973CD5AF41ad53Dd92D99D31D3c3', + chain: 'optimism', + symbol: 'USDC/DOLA', + meta: 'StableV2 AMM', + }, + ]; + const pools = await getPools(poolsList); + + pools.map((pool) => { + const poolValues = { + pool: pool.pool, + chain: pool.chain, + project: 'onering-v2', + symbol: pool.symbol, + tvlUsd: pool.tvl, + apyBase: pool.apy, + rewardTokens: [pool.rewardsToken], + underlyingTokens: [pool.underlyingToken], + poolMeta: pool.meta, + }; + poolsToReturn.push(poolValues); + }); + + return poolsToReturn; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://onering.tools', +}; diff --git a/src/adaptors/openleverage/abis/LPool.json b/src/adaptors/openleverage/abis/LPool.json new file mode 100644 index 0000000000..79ddc7882a --- /dev/null +++ b/src/adaptors/openleverage/abis/LPool.json @@ -0,0 +1,41 @@ +{ + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalBorrows": { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "supplyRatePerBlock": { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/openleverage/abis/OplContract.json b/src/adaptors/openleverage/abis/OplContract.json new file mode 100644 index 0000000000..6be078a082 --- /dev/null +++ b/src/adaptors/openleverage/abis/OplContract.json @@ -0,0 +1,75 @@ +{ + "numPairs": { + "inputs": [], + "name": "numPairs", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + "markets": { + "inputs": [ + { "internalType": "uint16", "name": "", "type": "uint16" } + ], + "name": "markets", + "outputs": [ + { + "internalType": "address", + "name": "pool0", + "type": "address" + }, + { + "internalType": "address", + "name": "pool1", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint16", + "name": "marginLimit", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "feesRate", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "priceDiffientRatio", + "type": "uint16" + }, + { + "internalType": "address", + "name": "priceUpdater", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pool0Insurance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pool1Insurance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/openleverage/abis/erc20.json b/src/adaptors/openleverage/abis/erc20.json new file mode 100644 index 0000000000..c6a8f22a3b --- /dev/null +++ b/src/adaptors/openleverage/abis/erc20.json @@ -0,0 +1,33 @@ +{ + "balanceOf": { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "type": "function", + "stateMutability": "view", + "payable": false, + "outputs": [{ "type": "string", "name": "" }], + "name": "symbol", + "inputs": [], + "constant": true + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/openleverage/index.js b/src/adaptors/openleverage/index.js new file mode 100644 index 0000000000..adf7ed56f5 --- /dev/null +++ b/src/adaptors/openleverage/index.js @@ -0,0 +1,247 @@ +const sdk = require('@defillama/sdk'); +const erc20 = require('./abis/erc20.json'); +const LPool = require('./abis/LPool.json'); +const OplContract = require('./abis/OplContract.json'); +const axios = require('axios'); +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); + +openleve_address = { + eth: '0x03bf707deb2808f711bb0086fc17c5cafa6e8aaf', + bsc: '0x6A75aC4b8d8E76d15502E69Be4cb6325422833B4', + arb: '0x2925671dc7f2def9e4ad3fa878afd997f0b4db45', +}; + +llama_chain_name = { + bsc: 'Binance', + arb: 'Arbitrum', + eth: 'Ethereum', +}; + +coins_llama_name = { + bsc: 'bsc', + arb: 'arbitrum', + eth: 'ethereum', +}; + +opl_chain_name = { + bsc: 'bnb', + arb: 'arbitrum', + eth: 'eth', +}; + +block_of_year = { + eth: 2102400, + bsc: 10512000, + arb: 2628000, +}; + +oleAddr = { + eth: '0x92cfbec26c206c90aee3b7c66a9ae673754fab7e', + bsc: '0xa865197a84e780957422237b5d152772654341f3', + arb: '0xd4d026322c88c2d49942a75dff920fcfbc5614c1', +}; + +async function getTokenPriceInUsdt(chain, tokenAddr) { + const tokenPrice = ( + await axios.get( + `https://coins.llama.fi/prices/current/${coins_llama_name[chain]}:${tokenAddr}` + ) + ).data; + return tokenPrice.coins[`${coins_llama_name[chain]}:${tokenAddr}`].price; +} + +async function getPoolInfo(chain) { + const poolInfo = await axios.get( + `https://${opl_chain_name[chain]}.openleverage.finance/api/info/pools/interest` + ); + return poolInfo; +} + +async function getDecimals(addr, chain, abi) { + const decimals = ( + await sdk.api.abi.call({ + abi: abi, + target: addr, + chain: coins_llama_name[chain], + }) + ).output; + return decimals; +} + +async function getSymbol(addr, chain) { + const symbol = ( + await sdk.api.abi.call({ + abi: erc20.symbol, + target: addr, + chain: coins_llama_name[chain], + }) + ).output; + return symbol; +} + +async function getPoolListByUrl(chain) { + let poolList; + try { + const response = await getPoolInfo(chain); + poolList = response.data; + } catch (err) { + console.error(`Error fetching pool info for chain ${chain}:`, err); + return {}; + } + const pools = {}; + for (let i = 0; i < poolList.length; i++) { + if (poolList[i].tvl > 8000) { + const token0Decimal = await getDecimals( + poolList[i].token0Address, + chain, + erc20.decimals + ); + const token0Symbol = await getSymbol(poolList[i].token0Address, chain); + const info = { + name: poolList[i].poolName, + token: poolList[i].token0Address, + symbol: token0Symbol, + tokenDecimal: token0Decimal, + lendOleRewardApy: poolList[i].lendOleRewardApy, + }; + pools[poolList[i].poolAddress] = info; + console.log( + `Pool ${info.name} (${poolList[i].poolAddress}) on Chain ${chain} TVL > 8000` + ); + } + } + return pools; +} + +async function getPoolListByContract(chain) { + const numPairs = ( + await sdk.api.abi.call({ + abi: OplContract.numPairs, + target: openleve_address[chain], + chain: coins_llama_name[chain], + }) + ).output; + + const pools = {}; + for (let i = 0; i < numPairs; i++) { + const market = ( + await sdk.api.abi.call({ + abi: OplContract.markets, + target: openleve_address[chain], + chain: coins_llama_name[chain], + params: i, + }) + ).output; + const token0Decimal = await getDecimals( + market.token0, + chain, + erc20.decimals + ); + const token1Decimal = await getDecimals( + market.token1, + chain, + erc20.decimals + ); + + const token0Symbol = await getSymbol(market.token0, chain); + const token1Symbol = await getSymbol(market.token1, chain); + let info = { + name: `${token0Symbol}`, + token: market.token0, + symbol: token0Symbol, + tokenDecimal: token0Decimal, + }; + pools[market.pool0] = info; + + info = { + name: `${token1Symbol}`, + token: market.token1, + symbol: token1Symbol, + tokenDecimal: token1Decimal, + }; + pools[market.pool1] = info; + } + return pools; +} + +const main = async () => { + const result = []; + for (const chain of Object.keys(openleve_address)) { + let poolInfo; + try { + poolInfo = await getPoolListByUrl(chain); + } catch (err) { + console.error(`Skipping chain ${chain} due to unexpected error:`, err); + continue; + } + + if (!Object.keys(poolInfo).length) continue; + + for (const poolAddr of Object.keys(poolInfo)) { + const poolDetails = poolInfo[poolAddr]; + const poolBalance = ( + await sdk.api.abi.call({ + abi: erc20.balanceOf, + target: poolDetails.token, + chain: coins_llama_name[chain], + params: poolAddr, + }) + ).output; + const totalBorrow = ( + await sdk.api.abi.call({ + abi: LPool.totalBorrows, + target: poolAddr, + chain: coins_llama_name[chain], + }) + ).output; + const poolAPYPerBlock = ( + await sdk.api.abi.call({ + abi: LPool.supplyRatePerBlock, + target: poolAddr, + chain: coins_llama_name[chain], + }) + ).output; + + let tokenPriceInUsdt = 0; + try { + tokenPriceInUsdt = await getTokenPriceInUsdt(chain, poolDetails.token); + } catch (e) { + console.error( + `Error fetching token price for ${poolDetails.token} on ${chain}:`, + e + ); + } + + const poolValues = { + pool: `${poolAddr}-${llama_chain_name[chain]}`.toLowerCase(), + chain: utils.formatChain(llama_chain_name[chain]), + project: 'openleverage', + symbol: utils.formatSymbol(poolDetails.name).split('->')[0], + tvlUsd: new BigNumber(poolBalance) + .multipliedBy(new BigNumber(tokenPriceInUsdt)) + .dividedBy(new BigNumber(10).pow(poolDetails.tokenDecimal)) + .toNumber(), + apyBase: new BigNumber(poolAPYPerBlock) + .multipliedBy(new BigNumber(block_of_year[chain])) + .dividedBy(new BigNumber(10).pow(16)) + .toNumber(), + url: `https://${opl_chain_name[chain]}.openleverage.finance/app/pool/${poolAddr}`, + apyReward: poolDetails.lendOleRewardApy * 100, + rewardTokens: [poolDetails.token, oleAddr[chain]], + underlyingTokens: [poolDetails.token], + poolMeta: `${utils.formatSymbol(poolDetails.name)} Market`, + }; + console.log(poolValues); + result.push(poolValues); + } + } + + return result; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://openleverage.finance/', +}; diff --git a/src/adaptors/optifi/index.js b/src/adaptors/optifi/index.js new file mode 100644 index 0000000000..219f0e17f9 --- /dev/null +++ b/src/adaptors/optifi/index.js @@ -0,0 +1,31 @@ +const utils = require('../utils'); + +const collectPools = async () => { + const [data1, data2] = await Promise.all([ + utils.getData('https://lambda.optifi.app/get_amm_apy?optifi_program_id=optFiKjQpoQ3PvacwnFWaPUAqXCETMJSz2sz8HwPe9B&amm_id=1'), + utils.getData('https://lambda.optifi.app/get_amm_apy?optifi_program_id=optFiKjQpoQ3PvacwnFWaPUAqXCETMJSz2sz8HwPe9B&amm_id=2'), + ]); + + let apy = [(Object.entries(data1))[0][1]["apy_pct"], (Object.entries(data2))[0][1]["apy_pct"]]; + let tvl = [(Object.entries(data1))[0][1]["now"]["tvl"], (Object.entries(data2))[0][1]["now"]["tvl"]]; + let poolMeta = ["BTC Option", "ETH Option"] + + let poolAddress = ["4UoELNjSk36m3aqTS6PnxNoUSZYXKWa7hEn7i6BRHrUu", "8J7AfECijPQDUfj7k6pQk6YNTEqjSAjiZnsGNgRZmowz"] + return Object.entries(apy).map(([i, apy]) => ({ + pool: poolAddress[i], + chain: utils.formatChain('solana'), + project: 'optifi', + symbol: utils.formatSymbol('USDC'), + tvlUsd: tvl[i], + apy: apy, + poolMeta: poolMeta[i] + }) + + ); +}; + +module.exports = { + timetravel: false, + apy: collectPools, + url: 'https://www.optifi.app/amm', +}; diff --git a/src/adaptors/optyfi/index.js b/src/adaptors/optyfi/index.js new file mode 100644 index 0000000000..94adc4083c --- /dev/null +++ b/src/adaptors/optyfi/index.js @@ -0,0 +1,164 @@ +const superagent = require('superagent'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { default: BigNumber } = require('bignumber.js'); +const { ethers } = require('ethers'); +const optyfi_api = 'https://api.opty.fi'; +const get_vaults_api = `${optyfi_api}/v1/yield/vaults`; +const get_strategy_apy_api = `${optyfi_api}/v1/yield/strategy_score/strategy_hash`; +const abi = { + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + investStrategyHash: { + inputs: [], + name: 'investStrategyHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getPricePerFullShare: { + inputs: [], + name: 'getPricePerFullShare', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + decimals: { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const EMPTY_STRATEGY_HASH = + '0x0000000000000000000000000000000000000000000000000000000000000000'; + +async function getTVL(chainName, tokenAddress, decimals) { + const totalSupply = ( + await sdk.api.abi.call({ + target: tokenAddress, + abi: abi.totalSupply, + chain: chainName, + }) + ).output; + + const pricePerFullShare = ( + await sdk.api.abi.call({ + target: tokenAddress, + abi: abi.getPricePerFullShare, + chain: chainName, + }) + ).output; + const convertedPricePerFullShare = ethers.utils.formatUnits( + pricePerFullShare, + 18 + ); + const tvl = BigNumber(convertedPricePerFullShare) + .multipliedBy(BigNumber(totalSupply)) + .div(`1e${decimals}`); + return Number(tvl); +} + +const main = async () => { + const vaults = (await axios.get(get_vaults_api)).data.items; + const filteredVaults = []; + const vaultsAddresses = []; + for (let i = 0; i < vaults.length; i++) { + const vault = vaults[i]; + if (!vault.is_staging && [1, 137].includes(vault.chain.chain_id)) { + filteredVaults.push(vault); + const underlyingToken = `${vault.chain.chain_name.toLowerCase()}:${ + vault.vault_underlying_token.address + }`; + if (!vaultsAddresses.includes(underlyingToken)) { + vaultsAddresses.push(underlyingToken); + } + } + } + const keys = vaultsAddresses.join(',').toLowerCase(); + const usdPrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${keys}`) + ).body.coins; + const pools = []; + for (let i = 0; i < filteredVaults.length; i++) { + const vault = filteredVaults[i]; + const tvl = await getTVL( + vault.chain.chain_name, + vault.vault_token.address, + vault.vault_token.decimals + ); + const strategyHash = ( + await sdk.api.abi.call({ + target: vault.vault_token.address, + abi: abi.investStrategyHash, + chain: vault.chain.chain_name, + }) + ).output; + const tvlUsd = Number( + new BigNumber(tvl).multipliedBy( + usdPrice[ + `${vault.chain.chain_name.toLowerCase()}:${vault.vault_underlying_token.address.toLowerCase()}` + ].price + ) + ); + let apyBase = 0; + if (strategyHash !== EMPTY_STRATEGY_HASH) { + const fetchedApy = ( + await axios.get(`${get_strategy_apy_api}/${strategyHash}`) + ).data; + apyBase = Number(fetchedApy.strategy_score.total_apy); + } + const opSymbol = vault.vault_token.symbol.split('-'); + pools.push({ + pool: `${vault.vault_token.address}-${vault.chain.chain_name}`.toLowerCase(), + chain: utils.formatChain(vault.chain.chain_name), + project: 'optyfi', + symbol: opSymbol[0], + tvlUsd, + apyBase, + underlyingTokens: [vault.vault_underlying_token.address], + url: `https://app.opty.fi/vault/${vault.vault_token.address}`, + poolMeta: opSymbol[1], + }); + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.opty.fi/', +}; diff --git a/src/adaptors/opyn-squeeth/abi.js b/src/adaptors/opyn-squeeth/abi.js new file mode 100644 index 0000000000..89ec189fd0 --- /dev/null +++ b/src/adaptors/opyn-squeeth/abi.js @@ -0,0 +1,6 @@ +module.exports = { + zenBullAbi: + [{"inputs":[{"internalType":"address","name":"_crab","type":"address"},{"internalType":"address","name":"_powerTokenController","type":"address"},{"internalType":"address","name":"_euler","type":"address"},{"internalType":"address","name":"_eulerMarketsModule","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdcToRepay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethToWithdraw","type":"uint256"}],"name":"AuctionRepayAndWithdrawFromLeverage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"crabAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethLent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdcBorrowed","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"wethDeposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdcRepaid","type":"uint256"}],"name":"DepositAndRepayFromLeverage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ethToDeposit","type":"uint256"}],"name":"DepositEthIntoCrab","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"}],"name":"Farm","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"crabToRedeem","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wPowerPerpRedeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethBalanceReturned","type":"uint256"}],"name":"RedeemCrabAndWithdrawEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAuction","type":"address"},{"indexed":false,"internalType":"address","name":"newAuction","type":"address"}],"name":"SetAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCap","type":"uint256"}],"name":"SetCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldShutdownContract","type":"address"},{"indexed":false,"internalType":"address","name":"newShutdownContract","type":"address"}],"name":"SetShutdownContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"wethToUniswap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shareToUnwind","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"crabToRedeem","type":"uint256"}],"name":"ShutdownRepayAndWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"bullAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"crabToRedeem","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wPowerPerpToRedeem","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdcToRepay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethToWithdraw","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":false,"internalType":"uint256","name":"bullAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethToReceive","type":"uint256"}],"name":"WithdrawShutdown","type":"event"},{"inputs":[],"name":"TARGET_CR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"auction","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wethToDeposit","type":"uint256"},{"internalType":"uint256","name":"_usdcToRepay","type":"uint256"}],"name":"auctionDepositAndRepayFromLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_usdcToRepay","type":"uint256"},{"internalType":"uint256","name":"_wethToWithdraw","type":"uint256"}],"name":"auctionRepayAndWithdrawFromLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_crabAmount","type":"uint256"},{"internalType":"uint256","name":"_bullShare","type":"uint256"},{"internalType":"uint256","name":"_ethInCrab","type":"uint256"},{"internalType":"uint256","name":"_wPowerPerpInCrab","type":"uint256"},{"internalType":"uint256","name":"_totalCrabSupply","type":"uint256"}],"name":"calcLeverageEthUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bullShare","type":"uint256"}],"name":"calcUsdcToRepay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bullShare","type":"uint256"}],"name":"calcWethToWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crab","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_crabAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wethToDeposit","type":"uint256"},{"internalType":"uint256","name":"_usdcToBorrow","type":"uint256"}],"name":"depositAndBorrowFromLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethToDeposit","type":"uint256"}],"name":"depositEthIntoCrab","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"farm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCrabBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCrabVaultDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasRedeemedInShutdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"powerTokenController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_crabToRedeem","type":"uint256"},{"internalType":"uint256","name":"_wPowerPerpToRedeem","type":"uint256"}],"name":"redeemCrabAndWithdrawWEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_auction","type":"address"}],"name":"setAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"setCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_shutdownContract","type":"address"}],"name":"setShutdownContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdownContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wethToUniswap","type":"uint256"},{"internalType":"uint256","name":"shareToUnwind","type":"uint256"}],"name":"shutdownRepayAndWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bullAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bullAmount","type":"uint256"}],"name":"withdrawShutdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}], + eulerSimpleLens: + [{"inputs":[{"internalType":"bytes32","name":"moduleGitCommit_","type":"bytes32"},{"internalType":"address","name":"euler_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"euler","outputs":[{"internalType":"contract Euler","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exec","outputs":[{"internalType":"contract Exec","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountStatus","outputs":[{"internalType":"uint256","name":"collateralValue","type":"uint256"},{"internalType":"uint256","name":"liabilityValue","type":"uint256"},{"internalType":"uint256","name":"healthScore","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"getDTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"getETokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getEnteredMarkets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"getEulerAccountAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"getPTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"getPriceFull","outputs":[{"internalType":"uint256","name":"twap","type":"uint256"},{"internalType":"uint256","name":"twapPeriod","type":"uint256"},{"internalType":"uint256","name":"currPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"getPricingConfig","outputs":[{"internalType":"uint16","name":"pricingType","type":"uint16"},{"internalType":"uint32","name":"pricingParameters","type":"uint32"},{"internalType":"address","name":"pricingForwarded","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"getTokenInfo","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"getTotalSupplyAndDebts","outputs":[{"internalType":"uint256","name":"poolSize","type":"uint256"},{"internalType":"uint256","name":"totalBalances","type":"uint256"},{"internalType":"uint256","name":"totalBorrows","type":"uint256"},{"internalType":"uint256","name":"reserveBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"interestAccumulator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"interestRateModel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"interestRates","outputs":[{"internalType":"uint256","name":"borrowSPY","type":"uint256"},{"internalType":"uint256","name":"borrowAPY","type":"uint256"},{"internalType":"uint256","name":"supplyAPY","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"irmSettings","outputs":[{"components":[{"internalType":"uint256","name":"kink","type":"uint256"},{"internalType":"uint256","name":"baseAPY","type":"uint256"},{"internalType":"uint256","name":"kinkAPY","type":"uint256"},{"internalType":"uint256","name":"maxAPY","type":"uint256"},{"internalType":"uint256","name":"baseSupplyAPY","type":"uint256"},{"internalType":"uint256","name":"kinkSupplyAPY","type":"uint256"},{"internalType":"uint256","name":"maxSupplyAPY","type":"uint256"}],"internalType":"struct EulerSimpleLens.ResponseIRM","name":"r","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"markets","outputs":[{"internalType":"contract Markets","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"moduleGitCommit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"reserveFee","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"underlyingToAssetConfig","outputs":[{"components":[{"internalType":"address","name":"eTokenAddress","type":"address"},{"internalType":"bool","name":"borrowIsolated","type":"bool"},{"internalType":"uint32","name":"collateralFactor","type":"uint32"},{"internalType":"uint32","name":"borrowFactor","type":"uint32"},{"internalType":"uint24","name":"twapWindow","type":"uint24"}],"internalType":"struct Storage.AssetConfig","name":"config","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"underlyingToDToken","outputs":[{"internalType":"address","name":"dToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"underlyingToEToken","outputs":[{"internalType":"address","name":"eToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"underlyingToInternalTokens","outputs":[{"internalType":"address","name":"eToken","type":"address"},{"internalType":"address","name":"dToken","type":"address"},{"internalType":"address","name":"pToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"underlyingToPToken","outputs":[{"internalType":"address","name":"pToken","type":"address"}],"stateMutability":"view","type":"function"}] +} \ No newline at end of file diff --git a/src/adaptors/opyn-squeeth/index.js b/src/adaptors/opyn-squeeth/index.js new file mode 100644 index 0000000000..a5cda6b4c9 --- /dev/null +++ b/src/adaptors/opyn-squeeth/index.js @@ -0,0 +1,206 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const utils = require('../utils'); +const { zenBullAbi, eulerSimpleLens } = require('./abi'); + +const poolsFunction = async () => { + const API_URLS = { + ethereum: sdk.graph.modifyEndpoint('9VC95zuTxcMhXxU25qQkEK2akFzE3eEPiBZGXjGbGcbA'), + }; + const currentTimestamp = new Date().getTime() / 1000; + const startTimestamp = currentTimestamp - 60 * 60 * 24 * 7; + // get eth usd price + const key = 'ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + const ethPriceUSD = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + // get squeeth usd price + const squeethKey = 'ethereum:0xf1b99e3e573a1a9c5e6b2ce818b617f0e664e86b'; + const squeethPriceUSD = ( + await superagent.get(`https://coins.llama.fi/prices/current/${squeethKey}`) + ).body.coins[squeethKey].price; + const usdc = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; + const weth = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + + /**************** Crab strategy APY and TVL ****************/ + // crab strategy vault in squeeth + const crabVaultQuery = gql` + query Vault($vaultID: ID! = 286) { + vault(id: $vaultID) { + id + shortAmount + collateralAmount + NftCollateralId + owner { + id + } + operator + } + } + `; + const crabVaultQueryData = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await request(url, crabVaultQuery)).vault, + ]) + ); + + const crabTvl = + (crabVaultQueryData[0][1].collateralAmount * ethPriceUSD) / 1e18 - + (crabVaultQueryData[0][1].shortAmount * squeethPriceUSD) / 1e18; + + // weekly apy + let crabApyData = ( + await utils.getData( + `https://data-dot-mm-bot-prod.uc.r.appspot.com/metrics/crabv2?start_timestamp=${startTimestamp}&end_timestamp=${currentTimestamp}` + ) + ).data; + crabApyData = crabApyData[crabApyData.length - 1]; + const historicalUsdcReturns = crabApyData.crabPnL * 100; + const crabNumberOfDays = + (Number(currentTimestamp) - Number(startTimestamp)) / (60 * 60 * 24); + const annualizedUsdcReturns = + (Math.pow(1 + historicalUsdcReturns / 100, 365 / crabNumberOfDays) - 1) * + 100; + + // inception apy + const crabStartTimestamp = '1658966400'; + let crabApyDataInception = ( + await utils.getData( + `https://data-dot-mm-bot-prod.uc.r.appspot.com/metrics/crabv2?start_timestamp=${crabStartTimestamp}&end_timestamp=${currentTimestamp}` + ) + ).data; + crabApyDataInception = crabApyDataInception[crabApyDataInception.length - 1]; + + const crabNumberOfDaysInception = + (Number(currentTimestamp) - Number(crabStartTimestamp)) / (60 * 60 * 24); + + const annualizedUsdcReturnsInception = + (Math.pow( + 1 + (crabApyDataInception.crabPnL * 100) / 100, + 365 / crabNumberOfDaysInception + ) - + 1) * + 100; + console.log(annualizedUsdcReturns); + + const chain = 'ethereum'; + const usdcPool = { + pool: `${usdc}-${chain}`, + chain: chain, + project: 'opyn-squeeth', + symbol: 'USDC', + tvlUsd: crabTvl, + apyBase: annualizedUsdcReturns, + apyBaseInception: annualizedUsdcReturnsInception, + poolMeta: 'Crab USDC', + }; + + // affected by euler hack + // /**************** Zen Bull strategy APY and TVL ****************/ + // const zenBullAddress = '0xb46Fb07b0c80DBC3F97cae3BFe168AcaD46dF507'; + // const eulerSimpleLensAddress = '0x5077B7642abF198b4a5b7C4BdCE4f03016C7089C'; + // const [ethInCrab, squeethInCrab] = ( + // await sdk.api.abi.call({ + // target: zenBullAddress, + // abi: zenBullAbi.find(({ name }) => name === 'getCrabVaultDetails'), + // chain: 'ethereum', + // }) + // ).output; + // const bullCrabBalance = ( + // await sdk.api.abi.call({ + // target: zenBullAddress, + // abi: zenBullAbi.find(({ name }) => name === 'getCrabBalance'), + // chain: 'ethereum', + // }) + // ).output; + // const crab = '0x3B960E47784150F5a63777201ee2B15253D713e8'; + // const crabTotalSupply = ( + // await sdk.api.erc20.totalSupply({ + // target: crab, + // chain: 'ethereum', + // }) + // ).output; + // const bullDtokenBalance = ( + // await sdk.api.abi.call({ + // target: eulerSimpleLensAddress, + // abi: eulerSimpleLens.find(({ name }) => name === 'getDTokenBalance'), + // params: [usdc, zenBullAddress], + // chain: 'ethereum', + // }) + // ).output; + // const bullEtokenBalance = ( + // await sdk.api.abi.call({ + // target: eulerSimpleLensAddress, + // abi: eulerSimpleLens.find(({ name }) => name === 'getETokenBalance'), + // params: [weth, zenBullAddress], + // chain: 'ethereum', + // }) + // ).output; + + // const crabUsdPrice = + // ((ethInCrab * ethPriceUSD) / 1e18 - + // (squeethInCrab * squeethPriceUSD) / 1e18) / + // (crabTotalSupply / 1e18); + // const zenBullTvl = + // (bullEtokenBalance * ethPriceUSD) / 1e18 + + // (bullCrabBalance * crabUsdPrice) / 1e18 - + // bullDtokenBalance / 1e6; + + // // weekly apy + // let zenBullApyData = ( + // await utils.getData( + // `https://data-dot-mm-bot-prod.uc.r.appspot.com/metrics/zenbull/pnl/${startTimestamp}/${currentTimestamp}` + // ) + // ).data; + // zenBullApyData = zenBullApyData[zenBullApyData.length - 1]; + // const historicalWethReturns = zenBullApyData.bullEthPnl; + // const zenBullNumberOfDays = + // (Number(currentTimestamp) - Number(startTimestamp)) / (60 * 60 * 24); + // const annualizedWethReturns = + // (Math.pow(1 + historicalWethReturns / 100, 365 / zenBullNumberOfDays) - 1) * + // 100; + + // // inception apy + // const zenBullStartTimestamp = '1671500159'; + // let zenBullApyDataInception = ( + // await utils.getData( + // `https://data-dot-mm-bot-prod.uc.r.appspot.com/metrics/zenbull/pnl/${zenBullStartTimestamp}/${currentTimestamp}` + // ) + // ).data; + // zenBullApyDataInception = + // zenBullApyDataInception[zenBullApyDataInception.length - 1]; + // const historicalWethReturnsInception = zenBullApyDataInception.bullEthPnl; + + // const zenBullNumberOfDaysInception = + // (Number(currentTimestamp) - Number(zenBullStartTimestamp)) / (60 * 60 * 24); + + // const annualizedWethReturnsInception = + // (Math.pow( + // 1 + historicalWethReturnsInception / 100, + // 365 / zenBullNumberOfDaysInception + // ) - + // 1) * + // 100; + + // const zenBullChain = 'ethereum'; + // const wethPool = { + // pool: `${weth}-${zenBullChain}`, + // chain: zenBullChain, + // project: 'opyn-squeeth', + // symbol: 'WETH', + // tvlUsd: zenBullTvl, + // apyBase: annualizedWethReturns, + // apyBaseInception: annualizedWethReturnsInception, + // poolMeta: 'Zen Bull ETH', + // }; + + return [usdcPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://squeeth.opyn.co/strategies/', +}; diff --git a/src/adaptors/orange-finance/abi.ts b/src/adaptors/orange-finance/abi.ts new file mode 100644 index 0000000000..0d8b0ce5c3 --- /dev/null +++ b/src/adaptors/orange-finance/abi.ts @@ -0,0 +1,365 @@ +module.exports = { + v1VaultAbi: [ + { + inputs: [ + { internalType: 'string', name: '_name', type: 'string' }, + { internalType: 'string', name: '_symbol', type: 'string' }, + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + { internalType: 'address', name: '_liquidityPool', type: 'address' }, + { internalType: 'address', name: '_lendingPool', type: 'address' }, + { internalType: 'address', name: '_params', type: 'address' }, + { internalType: 'address', name: '_router', type: 'address' }, + { internalType: 'uint24', name: '_routerFee', type: 'uint24' }, + { internalType: 'address', name: '_balancer', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'enum IOrangeVaultV1.ActionType', + name: 'actionType', + type: 'uint8', + }, + { indexed: true, internalType: 'address', name: 'caller', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'collateralAmount0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'debtAmount1', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'liquidityAmount0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'liquidityAmount1', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'accruedFees0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'accruedFees1', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'vaultAmount0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'vaultAmount1', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'totalAssets', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + ], + name: 'Action', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'spender', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'uint256', name: 'burn0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'burn1', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'fee0', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'fee1', type: 'uint256' }, + ], + name: 'BurnAndCollectFees', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'balancer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'uint256', name: '_maxAssets', type: 'uint256' }, + { internalType: 'bytes32[]', name: '_merkleProof', type: 'bytes32[]' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'deposits', + outputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint40', name: 'timestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'enum IOrangeVaultV1.ActionType', name: '_actionType', type: 'uint8' }, + ], + name: 'emitAction', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'flashloanHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getUnderlyingBalances', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'liquidityAmount0', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityAmount1', type: 'uint256' }, + { internalType: 'uint256', name: 'accruedFees0', type: 'uint256' }, + { internalType: 'uint256', name: 'accruedFees1', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultAmount0', type: 'uint256' }, + { internalType: 'uint256', name: 'vaultAmount1', type: 'uint256' }, + ], + internalType: 'struct IOrangeVaultV1.UnderlyingAssets', + name: 'underlyingAssets', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'hasPosition', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lendingPool', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidityPool', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lowerTick', + outputs: [{ internalType: 'int24', name: '', type: 'int24' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'params', + outputs: [{ internalType: 'contract IOrangeParametersV1', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'int24', name: '', type: 'int24' }, + { internalType: 'int24', name: '', type: 'int24' }, + { + components: [ + { internalType: 'uint256', name: 'collateralAmount0', type: 'uint256' }, + { internalType: 'uint256', name: 'debtAmount1', type: 'uint256' }, + { internalType: 'uint256', name: 'token0Balance', type: 'uint256' }, + { internalType: 'uint256', name: 'token1Balance', type: 'uint256' }, + ], + internalType: 'struct IOrangeVaultV1.Positions', + name: '', + type: 'tuple', + }, + { internalType: 'uint128', name: '', type: 'uint128' }, + ], + name: 'rebalance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20[]', name: '_tokens', type: 'address[]' }, + { internalType: 'uint256[]', name: '_amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: '', type: 'uint256[]' }, + { internalType: 'bytes', name: '_userData', type: 'bytes' }, + ], + name: 'receiveFlashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'uint256', name: '_minAssets', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: 'returnAssets_', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'router', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'routerFee', + outputs: [{ internalType: 'uint24', name: '', type: 'uint24' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'int24', name: '', type: 'int24' }], + name: 'stoploss', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalDeposits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'upperTick', + outputs: [{ internalType: 'int24', name: '', type: 'int24' }], + stateMutability: 'view', + type: 'function', + }, + ] +} \ No newline at end of file diff --git a/src/adaptors/orange-finance/index.ts b/src/adaptors/orange-finance/index.ts new file mode 100644 index 0000000000..fdd4bd5b80 --- /dev/null +++ b/src/adaptors/orange-finance/index.ts @@ -0,0 +1,119 @@ +const utils = require('../utils'); +const { calculateAPR } = require('./strykeFee'); +const BigNumber = require('bignumber.js'); +const { chain, uniqBy } = require('lodash'); +const { request } = require('graphql-request'); + +const orangeGraphUrl = + 'https://subgraph.satsuma-prod.com/1563a78cd0f9/pao-tech/orange-finance/api'; +const strykeGraphUrl = + 'https://api.0xgraph.xyz/subgraphs/name/dopex-v2-clamm-public'; + +const { + getStrykeVaultListQuery, + getUniV3PoolListQuery, + getStrykeLpPositionsListQuery, + getDailyStrikeEarningsListQuery, +} = require('./query'); + +const vaultList = [ + '0xe1B68841E764Cc31be1Eb1e59d156a4ED1217c2C', + '0x708790D732c5886D56b0cBBEd7b60ABF47848FaA', + '0x01E371c500C49beA2fa985334f46A8Dc906253Ea', + '0x22dd31a495CafB229131A16C54a8e5b2f43C1162', + '0x5f6D5a7e8eccA2A53C6322a96e9a48907A8284e0', + '0xE32132282D181967960928b77236B3c472d5f396', + '0x3D2692Bb38686d0Fb9B1FAa2A3e2e5620EF112A9' +]; + +const fetchVaultData = async(vault, pool, ethPriceUSD, rewardsData) => { + const dataDopexFirst = await request( + strykeGraphUrl, + getStrykeLpPositionsListQuery, + { vaultIds: [vault.id] } + ); + + const tokenIds = dataDopexFirst?.lppositions.map(lpPosition => lpPosition.strike.id) ?? [] + + const dataDopexSecond = await request( + strykeGraphUrl, + getDailyStrikeEarningsListQuery, + { tokenIds, tokenIdsCount: tokenIds.length, startTime: Math.floor(new Date().getTime() / 1000) - 60 * 60 * 24 } + ); + + const lpPositions = dataDopexFirst?.lppositions ?? [] + const dailyDonations = uniqBy(dataDopexSecond?.dailyDonations, 'strike.id') + const dailyFeeCompounds = uniqBy(dataDopexSecond?.dailyFeeCompounds, 'strike.id') + const dopexStrikeEarnings = chain(lpPositions) + .map(lpPosition => { + const donation = dailyDonations.find(d => d.strike.id === lpPosition.strike.id) + const compound = dailyFeeCompounds.find(c => c.strike.id === lpPosition.strike.id) + if (!donation && !compound) { + return null + } + + return { + sqrtPriceX96: donation?.sqrtPriceX96 ?? compound?.sqrtPriceX96, + donation: donation?.donation ?? '0', + compound: compound?.compound ?? '0', + strike: lpPosition?.strike, + pool: lpPosition.pool, + shares: lpPosition.shares, + user: lpPosition.user, + handler: lpPosition.handler, + } + }) + .compact() + .value() + + const stats = calculateAPR(dopexStrikeEarnings, vault, pool, ethPriceUSD) + const vaultStats = {stats, vault, pool} + const symbol = vaultStats.vault.isTokenPairReversed + ? `${vaultStats.pool.token1.symbol}-${vaultStats.pool.token0.symbol}` + : `${vaultStats.pool.token0.symbol}-${vaultStats.pool.token1.symbol}` + const apyReward = rewardsData[vault.id]?.rewardAPR || 0 + return { + pool: vaultStats.vault.id, + chain: utils.formatChain('arbitrum'), + project: 'orange-finance', + symbol, + apyBase: vaultStats.stats.dopexApr.toNumber() * 100, + apyReward, + tvlUsd: vaultStats.stats.tvl.toNumber(), + poolMeta: 'LPDfi', + rewardTokens: ["0x912CE59144191C1204E64559FE8253a0e49E6548"] + } +} + +async function getPools() { + const dataOrange = await request(orangeGraphUrl, getStrykeVaultListQuery); + + const strykeVaults = + dataOrange?.dopexVaults.filter((vault) => { + return vaultList + .map((address) => address.toLowerCase()) + .includes(vault.id.toLowerCase()); + }) ?? []; + + const dataUni = await request(orangeGraphUrl, getUniV3PoolListQuery, { + poolIds: chain(strykeVaults).map((vault) => vault.pool).uniq().value(), + }); + const ethPriceUSD = new BigNumber(dataUni.bundle.ethPriceUSD) + + const rewardsData = await (await fetch('https://raw.githubusercontent.com/orange-finance/resource/main/stats.json')).json() + const formattedRewardsData = Object.fromEntries( + Object.entries(rewardsData).map(([k, v]) => [k.toLowerCase(), v]) + ); + + const stats = await Promise.all(strykeVaults.map(vault => { + const pool = dataUni?.pools.find(pool => pool.id === vault?.pool) + return fetchVaultData(vault, pool, ethPriceUSD, formattedRewardsData) + })) + return stats +} + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.orangefinance.io', +}; \ No newline at end of file diff --git a/src/adaptors/orange-finance/price.ts b/src/adaptors/orange-finance/price.ts new file mode 100644 index 0000000000..97d8727f2e --- /dev/null +++ b/src/adaptors/orange-finance/price.ts @@ -0,0 +1,28 @@ +const { SqrtPriceMath } = require('@uniswap/v3-sdk'); +const JSBI = require('jsbi') + +const getAmountsForLiquidity = ( + sqrtRatioX96: typeof JSBI, + sqrtRatioAX96: typeof JSBI, + sqrtRatioBX96: typeof JSBI, + liquidity: typeof JSBI +): { amount0: typeof JSBI; amount1: typeof JSBI } => { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + + let amount0 = JSBI.BigInt(0) + let amount1 = JSBI.BigInt(0) + + if (JSBI.lessThanOrEqual(sqrtRatioX96, sqrtRatioAX96)) { + amount0 = SqrtPriceMath.getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity, false) + } else if (JSBI.lessThan(sqrtRatioX96, sqrtRatioBX96)) { + amount0 = SqrtPriceMath.getAmount0Delta(sqrtRatioX96, sqrtRatioBX96, liquidity, false) + amount1 = SqrtPriceMath.getAmount1Delta(sqrtRatioAX96, sqrtRatioX96, liquidity, false) + } else { + amount1 = SqrtPriceMath.getAmount1Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity, false) + } + return { amount0, amount1 } +} + +module.exports = { getAmountsForLiquidity } \ No newline at end of file diff --git a/src/adaptors/orange-finance/query.ts b/src/adaptors/orange-finance/query.ts new file mode 100644 index 0000000000..8728ad7223 --- /dev/null +++ b/src/adaptors/orange-finance/query.ts @@ -0,0 +1,107 @@ +const { gql } = require('graphql-request'); + +const getStrykeVaultListQuery = gql` + query getStrykeVaultList { + dopexVaults(orderBy: totalSupply, orderDirection: desc) { + id + totalAssets + totalSupply + decimals + yieldStart + isTokenPairReversed + depositCap + pool + } + } +` + +const getUniV3PoolListQuery = gql` + query getUniV3PoolListQuery($poolIds: [ID!]!) { + pools(where: { id_in: $poolIds }) { + id + tick + sqrtPrice + token0 { + id + name + symbol + decimals + derivedETH + } + token1 { + id + name + symbol + decimals + derivedETH + } + token0Price + token1Price + } + bundle(id: "1") { + ethPriceUSD + id + } + } +` + +const getStrykeLpPositionsListQuery = gql` + query getStrykeLpPositionsList($vaultIds: [String!]!) { + lppositions(where: { user_in: $vaultIds, shares_gt: "0" }) { + id + pool + shares + initialLiquidity + user + handler + strike { + id + pool + tickLower + tickUpper + totalLiquidity + usedLiquidity + totalShares + } + } + } +` + +const getDailyStrikeEarningsListQuery = gql` + query getDailyStrikeEarningsListQuery( + $tokenIds: [ID!]! + $tokenIdsCount: Int! + $startTime: BigInt! + ) { + dailyDonations( + where: { strike_: { id_in: $tokenIds }, donation_gt: "0", start_gte: $startTime } + orderBy: start + orderDirection: desc + first: $tokenIdsCount + ) { + id + donation + sqrtPriceX96 + start + strike { + id + } + } + dailyFeeCompounds( + where: { strike_: { id_in: $tokenIds }, compound_gt: "0", start_gte: $startTime } + orderBy: start + orderDirection: desc + first: $tokenIdsCount + ) { + id + compound + sqrtPriceX96 + start + strike { + id + } + } + } +` + +module.exports = { getStrykeVaultListQuery, getUniV3PoolListQuery, getStrykeLpPositionsListQuery, getDailyStrikeEarningsListQuery} \ No newline at end of file diff --git a/src/adaptors/orange-finance/strykeFee.ts b/src/adaptors/orange-finance/strykeFee.ts new file mode 100644 index 0000000000..65c61564c0 --- /dev/null +++ b/src/adaptors/orange-finance/strykeFee.ts @@ -0,0 +1,226 @@ +const BigNumber = require('bignumber.js'); +const { TickMath } = require('@uniswap/v3-sdk') +const JSBI = require('jsbi') +const { getAmountsForLiquidity } = require('./price') + +export type DopexStrikeEarningPerVault = { + sqrtPriceX96?: string + compound?: string + donation?: string + strike: { + id: string + pool: string + tickLower: number + tickUpper: number + totalLiquidity: string + totalShares: string + } + pool: string + shares: string + user: string + handler: string +} + +type Token = { + id: string + decimals: string + derivedETH: string +} +type Pool = { + id: string + token0Price: string + token1Price: string + token0: Token + token1: Token +} + +type Vault = { + id: string + totalAssets: string + totalSupply: string + decimals: string + isTokenPairReversed: boolean +} + +const calculateAPR = ( + earningList: DopexStrikeEarningPerVault[], + vault: Vault, + pool: Pool, + ethPriceUSD: typeof BigNumber +) => { + const strikeEarningAmounts = getStrikeEarningAmounts(earningList) + + const result = strikeEarningAmounts.map(earn => { + const { + amount0ETH: feeAmount0ETH, + amount1ETH: feeAmount1ETH, + totalAmountETH: feeTotalAmountETH, + totalAmountUSD: feeTotalAmountUSD, + } = convertAmountToETH( + earn.fee.amount0, + earn.fee.amount1, + pool.token0, + pool.token1, + ethPriceUSD + ) + const { + amount0ETH: premiumAmount0ETH, + amount1ETH: premiumAmount1ETH, + totalAmountETH: premiumTotalAmountETH, + totalAmountUSD: premiumTotalAmountUSD, + } = convertAmountToETH( + earn.premium.amount0, + earn.premium.amount1, + pool.token0, + pool.token1, + ethPriceUSD + ) + const { + amount0: orangeAmount0, + amount1: orangeAmount1, + totalAmountETH: orangeTotalAmountETH, + totalAmountUSD: orangeTotalAmountUSD, + } = convertAmountToETH( + earn.orange.amount0, + earn.orange.amount1, + pool.token0, + pool.token1, + ethPriceUSD + ) + + const feeAPR = feeTotalAmountETH + .multipliedBy(earn.rate) + .dividedBy(orangeTotalAmountETH) + .multipliedBy(365) + + const premiumAPR = premiumTotalAmountETH + .multipliedBy(earn.rate) + .dividedBy(orangeTotalAmountETH) + .multipliedBy(365) + + return { + id: earn.tokenId, + feeAmount0ETH, + feeAmount1ETH, + feeTotalAmountETH, + feeTotalAmountETHOfOrangeShare: feeTotalAmountETH.multipliedBy(earn.rate), + premiumAmount0ETH, + premiumAmount1ETH, + premiumTotalAmountETH, + premiumTotalAmountETHOfOrangeShare: premiumTotalAmountETH.multipliedBy(earn.rate), + orangeAmount0, + orangeAmount1, + orangeTotalAmountETH, + feeAPR, + premiumAPR, + rate: earn.rate, + } + }) + const baseToken = vault.isTokenPairReversed ? pool.token1 : pool.token0 + const tvl = new BigNumber(vault.totalAssets) + .dividedBy(10 ** Number(baseToken.decimals)) + .times(baseToken.derivedETH) + .times(ethPriceUSD) + + const res = result.reduce( + (acc, sp) => { + acc.fee = acc.fee.plus(sp.feeTotalAmountETHOfOrangeShare) + acc.premium = acc.premium.plus(sp.premiumTotalAmountETHOfOrangeShare) + acc.orange = acc.orange.plus(sp.orangeTotalAmountETH) + return acc + }, + { fee: new BigNumber(0), premium: new BigNumber(0), orange: new BigNumber(0) } + ) + + return { + vaultId: vault.id, + fee: res.fee, + premium: res.premium, + orange: res.orange, + dopexApr: !res.orange.isZero() + ? res.fee.plus(res.premium).dividedBy(res.orange).multipliedBy(365) + : new BigNumber(0), + strikePremimFee: result, + tvl, + } +} + +const getStrikeEarningAmounts = (earningList: DopexStrikeEarningPerVault[]) => { + if (!earningList) return [] + + return earningList.map(earning => { + if (!earning.strike || !earning.sqrtPriceX96 || !earning.donation || !earning.compound) { + return { + tokenId: earning.strike.id, + fee: { amount0: JSBI.BigInt(0), amount1: JSBI.BigInt(0) }, + premium: { amount0: JSBI.BigInt(0), amount1: JSBI.BigInt(0) }, + orange: { amount0: JSBI.BigInt(0), amount1: JSBI.BigInt(0) }, + rate: new BigNumber(0), + } + } + const sqrtPriceX96 = JSBI.BigInt(earning.sqrtPriceX96) + const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(earning.strike.tickLower) + const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(earning.strike.tickUpper) + const donations = JSBI.BigInt(earning.donation) + const compouds = JSBI.BigInt(earning.compound) + const premiumAmounts = getAmountsForLiquidity( + sqrtPriceX96, + sqrtRatioAX96, + sqrtRatioBX96, + donations + ) + const feeAmounts = getAmountsForLiquidity(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, compouds) + + const totalLiquidity = new BigNumber(earning.strike.totalLiquidity.toString()) + const shares = new BigNumber(earning.shares.toString() ?? 0) + const totalShares = new BigNumber(earning.strike.totalShares.toString()) + const orangeShareRate = + shares.isZero() || totalShares.isZero() ? new BigNumber(0) : shares.dividedBy(totalShares) + const orangeLiquidity = totalLiquidity.multipliedBy(orangeShareRate).toFixed(0) + + const orangeAmounts = getAmountsForLiquidity( + sqrtPriceX96, + sqrtRatioAX96, + sqrtRatioBX96, + JSBI.BigInt(Number(orangeLiquidity)) + ) + + return { + tokenId: earning.strike.id, + fee: feeAmounts, + premium: premiumAmounts, + orange: orangeAmounts, + rate: shares.dividedBy(totalShares), + } + }) +} + +const convertAmountToETH = ( + amount0: typeof JSBI, + amount1: typeof JSBI, + token0: Token, + token1: Token, + ethPriceUSD: typeof BigNumber +) => { + const token0Decimal = 10 ** Number(token0.decimals) + const token1Decimal = 10 ** Number(token1.decimals) + + const decimalizeAmount0 = new BigNumber(amount0.toString()).div(token0Decimal) + const decimalizeAmount1 = new BigNumber(amount1.toString()).div(token1Decimal) + + const amount0ETH = decimalizeAmount0.times(token0.derivedETH) + const amount1ETH = decimalizeAmount1.times(token1.derivedETH) + const totalAmountETH = amount0ETH.plus(amount1ETH) + const totalAmountUSD = totalAmountETH.times(ethPriceUSD) + + return { + amount0: decimalizeAmount0, + amount1: decimalizeAmount1, + amount0ETH, + amount1ETH, + totalAmountETH, + totalAmountUSD, + } +} + +module.exports = { calculateAPR, getStrikeEarningAmounts } \ No newline at end of file diff --git a/src/adaptors/orange-finance/v1.ts b/src/adaptors/orange-finance/v1.ts new file mode 100644 index 0000000000..66f2902b3f --- /dev/null +++ b/src/adaptors/orange-finance/v1.ts @@ -0,0 +1,110 @@ +const utils = require('../utils'); +const { v1VaultAbi } = require('./abi'); +const { Web3 } = require('web3'); +const dayjs = require('dayjs'); +const duration = require('dayjs/plugin/duration'); +const { compact, isEmpty, last } = require('lodash'); + +dayjs.extend(duration); + +const RPC_URL = 'https://arb1.arbitrum.io/rpc'; +const APR_BASE_DAYS = 30; +const V1_VAULTS = [ + { + name: 'ETH-USDC.e', + address: '0xB9c5425084671221d7D5A547dBf1Bdcec26C8B7d', + yieldStart: 1689033600000, + showApy: true, + }, +]; +const web3 = new Web3(RPC_URL); + +const getAprFromActionEvents = async (address, yieldStart, block) => { + const v1Contract = new web3.eth.Contract(v1VaultAbi, address); + + const events = await v1Contract.getPastEvents('Action', { + filter: { actionType: [0] }, + fromBlock: block, + }); + + const tokenValueList = await Promise.all( + events.map(async (event) => { + const block = await web3.eth.getBlock(event.blockNumber); + const blockTime = dayjs.unix(block.timestamp); + + if (blockTime.valueOf() < yieldStart) { + return null; + } + const totalAssets = event.returnValues.totalAssets; + const totalSupply = event.returnValues.totalSupply; + const tokenValue = totalSupply !== 0 ? totalAssets / totalSupply : 0; + return { + timestamp: blockTime.valueOf(), + tokenValue, + }; + }) + ); + + const tokenValues = compact(tokenValueList); + const lastSnapshot = last(tokenValues); + const lastSnapshotTime = lastSnapshot?.timestamp ?? yieldStart; + const yearDays = dayjs.duration(1, 'years').asDays(); + + if (tokenValues.length >= APR_BASE_DAYS) { + const baseSnapshot = tokenValues[tokenValues.length - APR_BASE_DAYS]; + const gainValue = lastSnapshot.tokenValue - baseSnapshot.tokenValue; + return ( + (gainValue / baseSnapshot.tokenValue) * 100 * (yearDays / APR_BASE_DAYS) + ); + } else { + const period = dayjs + .duration(lastSnapshotTime - yieldStart, 'milliseconds') + .asDays(); + return lastSnapshot.tokenValue * (yearDays / period); + } +}; + +const getApy = async () => { + const totalDepositList = await Promise.all( + ['totalAssets', 'decimals', 'token0'].map((method) => + utils.makeMulticall( + v1VaultAbi.find(({ name }) => name === method), + V1_VAULTS.map(({ address }) => address), + 'arbitrum' + ) + ) + ); + + const startTimestamp = dayjs() + .subtract(APR_BASE_DAYS + 5, 'days') + .unix(); + const blocks = await utils.getBlocksByTime([startTimestamp], 'arbitrum'); + + const res = await Promise.all( + V1_VAULTS.map(async ({ name, address, yieldStart, showApy }, idx) => { + const apyBase = showApy + ? await getAprFromActionEvents(address, yieldStart, blocks[0]) + : 0; + const pool = { + pool: address, + chain: utils.formatChain('arbitrum'), + project: 'orange-finance', + symbol: name, + tvlUsd: + Number(totalDepositList[0][idx]) / 10 ** totalDepositList[1][idx], + apyBase, + underlyingTokens: [totalDepositList[2][idx]], + poolMeta: 'v1', + }; + return pool; + }) + ); + + return res; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://alpha.orangefinance.io', +}; diff --git a/src/adaptors/orbit-protocol/comptrollerAbi.json b/src/adaptors/orbit-protocol/comptrollerAbi.json new file mode 100644 index 0000000000..9de2585996 --- /dev/null +++ b/src/adaptors/orbit-protocol/comptrollerAbi.json @@ -0,0 +1,1352 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorOrbSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerOrb", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierOrb", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldOrbAccrued", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newOrbAccrued", + "type": "uint256" + } + ], + "name": "OrbAccruedAdjusted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "OrbBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "OrbGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldOrbReceivable", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newOrbReceivable", + "type": "uint256" + } + ], + "name": "OrbReceivableUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "OrbSupplySpeedUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract SpaceStationUpgradable", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "_grantOrb", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { "internalType": "bool", "name": "state", "type": "bool" } + ], + "name": "_setBorrowPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "contributor", "type": "address" }, + { "internalType": "uint256", "name": "compSpeed", "type": "uint256" } + ], + "name": "_setContributorOrbSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract OToken[]", + "name": "oTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract OToken", + "name": "oToken", + "type": "address" + }, + { "internalType": "bool", "name": "state", "type": "bool" } + ], + "name": "_setMintPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract OToken[]", + "name": "oTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "_setOrbSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], + "name": "_setSeizePaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newAddress", "type": "address" } + ], + "name": "_setTokenAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "state", "type": "bool" }], + "name": "_setTransferPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract OToken", "name": "oToken", "type": "address" } + ], + "name": "_supportMarket", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "accountAssets", + "outputs": [ + { "internalType": "contract OToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allMarkets", + "outputs": [ + { "internalType": "contract OToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "borrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowCaps", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "borrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "contract OToken", "name": "oToken", "type": "address" } + ], + "name": "checkMembership", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "holders", "type": "address[]" }, + { + "internalType": "contract OToken[]", + "name": "oTokens", + "type": "address[]" + }, + { "internalType": "bool", "name": "borrowers", "type": "bool" }, + { "internalType": "bool", "name": "suppliers", "type": "bool" } + ], + "name": "claimOrb", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "holder", "type": "address" }, + { + "internalType": "contract OToken[]", + "name": "oTokens", + "type": "address[]" + } + ], + "name": "claimOrb", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "holder", "type": "address" } + ], + "name": "claimOrb", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compAccrued", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compBorrowSpeeds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compBorrowState", + "outputs": [ + { "internalType": "uint224", "name": "index", "type": "uint224" }, + { "internalType": "uint32", "name": "block", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "compBorrowerIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compContributorSpeeds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compInitialIndex", + "outputs": [{ "internalType": "uint224", "name": "", "type": "uint224" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compReceivable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compSpeeds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "compSupplierIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compSupplySpeeds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "compSupplyState", + "outputs": [ + { "internalType": "uint224", "name": "index", "type": "uint224" }, + { "internalType": "uint32", "name": "block", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "oTokens", "type": "address[]" } + ], + "name": "enterMarkets", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oTokenAddress", "type": "address" } + ], + "name": "exitMarket", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "affectedUsers", + "type": "address[]" + }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" } + ], + "name": "fixBadAccruals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { "internalType": "contract OToken[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "getAssetsIn", + "outputs": [ + { "internalType": "contract OToken[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "oTokenModify", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTokenAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract OToken", "name": "oToken", "type": "address" } + ], + "name": "isDeprecated", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "lastContributorBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "oTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "liquidateBorrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "oTokenCollateral", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "oTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { "internalType": "bool", "name": "isListed", "type": "bool" }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { "internalType": "bool", "name": "isComped", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "mintAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "mintGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "mintTokens", "type": "uint256" } + ], + "name": "mintVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { "internalType": "contract PriceOracle", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposal65FixExecuted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "redeemAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "redeemVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "repayBorrowAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { "internalType": "uint256", "name": "borrowerIndex", "type": "uint256" } + ], + "name": "repayBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "oTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seizeAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "oTokenBorrowed", + "type": "address" + }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seizeVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "transferTokens", "type": "uint256" } + ], + "name": "transferAllowed", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "oToken", "type": "address" }, + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "transferTokens", "type": "uint256" } + ], + "name": "transferVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "contributor", "type": "address" } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/orbit-protocol/index.js b/src/adaptors/orbit-protocol/index.js new file mode 100644 index 0000000000..f98201c4e9 --- /dev/null +++ b/src/adaptors/orbit-protocol/index.js @@ -0,0 +1,219 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { ercDelegator } = require('../compound-v2/abi'); + +const comptrollerAbi = require('./comptrollerAbi.json'); + +const COMPTROLLER_ADDRESS = '0x1E18C3cb491D908241D0db14b081B51be7B6e652'; +const CHAIN = 'blast'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 2; +const PROJECT_NAME = 'orbit-protocol'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x4300000000000000000000000000000000000004'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const apy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplySpeeds = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowSpeeds = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplySpeeds[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowSpeeds[i] / 10 ** 18); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + underlyingTokens: [token], + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + debtCeilingUsd: (borrowCaps[i] / 1e18) * price, + }; + } + return poolReturned; + }); + + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.orbitlending.io/markets', +}; diff --git a/src/adaptors/orbitalswap/abis/lp.json b/src/adaptors/orbitalswap/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/orbitalswap/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/orbitalswap/abis/masterchef.json b/src/adaptors/orbitalswap/abis/masterchef.json new file mode 100644 index 0000000000..0a23cc03c5 --- /dev/null +++ b/src/adaptors/orbitalswap/abis/masterchef.json @@ -0,0 +1,1035 @@ +[ + { + "inputs": [ + { + "internalType": "contract OrbitalToken", + "name": "_orb", + "type": "address" + }, + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + }, + { + "internalType": "address", + "name": "_burnAdmin", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "name": "AddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "devaddr", + "type": "address" + } + ], + "name": "SetDev", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "boostContract", + "type": "address" + } + ], + "name": "UpdateBoostContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldMultiplier", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "UpdateBoostMultiplier", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "UpdateBurnAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "burnRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "regularFarmRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "specialFarmRate", + "type": "uint256" + } + ], + "name": "UpdateOrbRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accOrbPerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "name": "UpdateWhiteList", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "ACC_ORB_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BOOST_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MASTERCHEF_ORB_PER_BLOCK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BOOST_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ORB_RATE_TOTAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isRegular", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_startBlockNumber", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "boostContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "burnAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "burnOrb", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + } + ], + "name": "dev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devaddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getBoostMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastBurnedBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "orb", + "outputs": [ + { + "internalType": "contract OrbitalToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isRegular", + "type": "bool" + } + ], + "name": "orbPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "orbPerBlockToBurn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "orbRateToBurn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "orbRateToRegularFarm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "orbRateToSpecialFarm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingOrb", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "accOrbPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostedShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "pools", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalRegularAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSpecialAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newBoostContract", + "type": "address" + } + ], + "name": "updateBoostContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newMultiplier", + "type": "uint256" + } + ], + "name": "updateBoostMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newAdmin", + "type": "address" + } + ], + "name": "updateBurnAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_burnRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_regularFarmRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_specialFarmRate", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "updateOrbRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "accOrbPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostedShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "internalType": "struct MasterChef.PoolInfo", + "name": "pool", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isValid", + "type": "bool" + } + ], + "name": "updateWhiteList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "boostMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whiteList", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/orbitalswap/index.js b/src/adaptors/orbitalswap/index.js new file mode 100644 index 0000000000..d97b0c678a --- /dev/null +++ b/src/adaptors/orbitalswap/index.js @@ -0,0 +1,246 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const ORB_TOKEN = '0x42b98a2f73a282d731b0b8f4acfb6caf3565496b'; +const MASTERCHEF_ADDRESS = '0xd67a0CE4B1484DBa8dB53349F9b26a3272dB04F5'; +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = Math.floor((60 / BSC_BLOCK_TIME) * 60 * 24 * 365); +// exclude pool sigle token +const EXCLUDE = [ + '0xC446ca59C44F931Ac5b7e0F6a7424e654dB57876', + '0x3e4BdABF4a9dAbB4438C00A61558D9AC8a965FbB', +]; + +const getORBPriceBUSD = async () => { + const reservesRes = await sdk.api.abi.call({ + abi: lpABI.filter(({ name }) => name === 'getReserves')[0], + target: '0xE1a104f204c6063B06577d8A7E6C796058494e82', + chain: 'bsc', + }); + return reservesRes.output._reserve1 / reservesRes.output._reserve0; +}; + +const getPairInfo = async (pair, tokenAddress) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses) => { + const coins = addresses + .map((address) => `bsc:${address}`) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + ORBPerBlock, + ORBPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const ORBPerYear = BLOCKS_PER_YEAR * ORBPerBlock; + return ((poolWeight * ORBPerYear * ORBPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + abi: masterChefABI.find((e) => e.name === 'totalRegularAllocPoint'), + }); + const ORBPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'bsc', + params: [true], + abi: masterChefABI.find((e) => e.name === 'orbPerBlock'), + }); + const normalizedORBPerBlock = ORBPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + requery: true, + }); + const lpTokensRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'lpToken')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((_, index) => index > 1) + .filter((e) => e.allocPoint !== '0'); + const lpTokens = lpTokensRes.output + .map(({ output }) => output) + .filter((e) => !EXCLUDE.includes(e)); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'bsc', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const ORBPrice = await getORBPriceBUSD(); + tokensPrices[ORB_TOKEN.toLowerCase()] = ORBPrice; + const pairInfos = await Promise.all( + pools.map((pool, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]]) + ) + ); + + const poolsApy = []; + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedORBPerBlock, + ORBPrice, + masterChefReservesUsd + ); + + poolsApy.push({ + pool: lpTokens[i], + chain: utils.formatChain('binance'), + project: 'orbitalswap', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward: apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [ORB_TOKEN], + }); + } + + return poolsApy.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://orbitalswap.com/', +}; diff --git a/src/adaptors/orby-network/index.js b/src/adaptors/orby-network/index.js new file mode 100644 index 0000000000..c26c75052b --- /dev/null +++ b/src/adaptors/orby-network/index.js @@ -0,0 +1,133 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const TROVE_MANAGER_ADDRESS = '0x7A47cF15a1fCbAd09c66077d1D021430eed7AC65'; +const USC_ADDRESS = '0xD42E078ceA2bE8D03cd9dFEcC1f0d28915Edea78'; +const SUBGRAPH_URL = 'https://graph.cronoslabs.com/subgraphs/name/orby/orby'; +const URL = 'https://api.crypto.com/pos/v1/public/get-conversion-rate'; + +const query = gql` + query { + global(id: "only") { + currentSystemState { + price + } + } + } +`; + +const req = { + id: 1, + method: 'ptivate/get-conversion-rate', + params: { + instrument_name: 'CDCETH', + }, +}; + +const ABIS = { + getEntireSystemColl: { + inputs: [], + name: 'getEntireSystemColl', + outputs: [ + { + internalType: 'uint256', + name: 'entireSystemColl', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getMCR: { + inputs: [], + name: 'MCR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getBorrowFee: { + inputs: [], + name: 'getBorrowingRateWithDecay', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; +const main = async () => { + const troveEthTvl = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getEntireSystemColl, + chain: 'cronos', + }) + ).output; + + const mcr = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getMCR, + chain: 'cronos', + }) + ).output; + + const uscTotalSupply = ( + await sdk.api.abi.call({ + target: USC_ADDRESS, + abi: 'erc20:totalSupply', + chain: 'cronos', + }) + ).output; + + const borrowFee = ( + await sdk.api.abi.call({ + target: TROVE_MANAGER_ADDRESS, + abi: ABIS.getBorrowFee, + chain: 'cronos', + }) + ).output; + + const key = `cronos:${USC_ADDRESS}`.toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins; + + const conversionRate = (await superagent.post(URL, req)).body.result + .conversion_rate; + + const totalSupplyUsd = (Number(uscTotalSupply) / 1e18) * prices[key].price; + + const { global } = await request(SUBGRAPH_URL, query); + + return [ + { + pool: TROVE_MANAGER_ADDRESS, + project: 'orby-network', + symbol: 'CDCETH', + chain: 'cronos', + apyBase: Number(conversionRate) - 1, + apyReward: 0, + tvlUsd: + (Number(troveEthTvl) / 1e18) * Number(global.currentSystemState.price), + apyBaseBorrow: Number(borrowFee / 1e18) * 100, + apyRewardBorrow: 0, + totalSupplyUsd: + (Number(troveEthTvl) / 1e18) * Number(global.currentSystemState.price), + totalBorrowUsd: totalSupplyUsd, + ltv: 1 / (mcr / 1e18), + mintedCoin: 'USC', + underlyingTokens: ['0x7a7c9db510aB29A2FC362a4c34260BEcB5cE3446'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://orby.network/', +}; diff --git a/src/adaptors/orca-dex/index.ts b/src/adaptors/orca-dex/index.ts new file mode 100644 index 0000000000..36948acbe7 --- /dev/null +++ b/src/adaptors/orca-dex/index.ts @@ -0,0 +1,143 @@ +import * as utils from '../utils'; + +declare const require: any; +const axios = require('axios'); + +const ORCA_API_BASE_URL = 'https://api.orca.so/v2/solana/pools'; + +interface PublicWhirlpoolStatsWindow { + fees?: string | null; + rewards?: string | null; + volume?: string | null; +} + +interface PublicWhirlpoolStats { + '24h'?: PublicWhirlpoolStatsWindow; + '7d'?: PublicWhirlpoolStatsWindow; + [period: string]: PublicWhirlpoolStatsWindow | undefined; +} + +interface PublicToken { + address: string; + symbol?: string | null; +} + +interface WhirlpoolReward { + mint: string; + active: boolean; + emissionsPerSecond: string; // BigDecimal serialized as decimal string +} + +interface PublicWhirlpool { + address: string; + tvlUsdc: string | number | null; + stats?: PublicWhirlpoolStats; + tokenA: PublicToken; + tokenB: PublicToken; + rewards?: WhirlpoolReward[]; +} + +interface CursorMeta { + previous?: string | null; + next?: string | null; +} + +interface OrcaPoolsResponse { + data: PublicWhirlpool[]; + meta?: { + cursor?: CursorMeta | null; + } | null; +} + +const toNumber = (value: string | number | null | undefined): number => + value == null ? NaN : Number(value); + +const ratioOrNaN = (num: number, denom: number): number => + Number.isFinite(num) && Number.isFinite(denom) && denom > 0 ? num / denom : NaN; + +async function fetchAllPools(): Promise { + const pools: PublicWhirlpool[] = []; + let next: string | undefined; + + for (; ;) { + const params = next + ? { next } + : { + sortBy: 'tvl', + sortDirection: 'desc', + minTvl: 10000, + size: 1000, + stats: '24h,7d', + }; + + const response = await axios.get(ORCA_API_BASE_URL, { params }); + const { data, meta } = (response.data || {}) as OrcaPoolsResponse; + + if (!Array.isArray(data) || data.length === 0) break; + + pools.push(...data); + + const cursor = meta?.cursor?.next ?? null; + if (!cursor) break; + next = cursor; + } + + return pools; +} + +const getApy = async () => { + const pools = await fetchAllPools(); + + const mapped = pools.map((p) => { + const tvlUsd = toNumber(p.tvlUsdc); + + const stats = p.stats; + const stats24h = stats?.['24h']; + const stats7d = stats?.['7d']; + + const fees24h = toNumber(stats24h?.fees); + const rewards24h = toNumber(stats24h?.rewards); + const fees7d = toNumber(stats7d?.fees); + + const volumeUsd1d = toNumber(stats24h?.volume); + const volumeUsd7d = toNumber(stats7d?.volume); + + // Only compute APY when both numerator and denominator are finite and denom > 0. + // Otherwise APY becomes NaN and the pool will be filtered out by keepFinite. + const apyBase = ratioOrNaN(fees24h, tvlUsd) * 365 * 100; + const apyReward = ratioOrNaN(rewards24h, tvlUsd) * 365 * 100; + const apyBase7d = ratioOrNaN(fees7d, tvlUsd) * (365 / 7) * 100; + + const rewardTokens = + p.rewards + ?.filter((r) => { + if (!r || !r.active || !r.mint) return false; + const emissions = toNumber(r.emissionsPerSecond); + return Number.isFinite(emissions) && emissions > 0; + }) + .map((r) => r.mint) ?? []; + + const symbolA = p.tokenA.symbol ?? ''; + const symbolB = p.tokenB.symbol ?? ''; + + return { + pool: p.address, + chain: 'Solana', + project: 'orca-dex', + symbol: utils.formatSymbol(`${symbolA}-${symbolB}`), + underlyingTokens: [p.tokenA.address, p.tokenB.address], + rewardTokens, + tvlUsd, + apyBase, + apyReward, + apyBase7d, + volumeUsd1d, + volumeUsd7d, + url: `https://www.orca.so/pools/${p.address}`, + }; + }); + + return mapped.filter((p) => utils.keepFinite(p)); +}; + +export const apy = getApy; diff --git a/src/adaptors/origami-finance/index.js b/src/adaptors/origami-finance/index.js new file mode 100644 index 0000000000..166581b30f --- /dev/null +++ b/src/adaptors/origami-finance/index.js @@ -0,0 +1,123 @@ +const { request, gql } = require('graphql-request'); +const { + utils: { getAddress }, +} = require('ethers'); + +const GRAPH_URLS = { + ethereum: { + chainId: 1, + subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzm4q1q009c5np2angrczxw/subgraphs/origami-mainnet/prod/gn', + }, + arbitrum: { + chainId: 42161, + subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzm4q1q009c5np2angrczxw/subgraphs/origami-arbitrum/prod/gn', + }, + berachain: { + chainId: 80094, + subgraphUrl: 'https://api.goldsky.com/api/public/project_cmgzm4q1q009c5np2angrczxw/subgraphs/origami-berachain/prod/gn', + }, +} + +function getSubgraphQuery() { + const nowUnix = Math.floor(new Date().getTime() / 1000); + return gql` + { + vaults { + id + symbol + vaultKinds + underlyingTokens + latestMetrics: metrics( + where: { + metricsType: LATEST + } + ) { + vaultPriceBasedApr + totalTvlUSD + } + + averageMetrics: metrics( + where: { + metricsType_not: LATEST + } + ) { + yieldSpreadApr + } + + offchainPoints( + where: { + and: [ + { + or: [ + {end: "0"}, + {end_gte: "${nowUnix}"}, + ], + }, + { + or: [ + {start: "0"}, + {start_lte: "${nowUnix}"}, + ], + }, + ], + } + orderBy: sortWeight, + orderDirection: asc + ) { + averageMetrics: metrics( + where: { + metricsType_not: LATEST + } + ) { + apr + } + } + } + }`; +} + +function vaultApy(chain, chainId, vault) { + let isLeveraged = vault.vaultKinds.includes("Leverage"); + + let totalApr = 0; + if (isLeveraged) { + const totalPendleBasedAPr = vault.offchainPoints + .map(op => parseFloat(op.averageMetrics[0].apr)) + .reduce((total, apr) => total + apr, 0); + totalApr = (parseFloat(vault.averageMetrics[0].yieldSpreadApr) + totalPendleBasedAPr); + } else { + totalApr = vault.latestMetrics[0].vaultPriceBasedApr; + } + + const result = { + pool: `${vault.id}-${chain}`, + chain: chain, + project: 'origami-finance', + symbol: vault.symbol, + tvlUsd: parseFloat(vault.latestMetrics[0].totalTvlUSD), + apyBase: (Math.exp(totalApr / 100) - 1) * 100, + underlyingTokens: vault.underlyingTokens, + url: `https://origami.finance/vaults/${chainId}-${getAddress(vault.id)}/info`, + }; + return result; +} + +async function chainApy(chain, config, sgraphQuery) { + const chainResults = await request(config.subgraphUrl, sgraphQuery); + return chainResults.vaults.map(vault => vaultApy(chain, config.chainId, vault)); +} + +const apy = async () => { + const sgraphQuery = getSubgraphQuery(); + + const results = await Promise.all( + Object.keys(GRAPH_URLS).map(async (chainName) => await chainApy(chainName, GRAPH_URLS[chainName], sgraphQuery)) + ); + + return results.flat(); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/origin-arm/index.js b/src/adaptors/origin-arm/index.js new file mode 100644 index 0000000000..16dd8c6e3b --- /dev/null +++ b/src/adaptors/origin-arm/index.js @@ -0,0 +1,62 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const STETH_ADDRESS = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'; +const ARM_WETH_STETH_ADDRESS = '0x85b78aca6deae198fbf201c82daf6ca21942acc6'; + +const apy = async () => { + const priceData = await utils.getData( + 'https://coins.llama.fi/prices/current/coingecko:ethereum?searchWidth=4h' + ); + const ethPrice = priceData.coins['coingecko:ethereum'].price; + + const apyData = await utils.getData( + 'https://api.originprotocol.com/api/v2/arm-weth-steth/apr/trailing' + ); + + const [wethBalance, stethBalance, outstandingStethBalance] = + await Promise.all([ + sdk.api.abi.call({ + chain: 'ethereum', + target: WETH_ADDRESS, + abi: 'erc20:balanceOf', + params: [ARM_WETH_STETH_ADDRESS], + }), + sdk.api.abi.call({ + chain: 'ethereum', + target: STETH_ADDRESS, + abi: 'erc20:balanceOf', + params: [ARM_WETH_STETH_ADDRESS], + }), + sdk.api.abi.call({ + chain: 'ethereum', + target: ARM_WETH_STETH_ADDRESS, + abi: 'uint256:lidoWithdrawalQueueAmount', + }), + ]); + + const tvlUsd = + (wethBalance.output / 1e18 + + stethBalance.output / 1e18 + + outstandingStethBalance.output / 1e18) * + ethPrice; + + return [ + { + pool: ARM_WETH_STETH_ADDRESS, + chain: utils.formatChain('Ethereum'), + project: 'origin-arm', + symbol: 'ARM-WETH-stETH', + tvlUsd, + apy: Number(apyData.apy), + underlyingTokens: [WETH_ADDRESS, STETH_ADDRESS], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://originprotocol.com', +}; diff --git a/src/adaptors/origin-dollar/index.js b/src/adaptors/origin-dollar/index.js new file mode 100644 index 0000000000..b70e9dfb35 --- /dev/null +++ b/src/adaptors/origin-dollar/index.js @@ -0,0 +1,67 @@ +const axios = require('axios'); +const { gql, request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const OUSD = '0x2A8e1E676Ec238d8A992307B495b45B3fEAa5e86'; +const graphUrl = 'https://origin.squids.live/origin-squid/graphql'; + +const apy = async () => { + const query = gql` + query OTokenApy($chainId: Int!, $token: String!) { + oTokenApies( + limit: 1 + orderBy: timestamp_DESC + where: { chainId_eq: $chainId, otoken_containsInsensitive: $token } + ) { + apy7DayAvg + apy14DayAvg + apy30DayAvg + apr + apy + } + } + `; + + const variables = { + token: OUSD, + chainId: 1, + }; + + const apy = + (await request(graphUrl, query, variables)).oTokenApies[0].apy7DayAvg * 100; + + const totalSupply = + ( + await sdk.api.abi.call({ + target: OUSD, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const priceKey = `ethereum:${OUSD}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const ousd = { + pool: OUSD, + chain: 'Ethereum', + project: 'origin-dollar', + symbol: 'OUSD', + tvlUsd: totalSupply * price, + apy, + underlyingTokens: [ + '0xdac17f958d2ee523a2206206994597c13d831ec7', + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + '0x6b175474e89094c44da98b954eedeac495271d0f', + ], + url: 'https://originprotocol.eth.limo/#/ousd', + }; + + return [ousd]; +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/origin-ether/index.js b/src/adaptors/origin-ether/index.js new file mode 100644 index 0000000000..5532417b7c --- /dev/null +++ b/src/adaptors/origin-ether/index.js @@ -0,0 +1,121 @@ +const axios = require('axios'); +const { gql, request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const { capitalizeFirstLetter } = require('../utils'); + +const ETHEREUM_WETH_TOKEN = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const ETHEREUM_OETH_TOKEN = '0x856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc3'; +const BASE_WETH_TOKEN = '0x4200000000000000000000000000000000000006'; +const BASE_SUPER_OETH_TOKEN = '0xDBFeFD2e8460a6Ee4955A68582F85708BAEA60A3'; +const PLUME_WETH_TOKEN = '0xca59cA09E5602fAe8B629DeE83FfA819741f14be'; +const PLUME_SUPER_OETH_TOKEN = '0xFCbe50DbE43bF7E5C88C6F6Fb9ef432D4165406E'; + +const oethVaultAddress = '0x39254033945AA2E4809Cc2977E7087BEE48bd7Ab'; +const superOETHbVaultAddress = '0x98a0CbeF61bD2D21435f433bE4CD42B56B38CC93'; +const superOETHpVaultAddress = '0xc8c8F8bEA5631A8AF26440AF32a55002138cB76a'; + +const graphUrl = 'https://origin.squids.live/origin-squid/graphql'; + +const vaultABI = { + inputs: [], + name: 'totalValue', + outputs: [{ internalType: 'uint256', name: 'value', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +const fetchPoolData = async ({ + chain, + vaultAddress, + token, + symbol, + project, + underlyingToken, + chainId, +}) => { + const query = gql` + query OTokenApy($chainId: Int!, $token: String!) { + oTokenApies( + limit: 1 + orderBy: timestamp_DESC + where: { chainId_eq: $chainId, otoken_containsInsensitive: $token } + ) { + apy7DayAvg + } + } + `; + + const variables = { + token, + chainId, + }; + + const apyData = await request(graphUrl, query, variables); + const apy = apyData.oTokenApies[0]?.apy7DayAvg * 100; + + const totalValueEth = ( + await sdk.api.abi.call({ + chain, + target: vaultAddress, + abi: vaultABI, + }) + ).output; + + const ethPriceKey = `ethereum:${ETHEREUM_WETH_TOKEN}`; + const ethPriceRes = await axios.get( + `https://coins.llama.fi/prices/current/${ethPriceKey}` + ); + const ethPrice = ethPriceRes.data.coins[ethPriceKey].price; + + const tvlUsd = (totalValueEth / 1e18) * ethPrice; + + return { + pool: token, + chain: capitalizeFirstLetter(chain), + project, + symbol, + tvlUsd, + apy, + underlyingTokens: [underlyingToken], + }; +}; + +const apy = async () => { + const pools = await Promise.allSettled([ + fetchPoolData({ + chain: 'ethereum', + chainId: 1, + vaultAddress: oethVaultAddress, + token: ETHEREUM_OETH_TOKEN, + symbol: 'OETH', + project: 'origin-ether', + underlyingToken: ETHEREUM_WETH_TOKEN, + }), + fetchPoolData({ + chain: 'base', + chainId: 8453, + vaultAddress: superOETHbVaultAddress, + token: BASE_SUPER_OETH_TOKEN, + symbol: 'superOETHb', + project: 'origin-ether', + underlyingToken: BASE_WETH_TOKEN, + }), + fetchPoolData({ + chain: 'plume_mainnet', + chainId: 98866, + vaultAddress: superOETHpVaultAddress, + token: PLUME_SUPER_OETH_TOKEN, + symbol: 'superOETHp', + project: 'origin-ether', + underlyingToken: PLUME_WETH_TOKEN, + }), + ]); + return pools.filter((i) => i.status === 'fulfilled').map((i) => i.value); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://originprotocol.com', +}; diff --git a/src/adaptors/origin-sonic/index.js b/src/adaptors/origin-sonic/index.js new file mode 100644 index 0000000000..7b4b10458b --- /dev/null +++ b/src/adaptors/origin-sonic/index.js @@ -0,0 +1,65 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const WRAPPED_ORIGIN_SONIC = '0x9F0dF7799f6FDAd409300080cfF680f5A23df4b1'; +const ORIGIN_SONIC = '0xb1e25689d55734fd3fffc939c4c3eb52dff8a794'; +const SONIC = '0x0000000000000000000000000000000000000000'; +const project = 'origin-sonic'; +const symbol = 'OS'; +const exchangeRateAbi = 'function convertToAssets(uint256 shares) view returns (uint256 assets)'; + +const apy = async () => { + const tvl = (await sdk.api.erc20.totalSupply({ target: ORIGIN_SONIC, chain: 'sonic' })).output / 1e18; + + const priceKey = `sonic:${SONIC}`; + const sonicPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const timestampNow = Math.floor(Date.now() / 1000); + const timestampYesterday = timestampNow - 86400; + + const blockNow = ( + await axios.get(`https://coins.llama.fi/block/sonic/${timestampNow}`) + ).data.height; + + const blockYesterday = ( + await axios.get( + `https://coins.llama.fi/block/sonic/${timestampYesterday}` + ) + ).data.height; + + const exchangeRateYesterday = await sdk.api.abi.call({ + target: WRAPPED_ORIGIN_SONIC, + chain: 'sonic', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockYesterday, + }); + + const exchangeRateToday = await sdk.api.abi.call({ + target: WRAPPED_ORIGIN_SONIC, + chain: 'sonic', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockNow, + }); + + const apr = + ((exchangeRateToday.output - exchangeRateYesterday.output) / + exchangeRateYesterday.output) * 365 * 100; + + return [ + { + pool: `${ORIGIN_SONIC}`, + chain: 'sonic', + project, + symbol, + underlyingTokens: [SONIC], + apyBase: apr, + tvlUsd: (tvl * sonicPrice), + }, + ]; +}; + +module.exports = { apy, url: 'https://www.originprotocol.com/os' }; diff --git a/src/adaptors/osmosis-dex/index.js b/src/adaptors/osmosis-dex/index.js new file mode 100644 index 0000000000..5872e0aa05 --- /dev/null +++ b/src/adaptors/osmosis-dex/index.js @@ -0,0 +1,47 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const apy = async () => { + const tvlData = await utils.getData( + 'https://data.osmosis.zone/pairs/v2/summary' + ); + + const aprData = await axios.get('https://osmosis.numia.xyz/pools_apr_range', { + headers: { + Authorization: `Bearer ${process.env.OSMOSIS_API_KEY}`, + 'Content-Type': 'application/json', + }, + }); + + const data = tvlData.data.map((pool) => { + const symbol = `${pool.base_symbol}-${pool.quote_symbol}`; + + if (symbol.includes(undefined)) return null; + + const apr = aprData.data.find((i) => i.pool_id === pool.pool_id); + if (!apr) return null; + const apyBase = apr.swap_fees.lower; + + return { + pool: `osmosis-${pool.pool_id}`, + chain: 'Osmosis', + project: 'osmosis-dex', + symbol: utils.formatSymbol(symbol), + tvlUsd: pool.liquidity, + apyBase, + apyBase7d: apyBase, + volumeUsd1d: pool.volume_24h, + volumeUsd7d: pool.volume_7d, + url: `https://app.osmosis.zone/pool/${pool.pool_id}`, + poolMeta: `#${pool.pool_id}`, + }; + }); + + return utils.removeDuplicates( + data.filter((p) => p && utils.keepFinite(p) && p.tvlUsd < 50e6) + ); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/osmosis/index.js b/src/adaptors/osmosis/index.js deleted file mode 100644 index 9ce6f7ace3..0000000000 --- a/src/adaptors/osmosis/index.js +++ /dev/null @@ -1,62 +0,0 @@ -const utils = require('../utils'); - -const buildPool = (entry, chainString) => { - const poolSplit = entry.denom.split('/'); - const pool = poolSplit.length > 1 ? poolSplit[1] : poolSplit[0]; - - const newObj = { - pool: `${pool}-${entry.symbol}-${entry.duration}`, - chain: utils.formatChain(chainString), - project: 'osmosis', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.liquidity, - apy: entry.apr, - market: entry.duration, - }; - - return newObj; -}; - -const topLvl = async (chainString) => { - const tvl = await utils.getData( - 'https://api-osmosis.imperator.co/pools/v2/all?low_liquidity=false' - ); - const apr = await utils.getData( - 'https://api-osmosis.imperator.co/apr/v2/all' - ); - - let data = []; - for (const poolId of Object.keys(tvl)) { - const pos = tvl[poolId]; - const symbol = `${pos[0].symbol}-${pos[1].symbol}`; - - const x = pos[0]; - x.poolId = poolId; - x.symbol = symbol; - aprs = apr - .find((x) => String(x.pool_id) === poolId) - ?.apr_list.find((el) => el.symbol === 'OSMO'); - - // add all 3 apy durations - for (const d of [1, 7, 14]) { - const y = { ...x }; - y.apr = aprs?.[`apr_${d}d`]; - y.duration = `${d}day`; - data.push(y); - } - } - - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async () => { - const data = await topLvl('osmosis'); - return data; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/oswap-amm/index.js b/src/adaptors/oswap-amm/index.js new file mode 100644 index 0000000000..58992e20d7 --- /dev/null +++ b/src/adaptors/oswap-amm/index.js @@ -0,0 +1,44 @@ +const utils = require('../utils'); + +const OSWAP_STATS_ENDPOINT = 'https://v2-stats.oswap.io/api/v1'; +const LIQUIDITY_PROVIDER_ENDPOINT = 'https://liquidity.obyte.org'; +const OSWAP_TOKEN_ENDPOINT = 'https://token.oswap.io/api'; //@see https://token.oswap.io/farming/all + +const COMMON_DATA = { chain: 'Obyte', project: 'oswap-amm' }; + +const poolsFunction = async () => { + const poolsData = await utils.getData(`${OSWAP_STATS_ENDPOINT}/yield`); + + const apyRewards = await utils.getData( + `${LIQUIDITY_PROVIDER_ENDPOINT}/mining-apy` + ); + + const farmingPoolsAPY = await utils.getData(`${OSWAP_TOKEN_ENDPOINT}/lp_apy`)?.then((data) => data?.data); + + return poolsData + .map(({ address, pool, apyBase, ...rest }) => { + const farmingAPY = +(farmingPoolsAPY.find((pool) => address === pool.address)?.apy || 0); + let apyReward = apyRewards[address] || null; + + if (!apyReward || farmingAPY && (farmingAPY > apyReward)) { + apyReward = farmingAPY; + } + + return ({ + url: `https://oswap.io/#/swap/${address}`, + apyReward, + apyBase, + rewardTokens: ['GBYTE'], + pool: `${address}-obyte`.toLowerCase(), + ...rest, + ...COMMON_DATA, + }) + }) + .filter(({ apyBase }) => apyBase !== null) + .filter((p) => p.symbol !== 'O-GBYTE-WBTC-WBTC'); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/ottopia/index.js b/src/adaptors/ottopia/index.js new file mode 100644 index 0000000000..cc44f98d88 --- /dev/null +++ b/src/adaptors/ottopia/index.js @@ -0,0 +1,81 @@ +const sdk = require('@defillama/sdk'); +const retry = require('async-retry'); +const utils = require('../utils'); +const { GraphQLClient, gql } = require('graphql-request'); + +async function tvl(timestamp) { + let endpoint = sdk.graph.modifyEndpoint('CejrrsnSQAxHJBpkgiBrLHQZ7h2MkK9QArM8bJvN9GuQ'); + let graphQLClient = new GraphQLClient(endpoint); + let query = gql` + query apy($start: BigInt!, $end: BigInt!) { + pearlBankMetrics( + where: { timestamp_gte: $start, timestamp_lt: $end } + orderBy: timestamp + orderDirection: desc + first: 1 + ) { + apy + pearlBankDepositedUsdValue + clamPondDepositedUsdValue + } + } + `; + let latestMetricsQuery = gql` + query apy { + pearlBankMetrics(orderBy: timestamp, orderDirection: desc, first: 1) { + apy + pearlBankDepositedUsdValue + clamPondDepositedUsdValue + } + } + `; + + //if invalid timestamp is passed, + //return the most recent available values + const results = + timestamp == null + ? await graphQLClient.request(latestMetricsQuery) + : await graphQLClient.request(query, { + start: timestamp - 2 * 60 * 60 * 1000, + end: timestamp, + }); + return [ + //CLAM+ / Clam Pond + { + pool: '0xF2A8705D327534E334d09BC28e5C97b5c356Aa01', + tvlUsd: parseFloat( + results?.pearlBankMetrics?.[0].clamPondDepositedUsdValue + ), + apy: parseFloat(results?.pearlBankMetrics?.[0].apy), + project: 'ottopia', + symbol: 'CLAM+', + chain: utils.formatChain('polygon'), + rewardTokens: ['0xF2A8705D327534E334d09BC28e5C97b5c356Aa01'], //CLAM+ + underlyingTokens: ['0xF2A8705D327534E334d09BC28e5C97b5c356Aa01'], //CLAM+ + }, + //PEARL / Pearl Bank + { + pool: '0x845EB7730a8D37e8D190Fb8bb9c582038331B48a', + tvlUsd: parseFloat( + results?.pearlBankMetrics?.[0].pearlBankDepositedUsdValue + ), + apy: parseFloat(results?.pearlBankMetrics?.[0].apy), + project: 'ottopia', + symbol: 'PEARL', + chain: utils.formatChain('polygon'), + rewardTokens: ['0x236eec6359fb44cce8f97e99387aa7f8cd5cde1f'], //USD+ + underlyingTokens: ['0x845EB7730a8D37e8D190Fb8bb9c582038331B48a'], //PEARL + }, + ]; +} + +const main = async (timestamp = null) => { + const data = await Promise.all([tvl(timestamp)]); + return data.flat(); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://ottopia.app/', +}; diff --git a/src/adaptors/overnight-finance/index.js b/src/adaptors/overnight-finance/index.js new file mode 100644 index 0000000000..0e02972cd9 --- /dev/null +++ b/src/adaptors/overnight-finance/index.js @@ -0,0 +1,115 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const { ethers } = require('ethers'); + +const xUSD = '0xe80772Eaf6e2E18B651F160Bc9158b2A5caFCA65'; + +const eventAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'profit', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'excessProfit', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'insurancePremium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'insuranceLoss', + type: 'uint256', + }, + ], + name: 'PayoutEvent', + type: 'event', + }, +]; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: xUSD, + abi: 'erc20:totalSupply', + chain: 'arbitrum', + }) + ).output / 1e6; + + const priceKey = `arbitrum:${xUSD}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const tvlUsd = totalSupply * price; + + const currentBlock = await sdk.api.util.getLatestBlock('arbitrum'); + const toBlock = currentBlock.number; + const topic = + '0x8dd3783ac3ed2cabfce0fa4347c2cab93b8273171a7e30b28a83147b099c4038'; + const logs = ( + await sdk.api.util.getLogs({ + target: '0x73cb180bf0521828d8849bc8CF2B920918e23032', + topic: '', + toBlock, + fromBlock: 63102109, + keys: [], + topics: [topic], + chain: 'arbitrum', + }) + ).output.sort((a, b) => b.blockNumber - a.blockNumber); + + const elapsedTime = + (await sdk.api.util.getTimestamp(logs[0].blockNumber, 'arbitrum')) - + (await sdk.api.util.getTimestamp(logs[1].blockNumber, 'arbitrum')); + + const iface = new ethers.utils.Interface(eventAbi); + const decoded = iface.parseLog(logs[0]); + const rewardsReceived = parseInt(decoded.args.profit / 1e6); + // daily compounding + const apyBase = calcApy(rewardsReceived, tvlUsd, elapsedTime); + return [ + { + pool: xUSD, + symbol: 'xUSD', + project: 'overnight-finance', + chain: 'arbitrum', + tvlUsd, + apyBase, + }, + ]; +}; + +function calcApy(profit, totalSupply, elapsedTime) { + if (profit == 0) { + return 0; + } + const hourlyRate = (profit / totalSupply / elapsedTime) * 3600; + const dailyRate = hourlyRate * 24; + const apy = (dailyRate + 1) ** 365 - 1; + return apy * 100; +} + +module.exports = { + apy, + url: 'https://app.overnight.fi/', +}; diff --git a/src/adaptors/oxium/index.js b/src/adaptors/oxium/index.js new file mode 100644 index 0000000000..710b523911 --- /dev/null +++ b/src/adaptors/oxium/index.js @@ -0,0 +1,42 @@ +const utils = require('../utils'); + +const CHAIN_MAPPING = { + 1329: 'Sei', +}; + +const TOKEN_ADDRESSES = { + 1329: { + 'wsei': '0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7', + }, +}; + +const poolsFunction = async () => { + const vaultsData = await utils.getData( + 'https://api.mgvinfra.com/registry/whitelist?chainId=1329&version=2' + ); + + const pools = vaultsData.map(vault => { + const wseiAddress = TOKEN_ADDRESSES[vault.chainId]?.wsei; + return { + pool: `${vault.address}-${CHAIN_MAPPING[vault.chainId] || vault.chainId}`.toLowerCase(), + chain: utils.formatChain(CHAIN_MAPPING[vault.chainId] || 'Sei'), + project: 'oxium', + symbol: utils.formatSymbol(`${vault.market.base.symbol}-${vault.market.quote.symbol}`), + tvlUsd: vault.snapshot.TVL.total || 0, + apyBase: (vault.snapshot.base?.total || 0) + (vault.snapshot.strategy?.total || 0), + apyReward: vault.snapshot.rewards?.total || 0, + rewardTokens: vault.snapshot.rewards?.total > 0 ? [wseiAddress] : undefined, + underlyingTokens: [vault.market.base.address, vault.market.quote.address], + poolMeta: `${vault.strategyType} - ${vault.manager}`, + url: `https://app.oxium.xyz/earn/${vault.address}` + }; + }); + + return pools.filter(pool => pool.tvlUsd >= 10000); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.oxium.xyz/earn', +}; \ No newline at end of file diff --git a/src/adaptors/pac-finance/index.js b/src/adaptors/pac-finance/index.js new file mode 100644 index 0000000000..53fed95399 --- /dev/null +++ b/src/adaptors/pac-finance/index.js @@ -0,0 +1,124 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const chain = 'blast'; +// PoolDataProvider +const target = '0x742316f430002D067dC273469236D0F3670bE446'; + +const apy = async () => { + const reserveTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimalsEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'decimals'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const pricesEthereum = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens + .map((pool, i) => { + const p = poolsReserveData[i]; + const price = pricesEthereum[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupply[i]; + const totalSupplyUsd = + (supply / 10 ** underlyingDecimalsEthereum[i]) * price; + + const currentSupply = underlyingBalances[i]; + const tvlUsd = + (currentSupply / 10 ** underlyingDecimalsEthereum[i]) * price; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + chain, + project: 'pac-finance', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd: totalSupplyUsd - tvlUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + }; + }) + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.kinza.finance/', +}; diff --git a/src/adaptors/package-lock.json b/src/adaptors/package-lock.json new file mode 100644 index 0000000000..7863dc8430 --- /dev/null +++ b/src/adaptors/package-lock.json @@ -0,0 +1,11583 @@ +{ + "name": "defillama-apy-adapters", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "defillama-apy-adapters", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@blend-capital/blend-sdk": "3.0.1", + "@defillama/sdk": "^5.0.112", + "@stacks/network": "^6.13.0", + "@stacks/transactions": "^6.15.0", + "@ton/ton": "14.0.0", + "@types/jest": "^28.1.6", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/v3-sdk": "^3.13.0", + "async-retry": "^1.3.3", + "axios": "^1.7.2", + "bignumber.js": "^9.1.1", + "csv-writer": "^1.6.0", + "date-fns": "^2.23.0", + "dotenv": "^10.0.0", + "ethers": "^5.7.2", + "graphql": "^15.5.1", + "graphql-request": "^3.5.0", + "limiter": "^2.1.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.1", + "superagent": "^6.1.0", + "web3": "^4.9.0" + }, + "devDependencies": { + "jest": "^28.1.3", + "prettier": "^2.2.1", + "ts-node": "^10.9.1" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/crc32c": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", + "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32c/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", + "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.596.0.tgz", + "integrity": "sha512-W5C85cEUTYbmCpvvhLye+KirtLcBMX4t0l4Zj3EsGc5tTwkp7lxZDmJEoDfRy0+FE2H/O6OZQJdWMXCwt/Inqw==", + "dependencies": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-bucket-endpoint": "3.587.0", + "@aws-sdk/middleware-expect-continue": "3.577.0", + "@aws-sdk/middleware-flexible-checksums": "3.587.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-location-constraint": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-sdk-s3": "3.587.0", + "@aws-sdk/middleware-signing": "3.587.0", + "@aws-sdk/middleware-ssec": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/signature-v4-multi-region": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@aws-sdk/xml-builder": "3.575.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/eventstream-serde-browser": "^3.0.0", + "@smithy/eventstream-serde-config-resolver": "^3.0.0", + "@smithy/eventstream-serde-node": "^3.0.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-blob-browser": "^3.0.0", + "@smithy/hash-node": "^3.0.0", + "@smithy/hash-stream-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/md5-js": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.592.0.tgz", + "integrity": "sha512-w+SuW47jQqvOC7fonyjFjsOh3yjqJ+VpWdVrmrl0E/KryBE7ho/Wn991Buf/EiHHeJikoWgHsAIPkBH29+ntdA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.596.0.tgz", + "integrity": "sha512-KnTWtKzO0N+rMdIrVwbewFp4FAvVWBV/ekCAh5w7EN+uAvBHxMoFElE2RwlcRF/gH1/F715OspPMvOxPom6bMA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.596.0.tgz", + "integrity": "sha512-37+WQDjgmqS/YXj3vPzIVIrbXaFcZ1WXk715AMGIPBZn9Y2/wr2bmSTpX7bsMyn0G8+LxmoIxFcG7n1Gu0nvLg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sso-oidc": "3.596.0", + "@aws-sdk/core": "3.592.0", + "@aws-sdk/credential-provider-node": "3.596.0", + "@aws-sdk/middleware-host-header": "3.577.0", + "@aws-sdk/middleware-logger": "3.577.0", + "@aws-sdk/middleware-recursion-detection": "3.577.0", + "@aws-sdk/middleware-user-agent": "3.587.0", + "@aws-sdk/region-config-resolver": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@aws-sdk/util-user-agent-browser": "3.577.0", + "@aws-sdk/util-user-agent-node": "3.587.0", + "@smithy/config-resolver": "^3.0.1", + "@smithy/core": "^2.2.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/hash-node": "^3.0.0", + "@smithy/invalid-dependency": "^3.0.0", + "@smithy/middleware-content-length": "^3.0.0", + "@smithy/middleware-endpoint": "^3.0.1", + "@smithy/middleware-retry": "^3.0.3", + "@smithy/middleware-serde": "^3.0.0", + "@smithy/middleware-stack": "^3.0.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/url-parser": "^3.0.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.3", + "@smithy/util-defaults-mode-node": "^3.0.3", + "@smithy/util-endpoints": "^2.0.1", + "@smithy/util-middleware": "^3.0.0", + "@smithy/util-retry": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.592.0.tgz", + "integrity": "sha512-gLPMXR/HXDP+9gXAt58t7gaMTvRts9i6Q7NMISpkGF54wehskl5WGrbdtHJFylrlJ5BQo3XVY6i661o+EuR1wg==", + "dependencies": { + "@smithy/core": "^2.2.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.587.0.tgz", + "integrity": "sha512-Hyg/5KFECIk2k5o8wnVEiniV86yVkhn5kzITUydmNGCkXdBFHMHRx6hleQ1bqwJHbBskyu8nbYamzcwymmGwmw==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.596.0.tgz", + "integrity": "sha512-nnmvEsz1KJgRmfSZJPWuzbxPRXu8Y+/78Ifa1jY3fQKSKdEJfXMDsjPljJvMDBl4dZ8pf5Hwx+S/ONnMEDwYEA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/fetch-http-handler": "^3.0.1", + "@smithy/node-http-handler": "^3.0.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/util-stream": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.596.0.tgz", + "integrity": "sha512-c7PLtd7GbnOVAc5sk3sVlHxLvEsM8RF96rsBGlRo4AVpil/lXLKyNv9VarS4w/ZZZoRbJRyZ+m92PjNcLvpTDQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.587.0", + "@aws-sdk/credential-provider-http": "3.596.0", + "@aws-sdk/credential-provider-process": "3.587.0", + "@aws-sdk/credential-provider-sso": "3.592.0", + "@aws-sdk/credential-provider-web-identity": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/credential-provider-imds": "^3.1.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.596.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.596.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.596.0.tgz", + "integrity": "sha512-F4MLyXpQyie1AnJS9n7TIRL0aF7YH8tKMIJXDsM5OXpSZi2en+yR6SzsxvHf5dwS2Ga8LUdEJyiyS2NoebaJGA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.587.0", + "@aws-sdk/credential-provider-http": "3.596.0", + "@aws-sdk/credential-provider-ini": "3.596.0", + "@aws-sdk/credential-provider-process": "3.587.0", + "@aws-sdk/credential-provider-sso": "3.592.0", + "@aws-sdk/credential-provider-web-identity": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/credential-provider-imds": "^3.1.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.587.0.tgz", + "integrity": "sha512-V4xT3iCqkF8uL6QC4gqBJg/2asd/damswP1h9HCfqTllmPWzImS+8WD3VjgTLw5b0KbTy+ZdUhKc0wDnyzkzxg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.592.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.592.0.tgz", + "integrity": "sha512-fYFzAdDHKHvhtufPPtrLdSv8lO6GuW3em6n3erM5uFdpGytNpjXvr3XGokIsuXcNkETAY/Xihg+G9ksNE8WJxQ==", + "dependencies": { + "@aws-sdk/client-sso": "3.592.0", + "@aws-sdk/token-providers": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.587.0.tgz", + "integrity": "sha512-XqIx/I2PG7kyuw3WjAP9wKlxy8IvFJwB8asOFT1xPFoVfZYKIogjG9oLP5YiRtfvDkWIztHmg5MlVv3HdJDGRw==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.587.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.587.0.tgz", + "integrity": "sha512-HkFXLPl8pr6BH/Q0JpOESqEKL0ZK3sk7aSZ1S6GE4RXET7H5R94THULXqQFZzD48gZcyFooO/yNKZTqrZFaWKg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.577.0.tgz", + "integrity": "sha512-6dPp8Tv4F0of4un5IAyG6q++GrRrNQQ4P2NAMB1W0VO4JoEu1C8GievbbDLi88TFIFmtKpnHB0ODCzwnoe8JsA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.587.0.tgz", + "integrity": "sha512-URMwp/budDvKhIvZ4a6zIBfFTun/iDlPWXqsGKYjEtHt8jz27OSjCZtDtIeqW4WTBdKL8KZgQcl+DdaE5M1qiQ==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", + "@aws-sdk/types": "3.577.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.577.0.tgz", + "integrity": "sha512-9ca5MJz455CODIVXs0/sWmJm7t3QO4EUa1zf8pE8grLpzf0J94bz/skDWm37Pli13T3WaAQBHCTiH2gUVfCsWg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.577.0.tgz", + "integrity": "sha512-DKPTD2D2s+t2QUo/IXYtVa/6Un8GZ+phSTBkyBNx2kfZz4Kwavhl/JJzSqTV3GfCXkVdFu7CrjoX7BZ6qWeTUA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.577.0.tgz", + "integrity": "sha512-aPFGpGjTZcJYk+24bg7jT4XdIp42mFXSuPt49lw5KygefLyJM/sB0bKKqPYYivW0rcuZ9brQ58eZUNthrzYAvg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.577.0.tgz", + "integrity": "sha512-pn3ZVEd2iobKJlR3H+bDilHjgRnNrQ6HMmK9ZzZw89Ckn3Dcbv48xOv4RJvu0aU8SDLl/SNCxppKjeLDTPGBNA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.587.0.tgz", + "integrity": "sha512-vtXTGEiw1E9Fax4LmcU2Z208gbrC8ShrdsSLmGcRPpu5NPOGBFBSDG5sy5EDNClrFxIl/Le8coQnD0EDBtx+uQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-arn-parser": "3.568.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/smithy-client": "^3.1.1", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.587.0.tgz", + "integrity": "sha512-tiZaTDj4RvhXGRAlncFn7CSEfL3iNPO67WSaxAq+Ls5j1VgczPhu5262cWONNoMgth3nXR1hhLC4ITSl/a6AzA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/types": "^3.0.0", + "@smithy/util-middleware": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.577.0.tgz", + "integrity": "sha512-i2BPJR+rp8xmRVIGc0h1kDRFcM2J9GnClqqpc+NLSjmYadlcg4mPklisz9HzwFVcRPJ5XcGf3U4BYs5G8+iTyg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.587.0.tgz", + "integrity": "sha512-SyDomN+IOrygLucziG7/nOHkjUXES5oH5T7p8AboO8oakMQJdnudNXiYWTicQWO52R51U6CR27rcMPTGeMedYA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@aws-sdk/util-endpoints": "3.587.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.587.0.tgz", + "integrity": "sha512-93I7IPZtulZQoRK+O20IJ4a1syWwYPzoO2gc3v+/GNZflZPV3QJXuVbIm0pxBsu0n/mzKGUKqSOLPIaN098HcQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.587.0.tgz", + "integrity": "sha512-TR9+ZSjdXvXUz54ayHcCihhcvxI9W7102J1OK6MrLgBlPE7uRhAx42BR9L5lLJ86Xj3LuqPWf//o9d/zR9WVIg==", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.587.0", + "@aws-sdk/types": "3.577.0", + "@smithy/protocol-http": "^4.0.0", + "@smithy/signature-v4": "^3.0.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.587.0.tgz", + "integrity": "sha512-ULqhbnLy1hmJNRcukANBWJmum3BbjXnurLPSFXoGdV0llXYlG55SzIla2VYqdveQEEjmsBuTZdFvXAtNpmS5Zg==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/property-provider": "^3.1.0", + "@smithy/shared-ini-file-loader": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.587.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.577.0.tgz", + "integrity": "sha512-FT2JZES3wBKN/alfmhlo+3ZOq/XJ0C7QOZcDNrpKjB0kqYoKjhVKZ/Hx6ArR0czkKfHzBBEs6y40ebIHx2nSmA==", + "dependencies": { + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", + "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.587.0.tgz", + "integrity": "sha512-8I1HG6Em8wQWqKcRW6m358mqebRVNpL8XrrEoT4In7xqkKkmYtHRNVYP6lcmiQh5pZ/c/FXu8dSchuFIWyEtqQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "@smithy/util-endpoints": "^2.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", + "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.577.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.577.0.tgz", + "integrity": "sha512-zEAzHgR6HWpZOH7xFgeJLc6/CzMcx4nxeQolZxVZoB5pPaJd3CjyRhZN0xXeZB0XIRCWmb4yJBgyiugXLNMkLA==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/types": "^3.0.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.587.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.587.0.tgz", + "integrity": "sha512-Pnl+DUe/bvnbEEDHP3iVJrOtE3HbFJBPgsD6vJ+ml/+IYk1Eq49jEG+EHZdNTPz3SDG0kbp2+7u41MKYJHR/iQ==", + "dependencies": { + "@aws-sdk/types": "3.577.0", + "@smithy/node-config-provider": "^3.1.0", + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.575.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.575.0.tgz", + "integrity": "sha512-cWgAwmbFYNCFzPwxL705+lWps0F3ZvOckufd2KKoEZUmtpVw9/txUXNrPySUXSmRTSRhoatIMABNfStWR043bQ==", + "dependencies": { + "@smithy/types": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@blend-capital/blend-sdk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@blend-capital/blend-sdk/-/blend-sdk-3.0.1.tgz", + "integrity": "sha512-jqIcvVof0MY3x9+M8FJU9xcYRDeASRGSXrrS2OrSBvmfFvJ5DJ/tkHr0o19pn9Z0aWO98WrriscRQFy2NKmSBg==", + "dependencies": { + "@stellar/stellar-sdk": "13.2.0", + "buffer": "6.0.3", + "follow-redirects": ">=1.15.6" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@defillama/sdk": { + "version": "5.0.172", + "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.172.tgz", + "integrity": "sha512-0ICEIle3TvV8DNMytrssNRnjFKwLgK54hpypsCrgEGZ4O+f6U4fq7D09M9kJmfk44XTCVgEUWFWnQX4ODVogiA==", + "license": "ISC", + "dependencies": { + "@aws-sdk/client-s3": "^3.400.0", + "@elastic/elasticsearch": "^8.13.1", + "@supercharge/promise-pool": "^2.1.0", + "axios": "^1.6.5", + "ethers": "^6.0.0", + "p-limit": "^3.0.0", + "tron-format-address": "^0.1.11" + } + }, + "node_modules/@defillama/sdk/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/@defillama/sdk/node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/@defillama/sdk/node_modules/ethers": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.0.tgz", + "integrity": "sha512-+yyQQQWEntY5UVbCv++guA14RRVFm1rSnO1GoLFdrK7/XRWMoktNgyG9UjwxrQqGBfGyFKknNZ81YpUS2emCgg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@defillama/sdk/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/@elastic/elasticsearch": { + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.13.1.tgz", + "integrity": "sha512-2G4Vu6OHw4+XTrp7AGIcOEezpPEoVrWg2JTK1v/exEKSLYquZkUdd+m4yOL3/UZ6bTj7hmXwrmYzW76BnLCkJQ==", + "dependencies": { + "@elastic/transport": "~8.4.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@elastic/transport": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.4.1.tgz", + "integrity": "sha512-/SXVuVnuU5b4dq8OFY4izG+dmGla185PcoqgK6+AJMpmOeY1QYVNbWtCwvSvoAANN5D/wV+EBU8+x7Vf9EphbA==", + "dependencies": { + "debug": "^4.3.4", + "hpagent": "^1.0.0", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0", + "tslib": "^2.4.0", + "undici": "^5.22.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "dev": true, + "dependencies": { + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.13", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "peer": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.4.0.tgz", + "integrity": "sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw==", + "peer": true, + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.4.0", + "@nomicfoundation/edr-darwin-x64": "0.4.0", + "@nomicfoundation/edr-linux-arm64-gnu": "0.4.0", + "@nomicfoundation/edr-linux-arm64-musl": "0.4.0", + "@nomicfoundation/edr-linux-x64-gnu": "0.4.0", + "@nomicfoundation/edr-linux-x64-musl": "0.4.0", + "@nomicfoundation/edr-win32-x64-msvc": "0.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz", + "integrity": "sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz", + "integrity": "sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz", + "integrity": "sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz", + "integrity": "sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz", + "integrity": "sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz", + "integrity": "sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz", + "integrity": "sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A==", + "peer": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-common": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", + "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", + "peer": true, + "dependencies": { + "@nomicfoundation/ethereumjs-util": "9.0.4" + } + }, + "node_modules/@nomicfoundation/ethereumjs-rlp": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", + "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", + "peer": true, + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", + "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", + "peer": true, + "dependencies": { + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/ethereumjs-util": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", + "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", + "peer": true, + "dependencies": { + "@nomicfoundation/ethereumjs-rlp": "5.0.4", + "ethereum-cryptography": "0.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "peer": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "3.4.2-solc-0.7", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz", + "integrity": "sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==" + }, + "node_modules/@scure/base": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", + "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "peer": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "peer": true, + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "peer": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "peer": true, + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "peer": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "peer": true, + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "peer": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.0.1.tgz", + "integrity": "sha512-Jb7jg4E+C+uvrUQi+h9kbILY6ts6fglKZzseMCHlH9ayq+1f5QdpYf8MV/xppuiN6DAMJAmwGz53GwP3213dmA==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-3.0.0.tgz", + "integrity": "sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.0.tgz", + "integrity": "sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==", + "dependencies": { + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.2.tgz", + "integrity": "sha512-wUyG6ezpp2sWAvfqmSYTROwFUmJqKV78GLf55WODrosBcT0BAMd9bOLO4HRhynWBgAobPml2cF9ZOdgCe00r+g==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.1.tgz", + "integrity": "sha512-R8Pzrr2v2oGUoj4CTZtKPr87lVtBsz7IUBGhSwS1kc6Cj0yPwNdYbkzhFsxhoDE9+BPl09VN/6rFsW9GJzWnBA==", + "dependencies": { + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-retry": "^3.0.4", + "@smithy/middleware-serde": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.1.tgz", + "integrity": "sha512-htndP0LwHdE3R3Nam9ZyVWhwPYOmD4xCL79kqvNxy8u/bv0huuy574CSiRY4cvEICgimv8jlVfLeZ7zZqbnB2g==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.0.1.tgz", + "integrity": "sha512-RNl3CuWZWPy+s8sx4PcOkRvlfodR33Dj3hzUuDG/CoF6XBvm5Xvr33wRoC1RWht0NN+Q6Z6KcoAkhlQA12MBBw==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^3.1.0", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.1.tgz", + "integrity": "sha512-hpjzFlsDwtircebetScjEiwQwwPy0XASsV3dpUxEhPQUnF/mQ/IeiXaDrhsOmJiscMuCwxNPoZm3x4XmnGwN1g==", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.1.tgz", + "integrity": "sha512-6+B8P+5Q1mll4u7IoI7mpmYOSW3/c2r3WQoYLdqOjbIKMixJFGmN79ZjJiNMy4X2GZ4We9kQ6LfnFuczSlhcyw==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.1.tgz", + "integrity": "sha512-8ylxIbZ0XiQD8kSKPmrrGS/2LmcDxg1mAAURa5tjcjYeBJPg7EaFRcH/aRe2RDPaoVUAbOfjHh2bTkWvy7P4Ig==", + "dependencies": { + "@smithy/eventstream-serde-universal": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.1.tgz", + "integrity": "sha512-E6aeN0MEO1p1KVN4Z3XQlvdUPp+hKJ21eiiioWtNLNNGAZUaJPlXgrqF+6Wj/aM86//9EQp6/iAwQB6eXaulzw==", + "dependencies": { + "@smithy/eventstream-codec": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.0.2.tgz", + "integrity": "sha512-0nW6tLK0b7EqSsfKvnOmZCgJqnodBAnvqcrlC5dotKfklLedPTRGsQamSVbVDWyuU/QGg+YbZDJUQ0CUufJXZQ==", + "dependencies": { + "@smithy/protocol-http": "^4.0.1", + "@smithy/querystring-builder": "^3.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.0.1.tgz", + "integrity": "sha512-P8xxvMm0F6vi/7+GwGhZbE532b7TzGJUfUoUNGrb+dcR+MJUisV8sEQBZ5EB/ddf1/aGr8KO7QqbO/6WhfdW/Q==", + "dependencies": { + "@smithy/chunked-blob-reader": "^3.0.0", + "@smithy/chunked-blob-reader-native": "^3.0.0", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/hash-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.1.tgz", + "integrity": "sha512-w2ncjgk2EYO2+WhAsSQA8owzoOSY7IL1qVytlwpnL1pFGWTjIoIh5nROkEKXY51unB63bMGZqDiVoXaFbyKDlg==", + "dependencies": { + "@smithy/types": "^3.1.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.0.1.tgz", + "integrity": "sha512-5Z5Oyqh9f5927HWyKK3klG09rMlVu8OcEQd4YDxYZbjdB9nHd8imTMN06tfcyrZCEzcOdeUCpJmjfVWUxUDigg==", + "dependencies": { + "@smithy/types": "^3.1.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.1.tgz", + "integrity": "sha512-RSNF/32BKygXKKMyS7koyuAq1rcdW5p5c4EFa77QenBFze9As+JiRnV9OWBh2cB/ejGZalEZjvIrMLHwJl7aGA==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.1.tgz", + "integrity": "sha512-wQa0YGsR4Zb1GQLGwOOgRAbkj22P6CFGaFzu5bKk8K4HVNIC2dBlIxqZ/baF0pLiSZySAPdDZT7CdZ7GkGXt5A==", + "dependencies": { + "@smithy/types": "^3.1.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.1.tgz", + "integrity": "sha512-6QdK/VbrCfXD5/QolE2W/ok6VqxD+SM28Ds8iSlEHXZwv4buLsvWyvoEEy0322K/g5uFgPzBmZjGqesTmPL+yQ==", + "dependencies": { + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.2.tgz", + "integrity": "sha512-gWEaGYB3Bei17Oiy/F2IlUPpBazNXImytoOdJ1xbrUOaJKAOiUhx8/4FOnYLLJHdAwa9PlvJ2ULda2f/Dnwi9w==", + "dependencies": { + "@smithy/middleware-serde": "^3.0.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "@smithy/url-parser": "^3.0.1", + "@smithy/util-middleware": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.4.tgz", + "integrity": "sha512-Tu+FggbLNF5G9L6Wi8o32Mg4bhlBInWlhhaFKyytGRnkfxGopxFVXJQn7sjZdFYJyTz6RZZa06tnlvavUgtoVg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/service-error-classification": "^3.0.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-retry": "^3.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.1.tgz", + "integrity": "sha512-ak6H/ZRN05r5+SR0/IUc5zOSyh2qp3HReg1KkrnaSLXmncy9lwOjNqybX4L4x55/e5mtVDn1uf/gQ6bw5neJPw==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.1.tgz", + "integrity": "sha512-fS5uT//y1SlBdkzIvgmWQ9FufwMXrHSSbuR25ygMy1CRDIZkcBMoF4oTMYNfR9kBlVBcVzlv7joFdNrFuQirPA==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.1.tgz", + "integrity": "sha512-z5G7+ysL4yUtMghUd2zrLkecu0mTfnYlt5dR76g/HsFqf7evFazwiZP1ag2EJenGxNBDwDM5g8nm11NPogiUVA==", + "dependencies": { + "@smithy/property-provider": "^3.1.1", + "@smithy/shared-ini-file-loader": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.0.1.tgz", + "integrity": "sha512-hlBI6MuREA4o1wBMEt+QNhUzoDtFFvwR6ecufimlx9D79jPybE/r8kNorphXOi91PgSO9S2fxRjcKCLk7Jw8zA==", + "dependencies": { + "@smithy/abort-controller": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/querystring-builder": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.1.tgz", + "integrity": "sha512-YknOMZcQkB5on+MU0DvbToCmT2YPtTETMXW0D3+/Iln7ezT+Zm1GMHhCW1dOH/X/+LkkQD9aXEoCX/B10s4Xdw==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.1.tgz", + "integrity": "sha512-eBhm9zwcFPEazc654c0BEWtxYAzrw+OhoSf5pkwKzfftWKXRoqEhwOE2Pvn30v0iAdo7Mfsfb6pi1NnZlGCMpg==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.1.tgz", + "integrity": "sha512-vKitpnG/2KOMVlx3x1S3FkBH075EROG3wcrcDaNerQNh8yuqnSL23btCD2UyX4i4lpPzNW6VFdxbn2Z25b/g5Q==", + "dependencies": { + "@smithy/types": "^3.1.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.1.tgz", + "integrity": "sha512-Qt8DMC05lVS8NcQx94lfVbZSX+2Ym7032b/JR8AlboAa/D669kPzqb35dkjkvAG6+NWmUchef3ENtrD6F+5n8Q==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.1.tgz", + "integrity": "sha512-ubFUvIePjDCyIzZ+pLETqNC6KXJ/fc6g+/baqel7Zf6kJI/kZKgjwkCI7zbUhoUuOZ/4eA/87YasVu40b/B4bA==", + "dependencies": { + "@smithy/types": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.1.tgz", + "integrity": "sha512-nD6tXIX2126/P9e3wqRY1bm9dTtPZwRDyjVOd18G28o+1UOG+kOVgUwujE795HslSuPlEgqzsH5sgNP1hDjj9g==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.0.1.tgz", + "integrity": "sha512-ARAmD+E7j6TIEhKLjSZxdzs7wceINTMJRN2BXPM09BiUmJhkXAF1ZZtDXH6fhlk7oehBZeh37wGiPOqtdKjLeg==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/types": "^3.1.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.1", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.2.tgz", + "integrity": "sha512-f3eQpczBOFUtdT/ptw2WpUKu1qH1K7xrssrSiHYtd9TuLXkvFqb88l9mz9FHeUVNSUxSnkW1anJnw6rLwUKzQQ==", + "dependencies": { + "@smithy/middleware-endpoint": "^3.0.2", + "@smithy/middleware-stack": "^3.0.1", + "@smithy/protocol-http": "^4.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-stream": "^3.0.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.1.0.tgz", + "integrity": "sha512-qi4SeCVOUPjhSSZrxxB/mB8DrmuSFUcJnD9KXjuP+7C3LV/KFV4kpuUSH3OHDZgQB9TEH/1sO/Fq/5HyaK9MPw==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.1.tgz", + "integrity": "sha512-G140IlNFlzYWVCedC4E2d6NycM1dCUbe5CnsGW1hmGt4hYKiGOw0v7lVru9WAn5T2w09QEjl4fOESWjGmCvVmg==", + "dependencies": { + "@smithy/querystring-parser": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.4.tgz", + "integrity": "sha512-sXtin3Mue3A3xo4+XkozpgPptgmRwvNPOqTvb3ANGTCzzoQgAPBNjpE+aXCINaeSMXwHmv7E2oEn2vWdID+SAQ==", + "dependencies": { + "@smithy/property-provider": "^3.1.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.4.tgz", + "integrity": "sha512-CUF6TyxLh3CgBRVYgZNOPDfzHQjeQr0vyALR6/DkQkOm7rNfGEzW1BRFi88C73pndmfvoiIT7ochuT76OPz9Dw==", + "dependencies": { + "@smithy/config-resolver": "^3.0.2", + "@smithy/credential-provider-imds": "^3.1.1", + "@smithy/node-config-provider": "^3.1.1", + "@smithy/property-provider": "^3.1.1", + "@smithy/smithy-client": "^3.1.2", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.2.tgz", + "integrity": "sha512-4zFOcBFQvifd2LSD4a1dKvfIWWwh4sWNtS3oZ7mpob/qPPmJseqKB148iT+hWCDsG//TmI+8vjYPgZdvnkYlTg==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.1.tgz", + "integrity": "sha512-WRODCQtUsO7vIvfrdxS8RFPeLKcewYtaCglZsBsedIKSUGIIvMlZT5oh+pCe72I+1L+OjnZuqRNpN2LKhWA4KQ==", + "dependencies": { + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.1.tgz", + "integrity": "sha512-5lRtYm+8fNFEUTdqZXg5M4ppVp40rMIJfR1TpbHAhKQgPIDpWT+iYMaqgnwEbtpi9U1smyUOPv5Sg+M1neOBgw==", + "dependencies": { + "@smithy/service-error-classification": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.2.tgz", + "integrity": "sha512-n5Obp5AnlI6qHo8sbupwrcpBe6vFp4qkl0SRNuExKPNrH3ABAMG2ZszRTIUIv2b4AsFrCO+qiy4uH1Q3z1dxTA==", + "dependencies": { + "@smithy/fetch-http-handler": "^3.0.2", + "@smithy/node-http-handler": "^3.0.1", + "@smithy/types": "^3.1.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.0.1.tgz", + "integrity": "sha512-wwnrVQdjQxvWGOAiLmqlEhENGCcDIN+XJ/+usPOgSZObAslrCXgKlkX7rNVwIWW2RhPguTKthvF+4AoO0Z6KpA==", + "dependencies": { + "@smithy/abort-controller": "^3.0.1", + "@smithy/types": "^3.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@stacks/common": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@stacks/common/-/common-6.16.0.tgz", + "integrity": "sha512-PnzvhrdGRMVZvxTulitlYafSK4l02gPCBBoI9QEoTqgSnv62oaOXhYAUUkTMFKxdHW1seVEwZsrahuXiZPIAwg==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "@types/node": "^18.0.4" + } + }, + "node_modules/@stacks/common/node_modules/@types/node": { + "version": "18.19.64", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", + "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@stacks/network": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/@stacks/network/-/network-6.17.0.tgz", + "integrity": "sha512-numHbfKjwco/rbkGPOEz8+FcJ2nBnS/tdJ8R422Q70h3SiA9eqk9RjSzB8p4JP8yW1SZvW+eihADHfMpBuZyfw==", + "dependencies": { + "@stacks/common": "^6.16.0", + "cross-fetch": "^3.1.5" + } + }, + "node_modules/@stacks/transactions": { + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/@stacks/transactions/-/transactions-6.17.0.tgz", + "integrity": "sha512-FUah2BRgV66ApLcEXGNGhwyFTRXqX5Zco3LpiM3essw8PF0NQlHwwdPgtDko5RfrJl3LhGXXe/30nwsfNnB3+g==", + "dependencies": { + "@noble/hashes": "1.1.5", + "@noble/secp256k1": "1.7.1", + "@stacks/common": "^6.16.0", + "@stacks/network": "^6.17.0", + "c32check": "^2.0.0", + "lodash.clonedeep": "^4.5.0" + } + }, + "node_modules/@stacks/transactions/node_modules/@noble/hashes": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.5.tgz", + "integrity": "sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@stellar/js-xdr": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.1.2.tgz", + "integrity": "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==" + }, + "node_modules/@stellar/stellar-base": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-13.1.0.tgz", + "integrity": "sha512-90EArG+eCCEzDGj3OJNoCtwpWDwxjv+rs/RNPhvg4bulpjN/CSRj+Ys/SalRcfM4/WRC5/qAfjzmJBAuquWhkA==", + "dependencies": { + "@stellar/js-xdr": "^3.1.2", + "base32.js": "^0.1.0", + "bignumber.js": "^9.1.2", + "buffer": "^6.0.3", + "sha.js": "^2.3.6", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "sodium-native": "^4.3.3" + } + }, + "node_modules/@stellar/stellar-sdk": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-13.2.0.tgz", + "integrity": "sha512-azxeh1+mS28h96Q+vl41ffytQvWdudRl1KtjYO0TRZb/9u0/lH57oYBeJ+gvcQr+T7s02wTayFdHbKru5V5/XA==", + "dependencies": { + "@stellar/stellar-base": "^13.1.0", + "axios": "^1.8.4", + "bignumber.js": "^9.1.2", + "eventsource": "^2.0.2", + "feaxios": "^0.0.23", + "randombytes": "^2.1.0", + "toml": "^3.0.0", + "urijs": "^1.19.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@supercharge/promise-pool": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-2.4.0.tgz", + "integrity": "sha512-O9CMipBlq5OObdt1uKJGIzm9cdjpPWfj+a+Zw9EgWKxaMNHKC7EU7X9taj3H0EGQNLOSq2jAcOa3EzxlfHsD6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ton/core": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.56.3.tgz", + "integrity": "sha512-HVkalfqw8zqLLPehtq0CNhu5KjVzc7IrbDwDHPjGoOSXmnqSobiWj8a5F+YuWnZnEbQKtrnMGNOOjVw4LG37rg==", + "peer": true, + "dependencies": { + "symbol.inspect": "1.0.1" + }, + "peerDependencies": { + "@ton/crypto": ">=3.2.0" + } + }, + "node_modules/@ton/crypto": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@ton/crypto/-/crypto-3.3.0.tgz", + "integrity": "sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA==", + "peer": true, + "dependencies": { + "@ton/crypto-primitives": "2.1.0", + "jssha": "3.2.0", + "tweetnacl": "1.0.3" + } + }, + "node_modules/@ton/crypto-primitives": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ton/crypto-primitives/-/crypto-primitives-2.1.0.tgz", + "integrity": "sha512-PQesoyPgqyI6vzYtCXw4/ZzevePc4VGcJtFwf08v10OevVJHVfW238KBdpj1kEDQkxWLeuNHEpTECNFKnP6tow==", + "peer": true, + "dependencies": { + "jssha": "3.2.0" + } + }, + "node_modules/@ton/ton": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@ton/ton/-/ton-14.0.0.tgz", + "integrity": "sha512-xb2CY6U0AlHUKc7DV7xK/K4Gqn6YoR253yUrM2E7L5WegVFsDF0CQRUIfpYACCuj1oUywQc5J2oMolYNu/uGkA==", + "dependencies": { + "axios": "^1.6.7", + "dataloader": "^2.0.0", + "symbol.inspect": "1.0.1", + "teslabot": "^1.3.0", + "zod": "^3.21.4" + }, + "peerDependencies": { + "@ton/core": ">=0.56.0", + "@ton/crypto": ">=3.2.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "28.1.8", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.8.tgz", + "integrity": "sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==", + "dependencies": { + "expect": "^28.0.0", + "pretty-format": "^28.0.0" + } + }, + "node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "peer": true + }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@uniswap/lib": { + "version": "4.0.1-alpha", + "resolved": "https://registry.npmjs.org/@uniswap/lib/-/lib-4.0.1-alpha.tgz", + "integrity": "sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/sdk-core": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-5.3.0.tgz", + "integrity": "sha512-wbMzSY3wbByOkoirZXyeomof4a7goueT4bOa4YqoXDWqIftqrT70UuCgjk98nIBu3UqPxRNMptXusppxZVvwWA==", + "dependencies": { + "@ethersproject/address": "^5.0.2", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/strings": "5.7.0", + "big.js": "^5.2.2", + "decimal.js-light": "^2.5.0", + "jsbi": "^3.1.4", + "tiny-invariant": "^1.1.0", + "toformat": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/swap-router-contracts": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.1.tgz", + "integrity": "sha512-mh/YNbwKb7Mut96VuEtL+Z5bRe0xVIbjjiryn+iMMrK2sFKhR4duk/86mEz0UO5gSx4pQIw9G5276P5heY/7Rg==", + "dependencies": { + "@openzeppelin/contracts": "3.4.2-solc-0.7", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v3-core": "^1.0.0", + "@uniswap/v3-periphery": "^1.4.4", + "dotenv": "^14.2.0", + "hardhat-watcher": "^2.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/swap-router-contracts/node_modules/dotenv": { + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.3.2.tgz", + "integrity": "sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@uniswap/v2-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", + "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/v3-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz", + "integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/v3-periphery": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz", + "integrity": "sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==", + "dependencies": { + "@openzeppelin/contracts": "3.4.2-solc-0.7", + "@uniswap/lib": "^4.0.1-alpha", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v3-core": "^1.0.0", + "base64-sol": "1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/v3-sdk": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-sdk/-/v3-sdk-3.13.0.tgz", + "integrity": "sha512-Jz8aEU7RrDK4LfFNLClXFr2hkBE08QANLEBTofmu+ueCCKoNoRd/OTR4q04HhIeMyXtzsSOzi32a5yS7OY9glg==", + "dependencies": { + "@ethersproject/abi": "^5.5.0", + "@ethersproject/solidity": "^5.0.9", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/swap-router-contracts": "^1.3.0", + "@uniswap/v3-periphery": "^1.1.1", + "@uniswap/v3-staker": "1.0.0", + "tiny-invariant": "^1.1.0", + "tiny-warning": "^1.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/v3-staker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-staker/-/v3-staker-1.0.0.tgz", + "integrity": "sha512-JV0Qc46Px5alvg6YWd+UIaGH9lDuYG/Js7ngxPit1SPaIP30AlVer1UYB7BRYeUVVxE+byUyIeN5jeQ7LLDjIw==", + "deprecated": "Please upgrade to 1.0.1", + "dependencies": { + "@openzeppelin/contracts": "3.4.1-solc-0.7-2", + "@uniswap/v3-core": "1.0.0", + "@uniswap/v3-periphery": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@uniswap/v3-staker/node_modules/@openzeppelin/contracts": { + "version": "3.4.1-solc-0.7-2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz", + "integrity": "sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==" + }, + "node_modules/@uniswap/v3-staker/node_modules/@uniswap/v3-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz", + "integrity": "sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/abitype": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", + "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", + "peerDependencies": { + "typescript": ">=4.9.4", + "zod": "^3 >=3.19.1" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "peer": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "peer": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "peer": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "peer": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "dev": true, + "dependencies": { + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bare-addon-resolve": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.9.4.tgz", + "integrity": "sha512-unn6Vy/Yke6F99vg/7tcrvM2KUvIhTNniaSqDbam4AWkd4NhvDVSrQiRYVlNzUV2P7SPobkCK7JFVxrJk9btCg==", + "optional": true, + "dependencies": { + "bare-module-resolve": "^1.10.0", + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-module-resolve": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.10.2.tgz", + "integrity": "sha512-C9COe/GhWfVXKytW3DElTkiBU+Gb2OXeaVkdGdRB/lp26TVLESHkTGS876iceAGdvtPgohfp9nX8vXHGvN3++Q==", + "optional": true, + "dependencies": { + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-semver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.1.tgz", + "integrity": "sha512-UtggzHLiTrmFOC/ogQ+Hy7VfoKoIwrP1UFcYtTxoCUdLtsIErT8+SWtOC2DH/snT9h+xDrcBEPcwKei1mzemgg==", + "optional": true + }, + "node_modules/bare-url": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.1.5.tgz", + "integrity": "sha512-lNImB5KLN+ggw+SYDYvqf/yCizXIyq8U/nWBlx7m4pc4TKS24SB/1WWskzGacon5cVVAC6qUzCYzI/aMYCf4Ng==", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "peer": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base32.js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", + "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64-sol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-sol/-/base64-sol-1.0.1.tgz", + "integrity": "sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==" + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "peer": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "peer": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "peer": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "peer": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "peer": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "peer": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "peer": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c32check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/c32check/-/c32check-2.0.0.tgz", + "integrity": "sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA==", + "dependencies": { + "@noble/hashes": "^1.1.2", + "base-x": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c32check/node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001633", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", + "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "peer": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "peer": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "peer": true + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "peer": true + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "peer": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "peer": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csv-writer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", + "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" + }, + "node_modules/dataloader": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", + "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.802", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", + "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "peer": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "peer": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "peer": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "peer": true + }, + "node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "peer": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "peer": true + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "peer": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "peer": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dependencies": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/extract-files": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", + "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", + "engines": { + "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fast-xml-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/feaxios": { + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/feaxios/-/feaxios-0.0.23.tgz", + "integrity": "sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g==", + "dependencies": { + "is-retry-allowed": "^3.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "peer": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "peer": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "peer": true + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-request": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", + "integrity": "sha512-dw5PxHCgBneN2DDNqpWu8QkbbJ07oOziy8z+bK/TAXufsOLaETuVO4GkXrbs0WjhdKhBMN3BkpN/RIvUHkmNUQ==", + "dependencies": { + "cross-fetch": "^3.0.6", + "extract-files": "^9.0.0", + "form-data": "^3.0.0" + }, + "peerDependencies": { + "graphql": "14 - 16" + } + }, + "node_modules/graphql-request/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hardhat": { + "version": "2.22.5", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.5.tgz", + "integrity": "sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw==", + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@metamask/eth-sig-util": "^4.0.0", + "@nomicfoundation/edr": "^0.4.0", + "@nomicfoundation/ethereumjs-common": "4.0.4", + "@nomicfoundation/ethereumjs-tx": "5.0.4", + "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "ethereumjs-abi": "^0.6.8", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "7.2.0", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hardhat-watcher/-/hardhat-watcher-2.5.0.tgz", + "integrity": "sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==", + "dependencies": { + "chokidar": "^3.5.3" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "peer": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "peer": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "peer": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "peer": true + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "peer": true, + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "peer": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-retry-allowed": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-3.0.0.tgz", + "integrity": "sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbi": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", + "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jssha": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", + "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/just-performance": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", + "integrity": "sha512-L7RjvtJsL0QO8xFs5wEoDDzzJwoiowRw6Rn/GnvldlchS2JQr9wFYPiwZcDfrbbujEKqKN0tvENdbjXdYhDp5Q==" + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/limiter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-2.1.0.tgz", + "integrity": "sha512-361TYz6iay6n+9KvUUImqdLuFigK+K79qrUtBsXhJTLdH4rIt/r1y8r1iozwh8KbZNpujbFTSh74mJ7bwbAMOw==", + "dependencies": { + "just-performance": "4.3.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "peer": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "peer": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "peer": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "peer": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "peer": true, + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", + "peer": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "8.1.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "peer": true + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "peer": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "peer": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "peer": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "peer": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "peer": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "peer": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "peer": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "peer": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "peer": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/require-addon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.1.0.tgz", + "integrity": "sha512-KbXAD5q2+v1GJnkzd8zzbOxchTkStSyJZ9QwoCq3QwEXAaIlG3wDYRZGzVD357jmwaGY7hr5VaoEAL0BkF0Kvg==", + "optional": true, + "dependencies": { + "bare-addon-resolve": "^1.3.0", + "bare-url": "^2.1.0" + }, + "engines": { + "bare": ">=1.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "peer": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "peer": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "peer": true, + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "peer": true + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "peer": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sodium-native": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.3.tgz", + "integrity": "sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==", + "optional": true, + "dependencies": { + "require-addon": "^1.1.0" + } + }, + "node_modules/solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "peer": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solcjs" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "peer": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 7.0.0" + } + }, + "node_modules/superagent/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/superagent/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol.inspect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol.inspect/-/symbol.inspect-1.0.1.tgz", + "integrity": "sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==" + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/teslabot": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/teslabot/-/teslabot-1.5.0.tgz", + "integrity": "sha512-e2MmELhCgrgZEGo7PQu/6bmYG36IDH+YrBI1iGm6jovXkeDIGa3pZ2WSqRjzkuw2vt1EqfkZoV5GpXgqL8QJVg==" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "peer": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tron-format-address": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/tron-format-address/-/tron-format-address-0.1.11.tgz", + "integrity": "sha512-Jx2i3R1yXrEMQsfc2jueAI71ivnySzdeva6SiSM/pddwj8TK7PVABSP6s/iYcTRI63GxJEgGMmOJXNNKoBmbQw==" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "peer": true + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "peer": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web3": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-4.9.0.tgz", + "integrity": "sha512-O0R90ijjyqUlG1Wk3SXqfYMU1ZGJvLCAF/WfSg/isDz/0Fkpqxoj893wauZ+ieRvTXITlbQHVXGfpp8qrhWZ1g==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-abi": "^4.2.2", + "web3-eth-accounts": "^4.1.2", + "web3-eth-contract": "^4.5.0", + "web3-eth-ens": "^4.3.0", + "web3-eth-iban": "^4.0.7", + "web3-eth-personal": "^4.0.8", + "web3-net": "^4.1.0", + "web3-providers-http": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-core": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.5.0.tgz", + "integrity": "sha512-Q8LIAqmF7vkRydBPiU+OC7wI44nEU6JEExolFaOakqrjMtQ1CWFHRUQMNJRDsk5bRirjyShuAsuqLeYByvvXhg==", + "dependencies": { + "web3-errors": "^1.2.0", + "web3-eth-accounts": "^4.1.2", + "web3-eth-iban": "^4.0.7", + "web3-providers-http": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + }, + "optionalDependencies": { + "web3-providers-ipc": "^4.0.7" + } + }, + "node_modules/web3-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.2.0.tgz", + "integrity": "sha512-58Kczou5zyjcm9LuSs5Hrm6VrG8t9p2J8X0yGArZrhKNPZL66gMGkOUpPx+EopE944Sk4yE+Q25hKv4H5BH+kA==", + "dependencies": { + "web3-types": "^1.6.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.7.0.tgz", + "integrity": "sha512-gqlWq4Xjz+yKL2MdxQ+BgR3F4CRo4AXWDXzftb3LDzvauEfjk/yRyoxkMSK4S9RIG96ylRImS172cV6cYzcukw==", + "dependencies": { + "setimmediate": "^1.0.5", + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth-abi": "^4.2.2", + "web3-eth-accounts": "^4.1.2", + "web3-net": "^4.1.0", + "web3-providers-ws": "^4.0.7", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.2.2.tgz", + "integrity": "sha512-akbGi642UtKG3k3JuLbhl9KuG7LM/cXo/by2WfdwfOptGZrzRsWJNWje1d2xfw1n9kkVG9SAMvPJl1uSyR3dfw==", + "dependencies": { + "abitype": "0.7.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.1.2.tgz", + "integrity": "sha512-y0JynDeTDnclyuE9mShXLeEj+BCrPHxPHOyPCgTchUBQsALF9+0OhP7WiS3IqUuu0Hle5bjG2f5ddeiPtNEuLg==", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "crc-32": "^1.2.2", + "ethereum-cryptography": "^2.0.0", + "web3-errors": "^1.1.4", + "web3-types": "^1.6.0", + "web3-utils": "^4.2.3", + "web3-validator": "^2.0.5" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "dependencies": { + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/web3-eth-contract": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.5.0.tgz", + "integrity": "sha512-AX6OiDrIryz/T28k9Xz0gXpUrlOUjcooEgGluu2s5dFDWCPM/zlN5RsUZlXZiXpQyj52VCUy5+bkvu3yDPA4fg==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-abi": "^4.2.2", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.3.0.tgz", + "integrity": "sha512-QpiKT9GqJouH5kEI/pRFprh88YPCtbht2Ym6rrklZ+VoWl9D+wLfbwvW7Aox349FS7k0UX2qVins5tVNLJ5GCQ==", + "dependencies": { + "@adraffy/ens-normalize": "^1.8.8", + "web3-core": "^4.4.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.7.0", + "web3-eth-contract": "^4.5.0", + "web3-net": "^4.1.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz", + "integrity": "sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==", + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.0.8.tgz", + "integrity": "sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw==", + "dependencies": { + "web3-core": "^4.3.0", + "web3-eth": "^4.3.1", + "web3-rpc-methods": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-net": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.1.0.tgz", + "integrity": "sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.1.0.tgz", + "integrity": "sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg==", + "dependencies": { + "cross-fetch": "^4.0.0", + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-http/node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/web3-providers-ipc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz", + "integrity": "sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==", + "optional": true, + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.7.tgz", + "integrity": "sha512-n4Dal9/rQWjS7d6LjyEPM2R458V8blRm0eLJupDEJOOIBhGYlxw5/4FthZZ/cqB7y/sLVi7K09DdYx2MeRtU5w==", + "dependencies": { + "@types/ws": "8.5.3", + "isomorphic-ws": "^5.0.0", + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "ws": "^8.8.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ws/node_modules/ws": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/web3-rpc-methods": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz", + "integrity": "sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==", + "dependencies": { + "web3-core": "^4.4.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-types": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.7.0.tgz", + "integrity": "sha512-nhXxDJ7a5FesRw9UG5SZdP/C/3Q2EzHGnB39hkAV+YGXDMgwxBXFWebQLfEzZzuArfHnvC0sQqkIHNwSKcVjdA==", + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.0.tgz", + "integrity": "sha512-fGG2IZr0XB1vEoWZiyJzoy28HpsIfZgz4mgPeQA9aj5rIx8z0o80qUPtIyrCYX/Bo2gYALlV5SWIJWxJNUQn9Q==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "eventemitter3": "^5.0.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "dependencies": { + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/web3-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", + "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "util": "^0.12.5", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "zod": "^3.21.4" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-validator/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-validator/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-validator/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-validator/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-validator/node_modules/ethereum-cryptography": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz", + "integrity": "sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA==", + "dependencies": { + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "peer": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "peer": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "peer": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/src/adaptors/package.json b/src/adaptors/package.json new file mode 100644 index 0000000000..67e2a0d097 --- /dev/null +++ b/src/adaptors/package.json @@ -0,0 +1,42 @@ +{ + "name": "defillama-apy-adapters", + "version": "1.0.0", + "scripts": { + "test": "jest" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@blend-capital/blend-sdk": "3.0.1", + "@defillama/sdk": "^5.0.112", + "@stacks/network": "^6.13.0", + "@stacks/transactions": "^6.15.0", + "@ton/ton": "14.0.0", + "@types/jest": "^28.1.6", + "@uniswap/sdk-core": "^5.3.0", + "@uniswap/v3-sdk": "^3.13.0", + "async-retry": "^1.3.3", + "axios": "^1.7.2", + "bignumber.js": "^9.1.1", + "csv-writer": "^1.6.0", + "date-fns": "^2.23.0", + "dotenv": "^10.0.0", + "ethers": "^5.7.2", + "graphql": "^15.5.1", + "graphql-request": "^3.5.0", + "limiter": "^2.1.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.1", + "superagent": "^6.1.0", + "web3": "^4.9.0" + }, + "devDependencies": { + "jest": "^28.1.3", + "prettier": "^2.2.1", + "ts-node": "^10.9.1" + }, + "jest": { + "globalSetup": "./beforeTests.js", + "globalTeardown": "./afterTests.js" + } +} diff --git a/src/adaptors/paladin-dullahan/abi.js b/src/adaptors/paladin-dullahan/abi.js new file mode 100644 index 0000000000..1182cbe160 --- /dev/null +++ b/src/adaptors/paladin-dullahan/abi.js @@ -0,0 +1,331 @@ +module.exports = { + podCollateralBalance: { + inputs: [], + name: 'podCollateralBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + allowedCollaterals: { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'allowedCollaterals', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + getAllReservesTokens: { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalAvailable: { + inputs: [], + name: 'totalAvailable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + GHO_DISCOUNTED_PER_DISCOUNT_TOKEN: { + inputs: [], + name: 'GHO_DISCOUNTED_PER_DISCOUNT_TOKEN', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getCurrentIndex: { + inputs: [], + name: 'getCurrentIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + rewardStates: { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'rewardStates', + outputs: [ + { + internalType: 'uint256', + name: 'rewardPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ratePerSecond', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentRewardAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'queuedRewardAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'distributionEndTimestamp', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getAllStakedTokenData: { + inputs: [], + name: 'getAllStakedTokenData', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'stakedTokenTotalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedTokenTotalRedeemableAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeCooldownSeconds', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeUnstakeWindow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedTokenPriceEth', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardTokenPriceEth', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeApy', + type: 'uint256', + }, + { + internalType: 'uint128', + name: 'distributionPerSecond', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'distributionEnd', + type: 'uint256', + }, + ], + internalType: 'struct IStakedTokenDataProvider.StakedTokenData', + name: 'stkAaveData', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'stakedTokenTotalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedTokenTotalRedeemableAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeCooldownSeconds', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeUnstakeWindow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakedTokenPriceEth', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardTokenPriceEth', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stakeApy', + type: 'uint256', + }, + { + internalType: 'uint128', + name: 'distributionPerSecond', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'distributionEnd', + type: 'uint256', + }, + ], + internalType: 'struct IStakedTokenDataProvider.StakedTokenData', + name: 'stkBptData', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'ethPrice', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalAssets: { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getAllPods: { + inputs: [], + name: 'getAllPods', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + pods: { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'pods', + outputs: [ + { internalType: 'address', name: 'podAddress', type: 'address' }, + { internalType: 'address', name: 'podOwner', type: 'address' }, + { internalType: 'address', name: 'collateral', type: 'address' }, + { internalType: 'uint96', name: 'lastUpdate', type: 'uint96' }, + { internalType: 'uint256', name: 'lastIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'rentedAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'accruedFees', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + calculateDiscountRate: { + inputs: [ + { internalType: 'uint256', name: 'debtBalance', type: 'uint256' }, + { + internalType: 'uint256', + name: 'discountTokenBalance', + type: 'uint256', + }, + ], + name: 'calculateDiscountRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + mintFeeRatio: { + inputs: [], + name: 'mintFeeRatio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + getGhoReserveData: { + inputs: [], + name: 'getGhoReserveData', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'ghoBaseVariableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ghoDiscountedPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ghoDiscountRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ghoMinDebtTokenBalanceForDiscount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'ghoMinDiscountTokenBalanceForDiscount', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'ghoReserveLastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'uint128', + name: 'ghoCurrentBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'aaveFacilitatorBucketLevel', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'aaveFacilitatorBucketMaxCapacity', + type: 'uint256', + }, + ], + internalType: 'struct IUiGhoDataProvider.GhoReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; diff --git a/src/adaptors/paladin-dullahan/index.js b/src/adaptors/paladin-dullahan/index.js new file mode 100644 index 0000000000..37410d413a --- /dev/null +++ b/src/adaptors/paladin-dullahan/index.js @@ -0,0 +1,383 @@ +const ethers = require('ethers'); +const abi = require('./abi'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +/////////////////////////// Constants /////////////////////////// + +const AAVE_DATA_PROVIDER = '0x7B4EB56E7CD4b454BA8ff71E4518426369a138a3'; +const STAKER_PROVIDER = '0x5E045cfb738F01bC73CEAFF783F4C16e8B14090b'; +const STAKING_CONTRACT = '0x990f58570b4C7b8b7ae3Bc28EFEB2724bE111545'; +const DULLAHAN_VAULT = '0x167c606be99DBf5A8aF61E1983E5B309e8FA2Ae7'; +const AAVE = '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9'; +const GHO = '0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f'; +const GHO_PROVIDER_UI = '0x379c1EDD1A41218bdbFf960a9d5AD2818Bf61aE8'; +const POD_MANAGER = '0xf3dEcC68c4FF828456696287B12e5AC0fa62fE56'; +const DISCOUNT_CALCULATOR_MODULE = '0x4C38Ec4D1D2068540DfC11DFa4de41F733DDF812'; +const RAY = ethers.BigNumber.from(10).pow(27); +const WEI_UNIT = ethers.BigNumber.from(10).pow(18); +const WEI_UNDER = ethers.BigNumber.from(10).pow(16); // 18 - 2 (decimals) +const RAY_UNDER = ethers.BigNumber.from(10).pow(25); // 27 - 2 (decimals) +const FEE_TO_PERCENT = 1000; +const BIG_PERC_TO_WEI = ethers.BigNumber.from(10).pow(14); // 18 - 4(LTV_PREC_DECIMAL) +const LTV_PRECISION = 4; +const LTV_PREC_BIG = 10 ** LTV_PRECISION; +const SECONDS_PER_YEAR = 365 * 24 * 60 * 60; + +/////////////////////////// Global variables /////////////////////////// + +let ghoPrice = 0; +let aavePrice = 0; +let defillamaPools = []; +let pods = []; + +/////////////////////////// Utils /////////////////////////// + +const getAaveApy = async (token) => { + return defillamaPools.find((pool) => pool.underlyingTokens.includes(token)) + .apy; +}; + +function binomialApproximatedRayPow(base, exp) { + if (exp.eq(0)) return RAY; + + const expMinusOne = exp.sub(1); + const expMinusTwo = exp.gt(2) ? exp.sub(2) : 0; + + const basePowerTwo = base.mul(base).div(RAY); + const basePowerThree = basePowerTwo.mul(base).div(RAY); + + const firstTerm = exp.mul(base); + const secondTerm = exp.mul(expMinusOne).mul(basePowerTwo).div(2); + const thirdTerm = exp + .mul(expMinusOne) + .mul(expMinusTwo) + .mul(basePowerThree) + .div(6); + + return RAY.add(firstTerm).add(secondTerm).add(thirdTerm); +} + +const getPrices = async (address) => { + const token = `ethereum:${address.toLowerCase()}`; + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${token}`) + ).body.coins[token]; + + return { + price: prices.price, + symbol: prices.symbol, + decimals: prices.decimals, + }; +}; + +const getDefiLLamaPools = async (project, chain) => { + const pools = (await superagent.get('https://yields.llama.fi/pools')).body + .data; + return pools.filter( + (pool) => + pool.project === project && pool.chain === chain && pool.underlyingTokens + ); +}; + +const getPods = async () => { + const pods = ( + await sdk.api.abi.call({ + target: POD_MANAGER, + abi: abi['getAllPods'], + chain: 'ethereum', + }) + ).output; + + const podsData = ( + await sdk.api.abi.multiCall({ + calls: pods.map((p) => ({ + target: POD_MANAGER, + params: p, + })), + abi: abi['pods'], + chain: 'ethereum', + }) + ).output; + + return podsData.map((p) => p.output); +}; + +/////////////////////////// Vault Apy Computation /////////////////////////// + +const stakeBig = async () => { + const assets = ( + await sdk.api.abi.call({ + target: STAKER_PROVIDER, + chain: 'ethereum', + abi: abi['getAllStakedTokenData'], + }) + ).output; + + const stakeApyBig = ethers.BigNumber.from(assets.stkAaveData.stakeApy); + const stakeBig = stakeApyBig.mul(BIG_PERC_TO_WEI); + + return stakeBig.div(BIG_PERC_TO_WEI).toNumber() / 100; +}; + +const bigReward = async () => { + const rewardState = ( + await sdk.api.abi.call({ + target: STAKING_CONTRACT, + abi: abi['rewardStates'], + params: [GHO], + chain: 'ethereum', + }) + ).output; + const indx = ethers.BigNumber.from( + ( + await sdk.api.abi.call({ + target: STAKING_CONTRACT, + abi: abi['getCurrentIndex'], + chain: 'ethereum', + }) + ).output + ); + + const ratePerSec = rewardState.ratePerSecond; + const ratePerYear = ethers.BigNumber.from(ratePerSec).mul(SECONDS_PER_YEAR); + + const rewardApy = + aavePrice !== 0 && indx.gt('0') && ratePerYear.gt(0) + ? ratePerYear + .mul(RAY) + .mul(ghoPrice * LTV_PREC_BIG) + .div(aavePrice * LTV_PREC_BIG) + .div(indx) + : ethers.BigNumber.from('0'); + const rewardPerc = rewardApy.mul(100); + + return rewardPerc.div(RAY_UNDER).toNumber() / 100; +}; + +/////////////////////////// GHO Borrow Apy Computation /////////////////////////// + +const getGhoApyDiscounted = (baseApy, ghoDiscount) => { + const maxGhoDiscount = 10000; + const apyDiscounted = baseApy.mul(ghoDiscount).div(maxGhoDiscount); + const apyAfterDiscount = baseApy.sub(apyDiscounted); + return apyAfterDiscount; +}; + +const minApy = async () => { + const assets = ( + await sdk.api.abi.call({ + target: GHO_PROVIDER_UI, + abi: abi['getGhoReserveData'], + chain: 'ethereum', + }) + ).output; + + const { ghoBaseVariableBorrowRate } = assets; + const ratePerSecond = ethers.BigNumber.from(ghoBaseVariableBorrowRate).div( + SECONDS_PER_YEAR + ); + + const interestEstimate = binomialApproximatedRayPow( + ratePerSecond, + ethers.BigNumber.from(SECONDS_PER_YEAR) + ); + const currentApy = interestEstimate.sub(RAY).mul(100); + return currentApy; +}; + +const maxApy = async () => { + let discountRate = ( + await sdk.api.abi.call({ + target: DISCOUNT_CALCULATOR_MODULE, + abi: abi['calculateDiscountRate'], + chain: 'ethereum', + params: [50000000000000000000n, 100000000000000000000000n], + }) + ).output; + const fee = ( + await sdk.api.abi.call({ + target: POD_MANAGER, + abi: abi['mintFeeRatio'], + chain: 'ethereum', + }) + ).output; + const dullahanFeesSim = ethers.utils + .parseEther('.00001') + .mul(fee) + .div(FEE_TO_PERCENT); + const dullahanApr = dullahanFeesSim + .mul(RAY) + .div(ethers.utils.parseEther('100')); + + const baseApy = await minApy(); + const apyAfterDiscount = getGhoApyDiscounted(baseApy, discountRate); + const apyMax = apyAfterDiscount.add(dullahanApr); + return apyMax.div(RAY_UNDER).toNumber() / 100; +}; + +/////////////////////////// Compute TVL /////////////////////////// + +const getBorrowTvl = async (token) => { + let totalAmount = 0; + + for (const pod of pods) { + if (pod.collateral !== token) continue; + totalAmount += + (ethers.BigNumber.from(pod.rentedAmount).div(WEI_UNDER).toNumber() / + 100) * + ghoPrice; + } + return totalAmount; +}; + +const getSupplyTvl = async (token) => { + let totalAmount = 0; + + for (const pod of pods) { + if (pod.collateral !== token) continue; + const tokenPrice = await getPrices(token); + const amount = ( + await sdk.api.abi.call({ + target: pod.podAddress, + abi: abi['podCollateralBalance'], + chain: 'ethereum', + }) + ).output; + if (tokenPrice.decimals > 2) { + totalAmount += + (ethers.BigNumber.from(amount) + .div(ethers.BigNumber.from(10).pow(tokenPrice.decimals - 2)) + .toNumber() / + 100) * + tokenPrice.price; + } else { + totalAmount += + ethers.BigNumber.from(amount) + .div(ethers.BigNumber.from(10).pow(tokenPrice.decimals)) + .toNumber() * tokenPrice.price; + } + } + return totalAmount; +}; + +const getTotalSuppliedTvl = async () => { + const assets = ( + await sdk.api.abi.call({ + abi: abi['totalAssets'], + chain: 'ethereum', + target: DULLAHAN_VAULT, + }) + ).output; + + return ethers.BigNumber.from(assets).div(WEI_UNIT).toNumber() * aavePrice; +}; + +const getDebtCeiling = async () => { + const stkaaaveAvailable = ethers.BigNumber.from( + ( + await sdk.api.abi.call({ + target: DULLAHAN_VAULT, + abi: abi['totalAvailable'], + chain: 'ethereum', + }) + ).output + ); + + const discount = ethers.BigNumber.from( + ( + await sdk.api.abi.call({ + target: DISCOUNT_CALCULATOR_MODULE, + abi: abi['GHO_DISCOUNTED_PER_DISCOUNT_TOKEN'], + chain: 'ethereum', + }) + ).output + ); + + return ( + stkaaaveAvailable.mul(discount).div(WEI_UNIT.pow(2)).toNumber() * ghoPrice + ); +}; + +/////////////////////////// Get the pool /////////////////////////// + +const getCollaterals = async () => { + const reserveTokens = ( + await sdk.api.abi.call({ + target: AAVE_DATA_PROVIDER, + abi: abi['getAllReservesTokens'], + chain: 'ethereum', + }) + ).output; + + const allowed = ( + await sdk.api.abi.multiCall({ + abi: abi['allowedCollaterals'], + calls: reserveTokens.map((t) => ({ + target: POD_MANAGER, + params: t.tokenAddress, + })), + chain: 'ethereum', + }) + ).output; + + return reserveTokens.filter( + (e) => allowed.find((p) => p.input.params[0] == e.tokenAddress).output + ); +}; + +const getApy = async () => { + ghoPrice = (await getPrices(GHO)).price; + aavePrice = (await getPrices(AAVE)).price; + defillamaPools = await getDefiLLamaPools('aave-v3', 'Ethereum'); + pods = await getPods(); + + const apyBaseBorrow = await maxApy(); + const suppliedTvl = await getTotalSuppliedTvl(); + const vaultApyBase = await stakeBig(); + const vaultApyReward = await bigReward(); + const debtCeilingUsd = await getDebtCeiling(); + + const collaterals = await getCollaterals(); + + const pools = []; + for (const collateral of collaterals) { + const totalBorrowUsd = await getBorrowTvl(collateral.tokenAddress); + const totalSupplyUsd = await getSupplyTvl(collateral.tokenAddress); + const apyBase = await getAaveApy(collateral.tokenAddress); + + const pool = { + pool: `${DULLAHAN_VAULT}-${collateral.symbol}-ethereum`, + project: 'paladin-dullahan', + chain: 'ethereum', + symbol: `d${collateral.symbol}`, + apyBase, + apyBaseBorrow, + totalSupplyUsd, + totalBorrowUsd, + tvlUsd: totalSupplyUsd, + mintedCoin: 'GHO', + debtCeilingUsd, + }; + pools.push(pool); + } + + const dstkAAVE = { + pool: `${DULLAHAN_VAULT}-ethereum`, + project: 'paladin-dullahan', + chain: 'ethereum', + symbol: 'dstkAAVE', + apyBase: vaultApyBase, + apyReward: vaultApyReward, + tvlUsd: suppliedTvl, + }; + pools.push(dstkAAVE); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://dullahan.paladin.vote/', +}; diff --git a/src/adaptors/paladin-warlord/abi/CvxLocker.js b/src/adaptors/paladin-warlord/abi/CvxLocker.js new file mode 100644 index 0000000000..4dea66d020 --- /dev/null +++ b/src/adaptors/paladin-warlord/abi/CvxLocker.js @@ -0,0 +1,627 @@ +const cvxLockerAbi = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: '_user', type: 'address' }, + { indexed: true, internalType: 'address', name: '_kicked', type: 'address' }, + { indexed: false, internalType: 'uint256', name: '_reward', type: 'uint256' } + ], + name: 'KickReward', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'previousOwner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'newOwner', type: 'address' } + ], + name: 'OwnershipTransferred', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'address', name: '_token', type: 'address' }, + { indexed: false, internalType: 'uint256', name: '_amount', type: 'uint256' } + ], + name: 'Recovered', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: '_token', type: 'address' }, + { indexed: false, internalType: 'uint256', name: '_reward', type: 'uint256' } + ], + name: 'RewardAdded', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: '_user', type: 'address' }, + { indexed: true, internalType: 'address', name: '_rewardsToken', type: 'address' }, + { indexed: false, internalType: 'uint256', name: '_reward', type: 'uint256' } + ], + name: 'RewardPaid', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: '_user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: '_epoch', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: '_paidAmount', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: '_lockedAmount', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: '_boostedAmount', type: 'uint256' } + ], + name: 'Staked', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: '_user', type: 'address' }, + { indexed: false, internalType: 'uint256', name: '_amount', type: 'uint256' }, + { indexed: false, internalType: 'bool', name: '_relocked', type: 'bool' } + ], + name: 'Withdrawn', + type: 'event' + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'address', name: '_distributor', type: 'address' }, + { internalType: 'bool', name: '_useBoost', type: 'bool' } + ], + name: 'addReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'address', name: '_distributor', type: 'address' }, + { internalType: 'bool', name: '_approved', type: 'bool' } + ], + name: 'approveRewardDistributor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_epoch', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' } + ], + name: 'balanceAtEpochOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balances', + outputs: [ + { internalType: 'uint112', name: 'locked', type: 'uint112' }, + { internalType: 'uint112', name: 'boosted', type: 'uint112' }, + { internalType: 'uint32', name: 'nextUnlockIndex', type: 'uint32' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'boostPayment', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'boostRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'boostedSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'checkpointEpoch', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'claimableRewards', + outputs: [ + { + components: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + internalType: 'struct CvxLockerV2.EarnedData[]', + name: 'userRewards', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'cvxCrv', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'cvxcrvStaking', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'denominator', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'epochCount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'epochs', + outputs: [ + { internalType: 'uint224', name: 'supply', type: 'uint224' }, + { internalType: 'uint32', name: 'date', type: 'uint32' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'uint256', name: '_time', type: 'uint256' }], + name: 'findEpochId', + outputs: [{ internalType: 'uint256', name: 'epoch', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_account', type: 'address' }, + { internalType: 'bool', name: '_stake', type: 'bool' } + ], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_rewardsToken', type: 'address' }], + name: 'getRewardForDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'isShutdown', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'kickExpiredLocks', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'kickRewardEpochDelay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'kickRewardPerEpoch', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_rewardsToken', type: 'address' }], + name: 'lastTimeRewardApplicable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_account', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + { internalType: 'uint256', name: '_spendRatio', type: 'uint256' } + ], + name: 'lock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'lockDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'lockedBalanceOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'lockedBalances', + outputs: [ + { internalType: 'uint256', name: 'total', type: 'uint256' }, + { internalType: 'uint256', name: 'unlockable', type: 'uint256' }, + { internalType: 'uint256', name: 'locked', type: 'uint256' }, + { + components: [ + { internalType: 'uint112', name: 'amount', type: 'uint112' }, + { internalType: 'uint112', name: 'boosted', type: 'uint112' }, + { internalType: 'uint32', name: 'unlockTime', type: 'uint32' } + ], + internalType: 'struct CvxLockerV2.LockedBalance[]', + name: 'lockData', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'lockedSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'maximumBoostPayment', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'maximumStake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'minimumStake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nextBoostRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nextMaximumBoostPayment', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'uint256', name: '_reward', type: 'uint256' } + ], + name: 'notifyRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_epoch', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' } + ], + name: 'pendingLockAtEpochOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'pendingLockOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'bool', name: '_relock', type: 'bool' }], + name: 'processExpiredLocks', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_tokenAddress', type: 'address' }, + { internalType: 'uint256', name: '_tokenAmount', type: 'uint256' } + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardData', + outputs: [ + { internalType: 'bool', name: 'useBoost', type: 'bool' }, + { internalType: 'uint40', name: 'periodFinish', type: 'uint40' }, + { internalType: 'uint208', name: 'rewardRate', type: 'uint208' }, + { internalType: 'uint40', name: 'lastUpdateTime', type: 'uint40' }, + { internalType: 'uint208', name: 'rewardPerTokenStored', type: 'uint208' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' } + ], + name: 'rewardDistributors', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_rewardsToken', type: 'address' }], + name: 'rewardPerToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewardTokens', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'rewardWeightOf', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' } + ], + name: 'rewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'rewardsDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'setApprovals', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_max', type: 'uint256' }, + { internalType: 'uint256', name: '_rate', type: 'uint256' }, + { internalType: 'address', name: '_receivingAddress', type: 'address' } + ], + name: 'setBoost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_rate', type: 'uint256' }, + { internalType: 'uint256', name: '_delay', type: 'uint256' } + ], + name: 'setKickIncentive', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: '_minimum', type: 'uint256' }, + { internalType: 'uint256', name: '_maximum', type: 'uint256' } + ], + name: 'setStakeLimits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_staking', type: 'address' }], + name: 'setStakingContract', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { inputs: [], name: 'shutdown', outputs: [], stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [], + name: 'stakeOffsetOnLock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'stakingProxy', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'stakingToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: 'supply', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'uint256', name: '_epoch', type: 'uint256' }], + name: 'totalSupplyAtEpoch', + outputs: [{ internalType: 'uint256', name: 'supply', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' } + ], + name: 'userLocks', + outputs: [ + { internalType: 'uint112', name: 'amount', type: 'uint112' }, + { internalType: 'uint112', name: 'boosted', type: 'uint112' }, + { internalType: 'uint32', name: 'unlockTime', type: 'uint32' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' } + ], + name: 'userRewardPerTokenPaid', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '_withdrawTo', type: 'address' }], + name: 'withdrawExpiredLocksTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } +]; + +module.exports = { cvxLockerAbi }; diff --git a/src/adaptors/paladin-warlord/abi/WarLocker.js b/src/adaptors/paladin-warlord/abi/WarLocker.js new file mode 100644 index 0000000000..7e32623acc --- /dev/null +++ b/src/adaptors/paladin-warlord/abi/WarLocker.js @@ -0,0 +1,11 @@ +const warLockerAbi = [ + { + inputs: [], + name: 'getCurrentLockedTokens', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + } +]; + +module.exports = { warLockerAbi }; diff --git a/src/adaptors/paladin-warlord/abi/WarRedeemer.js b/src/adaptors/paladin-warlord/abi/WarRedeemer.js new file mode 100644 index 0000000000..dedf1ceb64 --- /dev/null +++ b/src/adaptors/paladin-warlord/abi/WarRedeemer.js @@ -0,0 +1,858 @@ +const warRedeemerAbi = [ + { + inputs: [ + { + internalType: 'address', + name: '_war', + type: 'address' + }, + { + internalType: 'address', + name: '_ratios', + type: 'address' + }, + { + internalType: 'address', + name: '_feeReceiver', + type: 'address' + }, + { + internalType: 'uint256', + name: '_redeemFee', + type: 'uint256' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + inputs: [], + name: 'AlreadyRedeemed', + type: 'error' + }, + { + inputs: [], + name: 'CallerNotPendingOwner', + type: 'error' + }, + { + inputs: [], + name: 'CannotBeOwner', + type: 'error' + }, + { + inputs: [], + name: 'CannotRedeemYet', + type: 'error' + }, + { + inputs: [], + name: 'EmptyArray', + type: 'error' + }, + { + inputs: [], + name: 'InvalidIndex', + type: 'error' + }, + { + inputs: [], + name: 'InvalidParameter', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: 'expected', + type: 'address' + }, + { + internalType: 'address', + name: 'actual', + type: 'address' + } + ], + name: 'MismatchingLocker', + type: 'error' + }, + { + inputs: [], + name: 'NotListedLocker', + type: 'error' + }, + { + inputs: [], + name: 'OwnerAddressZero', + type: 'error' + }, + { + inputs: [], + name: 'RecoverForbidden', + type: 'error' + }, + { + inputs: [], + name: 'ZeroAddress', + type: 'error' + }, + { + inputs: [], + name: 'ZeroValue', + type: 'error' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldFeeReceiver', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'newFeeReceiver', + type: 'address' + } + ], + name: 'FeeReceiverUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldMintRatio', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'newMintRatio', + type: 'address' + } + ], + name: 'MintRatioUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousPendingOwner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'newPendingOwner', + type: 'address' + } + ], + name: 'NewPendingOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'id', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemIndex', + type: 'uint256' + } + ], + name: 'NewRedeemTicket', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'OwnershipTransferred', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address' + } + ], + name: 'Paused', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldRedeemFee', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRedeemFee', + type: 'uint256' + } + ], + name: 'RedeemFeeUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address' + }, + { + indexed: false, + internalType: 'address', + name: 'receiver', + type: 'address' + }, + { + indexed: true, + internalType: 'uint256', + name: 'ticketNumber', + type: 'uint256' + } + ], + name: 'Redeemed', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'locker', + type: 'address' + } + ], + name: 'SetWarLocker', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address' + } + ], + name: 'Unpaused', + type: 'event' + }, + { + inputs: [], + name: 'MAX_BPS', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'UNIT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'feeReceiver', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getTokenWeights', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + } + ], + internalType: 'struct WarRedeemer.TokenWeight[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address' + } + ], + name: 'getUserActiveRedeemTickets', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'redeemIndex', + type: 'uint256' + }, + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'bool', + name: 'redeemed', + type: 'bool' + } + ], + internalType: 'struct WarRedeemer.RedeemTicket[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address' + } + ], + name: 'getUserRedeemTickets', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'redeemIndex', + type: 'uint256' + }, + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'bool', + name: 'redeemed', + type: 'bool' + } + ], + internalType: 'struct WarRedeemer.RedeemTicket[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + } + ], + name: 'joinQueue', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lockerTokens', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lockers', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + } + ], + name: 'notifyUnlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'paused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address' + } + ], + name: 'queuedForWithdrawal', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'ratios', + outputs: [ + { + internalType: 'contract IRatios', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address' + } + ], + name: 'recoverERC20', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: 'tickets', + type: 'uint256[]' + }, + { + internalType: 'address', + name: 'receiver', + type: 'address' + } + ], + name: 'redeem', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'redeemFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'newFeeReceiver', + type: 'address' + } + ], + name: 'setFeeReceiver', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'address', + name: 'warLocker', + type: 'address' + } + ], + name: 'setLocker', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'newRatios', + type: 'address' + } + ], + name: 'setRatios', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newRedeemFee', + type: 'uint256' + } + ], + name: 'setRedeemFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'tokenIndexes', + outputs: [ + { + internalType: 'uint256', + name: 'queueIndex', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'redeemIndex', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + name: 'tokens', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address' + } + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + name: 'userRedeems', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'redeemIndex', + type: 'uint256' + }, + { + internalType: 'address', + name: 'token', + type: 'address' + }, + { + internalType: 'bool', + name: 'redeemed', + type: 'bool' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'war', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + } +]; + +module.exports = { warRedeemerAbi }; diff --git a/src/adaptors/paladin-warlord/abi/WarStaker.js b/src/adaptors/paladin-warlord/abi/WarStaker.js new file mode 100644 index 0000000000..514687b08c --- /dev/null +++ b/src/adaptors/paladin-warlord/abi/WarStaker.js @@ -0,0 +1,484 @@ +const warStakerABI = [ + { + inputs: [{ internalType: 'address', name: '_warToken', type: 'address' }], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { inputs: [], name: 'AlreadyListedDepositor', type: 'error' }, + { inputs: [], name: 'CallerNotAllowed', type: 'error' }, + { inputs: [], name: 'CallerNotPendingOwner', type: 'error' }, + { inputs: [], name: 'CannotBeOwner', type: 'error' }, + { inputs: [], name: 'MismatchingFarmer', type: 'error' }, + { inputs: [], name: 'NotListedDepositor', type: 'error' }, + { inputs: [], name: 'NumberExceed128Bits', type: 'error' }, + { inputs: [], name: 'OwnerAddressZero', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { inputs: [], name: 'ZeroValue', type: 'error' }, + { + anonymous: false, + inputs: [{ indexed: true, internalType: 'address', name: 'depositor', type: 'address' }], + name: 'AddedRewardDepositor', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'spender', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'reward', type: 'address' }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'receiver', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'ClaimedRewards', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'previousPendingOwner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'newPendingOwner', type: 'address' } + ], + name: 'NewPendingOwner', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'rewardToken', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'endTimestamp', type: 'uint256' } + ], + name: 'NewRewards', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'previousOwner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'newOwner', type: 'address' } + ], + name: 'OwnershipTransferred', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, internalType: 'address', name: 'account', type: 'address' }], + name: 'Paused', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: true, internalType: 'address', name: 'depositor', type: 'address' }], + name: 'RemovedRewardDepositor', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'rewardToken', type: 'address' }, + { indexed: true, internalType: 'address', name: 'farmer', type: 'address' } + ], + name: 'SetRewardFarmer', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'claimer', type: 'address' } + ], + name: 'SetUserAllowedClaimer', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'caller', type: 'address' }, + { indexed: true, internalType: 'address', name: 'receiver', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'Staked', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' } + ], + name: 'Transfer', + type: 'event' + }, + { + anonymous: false, + inputs: [{ indexed: false, internalType: 'address', name: 'account', type: 'address' }], + name: 'Unpaused', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'receiver', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'Unstaked', + type: 'event' + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'depositor', type: 'address' }], + name: 'addRewardDepositor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' } + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'claimAllRewards', + outputs: [ + { + components: [ + { internalType: 'address', name: 'reward', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + internalType: 'struct WarStaker.UserClaimedRewards[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'reward', type: 'address' }, + { internalType: 'address', name: 'receiver', type: 'address' } + ], + name: 'claimRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' } + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'farmerLastIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'getRewardTokens', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'reward', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' } + ], + name: 'getUserAccruedRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'reward', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' } + ], + name: 'getUserRewardState', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'lastRewardPerToken', type: 'uint256' }, + { internalType: 'uint256', name: 'accruedRewards', type: 'uint256' } + ], + internalType: 'struct WarStaker.UserRewardState', + name: '', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserTotalClaimableRewards', + outputs: [ + { + components: [ + { internalType: 'address', name: 'reward', type: 'address' }, + { internalType: 'uint256', name: 'claimableAmount', type: 'uint256' } + ], + internalType: 'struct WarStaker.UserClaimableRewards[]', + name: '', + type: 'tuple[]' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'addedValue', type: 'uint256' } + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'reward', type: 'address' }], + name: 'lastRewardUpdateTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { inputs: [], name: 'pause', outputs: [], stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'rewardToken', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'queueRewards', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'depositor', type: 'address' }], + name: 'removeRewardDepositor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardDepositors', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardFarmers', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardStates', + outputs: [ + { internalType: 'uint256', name: 'rewardPerToken', type: 'uint256' }, + { internalType: 'uint128', name: 'lastUpdate', type: 'uint128' }, + { internalType: 'uint128', name: 'distributionEndTimestamp', type: 'uint128' }, + { internalType: 'uint256', name: 'ratePerSecond', type: 'uint256' }, + { internalType: 'uint256', name: 'currentRewardAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'queuedRewardAmount', type: 'uint256' } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewardTokens', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'rewardToken', type: 'address' }, + { internalType: 'address', name: 'farmer', type: 'address' } + ], + name: 'setRewardFarmer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' } + ], + name: 'stake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' } + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { inputs: [], name: 'unpause', outputs: [], stateMutability: 'nonpayable', type: 'function' }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' } + ], + name: 'unstake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'updateAllRewardStates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [{ internalType: 'address', name: 'reward', type: 'address' }], + name: 'updateRewardState', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'warToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function' + } +]; +module.exports = { warStakerABI }; diff --git a/src/adaptors/paladin-warlord/apy.js b/src/adaptors/paladin-warlord/apy.js new file mode 100644 index 0000000000..505612b0fe --- /dev/null +++ b/src/adaptors/paladin-warlord/apy.js @@ -0,0 +1,216 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); +const { warLockerAbi } = require('./abi/WarLocker'); +const { warRedeemerAbi } = require('./abi/WarRedeemer'); +const { getTotalPricePerToken, fetchRewardStates } = require('./utils'); +const { cvxLockerAbi } = require('./abi/CvxLocker'); + +const WAR_ADDRESS = '0xa8258deE2a677874a48F5320670A869D74f0cbC1'; +const WAR_STAKER_ADDRESS = '0xA86c53AF3aadF20bE5d7a8136ACfdbC4B074758A'; +const WAR_CVX_LOCKER_ADDRESS = '0x700d6d24A55512c6AEC08820B49da4e4193105B3'; +const WAR_AURA_LOCKER_ADDRESS = '0x7B90e043aaC79AdeA0Dbb0690E3c832757207a3B'; +const REDEEMER_ADDRESS = '0x4787Ef084c1d57ED87D58a716d991F8A9CD3828C'; +const AURA_ADDRESS = '0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF'; +const CVX_ADDRESS = '0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B'; +const CVX_LOCKER_ADDRESS = '0x72a19342e8F1838460eBFCCEf09F6585e32db86E'; +const CVXCRV_ADDRESS = '0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7'; +const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const PAL_ADDRESS = '0xAB846Fb6C81370327e784Ae7CbB6d6a6af6Ff4BF'; + +const computeTotalTvl = async (auraLocked, cvxLocked, auraQueued, cvxQueued) => { + const auraAmount = Number(auraLocked / ethers.BigNumber.from(1e12)) / 1000000; + const cvxAmount = Number(cvxLocked / ethers.BigNumber.from(1e12)) / 1000000; + + const warlordTVL = + (await getTotalPricePerToken(auraAmount, AURA_ADDRESS)) + + (await getTotalPricePerToken(cvxAmount, CVX_ADDRESS)); + return warlordTVL; +} + +const computeActiveTvl = async ( + totalWarLocked, + warSupply, + auraLocked, + cvxLocked, + auraQueued, + cvxQueued +) => { + const auraAmount = + Number(((auraLocked - auraQueued) * totalWarLocked) / (warSupply * ethers.BigNumber.from(1e15))) / + 1000; + const cvxAmount = + Number(((cvxLocked - cvxQueued) * totalWarLocked) / (warSupply * ethers.BigNumber.from(1e15))) / + 1000; + + const warlordTVL = + (await getTotalPricePerToken(auraAmount, AURA_ADDRESS)) + + (await getTotalPricePerToken(cvxAmount, CVX_ADDRESS)); + return warlordTVL; +} + +const computeCrvCvxApr = async (rewardData, lockedSupply, cvxLocked, tvl) => { + const cvxCrvAmount = + Number( + (rewardData[2] * ethers.BigNumber.from(86400) * ethers.BigNumber.from(365) * cvxLocked) / + lockedSupply / + ethers.BigNumber.from(1e14) + ) / 10000; + const cvxCrvDollar = await getTotalPricePerToken(cvxCrvAmount, CVXCRV_ADDRESS); + const cvxCrvApr = cvxCrvDollar / tvl; + return cvxCrvApr; +} + +const computeAuraBalApr = async (totalWarLocked, warSupply, auraLocked, cvxLocked, breakdownResponse) => { + let amount = 0; + for (const apr of breakdownResponse.data.data.locker.aprs.breakdown) { + if (apr.name == "Aura BAL") { + amount += apr.value; + } + } + return ( + (amount * + ((Number(auraLocked) / Number(cvxLocked) / 10) * + (Number(warSupply) / Number(totalWarLocked)))) / + 100 + ); +} + +const computeWarApr = async (warRates, auraLocked, cvxLocked, auraQueued, cvxQueued, warSupply, tvl) => { + if (warRates[2] * ethers.BigNumber.from(1000) <= new Date().valueOf()) return 0; + + const warAmount = warRates[3] * ethers.BigNumber.from(86400) * ethers.BigNumber.from(365); + + const cvxAmount = + Number(((cvxLocked - cvxQueued) * warAmount) / warSupply / ethers.BigNumber.from(1e14)) / 10000; + const auraAmount = + Number(((auraLocked - auraQueued) * warAmount) / warSupply / ethers.BigNumber.from(1e14)) / 10000; + + const cvxDollar = await getTotalPricePerToken(cvxAmount, CVX_ADDRESS); + const auraDollar = await getTotalPricePerToken(auraAmount, AURA_ADDRESS); + + const warDollar = cvxDollar + auraDollar; + const warApr = warDollar / tvl; + + return warApr; +} + +const computeWethApr = async (wethRates, tvl) => { + if (wethRates[2] * ethers.BigNumber.from(1000) <= new Date().valueOf()) return 0; + + const wethAmount = wethRates[3] * ethers.BigNumber.from(86400) * ethers.BigNumber.from(365); + + const wethDollar = await getTotalPricePerToken( + Number(wethAmount / ethers.BigNumber.from(1e12)) / 1000000, + WETH_ADDRESS + ); + + const wethApr = wethDollar / tvl; + return wethApr; +} + +const computePalApr = async (palRates, tvl) => { + if (palRates[2] * ethers.BigNumber.from(1000) <= new Date().valueOf()) return 0; + + const palAmount = palRates[3] * ethers.BigNumber.from(86400) * ethers.BigNumber.from(365); + + const palDollar = await getTotalPricePerToken( + Number(palAmount / ethers.BigNumber.from(1e14)) / 10000, + PAL_ADDRESS + ); + const palApr = palDollar / tvl; + return palApr; +} + + + +const apy = async () => { + const warRates = await fetchRewardStates(WAR_ADDRESS); + const wethRates = await fetchRewardStates(WETH_ADDRESS); + const palRates = await fetchRewardStates(PAL_ADDRESS); + const { output: rewardData } = await sdk.api.abi.call({ + abi: cvxLockerAbi.find((a) => a.name === 'rewardData'), + target: CVX_LOCKER_ADDRESS, + params: [CVXCRV_ADDRESS], + }); + const { output: lockedSupply } = await sdk.api.abi.call({ + abi: cvxLockerAbi.find((a) => a.name === 'lockedSupply'), + target: CVX_LOCKER_ADDRESS, + }); + const {output: totalWarLocked} = await sdk.api.erc20.balanceOf({ + target: WAR_ADDRESS, + owner: WAR_STAKER_ADDRESS, + }); + const { output: totalSupply } = await sdk.api.erc20.totalSupply({ + target: WAR_ADDRESS, + }) + const { output: auraLocked } = await sdk.api.abi.call({ + abi: warLockerAbi[0], + target: WAR_AURA_LOCKER_ADDRESS, + }); + const { output: cvxLocked } = await sdk.api.abi.call({ + abi: warLockerAbi[0], + target: WAR_CVX_LOCKER_ADDRESS, + }); + const {output: auraQueued} = await sdk.api.abi.call({ + abi: warRedeemerAbi.find((a) => a.name === 'queuedForWithdrawal'), + target: REDEEMER_ADDRESS, + params: [AURA_ADDRESS] + }); + const {output: cvxQueued} = await sdk.api.abi.call({ + abi: warRedeemerAbi.find((a) => a.name === 'queuedForWithdrawal'), + target: REDEEMER_ADDRESS, + params: [CVX_ADDRESS] + }); + + const breakdownResponse = await axios.post('https://data.aura.finance/graphql', { + query: + '{\n locker {\n aprs {\n breakdown {\n value,\nname },\n }\n }\n \n}\n \n ' + }); + + const totalTvl = await computeTotalTvl( + auraLocked, + cvxLocked, + auraQueued, + cvxQueued + ); + const activeTvl = await computeActiveTvl( + ethers.BigNumber.from(totalWarLocked), + ethers.BigNumber.from(totalSupply), + auraLocked, + cvxLocked, + auraQueued, + cvxQueued + ); + const auraBalApr = await computeAuraBalApr( + ethers.BigNumber.from(totalWarLocked), + ethers.BigNumber.from(totalSupply), + auraLocked, + cvxLocked, + breakdownResponse + ); + const warApr = await computeWarApr( + warRates, + auraLocked, + cvxLocked, + auraQueued, + cvxQueued, + ethers.BigNumber.from(totalSupply), + activeTvl + ); + const wethApr = await computeWethApr(wethRates, activeTvl); + const palApr = await computePalApr(palRates, activeTvl); + const cvxCrvApr = await computeCrvCvxApr(rewardData, lockedSupply, cvxLocked, activeTvl); + + const totalApr = warApr + wethApr + palApr + cvxCrvApr + auraBalApr; + return [{ + pool: `warlord-ethereum`, + project: 'paladin-warlord', + chain: 'ethereum', + symbol: 'WAR', + apyBase: totalApr * 100, + tvlUsd: totalTvl, + }]; +} + +module.exports = apy; \ No newline at end of file diff --git a/src/adaptors/paladin-warlord/index.js b/src/adaptors/paladin-warlord/index.js new file mode 100644 index 0000000000..2379369c98 --- /dev/null +++ b/src/adaptors/paladin-warlord/index.js @@ -0,0 +1,7 @@ +const apy = require('./apy'); + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://warlord.paladin.vote/', +}; \ No newline at end of file diff --git a/src/adaptors/paladin-warlord/utils.js b/src/adaptors/paladin-warlord/utils.js new file mode 100644 index 0000000000..a12b18a2c9 --- /dev/null +++ b/src/adaptors/paladin-warlord/utils.js @@ -0,0 +1,42 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { warStakerABI } = require('./abi/WarStaker'); + +const WAR_STAKER_ADDRESS = '0xA86c53AF3aadF20bE5d7a8136ACfdbC4B074758A'; + +const getLlamaPrice = async (tokenAddress) => { + const res = await axios.get(`https://coins.llama.fi/prices/current/ethereum:${tokenAddress}`); + return res.data.coins[`ethereum:${tokenAddress}`].price; +}; + +const getCoingeckoPrice = async (tokenAddress) => { + const res = await axios.get( + `https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses=${tokenAddress}&vs_currencies=usd` + ); + return res.data[tokenAddress].usd; +}; + +const getTotalPricePerToken = async ( + tokenAmount, + tokenAddress +) => { + tokenAddress = tokenAddress.toLowerCase(); + const tokenPrice = await getLlamaPrice(tokenAddress).catch(() => + getCoingeckoPrice(tokenAddress).catch(() => 0) + ); + return tokenPrice * tokenAmount; +}; + +const fetchRewardStates = async (tokenAddress) => { + const res = await sdk.api.abi.call({ + abi: warStakerABI.find((a) => a.name === 'rewardStates'), + target: WAR_STAKER_ADDRESS, + params: tokenAddress, + }); + return res.output; +} + +module.exports = { + getTotalPricePerToken, + fetchRewardStates, +}; \ No newline at end of file diff --git a/src/adaptors/pancakeswap-amm-v3/cakeReward.js b/src/adaptors/pancakeswap-amm-v3/cakeReward.js new file mode 100644 index 0000000000..a983e05d31 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/cakeReward.js @@ -0,0 +1,243 @@ +const abiMcV3 = require('./masterchefv3.json'); +const abiMcV3Arbitrum = require('./masterchefv3Arbitrum.json'); +const abiMcV3PolygonZkevm = require('./masterchefv3PolygonZkevm.json'); + +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const bn = require('bignumber.js'); +const fetch = require('node-fetch'); + +const CAKE = { + ethereum: '0x152649eA73beAb28c5b49B26eb48f7EAD6d4c898', + bsc: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + polygon_zkevm: '0x0D1E753a25eBda689453309112904807625bEFBe2', + era: '0x3A287a06c66f9E95a56327185cA2BDF5f031cEcD', + arbitrum: '0x1b896893dfc86bb67Cf57767298b9073D2c1bA2c', + base: '0x3055913c90Fcc1A6CE9a358911721eEb942013A1', + linea: '0x0D1E753a25eBda689453309112904807625bEFBe', + op_bnb: '0x2779106e4F4A8A28d77A24c18283651a2AE22D1C', +}; + +const chainIds = { + ethereum: { + id: 1, + mchef: '0x556B9306565093C855AEA9AE92A594704c2Cd59e', + abi: abiMcV3, + }, + bsc: { + id: 56, + mchef: '0x556B9306565093C855AEA9AE92A594704c2Cd59e', + abi: abiMcV3, + }, + polygon_zkevm: { + id: 1101, + mchef: '0xe9c7f3196ab8c09f6616365e8873daeb207c0391', + abi: abiMcV3PolygonZkevm, + }, + arbitrum: { + id: 42161, + mchef: '0x5e09ACf80C0296740eC5d6F643005a4ef8DaA694', + abi: abiMcV3Arbitrum, + }, + era: { + id: 324, + mchef: '0x4c615E78c5fCA1Ad31e4d66eb0D8688d84307463', + abi: abiMcV3Arbitrum, + }, + linea: { + id: 59144, + mchef: '0x22E2f236065B780FA33EC8C4E58b99ebc8B55c57', + abi: abiMcV3Arbitrum, + }, + op_bnb: { + id: 204, + mchef: '0x05ddEDd07C51739d2aE21F6A9d97a8d69C2C3aaA', + abi: abiMcV3Arbitrum, + }, + base: { + id: 8453, + mchef: '0xC6A2Db661D5a5690172d8eB0a7DEA2d3008665A3', + abi: abiMcV3Arbitrum + } +}; + +const getCakeAprs = async (chain) => { + if (chainIds[chain] === undefined) return []; + + const masterChef = chainIds[chain].mchef; + const abi = chainIds[chain].abi; + + const poolLength = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'poolLength'), + target: masterChef, + chain, + }) + .then((o) => o.output); + const totalAllocPoint = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'totalAllocPoint'), + target: masterChef, + chain, + }) + .then((o) => o.output); + const latestPeriodCakePerSecond = await sdk.api.abi + .call({ + abi: abi.find((m) => m.name === 'latestPeriodCakePerSecond'), + target: masterChef, + chain, + }) + .then((o) => o.output); + + const cakePerSecond = new bn(latestPeriodCakePerSecond.toString()) + .div(1e18) + .div(1e12) + .toString(); + + const poolInfoCalls = Array.from({ length: +poolLength + 1 }) + .map((_, i) => i) + .filter((i) => i !== 0) + .map((i) => { + return { + target: masterChef, + params: i, + }; + }); + + const poolInfos = await sdk.api.abi + .multiCall({ + abi: abi.find((m) => m.name === 'poolInfo'), + calls: poolInfoCalls, + chain, + }) + .then((o) => + o.output + .map((r) => r.output) + .filter((r) => r.allocPoint !== '0' && r.totalLiquidity !== '0') + ); + + // Getting in range token amounts staked in MasterChef v3 + // https://github.com/pancakeswap/pancake-frontend/blob/develop/apis/farms/src/v3.ts + const allStakedTVL = await Promise.allSettled( + poolInfos.map((p) => { + return fetch( + `https://farms-api.pancakeswap.com/v3/${chainIds[chain].id}/liquidity/${p.v3Pool}` + ) + .then((r) => r.json()) + .catch((err) => { + console.log(err); + }); + }) + ); + + // by lp address + const tvls = {}; + + for (const [index, allStakedTVLResult] of allStakedTVL.entries()) { + if (allStakedTVLResult.status === 'fulfilled' && 'formatted' in allStakedTVLResult.value) { + tvls[poolInfos[index].v3Pool] = allStakedTVLResult.value.formatted; + } + } + + const allTokens = [ + ...new Set(poolInfos.map((p) => [p.token0, p.token1]).flat()), + ]; + + const { cakePrice, prices } = await getBaseTokensPrice(allTokens, chain); + + // by lp address + const tvlsUSD = Object.entries(tvls).reduce((acc, [lp, tvl]) => { + const poolInfo = poolInfos.find((p) => p.v3Pool === lp); + const token0 = poolInfo.token0; + const token1 = poolInfo.token1; + const token0Price = prices[`${chain}:${token0}`]?.price; + const token1Price = prices[`${chain}:${token1}`]?.price; + if (!token0Price) { + console.log('missing token price', `${chain}:${token0}`); + return acc; + } + if (!token1Price) { + console.log('missing token price', `${chain}:${token1}`); + return acc; + } + const token0Amount = new bn(tvl.token0); + const token1Amount = new bn(tvl.token1); + const tvlUSD = token0Amount + .times(token0Price) + .plus(token1Amount.times(token1Price)); + return { + [lp]: tvlUSD.toString(), + ...acc, + }; + }, {}); + + const cakeAPRs = poolInfos.reduce((cakeAprs, poolInfo) => { + const v3Pool = poolInfo.v3Pool; + const allocPoint = poolInfo.allocPoint; + const cakeApr = calucCakeAPR( + cakePerSecond, + totalAllocPoint, + allocPoint, + cakePrice, + tvlsUSD[v3Pool] + ); + return { + [v3Pool.toLowerCase()]: cakeApr, + ...cakeAprs, + }; + }, {}); + + return cakeAPRs; +}; + +// Cake APR (global) = (cakePerSecond * 31536000) / (totalAllocPoint / pool.allocPoint) * 100 * cakeUSD / totalStakedLiquidityUSD +const calucCakeAPR = ( + cakePerSecond, + totalAllocPoint, + poolAllocPoint, + cakeUSD, + totalStakedLiquidityUSD +) => { + if (!Number.isFinite(+totalStakedLiquidityUSD)) { + return 0; + } + return new bn(cakePerSecond) + .times(31536000) + .div(new bn(totalAllocPoint).div(poolAllocPoint)) + .times(100) + .times(cakeUSD) + .div(totalStakedLiquidityUSD) + .toNumber(); +}; + +const getBaseTokensPrice = async (allTokens, chain) => { + let priceKeys = { + // only use BSC cake price for consistent + cake: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + }; + + let prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${Object.values(priceKeys) + .map((t) => `bsc:${t}`) + .concat(allTokens.map((t) => `${chain}:${t}`)) + .join(',')}` + ) + ).coins; + + const cakePriceData = prices[`bsc:${priceKeys.cake}`]; + + const cakeId = `${chain}:${CAKE[chain]}`; + + if (CAKE[chain] && !prices[cakeId]) { + prices[cakeId] = cakePriceData; + } + + return { cakePrice: cakePriceData.price, prices }; +}; + +module.exports = { + getCakeAprs, + CAKE, + chainIds, +}; diff --git a/src/adaptors/pancakeswap-amm-v3/estimateFee.ts b/src/adaptors/pancakeswap-amm-v3/estimateFee.ts new file mode 100644 index 0000000000..e0744e2250 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/estimateFee.ts @@ -0,0 +1,248 @@ +// forked from see https://github.com/chunza2542/uniswap.fish + +const bn = require('bignumber.js'); + +interface Tick { + tickIdx: string; + liquidityNet: string; + price0: string; + price1: string; +} + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = ( + price: number, + token0Decimal: string, + token1Decimal: string +): number => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 1) +interface TokensAmount { + amount0: number; + amount1: number; +} +const getTokensAmountFromDepositAmountUSD = ( + P: number, + Pl: number, + Pu: number, + priceUSDX: number, + priceUSDY: number, + depositAmountUSD: number +): TokensAmount => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount0: bn +): bn => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount1: bn +): bn => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = ( + price: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P: number, + lowerP: number, + upperP: number, + amount0: number, + amount1: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity: bn; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +const estimateFee = ( + liquidityDelta: bn, + liquidity: bn, + volume24H: number, + feeTier: string +): number => { + const feeTierPercentage = getFeeTierPercentage(feeTier); + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + + return feeTierPercentage * volume24H * liquidityPercentage; +}; + +const getLiquidityFromTick = (poolTicks: Tick[], tick: number): bn => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity: bn = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price: number | string | bn): bn => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n: number | string | bn, exp: number): bn => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a: bn, b: bn, multiplier: bn) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getFeeTierPercentage = (tier: string): number => { + if (tier === '100') return 0.01 / 100; + if (tier === '500') return 0.05 / 100; + if (tier === '2500') return 0.25 / 100; + if (tier === '10000') return 1 / 100; + return 0; +}; + +const FEE_BASE = 10_000; + +function parseProtocolFees(feeProtocol) { + const packed = Number(feeProtocol); + if (Number.isNaN(packed)) { + throw new Error(`Invalid fee protocol ${feeProtocol}`); + } + + const token0ProtocolFee = packed % 2 ** 16; + const token1ProtocolFee = packed >> 16; + return [token0ProtocolFee / FEE_BASE, token1ProtocolFee / FEE_BASE]; +} + +module.exports.EstimatedFees = ( + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + feeTier, + volume, + feeProtocol, + poolTicks +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + // For now the protocol fee is the same on both tokens so here we just use the fee on token0 + const [protocolFee] = parseProtocolFees(feeProtocol); + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const estimatedFee = + P >= Pl && P <= Pu ? estimateFee(deltaL, L, volume, feeTier) : 0; + + const estimatedFeeAfterProtocolFee = estimatedFee * (1 - protocolFee); + + return estimatedFeeAfterProtocolFee; +}; diff --git a/src/adaptors/pancakeswap-amm-v3/index.js b/src/adaptors/pancakeswap-amm-v3/index.js new file mode 100644 index 0000000000..170549e537 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/index.js @@ -0,0 +1,370 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); + +const utils = require('../utils'); +const { EstimatedFees } = require('./estimateFee'); +const { getCakeAprs, CAKE, chainIds } = require('./cakeReward'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + 'CJYGNhb7RvnhfBDjqpRnD3oxgyhibzc7fkAMa38YV3oS' + ), + // temp disable bsc + // bsc: sdk.graph.modifyEndpoint('Hv1GncLY5docZoGtXjo4kwbTvxm3MAhVZqBZE4sUT9eZ'), + polygon_zkevm: + 'https://api.studio.thegraph.com/query/45376/exchange-v3-polygon-zkevm/version/latest', + era: 'https://api.studio.thegraph.com/query/45376/exchange-v3-zksync/version/latest', + arbitrum: sdk.graph.modifyEndpoint( + '251MHFNN1rwjErXD2efWMpNS73SANZN8Ua192zw6iXve' + ), + op_bnb: 'https://proxy-worker-dev.pancake-swap.workers.dev/opbnb-exchange-v3', + linea: + 'https://graph-query.linea.build/subgraphs/name/pancakeswap/exchange-v3-linea', + base: sdk.graph.modifyEndpoint( + 'BHWNsedAHtmTCzXxCCDfhPmm6iN9rxUhoRHdHKyujic3' + ), +}; + +const cakeByFormatChain = Object.keys(chains).reduce((acc, chain) => { + acc[utils.formatChain(chain)] = CAKE[chain]; + return acc; +}, {}); + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + feeProtocol + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + const balanceCalls = dataNow.flatMap((pool) => [ + { target: pool.token0.id, params: pool.id }, + { target: pool.token1.id, params: pool.id }, + ]); + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + const balancesByPool = tokenBalances.output.reduce( + (acc, { input, output }) => { + const poolId = input.params[0]; + if (!acc[poolId]) acc[poolId] = {}; + acc[poolId][input.target.toLowerCase()] = output ?? '0'; + return acc; + }, + {} + ); + + dataNow = dataNow.map((pool) => { + const poolBalances = balancesByPool[pool.id] || {}; + const reserve0Raw = poolBalances[pool.token0.id.toLowerCase()]; + const reserve1Raw = poolBalances[pool.token1.id.toLowerCase()]; + + const reserve0 = reserve0Raw + ? Number(reserve0Raw) / 10 ** Number(pool.token0.decimals) + : Number(pool.totalValueLockedToken0); + const reserve1 = reserve1Raw + ? Number(reserve1Raw) / 10 ** Number(pool.token1.decimals) + : Number(pool.totalValueLockedToken1); + + return { + ...pool, + reserve0, + reserve1, + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = true; + if (enableV3Apy && dataNow.length) { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // batching the tick query into 3 chunks to prevent it from breaking + const nbBatches = 3; + const chunkSize = Math.ceil(dataNow.length / nbBatches); + const chunks = [ + dataNow.slice(0, chunkSize).map((i) => i.id), + dataNow.slice(chunkSize, chunkSize * 2).map((i) => i.id), + dataNow.slice(chunkSize * 2, dataNow.length).map((i) => i.id), + ]; + + const tickData = {}; + // we fetch 3 pages for each pool + for (const page of [0, 1, 2]) { + console.log(`page nb: ${page}`); + let pageResults = {}; + for (const chunk of chunks) { + console.log(chunk.length); + if (!chunk.length) continue; + const tickQuery = ` + query { + ${chunk + .map( + (poolAddress, index) => ` + pool_${poolAddress}: ticks( + first: 1000, + skip: ${page * 1000}, + where: { poolAddress: "${poolAddress}" }, + orderBy: tickIdx + ) { + tickIdx + liquidityNet + price0 + price1 + } + ` + ) + .join('\n')} + } + `; + + try { + const response = await request(url, tickQuery); + pageResults = { ...pageResults, ...response }; + } catch (err) { + console.log(err); + } + } + tickData[`page_${page}`] = pageResults; + } + + // reformat tickData + const ticks = {}; + Object.values(tickData).forEach((page) => { + Object.entries(page).forEach(([pool, values]) => { + if (!ticks[pool]) { + ticks[pool] = []; + } + ticks[pool] = ticks[pool].concat(values); + }); + }); + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + dataNow = dataNow.map((p) => { + const poolTicks = ticks[`pool_${p.id}`] ?? []; + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${p.id}`); + return { ...p, estimatedFee: null, apy7d: null }; + } + + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + const estimatedFee = EstimatedFees( + priceAssumption, + [p.token1_in_token0 * (1 - delta), p.token1_in_token0 * (1 + delta)], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + p.volumeUSD7d, + p.feeProtocol, + poolTicks + ); + + const apy7d = ((estimatedFee * 52) / investmentAmount) * 100; + + return { ...p, estimatedFee, apy7d }; + }); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + + const chainId = chainIds[chainString].id; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://pancakeswap.finance/add/${token0}/${token1}/${feeTier}?chainId=${chainId}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'pancakeswap-amm-v3', + poolMeta: poolMeta, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + let cakeAPRsByChain = {}; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + try { + // cakeAPRsByChain[utils.formatChain(chain)] = await getCakeAprs(chain); + + data.push( + await topLvl( + chain, + url, + query, + queryPrior, + 'v3', + timestamp, + stablecoins + ) + ); + } catch (err) { + console.log(err); + } + } + + return data + .flat() + .filter((p) => utils.keepFinite(p)) + .map((p) => { + if ( + cakeAPRsByChain[p.chain] && + cakeAPRsByChain[p.chain] && + cakeAPRsByChain[p.chain][p.pool] + ) { + return { + ...p, + apyReward: cakeAPRsByChain[p.chain][p.pool], + rewardTokens: [ + cakeByFormatChain[p.chain] ?? + '0x152649eA73beAb28c5b49B26eb48f7EAD6d4c898', + ], + }; + } + return p; + }); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/pancakeswap-amm-v3/masterchefv3.json b/src/adaptors/pancakeswap-amm-v3/masterchefv3.json new file mode 100644 index 0000000000..b9b58388f5 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/masterchefv3.json @@ -0,0 +1,676 @@ +[ + { + "inputs": [ + { "internalType": "contract IERC20", "name": "_CAKE", "type": "address" }, + { + "internalType": "contract INonfungiblePositionManager", + "name": "_nonfungiblePositionManager", + "type": "address" + }, + { "internalType": "address", "name": "_WETH", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [{ "internalType": "uint256", "name": "pid", "type": "uint256" }], + "name": "DuplicatedPool", + "type": "error" + }, + { "inputs": [], "name": "InconsistentAmount", "type": "error" }, + { "inputs": [], "name": "InsufficientAmount", "type": "error" }, + { "inputs": [], "name": "InvalidNFT", "type": "error" }, + { "inputs": [], "name": "InvalidPeriodDuration", "type": "error" }, + { "inputs": [], "name": "InvalidPid", "type": "error" }, + { "inputs": [], "name": "NoBalance", "type": "error" }, + { "inputs": [], "name": "NoLMPool", "type": "error" }, + { "inputs": [], "name": "NoLiquidity", "type": "error" }, + { "inputs": [], "name": "NotEmpty", "type": "error" }, + { "inputs": [], "name": "NotOwner", "type": "error" }, + { "inputs": [], "name": "NotOwnerOrOperator", "type": "error" }, + { "inputs": [], "name": "NotPancakeNFT", "type": "error" }, + { "inputs": [], "name": "WrongReceiver", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { "indexed": true, "internalType": "contract IPancakeV3Pool", "name": "v3Pool", "type": "address" }, + { "indexed": true, "internalType": "contract ILMPool", "name": "lmPool", "type": "address" } + ], + "name": "AddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": true, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "indexed": false, "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "indexed": false, "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": true, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "deployer", "type": "address" }], + "name": "NewLMPoolDeployerAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "operator", "type": "address" }], + "name": "NewOperatorAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint256", "name": "periodDuration", "type": "uint256" }], + "name": "NewPeriodDuration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "address", "name": "receiver", "type": "address" }], + "name": "NewReceiver", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "periodNumber", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "startTime", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "endTime", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "cakeAmount", "type": "uint256" } + ], + "name": "NewUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "bool", "name": "emergency", "type": "bool" }], + "name": "SetEmergency", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "allocPoint", "type": "uint256" } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "farmBoostContract", "type": "address" }], + "name": "UpdateFarmBoostContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": true, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "indexed": false, "internalType": "int128", "name": "liquidity", "type": "int128" }, + { "indexed": false, "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "indexed": false, "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "UpdateLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "uint256", "name": "periodNumber", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "oldEndTime", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newEndTime", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "remainingCake", "type": "uint256" } + ], + "name": "UpdateUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "indexed": true, "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CAKE", + "outputs": [{ "internalType": "contract IERC20", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FARM_BOOSTER", + "outputs": [{ "internalType": "contract IFarmBooster", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LMPoolDeployer", + "outputs": [{ "internalType": "contract ILMPoolDeployer", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERIOD_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { "internalType": "contract IPancakeV3Pool", "name": "_v3Pool", "type": "address" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_tokenId", "type": "uint256" }], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cakeAmountBelongToMC", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint128", "name": "amount0Max", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint128", "name": "amount0Max", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "collectTo", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0Min", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Min", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergency", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_v3Pool", "type": "address" }], + "name": "getLatestPeriodInfo", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_pid", "type": "uint256" }], + "name": "getLatestPeriodInfoByPid", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "harvest", + "outputs": [{ "internalType": "uint256", "name": "reward", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "amount0Desired", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Desired", "type": "uint256" }, + { "internalType": "uint256", "name": "amount0Min", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Min", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodCakePerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodEndTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodStartTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }], + "name": "multicall", + "outputs": [{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "nonfungiblePositionManager", + "outputs": [{ "internalType": "contract INonfungiblePositionManager", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operatorAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_tokenId", "type": "uint256" }], + "name": "pendingCake", + "outputs": [{ "internalType": "uint256", "name": "reward", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { "internalType": "contract IPancakeV3Pool", "name": "v3Pool", "type": "address" }, + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { "internalType": "uint256", "name": "totalLiquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "totalBoostLiquidity", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "receiver", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_emergency", "type": "bool" }], + "name": "setEmergency", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract ILMPoolDeployer", "name": "_LMPoolDeployer", "type": "address" }], + "name": "setLMPoolDeployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_operatorAddress", "type": "address" }], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_periodDuration", "type": "uint256" }], + "name": "setPeriodDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_receiver", "type": "address" }], + "name": "setReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_newMultiplier", "type": "uint256" } + ], + "name": "updateBoostMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_newFarmBoostContract", "type": "address" }], + "name": "updateFarmBoostContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_tokenId", "type": "uint256" }], + "name": "updateLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256[]", "name": "pids", "type": "uint256[]" }], + "name": "updatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_duration", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "upkeep", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "userPositionInfos", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint128", "name": "boostLiquidity", "type": "uint128" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint256", "name": "rewardGrowthInside", "type": "uint256" }, + { "internalType": "uint256", "name": "reward", "type": "uint256" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { "internalType": "uint256", "name": "boostMultiplier", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "v3PoolAddressPid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "reward", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/pancakeswap-amm-v3/masterchefv3Arbitrum.json b/src/adaptors/pancakeswap-amm-v3/masterchefv3Arbitrum.json new file mode 100644 index 0000000000..df0b506982 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/masterchefv3Arbitrum.json @@ -0,0 +1,1044 @@ +[ + { + "inputs": [ + { "internalType": "contract IERC20", "name": "_CAKE", "type": "address" }, + { + "internalType": "contract INonfungiblePositionManager", + "name": "_nonfungiblePositionManager", + "type": "address" + }, + { "internalType": "address", "name": "_WETH", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [{ "internalType": "uint256", "name": "pid", "type": "uint256" }], + "name": "DuplicatedPool", + "type": "error" + }, + { "inputs": [], "name": "InconsistentAmount", "type": "error" }, + { "inputs": [], "name": "InsufficientAmount", "type": "error" }, + { "inputs": [], "name": "InvalidNFT", "type": "error" }, + { "inputs": [], "name": "InvalidPeriodDuration", "type": "error" }, + { "inputs": [], "name": "InvalidPid", "type": "error" }, + { "inputs": [], "name": "NoBalance", "type": "error" }, + { "inputs": [], "name": "NoLMPool", "type": "error" }, + { "inputs": [], "name": "NoLiquidity", "type": "error" }, + { "inputs": [], "name": "NotEmpty", "type": "error" }, + { "inputs": [], "name": "NotOwner", "type": "error" }, + { "inputs": [], "name": "NotOwnerOrOperator", "type": "error" }, + { "inputs": [], "name": "NotPancakeNFT", "type": "error" }, + { "inputs": [], "name": "WrongReceiver", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IPancakeV3Pool", + "name": "v3Pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ILMPool", + "name": "lmPool", + "type": "address" + } + ], + "name": "AddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "NewLMPoolDeployerAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "NewOperatorAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "periodDuration", + "type": "uint256" + } + ], + "name": "NewPeriodDuration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "NewReceiver", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "periodNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cakePerSecond", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cakeAmount", + "type": "uint256" + } + ], + "name": "NewUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "emergency", + "type": "bool" + } + ], + "name": "SetEmergency", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "farmBoostContract", + "type": "address" + } + ], + "name": "UpdateFarmBoostContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int128", + "name": "liquidity", + "type": "int128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "UpdateLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "periodNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingCake", + "type": "uint256" + } + ], + "name": "UpdateUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CAKE", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FARM_BOOSTER", + "outputs": [ + { "internalType": "contract IFarmBooster", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LMPoolDeployer", + "outputs": [ + { + "internalType": "contract ILMPoolDeployer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERIOD_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { + "internalType": "contract IPancakeV3Pool", + "name": "_v3Pool", + "type": "address" + }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cakeAmountBelongToMC", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "collectTo", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergency", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_v3Pool", "type": "address" } + ], + "name": "getLatestPeriodInfo", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getLatestPeriodInfoByPid", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "harvest", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodCakePerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodEndTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodStartTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "nonfungiblePositionManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operatorAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "pendingCake", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { + "internalType": "contract IPancakeV3Pool", + "name": "v3Pool", + "type": "address" + }, + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { + "internalType": "uint256", + "name": "totalLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostLiquidity", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "receiver", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_emergency", "type": "bool" } + ], + "name": "setEmergency", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILMPoolDeployer", + "name": "_LMPoolDeployer", + "type": "address" + } + ], + "name": "setLMPoolDeployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operatorAddress", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_periodDuration", + "type": "uint256" + } + ], + "name": "setPeriodDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "setReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_newMultiplier", "type": "uint256" } + ], + "name": "updateBoostMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newFarmBoostContract", + "type": "address" + } + ], + "name": "updateFarmBoostContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "updateLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "pids", "type": "uint256[]" } + ], + "name": "updatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_duration", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "upkeep", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "userPositionInfos", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint128", + "name": "boostLiquidity", + "type": "uint128" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint256", + "name": "rewardGrowthInside", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reward", "type": "uint256" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { + "internalType": "uint256", + "name": "boostMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "v3PoolAddressPid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/pancakeswap-amm-v3/masterchefv3PolygonZkevm.json b/src/adaptors/pancakeswap-amm-v3/masterchefv3PolygonZkevm.json new file mode 100644 index 0000000000..df0b506982 --- /dev/null +++ b/src/adaptors/pancakeswap-amm-v3/masterchefv3PolygonZkevm.json @@ -0,0 +1,1044 @@ +[ + { + "inputs": [ + { "internalType": "contract IERC20", "name": "_CAKE", "type": "address" }, + { + "internalType": "contract INonfungiblePositionManager", + "name": "_nonfungiblePositionManager", + "type": "address" + }, + { "internalType": "address", "name": "_WETH", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [{ "internalType": "uint256", "name": "pid", "type": "uint256" }], + "name": "DuplicatedPool", + "type": "error" + }, + { "inputs": [], "name": "InconsistentAmount", "type": "error" }, + { "inputs": [], "name": "InsufficientAmount", "type": "error" }, + { "inputs": [], "name": "InvalidNFT", "type": "error" }, + { "inputs": [], "name": "InvalidPeriodDuration", "type": "error" }, + { "inputs": [], "name": "InvalidPid", "type": "error" }, + { "inputs": [], "name": "NoBalance", "type": "error" }, + { "inputs": [], "name": "NoLMPool", "type": "error" }, + { "inputs": [], "name": "NoLiquidity", "type": "error" }, + { "inputs": [], "name": "NotEmpty", "type": "error" }, + { "inputs": [], "name": "NotOwner", "type": "error" }, + { "inputs": [], "name": "NotOwnerOrOperator", "type": "error" }, + { "inputs": [], "name": "NotPancakeNFT", "type": "error" }, + { "inputs": [], "name": "WrongReceiver", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IPancakeV3Pool", + "name": "v3Pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ILMPool", + "name": "lmPool", + "type": "address" + } + ], + "name": "AddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "NewLMPoolDeployerAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "NewOperatorAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "periodDuration", + "type": "uint256" + } + ], + "name": "NewPeriodDuration", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "NewReceiver", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "periodNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cakePerSecond", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cakeAmount", + "type": "uint256" + } + ], + "name": "NewUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "emergency", + "type": "bool" + } + ], + "name": "SetEmergency", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "farmBoostContract", + "type": "address" + } + ], + "name": "UpdateFarmBoostContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int128", + "name": "liquidity", + "type": "int128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "UpdateLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "periodNumber", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingCake", + "type": "uint256" + } + ], + "name": "UpdateUpkeepPeriod", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CAKE", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FARM_BOOSTER", + "outputs": [ + { "internalType": "contract IFarmBooster", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LMPoolDeployer", + "outputs": [ + { + "internalType": "contract ILMPoolDeployer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BOOST_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERIOD_DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { + "internalType": "contract IPancakeV3Pool", + "name": "_v3Pool", + "type": "address" + }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cakeAmountBelongToMC", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { "internalType": "uint128", "name": "amount1Max", "type": "uint128" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.CollectParams", + "name": "params", + "type": "tuple" + }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "collectTo", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergency", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_v3Pool", "type": "address" } + ], + "name": "getLatestPeriodInfo", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "getLatestPeriodInfoByPid", + "outputs": [ + { "internalType": "uint256", "name": "cakePerSecond", "type": "uint256" }, + { "internalType": "uint256", "name": "endTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "harvest", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" } + ], + "internalType": "struct INonfungiblePositionManagerStruct.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodCakePerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodEndTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestPeriodStartTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "nonfungiblePositionManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operatorAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "pendingCake", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { + "internalType": "contract IPancakeV3Pool", + "name": "v3Pool", + "type": "address" + }, + { "internalType": "address", "name": "token0", "type": "address" }, + { "internalType": "address", "name": "token1", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" }, + { + "internalType": "uint256", + "name": "totalLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostLiquidity", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "receiver", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_emergency", "type": "bool" } + ], + "name": "setEmergency", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILMPoolDeployer", + "name": "_LMPoolDeployer", + "type": "address" + } + ], + "name": "setLMPoolDeployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operatorAddress", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_periodDuration", + "type": "uint256" + } + ], + "name": "setPeriodDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "setReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" }, + { "internalType": "address", "name": "recipient", "type": "address" } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_newMultiplier", "type": "uint256" } + ], + "name": "updateBoostMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newFarmBoostContract", + "type": "address" + } + ], + "name": "updateFarmBoostContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "updateLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "pids", "type": "uint256[]" } + ], + "name": "updatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_duration", "type": "uint256" }, + { "internalType": "bool", "name": "_withUpdate", "type": "bool" } + ], + "name": "upkeep", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "userPositionInfos", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint128", + "name": "boostLiquidity", + "type": "uint128" + }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint256", + "name": "rewardGrowthInside", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reward", "type": "uint256" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "pid", "type": "uint256" }, + { + "internalType": "uint256", + "name": "boostMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "v3PoolAddressPid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/pancakeswap-amm/abis.js b/src/adaptors/pancakeswap-amm/abis.js new file mode 100644 index 0000000000..fc617f26ee --- /dev/null +++ b/src/adaptors/pancakeswap-amm/abis.js @@ -0,0 +1,1120 @@ +module.exports = { + masterChefABI: [ + { + inputs: [ + { + internalType: 'contract IMasterChef', + name: '_MASTER_CHEF', + type: 'address', + }, + { internalType: 'contract IBEP20', name: '_CAKE', type: 'address' }, + { internalType: 'uint256', name: '_MASTER_PID', type: 'uint256' }, + { internalType: 'address', name: '_burnAdmin', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IBEP20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'isRegular', + type: 'bool', + }, + ], + name: 'AddPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Init', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + ], + name: 'SetPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'boostContract', + type: 'address', + }, + ], + name: 'UpdateBoostContract', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldMultiplier', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMultiplier', + type: 'uint256', + }, + ], + name: 'UpdateBoostMultiplier', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'UpdateBurnAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'burnRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'regularFarmRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'specialFarmRate', + type: 'uint256', + }, + ], + name: 'UpdateCakeRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardBlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accCakePerShare', + type: 'uint256', + }, + ], + name: 'UpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'isValid', type: 'bool' }, + ], + name: 'UpdateWhiteList', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'ACC_CAKE_PRECISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'BOOST_PRECISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'CAKE', + outputs: [{ internalType: 'contract IBEP20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'CAKE_RATE_TOTAL_PRECISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTERCHEF_CAKE_PER_BLOCK', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_CHEF', + outputs: [ + { internalType: 'contract IMasterChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_PID', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_BOOST_PRECISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'contract IBEP20', name: '_lpToken', type: 'address' }, + { internalType: 'bool', name: '_isRegular', type: 'bool' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'boostContract', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'burnAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_withUpdate', type: 'bool' }], + name: 'burnCake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_isRegular', type: 'bool' }], + name: 'cakePerBlock', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'cakePerBlockToBurn', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'cakeRateToBurn', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'cakeRateToRegularFarm', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'cakeRateToSpecialFarm', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + ], + name: 'getBoostMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'harvestFromMasterChef', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IBEP20', + name: 'dummyToken', + type: 'address', + }, + ], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastBurnedBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IBEP20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingCake', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint256', name: 'accCakePerShare', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'totalBoostedShare', type: 'uint256' }, + { internalType: 'bool', name: 'isRegular', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalRegularAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSpecialAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newBoostContract', type: 'address' }, + ], + name: 'updateBoostContract', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_newMultiplier', type: 'uint256' }, + ], + name: 'updateBoostMultiplier', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_newAdmin', type: 'address' }], + name: 'updateBurnAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_burnRate', type: 'uint256' }, + { internalType: 'uint256', name: '_regularFarmRate', type: 'uint256' }, + { internalType: 'uint256', name: '_specialFarmRate', type: 'uint256' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'updateCakeRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'accCakePerShare', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastRewardBlock', + type: 'uint256', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { + internalType: 'uint256', + name: 'totalBoostedShare', + type: 'uint256', + }, + { internalType: 'bool', name: 'isRegular', type: 'bool' }, + ], + internalType: 'struct MasterChefV2.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'bool', name: '_isValid', type: 'bool' }, + ], + name: 'updateWhiteList', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'boostMultiplier', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'whiteList', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + lpTokenABI: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/pancakeswap-amm/index.js b/src/adaptors/pancakeswap-amm/index.js new file mode 100644 index 0000000000..a0dd784cfc --- /dev/null +++ b/src/adaptors/pancakeswap-amm/index.js @@ -0,0 +1,274 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const { masterChefABI, lpTokenABI } = require('./abis'); +const utils = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const PROJECT = 'pancakeswap-amm'; +const RPC_URL = 'https://bsc-dataseed1.binance.org/'; +const LP_APRS = + 'https://raw.githubusercontent.com/pancakeswap/pancake-frontend/develop/apps/web/src/config/constants/lpAprs/56.json'; +const MASTERCHEF_ADDRESS = '0xa5f8C5Dbd5F286960b9d90548680aE5ebFf07652'; +const CAKE = '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82'; + +const BSC_BLOCK_TIME = 3; +const BLOCKS_PER_YEAR = (60 / BSC_BLOCK_TIME) * 60 * 24 * 365; + +const web3 = new Web3(RPC_URL); + +const CHAINS = ['bsc', 'base', 'ethereum', 'linea', 'zksync', 'arbitrum', 'opbnb', 'monad'] +const EXPLORER_API = 'https://explorer.pancakeswap.com/api/cached'; + +async function getPoolsApy(chain) { + const response = await axios.get(`${EXPLORER_API}/pools/v2/${chain}/list/top`, { timeout: 0 }); + return response.data.map(p => { + const symbol = p.token0.symbol + '-' + p.token1.symbol; + + // 0.25% fee per swap + const feeUsd = Number(p.volumeUSD24h) * 0.0025; + const feeUsd7d = Number(p.volumeUSD7d) * 0.0025; + + return { + pool: utils.formatAddress(p.id), + chain: utils.formatChain(chain), + project: PROJECT, + symbol, + tvlUsd: Number(p.tvlUSD), + apyBase: feeUsd * 365 * 100 / Number(p.tvlUSD), + apyBase7d: feeUsd7d * 365 * 100 / 7 / Number(p.tvlUSD), + volumeUsd1d: Number(p.volumeUSD24h), + volumeUsd7d: Number(p.volumeUSD7d), + underlyingTokens: [p.token0.id, p.token1.id], + } + }) +} + +const calculateApy = ( + poolInfo, + totalAllocPoint, + cakePerBlock, + cakePrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / Number(totalAllocPoint); + const cakePerYear = BLOCKS_PER_YEAR * Number(cakePerBlock); + + return ((poolWeight * cakePerYear * cakePrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + pairName, + reserves, + reservesRatio, + bnbPrice, + cakePrice, + ethPrice, + token0decimals, + token1decimals +) => { + const [token0, token1] = pairName.split('-'); + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1decimals)); + + if (token0.includes('USD')) return reserve0.times(2); + if (token0.includes('BNB')) return reserve0.times(bnbPrice).times(2); + if (token0.includes('Cake')) return reserve0.times(cakePrice).times(2); + if (token0.includes('ETH')) return reserve0.times(ethPrice).times(2); + if (token1.includes('USD')) return reserve1.times(2); + if (token1.includes('BNB')) return reserve1.times(bnbPrice).times(2); + if (token1.includes('Cake')) return reserve1.times(cakePrice).times(2); + if (token1.includes('ETH')) return reserve1.times(ethPrice).times(2); +}; + +const getBaseTokensPrice = async () => { + const priceKeys = { + bnb: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + eth: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + cake: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + }; + const prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${Object.values(priceKeys).map( + (t) => `bsc:${t}` + )}` + ) + ).coins; + + const cakePrice = prices[`bsc:${priceKeys.cake}`].price; + const ethPrice = prices[`bsc:${priceKeys.eth}`].price; + const bnbPrice = prices[`bsc:${priceKeys.bnb}`].price; + + return { cakePrice, ethPrice, bnbPrice }; +}; + +const getPoolsBsc = async () => { + const { cakePrice, ethPrice, bnbPrice } = await getBaseTokensPrice(); + const masterChef = new web3.eth.Contract(masterChefABI, MASTERCHEF_ADDRESS); + let { data: lpAprs } = await fetchURL(LP_APRS); + lpAprs = Object.fromEntries( + Object.entries(lpAprs).map(([k, v]) => [k.toLowerCase(), v]) + ); + + const poolsCount = await masterChef.methods.poolLength().call(); + const totalAllocPoint = await masterChef.methods + .totalRegularAllocPoint() + .call(); + const cakeRateToRegularFarm = await masterChef.methods + .cakePerBlock(true) + .call(); + const normalizedCakePerBlock = cakeRateToRegularFarm / BigInt(1e18); + + const [poolsRes, lpTokensRes] = await Promise.all( + ['poolInfo', 'lpToken'].map((method) => + sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === method)[0], + calls: [...Array(Number(poolsCount) - 1).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'bsc', + permitFailure: true, + }) + ) + ); + const poolsInfo = poolsRes.output.map((res) => res.output); + const lpTokens = lpTokensRes.output.map((res) => res.output); + + // note: exchange subgraph is broken giving duplicated ids on pairs + // reading token info data from contracts instead + const [reservesRes, supplyRes, masterChefBalancesRes, token0Res, token1Res] = + await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf', 'token0', 'token1'].map( + (method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'bsc', + permitFailure: true, + }) + ) + ); + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res) => res.output + ); + const token0 = token0Res.output.map((res) => res.output); + const token1 = token1Res.output.map((res) => res.output); + + const symbol0 = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: token0.map((t) => ({ target: t })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbol1 = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: token1.map((t) => ({ target: t })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + // decimals + const decimals0 = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: token0.map((t) => ({ target: t })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + const decimals1 = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: token1.map((t) => ({ target: t })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + let pools = await Promise.all( + poolsInfo.map((pool, i) => { + // the first two pools are for lotteries, etc. + if (i < 2) return; + if (!reservesData[i]) return; + if (!symbol0[i] || !symbol1[i]) return null; + + const symbol = symbol0[i] + '-' + symbol1[i]; + const poolInfo = poolsInfo[i]; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const reserveUSD = calculateReservesUSD( + symbol, + reserves, + masterChefBalance / supply, + bnbPrice, + cakePrice, + ethPrice, + decimals0[i], + decimals1[i] + ) + .div(1e18) + .toString(); + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizedCakePerBlock, + cakePrice, + reserveUSD + ); + return { + pool: lpTokens[i].toLowerCase(), + chain: utils.formatChain('binance'), + project: PROJECT, + symbol, + tvlUsd: Number(reserveUSD), + apyBase: lpAprs[lpTokens[i].toLowerCase()], + apyReward, + rewardTokens: apyReward > 0 ? [CAKE] : [], + underlyingTokens: [token0[i], token1[i]], + }; + }) + ); + + // rmv null elements + return pools.filter(Boolean).filter((i) => utils.keepFinite(i)); +}; + +async function main(timestamp = null) { + let yieldPools = [] + + for (const chain of CHAINS) { + if (chain === 'bsc') { + yieldPools = yieldPools.concat(await getPoolsBsc()); + } else { + yieldPools = yieldPools.concat(await getPoolsApy(chain)); + } + } + + return yieldPools; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://pancakeswap.finance/farms', +}; diff --git a/src/adaptors/pando-leaf/index.js b/src/adaptors/pando-leaf/index.js new file mode 100644 index 0000000000..df199dd246 --- /dev/null +++ b/src/adaptors/pando-leaf/index.js @@ -0,0 +1,68 @@ +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const URL = 'https://leaf-api.pando.im/api/cats'; +const PUSD_ID = 'pando-usd'; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +async function main() { + const resp = JSON.parse((await superagent.get(URL)).text); + const collaterals = resp.data.collaterals; + const coins = [`coingecko:${PUSD_ID}`]; + const prices = await getPrices(coins); + + return collaterals + .map((col) => { + const totalSupplyUsd = new BigNumber(col.ink).times(col.price).toNumber(); + const totalBorrowUsd = new BigNumber(col.art) + .multipliedBy(new BigNumber(col.rate)) + .times(prices[PUSD_ID.toLowerCase()]) + .toNumber(); + const ltv = 1 / Number(col.mat); + const debtCeiling = Number(col.line) - Number(col.debt); + const debtCeilingUsd = debtCeiling * prices[PUSD_ID.toLowerCase()]; + return { + pool: col.id, + project: 'pando-leaf', + symbol: col.name, + chain: 'mixin', + apy: 0, + tvlUsd: totalSupplyUsd, + apyBaseBorrow: Number(col.duty) * 100 - 100, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + ltv: ltv, + debtCeilingUsd: debtCeilingUsd, + mintedCoin: 'pUSD', + }; + }) + .filter((p) => utils.keepFinite(p)); +} + +// mixin +module.exports = { + timetravel: false, + apy: main, + url: 'https://pando.im/', +}; diff --git a/src/adaptors/pangolin-v2/index.js b/src/adaptors/pangolin-v2/index.js new file mode 100644 index 0000000000..b37f299a60 --- /dev/null +++ b/src/adaptors/pangolin-v2/index.js @@ -0,0 +1,163 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const minichefAbi = require('./minichefAbi'); + +const url = sdk.graph.modifyEndpoint( + '7PRKughAkeESafrGZ8A2x1YsbNMQnFbxQ1bpeNjktwZk' +); +const minichef = '0x1f806f7C8dED893fd3caE279191ad7Aa3798E928'; +const PNG = '0x60781c2586d68229fde47564546784ab3faca982'; + +const query = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + reserve0 + reserve1 + token0 { + id + symbol + } + token1 { + id + symbol + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const buildPool = (entry, chainString) => { + const symbol = utils.formatSymbol( + `${entry.token0.symbol}-${entry.token1.symbol}` + ); + const newObj = { + pool: entry.id, + chain: utils.formatChain(chainString), + project: 'pangolin-v2', + symbol, + tvlUsd: entry.totalValueLockedUSD, + apyBase: entry.apy1d, + apyBase7d: entry.apy7d, + underlyingTokens: [entry.token0.id, entry.token1.id], + volumeUsd1d: entry.volumeUSD1d, + volumeUsd7d: entry.volumeUSD7d, + }; + + return newObj; +}; + +const topLvl = async (chainString, timestamp, url, version) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + data = await utils.tvl(data, chainString); + + // calculate apy + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + // build pool objects + data = data + .map((el) => buildPool(el, chainString)) + .filter((p) => utils.keepFinite(p)); + + return data; +}; + +const main = async (timestamp = null) => { + const data = ( + await Promise.all([topLvl('avalanche', timestamp, url, 'v2')]) + ).flat(); + + // -- rewards + const lpTokens = ( + await sdk.api.abi.call({ + target: minichef, + abi: minichefAbi.find((m) => m.name === 'lpTokens'), + chain: 'avax', + }) + ).output; + let poolInfos = ( + await sdk.api.abi.call({ + target: minichef, + abi: minichefAbi.find((m) => m.name === 'poolInfos'), + chain: 'avax', + }) + ).output; + poolInfos = poolInfos.map((p, i) => ({ ...p, lpToken: lpTokens[i] })); + + const rewardPerSecond = + ( + await sdk.api.abi.call({ + target: minichef, + abi: minichefAbi.find((m) => m.name === 'rewardPerSecond'), + chain: 'avax', + }) + ).output / 1e18; + + const priceKey = `avax:${PNG}`; + const pngPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + const pngPerYearUsd = rewardPerSecond * 60 * 60 * 24 * 365 * pngPrice; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: minichef, + abi: minichefAbi.find((m) => m.name === 'totalAllocPoint'), + chain: 'avax', + }) + ).output; + + return data.map((p) => { + const piAllocPoint = poolInfos.find( + (i) => i.lpToken.toLowerCase() === p.pool.toLowerCase() + )?.allocPoint; + + return { + ...p, + // apyReward: + // ((pngPerYearUsd * (piAllocPoint / totalAllocPoint)) / p.tvlUsd) * 100, + // rewardTokens: piAllocPoint > 0 ? [PNG] : [], + }; + }); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://app.pangolin.exchange/#/pool', +}; diff --git a/src/adaptors/pangolin-v2/minichefAbi.js b/src/adaptors/pangolin-v2/minichefAbi.js new file mode 100644 index 0000000000..7c74d7b490 --- /dev/null +++ b/src/adaptors/pangolin-v2/minichefAbi.js @@ -0,0 +1,654 @@ +module.exports = [ + { + inputs: [ + { internalType: 'address', name: '_rewardToken', type: 'address' }, + { internalType: 'address', name: '_firstOwner', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'funder', + type: 'address', + }, + ], + name: 'FunderAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'funder', + type: 'address', + }, + ], + name: 'FunderRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerSecond', + type: 'uint256', + }, + ], + name: 'LogRewardPerSecond', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardsExpiration', + type: 'uint256', + }, + ], + name: 'LogRewardsExpiration', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'uint256', name: 'pid', type: 'uint256' }, + ], + name: 'Migrate', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'MigratorDisabled', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'migrator', + type: 'address', + }, + ], + name: 'MigratorSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'PoolAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'overwrite', type: 'bool' }, + ], + name: 'PoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint64', + name: 'lastRewardTime', + type: 'uint64', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + ], + name: 'PoolUpdate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'REWARD', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_funder', type: 'address' }], + name: 'addFunder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'addPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: '_allocPoints', type: 'uint256[]' }, + { + internalType: 'contract IERC20[]', + name: '_lpTokens', + type: 'address[]', + }, + { + internalType: 'contract IRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'addPools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'addedTokens', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'disableMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'extension', type: 'uint256' }, + { internalType: 'uint256', name: 'maxFunding', type: 'uint256' }, + ], + name: 'extendRewardsViaDuration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'funding', type: 'uint256' }, + { internalType: 'uint256', name: 'minExtension', type: 'uint256' }, + ], + name: 'extendRewardsViaFunding', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'funding', type: 'uint256' }, + { internalType: 'uint256', name: 'duration', type: 'uint256' }, + ], + name: 'fundRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_funder', type: 'address' }], + name: 'isFunder', + outputs: [{ internalType: 'bool', name: 'allowed', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lpTokens', + outputs: [ + { internalType: 'contract IERC20[]', name: '', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdateAllPools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrationDisabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingReward', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint128', name: 'accRewardPerShare', type: 'uint128' }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolInfos', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accRewardPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MiniChefV2.PoolInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_funder', type: 'address' }], + name: 'removeFunder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'duration', type: 'uint256' }], + name: 'resetRewardsDuration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewarder', + outputs: [ + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsExpiration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: 'overwrite', type: 'bool' }, + ], + name: 'setPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'allocPoints', type: 'uint256[]' }, + { + internalType: 'contract IRewarder[]', + name: 'rewarders', + type: 'address[]', + }, + { internalType: 'bool[]', name: 'overwrites', type: 'bool[]' }, + ], + name: 'setPools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accRewardPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MiniChefV2.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'int256', name: 'rewardDebt', type: 'int256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdrawAndHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/pangolin/index.js b/src/adaptors/pangolin/index.js deleted file mode 100644 index d443dd8ebe..0000000000 --- a/src/adaptors/pangolin/index.js +++ /dev/null @@ -1,84 +0,0 @@ -const { request, gql } = require('graphql-request'); - -const utils = require('../utils'); - -const url = 'https://api.thegraph.com/subgraphs/name/pangolindex/exchange'; - -const query = gql` - { - pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { - id - volumeUSD - reserve0 - reserve1 - token0 { - id - symbol - } - token1 { - id - symbol - } - } - } -`; - -const queryPrior = gql` - { - pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { - id - volumeUSD - } - } -`; - -const buildPool = (entry, chainString) => { - const symbol = utils.formatSymbol( - `${entry.token0.symbol}-${entry.token1.symbol}` - ); - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'pangolin', - symbol, - tvlUsd: entry.totalValueLockedUSD, - apy: entry.apy, - }; - - return newObj; -}; - -const topLvl = async (chainString, timestamp, url) => { - const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ - url, - ]); - - dataNow = await request(url, query.replace('', block)); - - // pull 24h offset data to calculate fees from swap volume - let dataPrior = await request( - url, - queryPrior.replace('', blockPrior) - ); - - // calculate tvl - dataNow = await utils.tvl(dataNow.pairs, 'avalanche'); - - // calculate apy - let data = dataNow.map((el) => utils.apy(el, dataPrior.pairs, 'v2')); - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async (timestamp = null) => { - const data = await Promise.all([topLvl('avalanche', timestamp, url)]); - return data.flat(); -}; - -module.exports = { - timetravel: true, - apy: main, -}; diff --git a/src/adaptors/parallel-protocol-v3/config.js b/src/adaptors/parallel-protocol-v3/config.js new file mode 100644 index 0000000000..c4d785eb47 --- /dev/null +++ b/src/adaptors/parallel-protocol-v3/config.js @@ -0,0 +1,29 @@ +const config = { + avax: { + chainName: 'avalanche', + USDp: '0x9eE1963f05553eF838604Dd39403be21ceF26AA4', + sUSDp: '0x9d92c21205383651610f90722131655a5b8ed3e0', + }, + ethereum: { + chainName: 'Ethereum', + USDp: '0x9B3a8f7CEC208e247d97dEE13313690977e24459', + sUSDp: '0x0d45b129dc868963025Db79A9074EA9c9e32Cae4', + }, + base: { + chainName: 'Base', + USDp: ' 0x76A9A0062ec6712b99B4f63bD2b4270185759dd5', + sUSDp: '0x472eD57b376fE400259FB28e5C46eB53f0E3e7E7', + }, + sonic: { + chainName: 'Sonic', + USDp: '0x08417cdb7F52a5021bB4eb6E0deAf3f295c3f182', + sUSDp: '0xe8a3DA6f5ed1cf04c58ac7f6A7383641e877517b', + }, + hyperevm: { + chainName: 'hyperevm', + USDp: '0xBE65F0F410A72BeC163dC65d46c83699e957D588', + sUSDp: '0x9B3a8f7CEC208e247d97dEE13313690977e24459', + }, +}; + +module.exports = { config }; diff --git a/src/adaptors/parallel-protocol-v3/index.js b/src/adaptors/parallel-protocol-v3/index.js new file mode 100644 index 0000000000..2c00e048a4 --- /dev/null +++ b/src/adaptors/parallel-protocol-v3/index.js @@ -0,0 +1,73 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const { config } = require('./config'); +const BigNumber = require('bignumber.js'); + +// function getEstimatedAPR is misleading, it returns the estimated APY +const getEstimatedAPR = + 'function estimatedAPR() external view returns (uint256)'; +const getTotalAssets = 'function totalAssets() external view returns (uint256)'; + +const getsUSDpData = async (chain, chainConfig) => { + const { chainName, USDp, sUSDp } = chainConfig; + let estimatedAPY; + let totalAssets; + if (chain === 'hyperevm') { + const provider = new ethers.providers.JsonRpcProvider( + 'https://rpc.hyperliquid.xyz/evm' + ); + const abi = [getEstimatedAPR, getTotalAssets]; + const contract = new ethers.Contract(sUSDp, abi, provider); + [estimatedAPY, totalAssets] = await Promise.all([ + contract.estimatedAPR(), + contract.totalAssets(), + ]); + } else { + const api = new sdk.ChainApi({ chain }); + [estimatedAPY, totalAssets] = await Promise.all([ + api.call({ + abi: getEstimatedAPR, + target: sUSDp, + }), + api.call({ + abi: getTotalAssets, + target: sUSDp, + }), + ]); + } + + const tvlUsd = new BigNumber( + ethers.utils.formatUnits(totalAssets, 18) + ).toNumber(); + const apyBase = new BigNumber( + ethers.utils.formatUnits(estimatedAPY, 16) + ).toNumber(); + + return { + pool: `${sUSDp}-parallel-v3`.toLowerCase(), + chain: utils.formatChain(chainName), + project: 'parallel-protocol-v3', + symbol: 'sUSDp', + tvlUsd: tvlUsd, + apyBase: apyBase, + rewardTokens: [USDp], + underlyingTokens: [USDp], + poolMeta: 'saving', + }; +}; + +const main = async () => { + const markets = []; + for (let [chain, data] of Object.entries(config)) { + const result = await getsUSDpData(chain, data); + markets.push(result); + } + return markets; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.parallel.best/earn', +}; diff --git a/src/adaptors/paraspace-lending-v1/abi.js b/src/adaptors/paraspace-lending-v1/abi.js new file mode 100644 index 0000000000..6f55896a5e --- /dev/null +++ b/src/adaptors/paraspace-lending-v1/abi.js @@ -0,0 +1,476 @@ +module.exports = { + ethereum: { + UiPoolDataProvider: { + getReservesData: { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'getReservesData', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'underlyingAsset', + type: 'address', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseLTVasCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowingEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'auctionEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isPaused', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isAtomicPricing', + type: 'bool', + }, + { + internalType: 'uint128', + name: 'liquidityIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'liquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'address', + name: 'xTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'auctionStrategyAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalScaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'priceInMarketReferenceCurrency', + type: 'uint256', + }, + { + internalType: 'address', + name: 'priceOracle', + type: 'address', + }, + { + internalType: 'uint256', + name: 'variableRateSlope1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableRateSlope2', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseVariableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'optimalUsageRatio', + type: 'uint256', + }, + { + internalType: 'uint128', + name: 'accruedToTreasury', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'borrowCap', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyCap', + type: 'uint256', + }, + { + internalType: 'enum DataTypes.AssetType', + name: 'assetType', + type: 'uint8', + }, + ], + internalType: 'struct IUiPoolDataProvider.AggregatedReserveData[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketReferenceCurrencyUnit', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'marketReferenceCurrencyPriceInUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'networkBaseTokenPriceInUsd', + type: 'int256', + }, + { + internalType: 'uint8', + name: 'networkBaseTokenPriceDecimals', + type: 'uint8', + }, + ], + internalType: 'struct IUiPoolDataProvider.BaseCurrencyInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, + }, + arbitrum: { + UiPoolDataProvider: { + getReservesData: { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'getReservesData', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'underlyingAsset', + type: 'address', + }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { + internalType: 'uint256', + name: 'baseLTVasCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'auctionEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + { internalType: 'bool', name: 'isPaused', type: 'bool' }, + { internalType: 'bool', name: 'isAtomicPricing', type: 'bool' }, + { + internalType: 'uint128', + name: 'liquidityIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'liquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'address', + name: 'xTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'auctionStrategyAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'timeLockStrategyAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalScaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'priceInMarketReferenceCurrency', + type: 'uint256', + }, + { internalType: 'address', name: 'priceOracle', type: 'address' }, + { + internalType: 'uint256', + name: 'variableRateSlope1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableRateSlope2', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseVariableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'optimalUsageRatio', + type: 'uint256', + }, + { + internalType: 'uint128', + name: 'accruedToTreasury', + type: 'uint128', + }, + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + { + internalType: 'enum DataTypes.AssetType', + name: 'assetType', + type: 'uint8', + }, + { + components: [ + { + internalType: 'uint256', + name: 'minThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'midThreshold', + type: 'uint256', + }, + { + internalType: 'uint48', + name: 'minWaitTime', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'midWaitTime', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'maxWaitTime', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'poolPeriodWaitTime', + type: 'uint48', + }, + { + internalType: 'uint256', + name: 'poolPeriodLimit', + type: 'uint256', + }, + { internalType: 'uint256', name: 'period', type: 'uint256' }, + { + internalType: 'uint128', + name: 'totalAmountInCurrentPeriod', + type: 'uint128', + }, + { + internalType: 'uint48', + name: 'lastResetTimestamp', + type: 'uint48', + }, + ], + internalType: 'struct ITimeLockStrategy.TimeLockStrategyData', + name: 'timeLockStrategyData', + type: 'tuple', + }, + ], + internalType: 'struct IUiPoolDataProvider.AggregatedReserveData[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketReferenceCurrencyUnit', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'marketReferenceCurrencyPriceInUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'networkBaseTokenPriceInUsd', + type: 'int256', + }, + { + internalType: 'uint8', + name: 'networkBaseTokenPriceDecimals', + type: 'uint8', + }, + ], + internalType: 'struct IUiPoolDataProvider.BaseCurrencyInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, + }, +}; diff --git a/src/adaptors/paraspace-lending-v1/address.js b/src/adaptors/paraspace-lending-v1/address.js new file mode 100644 index 0000000000..f1ae638ea6 --- /dev/null +++ b/src/adaptors/paraspace-lending-v1/address.js @@ -0,0 +1,10 @@ +module.exports = { + ethereum: { + UiPoolDataProvider: '0xcFcca0A2531069f16634beeD1C74d28ac1F7d271', + PoolAddressProvider: '0x6cD30e716ADbE47dADf7319f6F2FB83d507c857d', + }, + arbitrum: { + UiPoolDataProvider: '0x94bDD135ccC48fF0440D750300A4e4Ba9B216B3A', + PoolAddressProvider: '0x45a35124749B061a29f91cc8ddf85606586dcf24', + }, +}; diff --git a/src/adaptors/paraspace-lending-v1/index.js b/src/adaptors/paraspace-lending-v1/index.js new file mode 100644 index 0000000000..607d42d022 --- /dev/null +++ b/src/adaptors/paraspace-lending-v1/index.js @@ -0,0 +1,85 @@ +const superagent = require('superagent'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const address = require('./address'); +const abi = require('./abi'); +const { calculateAPY } = require('./utils'); + +const chains = ['ethereum', 'arbitrum']; + +const isEthereum = (chain) => chain.toLowerCase() === 'ethereum'; + +const apy = async () => { + const pools = await Promise.all( + chains.map(async (chain) => { + const { UiPoolDataProvider: uiPool, PoolAddressProvider } = + address[chain]; + + const key = 'ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + const ethPriceUSD = isEthereum(chain) + ? (await superagent.get(`https://coins.llama.fi/prices/current/${key}`)) + .body.coins[key].price + : 1; + const marketReferenceCurrencyDecimal = isEthereum(chain) ? 18 : 8; + + const [reservesData] = ( + await sdk.api.abi.call({ + target: uiPool, + abi: abi[chain].UiPoolDataProvider.getReservesData, + params: PoolAddressProvider, + chain, + }) + ).output; + + const pools = reservesData + .filter( + (reserve) => + reserve.assetType === '0' && + reserve.underlyingAsset !== + '0x0000000000000000000000000000000000000001' + ) + .map((reserve, index) => { + const tvlUsd = new BigNumber(reserve.availableLiquidity) + .multipliedBy(reserve.priceInMarketReferenceCurrency) + .multipliedBy(ethPriceUSD) + .shiftedBy( + -(marketReferenceCurrencyDecimal + Number(reserve.decimals)) + ) + .toNumber(); + const totalBorrowUsd = new BigNumber(reserve.totalScaledVariableDebt) + .multipliedBy(reserve.variableBorrowIndex) + .multipliedBy(reserve.priceInMarketReferenceCurrency) + .multipliedBy(ethPriceUSD) + .shiftedBy( + -(marketReferenceCurrencyDecimal + 27 + Number(reserve.decimals)) + ) + .toNumber(); + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + return { + pool: `${reserve.xTokenAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'paraspace-lending-v1', + symbol: reserve.symbol, + tvlUsd, + apyBase: calculateAPY(reserve.liquidityRate).toNumber() * 100, + underlyingTokens: [reserve.underlyingAsset], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: + calculateAPY(reserve.variableBorrowRate).toNumber() * 100, + ltv: reserve.baseLTVasCollateral / 10000, + url: `https://app.para.space/`, + borrowable: reserve.borrowingEnabled, + }; + }); + + return pools; + }) + ); + return pools.flat(); +}; +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/paraspace-lending-v1/utils.js b/src/adaptors/paraspace-lending-v1/utils.js new file mode 100644 index 0000000000..de76908efa --- /dev/null +++ b/src/adaptors/paraspace-lending-v1/utils.js @@ -0,0 +1,47 @@ +const BigNumber = require('bignumber.js'); + +const valueToZDBigNumber = (amount) => { + const BigNumberZeroDecimal = BigNumber.clone({ + DECIMAL_PLACES: 0, + ROUNDING_MODE: BigNumber.ROUND_DOWN, + }); + return new BigNumberZeroDecimal(amount); +}; + +const calculateAPY = (rate) => { + const SECONDS_PER_YEAR = new BigNumber('31536000'); + const RAY = valueToZDBigNumber(10).pow(27); + const RAY_DECIMALS = 27; + const HALF_RAY = RAY.dividedBy(2); + + const rayPow = (a, p) => { + let x = valueToZDBigNumber(a); + let n = valueToZDBigNumber(p); + let z = n.modulo(2).eq(0) ? valueToZDBigNumber(RAY) : x; + + for (n = n.div(2); !n.eq(0); n = n.div(2)) { + x = rayMul(x, x); + + if (!n.modulo(2).eq(0)) { + z = rayMul(z, x); + } + } + + return z; + }; + + const rayMul = (a, b) => { + return HALF_RAY.plus(valueToZDBigNumber(a).multipliedBy(b)).div(RAY); + }; + + return rayPow( + valueToZDBigNumber(rate).dividedBy(SECONDS_PER_YEAR).plus(RAY), + SECONDS_PER_YEAR + ) + .minus(RAY) + .shiftedBy(-RAY_DECIMALS); +}; + +module.exports = { + calculateAPY, +}; diff --git a/src/adaptors/peapods-finance/index.js b/src/adaptors/peapods-finance/index.js new file mode 100644 index 0000000000..3895f3d85d --- /dev/null +++ b/src/adaptors/peapods-finance/index.js @@ -0,0 +1,376 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +// ========== MULTICALL BATCH SIZE ========== +const MULTICALL_BATCH_SIZE = 100; // Maximum number of calls per multicall batch + +// ========== METRICS ========== +// Metrics for tracking multicall usage throughout the script +let metrics = { + totalMulticallBatches: 0, + totalMulticallCalls: 0, + multicallByType: {}, +}; + +// ------------ START SETTINGS PER CHAIN -------------- +// Chain configuration with RPC endpoints and contracts +const CHAINS = { + ethereum: { + name: 'Ethereum', + levManager: '0x4e6EF371C9CDDE8C3e6716AffEEBaD14C8c62D0B', + idxManager: '0x6eFFcF94993d6a6081204fc3C30473468Eb7666E', + chainId: 1, + blocksPerDay: 7200, + }, + arbitrum: { + name: 'Arbitrum', + levManager: '0x3f2257B6f1fd055aEe020027740f266127E8E2B0', + idxManager: '0x64511ccE99ab01A6dD136207450eA81263b14FD8', + chainId: 42161, + blocksPerDay: 344000, + }, + base: { + name: 'Base', + levManager: '0x31E35550b15B2DFd267Edfb39Dd9F3CD1c6ab82D', + idxManager: '0x556059e80CB0073D4A9547081Cf0f80cBB94ec30', + chainId: 8453, + blocksPerDay: 43200, + }, + sonic: { + name: 'Sonic', + levManager: '0x0C4B19994F466ac4B6bA8F9B220d83beC6118b61', + idxManager: '0x9e054F6C328d8E424a2354af726FDc88cB166060', + chainId: 146, + blocksPerDay: 21600, + }, + berachain: { + name: 'Berachain', + levManager: '0x0ff519EEEc6f1C362A76F87fef3B4a3997bF5a69', + idxManager: '0xC9260cE495B5EeC77219Bf4faCCf27EeFD932f01', + chainId: 80094, + blocksPerDay: 43200, + }, +}; +// ------------ END SETTINGS PER CHAIN -------------- +// End chain config + +// ========== ABIs ========== +// Contract ABIs for multicall usage +const idxManagerAbi = [ + 'function allIndexes() view returns (tuple(address index, address creator, bool verified, bool selfLending, bool makePublic)[])', +]; +const levManagerAbi = ['function lendingPairs(address) view returns (address)']; +const lendingPairAbi = [ + 'function getPairAccounting() view returns (uint128,uint128,uint128,uint128,uint256)', + 'function asset() view returns (address)', + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function decimals() view returns (uint8)', + 'function currentRateInfo() view returns (tuple(uint32 lastBlock, uint32 feeToProtocolRate, uint64 lastTimestamp, uint64 ratePerSec, uint64 fullUtilizationRate))', + 'function totalAssets() view returns (uint256)', +]; +const erc20Abi = [ + 'function decimals() view returns (uint8)', + 'function symbol() view returns (string)', +]; + +// ========== BATCHED MULTICALL HELPER ========== +// Helper for batching multicall requests and tracking metrics +async function batchedMultiCall({ calls, chain, abi, type = 'unknown' }) { + const batches = []; + for (let i = 0; i < calls.length; i += MULTICALL_BATCH_SIZE) { + batches.push(calls.slice(i, i + MULTICALL_BATCH_SIZE)); + } + metrics.totalMulticallCalls += calls.length; + metrics.totalMulticallBatches += batches.length; + if (!metrics.multicallByType[type]) + metrics.multicallByType[type] = { calls: 0, batches: 0 }; + metrics.multicallByType[type].calls += calls.length; + metrics.multicallByType[type].batches += batches.length; + let results = []; + for (const batch of batches) { + const res = await sdk.api.abi.multiCall({ calls: batch, chain, abi }); + results = results.concat(res.output); + } + return results; +} + +// ========== Helper: Pool Discovery Per Chain ========== +// Discover lending pairs using batched multicall +async function discoverLendingPairs(chainConfig) { + // Use DefiLlama SDK for single call (no ethers needed) + const pods = ( + await sdk.api.abi.call({ + target: chainConfig.idxManager, + abi: idxManagerAbi[0], + chain: chainConfig.name.toLowerCase(), + }) + ).output; + // Prepare multicall for all pods to get their lendingPair + const multicallCalls = pods.map((pod) => ({ + target: chainConfig.levManager, + params: [pod.index], + abi: 'function lendingPairs(address) view returns (address)', + })); + const multicallResOutput = await batchedMultiCall({ + calls: multicallCalls, + chain: chainConfig.name.toLowerCase(), + abi: 'function lendingPairs(address) view returns (address)', + type: 'lendingPairs', + }); + let lendingPairs = []; + for (let i = 0; i < pods.length; i++) { + const podAddr = pods[i].index; + const lendingPairAddr = multicallResOutput[i]?.output; + if ( + lendingPairAddr && + lendingPairAddr !== '0x0000000000000000000000000000000000000000' + ) { + lendingPairs.push({ + chain: chainConfig.chainId, + pod: podAddr, + lendingPair: lendingPairAddr, + symbol: pods[i].symbol, + }); + } + } + return lendingPairs; +} + +// ========== Asset Metadata Helper ========== +// Get asset addresses, decimals, and symbols for each lending pair +async function getAssetMetadata(lendingPairs, chainConfig) { + const uniqueAssets = {}; + // Multicall: asset addresses + const calls = lendingPairs.map((lp) => ({ + target: lp.lendingPair, + abi: 'function asset() view returns (address)', + })); + const assetsResOutput = await batchedMultiCall({ + calls, + chain: chainConfig.name.toLowerCase(), + abi: 'function asset() view returns (address)', + type: 'asset', + }); + const assetAddresses = assetsResOutput.map((r) => r.output); + + // Multicall: decimals + const decCalls = assetAddresses.map((addr) => ({ + target: addr, + abi: 'function decimals() view returns (uint8)', + })); + const decResOutput = await batchedMultiCall({ + calls: decCalls, + chain: chainConfig.name.toLowerCase(), + abi: 'function decimals() view returns (uint8)', + type: 'decimals', + }); + + // Multicall: symbols + const symbolCalls = assetAddresses.map((addr) => ({ + target: addr, + abi: 'function symbol() view returns (string)', + })); + const symbolResOutput = await batchedMultiCall({ + calls: symbolCalls, + chain: chainConfig.name.toLowerCase(), + abi: 'function symbol() view returns (string)', + type: 'symbol', + }); + + // Fill uniqueAssets with all data + for (let i = 0; i < lendingPairs.length; i++) { + const assetAddr = assetsResOutput[i].output; + const decimals = decResOutput[i].output; + const symbol = symbolResOutput[i].output; + uniqueAssets[assetAddr.toLowerCase()] = { assetAddr, decimals, symbol }; + lendingPairs[i].assetAddr = assetAddr; + lendingPairs[i].assetDecimals = decimals; + lendingPairs[i].assetSymbol = symbol; // mocht je het direct op de pairs willen hebben + } + return uniqueAssets; +} + +// ========== Asset Price Helper ========== +// Fetch prices for all unique assets in one API call +async function getAssetPrices(uniqueAssets, chainConfig) { + const assetAddrs = Object.values(uniqueAssets).map((obj) => obj.assetAddr); + if (assetAddrs.length === 0) return {}; + const chainName = chainConfig.name.toLowerCase(); + const pricesArray = assetAddrs.map( + (addr) => `${chainName}:${addr.toLowerCase()}` + ); + const url = `https://coins.llama.fi/prices/current/${pricesArray.join(',')}`; + let prices = {}; + try { + const { data } = await axios.get(url); + for (const key of Object.keys(data.coins)) { + if (!data.coins[key].price) { + console.log( + `[WARNING] No price found in API response for asset ${key}, setting price to 0.` + ); + prices[key.split(':')[1]] = 0; + } else { + prices[key.split(':')[1]] = data.coins[key].price; + } + } + } catch (e) { + for (const addr of assetAddrs) { + prices[addr.toLowerCase()] = 0; + console.log( + `[WARNING] Failed to fetch price for asset ${addr} on ${chainConfig.name}, setting price to 0.` + ); + } + } + return prices; +} + +// ========== Pool Data Multicall Helper ========== +// Fetch pool-level data for all lending pairs in batches +async function getPoolsMulticallData(validLendingPairs, prices, chainConfig) { + const poolAddresses = validLendingPairs.map((lp) => lp.lendingPair); + + async function getAllBatchOutputs(calls, abi, type) { + return await batchedMultiCall({ + calls, + chain: chainConfig.name.toLowerCase(), + abi, + type, + }); + } + + const accountingCalls = poolAddresses.map((addr) => ({ + target: addr, + abi: 'function getPairAccounting() view returns (uint128,uint128,uint128,uint128,uint256)', + })); + const nameCalls = poolAddresses.map((addr) => ({ + target: addr, + abi: 'function name() view returns (string)', + })); + const symbolCalls = poolAddresses.map((addr) => ({ + target: addr, + abi: 'function symbol() view returns (string)', + })); + const rateInfoCalls = poolAddresses.map((addr) => ({ + target: addr, + abi: 'function currentRateInfo() view returns (tuple(uint32 lastBlock, uint32 feeToProtocolRate, uint64 lastTimestamp, uint64 ratePerSec, uint64 fullUtilizationRate))', + })); + + const [accountingRes, nameRes, symbolRes, rateInfoRes] = await Promise.all([ + getAllBatchOutputs(accountingCalls, accountingCalls[0]?.abi, 'accounting'), + getAllBatchOutputs(nameCalls, nameCalls[0]?.abi, 'name'), + getAllBatchOutputs(symbolCalls, symbolCalls[0]?.abi, 'symbol'), + getAllBatchOutputs(rateInfoCalls, rateInfoCalls[0]?.abi, 'rateInfo'), + ]); + + return { + accountingRes: { output: accountingRes }, + nameRes: { output: nameRes }, + symbolRes: { output: symbolRes }, + rateInfoRes: { output: rateInfoRes }, + }; +} + +// ========== Main Export ========== +// Entrypoint: fetch all pool data across all configured chains +async function main() { + let allPools = []; + + for (const [chainKey, chainConfig] of Object.entries(CHAINS)) { + const lendingPairs = await discoverLendingPairs(chainConfig); + console.log( + 'Discovered lending pairs for chain', + chainConfig.name, + ':', + lendingPairs.map((x) => x.lendingPair) + ); + + const uniqueAssets = await getAssetMetadata(lendingPairs, chainConfig); + const prices = await getAssetPrices(uniqueAssets, chainConfig); + console.log('Asset prices used for', chainConfig.name, ':', prices); + + // Multicall for all pool info at once + const validLendingPairs = lendingPairs.filter( + (lp) => lp.assetAddr && lp.assetDecimals + ); + const { accountingRes, nameRes, symbolRes, rateInfoRes } = + await getPoolsMulticallData(validLendingPairs, prices, chainConfig); + + const poolData = validLendingPairs.map((lp, i) => { + const accounting = accountingRes.output[i]?.output || []; + const pairName = nameRes.output[i]?.output || ''; + const pairSymbol = symbolRes.output[i]?.output || ''; + const rateInfo = rateInfoRes.output[i]?.output || {}; + let assetPrice = prices[lp.assetAddr.toLowerCase()]; + if (assetPrice === undefined) { + console.log( + `[WARNING] No price found for asset in pool ${lp.lendingPair}. Setting assetPrice = 0.` + ); + assetPrice = 0; + } + const totalAssetAmount = accounting[0]?.toString() || '0'; + const totalBorrowAmount = accounting[2]?.toString() || '0'; + const assetDecimals = lp.assetDecimals; + const ratePerSec = rateInfo.ratePerSec ?? rateInfo[3] ?? 0; + const protocolFee = + Number(rateInfo.feeToProtocolRate ?? rateInfo[1] ?? 0) / 1e5; + const borrowApr = + (Number(ratePerSec.toString()) * 60 * 60 * 24 * 365) / 1e18; + const totalBorrowToken = Number( + +totalBorrowAmount / Math.pow(10, assetDecimals) + ); + const totalAssetToken = Number( + +totalAssetAmount / Math.pow(10, assetDecimals) + ); + const utilization = + totalAssetToken > 0 ? totalBorrowToken / totalAssetToken : 0; + const supplierApr = borrowApr * utilization * (1 - protocolFee); + const blocksPerDay = chainConfig.blocksPerDay || 7200; + const secondsPerBlock = 86400 / blocksPerDay; + const compoundPeriods = Math.floor(31557600 / secondsPerBlock); + const supplierApy = + Math.pow(1 + supplierApr / compoundPeriods, compoundPeriods) - 1; + const tvlToken = totalAssetToken; + const borrowToken = totalBorrowToken; + const tvlUsd = tvlToken * assetPrice; + const totalBorrowUsd = borrowToken * assetPrice; + return { + pool: lp.lendingPair, + chain: chainKey, + project: 'peapods-finance', + symbol: lp.assetSymbol, + tvlUsd, + apyBase: supplierApy * 100, + apyBaseBorrow: borrowApr * 100, + underlyingTokens: [lp.assetAddr], + rewardTokens: [], + poolMeta: pairName, + totalSupplyUsd: tvlUsd, + totalBorrowUsd: totalBorrowUsd, + url: `https://beta.peapods.finance/pod/${chainConfig.chainId}/${lp.pod}`, + borrowable: true, + }; + }); + + allPools = allPools.concat(poolData.filter(Boolean)); + } + + // ==== METRICS LOGGING ==== + // Print multicall usage metrics after completion + console.log('\n========= Multicall Metrics ========='); + console.log('Total multicall batches:', metrics.totalMulticallBatches); + console.log('Total multicall calls:', metrics.totalMulticallCalls); + console.log( + 'Breakdown by type:', + JSON.stringify(metrics.multicallByType, null, 2) + ); + console.log('Batch size:', MULTICALL_BATCH_SIZE); + console.log('====================================\n'); + + return allPools; +} + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/pearl-v2/abis/BoxTrident.json b/src/adaptors/pearl-v2/abis/BoxTrident.json new file mode 100644 index 0000000000..1400e3eb68 --- /dev/null +++ b/src/adaptors/pearl-v2/abis/BoxTrident.json @@ -0,0 +1,1545 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "emissionToOwner", + "type": "uint256" + } + ], + "name": "ClaimManagementFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "feesToVault0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToVault1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesToOwner1", + "type": "uint256" + } + ], + "name": "CollectFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bool", + "name": "isTrue", + "type": "bool" + } + ], + "name": "DirectDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "FeeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "Rebalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxTotalSupply", + "type": "uint256" + } + ], + "name": "UpdateMaxTotalSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseLower", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseUpper", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boxFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "collectedfees0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collectedfees1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "claimManagementFees", + "outputs": [ + { + "internalType": "uint256", + "name": "collectedfees0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collectedfees1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissionToOwner", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentTick", + "outputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "directDeposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earnedFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feePerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "feePerShareClaimed", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "feesOwed", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalance0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBalance1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getManagementFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableEmission", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolLiquidityPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidityPerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolParams", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "getRequiredAmountsForInput", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "getSharesAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "twapInterval", + "type": "uint32" + } + ], + "name": "getSqrtTwapX96", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96Twap", + "type": "uint160" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "total0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pool0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pool1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_boxFactory", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isMinting", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "managementFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "max0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "max1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IPearlV2Pool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolFee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "_baseLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "_baseUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1Min", + "type": "uint256" + } + ], + "name": "pullLiquidity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "_baseLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "_baseUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "_amount0MinBurn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1MinBurn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount0MinMint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount1MinMint", + "type": "uint256" + } + ], + "name": "rebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "newFee", + "type": "uint24" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "setGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxTotalSupply", + "type": "uint256" + } + ], + "name": "setMaxTotalSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "toggleDirectDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usersFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/pearl-v2/abis/PairAPI.json b/src/adaptors/pearl-v2/abis/PairAPI.json new file mode 100644 index 0000000000..4c220c4e20 --- /dev/null +++ b/src/adaptors/pearl-v2/abis/PairAPI.json @@ -0,0 +1,1113 @@ +[ + { + "inputs": [], + "name": "T", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "Owner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVoter", + "type": "address" + } + ], + "name": "Voter", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_EPOCHS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARDS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEEK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + } + ], + "name": "getAllPair", + "outputs": [ + { + "components": [ + { + "internalType": "enum IPearlV2PoolAPI.Version", + "name": "version", + "type": "uint8" + }, + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "address", + "name": "box_address", + "type": "address" + }, + { + "internalType": "address", + "name": "box_manager_address", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "total_liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "gauge_alm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_alm_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge_fee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_fee_claimable0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gauge_fee_claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "alm_lower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "alm_upper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "alm_total_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_total_supply1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_staked_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_staked_supply1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "alm_total_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_claimable0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_claimable1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isStaked", + "type": "bool" + } + ], + "internalType": "struct IPearlV2PoolAPI.PositionInfo[]", + "name": "account_positions", + "type": "tuple[]" + } + ], + "internalType": "struct IPearlV2PoolAPI.PairInfo[]", + "name": "pairs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + } + ], + "name": "getGaugeTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "uint8", + "name": "_version", + "type": "uint8" + } + ], + "name": "getPair", + "outputs": [ + { + "components": [ + { + "internalType": "enum IPearlV2PoolAPI.Version", + "name": "version", + "type": "uint8" + }, + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "address", + "name": "box_address", + "type": "address" + }, + { + "internalType": "address", + "name": "box_manager_address", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "total_supply1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "total_liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "gauge_alm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_alm_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge_fee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_fee_claimable0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gauge_fee_claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "alm_lower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "alm_upper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "alm_total_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_total_supply1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_staked_supply0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "alm_staked_supply1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "alm_total_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_staked_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_earned", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_claimable0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_alm_claimable1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee_amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee_amount1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isStaked", + "type": "bool" + } + ], + "internalType": "struct IPearlV2PoolAPI.PositionInfo[]", + "name": "account_positions", + "type": "tuple[]" + } + ], + "internalType": "struct IPearlV2PoolAPI.PairInfo", + "name": "_pairInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "getPairBribe", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "epochTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVotes", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "internalType": "struct IPearlV2PoolAPI.TokenBribe[]", + "name": "bribes", + "type": "tuple[]" + } + ], + "internalType": "struct IPearlV2PoolAPI.PairBribeEpoch[]", + "name": "_pairEpoch", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_intialOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "address", + "name": "_posManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_liquidBoxManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_factoryV1", + "type": "address" + }, + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lboxManager", + "outputs": [ + { + "internalType": "contract ILiquidBoxManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewPerEpoch", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFactory", + "outputs": [ + { + "internalType": "contract IPearlV2Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFactoryV1", + "outputs": [ + { + "internalType": "contract IPearlV1Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "positionManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidBoxManager", + "type": "address" + } + ], + "name": "setBoxManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_posManager", + "type": "address" + } + ], + "name": "setPositionManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voter", + "type": "address" + } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "enum IPearlV2PoolAPI.Version", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "contract IVoter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/pearl-v2/abis/PairFactory.json b/src/adaptors/pearl-v2/abis/PairFactory.json new file mode 100644 index 0000000000..666edda79e --- /dev/null +++ b/src/adaptors/pearl-v2/abis/PairFactory.json @@ -0,0 +1,514 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_initialOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolImplementation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "GaugeManagerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "PoolImplementationChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "PoolManagerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "RebaseProxyChanged", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "createPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "feeAmountTickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initializePoolPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "parameters", + "outputs": [ + { + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeManager", + "type": "address" + } + ], + "name": "setGaugeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "setPoolGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolImplementation", + "type": "address" + } + ], + "name": "setPoolImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolManager", + "type": "address" + } + ], + "name": "setPoolManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rebaseProxy", + "type": "address" + } + ], + "name": "setRebaseProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/pearl-v2/index.js b/src/adaptors/pearl-v2/index.js new file mode 100644 index 0000000000..9af8182f43 --- /dev/null +++ b/src/adaptors/pearl-v2/index.js @@ -0,0 +1,265 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abis/PairFactory.json'); +const abiPairAPI = require('./abis/PairAPI.json'); +const abiBoxTrident = require('./abis/BoxTrident.json'); + +const PAIR_FACTORY_ADDRESS = '0xeF0b0a33815146b599A8D4d3215B18447F2A8101'; +const PAIR_API_ADDRESS = '0xa0b313836ec65bD999cc78a0000C7f0a8DCe16A9'; +const PEARL_V2_AMOUNTS = '0x861e27AF5B47a7D91e801cc1cd8d19bD3fcDFCA6'; +const PEARL_ADDRESS = '0xCE1581d7b4bA40176f0e219b2CaC30088Ad50C7A'; +const CHAIN_NAME = 'real'; + +/** + * Retrieves and computes APY for pools of tokens on the Polygon blockchain. + */ +const getAPY = async () => { + const allPairs = await getAllPairs(); + const pairInfo = await getPairInfo(allPairs); + const prices = await getTokenPrices(pairInfo); + const pearlPrice = prices[PEARL_ADDRESS.toLowerCase()]; + + await computePairInfo(pairInfo, prices, pearlPrice); + + return pairInfo.map(formatPool).filter(utils.keepFinite); +}; + +/** + * Fetches all pairs from the blockchain. + */ +async function getAllPairs() { + const allPairsLength = ( + await sdk.api.abi.call({ + target: PAIR_FACTORY_ADDRESS, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: CHAIN_NAME, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: PAIR_FACTORY_ADDRESS, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: CHAIN_NAME, + }) + ).output.map((o) => o.output); + + return allPairs; +} + +/** + * Fetches and formats pair info from the blockchain. + */ +async function getPairInfo(allPairs) { + const zip = (a, b) => a.map((k, i) => [k, b[i]]); + const keys = [ + // pair info + "version", + "pair_address", // pair contract address + "box_address", // box contract address + "box_manager_address", // box manager contract address + "name", // pair name + "symbol", // pair symbol + "decimals", //v1Pools LP token decimals + "token0", // pair 1st token address + "token1", // pair 2nd token address + "fee", // fee of the pair + "token0_symbol", // pair 1st token symbol + "token0_decimals", // pair 1st token decimals + "token1_symbol", // pair 2nd token symbol + "token1_decimals", // pair 2nd token decimals + "total_supply", // total supply of v1 pools + "total_supply0", // token0 available in pool + "total_supply1", // token1 available in pool + "total_liquidity", //liquidity of the pool + "sqrtPriceX96", + "tick", + // pairs gauge + "gauge", // pair gauge address + "gauge_alm", // pair gauge ALM address + "gauge_alm_total_supply", // pair staked tokens (less/eq than/to pair total supply) + "gauge_fee", // pair fees contract address + "gauge_fee_claimable0", // fees claimable in token1 + "gauge_fee_claimable1", // fees claimable in token1 + "bribe", // pair bribes contract address + "emissions", // pair emissions (per second) for active liquidity + "emissions_token", // pair emissions token address + "emissions_token_decimals", // pair emissions token decimals + //alm + "alm_lower", //lower limit of the alm + "alm_upper", //upper limit of the alm + "alm_total_supply0", // token0 available in alm + "alm_total_supply1", // token1 available in alm + "alm_staked_supply0", // token0 available in alm for staked ALM LP token + "alm_staked_supply1", // token1 available in alm for staked ALM LP token + "alm_total_liquidity", //liquidity of the alm + // User deposit + "account_lp_balance", //v1Pools account LP tokens balance + "account_lp_amount0", // total amount of token0 available in pool including alm for account + "account_lp_amount1", // total amount of token1 available in pool including alm for account + "account_lp_alm", // total amount of token0 available in pool including alm for account + "account_lp_alm_staked", // total amount of token0 available in pool including alm for account + "account_lp_alm_amount0", // amount of token0 available in alm for account + "account_lp_alm_amount1", // amount of token1 available in alm for account + "account_lp_alm_staked_amount0", // amount of token1 for staked ALM LP token + "account_lp_alm_staked_amount1", // amount of token0 for stakedALM LP token + "account_lp_alm_earned", // amount of rewards earned on stake ALM LP token + "account_lp_alm_claimable0", // total amount of token0 available in pool including alm for account + "account_lp_alm_claimable1", // total amount of token0 available in pool including alm for account + "account_token0_balance", // account 1st token balance + "account_token1_balance", // account 2nd token balance + 'account_gauge_balance', // account pair staked in gauge balance + ]; + + const abi = abiPairAPI.find((m) => m.name === 'getPair'); + + const result = await Promise.all( + allPairs.map((i) => sdk.api.abi.call({ + target: PAIR_API_ADDRESS, + params: [i, '0x1111110000000000000000000000000000000000', 1], + abi: abi, + chain: CHAIN_NAME, + })) + ); + + const pairInfo = result.map((o) => Object.fromEntries(zip(keys, o.output))); + + return pairInfo; +} + +/** + * Fetches prices for all tokens used in the pairs. + */ +async function getTokenPrices(pairInfo) { + const tokens = [ + ...new Set( + pairInfo + .map((p) => [p.token0, p.token1]) + .flat() + .concat(PEARL_ADDRESS) + ), + ]; + + const allCoins = ( + await axios.get( + 'https://api.coingecko.com/api/v3/coins/list?include_platform=true' + ) + ).data.filter( + (coin) => coin && coin.platforms && coin.platforms['re-al'] + ); + + const tokenAddresses = tokens.map((a) => a.toLowerCase()); + const coins = allCoins.filter((coin) => + tokenAddresses.includes(coin.platforms['re-al'].toLowerCase()) + ); + const markets = ( + await axios.get( + `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${coins + .map((c) => c.id) + .join(',')}` + ) + ).data; + + async function getPriceFromDexScreener(token) { + const pairs = ( + await axios.get(`https://api.dexscreener.com/latest/dex/tokens/${token}`) + ).data.pairs; + if (!pairs?.length) return undefined; + const totalLiquidity = pairs + .map((p) => p.liquidity.usd) + .reduce((a, b) => a + b); + return ( + pairs.map((p) => p.priceUsd * p.liquidity.usd).reduce((a, b) => a + b) / + totalLiquidity + ); + } + + function getPriceFromCoinGecko(token) { + const id = allCoins.find( + (coin) => + coin.platforms['re-al'].toLowerCase() === token.toLowerCase() + )?.id; + if (id === undefined) return undefined; + const marketData = markets.find((m) => m.id === id); + return marketData?.current_price; + } + + async function getPrice(token) { + return ( + getPriceFromCoinGecko(token) ?? (await getPriceFromDexScreener(token)) + ); + } + + const pricePromises = tokenAddresses.map((t) => + getPrice(t).then((p) => [t, p]) + ); + const prices = await Promise.all(pricePromises).then((results) => + Object.fromEntries(results) + ); + + return prices; +} + +/** + * Computes additional properties for each pair info object. + */ +async function computePairInfo(pairInfo, prices, pearlPrice) { + pairInfo = pairInfo.filter((p) => Number(p.total_liquidity) !== 0); + for (let i = 0; i < pairInfo.length; i++) { + const pi = pairInfo[i]; + pi.reserve0Usd = pi.total_supply0 === 0 ? 0 : + (pi.total_supply0 / Math.pow(10, pi.token0_decimals)) * + (prices[pi.token0.toLowerCase()] ?? 0); + pi.reserve1Usd = pi.total_supply1 === 0 ? 0 : + (pi.total_supply1 / Math.pow(10, pi.token1_decimals)) * + (prices[pi.token1.toLowerCase()] ?? 0); + pi.pairTvlUsd = pi.reserve0Usd + pi.reserve1Usd; + // calculate staked amount by using pearl v2 amounts contract + const results = pi.box_address !== "0x0000000000000000000000000000000000000000" ? (await sdk.api.abi.call({ + target: pi.box_address, + abi: abiBoxTrident.find((m) => m.name === 'getTotalAmounts'), + chain: CHAIN_NAME, + })).output : {pool0:0, pool1:0, liquidity:0, total0:0, total1:0}; + + // through amounts + pi.stakedReserve0Usd = results.total0 === 0 ? 0 : + (results.total0 / Math.pow(10, pi.token0_decimals)) * + (prices[pi.token0.toLowerCase()] ?? 0); + pi.stakedReserve1Usd = results.total1 === 0 ? 0 : + (results.total1 / Math.pow(10, pi.token1_decimals)) * + (prices[pi.token1.toLowerCase()] ?? 0); + pi.stakedUsd = pi.stakedReserve0Usd + pi.stakedReserve1Usd; + + pi.apr = pi.stakedUsd === 0 ? 0 : + (((pi.emissions / Math.pow(10, 18)) * pearlPrice * 86400 * 365) / + pi.stakedUsd) * + 100; + } +} + +/** + * Formats a pair info object into a pool object. + */ +function formatPool(p) { + return { + pool: p.pair_address, + chain: utils.formatChain('real'), + project: 'pearl-v2', + symbol: utils.formatSymbol(p.symbol.split('-')[1]), + tvlUsd: p.pairTvlUsd, + apyReward: p.apr, + rewardTokens: p.apr ? [PEARL_ADDRESS] : [], + underlyingTokens: [p.token0, p.token1], + }; +} + +module.exports = { + timetravel: false, + apy: getAPY, + url: 'https://www.pearl.exchange/pools', +}; diff --git a/src/adaptors/pearlfi/abis/Gauge.json b/src/adaptors/pearlfi/abis/Gauge.json new file mode 100644 index 0000000000..8c5fa85efd --- /dev/null +++ b/src/adaptors/pearlfi/abis/Gauge.json @@ -0,0 +1,687 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_distribution", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isForPair", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DISTRIBUTION", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_VE", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "_balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeRewarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardForDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewarderPid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_distribution", + "type": "address" + } + ], + "name": "setDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeRewarder", + "type": "address" + } + ], + "name": "setGaugeRewarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "setRewarderPid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAllAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/pearlfi/abis/Pair.json b/src/adaptors/pearlfi/abis/Pair.json new file mode 100644 index 0000000000..999e0900e5 --- /dev/null +++ b/src/adaptors/pearlfi/abis/Pair.json @@ -0,0 +1,1112 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/pearlfi/abis/PairAPI.json b/src/adaptors/pearlfi/abis/PairAPI.json new file mode 100644 index 0000000000..d9441d869c --- /dev/null +++ b/src/adaptors/pearlfi/abis/PairAPI.json @@ -0,0 +1,635 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "Owner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVoter", + "type": "address" + } + ], + "name": "Voter", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_EPOCHS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PAIRS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARDS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEEK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + } + ], + "name": "getAllPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fee", + "type": "address" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo[]", + "name": "Pairs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fee", + "type": "address" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo", + "name": "_pairInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "getPairBribe", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "epochTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVotes", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "internalType": "struct PairAPI.tokenBribe[]", + "name": "bribes", + "type": "tuple[]" + } + ], + "internalType": "struct PairAPI.pairBribeEpoch[]", + "name": "_pairEpoch", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voter", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewPerEpoch", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFactory", + "outputs": [ + { + "internalType": "contract IPairFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voter", + "type": "address" + } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "contract IVoter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/pearlfi/abis/PairFactory.json b/src/adaptors/pearlfi/abis/PairFactory.json new file mode 100644 index 0000000000..7e1da3aaa6 --- /dev/null +++ b/src/adaptors/pearlfi/abis/PairFactory.json @@ -0,0 +1,459 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "getFeeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_state", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/pearlfi/abis/Voter.json b/src/adaptors/pearlfi/abis/Voter.json new file mode 100644 index 0000000000..631d9cb627 --- /dev/null +++ b/src/adaptors/pearlfi/abis/Voter.json @@ -0,0 +1,1402 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "internal_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "external_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "_initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_bribes", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_fees", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "createGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "finish", + "type": "uint256" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "external_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gauges", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gaugesDistributionTimestmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "increaseGaugeApprovals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_pools", + "type": "address[]" + } + ], + "name": "initGauges", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauges", + "type": "address" + }, + { + "internalType": "address", + "name": "_bribes", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "internal_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAlive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isGauge", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGaugeTotally", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lastVoted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolForGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolVote", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "poolVoteLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bribeFactory", + "type": "address" + } + ], + "name": "setBribeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_council", + "type": "address" + } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeFactory", + "type": "address" + } + ], + "name": "setGaugeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal", + "type": "address" + }, + { + "internalType": "address", + "name": "_external", + "type": "address" + } + ], + "name": "setNewBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + } + ], + "name": "setPairFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_usdr", + "type": "address" + } + ], + "name": "setUSDR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usedWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_poolVote", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_weights", + "type": "uint256[]" + } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "weights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_token", + "type": "address[]" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/pearlfi/index.js b/src/adaptors/pearlfi/index.js new file mode 100644 index 0000000000..2b78e86f67 --- /dev/null +++ b/src/adaptors/pearlfi/index.js @@ -0,0 +1,221 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abis/PairFactory.json'); +const abiPairAPI = require('./abis/PairAPI.json'); + +const PAIR_FACTORY_ADDRESS = '0xEaF188cdd22fEEBCb345DCb529Aa18CA9FcB4FBd'; +const PAIR_API_ADDRESS = '0xa6E13F76632A5c6c007Da0Fc00e8659fCEB7Bb66'; +const PEARL_ADDRESS = '0x7238390d5f6F64e67c3211C343A410E2A3DEc142'; +const CHAIN_NAME = 'polygon'; + +/** + * Retrieves and computes APY for pools of tokens on the Polygon blockchain. + */ +const getAPY = async () => { + const allPairs = await getAllPairs(); + const pairInfo = await getPairInfo(allPairs); + const prices = await getTokenPrices(pairInfo); + const pearlPrice = prices[PEARL_ADDRESS.toLowerCase()]; + + computePairInfo(pairInfo, prices, pearlPrice); + + return pairInfo.map(formatPool).filter(utils.keepFinite); +}; + +/** + * Fetches all pairs from the blockchain. + */ +async function getAllPairs() { + const allPairsLength = ( + await sdk.api.abi.call({ + target: PAIR_FACTORY_ADDRESS, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: CHAIN_NAME, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: PAIR_FACTORY_ADDRESS, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: CHAIN_NAME, + }) + ).output.map((o) => o.output); + + return allPairs; +} + +/** + * Fetches and formats pair info from the blockchain. + */ +async function getPairInfo(allPairs) { + const zip = (a, b) => a.map((k, i) => [k, b[i]]); + const keys = [ + 'pair_address', + 'symbol', + 'name', + 'decimals', + 'stable', + 'total_supply', + // token pair info + 'token0', + 'token0_symbol', + 'token0_decimals', + 'reserve0', + 'claimable0', + 'token1', + 'token1_symbol', + 'token1_decimals', + 'reserve1', + 'claimable1', + // pairs gauge + 'gauge', + 'gauge_total_supply', + 'fee', + 'bribe', + 'emissions', + 'emissions_token', + 'emissions_token_decimals', + // user deposit + 'account_lp_balance', + 'account_token0_balance', + 'account_token1_balance', + 'account_gauge_balance', + 'account_gauge_earned', + ]; + + const pairInfo = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: PAIR_API_ADDRESS, + params: [i, '0x0000000000000000000000000000000000000000'], + })), + abi: abiPairAPI.find((m) => m.name === 'getPair'), + chain: CHAIN_NAME, + }) + ).output.map((o) => Object.fromEntries(zip(keys, o.output))); + + return pairInfo; +} + +/** + * Fetches prices for all tokens used in the pairs. + */ +async function getTokenPrices(pairInfo) { + const tokens = [ + ...new Set( + pairInfo + .map((p) => [p.token0, p.token1]) + .flat() + .concat(PEARL_ADDRESS) + ), + ]; + + const allCoins = ( + await axios.get( + 'https://api.coingecko.com/api/v3/coins/list?include_platform=true' + ) + ).data.filter( + (coin) => coin && coin.platforms && coin.platforms['polygon-pos'] + ); + + const tokenAddresses = tokens.map((a) => a.toLowerCase()); + const coins = allCoins.filter((coin) => + tokenAddresses.includes(coin.platforms['polygon-pos'].toLowerCase()) + ); + const markets = ( + await axios.get( + `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${coins + .map((c) => c.id) + .join(',')}` + ) + ).data; + + async function getPriceFromDexScreener(token) { + const pairs = ( + await axios.get(`https://api.dexscreener.com/latest/dex/tokens/${token}`) + ).data.pairs; + if (!pairs?.length) return undefined; + const totalLiquidity = pairs + .map((p) => p.liquidity.usd) + .reduce((a, b) => a + b); + return ( + pairs.map((p) => p.priceUsd * p.liquidity.usd).reduce((a, b) => a + b) / + totalLiquidity + ); + } + + function getPriceFromCoinGecko(token) { + const id = allCoins.find( + (coin) => + coin.platforms['polygon-pos'].toLowerCase() === token.toLowerCase() + )?.id; + if (id === undefined) return undefined; + const marketData = markets.find((m) => m.id === id); + return marketData?.current_price; + } + + async function getPrice(token) { + return ( + getPriceFromCoinGecko(token) ?? (await getPriceFromDexScreener(token)) + ); + } + + const pricePromises = tokenAddresses.map((t) => + getPrice(t).then((p) => [t, p]) + ); + const prices = await Promise.all(pricePromises).then((results) => + Object.fromEntries(results) + ); + + return prices; +} + +/** + * Computes additional properties for each pair info object. + */ +function computePairInfo(pairInfo, prices, pearlPrice) { + for (const pi of pairInfo) { + pi.reserve0Usd = + (pi.reserve0 / Math.pow(10, pi.token0_decimals)) * + prices[pi.token0.toLowerCase()]; + pi.reserve1Usd = + (pi.reserve1 / Math.pow(10, pi.token1_decimals)) * + prices[pi.token1.toLowerCase()]; + pi.pairTvlUsd = pi.reserve0Usd + pi.reserve1Usd; + pi.staked = pi.gauge_total_supply / pi.total_supply; + pi.stakedUsd = pi.pairTvlUsd * pi.staked; + pi.apr = + (((pi.emissions / Math.pow(10, 18)) * pearlPrice * 86400 * 365) / + pi.stakedUsd) * + 100; + } +} + +/** + * Formats a pair info object into a pool object. + */ +function formatPool(p) { + const apyReward = (Math.pow(1 + p.apr / 36500, 365) - 1) * 100; // daily compounding + return { + pool: p.pair_address, + chain: utils.formatChain('polygon'), + project: 'pearlfi', + symbol: utils.formatSymbol(p.symbol.split('-')[1]), + tvlUsd: p.pairTvlUsd, + apyReward, + rewardTokens: p.apr ? [PEARL_ADDRESS] : [], + underlyingTokens: [p.token0, p.token1], + }; +} + +module.exports = { + timetravel: false, + apy: getAPY, + url: 'https://www.pearl.exchange/liquidity', +}; diff --git a/src/adaptors/pembrock-finance/index.ts b/src/adaptors/pembrock-finance/index.ts new file mode 100644 index 0000000000..3db7044646 --- /dev/null +++ b/src/adaptors/pembrock-finance/index.ts @@ -0,0 +1,206 @@ +const BigNumber = require('bignumber.js'); +const axios = require('axios'); + +const { + calculateLendTableData, + calcFarmTableData, + commonCall, + getVolume, + getTvl, +} = require('./utils'); + +const tokensMetadata = require('./tokens_metadata'); + +const PEMBROCK_CONTRACT = 'v1.pembrock.near'; +const REF_FINANCE_CONTRACT = 'v2.ref-finance.near'; +const REF_BOOST_CONTRACT = 'boostfarm.ref-labs.near'; +const PEM_TOKEN = 'token.pembrock.near'; + +const indexerUrl = 'https://indexer.ref.finance/'; + +const endpoint = 'https://rpc.mainnet.near.org/'; + +const getNearPrice = async (): Promise => { + return commonCall('https://helper.mainnet.near.org', 'get') + .then((res) => res.json()) + .then((price) => { + return price.near.usd.toString(); + }) + .catch(() => []); +}; + +async function call(contract, method, args = {}) { + const result = await axios.post(endpoint, { + jsonrpc: '2.0', + id: '1', + method: 'query', + params: { + request_type: 'call_function', + finality: 'final', + account_id: contract, + method_name: method, + args_base64: Buffer.from(JSON.stringify(args)).toString('base64'), + }, + }); + if (result.data.error) { + throw new Error(`${result.data.error.message}: ${result.data.error.data}`); + } + return JSON.parse(Buffer.from(result.data.result.result).toString()); +} + +async function getFormattedFarms(tokenPrices): Promise<[any[], any]> { + const farms: Record = await call( + PEMBROCK_CONTRACT, + 'get_farms', + {} + ); + + const volume = await Promise.all( + Object.keys(farms).map((key) => { + return getVolume(farms[key]['ref_pool_id']); + }) + ); + + const tvl = await Promise.all( + Object.keys(farms).map((key) => { + return getTvl(farms[key]['ref_pool_id']); + }) + ); + + const tokens = await call(PEMBROCK_CONTRACT, 'get_tokens', {}); + + const arr = Object.keys(farms).map((key) => ({ + ...farms[key], + pem_farm_id: +key, + })); + arr.forEach((item: Record, index) => { + // we need only 7 days exclude current day + item.volume = volume[index].slice(1, 8); + // we need only 7 days exclude current day + item.tvl = tvl[index].slice(1, 8); + + item.token1 = tokens[item.token1_id]; + item.token2 = tokens[item.token2_id]; + item.t1meta = tokensMetadata[item.token1_id]; + item.t2meta = tokensMetadata[item.token2_id]; + + item.tokensPriceList = tokenPrices || []; + }); + + for (let farm of arr) { + const pool = await commonCall( + indexerUrl, + `list-pools-by-ids?ids=${farm.ref_pool_id}` + ); + farm.pool = pool[0]; + const seed_id = `${REF_FINANCE_CONTRACT}@${farm.ref_pool_id}`; + const listFarmsBySeed = await call(REF_BOOST_CONTRACT, 'list_seed_farms', { + seed_id, + }); + const seedInfo = await call(REF_BOOST_CONTRACT, 'get_seed', { seed_id }); + farm.listFarmsBySeed = listFarmsBySeed; + farm.seedInfo = seedInfo; + } + + const tokensList = Object.entries(tokens).map( + ([key, value]: [string, any]) => ({ + id: key, + ...value, + refPrice: tokenPrices[key].price, + metadata: tokensMetadata[key], + }) + ); + return [arr, tokensList]; +} + +async function getLendPoolApyData(tokenInfos, pemTokenPrice) { + const lendPools: Record = await call( + PEMBROCK_CONTRACT, + 'get_tokens', + { + account_id: PEMBROCK_CONTRACT, + } + ); + const lendPoolsApyData = []; + + for (let [token, lendPoolInfo] of Object.entries(lendPools)) { + if ( + token === 'c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near' + ) + continue; + const tokenInfo = tokenInfos[token]; + + const tokenPrice = new BigNumber(lendPoolInfo.total_supply) + .multipliedBy(tokenInfo.price) + .shiftedBy(-tokenInfo.decimal); + + const { totalLendAPY } = calculateLendTableData( + { + ...lendPoolInfo, + metadata: tokensMetadata[token], + refPrice: tokenInfo.price, + }, + pemTokenPrice + ); + + lendPoolsApyData.push({ + pool: `${token}-lending`, + chain: 'NEAR', + project: 'pembrock-finance', + symbol: tokensMetadata[token]?.symbol, + poolMeta: 'Ref-Finance', + apy: +totalLendAPY, + tvlUsd: tokenPrice.toNumber(), + }); + } + return lendPoolsApyData; +} + +async function getFarmPoolApyData(tokenInfos) { + const [farms, tokens] = await getFormattedFarms(tokenInfos); + const farmPoolsApyData = []; + + for (let farm of Object.values(farms)) { + const token1 = tokensMetadata[farm['token1_id']]; + const token2 = tokensMetadata[farm['token2_id']]; + + const leverage = 1000; + + const dataBorrowToken1 = calcFarmTableData(farm, true, leverage, tokens); + const dataBorrowToken2 = calcFarmTableData(farm, false, leverage, tokens); + + const data = + dataBorrowToken1.apy > dataBorrowToken2.apy + ? dataBorrowToken1 + : dataBorrowToken2; + + farmPoolsApyData.push({ + pool: `ref-pool-${farm.ref_pool_id}-farming`, + chain: 'NEAR', + project: 'pembrock-finance', + symbol: `${token1?.symbol}-${token2?.symbol}`, + poolMeta: 'Ref-Finance', + apy: +data.apy, + tvlUsd: +data.tvl, + }); + } + + return farmPoolsApyData; +} + +async function getPemApy() { + const tokenInfos = await commonCall(indexerUrl, 'list-token-price'); + const pemToken = tokenInfos[PEM_TOKEN]; + + const lendPools = await getLendPoolApyData(tokenInfos, pemToken.price); + const farmPools = await getFarmPoolApyData(tokenInfos); + return [...lendPools, ...farmPools].filter( + (p) => p.symbol && !p.symbol.includes('undefined') + ); +} + +module.exports = { + timetravel: false, + apy: getPemApy, + url: 'https://app.pembrock.finance/farm', +}; diff --git a/src/adaptors/pembrock-finance/tokens_metadata.ts b/src/adaptors/pembrock-finance/tokens_metadata.ts new file mode 100644 index 0000000000..f6e4373642 --- /dev/null +++ b/src/adaptors/pembrock-finance/tokens_metadata.ts @@ -0,0 +1,192 @@ +const tokensMetadata: Record = { + 'wrap.near': { + decimals: 24, + symbol: 'wNEAR', + }, + 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near': { + decimals: 6, + symbol: 'USDC', + }, + 'dac17f958d2ee523a2206206994597c13d831ec7.factory.bridge.near': { + decimals: 6, + symbol: 'USDT', + }, + '6b175474e89094c44da98b954eedeac495271d0f.factory.bridge.near': { + decimals: 18, + symbol: 'DAI', + }, + 'c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near': { + decimals: 18, + symbol: 'WETH', + }, + '111111111117dc0aa78b770fa6a738034120c302.factory.bridge.near': { + decimals: 18, + symbol: '1INCH', + }, + 'c944e90c64b2c07662a292be6244bdf05cda44a7.factory.bridge.near': { + decimals: 18, + symbol: 'GRT', + }, + 'token.skyward.near': { + decimals: 18, + symbol: 'SKYWARD', + }, + 'token.v2.ref-finance.near': { + decimals: 18, + symbol: 'REF', + }, + 'berryclub.ek.near': { + decimals: 18, + symbol: 'BANANA', + }, + '6f259637dcd74c767781e37bc6133cd6a68aa161.factory.bridge.near': { + decimals: 18, + symbol: 'HT', + }, + 'de30da39c46104798bb5aa3fe8b9e0e1f348163f.factory.bridge.near': { + decimals: 18, + symbol: 'GTC', + }, + '1f9840a85d5af5bf1d1762f925bdaddc4201f984.factory.bridge.near': { + decimals: 18, + symbol: 'UNI', + }, + '2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near': { + decimals: 8, + symbol: 'WBTC', + }, + '514910771af9ca656af840dff83e8264ecf986ca.factory.bridge.near': { + decimals: 18, + symbol: 'LINK', + }, + 'token.paras.near': { + decimals: 18, + symbol: 'PARAS', + }, + 'meta-pool.near': { + decimals: 24, + symbol: 'STNEAR', + }, + 'marmaj.tkn.near': { + decimals: 18, + symbol: 'MARMAJ', + }, + '52a047ee205701895ee06a375492490ec9c597ce.factory.bridge.near': { + decimals: 18, + symbol: 'PULSE', + }, + aurora: { + decimals: 18, + symbol: 'ETH', + }, + 'aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near': { + decimals: 18, + symbol: 'AURORA', + }, + 'dbio.near': { + decimals: 18, + symbol: 'DBIO', + }, + 'f5cfbc74057c610c8ef151a439252680ac68c6dc.factory.bridge.near': { + decimals: 18, + symbol: 'OCT', + }, + 'd9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near': { + decimals: 18, + symbol: 'HAPI', + }, + 'meta-token.near': { + decimals: 24, + symbol: 'META', + }, + 'v3.oin_finance.near': { + decimals: 8, + symbol: 'USDO', + }, + '3ea8ea4237344c9931214796d9417af1a1180770.factory.bridge.near': { + decimals: 18, + symbol: 'FLX', + }, + 'pixeltoken.near': { + decimals: 6, + symbol: 'PXT', + }, + 'myriadcore.near': { + decimals: 18, + symbol: 'MYRIA', + }, + 'celo.token.a11bd.near': { + decimals: 24, + symbol: 'CELO', + }, + 'cusd.token.a11bd.near': { + decimals: 24, + symbol: 'cUSD', + }, + 'abr.a11bd.near': { + decimals: 24, + symbol: 'ABR', + }, + 'sol.token.a11bd.near': { + decimals: 24, + symbol: 'SOL', + }, + 'utopia.secretskelliessociety.near': { + decimals: 8, + symbol: 'UTO', + }, + '4691937a7508860f876c9c0a2a617e7d9e945d4b.factory.bridge.near': { + decimals: 18, + symbol: 'WOO', + }, + 'linear-protocol.near': { + decimals: 24, + symbol: 'LINEAR', + }, + '0316eb71485b0ab14103307bf65a021042c6d380.factory.bridge.near': { + decimals: 18, + symbol: 'HBTC', + }, + 'token.cheddar.near': { + decimals: 24, + symbol: 'Cheddar', + }, + 'token.pembrock.near': { + decimals: 18, + symbol: 'PEM', + }, + 'token.burrow.near': { + decimals: 18, + symbol: 'BRRR', + }, + 'atocha-token.near': { + decimals: 18, + symbol: 'ATO', + }, + 'nearx.stader-labs.near': { + decimals: 24, + symbol: 'NearX', + }, + '30d20208d987713f46dfd34ef128bb16c404d10f.factory.bridge.near': { + decimals: 18, + symbol: 'SD', + }, + 'xtoken.ref-finance.near': { + decimals: 18, + symbol: 'xREF', + }, + usn: { + decimals: 18, + symbol: 'USN', + }, + 'rftt.tkn.near': { + decimals: 8, + symbol: 'RFTT', + }, + 'token.sweat': { + decimals: 18, + symbol: 'SWEAT', + }, +}; + +module.exports = tokensMetadata; diff --git a/src/adaptors/pembrock-finance/utils.ts b/src/adaptors/pembrock-finance/utils.ts new file mode 100644 index 0000000000..b226f3a43e --- /dev/null +++ b/src/adaptors/pembrock-finance/utils.ts @@ -0,0 +1,330 @@ +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const statsUrl = 'https://api.stats.ref.finance/'; + +const PEM_TOKEN = 'token.pembrock.near'; + +interface Volume { + pool_id: string; + volume_dollar: string; +} + +interface PoolInfo { + amounts: string[]; + farming: boolean; + id: string; + pool_kind: string; + shares_total_supply: string; + token_account_ids: string[]; + total_fee: number; + tvl: string; +} + +interface FarmInfo { + max_leverage: number; + ref_pool_id: number; + shares: string; + token1_id: string; + token2_id: string; + value: string; + + seedInfo?: object; + token1?: TokenInfo; + token2?: TokenInfo; + listFarmsBySeed?: []; + pool?: PoolInfo; + volume?: Volume[]; + tvl?: object; + tokensPriceList?: object[]; +} + +interface TokenMetadata { + id: string; + decimals: number; + price?: string; +} + +interface TokenInfo { + total_supply: string; + total_borrowed: string; + lend_shares: string; + debt_shares: string; + debt_rate?: string; + lend_reward_rate_per_week: string; + debt_reward_rate_per_week: string; +} + +interface TokenWithMetadata extends TokenInfo { + id: string; + metadata: TokenMetadata; + refPrice?: string; +} + +interface FarmTableData { + apy: string; + tvl?: string; +} + +interface LendTableData { + totalLendAPY: string; +} + +interface TVL { + pool_id: string; + asset_amount: string; + fiat_amount: string; + asset_price: string; + fiat_price: string; + asset_tvl: string; + fiat_tvl: string; + date: string; +} + +async function commonCall(url, method, args = {}) { + const result = await axios({ + method: 'get', + url: url + method, + params: args, + }); + if (result.data.error) { + throw new Error(`${result.data.error.message}: ${result.data.error.data}`); + } + return result.data; +} + +const apr2apy = (apr: BigNumber): BigNumber => { + return apr.div(365).plus(1).pow(365).minus(1); +}; + +const getTvl = async (id: string): Promise<[TVL]> => { + return commonCall(statsUrl, `api/pool/${id}/tvl`); +}; + +const getVolume = async (id: string): Promise<[Volume]> => { + return commonCall(statsUrl, `api/pool/${id}/volume`); +}; + +const calcTradingFees = (farm: FarmInfo): BigNumber => { + const { pool, volume, tvl } = farm; + + const sevenDaysSumVolume = Object.keys(volume).reduce((sum, item) => { + return sum.plus(new BigNumber(volume[item]['volume_dollar'])); + }, new BigNumber(0)); + + const sevenDaysSumTvl = Object.keys(tvl).reduce((sum, item) => { + return sum.plus( + new BigNumber(tvl[item]['asset_tvl']).plus( + new BigNumber(tvl[item]['fiat_tvl']) + ) + ); + }, new BigNumber(0)); + + // Calc Trading Fees + const tradingFees = !sevenDaysSumTvl.isZero() + ? sevenDaysSumVolume + .multipliedBy(365) + .multipliedBy(pool ? pool['total_fee'] : 0) + .multipliedBy(0.8) // 20% of total fee takes the exchange + .dividedBy(sevenDaysSumTvl) + .dividedBy(10000) // fee divisor + : new BigNumber(0); + + return tradingFees; +}; + +const calcYieldFarming = (farm: FarmInfo): BigNumber => { + const { listFarmsBySeed, seedInfo, pool, tokensPriceList } = farm; + // Calc Yield Farming + const refTVL = pool && new BigNumber(pool['tvl']); + const refSharesTotalSupply = + pool && new BigNumber(pool['shares_total_supply']); + let yieldFarming = new BigNumber(0); + + const stakedAmount = new BigNumber( + seedInfo ? seedInfo['total_seed_amount'] : 0 + ); + const stakedTVL = stakedAmount + .multipliedBy(refTVL) + .dividedBy(refSharesTotalSupply); + + listFarmsBySeed?.forEach((el: object) => { + const rewardTokenId = el['terms']['reward_token']; + const rewardTokenPrice = tokensPriceList[rewardTokenId]['price']; + const tokenDecimals = tokensPriceList[rewardTokenId]['decimal']; + const rewardPerDay = el['terms']['daily_reward']; + const farmApr = new BigNumber(365) + .multipliedBy(rewardPerDay) + .multipliedBy(rewardTokenPrice) + .dividedBy(stakedTVL) + .shiftedBy(-tokenDecimals); + + yieldFarming = yieldFarming.plus(farmApr); + }); + + return yieldFarming; +}; + +const calcLeveragedFarmData = ( + farm: FarmInfo, + leverage: any, + debtRate: BigNumber, + token: TokenWithMetadata, + pemToken: TokenWithMetadata +) => { + const rewardsAPR = calcDebtRewardsAPR(token, pemToken?.refPrice); + + const _leverage = new BigNumber(leverage); + + let yieldFarming = calcYieldFarming(farm); + let tradingFees = calcTradingFees(farm); + + const yieldFarmingLev = yieldFarming.multipliedBy(_leverage).dividedBy(1000); + const tradingFeesLev = tradingFees.multipliedBy(_leverage).dividedBy(1000); + + let borrowInterestLev = _leverage + .minus(1000) + .negated() + .multipliedBy(debtRate) + .dividedBy(1000); // leverage divisor // ! differe from docs, not divided by 10000 + let rewardsAprLev = _leverage + .minus(1000) + .multipliedBy(rewardsAPR) + .dividedBy(1000); // leverage divisor + + // Calc Total APR + const totalApr = yieldFarmingLev.plus(tradingFeesLev).plus(borrowInterestLev); + + // Calc DailyAPR Apr + const dailyAPR = totalApr.dividedBy(365); + + // Calc APY + const totalApy = dailyAPR + .plus(1) + .pow(365) + .minus(1) + .plus(rewardsAprLev.isNaN() ? 0 : rewardsAprLev); // ! differe from docs, rewardsAprLev added + + return { totalApy }; +}; + +function formatBigNumber(num: any, showDecimals: number = 2): string { + const _num = new BigNumber(num); + return _num.isNaN() ? '--' : _num.toFixed(showDecimals); +} + +const calcFarmTVL = ( + farm: FarmInfo, + tokens: TokenWithMetadata[] +): BigNumber => { + const [token1_id, token2_id] = [farm.token1_id, farm.token2_id]; + const token1 = tokens.find((token) => token.id === token1_id); + const token2 = tokens.find((token) => token.id === token2_id); + + // this condition if we don't have enough data + const refPrice1 = token1?.refPrice || '0'; + const refPrice2 = token2?.refPrice || '0'; + const tokenDecimals1 = token1?.metadata?.decimals || 18; + const tokenDecimals2 = token2?.metadata?.decimals || 18; + + const token1_value = new BigNumber(farm.value) + .multipliedBy(farm.pool.amounts[0]) + .multipliedBy(refPrice1) + .dividedBy(farm.pool.shares_total_supply) + .shiftedBy(-tokenDecimals1); + const token2_value = new BigNumber(farm.value) + .multipliedBy(farm.pool.amounts[1]) + .multipliedBy(refPrice2) + .dividedBy(farm.pool.shares_total_supply) + .shiftedBy(-tokenDecimals2); + return token1_value.plus(token2_value); +}; + +const calcFarmTableData = ( + farm: FarmInfo, + debtIsToken1: boolean, + leverage: number, + tokens: TokenWithMetadata[] +): FarmTableData => { + const pemToken = tokens?.find((item) => item.id === PEM_TOKEN); + const token = tokens?.find( + (item) => item.id === (debtIsToken1 ? farm.token1_id : farm.token2_id) + ); + + const debtRate = new BigNumber(token.debt_rate).shiftedBy(-24); + const calcData = calcLeveragedFarmData( + farm, + leverage, + debtRate, + token, + pemToken + ); + + return { + tvl: formatBigNumber(calcFarmTVL(farm, tokens)), + apy: formatBigNumber(calcData.totalApy.multipliedBy(100)), + }; +}; + +const calcLendRewardsAPR = ( + token: TokenWithMetadata, + pemTokenPrice: string +): BigNumber => { + return token.metadata?.decimals + ? new BigNumber(52) + .multipliedBy(token.lend_reward_rate_per_week) + .multipliedBy(pemTokenPrice) + .shiftedBy(token.metadata.decimals) + .dividedBy(token.total_supply) + .dividedBy(token.refPrice) + .shiftedBy(-18) + : BigNumber(0); +}; + +const calcDebtRewardsAPR = ( + token: TokenWithMetadata, + pemTokenPrice: string +): BigNumber => { + return token.metadata?.decimals + ? new BigNumber(52) + .multipliedBy(token.debt_reward_rate_per_week) + .multipliedBy(pemTokenPrice) + .shiftedBy(token.metadata.decimals) + .dividedBy(token.total_borrowed) + .dividedBy(token.refPrice) + .shiftedBy(-18) + : BigNumber(0); +}; + +const calculateLendTableData = ( + token: TokenWithMetadata, + pemTokenPrice: string +): LendTableData => { + // TODO: use settings.borrow_fee + const borrow_fee = 100; // 10% + const debt_rate = new BigNumber(token.debt_rate).shiftedBy(-24); + const lendAPR = token.total_supply + ? debt_rate + .multipliedBy(10000 - borrow_fee) + .multipliedBy(token.total_borrowed) + .dividedBy(token.total_supply) + .dividedBy(10000) // borrow_fee divisor + : new BigNumber(0); + const lendRewardsAPR = calcLendRewardsAPR(token, pemTokenPrice).multipliedBy( + 100 + ); + const lendAPY = apr2apy(lendAPR).multipliedBy(100); + const totalLendAPY = lendAPY.plus(lendRewardsAPR); + + return { + totalLendAPY: totalLendAPY.toFixed(2), + }; +}; + +module.exports = { + calculateLendTableData, + calcFarmTableData, + commonCall, + getVolume, + getTvl, +}; diff --git a/src/adaptors/pendle/index.js b/src/adaptors/pendle/index.js new file mode 100644 index 0000000000..f58c422b3b --- /dev/null +++ b/src/adaptors/pendle/index.js @@ -0,0 +1,299 @@ +const utils = require('../utils'); +const axios = require('axios'); +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); + +const chains = { + 1: { + chainName: 'ethereum', + chainSlug: 'ethereum', + PENDLE: '0x808507121b80c02388fad14726482e061b8da827', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 42161: { + chainName: 'arbitrum', + chainSlug: 'arbitrum', + PENDLE: '0x0c880f6761f1af8d9aa9c466984b80dab9a8c9e8', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 56: { + chainName: 'bsc', + chainSlug: 'bnbchain', + PENDLE: '0xb3ed0a426155b79b898849803e3b36552f7ed507', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + disabledVolume: true, + }, + 10: { + chainName: 'optimism', + chainSlug: 'optimism', + PENDLE: '0xBC7B1Ff1c6989f006a1185318eD4E7b5796e66E1', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 146: { + chainName: 'sonic', + chainSlug: 'sonic', + PENDLE: '0xf1ef7d2d4c0c881cd634481e0586ed5d2871a74b', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 8453: { + chainName: 'base', + chainSlug: 'base', + PENDLE: '0xa99f6e6785da0f5d6fb42495fe424bce029eeb3e', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 5000: { + chainName: 'mantle', + chainSlug: 'mantle', + PENDLE: '0xd27b18915e7acc8fd6ac75db6766a80f8d2f5729', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, + 999: { + chainName: 'hyperliquid', + chainSlug: 'hyperliquid', + PENDLE: '0xD6Eb81136884713E843936843E286FD2a85A205A', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + disabledVolume: true, + }, + 80094: { + chainName: 'berachain', + chainSlug: 'berachain', + PENDLE: '0xFf9c599D51C407A45D631c6e89cB047Efb88AeF6', + ROUTERS: ['0x888888888889758F76e7103c6CbF23ABbF58F946'], + }, +}; + +function splitId(id) { + const [chainId, address] = id.split('-'); + return { chainId, address }; +} + +function expiryToText(dateIso) { + return new Date(dateIso) + .toLocaleDateString('en-GB', { + day: '2-digit', + month: 'short', + year: 'numeric', + }) + .replace(/ /g, '') + .toUpperCase(); +} + +const ROUTER_EVENTS = { + // on these events, router will do a swap (zap in or zap out) + // so, swap volume = add/remove volume / 2 + AddLiquiditySingleToken: 'event AddLiquiditySingleToken(address indexed caller, address indexed market, address indexed token, address receiver, uint256 netTokenAmount, uint256 netLpOut, uint256 netSyInterm)', + RemoveLiquiditySingleToken: 'event RemoveLiquiditySingleToken(address indexed caller, address indexed market, address indexed token, address receiver, uint256 netLpToRemove, uint256 netTokenAmount, uint256 netSyInterm)', + + // swap volumes + SwapPtAndToken: 'event SwapPtAndToken(address indexed caller, address indexed market, address indexed token, address receiver, int256 netPtToAccount, int256 netTokenAmount, uint256 netSyInterm)', + SwapYtAndToken: 'event SwapYtAndToken(address indexed caller, address indexed market, address indexed token, address receiver, int256 netYtToAccount, int256 netTokenAmount, uint256 netSyInterm)', +} + +async function fetchPoolsVolumes(chain, pools, routers) { + const timestamp = Math.floor(new Date().getTime() / 1000); + const currentBlocks = await sdk.blocks.getBlocks(timestamp, [chain]) + const last1DaysBlocks = await sdk.blocks.getBlocks(timestamp - 24 * 60 * 60, [chain]) + const last7DaysBlocks = await sdk.blocks.getBlocks(timestamp - 7 * 24 * 60 * 60, [chain]) + + const currentBlock = currentBlocks.chainBlocks[chain]; + const last1DaysBlock = last1DaysBlocks.chainBlocks[chain]; + const last7DaysBlock = last7DaysBlocks.chainBlocks[chain]; + + const markets = {} + for (const pool of pools) { + const marketAddress = utils.formatAddress(pool.address) + const tokenAddress = utils.formatAddress(pool.underlyingAsset.split('-')[1]) + markets[utils.formatAddress(pool.address)] = { + market: marketAddress, + token: tokenAddress, + + // will fill at step get swap volumes + volumeUsd1d: 0, + volumeUsd7d: 0, + } + } + + const addLogs = await sdk.getEventLogs({ + chain: chain, + targets: routers, + eventAbi: ROUTER_EVENTS.AddLiquiditySingleToken, + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + }); + const removeLogs = await sdk.getEventLogs({ + chain: chain, + targets: routers, + eventAbi: ROUTER_EVENTS.AddLiquiditySingleToken, + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + }); + const SwapPtAndTokenLogs = await sdk.getEventLogs({ + chain: chain, + targets: routers, + eventAbi: ROUTER_EVENTS.AddLiquiditySingleToken, + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + }); + const SwapYtAndTokenLogs = await sdk.getEventLogs({ + chain: chain, + targets: routers, + eventAbi: ROUTER_EVENTS.AddLiquiditySingleToken, + flatten: true, // !!! + fromBlock: last7DaysBlock, + toBlock: currentBlock, + entireLog: true, + }); + + const iface = new ethers.utils.Interface(Object.values(ROUTER_EVENTS)) + const events = addLogs.concat(removeLogs).map(log => { + const event = iface.parseLog({ + topics: log.topics, + data: log.data, + }); + + const market = utils.formatAddress(event.args.market); + if (!markets[market]) return null; + + let netTokenAmount = Number(event.args.netTokenAmount); + if (event.name === 'AddLiquiditySingleToken' || event.name === 'RemoveLiquiditySingleToken') { + netTokenAmount = netTokenAmount / 2; + } + + return { + tx: log.transactionHash, // for debug purpose + address: utils.formatAddress(log.address), + blockNumber: Number(log.blockNumber), + market, + token: utils.formatAddress(event.args.token), + tokenAmount: netTokenAmount, + } + }).filter(Boolean) + + const tokens = {} + for (const event of events) { + tokens[event.token] = { + price: 0, + decimals: 0, + } + } + + // fill token decimals + const decimals = await sdk.api2.abi.multiCall({ + chain: chain, + abi: 'uint8:decimals', + calls: Object.keys(tokens), + permitFailure: true, + }); + for (let i = 0; i < Object.keys(tokens).length; i++) { + tokens[Object.keys(tokens)[i]].decimals = decimals[i] ? Number(decimals[i]) : 18; + } + + // get token price from llama coins api + const coinLists = Object.keys(tokens).map(token => `${chain}:${token}`); + const coinPrices = (await axios.get(`https://coins.llama.fi/prices/current/${coinLists.toString()}`)).data.coins; + for (const [coinId, coinPrice] of Object.entries(coinPrices)) { + tokens[utils.formatAddress(coinId.split(':')[1])].price = Number(coinPrice.price); + } + + for (const event of events) { + if (!tokens[event.token]) { + console.warn(`Token not found for event.token: ${event.token}`); + continue; + } + if (!markets[event.market]) { + console.warn(`Market not found for event.market: ${event.market}`); + continue; + } + const volumeUsd = event.tokenAmount * tokens[event.token].price / 10**tokens[event.token].decimals; + + if (event.blockNumber >= last1DaysBlock) { + markets[event.market].volumeUsd1d += volumeUsd; + } + markets[event.market].volumeUsd7d += volumeUsd; + } + + return pools.map(pool => { + const market = markets[utils.formatAddress(pool.address)] || { volumeUsd1d: 0, volumeUsd7d: 0 }; + return { + ...pool, + volumeUsd1d: market.volumeUsd1d, + volumeUsd7d: market.volumeUsd7d, + } + }) +} + +async function poolApys(chainId, pools) { + // support swap volumes on pool + const poolWithVolumes = chains[chainId].disabledVolume ? pools : await fetchPoolsVolumes(chains[chainId].chainName, pools, chains[chainId].ROUTERS) + + return poolWithVolumes.map((p) => ({ + pool: p.address, + chain: utils.formatChain(chains[chainId].chainName), + project: 'pendle', + symbol: utils.formatSymbol(p.name), + tvlUsd: p.details.liquidity, + apyBase: (p.details.aggregatedApy - p.details.pendleApy) * 100, + apyReward: p.details.pendleApy * 100, + rewardTokens: [chains[chainId].PENDLE], + underlyingTokens: [splitId(p.pt).address, splitId(p.sy).address], + volumeUsd1d: typeof p.volumeUsd1d === 'number' ? p.volumeUsd1d : 0, + volumeUsd7d: typeof p.volumeUsd7d === 'number' ? p.volumeUsd7d : 0, + poolMeta: `For LP | Maturity ${expiryToText(p.expiry)}`, + url: `https://app.pendle.finance/trade/pools/${p.address}/zap/in?chain=${chains[chainId].chainSlug}`, + })); +} + +function ptApys(chainId, pools) { + return pools.map((p) => ({ + pool: splitId(p.pt).address, + chain: utils.formatChain(chains[chainId].chainName), + project: 'pendle', + symbol: utils.formatSymbol(p.name), + tvlUsd: p.details.liquidity, + apyBase: p.details.impliedApy * 100, + underlyingTokens: [splitId(p.underlyingAsset).address], + poolMeta: `For buying PT-${p.name}-${expiryToText(p.expiry)}`, + url: `https://app.pendle.finance/trade/markets/${p.address}/swap?view=pt&chain=${chains[chainId].chainSlug}&py=output`, + })); +} + +async function apy() { + const date = new Date(); + const poolsFiltered = []; + + await Promise.all( + Object.keys(chains).map(async (chainId) => { + const pools = ( + await axios.get( + `https://api-v2.pendle.finance/core/v1/${chainId}/markets/active` + ) + ).data.markets; + const poolApysList = await poolApys(chainId, pools) + const ptApysList = ptApys(chainId, pools) + + const yieldPools = [poolApysList, ptApysList] + .flat() + .sort((a, b) => b.tvlUsd - a.tvlUsd); + + const unique = new Set(); + for (const p of yieldPools) { + if (unique.has(p.pool)) continue; + poolsFiltered.push(p); + unique.add(p.pool); + } + }) + ); + + return poolsFiltered; +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/penrose/index.js b/src/adaptors/penrose/index.js index 28eb42b318..6af984b72a 100644 --- a/src/adaptors/penrose/index.js +++ b/src/adaptors/penrose/index.js @@ -3,17 +3,24 @@ const utils = require('../utils'); const collectPools = async () => { const data = await utils.getData('https://api.penrose.money/pools'); - return data.map((pool) => ({ - pool: pool.id, - chain: utils.formatChain('polygon'), - project: 'penrose', - symbol: pool.poolData.symbol.replace('-', ' ').replace('/', '-'), - tvlUsd: Number(pool.totalTvlUsd), - apy: utils.aprToApy(Number(pool.totalApr)), - })); + return data + .map((pool) => { + const name = pool.poolData.symbol.split('-'); + return { + pool: pool.id, + chain: utils.formatChain('polygon'), + project: 'penrose', + symbol: utils.formatSymbol(name[1]), + poolMeta: name[0], + tvlUsd: Number(pool.totalTvlUsd), + apy: utils.aprToApy(Number(pool.totalApr)), + }; + }) + .filter((p) => utils.keepFinite(p)); }; module.exports = { timetravel: false, apy: collectPools, + url: 'https://app.penrose.money/dashboard/earn/stake', }; diff --git a/src/adaptors/pepeteam-swaves/index.js b/src/adaptors/pepeteam-swaves/index.js new file mode 100644 index 0000000000..b30e305a4c --- /dev/null +++ b/src/adaptors/pepeteam-swaves/index.js @@ -0,0 +1,47 @@ +const utils = require('../utils'); +const { data } = require('./waves'); + +const wavesStakingContract = '3PDPzZVLhN1EuzGy4xAxjjTVkawKDLEaHiV'; + +async function tvlUsd() { + const contractTVLInWAVES = await data(wavesStakingContract, 'STAKING_AMOUNT'); + + const priceKeys = ['waves', 'usd'].map((t) => `coingecko:${t}`).join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + + const wavesPrice = prices['coingecko:waves'].price; + return (contractTVLInWAVES.value / 1e8) * wavesPrice; +} + +async function apyBase() { + const deltaRateResponse = await data(wavesStakingContract, 'CURRENT_RATE'); + const deltaRateBytes = Buffer.from( + deltaRateResponse.value.substr(7), + 'base64' + ); + var aprPerDay = + ((1440 * deltaRateBytes.readUIntBE(0, deltaRateBytes.length)) / 1e12) * 100; // 1440 blocks/day, 10^12 - contract divider + var apy = utils.aprToApy(aprPerDay * 365); + return apy; +} + +async function apy() { + return [ + { + pool: wavesStakingContract, + symbol: utils.formatSymbol('sWAVES'), + tvlUsd: await tvlUsd(), + apyBase: await apyBase(), + project: 'pepeteam-swaves', + chain: utils.formatChain('waves'), + }, + ]; +} + +module.exports = { + timetravel: false, // Waves blockchain + apy, + url: 'https://swaves.pepe.team', +}; diff --git a/src/adaptors/pepeteam-swaves/waves.js b/src/adaptors/pepeteam-swaves/waves.js new file mode 100644 index 0000000000..737ea38856 --- /dev/null +++ b/src/adaptors/pepeteam-swaves/waves.js @@ -0,0 +1,21 @@ +const utils = require('../utils'); + +const API_HOST = 'https://nodes.wavesnodes.com'; // https://docs.waves.tech/en/waves-node/node-api/#api-of-pool-of-public-nodes + +/** + * Read account data entries by a given key + * @param {string} address - Address base58 encoded + * @param {string} key - Data key + * @returns {{ + * key: string, + * type: string, + * value: any + * }} Data value + */ +async function data(address, key) { + return await utils.getData(`${API_HOST}/addresses/data/${address}/${key}`); +} + +module.exports = { + data, +}; diff --git a/src/adaptors/perpetual-protocol/abi/QuoteVault.js b/src/adaptors/perpetual-protocol/abi/QuoteVault.js new file mode 100644 index 0000000000..7d37a23a7a --- /dev/null +++ b/src/adaptors/perpetual-protocol/abi/QuoteVault.js @@ -0,0 +1,726 @@ +module.exports = [ + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "keeper", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "baseToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reducedPositionSizeAbs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "base", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "quote", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "soldSpotNotional", + "type": "uint256" + } + ], + "name": "Deleverage", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "oldBaseUsdPriceFeed", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBaseUsdPriceFeed", + "type": "address" + } + ], + "name": "UpdateBaseUsdPriceFeed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "oldQuoteUsdPriceFeed", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newQuoteUsdPriceFeed", + "type": "address" + } + ], + "name": "UpdateQuoteUsdPriceFeed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "oldRouter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newRouter", + "type": "address" + } + ], + "name": "UpdateRouterAddress", + "type": "event" + }, + { + "inputs": + [], + "name": "candidate", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "reducedPositionSize", + "type": "uint256" + } + ], + "name": "deleverage", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "getBaseToken", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getBaseUsdPriceFeed", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getIndexPrice", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getQuoteToken", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getQuoteUsdPriceFeed", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getRouter", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getVaultConfig", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "vaultTokenArg", + "type": "address" + }, + { + "internalType": "address", + "name": "quoteTokenArg", + "type": "address" + }, + { + "internalType": "address", + "name": "baseTokenArg", + "type": "address" + }, + { + "internalType": "address", + "name": "vaultConfigArg", + "type": "address" + }, + { + "internalType": "address", + "name": "perpPositionManagerArg", + "type": "address" + } + ], + "name": "initialize", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "owner", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "pause", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "paused", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minRedeemedAmount", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": + [ + { + "internalType": "uint256", + "name": "redeemed", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "renounceOwnership", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "baseUsdPriceFeedArg", + "type": "address" + } + ], + "name": "setBaseUsdPriceFeed", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "quoteUsdPriceFeedArg", + "type": "address" + } + ], + "name": "setQuoteUsdPriceFeed", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "routerArg", + "type": "address" + } + ], + "name": "setRouter", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96OnPerp", + "type": "uint160" + } + ], + "internalType": "struct ICommonVaultStruct.SwapExactInputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "swapExactInput", + "outputs": + [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMaximum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96OnPerp", + "type": "uint160" + } + ], + "internalType": "struct ICommonVaultStruct.SwapExactOutputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "swapExactOutput", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "totalAssets", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "unpause", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "updateOwner", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/perpetual-protocol/abi/erc20.js b/src/adaptors/perpetual-protocol/abi/erc20.js new file mode 100644 index 0000000000..c723c7f723 --- /dev/null +++ b/src/adaptors/perpetual-protocol/abi/erc20.js @@ -0,0 +1,625 @@ +module.exports = [ + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "address", + "name": "oldMinter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "UpdateMinter", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldTotalSupplyCap", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalSupplyCap", + "type": "uint256" + } + ], + "name": "UpdateTotalSupplyCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": false, + "internalType": "uint24", + "name": "oldTransferCooldown", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "newTransferCooldown", + "type": "uint24" + } + ], + "name": "UpdateTransferCooldown", + "type": "event" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "candidate", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "decimals", + "outputs": + [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getLastMintedAt", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getMinter", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getTotalSupplyCap", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "getTransferCooldown", + "outputs": + [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "string", + "name": "nameArg", + "type": "string" + }, + { + "internalType": "string", + "name": "symbolArg", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimalsArg", + "type": "uint8" + }, + { + "internalType": "uint24", + "name": "transferCoolDownArg", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "totalSupplyCapArg", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "name", + "outputs": + [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "owner", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "renounceOwnership", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "minterArg", + "type": "address" + } + ], + "name": "setMinter", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "totalSupplyCapArg", + "type": "uint256" + } + ], + "name": "setTotalSupplyCap", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint24", + "name": "transferCooldownArg", + "type": "uint24" + } + ], + "name": "setTransferCooldown", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "symbol", + "outputs": + [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [], + "name": "totalSupply", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [], + "name": "updateOwner", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/perpetual-protocol/index.js b/src/adaptors/perpetual-protocol/index.js new file mode 100644 index 0000000000..c3d3b94769 --- /dev/null +++ b/src/adaptors/perpetual-protocol/index.js @@ -0,0 +1,147 @@ +const utils = require('../utils'); + +const vaultAbi = require('./abi/QuoteVault'); +const erc20abi = require('./abi/erc20'); +const BN = require('bignumber.js'); +const { getBlocksByTime } = require('../utils'); +const { Web3 } = require('web3'); + +const web3 = new Web3( + new Web3.providers.HttpProvider('https://rpc.ankr.com/optimism') +); + +function getErc20Contract(token) { + return new web3.eth.Contract(erc20abi, token); +} + +async function getDecimals(token) { + const erc20 = getErc20Contract(token); + const decimals = await erc20.methods.decimals().call(); + return BN(decimals); +} + +async function getSymbol(token) { + const erc20 = getErc20Contract(token); + return await erc20.methods.symbol().call(); +} + +async function getTotalAssets(vault, block) { + const vaultContract = new web3.eth.Contract(vaultAbi, vault); + const totalAssets = await vaultContract.methods.totalAssets().call({}, block); + return BN(totalAssets); +} + +async function getTotalSupply(token, block) { + const erc20 = getErc20Contract(token); + const totalSupply = await erc20.methods.totalSupply().call({}, block); + return BN(totalSupply); +} + +async function getTvlInUsd(vault, vaultAssetToken, block) { + const totalAssetX10d = await getTotalAssets(vault, block); + const decimals = await getDecimals(vaultAssetToken); + const price = ( + await utils.getPrices([vaultAssetToken.toLowerCase()], 'optimism') + ).pricesByAddress[vaultAssetToken.toLowerCase()]; + + const totalAsset = totalAssetX10d.div(BN(10).pow(decimals)); + + return totalAsset.times(price).toNumber(); +} + +async function getApyInNDaysPercentage( + vault, + vaultAssetToken, + vaultToken, + blockNow, + blockNDaysAgo, + nDays +) { + const assetTokenDecimal = await getDecimals(vaultAssetToken); + const vaultTokenDecimals = await getDecimals(vaultToken); + + const todayAssetX10d = await getTotalAssets(vault, blockNow); + const todayAsset = todayAssetX10d.div(BN(10).pow(assetTokenDecimal)); + const todaySupplyX10d = await getTotalSupply(vaultToken, blockNow); + + const todaySupply = todaySupplyX10d.div(BN(10).pow(vaultTokenDecimals)); + const todaySharePrice = todayAsset.div(todaySupply); + + const nDaysAgoAssetX10d = await getTotalAssets(vault, blockNDaysAgo); + const nDaysAgoAsset = nDaysAgoAssetX10d.div(BN(10).pow(assetTokenDecimal)); + const nDaysAgoSupplyX10d = await getTotalSupply(vaultToken, blockNDaysAgo); + const nDaysAgoSupply = nDaysAgoSupplyX10d.div(BN(10).pow(vaultTokenDecimals)); + const nDaysAgoSharePrice = nDaysAgoAsset.div(nDaysAgoSupply); + + const apr = todaySharePrice.minus(nDaysAgoSharePrice).div(nDays).times(365); + + const aprInPercentage = apr.times(100); + return utils.aprToApy(aprInPercentage.toNumber()); +} + +async function calculatePool(vault, vaultAssetToken, vaultToken) { + const timestampNow = Math.floor(Date.now() / 1_000); + const timestamp24hsAgo = timestampNow - 86_400; + const timestamp7daysAgo = timestampNow - 86_400 * 7; + const [block7daysAgo, block24hrsAgo, blockNow] = await getBlocksByTime( + [timestamp7daysAgo, timestamp24hsAgo, timestampNow], + 'optimism' + ); + + const tvlInUsd = await getTvlInUsd(vault, vaultAssetToken, blockNow); + const apy1DayPercentage = await getApyInNDaysPercentage( + vault, + vaultAssetToken, + vaultToken, + blockNow, + block24hrsAgo, + 1 + ); + const apy7DaysPercentage = await getApyInNDaysPercentage( + vault, + vaultAssetToken, + vaultToken, + blockNow, + block7daysAgo, + 7 + ); + return { tvlInUsd, apy1DayPercentage, apy7DaysPercentage }; +} + +const poolsFunction = async () => { + const meta = await utils.getData( + 'https://metadata.perp.exchange/kantaban/optimism.json' + ); + const pools = []; + + for (const { + vault, + vaultAsset, + vaultToken, + vaultBaseToken, + vaultQuoteToken, + } of meta.vaults) { + const { tvlInUsd, apy1DayPercentage, apy7DaysPercentage } = + await calculatePool(vault, vaultAsset, vaultToken); + + const symbol = await getSymbol(vaultToken); + pools.push({ + pool: `${vaultToken}-optimism`.toLowerCase(), + chain: 'Optimism', + project: 'perpetual-protocol', + symbol: symbol, + tvlUsd: tvlInUsd, + apyBase: apy1DayPercentage, + apyBase7d: apy7DaysPercentage, + underlyingTokens: [vaultBaseToken, vaultQuoteToken], + url: 'https://vaults.perp.com/', + }); + } + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/persistence-dex/index.js b/src/adaptors/persistence-dex/index.js new file mode 100644 index 0000000000..ed4da63c28 --- /dev/null +++ b/src/adaptors/persistence-dex/index.js @@ -0,0 +1,131 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js').default; + +const utils = require('../utils'); + +const query = gql` + { + atom_price_data: price_data( + limit: 1 + where: { asset_id: { _eq: "cosmos" } } + order_by: { timestamp: desc } + ) { + price_usd + } + stkatom_price_data: price_data( + limit: 1 + where: { asset_id: { _eq: "stkatom" } } + order_by: { timestamp: desc } + ) { + price_usd + } + pools { + poolId + poolContractAddress + poolAssets { + identifier + amount + } + } + token_metadata { + identifier + ticker + } + pool_current_incentive_apr { + pool_id + incentive_apr + reward_asset_id + } + pool_daily_aggregate { + pool_id + total_swap_fee + total_volume + } + pool_weekly_aggregate_with_apr { + pool_id + apr + current_liquidity_usd + total_volume + } + } +`; + +async function apy() { + const data = await request( + 'https://api.dex.persistence.one/v1/graphql', + query + ); + const res = await superagent.get( + 'https://api.persistence.one/pstake/stkatom/apr' + ); + const pstakeApr = Number(res.text) * 100; + let stakingApr = 0; + + const pools = {}; + const tokenSymbolById = data.token_metadata.reduce((acc, token) => { + acc[token.identifier] = token.ticker; + return acc; + }, {}); + + data.pools.forEach((p) => { + const tokenSymbol1 = tokenSymbolById[p.poolAssets[0].identifier]; + const tokenSymbol2 = tokenSymbolById[p.poolAssets[1].identifier]; + pools[p.poolId] = { + pool: `dexter-pool-${p.poolId}-${tokenSymbol1}-${tokenSymbol2}`, + chain: 'Persistence', + project: 'persistence-dex', + symbol: utils.formatSymbol(`${tokenSymbol1}-${tokenSymbol2}`), + url: `https://app.dexter.zone/pools/${p.poolContractAddress}`, + apyReward: 0, + rewardTokens: [], + }; + + if (p.poolId === 1) { + const atomsUsd = new BigNumber(p.poolAssets[0].amount).times( + data.atom_price_data[0].price_usd + ); + const stkAtomsUsd = new BigNumber(p.poolAssets[1].amount).times( + data.stkatom_price_data[0].price_usd + ); + const stkAtomsUsdRatio = stkAtomsUsd.div(atomsUsd.plus(stkAtomsUsd)); + stakingApr = stkAtomsUsdRatio.times(pstakeApr).toNumber(); + } + }); + + data.pool_current_incentive_apr.forEach((p) => { + pools[p.pool_id].apyReward += p.incentive_apr; + if (p.incentive_apr > 0) { + const rewardSymbol = tokenSymbolById[p.reward_asset_id]; + pools[p.pool_id].rewardTokens.push(rewardSymbol); + } + }); + + data.pool_weekly_aggregate_with_apr.forEach((p) => { + pools[p.pool_id].apyBase7d = p.apr; + pools[p.pool_id].volumeUsd7d = p.total_volume; + pools[p.pool_id].tvlUsd = p.current_liquidity_usd; + + if (p.pool_id === 1) { + pools[p.pool_id].apyBase7d += stakingApr; + } + }); + + data.pool_daily_aggregate.forEach((p) => { + const tvlUsd = pools[p.pool_id].tvlUsd; + pools[p.pool_id].apyBase = ((p.total_swap_fee * 365) / tvlUsd) * 100; + pools[p.pool_id].volumeUsd1d = p.total_volume; + + if (p.pool_id === 1) { + pools[p.pool_id].apyBase += stakingApr; + } + }); + + return Object.values(pools); +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.dexter.zone/pools', +}; diff --git a/src/adaptors/pharaoh-v3/index.js b/src/adaptors/pharaoh-v3/index.js new file mode 100644 index 0000000000..34f613c376 --- /dev/null +++ b/src/adaptors/pharaoh-v3/index.js @@ -0,0 +1,150 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const PHAR = '0x13A466998Ce03Db73aBc2d4DF3bBD845Ed1f28E7'; +const PROJECT = 'pharaoh-v3'; +const CHAIN = 'avalanche'; +const SUBGRAPH = 'https://avalanchev2.kingdomsubgraph.com/subgraphs/name/pharaoh-v3-pruned/'; + +const poolsQuery = gql` + query getPools($first: Int!, $skip: Int!) { + clPools( + first: $first + skip: $skip + orderBy: totalValueLockedUSD + orderDirection: desc + where: { gauge_not: null } + ) { + id + token0 { + id + symbol + } + token1 { + id + symbol + } + feeTier + tickSpacing + totalValueLockedUSD + gauge { + id + } + poolDayData(first: 7, orderBy: startOfDay, orderDirection: desc) { + volumeUSD + } + } + } +`; + +async function fetchAllPools() { + let allPools = []; + let skip = 0; + const first = 1000; + + while (true) { + const poolsData = await request(SUBGRAPH, poolsQuery, { first, skip }); + const pools = poolsData.clPools; + + if (pools.length === 0) break; + + allPools = allPools.concat(pools); + + if (pools.length < first) break; + + skip += first; + } + + return allPools; +} + +async function apy() { + try { + const pools = await fetchAllPools(); + + let pharaohPools = []; + try { + const pharaohApiData = await axios.get('https://pharaoh-new-api-production.up.railway.app/all-pools'); + if (pharaohApiData.data && Array.isArray(pharaohApiData.data.pools)) { + pharaohPools = pharaohApiData.data.pools; + } + } catch (error) { + console.error('Failed to fetch Pharaoh API data:', error.message); + } + + const aprMap = {}; + for (const pool of pharaohPools) { + if (pool.id) { + aprMap[pool.id.toLowerCase()] = { + lpApr: Number(pool.lpApr) || 0 + }; + } + } + + const results = []; + + for (const pool of pools) { + const tvlUsd = Number(pool.totalValueLockedUSD) || 0; + + if (!pool.gauge?.id) continue; + + const poolAddress = pool.id.toLowerCase(); + const apiData = aprMap[poolAddress]; + + if (!apiData) continue; + + const apyBase = 0; + let apyReward = 0; + const tickSpacing = parseInt(pool.tickSpacing); + + const apiPool = pharaohPools.find(p => p.id.toLowerCase() === poolAddress); + if (apiPool && apiPool.recommendedRanges) { + if (tickSpacing === 1 || tickSpacing === 5) { + const wideRange = apiPool.recommendedRanges.find(range => range.name === 'Wide'); + apyReward = wideRange ? wideRange.lpApr : apiData.lpApr || 0; + } else { + const narrowRange = apiPool.recommendedRanges.find(range => range.name === 'Narrow'); + apyReward = narrowRange ? narrowRange.lpApr : apiData.lpApr || 0; + } + } else { + apyReward = apiData.lpApr || 0; + } + + results.push({ + pool: `${poolAddress}-${utils.formatChain(CHAIN)}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT, + poolMeta: `CL ${(Number(pool.feeTier) / 10000).toFixed(2)}%`, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd, + apyBase, + apyBase7d: 0, + apyReward, + rewardTokens: apyReward > 0 ? [PHAR] : [], + underlyingTokens: [ + pool.token0.id.toLowerCase(), + pool.token1.id.toLowerCase() + ], + url: `https://www.phar.gg/liquidity/${poolAddress}`, + volumeUsd1d: pool.poolDayData?.[0]?.volumeUSD + ? Number(pool.poolDayData[0].volumeUSD) + : 0, + volumeUsd7d: pool.poolDayData + ? pool.poolDayData.reduce((sum, day) => sum + Number(day.volumeUSD || 0), 0) + : 0, + }); + } + + return results.filter((p) => utils.keepFinite(p)); + + } catch (error) { + console.error('Error fetching Pharaoh CL data:', error); + return []; + } +} + +module.exports = { + timetravel: false, + apy: apy, +}; \ No newline at end of file diff --git a/src/adaptors/phase/abi/Balancer.js b/src/adaptors/phase/abi/Balancer.js new file mode 100644 index 0000000000..787af1ec94 --- /dev/null +++ b/src/adaptors/phase/abi/Balancer.js @@ -0,0 +1,357 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IYield', + name: 'yieldSrc', + type: 'address', + }, + ], + name: 'addYield', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'allYields', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + ], + name: 'assetAPR', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'feeAccount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'fullWithdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + ], + name: 'offsets', + outputs: [ + { + components: [ + { + internalType: 'contract IYield', + name: 'yieldSrc', + type: 'address', + }, + { + internalType: 'uint256', + name: 'apr', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'offset', + type: 'uint256', + }, + { + internalType: 'enum OffsetState', + name: 'state', + type: 'uint8', + }, + ], + internalType: 'struct Offset[]', + name: 'arr', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'totalNegative', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalPositive', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'performanceFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newPerformanceFee', + type: 'uint256', + }, + ], + name: 'setPerformanceFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IYield', + name: 'yieldSrc', + type: 'address', + }, + { + internalType: 'bool', + name: 'state', + type: 'bool', + }, + ], + name: 'setYieldState', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + ], + name: 'totalBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'treasury', + outputs: [ + { + internalType: 'contract ITreasury', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IYield', + name: 'yieldSrc', + type: 'address', + }, + ], + name: 'twaa', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'withdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'asset', + type: 'address', + }, + ], + name: 'yields', + outputs: [ + { + components: [ + { + internalType: 'contract IYield', + name: 'yieldSrc', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'apr', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastDeposit', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'state', + type: 'bool', + }, + ], + internalType: 'struct Yield[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/phase/abi/DB.js b/src/adaptors/phase/abi/DB.js new file mode 100644 index 0000000000..3b8a4d78d9 --- /dev/null +++ b/src/adaptors/phase/abi/DB.js @@ -0,0 +1,462 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'string', + name: 'version', + type: 'string', + }, + ], + name: 'VersionInitialized', + type: 'event', + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: 'keys', + type: 'bytes32[]', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32[]', + name: 'values', + type: 'bytes32[]', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'address[]', + name: 'values', + type: 'address[]', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: 'keys', + type: 'bytes32[]', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'enum OpcodeType', + name: 'opcode', + type: 'uint8', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + internalType: 'struct Opcode', + name: 'opcode', + type: 'tuple', + }, + ], + name: 'digest', + outputs: [ + { + internalType: 'bytes32[]', + name: 'result', + type: 'bytes32[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'string', + name: 'key', + type: 'string', + }, + ], + name: 'getAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getAddressB32', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'getKeys', + outputs: [ + { + internalType: 'bytes32[]', + name: 'arr', + type: 'bytes32[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'string', + name: 'key', + type: 'string', + }, + ], + name: 'getValue', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getValueB32', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getValues', + outputs: [ + { + internalType: 'bytes32[]', + name: 'arr', + type: 'bytes32[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'hasKey', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'hasPair', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'hasValue', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeKey', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'removePair', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'removeValue', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/phase/abi/Vault.js b/src/adaptors/phase/abi/Vault.js new file mode 100644 index 0000000000..c72b9d43f3 --- /dev/null +++ b/src/adaptors/phase/abi/Vault.js @@ -0,0 +1,889 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'extraData', + type: 'bytes', + }, + ], + name: 'addCollateral', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'extraData', + type: 'bytes', + }, + ], + name: 'addCollateral', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'extraData', + type: 'bytes', + }, + ], + name: 'addCollateral', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [ + { + internalType: 'contract IERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'cash', + outputs: [ + { + internalType: 'contract IPegToken', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'collectiveCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'collectiveDebt', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'contextLocked', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'debtShares', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'debtValue', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'depositValue', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getInterest', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + ], + name: 'getRoleAdmin', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'grantRoleAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'grantRoleKey', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'hasRole', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'healthTargetMaximum', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'healthTargetMinimum', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'interest', + outputs: [ + { + internalType: 'contract IInterest', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'isSolvent', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastDebtUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'liquidateUser', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'liquidationFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'liquidationInfo', + outputs: [ + { + components: [ + { + internalType: 'bool', + name: 'solvent', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'borrowChange', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'assetReward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rebate', + type: 'uint256', + }, + ], + internalType: 'struct LiquidationInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'manager', + outputs: [ + { + internalType: 'contract Manager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'marketsLocked', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxCollateralRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxMint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'mintUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes[]', + name: 'data', + type: 'bytes[]', + }, + ], + name: 'multicall', + outputs: [ + { + internalType: 'bytes[]', + name: 'results', + type: 'bytes[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'price', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'priceOracle', + outputs: [ + { + internalType: 'contract IOracle', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'pureDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'extraData', + type: 'bytes', + }, + ], + name: 'removeAllCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'extraData', + type: 'bytes', + }, + ], + name: 'removeCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'repayAllUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'repayAllUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'repayAllUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'repayUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'repayUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'repayUSD', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'revokeRoleAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'revokeRoleKey', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'healthTarget', + type: 'uint256', + }, + ], + name: 'setHealthTarget', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'yieldPercent', + type: 'uint256', + }, + ], + name: 'setYieldPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'systemClock', + outputs: [ + { + internalType: 'contract ISystemClock', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalDebtShares', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'treasury', + outputs: [ + { + internalType: 'contract ITreasury', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'userInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'version', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deposit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'healthTarget', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'yieldPercent', + type: 'uint256', + }, + ], + internalType: 'struct UserInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'varStorage', + outputs: [ + { + internalType: 'contract Storage', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'user', + type: 'uint256', + }, + ], + name: 'yieldDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/phase/config.js b/src/adaptors/phase/config.js new file mode 100644 index 0000000000..2df36d8d05 --- /dev/null +++ b/src/adaptors/phase/config.js @@ -0,0 +1,7 @@ +module.exports = { + base: { + network: 8453, + db: '0xC069B3FAF13ae92Dd058C65a8d8d0EC9f8975CF4', + balancer: '0xFB9Babf572D5e0597F9320a106b6DE6fd394E41F', + }, +}; diff --git a/src/adaptors/phase/index.js b/src/adaptors/phase/index.js new file mode 100644 index 0000000000..3a1d0e7c5f --- /dev/null +++ b/src/adaptors/phase/index.js @@ -0,0 +1,115 @@ +const sdk = require('@defillama/sdk'); +const utils = require('./utils'); +const noAPIUtils = require('../utils'); + +const DBAbi = require('./abi/DB'); +const VaultAbi = require('./abi/Vault'); +const BalancerAbi = require('./abi/Balancer'); + +const config = require('./config'); + +const VAULT_KEY = + '0x68fc488efe30251cadb6ac88bdeef3f1a5e6048808baf387258d1d78e986720c'; + +async function getVaults(chain) { + const { db } = config[chain]; + + const data = await sdk.api.abi.call({ + target: db, + abi: DBAbi.find((m) => m.name === 'getValues'), + chain, + params: [VAULT_KEY], + }); + + const rawAddresses = data.output; + const fixedAddresses = rawAddresses.map((a) => a.substr(0, 42)); + + return fixedAddresses; +} + +const poolsFunction = async () => { + const pools = []; + + for (const chain of Object.keys(config)) { + const { balancer, network } = config[chain]; + + const vaults = await getVaults(chain); + + const collaterals = await utils.makeMulticall({ + abi: VaultAbi.find((m) => m.name === 'collectiveCollateral'), + calls: vaults.map((vault) => ({ target: vault })), + chain, + }); + + const prices = await utils.makeMulticall({ + abi: VaultAbi.find((m) => m.name === 'price'), + calls: vaults.map((vault) => ({ target: vault })), + chain, + }); + + const assets = await utils.makeMulticall({ + abi: VaultAbi.find((m) => m.name === 'asset'), + calls: vaults.map((vault) => ({ target: vault })), + chain, + }); + + const symbols = await utils.makeMulticall({ + abi: 'erc20:symbol', + calls: assets.map((asset) => ({ target: asset })), + chain, + }); + + const decimals = await utils.makeMulticall({ + abi: 'erc20:decimals', + calls: assets.map((asset) => ({ target: asset })), + chain, + }); + + const tvls = collaterals.map((collateral, i) => { + const price = prices[i]; + const decimal = decimals[i]; + + return (collateral / 10 ** decimal) * (price / 10 ** 18); + }); + + const aprs = await utils.makeMulticall({ + abi: BalancerAbi.find((m) => m.name === 'assetAPR'), + calls: assets.map((asset) => ({ target: balancer, params: [asset] })), + chain, + }); + + const apys = aprs + .map(Number) + .map((apr) => apr / 1e18) + .map((apr) => utils.aprToApy(apr)) + .map((apy) => apy * 100); + + for (let i = 0; i < vaults.length; i++) { + const vault = vaults[i]; + const asset = assets[i]; + const symbol = symbols[i]; + const apy = apys[i]; + const tvl = tvls[i]; + + pools.push({ + pool: `${chain}:${vault}`, + chain: noAPIUtils.formatChain(chain), + project: 'phase', + symbol: noAPIUtils.formatSymbol(symbol), + tvlUsd: tvl, + apyBase: apy, + underlyingTokens: [asset], + poolMeta: 'V1 Vault', + url: `https://app.phase.cash/protocol/vault?network=${network}&id=${vault}`, + }); + } + } + + return pools; +}; + +module.exports = { + timetravel: true, + apy: poolsFunction, + url: 'https://app.phase.cash/vaults?p=explore', +}; diff --git a/src/adaptors/phase/utils.js b/src/adaptors/phase/utils.js new file mode 100644 index 0000000000..484d7bedb4 --- /dev/null +++ b/src/adaptors/phase/utils.js @@ -0,0 +1,17 @@ +const sdk = require('@defillama/sdk'); + +module.exports.makeMulticall = async ({ abi, calls, chain }) => { + const data = await sdk.api.abi.multiCall({ + abi, + calls, + chain, + }); + + const res = data.output.map(({ output }) => output); + + return res; +}; + +exports.aprToApy = (apr, compoundFrequency = 365) => { + return (1 + apr / compoundFrequency) ** compoundFrequency - 1; +}; diff --git a/src/adaptors/phuture/abis/SavingsVault.abi.js b/src/adaptors/phuture/abis/SavingsVault.abi.js new file mode 100644 index 0000000000..36468ce7e1 --- /dev/null +++ b/src/adaptors/phuture/abis/SavingsVault.abi.js @@ -0,0 +1,767 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IWrappedfCashComplete', + name: '_fCashPosition', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: '_assetAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: '_fCashAmount', + type: 'uint256', + }, + ], + name: 'FCashMinted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'uint8', name: 'version', type: 'uint8' }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, + ], + name: 'RoleAdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleRevoked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'AUM_SCALED_PER_SECONDS_RATE', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'BP', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'BURNING_FEE_IN_BP', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINTING_FEE_IN_BP', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'SUPPORTED_MATURITIES', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'currencyId', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assets', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assets', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'uint256', name: '_deadline', type: 'uint256' }, + { internalType: 'uint8', name: '_v', type: 'uint8' }, + { internalType: 'bytes32', name: '_r', type: 'bytes32' }, + { internalType: 'bytes32', name: '_s', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getfCashPositions', + outputs: [{ internalType: 'address[2]', name: '', type: 'address[2]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_maxDepositedAmount', type: 'uint256' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '_name', type: 'string' }, + { internalType: 'string', name: '_symbol', type: 'string' }, + { internalType: 'address', name: '_asset', type: 'address' }, + { internalType: 'uint16', name: '_currencyId', type: 'uint16' }, + { + internalType: 'contract IWrappedfCashFactory', + name: '_wrappedfCashFactory', + type: 'address', + }, + { internalType: 'address', name: '_notionalRouter', type: 'address' }, + { internalType: 'uint16', name: '_maxLoss', type: 'uint16' }, + { internalType: 'address', name: '_feeRecipient', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxLoss', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'notionalRouter', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'uint256', name: '_minOutputAmount', type: 'uint256' }, + ], + name: 'redeemWithMinOutputAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_feeRecipient', type: 'address' }, + ], + name: 'setFeeRecipient', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint16', name: '_maxLoss', type: 'uint16' }], + name: 'setMaxLoss', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'settleAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sortMarketsByOracleRate', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'maturity', type: 'uint256' }, + { internalType: 'uint256', name: 'oracleRate', type: 'uint256' }, + ], + internalType: 'struct ISavingsVault.NotionalMarket', + name: 'lowestYieldMarket', + type: 'tuple', + }, + { + components: [ + { internalType: 'uint256', name: 'maturity', type: 'uint256' }, + { internalType: 'uint256', name: 'oracleRate', type: 'uint256' }, + ], + internalType: 'struct ISavingsVault.NotionalMarket', + name: 'highestYieldMarket', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newImplementation', type: 'address' }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newImplementation', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assets', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'wrappedfCashFactory', + outputs: [ + { + internalType: 'contract IWrappedfCashFactory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/phuture/abis/SavingsVaultViews.abi.json b/src/adaptors/phuture/abis/SavingsVaultViews.abi.json new file mode 100644 index 0000000000..80d95ae0ea --- /dev/null +++ b/src/adaptors/phuture/abis/SavingsVaultViews.abi.json @@ -0,0 +1,21 @@ +{ + "getAPY": { + "inputs": [ + { + "internalType": "contract ISavingsVaultViewer", + "name": "_savingsVault", + "type": "address" + } + ], + "name": "getAPY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/phuture/index.ts b/src/adaptors/phuture/index.ts new file mode 100644 index 0000000000..d04f128d83 --- /dev/null +++ b/src/adaptors/phuture/index.ts @@ -0,0 +1,58 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const SavingsVaultViews = require('./abis/SavingsVaultViews.abi.json'); +const SavingsVault = require('./abis/SavingsVault.abi.js'); + +const project = 'phuture'; +const url = 'https://app.phuture.finance'; + +const usvAddress = '0x6bAD6A9BcFdA3fd60Da6834aCe5F93B8cFed9598'; +const usvViewAddress = '0xE574beBdDB460e3E0588F1001D24441102339429'; + +const main = (chain) => async (): Promise> => { + const { output: asset } = await sdk.api.abi.call({ + chain, + abi: SavingsVault.find((m) => m.name === 'asset'), + target: usvAddress, + }); + + const { output: totalAssets } = await sdk.api.abi.call({ + chain, + abi: SavingsVault.find((m) => m.name === 'totalSupply'), + target: usvAddress, + }); + + const { output: apy } = await sdk.api.abi.call({ + chain, + abi: SavingsVaultViews.getAPY, + params: [usvAddress], + target: usvViewAddress, + }); + + const usdcPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/ethereum:${asset}`) + ).data.coins; + + return [ + { + pool: `${usvAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project, + symbol: 'USDC', + tvlUsd: (+totalAssets / 1e18) * usdcPrice[`ethereum:${asset}`].price, + apyBase: apy / 10e6, + rewardTokens: [asset], + underlyingTokens: [asset], + url: url + '/index/' + usvAddress.toLowerCase(), + poolMeta: 'USV', + }, + ]; +}; + +module.exports = { + timetravel: true, + apy: main('ethereum'), + url, +}; diff --git a/src/adaptors/pickle/index.js b/src/adaptors/pickle/index.js index 52f32e7de6..632f1edce6 100644 --- a/src/adaptors/pickle/index.js +++ b/src/adaptors/pickle/index.js @@ -1,49 +1,61 @@ -const axios = require("axios"); +const axios = require('axios'); const utils = require('../utils'); -const pfcore = "https://api.pickle.finance/prod/protocol/pfcore/"; +// const pfcore = 'https://api.pickle.finance/prod/protocol/pfcore/'; +const pfcore = + 'https://f8wgg18t1h.execute-api.us-west-1.amazonaws.com/prod/protocol/pfcore'; async function apy() { - const response = (await axios.get(pfcore))?.data.assets; - const strategies = Object.values(response).flat(1); - const current = strategies.filter( - s => s.enablement == 'enabled' - && s.details.harvestStats != undefined - && (s.aprStats || - s.farm?.details.farmApyComponents || - s.details.farmApyComponents) - ); + const response = (await axios.get(pfcore))?.data.assets; + const strategies = Object.values(response).flat(1); + const current = strategies.filter( + (s) => + s.enablement == 'enabled' && + s.details.harvestStats != undefined && + (s.aprStats || + s.farm?.details.farmApyComponents || + s.details.farmApyComponents) + ); - return current.map(s => ({ - pool: `${s.contract}-${s.id.toLowerCase().replace(/ /g,'')}`, - chain: utils.formatChain(s.chain == 'eth' ? 'ethereum' : s.chain), - project: 'pickle', - symbol: utils.formatSymbol( - s.depositToken.components ? s.depositToken.components.join('-').toUpperCase() : s.depositToken.name - ), - tvlUsd: s.details.harvestStats.balanceUSD ?? 0, - apy: aggregateApys(s) - })); -}; + return current.map((s) => ({ + pool: `${s.contract}-${s.id.toLowerCase().replace(/ /g, '')}`, + chain: utils.formatChain(s.chain == 'eth' ? 'ethereum' : s.chain), + project: 'pickle', + symbol: utils.formatSymbol( + s.depositToken.components + ? s.depositToken.components.join('-').toUpperCase() + : s.depositToken.name + ), + tvlUsd: s.details.harvestStats.balanceUSD ?? 0, + apy: aggregateApys(s), + })); +} function aggregateApys(strategy) { - let apy = 0; - if (strategy.hasOwnProperty('aprStats') - && strategy.aprStats.apy != undefined) { - apy += strategy.aprStats.apy; - }; - if (strategy.hasOwnProperty('farm') - && strategy.farm.details.farmApyComponents != undefined) { - apy += strategy.farm.details.farmApyComponents - .reduce((a, b) => Number(a) + Number(b.apr), 0) - }; - if (strategy.details.hasOwnProperty('farmApyComponents')) - apy += strategy.details.farmApyComponents.reduce((a, b) => a + b.apr, 0); - return apy; -}; + let apy = 0; + if ( + strategy.hasOwnProperty('aprStats') && + strategy.aprStats.apy != undefined + ) { + apy += strategy.aprStats.apy; + } + if ( + strategy.hasOwnProperty('farm') && + strategy.farm.details.farmApyComponents != undefined + ) { + apy += strategy.farm.details.farmApyComponents.reduce( + (a, b) => Number(a) + Number(b.apr), + 0 + ); + } + if (strategy.details.hasOwnProperty('farmApyComponents')) + apy += strategy.details.farmApyComponents.reduce((a, b) => a + b.apr, 0); + return apy; +} const main = async () => { - const data = await apy(); - return data; + const data = await apy(); + return data; }; module.exports = { - timetravel: false, - apy: main, + timetravel: false, + apy: main, + url: 'https://app.pickle.finance/farms', }; diff --git a/src/adaptors/pinjam-labs/abiLendingPool.js b/src/adaptors/pinjam-labs/abiLendingPool.js new file mode 100644 index 0000000000..0b1530fb78 --- /dev/null +++ b/src/adaptors/pinjam-labs/abiLendingPool.js @@ -0,0 +1,572 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getAmountWorked', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getBorrowRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getDebtToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getDepositToVaultStatus', + outputs: [ + { + internalType: 'bool', + name: 'status_', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getFlags', + outputs: [ + { + internalType: 'bool', + name: 'assetAsCollateral', + type: 'bool', + }, + { + internalType: 'bool', + name: 'depositEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowEnabled', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getInterestConfig', + outputs: [ + { + internalType: 'uint256', + name: 'variableSlope1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableSlope2', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'optimalUtilizationRate', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getLiquidationConfig', + outputs: [ + { + internalType: 'uint256', + name: 'loanToValue', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationBonus', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getMaxCapitalEfficiency', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getNormalizedBorrowIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getNormalizedSupplyIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getPToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'getPendingVaultRewards', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getPoolRewardsData', + outputs: [ + { + internalType: 'uint256', + name: 'accRewardPerShare_', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardsClaimed_', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accRewards_', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getReserveFactors', + outputs: [ + { + internalType: 'uint256', + name: 'borrowFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'farmingFactor', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getReserveFees', + outputs: [ + { + internalType: 'uint256', + name: 'vaultDepositFees', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getReserveId', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getSupplyAndDebtLimit', + outputs: [ + { + internalType: 'uint256', + name: 'supplyLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtLimit', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getSupplyRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256', + }, + ], + name: 'getSupportedAsset', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getTotalDebt', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getTotalLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + ], + name: 'getTotalVaultRewards', + outputs: [ + { + internalType: 'uint256', + name: 'totalRewards', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vaultDepositRewards', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'getUserData', + outputs: [ + { + internalType: 'uint256', + name: 'healthFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCollateralInBaseCurrency', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalDebtInBaseCurrency', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'avgLtv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'avgLiquiditationThreshold', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'getUserIsUsingAsCollateral', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_underlyingAsset', + type: 'address', + }, + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'getUserRewardsData', + outputs: [ + { + internalType: 'uint256', + name: 'rewardDebt_', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardsOwed_', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/pinjam-labs/index.js b/src/adaptors/pinjam-labs/index.js new file mode 100644 index 0000000000..cc28a86f6b --- /dev/null +++ b/src/adaptors/pinjam-labs/index.js @@ -0,0 +1,182 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const abiLendingPool = require('./abiLendingPool'); + +const chains = { + kava: { + LendingPool: '0x11C3D91259b1c2Bd804344355C6A255001F7Ba1e', + url: 'kava', + reservesList: [ + { + underlying: '0xc86c7c0efbd6a49b35e8714c5f59d99de09a225b', + pToken: '0xb096768a0E4f5d08927C19Df9651293485b21072', + vdToken: '0x13aB1A2e26f0F1022F2286960055847100Bd7218', + symbol: 'kava', + decimals: 18, + }, + { + underlying: '0x15932e26f5bd4923d46a2b205191c4b5d5f43fe3', + pToken: '0xa360C5B959499503e67B93EbD22Fc9879554b3b5', + vdToken: '0x57906bc7E616526937c54aBeEfac26a0B52C51F3', + symbol: 'atom', + decimals: 6, + }, + { + underlying: '0xeb466342c4d449bc9f53a865d5cb90586f405215', + pToken: '0x5C91F5d2b7046A138c7D1775BfFEa68d5e95D68d', + vdToken: '0xbB9D890D6511598ccC717D2C6C1266007dAa1D78', + symbol: 'axlUsdc', + decimals: 6, + }, + { + underlying: '0x5c7e299cf531eb66f2a1df637d37abb78e6200c7', + pToken: '0x08CcC9665c40004d764E7Ed8F3c345FdE5Ff24d0', + vdToken: '0x65bE004724622CD5FD54FDa4D6d71aaD9DfF9d7b', + symbol: 'axlDai', + decimals: 18, + }, + { + underlying: '0x7f5373ae26c3e8ffc4c77b7255df7ec1a9af52a6', + pToken: '0x0fc0e71DC8616D6664085aB98F7D29F71576b590', + vdToken: '0x9af9b432Df911c5d1293B63bcFED6a6E6b0B4dF2', + symbol: 'axlUsdt', + decimals: 6, + }, + { + underlying: '0x919c1c267bc06a7039e03fcc2ef738525769109c', + pToken: '0xc662B16F391ade279956283F14835164f1d367fE', + vdToken: '0xB36239deC6cc681C0c7a49241fA6d20c7c263229', + symbol: 'usdt', + decimals: 6, + }, + ], + }, +}; + +const getApy = async () => { + const pools = await Promise.all( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + const sdkChain = chain === 'avalanche' ? 'avax' : chain; + + const [liquidityRes] = await Promise.all( + ['erc20:totalSupply'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: addresses.reservesList.map((t, i) => ({ + target: t.pToken, + params: null, + })), + chain: sdkChain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + + const pricesArray = addresses.reservesList.map( + (t) => `${sdkChain}:${t.underlying}` + ); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: addresses.reservesList.map((p) => ({ + target: p.vdToken, + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const supplyRate = ( + await sdk.api.abi.multiCall({ + abi: abiLendingPool.find((m) => m.name === 'getSupplyRate'), + calls: addresses.reservesList.map((p) => ({ + target: addresses.LendingPool, + params: [p.underlying], + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const borrowRate = ( + await sdk.api.abi.multiCall({ + abi: abiLendingPool.find((m) => m.name === 'getBorrowRate'), + calls: addresses.reservesList.map((p) => ({ + target: addresses.LendingPool, + params: [p.underlying], + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const poolConfig = ( + await sdk.api.abi.multiCall({ + abi: abiLendingPool.find((m) => m.name === 'getFlags'), + calls: addresses.reservesList.map((p) => ({ + target: addresses.LendingPool, + params: [p.underlying], + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + const poolLiquidationConfig = ( + await sdk.api.abi.multiCall({ + abi: abiLendingPool.find((m) => m.name === 'getLiquidationConfig'), + calls: addresses.reservesList.map((p) => ({ + target: addresses.LendingPool, + params: [p.underlying], + })), + chain: sdkChain, + }) + ).output.map((o) => o.output); + + return addresses.reservesList.map((t, i) => { + const price = prices[`${sdkChain}:${t.underlying}`]?.price; + const apyBase = supplyRate[i] / 1e25; + const apyBaseBorrow = borrowRate[i] / 1e25; + + const totalSupplyUsd = (liquidity[i] / 10 ** t.decimals) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** t.decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const url = `https://app.pinjamlabs.com/reserve-overview?underlyingAddress=${t.underlying.toLowerCase()}`; + const borrowable = poolConfig[i].borrowEnabled; + const depositPaused = !poolConfig[i].depositEnabled; + const liqConfig = poolLiquidationConfig[i]; + + const ltv = liqConfig.loanToValue / 1e4; + return { + pool: `${t.pToken}-${chain}`.toLowerCase(), + symbol: t.symbol, + project: 'pinjam-labs', + chain, + tvlUsd, + apyBase, + underlyingTokens: [t.underlying], + url, + + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: depositPaused ? 'frozen' : null, + }; + }); + }) + ); + + return pools.flat(); +}; + +module.exports = { + timetravel: true, + apy: getApy, + url: 'https://app.pinjamlabs.com', +}; diff --git a/src/adaptors/pinto/index.js b/src/adaptors/pinto/index.js new file mode 100644 index 0000000000..91a4b9e8e9 --- /dev/null +++ b/src/adaptors/pinto/index.js @@ -0,0 +1,233 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); +const axios = require('axios'); + +const START_TIME = 1732071601; // First silo yield distribution at Season 4. +const API = 'https://api.pinto.money/silo/yield'; +const SUBGRAPH = 'https://graph.pinto.money/pinto/'; + +const PINTO = '0xb170000aeefa790fa61d6e837d1035906839a3c8'; +const PINTO_DIAMOND = '0xd1a0d188e861ed9d15773a2f3574a2e94134ba8f'; +const PRICE_CONTRACT = '0xD0fd333F7B30c7925DEBD81B7b7a4DFE106c3a5E'; + +const PRICE_ABI = { + inputs: [], + name: 'price', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'deltaB', + type: 'int256', + }, + { + components: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address[2]', + name: 'tokens', + type: 'address[2]', + }, + { + internalType: 'uint256[2]', + name: 'balances', + type: 'uint256[2]', + }, + { + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'beanLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'nonBeanLiquidity', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'deltaB', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'lpUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lpBdv', + type: 'uint256', + }, + ], + internalType: 'struct P.Pool[]', + name: 'ps', + type: 'tuple[]', + }, + ], + internalType: 'struct BeanstalkPrice.Prices', + name: 'p', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +// Returns total deposited + germinating token amounts of the requested token +async function getSiloDeposited(token) { + const deposited = await sdk.api.abi.call({ + abi: 'function getTotalDeposited(address) external view returns (uint256)', + target: PINTO_DIAMOND, + params: token, + chain: 'base', + }); + const germinating = await sdk.api.abi.call({ + abi: 'function getGerminatingTotalDeposited(address) external view returns (uint256)', + target: PINTO_DIAMOND, + params: token, + chain: 'base', + }); + return BigInt(deposited.output) + BigInt(germinating.output); +} + +// Returns the deposited TVL of the requested token. +async function getDepositedTVL(token) { + // Only PINTO is supported for onchain TVL + if ((token || '').toLowerCase() !== PINTO.toLowerCase()) { + return null; + } + + const depositedTokens = await getSiloDeposited(token); + const priceResult = await sdk.api.abi.call({ + abi: PRICE_ABI, + target: PRICE_CONTRACT, + chain: 'base', + }); + const price = BigInt(priceResult.output[0]); + + // Tokens and price each have 6 decimals + return Number(depositedTokens * price) / 10 ** 12; +} + +async function getPools(timestamp = null) { + const pools = await getPoolsForChain('base', timestamp); + return pools.flat(); +} + +async function getPoolsForChain(chain, timestamp) { + if (timestamp && timestamp < START_TIME) { + return []; + } + + const resultPools = []; + + // When a timestamp is specified, determine which block to use + let block; + if (timestamp) { + [block] = await utils.getBlocksByTime([timestamp], chain); + } + + // Query subgraph to identify each yield-bearing pool and its info + const poolData = await request( + SUBGRAPH, + gql` + { + beans${block ? `(block: {number: ${block}})` : ''} { + id + currentSeason { + season + } + pools { + id + liquidityUSD + tokens { + id + name + } + } + } + }` + ); + + for (const bean of poolData.beans) { + // Get apy info + const apy = await axios.post(API, { + season: bean.currentSeason.season, + emaWindows: [720], + options: { + initType: 'NEW', + }, + }); + // Uses the available window if fewer datapoints were available + const yields = apy.data.yields[Object.keys(apy.data.yields)[0]]; + const pools = bean.pools.filter((p) => yields[p.id]); + + // Add results for each silo asset + for (const token in yields) { + let tokens; + let tvlUsd; + const pool = pools.find((p) => p.id === token); + if (pool) { + // Sort PINTO to be first in the token list + tokens = + pool.tokens[0].name === 'PINTO' + ? pool.tokens + : [pool.tokens[1], pool.tokens[0]]; + tvlUsd = parseInt(pool.liquidityUSD); + } else { + // Non-pool token: only PINTO is supported; skip others + tvlUsd = await getDepositedTVL(token); + if (tvlUsd === null) { + // Unsupported token, skip adding this pool + continue; + } + tokens = [{ id: token, name: 'PINTO' }]; + } + + resultPools.push({ + pool: `${token}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'pinto', + symbol: `${tokens.map((t) => t.name).join('-')}`, + tvlUsd, + apyReward: Math.round(yields[token].bean * 10000) / 100, + rewardTokens: [bean.id], + underlyingTokens: tokens.map((t) => t.id.toLowerCase()), + poolMeta: 'Pinto Silo', + }); + } + } + return resultPools; +} + +module.exports = { + timetravel: true, + apy: getPools, + url: 'https://pinto.money/', +}; diff --git a/src/adaptors/platypus-finance/abiBoostedMultiRewarder.js b/src/adaptors/platypus-finance/abiBoostedMultiRewarder.js new file mode 100644 index 0000000000..4144bcafab --- /dev/null +++ b/src/adaptors/platypus-finance/abiBoostedMultiRewarder.js @@ -0,0 +1,313 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IMasterPlatypusV4', + name: '_MP', + type: 'address', + }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'uint40', name: '_startTimestamp', type: 'uint40' }, + { internalType: 'uint16', name: '_dilutingRepartition', type: 'uint16' }, + { + internalType: 'contract IERC20', + name: '_rewardToken', + type: 'address', + }, + { internalType: 'uint96', name: '_tokenPerSec', type: 'uint96' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'OnReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRate', + type: 'uint256', + }, + ], + name: 'RewardRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'dilutingRepartition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nonDilutingRepartition', + type: 'uint256', + }, + ], + name: 'UpdateEmissionRepartition', + type: 'event', + }, + { + inputs: [], + name: 'MP', + outputs: [ + { internalType: 'contract IMasterPlatypusV4', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: '_rewardToken', + type: 'address', + }, + { internalType: 'uint96', name: '_tokenPerSec', type: 'uint96' }, + ], + name: 'addRewardToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'balances', + outputs: [ + { internalType: 'uint256[]', name: 'balances_', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'dilutingRepartition', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'emergencyTokenWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastRewardTimestamp', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_lpAmount', type: 'uint256' }, + { internalType: 'uint256', name: '_newLpAmount', type: 'uint256' }, + { internalType: 'uint256', name: '_factor', type: 'uint256' }, + { internalType: 'uint256', name: '_newFactor', type: 'uint256' }, + ], + name: 'onPtpReward', + outputs: [ + { internalType: 'uint256[]', name: 'rewards', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_lpAmount', type: 'uint256' }, + { internalType: 'uint256', name: '_factor', type: 'uint256' }, + { internalType: 'uint256', name: '_newFactor', type: 'uint256' }, + ], + name: 'onUpdateFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'operator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_lpAmount', type: 'uint256' }, + { internalType: 'uint256', name: '_factor', type: 'uint256' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'uint256[]', name: 'rewards', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'rewardToken', type: 'address' }, + { internalType: 'uint96', name: 'tokenPerSec', type: 'uint96' }, + { internalType: 'uint128', name: 'accTokenPerShare', type: 'uint128' }, + { + internalType: 'uint128', + name: 'accTokenPerFactorShare', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardTokens', + outputs: [ + { internalType: 'contract IERC20[]', name: 'tokens', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_operator', type: 'address' }], + name: 'setOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_tokenId', type: 'uint256' }, + { internalType: 'uint96', name: '_tokenPerSec', type: 'uint96' }, + ], + name: 'setRewardRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: '_dilutingRepartition', type: 'uint16' }, + ], + name: 'updateEmissionRepartition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint128', name: 'rewardDebt', type: 'uint128' }, + { internalType: 'uint128', name: 'claimable', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, +]; diff --git a/src/adaptors/platypus-finance/abiLP.js b/src/adaptors/platypus-finance/abiLP.js new file mode 100644 index 0000000000..908a05c8bb --- /dev/null +++ b/src/adaptors/platypus-finance/abiLP.js @@ -0,0 +1,448 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'previousCashPosition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'cashBeingAdded', + type: 'uint256', + }, + ], + name: 'CashAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'previousCashPosition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'cashBeingRemoved', + type: 'uint256', + }, + ], + name: 'CashRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'previousLiabilityPosition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liabilityBeingAdded', + type: 'uint256', + }, + ], + name: 'LiabilityAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'previousLiabilityPosition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liabilityBeingRemoved', + type: 'uint256', + }, + ], + name: 'LiabilityRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'previousMaxSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMaxSupply', + type: 'uint256', + }, + ], + name: 'MaxSupplyUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousPool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newPool', + type: 'address', + }, + ], + name: 'PoolUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: '_name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: '_symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'addCash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'addLiability', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'aggregateAccount', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'cash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlyingToken_', type: 'address' }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'address', name: 'aggregateAccount_', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'liability', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pool', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'removeCash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'removeLiability', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'aggregateAccount_', type: 'address' }, + ], + name: 'setAggregateAccount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'maxSupply_', type: 'uint256' }], + name: 'setMaxSupply', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'pool_', type: 'address' }], + name: 'setPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferUnderlyingToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'underlyingToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'underlyingTokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/platypus-finance/abiMasterPlatypusV4.js b/src/adaptors/platypus-finance/abiMasterPlatypusV4.js new file mode 100644 index 0000000000..3a069a2659 --- /dev/null +++ b/src/adaptors/platypus-finance/abiMasterPlatypusV4.js @@ -0,0 +1,650 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: true, + internalType: 'contract IAsset', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IBoostedMultiRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'Add', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'DepositFor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: true, + internalType: 'contract IBoostedMultiRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'SetRewarder', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'dilutingRepartition', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nonDilutingRepartition', + type: 'uint256', + }, + ], + name: 'UpdateEmissionRepartition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'address', + name: 'oldVePTP', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newVePTP', + type: 'address', + }, + ], + name: 'UpdateVePTP', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IAsset', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IBoostedMultiRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [ + { internalType: 'uint256', name: 'reward', type: 'uint256' }, + { + internalType: 'uint256[]', + name: 'additionalRewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'depositFor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'dilutingRepartition', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emergencyPtpWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_lp', type: 'address' }], + name: 'getPoolId', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'getSumOfFactors', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'getUserInfo', + outputs: [ + { + components: [ + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + { internalType: 'uint128', name: 'factor', type: 'uint128' }, + { internalType: 'uint128', name: 'rewardDebt', type: 'uint128' }, + { internalType: 'uint128', name: 'claimablePtp', type: 'uint128' }, + ], + internalType: 'struct IMasterPlatypusV4.UserInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_ptp', type: 'address' }, + { internalType: 'contract IVePtp', name: '_vePtp', type: 'address' }, + { internalType: 'address', name: '_voter', type: 'address' }, + { internalType: 'uint16', name: '_dilutingRepartition', type: 'uint16' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'liquidate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'maxPoolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: '_pids', type: 'uint256[]' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: '_pids', type: 'uint256[]' }], + name: 'multiClaim', + outputs: [ + { internalType: 'uint256', name: 'reward', type: 'uint256' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { + internalType: 'uint256[][]', + name: 'additionalRewards', + type: 'uint256[][]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'newMasterPlatypus', + outputs: [ + { internalType: 'contract IMasterPlatypusV4', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nonDilutingRepartition', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_lpToken', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'notifyRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ownerCandidate', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'uint256', name: 'pendingPtp', type: 'uint256' }, + { + internalType: 'contract IERC20[]', + name: 'bonusTokenAddresses', + type: 'address[]', + }, + { internalType: 'string[]', name: 'bonusTokenSymbols', type: 'string[]' }, + { + internalType: 'uint256[]', + name: 'pendingBonusTokens', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'platypusTreasure', + outputs: [ + { internalType: 'contract IPlatypusTreasure', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IAsset', name: 'lpToken', type: 'address' }, + { + internalType: 'contract IBoostedMultiRewarder', + name: 'rewarder', + type: 'address', + }, + { internalType: 'uint128', name: 'sumOfFactors', type: 'uint128' }, + { internalType: 'uint128', name: 'accPtpPerShare', type: 'uint128' }, + { + internalType: 'uint128', + name: 'accPtpPerFactorShare', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'proposeOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'ptp', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'rewarderBonusTokenInfo', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'bonusTokenAddresses', + type: 'address[]', + }, + { internalType: 'string[]', name: 'bonusTokenSymbols', type: 'string[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_maxPoolLength', type: 'uint256' }, + ], + name: 'setMaxPoolLength', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMasterPlatypusV4', + name: '_newMasterPlatypus', + type: 'address', + }, + ], + name: 'setNewMasterPlatypus', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_platypusTreasure', type: 'address' }, + ], + name: 'setPlatypusTreasure', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { + internalType: 'contract IBoostedMultiRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'setRewarder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IVePtp', name: '_newVePtp', type: 'address' }, + ], + name: 'setVePtp', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: '_dilutingRepartition', type: 'uint16' }, + ], + name: 'updateEmissionRepartition', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_newVePtpBalance', type: 'uint256' }, + ], + name: 'updateFactor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + { internalType: 'uint128', name: 'factor', type: 'uint128' }, + { internalType: 'uint128', name: 'rewardDebt', type: 'uint128' }, + { internalType: 'uint128', name: 'claimablePtp', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vePtp', + outputs: [{ internalType: 'contract IVePtp', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'voter', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [ + { internalType: 'uint256', name: 'reward', type: 'uint256' }, + { + internalType: 'uint256[]', + name: 'additionalRewards', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/platypus-finance/abiVoter.js b/src/adaptors/platypus-finance/abiVoter.js new file mode 100644 index 0000000000..df6471515b --- /dev/null +++ b/src/adaptors/platypus-finance/abiVoter.js @@ -0,0 +1,373 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'DistributeReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'UpdateVote', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_gauge', type: 'address' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'address', name: '_bribe', type: 'address' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + name: 'bribes', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: '_lpTokens', + type: 'address[]', + }, + ], + name: 'claimBribes', + outputs: [ + { internalType: 'uint256[]', name: 'bribeRewards', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + ], + name: 'distribute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyPtpWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + ], + name: 'getUserVotes', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'index', + outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_ptp', type: 'address' }, + { internalType: 'contract IVe', name: '_vePtp', type: 'address' }, + { internalType: 'uint88', name: '_ptpPerSec', type: 'uint88' }, + { internalType: 'uint256', name: '_startTimestamp', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastRewardTimestamp', + outputs: [{ internalType: 'uint40', name: '', type: 'uint40' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lpTokenLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpTokens', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ownerCandidate', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + ], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: '_lpTokens', + type: 'address[]', + }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingBribes', + outputs: [ + { internalType: 'uint256[]', name: 'bribeRewards', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + ], + name: 'pendingPtp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'proposeOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'ptp', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ptpPerSec', + outputs: [{ internalType: 'uint88', name: '', type: 'uint88' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + ], + name: 'resume', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'resumeAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'address', name: '_bribe', type: 'address' }, + ], + name: 'setBribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'address', name: '_gauge', type: 'address' }, + ], + name: 'setGauge', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint88', name: '_ptpPerSec', type: 'uint88' }], + name: 'setPtpPerSec', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalWeight', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vePtp', + outputs: [{ internalType: 'contract IVe', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20[]', name: '_lpVote', type: 'address[]' }, + { internalType: 'int256[]', name: '_deltas', type: 'int256[]' }, + ], + name: 'vote', + outputs: [ + { internalType: 'uint256[]', name: 'bribeRewards', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'contract IERC20', name: '', type: 'address' }, + ], + name: 'votes', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + name: 'weights', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/platypus-finance/index.js b/src/adaptors/platypus-finance/index.js new file mode 100644 index 0000000000..764b9d0d08 --- /dev/null +++ b/src/adaptors/platypus-finance/index.js @@ -0,0 +1,227 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { gql, request } = require('graphql-request'); + +const abiVoter = require('./abiVoter'); +const abiMasterPlatypusV4 = require('./abiMasterPlatypusV4'); +const abiLP = require('./abiLP'); +const abiBoostedMultiRewarder = require('./abiBoostedMultiRewarder'); + +const Voter = '0x1f6B6b505D199B9bd0a6642B8d44533a811598da'; +const MasterPlatypusV4 = '0xfF6934aAC9C94E1C39358D4fDCF70aeca77D0AB0'; +const PTP = '0x22d4002028f537599be9f666d1c4fa138522f9c8'; + +// only used to get poolMeta names +const POOLS_URL = sdk.graph.modifyEndpoint( + 'B916PBxF7iMxK9PVyDQwGi66aZvUQTWQS8vsKAF9jQQc' +); + +const poolsQuery = gql` + query MyQuery { + assets { + id + pool { + name + id + } + } + } +`; + +const apy = async () => { + const poolLength = ( + await sdk.api.abi.call({ + target: MasterPlatypusV4, + abi: abiMasterPlatypusV4.find((m) => m.name === 'poolLength'), + chain: 'avax', + }) + ).output; + + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: MasterPlatypusV4, + params: [i], + })), + abi: abiMasterPlatypusV4.find((m) => m.name === 'poolInfo'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const lpTokens = poolInfo.map((p) => p.lpToken); + + const ptpPerSec = ( + await sdk.api.abi.call({ + target: Voter, + abi: abiVoter.find((m) => m.name === 'ptpPerSec'), + chain: 'avax', + permitFailure: true, + }) + ).output; + + const totalWeight = ( + await sdk.api.abi.call({ + target: Voter, + abi: abiVoter.find((m) => m.name === 'totalWeight'), + chain: 'avax', + permitFailure: true, + }) + ).output; + + const weights = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((lpToken) => ({ target: Voter, params: [lpToken] })), + abi: abiVoter.find((m) => m.name === 'weights'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const dilutingRepartition = ( + await sdk.api.abi.call({ + target: MasterPlatypusV4, + abi: abiMasterPlatypusV4.find((m) => m.name === 'dilutingRepartition'), + chain: 'avax', + permitFailure: true, + }) + ).output; + + const underlyingTokens = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((lpToken) => ({ target: lpToken })), + abi: abiLP.find((m) => m.name === 'underlyingToken'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: underlyingTokens.map((underlying) => ({ + target: underlying, + })), + abi: 'erc20:symbol', + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((lp) => ({ + target: lp, + })), + abi: abiLP.find((m) => m.name === 'totalSupply'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const decimals = ( + await sdk.api.abi.multiCall({ + calls: lpTokens.map((lp) => ({ + target: lp, + })), + abi: abiLP.find((m) => m.name === 'decimals'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewarderPoolInfo = ( + await sdk.api.abi.multiCall({ + calls: poolInfo.map((p) => ({ + target: p.rewarder, + params: [0], + })), + abi: abiBoostedMultiRewarder.find((m) => m.name === 'poolInfo'), + chain: 'avax', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const priceKeys = underlyingTokens + .concat(PTP) + .concat( + rewarderPoolInfo.filter((r) => r !== null).map((r) => r.rewardToken) + ) + .map((u) => `avax:${u}`) + .join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + // for pool names (eg Main Pool, BTC pool etc) + const { assets } = await request(POOLS_URL, poolsQuery); + + // dilutingRepartition is what goes to base APR, the rest to those who boost + const rewardBasePartition = dilutingRepartition / 1e3; + + const ptpPerYearUsd = + (ptpPerSec / 1e18) * + 86400 * + 365 * + rewardBasePartition * + prices[`avax:${PTP}`].price; + + return lpTokens + .map((t, i) => { + const tvlUsd = + (totalSupply[i] / 10 ** decimals[i]) * + prices[`avax:${underlyingTokens[i]}`]?.price; + const apyRewardPTP = + ((ptpPerYearUsd * weights[i]) / totalWeight / tvlUsd) * 100; + + const rewardTokens = apyRewardPTP > 0 ? [PTP] : []; + + // any other pool rewards eg avax, benqi etc. + let apyRewardExtra = 0; + if (rewarderPoolInfo[i] !== null) { + const extraRewardToken = rewarderPoolInfo[i].rewardToken; + const tokenPerSec = rewarderPoolInfo[i].tokenPerSec; + const priceData = prices[`avax:${extraRewardToken}`]; + const extraPerYearUsd = + (tokenPerSec / 1e18) * + 86400 * + 365 * + rewardBasePartition * + priceData?.price; + apyRewardExtra = (extraPerYearUsd / tvlUsd) * 100; + if (apyRewardExtra > 0) rewardTokens.push(extraRewardToken); + } + + const poolName = assets.find( + (a) => a.id.toLowerCase() === t.toLowerCase() + ); + if (poolName === undefined) return null; + + return { + pool: `${poolName.pool.id}-${underlyingTokens[i]}`.toLowerCase(), + symbol: symbols[i], + chain: 'avalanche', + project: 'platypus-finance', + tvlUsd, + apyReward: apyRewardPTP + apyRewardExtra, + underlyingTokens: [underlyingTokens[i]], + rewardTokens, + poolMeta: poolName?.pool?.name, + }; + }) + .filter( + (p) => + p !== null && + p.tvlUsd > 0 && + p.poolMeta !== 'UST Pool' && + p.pool !== + '0x66357dcace80431aee0a7507e2e361b7e2402370-0x130966628846bfd36ff31a822705796e8cb8c18d' && // MIM in main pool not available + p.apyReward >= 0 + ); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.platypus.finance/pool', +}; diff --git a/src/adaptors/plenty/index.js b/src/adaptors/plenty/index.js new file mode 100644 index 0000000000..d4cda37541 --- /dev/null +++ b/src/adaptors/plenty/index.js @@ -0,0 +1,47 @@ +const { fetchURL } = require('../../helper/utils'); + +const convertToMap = (arr, key) => { + const res = {}; + for (const item of arr) { + res[`${item[`${key}`]}`] = item; + } + return res; +}; + +const apy = async () => { + const aprData = convertToMap( + (await fetchURL('https://ply-indexer.mainnet.plenty.network/v1/pools')) + .data, + 'pool' + ); + const analyticsData = convertToMap( + (await fetchURL('https://api.analytics.plenty.network/analytics/pools')) + .data, + 'pool' + ); + + const pools = []; + Object.keys(aprData).forEach((pool) => { + pools.push({ + pool: `${pool}-tezos`, + chain: 'Tezos', + project: 'plenty', + symbol: analyticsData[pool].symbol.replace('/', '-'), + tvlUsd: parseFloat(analyticsData[pool].tvl.value), + apyReward: parseFloat(aprData[pool].apr), // no compounding available + rewardTokens: ['KT1JVjgXPMMSaa6FkzeJcgb8q9cUaLmwaJUX'], + poolMeta: + analyticsData[pool].type === 'STABLE' + ? 'Delta neutral yield' + : undefined, + }); + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.plenty.network/pools', +}; diff --git a/src/adaptors/ploutos-money/index.js b/src/adaptors/ploutos-money/index.js new file mode 100644 index 0000000000..902ef51549 --- /dev/null +++ b/src/adaptors/ploutos-money/index.js @@ -0,0 +1,315 @@ +// Ploutos Money Market (Aave v3 fork) — yield adapter with Merkl integration (dedup by opportunity id, SES-safe) +// project: 'ploutos-money' + +const axios = require('axios') +const sdk = require('@defillama/sdk') +const utils = require('../utils') +const poolAbi = require('./poolAbi') + +// ---------- chain maps ---------- +const protocolDataProviders = { + base: '0x7dcb86dC49543E14A98F80597696fe5f444f58bC', + arbitrum:'0x0F65a7fBCb69074cF8BE8De1E01Ef573da34bD59', + polygon: '0x6A9b632010226F9bBbf2B6cb8B6990bE3F90cb0e', + katana: '0x4DC446e349bDA9516033E11D63f1851d6B5Fd492', + plasma: '0x9C48A6D3e859ab124A8873D73b2678354D0B4c0A', + hemi: '0x0F65a7fBCb69074cF8BE8De1E01Ef573da34bD59', +} + +const CHAIN_NAME = { + base: 'Base', + arbitrum: 'Arbitrum', + polygon: 'Polygon', + katana: 'Katana', + plasma: 'Plasma', + hemi: 'Hemi', +} + +// chain IDs +const CHAIN_ID = { + base: 8453, + arbitrum: 42161, + polygon: 137, + katana: 747474, + plasma: 9745, + hemi: 43111, +} + +function toMarketUrlParam(market) { + if (market === 'ethereum') return 'mainnet' + if (market === 'avax') return 'avalanche' + if (market === 'xdai') return 'gnosis' + if (market === 'bsc') return 'bnb' + return market +} + +// ---------- math ---------- +const RAY = 1e27 +const aprRayToDecimal = (ray) => Number(ray) / RAY +const aprToApyDecimal = (apr) => Math.pow(1 + apr / 365, 365) - 1 + +// ---------- helpers ---------- +const setToArray = (s) => Array.from(s ? s.values() : []) + +/** + * Extracts first valid 0x-address from any string (SES-safe) + */ +function extractAddrLoose(x) { + if (x == null) return '' + const s = String(x) + .toLowerCase() + .replace(/[\u200b-\u200d\uFEFF]/g, '') // remove zero-width chars + .trim() + const m = s.match(/0x[0-9a-f]{40}/i) + return m ? m[0] : '' +} +const normAddr = extractAddrLoose + +// ---------- Merkl ---------- +let merklCache = null + +async function fetchMerkl() { + if (merklCache) return merklCache + try { + const { data } = await axios.get('https://api.merkl.xyz/v4/opportunities', { + params: { mainProtocolId: 'ploutos' }, + timeout: 15000, + }) + merklCache = Array.isArray(data) ? data : (data ? [data] : []) + } catch (e) { + console.warn('[ploutos]', 'Merkl fetch failed:', e?.message || e) + merklCache = [] + } + return merklCache +} + +/** + * Build Merkl index by key `${chainId}:${addressLower}` + * Value shape: + * { supplyOps: Map, borrowOps: Map<...> } + * + * Deduplicated by opportunity ID (it.id) to avoid double-counting the same + * opportunity that appears under both aToken and underlying addresses. + * SES-safe: no direct iteration with spreads. + */ +async function buildMerklIndex() { + const items = await fetchMerkl() + const index = new Map() + + for (let idx = 0; idx < items.length; idx++) { + const it = items[idx] + const chainId = Number(it.chainId || 0) + if (!chainId) continue + + const side = String(it.type || '').toUpperCase().includes('BORROW') ? 'borrow' : 'supply' + const apr = Number(it.apr || 0) + const opId = String(it.id || '') + if (!opId) continue + + // collect reward tokens + const rewardSet = new Set() + const br = (it.rewardsRecord && it.rewardsRecord.breakdowns) || [] + for (let j = 0; j < br.length; j++) { + const addr = normAddr(br[j]?.token?.address) + if (addr) rewardSet.add(addr) + } + const rewardTokens = setToArray(rewardSet) + + // bind this opportunity to possible keys (identifier, explorerAddress, tokens) + const keysRaw = new Set() + const k1 = normAddr(it.identifier) + const k2 = normAddr(it.explorerAddress) + if (k1) keysRaw.add(k1) + if (k2) keysRaw.add(k2) + const toks = Array.isArray(it.tokens) ? it.tokens : [] + for (let k = 0; k < toks.length; k++) { + const a = normAddr(typeof toks[k] === 'string' ? toks[k] : toks[k]?.address) + if (a) keysRaw.add(a) + } + + const keysArr = setToArray(keysRaw).map(a => `${chainId}:${a}`) + for (let qi = 0; qi < keysArr.length; qi++) { + const key = keysArr[qi] + const cur = index.get(key) || { supplyOps: new Map(), borrowOps: new Map() } + const bucket = side === 'borrow' ? cur.borrowOps : cur.supplyOps + const ex = bucket.get(opId) + if (ex) { + // merge duplicate entries if the same op appears twice in API + ex.apr += apr + const s = new Set(ex.rewardTokens || []) + for (let ri = 0; ri < rewardTokens.length; ri++) s.add(rewardTokens[ri]) + ex.rewardTokens = setToArray(s) + } else { + bucket.set(opId, { apr, rewardTokens }) + } + index.set(key, cur) + } + } + + return index +} + +// ---------- core adapter ---------- +async function getApy(market) { + const chain = market + const chainOut = CHAIN_NAME[market] ?? market + const provider = protocolDataProviders[market] + const chainId = CHAIN_ID[market] || 0 + if (!provider) return [] + + const reserves = (await sdk.api.abi.call({ + target: provider, + abi: poolAbi.find(m => m.name === 'getAllReservesTokens'), + chain, + })).output + + const aTokens = (await sdk.api.abi.call({ + target: provider, + abi: poolAbi.find(m => m.name === 'getAllATokens'), + chain, + })).output + + const reserveData = (await sdk.api.abi.multiCall({ + chain, + abi: poolAbi.find(m => m.name === 'getReserveData'), + calls: reserves.map(p => ({ target: provider, params: p.tokenAddress })), + })).output.map(o => o.output) + + const reserveCfg = (await sdk.api.abi.multiCall({ + chain, + abi: poolAbi.find(m => m.name === 'getReserveConfigurationData'), + calls: reserves.map(p => ({ target: provider, params: p.tokenAddress })), + })).output.map(o => o.output) + + const aSupplies = (await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map(t => ({ target: t.tokenAddress })), + })).output.map(o => o.output) + + const underlyingBalances = (await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserves[i].tokenAddress, + params: [t.tokenAddress], + })), + })).output.map(o => o.output) + + const aDecs = (await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map(t => ({ target: t.tokenAddress })), + })).output.map(o => o.output) + + const uDecs = (await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: reserves.map(p => ({ target: p.tokenAddress })), + })).output.map(o => o.output) + + const priceKeys = reserves.map(t => `${chain}:${t.tokenAddress}`).join(',') + const prices = (await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`)).data?.coins || {} + + // Merkl map + const merklMap = await buildMerklIndex() + + const out = [] + for (let i = 0; i < reserves.length; i++) { + const r = reserves[i] + const cfg = reserveCfg[i] + if (cfg.isFrozen) continue + + const symUp = String(r.symbol || '').toUpperCase() + if (symUp === 'GHO' || symUp === 'SGHO' || symUp === 'STKGHO') continue + + const price = prices[`${chain}:${r.tokenAddress}`]?.price + if (!price) continue + + const supplyAToken = Number(aSupplies[i]) / 10 ** Number(aDecs[i]) + const totalSupplyUsd = supplyAToken * price + + const underlying = Number(underlyingBalances[i]) / 10 ** Number(uDecs[i]) + const tvlUsd = underlying * price + + const totalBorrowUsd = Math.max(totalSupplyUsd - tvlUsd, 0) + + const data = reserveData[i] + const apyBase = aprToApyDecimal(aprRayToDecimal(data.liquidityRate)) * 100 + const apyBaseBorrow = aprToApyDecimal(aprRayToDecimal(data.variableBorrowRate)) * 100 + + const marketUrlParam = toMarketUrlParam(market) + const url = `https://app.ploutos.money/reserve-overview/?underlyingAsset=${r.tokenAddress.toLowerCase()}&marketName=proto_${marketUrlParam}_v3` + + // Merkl match by chainId + (aToken | underlying), deduplicated by opId + const aTok = normAddr(aTokens[i].tokenAddress) + const uTok = normAddr(r.tokenAddress) + + const mAT = chainId ? merklMap.get(`${chainId}:${aTok}`) : undefined + const mUA = chainId ? merklMap.get(`${chainId}:${uTok}`) : undefined + + // Merge by unique opportunity ID for each side + function unionOps(a, b, side) { + const mapA = a ? (side === 'borrow' ? a.borrowOps : a.supplyOps) : null + const mapB = b ? (side === 'borrow' ? b.borrowOps : b.supplyOps) : null + const ids = new Set() + if (mapA) mapA.forEach((_, id) => ids.add(id)) + if (mapB) mapB.forEach((_, id) => ids.add(id)) + + let aprSum = 0 + const rts = new Set() + ids.forEach((id) => { + const rec = (mapA && mapA.get(id)) || (mapB && mapB.get(id)) || null + if (!rec) return + aprSum += Number(rec.apr || 0) + const tokens = rec.rewardTokens || [] + for (let t = 0; t < tokens.length; t++) rts.add(tokens[t]) + }) + return { apr: aprSum, rts: setToArray(rts) } + } + + const sup = unionOps(mAT, mUA, 'supply') + const bor = unionOps(mAT, mUA, 'borrow') + + const rewardUnion = new Set([...sup.rts, ...bor.rts]) + const rewardTokens = setToArray(rewardUnion) + + const poolObj = { + pool: `${aTokens[i].tokenAddress}-${(market === 'avax' ? 'avalanche' : market)}`.toLowerCase(), + chain: chainOut, + project: 'ploutos-money', + symbol: r.symbol, + tvlUsd, + apyBase, + apyBaseBorrow, + underlyingTokens: [r.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + ltv: cfg.ltv / 10000, + borrowable: cfg.borrowingEnabled, + url, + } + + if (sup.apr > 0) poolObj.apyReward = sup.apr + if (bor.apr > 0) poolObj.apyRewardBorrow = bor.apr + if (rewardTokens.length) poolObj.rewardTokens = rewardTokens + + out.push(poolObj) + } + + return out +} + +async function apy() { + const markets = Object.keys(protocolDataProviders) + const res = await Promise.allSettled(markets.map(m => getApy(m))) + return res + .filter(r => r.status === 'fulfilled') + .flatMap(r => r.value) + .filter(p => utils.keepFinite(p)) +} + +module.exports = { + timetravel: false, + apy, +} diff --git a/src/adaptors/ploutos-money/poolAbi.js b/src/adaptors/ploutos-money/poolAbi.js new file mode 100644 index 0000000000..bba1c9dc38 --- /dev/null +++ b/src/adaptors/ploutos-money/poolAbi.js @@ -0,0 +1,242 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/pluto/index.js b/src/adaptors/pluto/index.js new file mode 100644 index 0000000000..6e05815d26 --- /dev/null +++ b/src/adaptors/pluto/index.js @@ -0,0 +1,41 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const CLIENT_ID = "726755f8-ff00-4376-ad3a-259537bfac80" +const CLIENT_KEY = "736a9e0729bac973ebd5b4df653ba133c5ee7c105852ce111eb74bd7f7e94c56" + +const getApy = async () => { + const reserveApys = []; + const req = (await axios.get(`https://nebula.pluto.so/v1/earn/vaults`, { + headers: { + 'x-client-id': CLIENT_ID, + 'authorization': 'Bearer '+CLIENT_KEY + } + })); + const reserves = req.data.data; + + reserveApys.push( + ...reserves.map((r) => { + return { + pool: r.earn_vault_address, + chain: 'Solana', + project: 'pluto', + symbol: utils.formatSymbol(r.symbol), + tvlUsd: Number(r.supply_amount_usd), + url: `https://app.pluto.so/earn/`, + apyBase: Number(r.supply_apy), + totalSupplyUsd: Number(r.supply_amount_usd), + totalBorrowUsd: Number(r.borrowed_amount_usd), + apyBaseBorrow: Number(r.borrow_apy), + }; + }) + ); + + return reserveApys; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://pluto.so/', +}; diff --git a/src/adaptors/pods-yield/abi.json b/src/adaptors/pods-yield/abi.json new file mode 100644 index 0000000000..c838dfe9c2 --- /dev/null +++ b/src/adaptors/pods-yield/abi.json @@ -0,0 +1,1507 @@ +[ + { + "inputs": [ + { + "internalType": "contract IConfigurationManager", + "name": "_configuration", + "type": "address" + }, + { + "internalType": "contract IERC20Metadata", + "name": "_asset", + "type": "address" + }, + { + "internalType": "address", + "name": "_investor", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + } + ], + "name": "Capped__AmountExceedsCap", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__AlreadyProcessingDeposits", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "IVault__AssetsUnderMinimumAmount", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__CallerIsNotTheController", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__ForbiddenWhileProcessingDeposits", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__MigrationNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__NotProcessingDeposits", + "type": "error" + }, + { + "inputs": [], + "name": "IVault__ZeroAssets", + "type": "error" + }, + { + "inputs": [], + "name": "STETHVault__PermitNotAvailable", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint32", + "name": "roundId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "DepositProcessed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint32", + "name": "roundId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "DepositRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "roundAccruedInterest", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "investmentYield", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "idleAssets", + "type": "uint256" + } + ], + "name": "EndRoundData", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "FeeCollected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Migrated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "roundId", + "type": "uint32" + } + ], + "name": "RoundEnded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "roundId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountAddedToStrategy", + "type": "uint256" + } + ], + "name": "RoundStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startSharePrice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endSharePrice", + "type": "uint256" + } + ], + "name": "SharePrice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRoundAssets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sharePrice", + "type": "uint256" + } + ], + "name": "StartRoundData", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INVESTOR_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_WITHDRAW_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_INITIAL_ASSETS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "assetsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "availableCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "configuration", + "outputs": [ + { + "internalType": "contract IConfigurationManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentRoundId", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositQueueSize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "depositWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "endRound", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getWithdrawFeeRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "handleMigration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "idleAssetsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "investor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isProcessingDeposits", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRoundAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastSharePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "numerator", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "denominator", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "migrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "mintWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "depositors", + "type": "address[]" + } + ], + "name": "processQueuedDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "processedDeposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "queuedDeposits", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "refund", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharePrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sharePriceDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "spentCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startRound", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalIdleAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/pods-yield/index.js b/src/adaptors/pods-yield/index.js new file mode 100644 index 0000000000..b56dd30a71 --- /dev/null +++ b/src/adaptors/pods-yield/index.js @@ -0,0 +1,158 @@ +const axios = require('axios'); +const { default: BigNumber } = require('bignumber.js'); +const { convertToAssets, totalAssets } = require('./queries'); +const { getProvider } = require('@defillama/sdk/build/general'); +const provider = getProvider('ethereum'); + +// **** +// HELPER FUNCTIONS +// **** +const getBlockNumberFromTimestamp = async (timestamp) => { + const response = await axios.get( + `https://coins.llama.fi/block/ethereum/${timestamp}` + ); + return response.data.height; +}; + +const getTokenPrice = async (tokenAddress) => { + const priceKey = `ethereum:${tokenAddress}`; + const tokenPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + return tokenPrice; +}; + +const getAPY = async ( + strategy, + initialPosition, + versionFactor = 1, + blockNumber = 'latest' +) => { + const assets = await convertToAssets(strategy, initialPosition, blockNumber); + return new BigNumber(assets) + .dividedBy(initialPosition) + .multipliedBy(versionFactor); +}; + +// **** +// MAIN FUNCTION +// **** + +const vaultApys = async () => { + const apys = {}; + + const volatilityVaultAddress = '0x463f9ed5e11764eb9029762011a03643603ad879'; + const fudVaultAddress = '0x287f941aB4B5AaDaD2F13F9363fcEC8Ee312a969'; + const ethPhoriaAddress = '0x5fe4b38520e856921978715c8579d2d7a4d2274f'; + + const totalAssetsETHPhoria = (await totalAssets(ethPhoriaAddress)) / 1e18; + const totalAssetsFudVault = (await totalAssets(fudVaultAddress)) / 1e6; + const totalAssetsSTETHvv = (await totalAssets(volatilityVaultAddress)) / 1e18; + + const lidoTokenPrice = await getTokenPrice( + '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84' + ); + + const lastYieldFromV1 = '1.0284808574603643'; + const firstYieldFromV2 = '1.011289282624759'; + + const vaults = [ + { + address: ethPhoriaAddress, + name: 'ETHPhoria', + symbol: 'stETH', + tvl: totalAssetsETHPhoria * lidoTokenPrice, + underlyingTokens: ['0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'], + initialPosition: '1000000000000000000', + decimals: 18, + deployBlock: 16901984, + }, + { + address: fudVaultAddress, + name: 'FudVault', + symbol: 'aEthUSDC', + tvl: totalAssetsFudVault, + underlyingTokens: ['0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c'], + initialPosition: '150000000000', + decimals: 6, + deployBlock: 17118350, + }, + { + address: volatilityVaultAddress, + name: 'Volatility Vault', + symbol: 'stETHvv', + tvl: totalAssetsSTETHvv * lidoTokenPrice, + underlyingTokens: ['0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'], + initialPosition: '638537294599340499', + decimals: 18, + deployBlock: 15079795, + versionFactor: new BigNumber(lastYieldFromV1).dividedBy(firstYieldFromV2), + }, + ]; + + return await Promise.all( + vaults.map(async (vault) => { + const strategy = vault.address; + + // calculate baseAPY - 1 day period + const yesterday = Math.floor(Date.now() / 1000) - 24 * 60 * 60; + const blockNumberYesterday = await getBlockNumberFromTimestamp(yesterday); + const positionYesterday = await totalAssets( + strategy, + blockNumberYesterday + ); + const positionToday = await totalAssets(strategy, 'latest'); + + const apyBase = ( + await getAPY( + strategy, + new BigNumber(positionToday).minus(positionYesterday), + vault.versionFactor + ) + ).toNumber(); + + const apyInception = ( + await getAPY( + strategy, + new BigNumber(vault.initialPosition), + vault.versionFactor + ) + ).toNumber(); + + let finalApyInception = apyInception; + let finalApyBase = apyBase; + if (strategy === fudVaultAddress) { + finalApyInception = apyInception - 1.003328; + finalApyBase = apyBase - 1.003328; + } + + const block = await provider.getBlock(vault.deployBlock); + const NUM_OF_DAYS_YEAR = 365; + + const daysDiff = Date.now() / 1000 - block.timestamp; + const numOfDays = daysDiff / (24 * 60 * 60); // 1 day in seconds + const expoent = NUM_OF_DAYS_YEAR / numOfDays; + + const projectedAPY = finalApyInception ** expoent - 1; + const apyBaseInception = projectedAPY * 100; + + return { + pool: `${strategy}-ethereum`, + chain: 'Ethereum', + project: 'pods-yield', + symbol: vault.symbol, + tvlUsd: vault.tvl, + apyBase: (finalApyBase - 1) * 100, + underlyingTokens: vault.underlyingTokens, + poolMeta: vault.name, + apyBaseInception, + }; + }) + ); +}; + +module.exports = { + timetravel: false, + apy: vaultApys, + url: 'https://app.pods.finance', +}; diff --git a/src/adaptors/pods-yield/queries.js b/src/adaptors/pods-yield/queries.js new file mode 100644 index 0000000000..5de18d72e0 --- /dev/null +++ b/src/adaptors/pods-yield/queries.js @@ -0,0 +1,34 @@ +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); + +const convertToAssets = async (strategy, position, block = 'latest') => { + const data = ( + await sdk.api.abi.call({ + target: strategy, + abi: abi.find((m) => m.name === 'convertToAssets'), + params: [position.toString()], + chain: 'ethereum', + block: block, + }) + ).output; + + return data; +}; + +const totalAssets = async (strategy, block = 'latest') => { + const data = ( + await sdk.api.abi.call({ + target: strategy, + abi: abi.find((m) => m.name === 'totalAssets'), + chain: 'ethereum', + block, + }) + ).output; + + return data; +}; + +module.exports = { + convertToAssets, + totalAssets, +}; diff --git a/src/adaptors/polylend/index.js b/src/adaptors/polylend/index.js new file mode 100755 index 0000000000..c413e83e99 --- /dev/null +++ b/src/adaptors/polylend/index.js @@ -0,0 +1,252 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const SECONDS_PER_YEAR = 31536000; + +const chainUrlParam = { + polygon_zkevm: 'proto_main', +}; + +const oraclePriceABI = { + inputs: [], + name: 'latestAnswer', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getPrices = async (addresses) => { + const _prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const plendOraclePrice = ( + await sdk.api.abi.call({ + target: '0x63a02a94eb32fd42c938734f12ee41ae24b901c1', + abi: oraclePriceABI, + chain: 'polygon_zkevm', + }) + ).output; + + const plend = { + 'polygon_zkevm:0xe061cf2aa271f9fdca9e61eaee372e76fea3a5d0': { + decimals: 18, + symbol: 'PLEND', + price: Number(plendOraclePrice) / 1e8, + timestamp: Date.now(), + confidence: 0.99, + }, + }; + + const prices = { ..._prices, ...plend }; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const API_URLS = { + polygon_zkevm: + 'https://api.studio.thegraph.com/query/52108/polylend/version/latest', +}; + +const query = gql` + query ReservesQuery { + reserves(where: { name_not: "" }) { + name + borrowingEnabled + aToken { + id + rewards(where: { distributionEnd_gt: 0 }) { + id + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + underlyingAssetAddress + underlyingAssetDecimals + } + vToken { + rewards(where: { distributionEnd_gt: 0 }) { + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + } + symbol + liquidityRate + variableBorrowRate + baseLTVasCollateral + isFrozen + } + } +`; + +const apy = async () => { + let data = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await request(url, query)).reserves, + ]) + ); + + data = data.map(([chain, reserves]) => [ + chain, + reserves.filter((p) => !p.isFrozen), + ]); + + const totalSupply = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: reserves.map((reserve) => ({ + target: reserve.aToken.id, + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingBalances = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: reserves.map((reserve, i) => ({ + target: reserve.aToken.underlyingAssetAddress, + params: [reserve.aToken.id], + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingTokens = data.map(([chain, reserves]) => + reserves.map((pool) => `${chain}:${pool.aToken.underlyingAssetAddress}`) + ); + + const rewardTokens = data.map(([chain, reserves]) => + reserves.map((pool) => + pool.aToken.rewards.map((rew) => `${chain}:${rew.rewardToken}`) + ) + ); + + const { pricesByAddress, pricesBySymbol } = await getPrices( + underlyingTokens.flat().concat(rewardTokens.flat(Infinity)) + ); + + const pools = data.map(([chain, markets], i) => { + const chainPools = markets.map((pool, idx) => { + const supply = totalSupply[i][idx]; + const currentSupply = underlyingBalances[i][idx]; + const totalSupplyUsd = + (supply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const tvlUsd = + (currentSupply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const { rewards } = pool.aToken; + + const rewardPerYear = rewards.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + + const { rewards: rewardsBorrow } = pool.vToken; + const rewardPerYearBorrow = rewardsBorrow.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol]), + 0 + ); + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + totalBorrowUsd = totalBorrowUsd < 0 ? 0 : totalBorrowUsd; + + const supplyRewardEnd = pool.aToken.rewards[0]?.distributionEnd; + const borrowRewardEnd = pool.vToken.rewards[0]?.distributionEnd; + + return { + pool: `${pool.aToken.id}-${chain}`.toLowerCase(), + chain: utils.formatChain('polygon_zkevm'), + project: 'polylend', + symbol: pool.symbol, + tvlUsd, + apyBase: (pool.liquidityRate / 10 ** 27) * 100, + apyReward: + supplyRewardEnd * 1000 > new Date() + ? (rewardPerYear / totalSupplyUsd) * 100 + : null, + rewardTokens: + supplyRewardEnd * 1000 > new Date() + ? rewards.map((rew) => rew.rewardToken) + : null, + underlyingTokens: [pool.aToken.underlyingAssetAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.variableBorrowRate) / 1e25, + apyRewardBorrow: + borrowRewardEnd * 1000 > new Date() + ? (rewardPerYearBorrow / totalBorrowUsd) * 100 + : null, + ltv: Number(pool.baseLTVasCollateral) / 10000, + url: `https://polylend.xyz/reserve-overview/?underlyingAsset=${pool.aToken.underlyingAssetAddress}&marketName=${chainUrlParam[chain]}&utm_source=defillama&utm_medium=listing&utm_campaign=external`, + borrowable: pool.borrowingEnabled, + }; + }); + + return chainPools; + }); + + return pools.flat().filter((p) => !!p.tvlUsd); +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/polynomial-liquidity/index.js b/src/adaptors/polynomial-liquidity/index.js new file mode 100644 index 0000000000..6437b54231 --- /dev/null +++ b/src/adaptors/polynomial-liquidity/index.js @@ -0,0 +1,49 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const API_URL = + 'https://perps-api-mainnet.polynomial.finance/vaults/all?chainId=8008'; +// LIUIDITY UI +const LIQUIDITY_URL = 'https://polynomial.fi/en/mainnet/earn/liquidity'; + +const getApy = async () => { + // APR is retrieved using our api, tvl pairs etc trough subgraph + + const { data } = await axios.get( + 'https://perps-api-mainnet.polynomial.finance/vaults/all?chainId=8008', + { + maxBodyLength: Infinity, + headers: { + 'User-Agent': 'defillama (aws-lambda)', + Accept: 'application/json', + }, + } + ); + + const poolInfo = await Promise.all( + data.map(async (pool) => { + return { + pool: `${pool.poolId}-${pool.collateralType}`, + chain: 'polynomial', + project: 'polynomial-liquidity', + symbol: pool.collateralType === 'fxUSDC' ? 'USDC' : pool.collateralType, + tvlUsd: pool.tvl, + apyBase: pool.apr + pool.baseApr, + apyReward: pool.opRewardsApr, + rewardTokens: ['0x4200000000000000000000000000000000000042'], + url: LIQUIDITY_URL, + }; + }) + ); + return poolInfo; +}; + +async function main() { + let data = await getApy(); + return data; +} + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/polytrade/index.js b/src/adaptors/polytrade/index.js new file mode 100644 index 0000000000..5ad8dc9abd --- /dev/null +++ b/src/adaptors/polytrade/index.js @@ -0,0 +1,71 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const axios = require('axios'); + +const getTokenPrice = async (token, exchangeTo, amount) => { + const { data } = await axios.get(`https://min-api.cryptocompare.com/data/price?fsym=${token}&tsyms=${exchangeTo}`); + const unitPrice = Object.values(data)[0]; + return amount * Number(unitPrice); +} + +const formatUnits = (amount, decimals) => Number(ethers.utils.formatUnits(amount, decimals)); + +const poolsFunction = async () => { + + const LENDER_POOL_CONTRACT = '0xE544a0Ca5F4a01f137AE5448027471D6a9eC9661'; + const STRATEGY_CONTRACT = '0xfE624A12b1732d19680A7a2a2efBe21f1C0F3F19'; + const TRADE_REWARD = '0xa3e8e842683d48bf2e929eda240c368ec6f8b986'; + const STABLE_REWARD = '0x352A424Caf2aB698570b1E9a273209b5A0fF52BD'; + const chain = 'polygon'; + const abis = { + getReward: {"inputs":[],"name":"getReward","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"}, + getBalance: {"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}, + }; + + // GET total TVL + const tvl = (await sdk.api.abi.call({ + target: STRATEGY_CONTRACT, + abi: abis.getBalance, + chain + })).output; + + // Get rewards in TRADE token + const tradeReward = (await sdk.api.abi.call({ + target: TRADE_REWARD, + abi: abis.getReward, + chain + })).output; + + // Get rewards in USDC + const stableReward = (await sdk.api.abi.call({ + target: STABLE_REWARD, + abi: abis.getReward, + chain + })).output; + + // TRADE rewards in USD + const tokenPrice = await getTokenPrice( + "TRADE", + "USD", + formatUnits(tradeReward, '3'), + ); + + const lenderPool = { + pool: `${LENDER_POOL_CONTRACT}-${chain}`, + chain: 'Polygon', + project: 'polytrade', + symbol: 'USDC', + tvlUsd: Number(tvl) / 1e6, + apyBase: formatUnits(stableReward, '2'), + apyReward: tokenPrice, + rewardTokens: ['0x692ac1e363ae34b6b489148152b12e2785a3d8d6'] + }; + + return [lenderPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://lender.polytrade.app', +}; \ No newline at end of file diff --git a/src/adaptors/pony-finance/index.js b/src/adaptors/pony-finance/index.js new file mode 100644 index 0000000000..4cb8b2eb34 --- /dev/null +++ b/src/adaptors/pony-finance/index.js @@ -0,0 +1,25 @@ +const utils = require('../utils'); +const axios = require('axios').default; + +const poolsFunction = async () => { + const res = await axios.get('https://api.ponyfinance.xyz/info'); + + const { apy, tvl } = res.data; + + const ponyPool = { + pool: '0x0d97fee619d955509e54b046c9992b6e9f5b0630', + chain: utils.formatChain('ethereum'), + project: 'pony-finance', + symbol: 'PONY', + tvlUsd: Number(tvl), + apyBase: Number(apy) * 100, + }; + + return [ponyPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://www.scalara.xyz/indices/pony', +}; diff --git a/src/adaptors/predy-v5/abi.js b/src/adaptors/predy-v5/abi.js new file mode 100644 index 0000000000..9bca55606a --- /dev/null +++ b/src/adaptors/predy-v5/abi.js @@ -0,0 +1,353 @@ +module.exports = { + ControllerAbi: [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getAsset", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pairGroupId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "supplyTokenAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "totalCompoundDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalNormalDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalNormalBorrowed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetScaler", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetGrowth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debtGrowth", + "type": "uint256" + } + ], + "internalType": "struct ScaledAsset.TokenStatus", + "name": "tokenStatus", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "baseRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kinkRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope2", + "type": "uint256" + } + ], + "internalType": "struct InterestRateModel.IRMParams", + "name": "irmParams", + "type": "tuple" + } + ], + "internalType": "struct DataType.AssetPoolStatus", + "name": "stablePool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "supplyTokenAddress", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "totalCompoundDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalNormalDeposited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalNormalBorrowed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetScaler", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetGrowth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debtGrowth", + "type": "uint256" + } + ], + "internalType": "struct ScaledAsset.TokenStatus", + "name": "tokenStatus", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "baseRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kinkRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope2", + "type": "uint256" + } + ], + "internalType": "struct InterestRateModel.IRMParams", + "name": "irmParams", + "type": "tuple" + } + ], + "internalType": "struct DataType.AssetPoolStatus", + "name": "underlyingPool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "riskRatio", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "rangeSize", + "type": "int24" + }, + { + "internalType": "int24", + "name": "rebalanceThreshold", + "type": "int24" + } + ], + "internalType": "struct DataType.AssetRiskParams", + "name": "riskParams", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "uniswapPool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint64", + "name": "numRebalance", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRebalanceTotalSquartAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastFee0Growth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastFee1Growth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowPremium0Growth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowPremium1Growth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee0Growth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee1Growth", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "int256", + "name": "positionAmount", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "lastFeeGrowth", + "type": "uint256" + } + ], + "internalType": "struct ScaledAsset.UserStatus", + "name": "rebalancePositionUnderlying", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "int256", + "name": "positionAmount", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "lastFeeGrowth", + "type": "uint256" + } + ], + "internalType": "struct ScaledAsset.UserStatus", + "name": "rebalancePositionStable", + "type": "tuple" + }, + { + "internalType": "int256", + "name": "rebalanceFeeGrowthUnderlying", + "type": "int256" + }, + { + "internalType": "int256", + "name": "rebalanceFeeGrowthStable", + "type": "int256" + } + ], + "internalType": "struct Perp.SqrtPerpAssetStatus", + "name": "sqrtAssetStatus", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "isMarginZero", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isIsolatedMode", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "lastUpdateTimestamp", + "type": "uint256" + } + ], + "internalType": "struct DataType.PairStatus", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + ERC20Abi: [ + { "inputs": [], "name": "totalSupply", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" } + ] +} \ No newline at end of file diff --git a/src/adaptors/predy-v5/helpers.js b/src/adaptors/predy-v5/helpers.js new file mode 100644 index 0000000000..11f983ae11 --- /dev/null +++ b/src/adaptors/predy-v5/helpers.js @@ -0,0 +1,29 @@ +const { default: BigNumber } = require('bignumber.js'); + +const ONE = new BigNumber(10).pow(18); + +function calculateInterestRate(params, ur) { + if (ur < 0) { + throw new Error('utilization ratio must be positive value.'); + } + + let ir = new BigNumber(params.baseRate); + + try { + if (ur.lte(params.kinkRate)) { + ir = ir.plus(ur.times(params.slope1).div(ONE)); + } else { + ir = ir.plus(params.kinkRate.times(params.slope1).div(ONE)); + ir = ir.plus(params.slope2.times(ur.minus(params.kinkRate)).div(ONE)); + } + } catch (err) { + console.log(err); + return ir; + } + + return ir; +} + +module.exports = { + calculateInterestRate, +}; diff --git a/src/adaptors/predy-v5/index.js b/src/adaptors/predy-v5/index.js new file mode 100755 index 0000000000..2bfa2e1e6b --- /dev/null +++ b/src/adaptors/predy-v5/index.js @@ -0,0 +1,255 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const { default: BigNumber } = require('bignumber.js'); +const { getAsset, getTotalSupply } = require('./queries'); +const { calculateInterestRate } = require('./helpers'); + +const endpoint = sdk.graph.modifyEndpoint('6pme7wuvRUDGjuV3zRcgyo6QdKcsHp87tSXZcS1U2QHb'); + +const query = gql` + query ($address: String, $strategyId: Int) { + aggregatedUniswapPriceEntities( + first: 7 + where: { address: $address, strategyId: $strategyId, interval: "DAILY" } + orderBy: openTimestamp + orderDirection: desc + ) { + id + address + strategyId + interval + openPrice + closePrice + openTimestamp + closeTimestamp + } + } +`; + +const strategies = [ + { + id: 1, + symbol: 'USDC.e', + poolMeta: 'Gamma short strategy of WETH-USDC.e 0.05% pool', + strategyTokenAddress: '0x5037Df4301489C96F17E3E2eBE55bFF909098043', + }, + { + id: 2, + symbol: 'USDC.e', + poolMeta: 'Gamma short strategy of ARB-USDC.e 0.3% pool', + strategyTokenAddress: '0xBd0a8a71283c92123A3cAE4E7Cb71D410973A9e1', + }, + { + id: 3, + symbol: 'USDC.e', + poolMeta: 'Gamma short strategy of LUSD-USDC.e 0.05% pool', + strategyTokenAddress: '0xaA25788310eEf9E78e7D601EF727f19BE0944463', + }, + { + id: 4, + symbol: 'USDC.e', + poolMeta: 'Gamma short strategy of WETH-USDC.e 0.05% extra pool', + strategyTokenAddress: '0xde2781A9eA08E75149EF5EdC9CF97d44F1c05a0c', + }, +]; + +const pairs = [ + { + pairId: 1, + symbol: 'WETH', + poolMeta: 'Lending Pool for WETH-USDC.e 0.05% LP position', + tokenAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + decimals: 18, + }, + { + pairId: 2, + symbol: 'ARB', + poolMeta: 'Lending Pool for ARB-USDC.e 0.3% LP position', + tokenAddress: '0x912CE59144191C1204E64559FE8253a0e49E6548', + decimals: 18, + }, + { + pairId: 3, + symbol: 'WBTC', + poolMeta: 'Lending Pool for WBTC-USDC.e 0.05% LP position', + tokenAddress: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + decimals: 8, + }, + { + pairId: 4, + symbol: 'GYEN', + poolMeta: 'Lending Pool for GYEN-USDC.e 0.05% LP position', + tokenAddress: '0x589d35656641d6aB57A545F08cf473eCD9B6D5F7', + decimals: 6, + }, + { + pairId: 5, + symbol: 'LUSD', + poolMeta: 'Lending Pool for LUSD-USDC.e 0.05% LP position', + tokenAddress: '0x93b346b6BC2548dA6A1E7d98E9a421B42541425b', + decimals: 18, + }, + { + pairId: 6, + symbol: 'WETH', + poolMeta: 'Lending Pool for WETH-USDC.e 0.05% narrow range LP position', + tokenAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + decimals: 18, + isEx: true, + }, +]; + +const ONE = 10 ** 18; +const ZERO = new BigNumber(0); + +function getLendingSummary(scaledAssetStatus, irmParams, price, decimals) { + const supply = new BigNumber(scaledAssetStatus.totalCompoundDeposited) + .times(scaledAssetStatus.assetScaler) + .div(ONE) + .plus(scaledAssetStatus.totalNormalDeposited); + const borrow = new BigNumber(scaledAssetStatus.totalNormalBorrowed); + const ur = supply.eq(ZERO) ? ZERO : borrow.times(ONE).div(supply); + + const borrowInterest = calculateInterestRate(irmParams, ur); + const supplyInterest = supply.eq(ZERO) + ? ZERO + : borrowInterest.times(borrow).div(supply); + + const scaler = new BigNumber(10).pow(decimals); + + return { + supply: supply.times(price).div(scaler).toNumber(), + borrow: borrow.times(price).div(scaler).toNumber(), + apy: supplyInterest.div(new BigNumber(10).pow(16)).toNumber(), + }; +} + +const lendingApys = async () => { + const controller = '0x06a61E55d4d4659b1A23C0F20AEdfc013C489829'; + const usdcAddress = '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'; + + const priceKeys = pairs + .map((t) => `arbitrum:${t.tokenAddress}`) + .concat([`arbitrum:${usdcAddress}`]) + .join(','); + const pricesEthereum = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).body.coins; + + return await Promise.all( + pairs.map(async (pair) => { + const usdcPrice = pricesEthereum[`arbitrum:${usdcAddress}`]?.price; + const price = pricesEthereum[`arbitrum:${pair.tokenAddress}`]?.price; + + const pairStatus = await getAsset(controller, pair.pairId); + + const stableSummary = getLendingSummary( + pairStatus.stablePool.tokenStatus, + pairStatus.stablePool.irmParams, + usdcPrice, + 6 + ); + const underlyingSummary = getLendingSummary( + pairStatus.underlyingPool.tokenStatus, + pairStatus.underlyingPool.irmParams, + price, + pair.decimals + ); + + const stableSupplyToken = pairStatus.stablePool.supplyTokenAddress; + const underlyingSupplyToken = + pairStatus.underlyingPool.supplyTokenAddress; + + return [ + { + pool: `${stableSupplyToken}-arbitrum`, + chain: 'Arbitrum', + project: 'predy-v5', + symbol: 'USDC.e', + poolMeta: pair.poolMeta, + tvlUsd: stableSummary.supply - stableSummary.borrow, + totalSupplyUsd: stableSummary.supply, + totalBorrowUsd: stableSummary.borrow, + apyBase: stableSummary.apy, + url: `https://v5app.predy.finance/arbitrum/trade/usdce/lending/${pair.pairId}`, + }, + { + pool: `${underlyingSupplyToken}-arbitrum`, + chain: 'Arbitrum', + project: 'predy-v5', + symbol: pair.symbol, + poolMeta: pair.poolMeta, + tvlUsd: underlyingSummary.supply - underlyingSummary.borrow, + totalSupplyUsd: underlyingSummary.supply, + totalBorrowUsd: underlyingSummary.borrow, + apyBase: underlyingSummary.apy, + url: `https://v5app.predy.finance/arbitrum/trade/usdce/lending/${pair.pairId}`, + }, + ]; + }) + ); +}; + +function getApr(latest, start) { + const latestPrice = new BigNumber(latest.closePrice); + const startPrice = new BigNumber(start.closePrice); + const apr = latestPrice.times(1000000).div(startPrice).toNumber() - 1000000; + const span = Number(latest.closeTimestamp) - Number(start.closeTimestamp); + + if (span === 0) { + return 0; + } + + return ((apr / 10000) * (60 * 60 * 24 * 365)) / span; +} + +const strategyApys = async () => { + const strategyAddress = '0x247d8E00a2714665a5231f4AB165839d943C1838'; + + return await Promise.all( + strategies.map(async (strategy) => { + const prices = ( + await request(endpoint, query, { + address: strategyAddress, + strategyId: strategy.id, + }) + ).aggregatedUniswapPriceEntities; + + const apy = getApr( + prices[0], + prices[prices.length >= 7 ? 6 : prices.length - 1] + ); + + const totalSupply = await getTotalSupply(strategy.strategyTokenAddress); + + const tvlUsd = + new BigNumber(totalSupply) + .times(prices[0].closePrice) + .div(1e18) + .toNumber() / 1000000; + + return { + pool: `${strategy.strategyTokenAddress}-arbitrum`, + chain: 'Arbitrum', + project: 'predy-v5', + symbol: strategy.symbol, + poolMeta: strategy.poolMeta, + apyBase: apy, + tvlUsd, + url: `https://v5app.predy.finance/arbitrum/trade/usdce/strategy/${strategy.id}`, + }; + }) + ); +}; + +module.exports = { + timetravel: false, + apy: async () => { + const lendingApyResults = await lendingApys(); + const strategyApyResults = await strategyApys(); + + return lendingApyResults.flat().concat(strategyApyResults); + }, + url: 'https://appv5.predy.finance', +}; diff --git a/src/adaptors/predy-v5/queries.js b/src/adaptors/predy-v5/queries.js new file mode 100644 index 0000000000..3d3ff597a8 --- /dev/null +++ b/src/adaptors/predy-v5/queries.js @@ -0,0 +1,35 @@ +const sdk = require('@defillama/sdk'); +const { ControllerAbi, ERC20Abi } = require('./abi'); + +const getAsset = async (strategy, pairId, block = 'latest') => { + const data = ( + await sdk.api.abi.call({ + target: strategy, + abi: ControllerAbi.find((m) => m.name === 'getAsset'), + params: [pairId], + chain: 'arbitrum', + block: block, + }) + ).output; + + return data; +}; + +const getTotalSupply = async (strategyToken, block = 'latest') => { + const data = ( + await sdk.api.abi.call({ + target: strategyToken, + abi: ERC20Abi.find((m) => m.name === 'totalSupply'), + params: [], + chain: 'arbitrum', + block: block, + }) + ).output; + + return data; +}; + +module.exports = { + getAsset, + getTotalSupply, +}; diff --git a/src/adaptors/premia-v2/abi.ts b/src/adaptors/premia-v2/abi.ts new file mode 100644 index 0000000000..38dd23d8d6 --- /dev/null +++ b/src/adaptors/premia-v2/abi.ts @@ -0,0 +1,379 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'address', + name: '_diamond', + type: 'address', + }, + { + internalType: 'address', + name: '_premia', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'bool', + name: 'isCallPool', + type: 'bool', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardAmount', + type: 'uint256', + }, + ], + name: 'Claim', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoints', + type: 'uint256', + }, + ], + name: 'UpdatePoolAlloc', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'uint256', + name: '_allocPoints', + type: 'uint256', + }, + ], + name: 'addPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'addPremiaRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bool', + name: '_isCallPool', + type: 'bool', + }, + { + internalType: 'uint256', + name: '_userTVLOld', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_userTVLNew', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_totalTVL', + type: 'uint256', + }, + ], + name: 'allocatePending', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bool', + name: '_isCallPool', + type: 'bool', + }, + { + internalType: 'uint256', + name: '_userTVLOld', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_userTVLNew', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_totalTVL', + type: 'uint256', + }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'bool', + name: 'isCallPool', + type: 'bool', + }, + ], + name: 'getPoolInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accPremiaPerShare', + type: 'uint256', + }, + ], + internalType: 'struct PremiaMiningStorage.PoolInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPremiaPerYear', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTotalAllocationPoints', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address[]', + name: 'pools', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'isCall', + type: 'bool[]', + }, + ], + name: 'multiClaim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bool', + name: '_isCallPool', + type: 'bool', + }, + { + internalType: 'address', + name: '_user', + type: 'address', + }, + ], + name: 'pendingPremia', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'premiaRewardsAvailable', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_pools', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '_allocPoints', + type: 'uint256[]', + }, + ], + name: 'setPoolAllocPoints', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_premiaPerYear', + type: 'uint256', + }, + ], + name: 'setPremiaPerYear', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bool', + name: '_isCallPool', + type: 'bool', + }, + { + internalType: 'uint256', + name: '_totalTVL', + type: 'uint256', + }, + ], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_pools', + type: 'address[]', + }, + { + internalType: 'uint256', + name: '_premiaPerYear', + type: 'uint256', + }, + ], + name: 'upgrade', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/premia-v2/addresses.ts b/src/adaptors/premia-v2/addresses.ts new file mode 100644 index 0000000000..35aae81ce8 --- /dev/null +++ b/src/adaptors/premia-v2/addresses.ts @@ -0,0 +1,18 @@ +const PREMIA_MINING_CONTRACT_ADDRESS = { + ethereum: '0x9aBB27581c2E46A114F8C367355851e0580e9703', + arbitrum: '0xbC3c01D954282eEd8433da4359C1ac1443a7d09A', + optimism: '0xbfDC37499D99046710a9C567016791c71cD25Cf6', + fantom: '0x0389996552F5Da35fa6Ddc80B083F78622df3A6f', +}; + +const PREMIA_TOKEN_ADDRESS = { + ethereum: '0x6399C842dD2bE3dE30BF99Bc7D1bBF6Fa3650E70', + arbitrum: '0x51fc0f6660482ea73330e414efd7808811a57fa2', + fantom: '0x3028b4395f98777123c7da327010c40f3c7cc4ef', + optimism: '0x374ad0f47f4ca39c78e5cc54f1c9e426ff8f231a', +}; + +module.exports = { + PREMIA_MINING_CONTRACT_ADDRESS, + PREMIA_TOKEN_ADDRESS, +}; diff --git a/src/adaptors/premia-v2/index.ts b/src/adaptors/premia-v2/index.ts new file mode 100644 index 0000000000..ed1642734f --- /dev/null +++ b/src/adaptors/premia-v2/index.ts @@ -0,0 +1,111 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); +const { PREMIA_TOKEN_ADDRESS } = require('./addresses'); +const { convert, getChainRewardData } = require('./utils'); +const { getPrices } = require('../utils'); + +const getPoolsQuery = gql` + query MyQuery { + pools { + address + annualPercentageReturn + averageReturn + netSizeInUsd + openInterest + totalLocked + name + id + underlying { + address + symbol + decimals + } + totalVolumeInUsd + openInterestInUsd + profitLossPercentage + optionType + base { + address + symbol + decimals + } + } + } +`; + +const chainToSubgraph = { + ethereum: sdk.graph.modifyEndpoint( + 'CqWfkgRsJRrQ5vWq9tkEr68F5nvbAg63ati5SVJQLjK8' + ), + arbitrum: sdk.graph.modifyEndpoint( + '3o6rxHKuXZdy8jFifV99gMUe8FaVUL8w8bDTNdc4zyYg' + ), + fantom: sdk.graph.modifyEndpoint( + '5ahtXN7DVTwnPuDhWqgJWvEeAEP3JD7h2kD1Kpe67VuW' + ), + optimism: sdk.graph.modifyEndpoint( + '8wMexS8BB1cXWYu2V8cPHURGXSRGDBhshnU9nTiSkXQ7' + ), +}; + +interface PoolType { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; + apyBaseInception?: number; +} + +async function fetchChainPools( + url: string, + chain: string, + price: number +): Promise { + const { pools } = await request(url, getPoolsQuery); + const chainRewardData = await getChainRewardData(chain); + return await Promise.all( + pools.map( + async (pool) => await convert(pool, chain, chainRewardData, price) + ) + ); +} + +async function getPREMIAPrice() { + const PREMIA_PRICE = await getPrices( + [PREMIA_TOKEN_ADDRESS['ethereum']], + 'ethereum' + ); + return PREMIA_PRICE.pricesBySymbol.premia; +} + +async function poolsFunction(): Promise { + const PRICE = await getPREMIAPrice(); + const pools = await Promise.allSettled( + Object.keys(chainToSubgraph).map(async (chain) => + fetchChainPools(chainToSubgraph[chain], chain, PRICE) + ) + ); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat(); +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.premia.finance/options', +}; diff --git a/src/adaptors/premia-v2/utils.ts b/src/adaptors/premia-v2/utils.ts new file mode 100644 index 0000000000..025c019ab6 --- /dev/null +++ b/src/adaptors/premia-v2/utils.ts @@ -0,0 +1,167 @@ +const { + utils: { formatUnits, formatEther }, +} = require('ethers'); +const ContractAbi = require('./abi'); +const sdk = require('@defillama/sdk'); +const { + PREMIA_MINING_CONTRACT_ADDRESS, + PREMIA_TOKEN_ADDRESS, +} = require('./addresses'); + +export interface PoolType { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; + apyBaseInception?: number; +} + +export interface Token { + address: string; + symbol: string; + decimals: number; +} + +interface FetchedPool { + id: string; + name: string; + address: string; + netSizeInUsd: string; + openInterestInUsd: string; + underlying: Token; + profitLossPercentage: string; + totalLocked: string; + optionType: 'CALL' | 'PUT'; + netSize: string; + base: Token; + annualPercentageReturn: string; +} + +export interface PoolInfo { + allocPoint: string; +} + +const isCall = (value: string) => { + return value === 'CALL'; +}; + +const weiToNumber = (value: string) => { + if (!value) return 0; + return Number(formatEther(value)); +}; + +const getCall = async (chain, method, params = []) => + await sdk.api.abi.call({ + chain, + target: PREMIA_MINING_CONTRACT_ADDRESS[chain], + abi: ContractAbi.find((e) => e.name === method), + params, + }); + +async function getChainRewardData(chain) { + const result = await Promise.all([ + getCall(chain, 'getPremiaPerYear'), + getCall(chain, 'getTotalAllocationPoints'), + ]); + + return { + premiaPerYear: result[0].output, + totalAllocations: result[1].output, + }; +} + +async function getPoolRewardInfo(chain, pool): Promise { + const result = await getCall(chain, 'getPoolInfo', [ + pool.address, + isCall(pool.optionType), + ]); + + return { + allocPoint: result.output.allocPoint as string, + }; +} + +interface CalcAPYParam { + premiaPerYear: BigNumber; + totalAllocations: BigNumber; + poolInfo: PoolInfo; + premiaPrice: number; + pool: FetchedPool; +} + +function calcRewardAPY({ + premiaPerYear, + totalAllocations, + poolInfo, + premiaPrice, + pool, +}: CalcAPYParam): number { + const { netSizeInUsd } = pool; + const { allocPoint } = poolInfo; + const _totalAllocations = Number(formatUnits(totalAllocations, 0)); + const _allocPoints = Number(formatUnits(allocPoint, 0)); + const _premiaPerYear = Number(formatUnits(premiaPerYear, 18)); + const premiaPerYearToThisPool = + (_allocPoints / _totalAllocations) * _premiaPerYear; + if (!netSizeInUsd || !_totalAllocations) { + return 0; + } + const USDValueOfYearlyPoolRewards = premiaPerYearToThisPool * premiaPrice; + + const poolAPY = + (USDValueOfYearlyPoolRewards / Number(formatEther(netSizeInUsd))) * 100; + + if (poolAPY) { + return Number(poolAPY.toFixed(2)); + } + return 0; +} + +async function convert( + fetchedPool: FetchedPool, + chain: string, + chainRewardData, + price: number +): PoolType { + const { name, netSizeInUsd, underlying, id, annualPercentageReturn } = + fetchedPool; + const poolReward = await getPoolRewardInfo(chain, fetchedPool); + const rewardAPY = await calcRewardAPY({ + ...chainRewardData, + poolInfo: poolReward, + pool: fetchedPool, + premiaPrice: price, + }); + + return { + chain, + pool: id, + poolMeta: name, + underlyingTokens: [underlying.address], + apyReward: rewardAPY, + rewardTokens: [PREMIA_TOKEN_ADDRESS[chain]], + tvlUsd: weiToNumber(netSizeInUsd), + project: 'premia-v2', + symbol: underlying.symbol, + apyBase: weiToNumber(annualPercentageReturn), + apyBaseInception: weiToNumber(annualPercentageReturn), + }; +} + +module.exports = { + calcRewardAPY, + convert, + getChainRewardData, +}; diff --git a/src/adaptors/prime-protocol/index.js b/src/adaptors/prime-protocol/index.js new file mode 100644 index 0000000000..2cd2a580c3 --- /dev/null +++ b/src/adaptors/prime-protocol/index.js @@ -0,0 +1,491 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); +const utils = require('../utils'); + +// interface PoolType { +// pool: string; +// chain: string; +// project: string; +// symbol: string; +// tvlUsd: number; +// apyBase?: number; +// apyReward?: number; +// rewardTokens?: Array; +// underlyingTokens?: Array; +// poolMeta?: string; +// url?: string; +// apyBaseBorrow?: number; +// apyRewardBorrow?: number; +// totalSupplyUsd?: number; +// totalBorrowUsd?: number; +// ltv?: number; +// apyBaseInception?: number; +// } + +const projectSlug = 'prime-protocol'; + +const primeSubgraphUrl = sdk.graph.modifyEndpoint( + '6LrvPGTZeMZfEQh4p9DvDBBv4G8cjhLs4v3mdiUycERp' +); + +const primeRewardMarketsQuery = gql` + { + rewardAssets { + id + market { + address + totalBorrows + totalBorrowsUSD + totalDeposits + totalDepositsUSD + rewards { + rewardAssetAddress + depositRewardRatePerDay + borrowRewardRatePerDay + } + chainId + } + } + } +`; + +const primeAllMarketsQuery = gql` + { + markets { + address + totalBorrows + totalBorrowsUSD + totalDeposits + totalDepositsUSD + chainId + } + } +`; + +const FACTOR_DECIMALS = 8; + +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +const CHAIN_ID_TO_NETWORK = { + 1284: 'moonbeam', + 43114: 'avax', + 42161: 'arbitrum', + 1: 'ethereum', + 56: 'bsc', + 137: 'polygon', +}; + +const NETWORK_TO_NETWORK_TOKEN_SYMBOL = { + moonbeam: 'GLMR', + avax: 'AVAX', + arbitrum: 'ETH', + ethereum: 'ETH', + bsc: 'BNB', + polygon: 'MATIC', +}; + +const PRIME_CONTRACTS = { + MASTER_VIEW_v1_4_6: { + address: '0x47ecFB57deD0160d66103A6A201C5f30f7CC7d13', + abi: { + calculateAssetTVL: + 'function calculateRawAssetTVL(uint256 chainId, address pToken) view returns (uint256)', + }, + }, + MASTER_VIEW_v1_10_2: { + address: '0x30095B6616eB637B72f86E9613cdAcF18C11ED8d', + abi: { + getCollateralFactors: + 'function getCollateralFactors(address[] memory underlyings, uint256[] memory chainIds) view returns (uint256[] memory collateralFactors)', + }, + }, + IRM_ROUTER_v1_10_2: { + address: '0xd7af46089C5ED25871b770F18a2Ff1C07929abfa', + abi: { + borrowInterestRatePerBlock: + 'function borrowInterestRatePerBlock(address loanAsset, uint256 loanAssetChainId) view returns (uint256)', + }, + }, + PTOKEN_v1_10_2: { + abi: { + underlying: 'function underlying() view returns (address)', + }, + }, + MASTER_VIEW_v1_10_3: { + address: '0x9Ee26206Bc1143668aD56498b8C7A621bFa27c00', + abi: { + supplierInterestRateWithoutTuple: + 'function supplierInterestRateWithoutTuple(uint256 chainId, address loanAsset) view returns (uint256 rate, uint256 factor)', + }, + }, +}; + +const getTokenPrice = async (tokenAddress, network) => { + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${network}:${tokenAddress}` + ); + + return Number(data.coins[Object.keys(data.coins)[0]].price); +}; + +const getRewardPool = async (chain, network, market, reward) => { + const underlyingAddress = ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.PTOKEN_v1_10_2.abi.underlying, + calls: [market.address].map((address) => ({ + target: address, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output)[0]; + + let symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: [underlyingAddress].map((token) => ({ + target: token, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output)[0]; + + if (underlyingAddress === ZERO_ADDRESS) + symbol = NETWORK_TO_NETWORK_TOKEN_SYMBOL[network]; + + let underlyingDecimals = Number( + ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: [underlyingAddress].map((token) => ({ + target: token, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output) + ); + + if (!underlyingDecimals) underlyingDecimals = 18; + + let rewardDecimals = Number( + ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: [reward.rewardAssetAddress].map((r) => ({ + target: r, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output) + ); + + if (!rewardDecimals) rewardDecimals = 18; + + let tvlUsd = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_4_6.abi.calculateAssetTVL, + calls: [market].map((m) => ({ + params: [m.chainId, m.address], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_4_6.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => o.output)[0] + ); + + tvlUsd *= 10 ** underlyingDecimals / 10 ** 18; + + const apyBase = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_10_3.abi + .supplierInterestRateWithoutTuple, + calls: [market].map((m) => ({ + params: [m.chainId, m.address], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_10_3.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => { + const [rate, factor] = o.output; + return (Number(rate) * 2336000 * 100) / 10 ** Number(factor); + }) + ); + + const apyBaseBorrow = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.IRM_ROUTER_v1_10_2.abi.borrowInterestRatePerBlock, + calls: [market].map((m) => ({ + params: [m.address, m.chainId], + target: PRIME_CONTRACTS.IRM_ROUTER_v1_10_2.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => { + const borrowInterestRatePerBlock = o.output; + return (borrowInterestRatePerBlock * 2336000 * 100) / 1e18; + }) + ); + + let ltv = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_10_2.abi.getCollateralFactors, + calls: [market].map((m) => ({ + params: [[underlyingAddress], [m.chainId]], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_10_2.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => o.output)[0][0] + ); + + ltv /= 10 ** FACTOR_DECIMALS; + + const apyReward = + ((Number(reward.depositRewardRatePerDay) * + (await getTokenPrice(reward.rewardAssetAddress, network))) / + (Number(market.totalDepositsUSD) * 10 ** rewardDecimals)) * + Number(365) * + 1e2; + const apyRewardBorrow = + ((Number(reward.borrowRewardRatePerDay) * + (await getTokenPrice(reward.rewardAssetAddress, network))) / + (Number(market.totalBorrowsUSD) * 10 ** rewardDecimals)) * + Number(365) * + 1e2; + + const totalSupplyUsd = Number(market.totalDepositsUSD); + const totalBorrowUsd = Number(market.totalBorrowsUSD); + + return { + pool: `${network.toUpperCase() ?? 'NETWORK_NOT_FOUND'}-${ + market.address ?? 'MARKET_NOT_FOUND' + }-${reward.rewardAssetAddress ?? 'REWARD_ASSET_ADDRESS_NOT_FOUND'}`, + chain: network ?? 'CHAIN_NOT_FOUND', + project: projectSlug ?? 'PROJECT_NOT_FOUND', + symbol: symbol ?? 'SYMBOL_NOT_FOUND', + tvlUsd: totalSupplyUsd - totalBorrowUsd ?? 0, + apyBase: apyBase ?? 0, + apyBaseBorrow: apyBaseBorrow ?? 0, + apyReward: apyReward ?? 0, + apyRewardBorrow: apyRewardBorrow ?? 0, + rewardTokens: [ + reward.rewardAssetAddress ?? 'REWARD_ASSET_ADDRESS_NOT_FOUND', + ], + underlyingTokens: [underlyingAddress ?? 'UNDERLYING_TOKENS_NOT_FOUND'], + url: 'https://app.primeprotocol.xyz/', + ltv: ltv ?? 0, + totalSupplyUsd: totalSupplyUsd ?? 0, + totalBorrowUsd: totalBorrowUsd ?? 0, + }; +}; + +const getPool = async (chain, network, market) => { + const underlyingAddress = ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.PTOKEN_v1_10_2.abi.underlying, + calls: [market.address].map((address) => ({ + target: address, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output)[0]; + + let symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: [underlyingAddress].map((token) => ({ + target: token, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output)[0]; + + if (underlyingAddress === ZERO_ADDRESS) + symbol = NETWORK_TO_NETWORK_TOKEN_SYMBOL[network]; + + let underlyingDecimals = Number( + ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: [underlyingAddress].map((token) => ({ + target: token, + })), + permitFailure: true, + chain: network, + }) + ).output.map((o) => o.output) + ); + + if (!underlyingDecimals) underlyingDecimals = 18; + + let tvlUsd = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_4_6.abi.calculateAssetTVL, + calls: [market].map((m) => ({ + params: [m.chainId, m.address], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_4_6.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => o.output)[0] + ); + + tvlUsd *= 10 ** underlyingDecimals / 10 ** 18; + + const apyBase = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_10_3.abi + .supplierInterestRateWithoutTuple, + calls: [market].map((m) => ({ + params: [m.chainId, m.address], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_10_3.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => { + const [rate, factor] = o.output; + return (Number(rate) * 2336000 * 100) / 10 ** Number(factor); + }) + ); + + const apyBaseBorrow = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.IRM_ROUTER_v1_10_2.abi.borrowInterestRatePerBlock, + calls: [market].map((m) => ({ + params: [m.address, m.chainId], + target: PRIME_CONTRACTS.IRM_ROUTER_v1_10_2.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => { + const borrowInterestRatePerBlock = o.output; + return (borrowInterestRatePerBlock * 2336000 * 100) / 1e18; + }) + ); + + let ltv = Number( + ( + await sdk.api.abi.multiCall({ + abi: PRIME_CONTRACTS.MASTER_VIEW_v1_10_2.abi.getCollateralFactors, + calls: [market].map((m) => ({ + params: [[underlyingAddress], [m.chainId]], + target: PRIME_CONTRACTS.MASTER_VIEW_v1_10_2.address, + })), + permitFailure: true, + chain, + }) + ).output.map((o) => o.output)[0][0] + ); + + ltv /= 10 ** FACTOR_DECIMALS; + + const totalSupplyUsd = Number(market.totalDepositsUSD ?? 0); + const totalBorrowUsd = Number(market.totalBorrowsUSD ?? 0); + + return { + pool: `${network.toUpperCase() ?? 'NETWORK_NOT_FOUND'}-${ + market.address ?? 'MARKET_NOT_FOUND' + }`, + chain: network ?? 'CHAIN_NOT_FOUND', + project: projectSlug ?? 'PROJECT_NOT_FOUND', + symbol: symbol ?? 'SYMBOL_NOT_FOUND', + tvlUsd: totalSupplyUsd - totalBorrowUsd ?? 0, + apyBase: apyBase ?? 0, + apyBaseBorrow: apyBaseBorrow ?? 0, + underlyingTokens: [underlyingAddress ?? 'UNDERLYING_TOKENS_NOT_FOUND'], + url: 'https://app.primeprotocol.xyz/', + ltv: ltv ?? 0, + totalSupplyUsd: totalSupplyUsd ?? 0, + totalBorrowUsd: totalBorrowUsd ?? 0, + }; +}; + +const addRewardMarketPools = async (pools) => { + const primeRewardMarketsData = await request( + primeSubgraphUrl, + primeRewardMarketsQuery + ); + + for (let ra = 0; ra < primeRewardMarketsData.rewardAssets.length; ra++) { + const market = primeRewardMarketsData.rewardAssets[ra].market; + + for (let r = 0; r < market.rewards.length; r++) { + console.log( + `\nmarket(${market.address})-reward(${market.rewards[r].rewardAssetAddress})` + ); + + pools.push( + await getRewardPool( + 'moonbeam', + CHAIN_ID_TO_NETWORK[market.chainId], + market, + market.rewards[r] + ) + ); + } + } +}; + +const addAllMarketPools = async (pools) => { + const primeAllMarketsData = await request( + primeSubgraphUrl, + primeAllMarketsQuery + ); + + for (let m = 0; m < primeAllMarketsData.markets.length; m++) { + const market = primeAllMarketsData.markets[m]; + + console.log(`\nmarket(${market.address})`); + + let marketAlreadyAdded = false; + + pools.forEach((pool) => { + if (pool.pool.split('-')[1] == market.address) marketAlreadyAdded = true; + }); + + if (marketAlreadyAdded) continue; + + try { + pools.push( + await getPool('moonbeam', CHAIN_ID_TO_NETWORK[market.chainId], market) + ); + } catch (err) { + console.log(market); + } + } +}; + +const apy = async () => { + const pools = []; + + await addRewardMarketPools(pools); + await addAllMarketPools(pools); + + return pools; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.primeprotocol.xyz/', +}; diff --git a/src/adaptors/prime-staked-eth/index.js b/src/adaptors/prime-staked-eth/index.js new file mode 100644 index 0000000000..5846b995ba --- /dev/null +++ b/src/adaptors/prime-staked-eth/index.js @@ -0,0 +1,50 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils.js'); + +const PRIME_ETH = '0x6ef3D766Dfe02Dc4bF04aAe9122EB9A0Ded25615'; +const LRT_ORACLE = '0xA755c18CD2376ee238daA5Ce88AcF17Ea74C1c32'; + +const apy = async () => { + const totalSupply = await sdk.api.abi.call({ + abi: 'uint:totalSupply', + target: PRIME_ETH, + }); + // primeETH/ETH price + const primeEthPrice = await sdk.api.abi.call({ + abi: 'uint:primeETHPrice', + target: LRT_ORACLE, + }); + const priceData = await utils.getData( + 'https://coins.llama.fi/prices/current/coingecko:ethereum?searchWidth=4h' + ); + const ethPrice = priceData.coins['coingecko:ethereum'].price; + const tvlUsd = + ((totalSupply.output * primeEthPrice.output) / 1e36) * ethPrice; + + const { data } = await axios.get( + 'https://api.originprotocol.com/api/v2/primestaked' + ); + + const primeStaked = { + pool: '0x6ef3D766Dfe02Dc4bF04aAe9122EB9A0Ded25615-ethereum'.toLowerCase(), + chain: 'Ethereum', + project: 'prime-staked-eth', + symbol: 'primeETH', + apy: data.apy, + tvlUsd, + underlyingTokens: [ + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + '0x0000000000000000000000000000000000000000', + '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3', + ], + }; + + return [primeStaked]; +}; +module.exports = { + timetravel: false, + apy, + url: 'https://www.primestaked.com', +}; diff --git a/src/adaptors/primex-finance/abi.js b/src/adaptors/primex-finance/abi.js new file mode 100644 index 0000000000..78aa5c6039 --- /dev/null +++ b/src/adaptors/primex-finance/abi.js @@ -0,0 +1,564 @@ +const abi = { + getAllBucketsFactory: { + inputs: [ + { + internalType: 'address[]', + name: '_bucketFactories', + type: 'address[]', + }, + { + internalType: 'address', + name: '_user', + type: 'address', + }, + { + internalType: 'address', + name: '_positionManager', + type: 'address', + }, + { + internalType: 'bool', + name: '_showDeprecated', + type: 'bool', + }, + { + internalType: 'uint256', + name: '_cursor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_count', + type: 'uint256', + }, + ], + name: 'getAllBucketsFactory', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'bucketAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + components: [ + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.TokenMetadata', + name: 'asset', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'bar', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'lar', + type: 'uint128', + }, + { + internalType: 'uint256', + name: 'supply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'demand', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'utilizationRatio', + type: 'uint256', + }, + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.TokenMetadata', + name: 'asset', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isSupported', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'pairPriceDrop', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxLeverage', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.BucketTokenMetadata', + name: 'properties', + type: 'tuple', + }, + ], + internalType: 'struct IPrimexLens.SupportedAsset[]', + name: 'supportedAssets', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.TokenMetadata', + name: 'pToken', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.TokenMetadata', + name: 'debtToken', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'feeBuffer', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawalFeeRate', + type: 'uint256', + }, + { + components: [ + { + internalType: 'contract ILiquidityMiningRewardDistributor', + name: 'liquidityMiningRewardDistributor', + type: 'address', + }, + { + internalType: 'bool', + name: 'isBucketLaunched', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'accumulatingAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadlineTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stabilizationDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stabilizationEndTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxAmountPerUser', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxStabilizationEndTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct IBucketStorage.LiquidityMiningParams', + name: 'miningParams', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'amountInMining', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentPercent', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'minReward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxReward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'extraReward', + type: 'uint256', + }, + ], + internalType: + 'struct ILiquidityMiningRewardDistributor.RewardsInPMX', + name: 'rewardsInPMX', + type: 'tuple', + }, + ], + internalType: 'struct IPrimexLens.LenderInfo', + name: 'lenderInfo', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'pmxAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawnRewards', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalPoints', + type: 'uint256', + }, + ], + internalType: 'struct IPrimexLens.LiquidityMiningBucketInfo', + name: 'lmBucketInfo', + type: 'tuple', + }, + { + internalType: 'uint128', + name: 'estimatedBar', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'estimatedLar', + type: 'uint128', + }, + { + internalType: 'bool', + name: 'isDeprecated', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isDelisted', + type: 'bool', + }, + { + components: [ + { + internalType: 'uint256', + name: 'urOptimal', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'k0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'k1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'b0', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'b1', + type: 'int256', + }, + ], + internalType: 'struct IInterestRateStrategy.BarCalculationParams', + name: 'barCalcParams', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'maxTotalDeposit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + internalType: 'enum IPrimexDNSStorage.Status', + name: 'currentStatus', + type: 'uint8', + }, + ], + internalType: 'struct IPrimexLensPart2.BucketMetaDataPart2[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + + stateMutability: 'view', + type: 'function', + }, + activityRewardDistributorBuckets: { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'buckets', + outputs: [ + { + internalType: 'uint256', + name: 'rewardIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdatedTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardPerToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'scaledTotalSupply', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isFinished', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'fixedReward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastUpdatedRewardTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rewardPerDay', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalReward', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'endTimestamp', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getChainlinkLatestRoundData: { + inputs: [ + { + internalType: 'address[]', + name: '_feeds', + type: 'address[]', + }, + ], + name: 'getChainlinkLatestRoundData', + outputs: [ + { + components: [ + { + internalType: 'uint80', + name: 'roundId', + type: 'uint80', + }, + { + internalType: 'int256', + name: 'answer', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'startedAt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAt', + type: 'uint256', + }, + { + internalType: 'uint80', + name: 'answeredInRound', + type: 'uint80', + }, + ], + internalType: 'struct IPrimexLens.RoundData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +module.exports = { abi }; diff --git a/src/adaptors/primex-finance/index.js b/src/adaptors/primex-finance/index.js new file mode 100644 index 0000000000..dc2b0d0d48 --- /dev/null +++ b/src/adaptors/primex-finance/index.js @@ -0,0 +1,170 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { abi } = require('./abi'); +const { ethers } = require('ethers'); +const utils = require('../utils'); +const { + CHAIN_IDS, + DEAD_ADDRESS, + ROLES, + SECONDS_PER_YEAR, + APY_REWARD_BONUS, + config, + addressEq, + getPoolUrl, +} = require('./utils'); + +const formatPool = async (bucket, config) => { + const { + bucketAddress, + asset, + supportedAssets, + supply, + demand, + bar, + lar, + estimatedBar, + estimatedLar, + miningParams, + name, + } = bucket; + + const { chain, EPMX, USDCE, apyRewardBySymbol } = config; + + const symbol = addressEq(asset?.tokenAddress, USDCE) + ? 'USDC.E' + : asset?.symbol; + const underlyingTokens = [asset?.tokenAddress]; + + const priceKeys = underlyingTokens + .map((t) => `${chain.toLowerCase()}:${t}`) + .join(','); + + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).body.coins; + + const assetPrice = prices[`${chain.toLowerCase()}:${asset?.tokenAddress}`]; + const totalSupplyUsd = + (supply / 10 ** assetPrice?.decimals) * assetPrice?.price; + const totalBorrowUsd = + (demand / 10 ** assetPrice?.decimals) * assetPrice?.price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const isMiningPhase = + !miningParams?.isBucketLaunched && + miningParams?.deadlineTimestamp * 1000 > Date.now(); + + const apyBaseCalculated = + (Math.pow(1 + lar / 10 ** 27 / SECONDS_PER_YEAR, SECONDS_PER_YEAR) - 1) * + 100; + const apyBase = isMiningPhase ? 0 : apyBaseCalculated; + + const apyBaseBorrowCalculated = + (Math.pow(1 + bar / 10 ** 27 / SECONDS_PER_YEAR, SECONDS_PER_YEAR) - 1) * + 100; + const apyBaseBorrow = isMiningPhase ? 0 : apyBaseBorrowCalculated; + const apyReward = isMiningPhase ? APY_REWARD_BONUS : 0; + const apyRewardBorrow = 0; + + return { + pool: `${bucketAddress}-${chain}`.toLowerCase(), + chain, + project: 'primex-finance', + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + url: getPoolUrl(bucketAddress, chain), + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + }; +}; + +const getPools = async (config) => { + const { + chain, + lensAddress, + bucketsFactory, + positionManager, + } = config; + + if (chain === 'Ethereum') { + sdk.api.config.setProvider( + 'ethereum', + new ethers.providers.JsonRpcProvider( + "https://lb.drpc.org/ogrpc?network=ethereum&dkey=AhjAIUax7EMFtu9ErxcXVpjOZcogyegR77I1IlZWwHzR" + ) + ); + } + + if (chain === 'Base') { + sdk.api.config.setProvider( + 'base', + new ethers.providers.JsonRpcProvider( + 'https://lb.drpc.org/ogrpc?network=base&dkey=AhjAIUax7EMFtu9ErxcXVpjOZcogyegR77I1IlZWwHzR' + ) + ); + } + let bucketsArr = []; + let offset = 0; + const limit = 3; + + while (true) { + try { + const result = ( + await sdk.api.abi.call({ + abi: abi.getAllBucketsFactory, + target: lensAddress, + chain: chain.toLowerCase(), + params: [ + bucketsFactory, + DEAD_ADDRESS, + positionManager, + false, + offset, + limit, + ], + }) + ).output; + + if (result[0].length !== 0) { + bucketsArr = bucketsArr.concat(result[0]); + } + + if (result[1] === '0') { + break; + } + + offset += limit; + } catch (error) { + console.error(error); + break; + } + } + + return await Promise.all( + bucketsArr + .filter((bucket) => { + const miningParams = bucket.miningParams; + const isMiningFailed = + !miningParams?.isBucketLaunched && + miningParams?.deadlineTimestamp * 1000 <= Date.now(); + return !isMiningFailed; + }) + .map((b) => formatPool(b, config)) + ); +}; + +const getApy = async () => { + const pools = (await Promise.all(config.map((c) => getPools(c)))).flat(); + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/primex-finance/utils.js b/src/adaptors/primex-finance/utils.js new file mode 100644 index 0000000000..6f62dc4db2 --- /dev/null +++ b/src/adaptors/primex-finance/utils.js @@ -0,0 +1,85 @@ +const DEAD_ADDRESS = '0x000000000000000000000000000000000000dEaD'; +const SECONDS_PER_YEAR = 31536000; + +const ROLES = { + LENDER: 0, + TRADER: 1, +}; + +const CHAIN_IDS = { + Ethereum: 'ethereum', + Arbitrum: 'arbitrum_one', + Polygon: 'polygon_mainnet', + Base: 'base', +}; + +const APY_REWARD_BONUS = 7; + +const config = [ + { + chain: 'Base', + lensAddress: '0x636177fa2629927500f0d7946b46d6275d2b01d2', + bucketsFactory: [ + '0xcf552c38a0ecb51982af28d4e475bef27ac2dd25', + '0x8e8792881227e8fee8a9e05a567a44d3fa04a7f0', + ], + positionManager: '0x01ed183275956dbd0064b789b778ca0921e695e9', + }, + { + chain: 'Polygon', + lensAddress: '0xfd5BB42E9B647d316c9c0356D368F09505D0F584', + bucketsFactory: [ + '0x7E6915D307F434E4171cCee90e180f5021c60089', + '0x9649CfDCfAa9c80907e63dD9Cb161cBA2033F3A0', + ], + positionManager: '0x02bcaA4633E466d151b34112608f60A82a4F6035', + USDCE: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + EPMX: '0xDc6D1bd104E1efa4A1bf0BBCf6E0BD093614E31A', + EPMXPriceFeed: '0x103A9FF33c709405DF58f8f209C53f6B5c5eA2BE', + EPMXPriceFeedDecimals: 8, + }, + { + chain: 'Arbitrum', + lensAddress: '0xa057c1464dD31B3Aacf72Ef3470E0dA9548e551f', + bucketsFactory: [ + '0x4e6f7372bCE4083c779c17B240A94dc2EA57AE67', + '0xB4d3A9f10D3D687FaF3b05b9aa3054856A1d7be8', + ], + positionManager: '0x86890E30cE9E1e13Db5560BbEb435c55567Af1cd', + USDCE: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + EPMX: '0xA533f744B179F2431f5395978e391107DC76e103', + EPMXPriceFeed: '0x053FB5b7c555FC0d9Bc49118023d6B6A4019168f', + EPMXPriceFeedDecimals: 8, + }, + { + chain: 'Ethereum', + lensAddress: '0xa5b9Fc7038d5e3b054249cf89A065b3Bb15D0d28', + bucketsFactory: [ + '0x7dE8607157124c894Ba9F18dd6138B5E8AAd5890', + '0x55120da310A0c5fd81Fd3bb8C177F6649bE30ACc', + ], + positionManager: '0x99d63fEA4b3Ef6ca77941df3C5740dAd1586f0B8', + EPMX: '0xA533f744B179F2431f5395978e391107DC76e103', + EPMXPriceFeed: '0xF146a76F3Aa82D4cEa3eaB44932b7eE75737E11a', + EPMXPriceFeedDecimals: 8, + }, +]; + +const getPoolUrl = (address, chain) => + `https://app.primex.finance/#/bucket-details/${address}?network=${CHAIN_IDS[chain]}`; + +const addressEq = (addressA, addressB) => { + if (!addressA || !addressB) return false; + return addressA.toLowerCase() === addressB.toLowerCase(); +}; + +module.exports = { + DEAD_ADDRESS, + SECONDS_PER_YEAR, + ROLES, + CHAIN_IDS, + APY_REWARD_BONUS, + config, + getPoolUrl, + addressEq, +}; diff --git a/src/adaptors/prismalst/factoryAbi.json b/src/adaptors/prismalst/factoryAbi.json new file mode 100644 index 0000000000..d53b5699c5 --- /dev/null +++ b/src/adaptors/prismalst/factoryAbi.json @@ -0,0 +1,238 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_prismaCore", "type": "address" }, + { + "internalType": "contract IDebtToken", + "name": "_debtToken", + "type": "address" + }, + { + "internalType": "contract IStabilityPool", + "name": "_stabilityPool", + "type": "address" + }, + { + "internalType": "contract IBorrowerOperations", + "name": "_borrowerOperations", + "type": "address" + }, + { "internalType": "address", "name": "_sortedTroves", "type": "address" }, + { "internalType": "address", "name": "_troveManager", "type": "address" }, + { + "internalType": "contract ILiquidationManager", + "name": "_liquidationManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "collateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "priceFeed", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "troveManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "sortedTroves", + "type": "address" + } + ], + "name": "NewDeployment", + "type": "event" + }, + { + "inputs": [], + "name": "PRISMA_CORE", + "outputs": [ + { "internalType": "contract IPrismaCore", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowerOperations", + "outputs": [ + { + "internalType": "contract IBorrowerOperations", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtToken", + "outputs": [ + { "internalType": "contract IDebtToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "collateral", "type": "address" }, + { "internalType": "address", "name": "priceFeed", "type": "address" }, + { + "internalType": "address", + "name": "customTroveManagerImpl", + "type": "address" + }, + { + "internalType": "address", + "name": "customSortedTrovesImpl", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "minuteDecayFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redemptionFeeFloor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxRedemptionFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowingFeeFloor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxBorrowingFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestRateInBps", + "type": "uint256" + }, + { "internalType": "uint256", "name": "maxDebt", "type": "uint256" }, + { "internalType": "uint256", "name": "MCR", "type": "uint256" } + ], + "internalType": "struct Factory.DeploymentParams", + "name": "params", + "type": "tuple" + } + ], + "name": "deployNewInstance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationManager", + "outputs": [ + { + "internalType": "contract ILiquidationManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_troveManagerImpl", + "type": "address" + }, + { + "internalType": "address", + "name": "_sortedTrovesImpl", + "type": "address" + } + ], + "name": "setImplementations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sortedTrovesImpl", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stabilityPool", + "outputs": [ + { + "internalType": "contract IStabilityPool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "troveManagerCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "troveManagerImpl", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "troveManagers", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/prismalst/index.js b/src/adaptors/prismalst/index.js new file mode 100644 index 0000000000..e01b8219d4 --- /dev/null +++ b/src/adaptors/prismalst/index.js @@ -0,0 +1,133 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const factoryAbi = require('./factoryAbi.json'); +const troveManagerAbi = require('./troveManagerAbi.json'); + +const mkUsd = '0x4591DBfF62656E7859Afe5e45f6f47D3669fBB28'; // debt token +const prisma = '0xda47862a83dac0c112ba89c6abc2159b95afd71c'; // reward token +const factory = '0x70b66E20766b775B2E9cE5B718bbD285Af59b7E1'; + +const apy = async () => { + const troveManagerCount = ( + await sdk.api.abi.call({ + target: factory, + abi: factoryAbi.find((i) => i.name === 'troveManagerCount'), + }) + ).output; + + const troveManagers = ( + await sdk.api.abi.multiCall({ + calls: Array.from({ length: troveManagerCount }, (_, index) => index).map( + (i) => ({ target: factory, params: i }) + ), + abi: factoryAbi.find((i) => i.name === 'troveManagers'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const collateralTokens = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'collateralToken'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const balanceOf = ( + await sdk.api.abi.multiCall({ + calls: collateralTokens.map((t, i) => ({ + target: t, + params: troveManagers[i], + })), + abi: 'erc20:balanceOf', + permitFailure: true, + }) + ).output.map((i) => i.output); + + const MCR = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'MCR'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const systemDebt = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'getEntireSystemDebt'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const maxSystemDebt = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'maxSystemDebt'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'rewardRate'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const interestRate = ( + await sdk.api.abi.multiCall({ + calls: troveManagers.map((i) => ({ target: i })), + abi: troveManagerAbi.find((i) => i.name === 'interestRate'), + permitFailure: true, + }) + ).output.map((i) => i.output); + + const keys = [...collateralTokens, prisma] + .map((i) => `ethereum:${i}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${keys}`) + ).data.coins; + + return troveManagers.map((t, i) => { + const priceDetails = prices[`ethereum:${collateralTokens[i]}`]; + const tvlUsd = + (balanceOf[i] * priceDetails.price) / 10 ** priceDetails.decimals; + + const apyBaseBorrow = ((interestRate[i] * 86400 * 365) / 1e27) * 100; + + const apyRewardBorrow = + (((rewardRate[i] / 1e18) * + 86400 * + 365 * + prices[`ethereum:${prisma}`].price) / + tvlUsd) * + 100; + + return { + pool: t, + chain: 'ethereum', + project: 'prismalst', + symbol: priceDetails.symbol, + tvlUsd, + apy: 0, + mintedCoin: 'mkUsd', + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd: tvlUsd, + totalBorrowUsd: systemDebt[i] / 1e18, + debtCeilingUsd: maxSystemDebt[i] / 1e18, + ltv: 1 / Number(MCR[i] / 1e18), + url: `https://app.prismafinance.com/vaults/select/${t}`, + rewardTokens: apyRewardBorrow > 0 ? [prisma] : [], + underlyingTokens: [collateralTokens[i]], + }; + }); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/prismalst/troveManagerAbi.json b/src/adaptors/prismalst/troveManagerAbi.json new file mode 100644 index 0000000000..b8bf500ebc --- /dev/null +++ b/src/adaptors/prismalst/troveManagerAbi.json @@ -0,0 +1,1253 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_prismaCore", "type": "address" }, + { + "internalType": "address", + "name": "_gasPoolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_debtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_borrowerOperationsAddress", + "type": "address" + }, + { "internalType": "address", "name": "_vault", "type": "address" }, + { + "internalType": "address", + "name": "_liquidationManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasCompensation", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_baseRate", + "type": "uint256" + } + ], + "name": "BaseRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "CollateralSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_L_collateral", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_L_debt", + "type": "uint256" + } + ], + "name": "LTermsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_lastFeeOpTime", + "type": "uint256" + } + ], + "name": "LastFeeOpTimeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_attemptedDebtAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_actualDebtAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_collateralSent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_collateralFee", + "type": "uint256" + } + ], + "name": "Redemption", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed", + "type": "uint256" + } + ], + "name": "RewardClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_totalStakesSnapshot", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_totalCollateralSnapshot", + "type": "uint256" + } + ], + "name": "SystemSnapshotsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_newTotalStakes", + "type": "uint256" + } + ], + "name": "TotalStakesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newIndex", + "type": "uint256" + } + ], + "name": "TroveIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_L_collateral", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_L_debt", + "type": "uint256" + } + ], + "name": "TroveSnapshotsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_debt", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_coll", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_stake", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum TroveManager.TroveManagerOperation", + "name": "_operation", + "type": "uint8" + } + ], + "name": "TroveUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "BOOTSTRAP_PERIOD", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CCR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEBT_GAS_COMPENSATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DECIMAL_PRECISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L_collateral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "L_debt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_INTEREST_RATE_IN_BPS", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MCR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERCENT_DIVISOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRISMA_CORE", + "outputs": [ + { "internalType": "contract IPrismaCore", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUNSETTING_INTEREST_RATE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "Troves", + "outputs": [ + { "internalType": "uint256", "name": "debt", "type": "uint256" }, + { "internalType": "uint256", "name": "coll", "type": "uint256" }, + { "internalType": "uint256", "name": "stake", "type": "uint256" }, + { + "internalType": "enum TroveManager.Status", + "name": "status", + "type": "uint8" + }, + { "internalType": "uint128", "name": "arrayIndex", "type": "uint128" }, + { + "internalType": "uint256", + "name": "activeInterestIndex", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "accountLatestMint", + "outputs": [ + { "internalType": "uint32", "name": "amount", "type": "uint32" }, + { "internalType": "uint32", "name": "week", "type": "uint32" }, + { "internalType": "uint32", "name": "day", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "activeInterestIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "collSurplus", "type": "uint256" } + ], + "name": "addCollateralSurplus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "applyPendingRewards", + "outputs": [ + { "internalType": "uint256", "name": "coll", "type": "uint256" }, + { "internalType": "uint256", "name": "debt", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "baseRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowerOperationsAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowingFeeFloor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "claimCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "claimReward", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "claimableReward", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" }, + { "internalType": "uint256", "name": "collAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "debtAmount", "type": "uint256" } + ], + "name": "closeTrove", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "closeTroveByLiquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "collateralToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "collectInterests", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "dailyMintReward", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "debtToken", + "outputs": [ + { "internalType": "contract IDebtToken", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_debt", "type": "uint256" } + ], + "name": "decayBaseRateAndGetBorrowingFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "debt", "type": "uint256" }, + { "internalType": "uint256", "name": "coll", "type": "uint256" } + ], + "name": "decreaseDebtAndSendCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultedCollateral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "defaultedDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emissionId", + "outputs": [ + { "internalType": "uint16", "name": "debt", "type": "uint16" }, + { "internalType": "uint16", "name": "minting", "type": "uint16" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fetchPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_liquidator", "type": "address" }, + { "internalType": "uint256", "name": "_debt", "type": "uint256" }, + { "internalType": "uint256", "name": "_coll", "type": "uint256" }, + { "internalType": "uint256", "name": "_collSurplus", "type": "uint256" }, + { "internalType": "uint256", "name": "_debtGasComp", "type": "uint256" }, + { "internalType": "uint256", "name": "_collGasComp", "type": "uint256" } + ], + "name": "finalizeLiquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_debt", "type": "uint256" } + ], + "name": "getBorrowingFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_debt", "type": "uint256" } + ], + "name": "getBorrowingFeeWithDecay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBorrowingRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBorrowingRateWithDecay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "uint256", "name": "_price", "type": "uint256" } + ], + "name": "getCurrentICR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getEntireDebtAndColl", + "outputs": [ + { "internalType": "uint256", "name": "debt", "type": "uint256" }, + { "internalType": "uint256", "name": "coll", "type": "uint256" }, + { + "internalType": "uint256", + "name": "pendingDebtReward", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pendingCollateralReward", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEntireSystemBalances", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getEntireSystemColl", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEntireSystemDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getNominalICR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getPendingCollAndDebtRewards", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_collateralDrawn", + "type": "uint256" + } + ], + "name": "getRedemptionFeeWithDecay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRedemptionRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRedemptionRateWithDecay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalActiveCollateral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalActiveDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "week", "type": "uint256" } + ], + "name": "getTotalMints", + "outputs": [ + { "internalType": "uint32[7]", "name": "", "type": "uint32[7]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getTroveCollAndDebt", + "outputs": [ + { "internalType": "uint256", "name": "coll", "type": "uint256" }, + { "internalType": "uint256", "name": "debt", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_index", "type": "uint256" } + ], + "name": "getTroveFromTroveOwnersArray", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTroveOwnersCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getTroveStake", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "getTroveStatus", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWeek", + "outputs": [ + { "internalType": "uint256", "name": "week", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWeekAndDay", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "guardian", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" } + ], + "name": "hasPendingRewards", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestPayable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastActiveIndexUpdate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastCollateralError_Redistribution", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastDebtError_Redistribution", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastFeeOperationTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdate", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxBorrowingFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxRedemptionFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSystemDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minuteDecayFactor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_debt", "type": "uint256" }, + { "internalType": "uint256", "name": "_collateral", "type": "uint256" } + ], + "name": "movePendingTroveRewardsToActiveBalances", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_assignedIds", + "type": "uint256[]" + } + ], + "name": "notifyRegisteredId", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_borrower", "type": "address" }, + { + "internalType": "uint256", + "name": "_collateralAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_compositeDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "NICR", "type": "uint256" }, + { "internalType": "address", "name": "_upperHint", "type": "address" }, + { "internalType": "address", "name": "_lowerHint", "type": "address" }, + { "internalType": "bool", "name": "_isRecoveryMode", "type": "bool" } + ], + "name": "openTrove", + "outputs": [ + { "internalType": "uint256", "name": "stake", "type": "uint256" }, + { "internalType": "uint256", "name": "arrayIndex", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeed", + "outputs": [ + { "internalType": "contract IPriceFeed", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_debtAmount", "type": "uint256" }, + { + "internalType": "address", + "name": "_firstRedemptionHint", + "type": "address" + }, + { + "internalType": "address", + "name": "_upperPartialRedemptionHint", + "type": "address" + }, + { + "internalType": "address", + "name": "_lowerPartialRedemptionHint", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_partialRedemptionHintNICR", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxIterations", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxFeePercentage", + "type": "uint256" + } + ], + "name": "redeemCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "redemptionFeeFloor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardIntegral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardIntegralFor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardSnapshots", + "outputs": [ + { "internalType": "uint256", "name": "collateral", "type": "uint256" }, + { "internalType": "uint256", "name": "debt", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_priceFeedAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_sortedTrovesAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_collateralToken", + "type": "address" + } + ], + "name": "setAddresses", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minuteDecayFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_redemptionFeeFloor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxRedemptionFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowingFeeFloor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxBorrowingFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_interestRateInBPS", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxSystemDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_MCR", "type": "uint256" } + ], + "name": "setParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_priceFeedAddress", + "type": "address" + } + ], + "name": "setPriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sortedTroves", + "outputs": [ + { + "internalType": "contract ISortedTroves", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startSunset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sunsetting", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "surplusBalances", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "systemDeploymentTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalCollateralSnapshot", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStakes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStakesSnapshot", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateBalances", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_isRecoveryMode", "type": "bool" }, + { "internalType": "bool", "name": "_isDebtIncrease", "type": "bool" }, + { "internalType": "uint256", "name": "_debtChange", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_netDebtChange", + "type": "uint256" + }, + { "internalType": "bool", "name": "_isCollIncrease", "type": "bool" }, + { "internalType": "uint256", "name": "_collChange", "type": "uint256" }, + { "internalType": "address", "name": "_upperHint", "type": "address" }, + { "internalType": "address", "name": "_lowerHint", "type": "address" }, + { "internalType": "address", "name": "_borrower", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "updateTroveFromAdjustment", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { "internalType": "contract IPrismaVault", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "claimant", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "vaultClaimReward", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/psyoptions/index.js b/src/adaptors/psyoptions/index.js new file mode 100644 index 0000000000..e581576fef --- /dev/null +++ b/src/adaptors/psyoptions/index.js @@ -0,0 +1,49 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const BASE_URL = 'https://us-central1-psyfi-api.cloudfunctions.net/'; + +async function getVaultsData() { + const vaultResponse = await axios.get(BASE_URL + 'vaults'); + if (!vaultResponse) { + throw new Error('Unable to retrieve PsyFinance vaults from the api'); + } + + const performanceFeeRate = 0.1; + const withdrawalFeeRate = 0.001; + const vaults = []; + Object.values(vaultResponse.data.vaults).map(async (vaultInfo) => { + const currentWeekPerformance = + utils.apyToApr(vaultInfo.apy.currentEpochApy, 52) / 52; + const vault = { + pool: vaultInfo.id, + chain: utils.formatChain('solana'), + project: 'psyoptions', + symbol: vaultInfo.id.includes('put') + ? 'USDC' + : vaultInfo.id.split('-')[0].toUpperCase(), + poolMeta: vaultInfo.id.includes('call') + ? 'Covered Call' + : 'Cash Secured Put', + tvlUsd: + Number(vaultInfo.deposits.current) * + (vaultInfo.collateralTokenPrice?.value || 0), + apyBase: + vaultInfo.apy.currentEpochApy * + (1 - (performanceFeeRate + withdrawalFeeRate)) || 0, + il7d: currentWeekPerformance < 0 ? currentWeekPerformance : null, + }; + if (vaultInfo?.staking?.stakingApr[0]) { + vault.apyReward = vaultInfo.staking?.stakingApr[0]; + vault.rewardTokens = ['SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt']; + } + vaults.push(vault); + }); + return vaults; +} + +module.exports = { + timetravel: false, + apy: getVaultsData, + url: 'https://psyfi.io/vaults', +}; diff --git a/src/adaptors/qidao/index.js b/src/adaptors/qidao/index.js new file mode 100644 index 0000000000..210889685a --- /dev/null +++ b/src/adaptors/qidao/index.js @@ -0,0 +1,227 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const BIG_10 = new BigNumber(10); + +const utils = require('../utils'); +const { vaults, ChainId, FRONTEND } = require('./vaults'); + +const MAI_ID = 'mimatic'; +const url = 'https://api.mai.finance/v2/vaultIncentives'; +const qidao = '0xD694620D4621124F341951a2bae4C794baFD1723'; + +const VAULT = { + abis: { + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + iR: { + inputs: [], + name: 'iR', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getDebtCeiling: { + inputs: [], + name: 'getDebtCeiling', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + totalBorrowed: { + inputs: [], + name: 'totalBorrowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + _minimumCollateralPercentage: { + inputs: [], + name: '_minimumCollateralPercentage', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const chainIdMap = { + ethereum: 1, + optimism: 10, + polygon: 137, + metis: 1088, +}; + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; +const main = async () => { + const result = []; + const vaultIncentives = (await utils.getData(url)).incentives; + const incentives = Object.keys(vaultIncentives).flatMap( + (e) => vaultIncentives[e] + ); + + for (const [index, chain] of Object.keys(ChainId).entries()) { + const _vaultsInfo = vaults[ChainId[chain]].filter((e) => e.version === 2); + const _chain = ChainId[chain]; + const totalSupplys = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ vaultAddress }) => ({ + target: vaultAddress, + })), + abi: VAULT.abis.totalSupply, + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const iRs = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ vaultAddress }) => ({ + target: vaultAddress, + })), + abi: VAULT.abis.iR, + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const getDebtCeilings = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ vaultAddress }) => ({ + target: vaultAddress, + })), + abi: VAULT.abis.getDebtCeiling, + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const totalBorroweds = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ vaultAddress }) => ({ + target: vaultAddress, + })), + abi: VAULT.abis.totalBorrowed, + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const balances = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ token, vaultAddress }) => ({ + target: token.address, + params: [vaultAddress], + })), + abi: 'erc20:balanceOf', + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const ltv = ( + await sdk.api.abi.multiCall({ + calls: _vaultsInfo.map(({ token, vaultAddress }) => ({ + target: vaultAddress, + params: null, + })), + abi: VAULT.abis._minimumCollateralPercentage, + chain: _chain, + requery: true, + }) + ).output.map((x) => x.output); + + const coins_address = _vaultsInfo.map( + (e) => `${_chain}:${e.token.address}` + ); + const coins_id = [MAI_ID].map((e) => `coingecko:${e}`); + const prices = (await utils.getPrices([...coins_address, ...coins_id])) + .pricesByAddress; + const _incentive = incentives.filter( + (e) => Number(e.chainId) === chainIdMap[_chain] + ); + + const _result = _vaultsInfo.map((e, index) => { + const tvlUsd = new BigNumber(balances[index]) + .div(BIG_10.pow(e.token.decimals)) + .times(prices[e.token.address.toLowerCase()]); + const debtCeilingUsd = new BigNumber(getDebtCeilings[index]) + .div(BIG_10.pow(18)) + .times(prices[MAI_ID.toLowerCase()]); + + const totalBorrowUsd = new BigNumber(totalBorroweds[index]) + .div(BIG_10.pow(18)) + .times(prices[MAI_ID.toLowerCase()]); + + const apyCall = _incentive.find( + (x) => x.vaultAddress.toLowerCase() === e.vaultAddress.toLowerCase() + ); + + const rewardTokens = [qidao]; + let apyRewardBorrow = Number(apyCall?.apr || '0'); + if (_chain === 'metis' && apyCall?.extraRewards?.length > 0) { + const rewards = apyCall?.extraRewards[0]; + apyRewardBorrow += Number(rewards?.apr || '0'); + rewardTokens.push(rewards?.address); + } + + const symbol = e.token.symbol; + + return { + pool: `${e.vaultAddress}-${_chain}`, + project: 'qidao', + symbol: symbol === 'yvcurve-eth-steth' ? 'eth-steth' : symbol, + poolMeta: symbol === 'yvcurve-eth-steth' ? 'Curve' : null, + chain: _chain, + apy: 0, + tvlUsd: tvlUsd.toNumber(), + // borrow fields + apyBaseBorrow: Number(iRs[index] / 100), // interest free except the pools on manhattan finance + // apyRewardBorrow, // ignoring this cause its only available within a specific range of collateral factor + totalSupplyUsd: tvlUsd.toNumber(), + totalBorrowUsd: totalBorrowUsd.toNumber(), + debtCeilingUsd: totalBorrowUsd.plus(debtCeilingUsd).toNumber(), + mintedCoin: 'MAI', + ltv: (1 / ltv[index]) * 100, + }; + }); + result.push(_result); + } + return result.flat().filter((e) => e.tvlUsd); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://app.mai.finance/', +}; diff --git a/src/adaptors/qidao/vaults.js b/src/adaptors/qidao/vaults.js new file mode 100644 index 0000000000..fd5f8f7a53 --- /dev/null +++ b/src/adaptors/qidao/vaults.js @@ -0,0 +1,1353 @@ +const sdk = require('@defillama/sdk'); +// ref https://github.com/royalaid/qidao-sdk/blob/main/src/vaultInfo.ts + +const ChainId = { + MAINNET: 'ethereum', + FANTOM: 'fantom', + // AVALANCHE: 'avax', // not found v2 + // ARBITRUM: 'arbitrum', // not found v2 + // OPTIMISM: 'optimism', + // MOONRIVER: 'moonriver', // not found v2 + // MOONBEAM: 'moonbeam', // apyBaseBorrow is weird + // HARMONY: 'harmony', // not found v2 + BSC: 'bsc', + // XDAI: 'xdai', // not found v2 + MATIC: 'polygon', + METIS: 'metis', +}; +const FRONTEND = { + MAI: 'MAI', + MANHATTAN: 'MANHATTAN', + STELLASWAP: 'STELLASWAP', +}; + +class Token { + chain; + address; + decimals; + symbol; + name; + constructor() {} + static deserializer(chain, address, decimals, symbol, name) { + const item = new Token(); + item.chain = chain; + item.address = address; + item.decimals = decimals; + item.symbol = symbol; + item.name = name; + return item; + } +} + +const WFTM_ADDRESS = '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83'; +const STETH_ADDRESS = '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'; +const METIS_WBTC_ADDRESS = '0xa5B55ab1dAF0F8e1EFc0eB1931a957fd89B918f4'; +//CAM Vaults +const CAMWMATIC_VAULT_ADDRESS = '0x88d84a85A87ED12B8f098e8953B322fF789fCD1a'; +const CAMWETH_VAULT_ADDRESS = '0x11A33631a5B5349AF3F165d2B7901A4d67e561ad'; +const CAMAAVE_VAULT_ADDRESS = '0x578375c3af7d61586c2C3A7BA87d2eEd640EFA40'; +const CAMWBTC_VAULT_ADDRESS = '0x7dDA5e1A389E0C1892CaF55940F5fcE6588a9ae0'; +const CAMDAI_VAULT_ADDRESS = '0xD2FE44055b5C874feE029119f70336447c8e8827'; +//FTM Vaults +const YVWFTM_VAULT_ADDRESS = '0x7efB260662a6FA95c1CE1092c53Ca23733202798'; +const YVWBTC_VAULT_ADDRESS = '0x571F42886C31f9b769ad243e81D06D0D144BE7B4'; +const YVYFI_VAULT_ADDRESS = '0x6d6029557a06961aCC5F81e1ffF5A474C54e32Fd'; +const YVWETH_VAULT_ADDRESS = '0x7aE52477783c4E3e5c1476Bbb29A8D029c920676'; +const YVDAI_VAULT_ADDRESS = '0x682E473FcA490B0adsFA7EfE94083C1E63f28F034'; +const MOO_SCREAM_WBTC_VAULT_ADDRESS = + '0x5563Cc1ee23c4b17C861418cFF16641D46E12436'; +const MOO_SCREAM_DAI_VAULT_ADDRESS = + '0xBf0ff8ac03f3E0DD7d8faA9b571ebA999a854146'; +const MOO_SCREAM_ETH_VAULT_ADDRESS = + '0xC1c7eF18ABC94013F6c58C6CdF9e829A48075b4e'; +const MOO_SCREAM_WFTM_VAULT_ADDRESS = + '0x3609A304c6A41d87E895b9c1fd18c02ba989Ba90'; +const MOO_SCREAM_LINK_VAULT_ADDRESS = + '0x8e5e4D08485673770Ab372c05f95081BE0636Fa2'; +const MOO_BIFI_FTM_VAULT_ADDRESS = '0x75D4aB6843593C111Eeb02Ff07055009c836A1EF'; +//AVAX Vaults +const MOO_WAVAX_VAULT_ADDRESS = '0xfA19c1d104F4AEfb8d5564f02B3AdCa1b515da58'; +//ETH Vaults +const YVETH_VAULT_ADDRESS = '0xEcbd32bD581e241739be1763DFE7a8fFcC844ae1'; +const YVLINK_VAULT_ADDRESS = '0x60d133c666919B54a3254E0d3F14332cB783B733'; +const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const LINK_ADDRESS = '0x514910771AF9Ca656af840dff83E8264EcF986CA'; +const FTM_ZAPPER_ADDRESS = '0xE2379CB4c4627E5e9dF459Ce08c2342C696C4c1f'; +const AVAX_ZAPPER_ADDRESS = '0x1d0a9E2c445EB8f99767eF289832637921e6F6a5'; +const OG_MATIC_VAULT = '0xa3Fa99A148fA48D14Ed51d610c367C61876997F1'; + +const vaults = { + [ChainId.MAINNET]: [ + { + vaultAddress: '0x98eb27E5F24FB83b7D129D789665b08C258b4cCF', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + 18, + 'WETH', + 'Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0x8C45969aD19D297c9B85763e90D0344C6E2ac9d1', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + 8, + 'WBTC', + 'Wrapped Bitcoin' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xcc61Ee649A95F2E2f0830838681f839BDb7CB823', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0xbC10c4F7B9FE0B305e8639B04c536633A3dB7065', + 18, + 'sdsteCRV', + 'StakeDAO Curve.fi ETH/stETH' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0x82E90EB7034C1DF646bD06aFb9E67281AAb5ed28', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0xdCD90C7f6324cfa40d7169ef80b12031770B4325', + 18, + 'yvcurve-eth-steth', + 'Yearn Curve.fi ETH/stETH' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xEcbd32bD581e241739be1763DFE7a8fFcC844ae1', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0xa258C4606Ca8206D8aA700cE2143D7db854D168c', + 18, + 'YVETH', + 'Yearn WETH' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0x60d133c666919B54a3254E0d3F14332cB783B733', + chainId: ChainId.MAINNET, + token: Token.deserializer( + ChainId.MAINNET, + '0x671a912C10bba0CFA74Cfc2d6Fba9BA1ed9530B2', + 18, + 'YVLINK', + 'Yearn Link' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + ], + [ChainId.FANTOM]: [ + { + vaultAddress: '0x1066b8FC999c1eE94241344818486D5f944331A0', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', + 18, + 'FTM', + 'Fantom' + ), + native: true, + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-fantom-vaults', + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: YVWFTM_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x0DEC85e74A92c52b7F708c4B10207D9560CEFaf0', + 18, + 'yvWFTM', + 'Yearn Fantom' + ), + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-yvwftm-vaults', + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: YVWBTC_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xd817a100ab8a29fe3dbd925c2eb489d67f758da9', + 8, + 'yvWBTC', + 'Yearn Wrapped Bitcoin' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: YVYFI_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x2C850cceD00ce2b14AA9D658b7Cad5dF659493Db', + 18, + 'yvYFI', + 'Yearn Vault YFI' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: YVWETH_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xCe2Fc0bDc18BD6a4d9A725791A3DEe33F3a23BB7', + 18, + 'yvWETH', + 'Yearn Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: YVDAI_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x637eC617c86D24E421328e6CAEa1d92114892439', + 18, + 'yvDAI', + 'Yearn DAI' + ), + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-yvdai-vaults', + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xD939c268C49c442F037E968F045ba02f499562D4', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x74b23882a30290451A17c44f4F05243b6b58C76d', + 18, + 'ETH', + 'Ethereum' + ), + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-fantom-eth-vaults', + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xdB09908b82499CAdb9E6108444D5042f81569bD9', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x6a07A792ab2965C72a5B8088d3a069A7aC3a993B', + 18, + 'AAVE', + 'Aave' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x267bDD1C19C932CE03c7A62BBe5b95375F9160A6', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xae75A438b2E0cB8Bb01Ec1E1e376De11D44477CC', + 18, + 'SUSHI', + 'Sushi' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xd6488d586E8Fcd53220e4804D767F19F5C846086', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xb3654dc3D10Ea7645f8319668E8F54d2574FBdC8', + 18, + 'LINK', + 'ChainLink' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xE5996a2cB60eA57F03bf332b5ADC517035d8d094', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x321162Cd933E2Be498Cd2267a90534A804051b11', + 8, + 'BTC', + 'Bitcoin' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_SCREAM_WBTC_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x97927aBfE1aBBE5429cBe79260B290222fC9fbba', + 18, + 'mooScreamWBTC', + 'Beefy Scream WBTC' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_SCREAM_DAI_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x920786cff2A6f601975874Bb24C63f0115Df7dc8', + 18, + 'mooScreamDAI', + 'Beefy Scream DAI' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_SCREAM_ETH_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x0a03D2C1cFcA48075992d810cc69Bd9FE026384a', + 18, + 'mooScreamETH', + 'Beefy Scream ETH' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_SCREAM_WFTM_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x49c68eDb7aeBd968F197121453e41b8704AcdE0C', + 18, + 'mooScreamFTM', + 'Beefy Scream FTM' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_SCREAM_LINK_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x6DfE2AAEA9dAadADf0865B661b53040E842640f8', + 18, + 'mooScreamLINK', + 'Beefy Scream LINK' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xF34e271312e41Bbd7c451B76Af2AF8339D6f16ED', + depreciated: true, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xA3e3Af161943CfB3941B631676134bb048739727', + 18, + 'mooBooBTC-FTM', + 'Beefy SpookySwap BTC-FTM LP' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x9BA01B1279B1F7152b42aCa69fAF756029A9ABDe', + depreciated: true, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0x2a30C5e0d577108F694d2A96179cd73611Ee069b', + 18, + 'mooBooETH-FTM', + 'Beefy SpookySwap ETH-FTM LP' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: MOO_BIFI_FTM_VAULT_ADDRESS, + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xbF07093ccd6adFC3dEB259C557b61E94c1F66945', + 18, + 'mooFantomBIFI', + 'Beefy Staked BIFI' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x3f6cf10e85e9c0630856599FAB8D8BFcd9C0E7D4', + chainId: ChainId.FANTOM, + token: Token.deserializer( + ChainId.FANTOM, + '0xa48d959AE2E88f1dAA7D5F611E01908106dE7598', + 18, + 'XBOO', + 'xBoo MirrorWorld' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + ], + [ChainId.AVALANCHE]: [ + { + vaultAddress: MOO_WAVAX_VAULT_ADDRESS, + chainId: ChainId.AVALANCHE, + token: Token.deserializer( + ChainId.AVALANCHE, + '0x1B156C5c75E9dF4CAAb2a5cc5999aC58ff4F9090', + 18, + 'mooAaveAVAX', + 'Beefy Aave AVAX' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x13A7fE3Ab741ea6301Db8B164290bE711f546A73', + chainId: ChainId.AVALANCHE, + token: Token.deserializer( + ChainId.AVALANCHE, + '0x0665eF3556520B21368754Fb644eD3ebF1993AD4', + 18, + 'sdav3CRV', + 'Stake DAO av3CRV Strategy' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x1f8f7a1d38e41eaf0ed916def29bdd13f2a3f11a', + chainId: ChainId.AVALANCHE, + token: Token.deserializer( + ChainId.AVALANCHE, + '0x50b7545627a5162F82A992c33b87aDc75187B218', + 8, + 'WBTC.e', + 'Wrapped BTC' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xa9122dacf3fccf1aae6b8ddd1f75b6267e5cbbb8', + chainId: ChainId.AVALANCHE, + token: Token.deserializer( + ChainId.AVALANCHE, + '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB', + 18, + 'WETH', + 'Wrapped Ethereum' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x73a755378788a4542a780002a75a7bae7f558730', + chainId: ChainId.AVALANCHE, + token: Token.deserializer( + ChainId.AVALANCHE, + '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', + 18, + 'WAVAX', + 'Wrapped AVAX' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + ], + [ChainId.ARBITRUM]: [ + { + depreciated: true, + vaultAddress: '0xf5c2b1b92456fe1b1208c63d8ea040d464f74a72', + chainId: ChainId.ARBITRUM, + token: Token.deserializer( + ChainId.ARBITRUM, + '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + 18, + 'WETH (OLD)', + 'Wrapped Ether (OLD)' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xC76a3cBefE490Ae4450B2fCC2c38666aA99f7aa0', + chainId: ChainId.ARBITRUM, + token: Token.deserializer( + ChainId.ARBITRUM, + '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + 18, + 'WETH', + 'Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xB237f4264938f0903F5EC120BB1Aa4beE3562FfF', + chainId: ChainId.ARBITRUM, + token: Token.deserializer( + ChainId.ARBITRUM, + '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + 8, + 'WBTC', + 'Wrapped Bitcoin' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + ], + [ChainId.OPTIMISM]: [ + { + vaultAddress: '0x062016Cd29Fabb26c52BAB646878987fC9B0Bc55', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x4200000000000000000000000000000000000006', + 18, + 'WETH', + 'Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xB9C8F0d3254007eE4b98970b94544e473Cd610EC', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x68f180fcCe6836688e9084f035309E29Bf0A2095', + 8, + 'WBTC', + 'Wrapped BTC' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xbf1aeA8670D2528E08334083616dD9C5F3B087aE', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x4200000000000000000000000000000000000042', + 18, + 'OP', + 'Optimism' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xB89c1b3d9f335B9d8Bb16016F3d60160AE71041f', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x4D153F47F03c237F6360a6eccd185b4aE09c63D0', + 18, + 'mooAaveDAI', + 'Beefy OP Aave Dai' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xF9CE2522027bD40D3b1aEe4abe969831FE3BeAf5', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x7eE71053102d54Fc843BaEBaf07277C2b6dB64f1', + 18, + 'mooAaveWETH', + 'Beefy OP Aave WETH' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xAB91c51b55F7Dd7B34F2FD7217506fD5b632B2B9', + chainId: ChainId.OPTIMISM, + token: Token.deserializer( + ChainId.OPTIMISM, + '0x8e2cdf8c6477439b7c989e86b917d80871b92339', + 18, + 'mooAaveWBTC', + 'Beefy OP Aave WBTC' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + ], + [ChainId.MOONRIVER]: [ + { + vaultAddress: '0x4a0474E3262d4DB3306Cea4F207B5d66eC8E0AA9', + depreciated: true, + chainId: ChainId.MOONRIVER, + token: Token.deserializer( + ChainId.MOONRIVER, + '0x639A647fbe20b6c8ac19E48E2de44ea792c62c5C', + 18, + 'ETH', + 'Ethereum' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x97D811A7eb99Ef4Cb027ad59800cE27E68Ee1109', + depreciated: true, + chainId: ChainId.MOONRIVER, + token: Token.deserializer( + ChainId.MOONRIVER, + '0x932009984bd2a7dA8C6396694E811Da5C0952d05', + 18, + 'mooSolarETH-USDC', + 'Beefy Solarbeam ETH-USDC LP' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + native: true, + vaultAddress: '0x5dB6617DDF077d76CFD9d7fC0Fa91aAabc3da683', + chainId: ChainId.MOONRIVER, + token: Token.deserializer( + ChainId.MOONRIVER, + '0x98878B06940aE243284CA214f92Bb71a2b032B8A', + 18, + 'MOVR', + 'Moonriver' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xF4fa968578723580935a00d1e12Fe96Bc6401947', + depreciated: true, + chainId: ChainId.MOONRIVER, + token: Token.deserializer( + ChainId.MOONRIVER, + '0x78Dc4b7C7A89812fb337dD8C3B0ccB3e04E02D7C', + 18, + 'mooSolarMOVR-USDC', + 'Beefy Solarbeam MOVR-USDC LP' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + ], + [ChainId.MOONBEAM]: [ + { + chainId: ChainId.MOONBEAM, + token: Token.deserializer( + ChainId.MOONBEAM, + '0xAcc15dC74880C9944775448304B263D191c6077F', + 18, + 'WGLMT', + 'Wrapped GLMR' + ), + frontend: FRONTEND.MANHATTAN, + vaultAddress: '0x3A82F4da24F93a32dc3C2A28cFA9D6E63EC28531', + version: 2, + }, + { + chainId: ChainId.MOONBEAM, + token: Token.deserializer( + ChainId.MOONBEAM, + '0x06A3b410b681c82417A906993aCeFb91bAB6A080', + 18, + 'xStella', + 'xStella' + ), + frontend: FRONTEND.MANHATTAN, + vaultAddress: '0x3756465c5b1C1C4cEe473880c9726E20875284f1', + version: 2, + }, + ], + [ChainId.HARMONY]: [ + { + vaultAddress: '0x46469f995A5CB60708200C25EaD3cF1667Ed36d6', + chainId: ChainId.HARMONY, + depreciated: true, + token: Token.deserializer( + ChainId.HARMONY, + '0x6983D1E6DEf3690C4d616b13597A09e6193EA013', + 18, + '1ETH', + 'Wrapped Ethereum' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x12FcB286D664F37981a42cbAce92eAf28d1dA94f', + native: true, + chainId: ChainId.HARMONY, + token: Token.deserializer( + ChainId.HARMONY, + '0xcF664087a5bB0237a0BAd6742852ec6c8d69A27a', + 18, + 'ONE', + 'Harmony (ONE)' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x9f4E3d01c634441F284beb92bBAEeb76133BbB28', + depreciated: true, + chainId: ChainId.HARMONY, + token: Token.deserializer( + ChainId.HARMONY, + '0x3095c7557bCb296ccc6e363DE01b760bA031F2d9', + 8, + '1WBTC OLD', + 'Wrapped Bitcoin OLD' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x4592e0bcf01121757e70404915f220a77ffb4e15', + depreciated: true, + chainId: ChainId.HARMONY, + token: Token.deserializer( + ChainId.HARMONY, + '0x3095c7557bCb296ccc6e363DE01b760bA031F2d9', + 8, + '1WBTC', + 'Wrapped Bitcoin' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + ], + [ChainId.BSC]: [ + { + vaultAddress: '0xA56F9A54880afBc30CF29bB66d2D9ADCdcaEaDD6', + chainId: ChainId.BSC, + token: Token.deserializer( + ChainId.BSC, + '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + 18, + 'Wrapped BNB', + 'WBNB' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x014A177E9642d1b4E970418f894985dC1b85657f', + chainId: ChainId.BSC, + token: Token.deserializer( + ChainId.BSC, + '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + 18, + 'PancakeSwap Token', + 'CAKE' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x7333fd58d8D73a8e5FC1a16C8037ADa4f580FA2B', + chainId: ChainId.BSC, + token: Token.deserializer( + ChainId.BSC, + '0x67ee3Cb086F8a16f34beE3ca72FAD36F7Db929e2', + 18, + 'DODO', + 'DODO' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + ], + [ChainId.XDAI]: [ + { + vaultAddress: '0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b', + chainId: ChainId.XDAI, + token: Token.deserializer( + ChainId.XDAI, + '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1', + 18, + 'Wrapped Ether', + 'WETH' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x014a177e9642d1b4e970418f894985dc1b85657f', + chainId: ChainId.XDAI, + token: Token.deserializer( + ChainId.XDAI, + '0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb', + 18, + 'Gnosis', + 'GNO' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + ], + [ChainId.MATIC]: [ + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '7xxKjtYc6yfDaSo2TDquGtZbxSXqdDnyfCZgvWGtXrRd' + ), + vaultAddress: CAMWMATIC_VAULT_ADDRESS, + token: Token.deserializer( + ChainId.MATIC, + '0x7068Ea5255cb05931EFa8026Bd04b18F3DeB8b0B', + 18, + 'camWMATIC', + 'Compounding Aave Market MATIC' + ), + aaveId: + '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf12700xd05e3e715d945b59290df0ae8ef85c1bdb684744', + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/mai-finance-weth-vaults', + vaultAddress: '0x3fd939B017b31eaADF9ae50C7fF7Fa5c0661d47C', + token: Token.deserializer( + ChainId.MATIC, + '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + 18, + 'WETH', + 'Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + 'Ap8NjXbJ261qLEDJY79WDMBoB8noFCssqXVPeo2eHwuz' + ), + vaultAddress: CAMWETH_VAULT_ADDRESS, + token: Token.deserializer( + ChainId.MATIC, + '0x0470CD31C8FcC42671465880BA81D631F0B76C1D', + 18, + 'camWETH', + 'Compounding Aave Market WETH' + ), + aaveId: + '0x7ceb23fd6bc0add59e62ac25578270cff1b9f6190xd05e3e715d945b59290df0ae8ef85c1bdb684744', + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '7DP4Egj28CbrrqVZALKqJehqYJa7AsvHwNUZXHVZ8hAd' + ), + vaultAddress: CAMAAVE_VAULT_ADDRESS, + token: Token.deserializer( + ChainId.MATIC, + '0xeA4040B21cb68afb94889cB60834b13427CFc4EB', + 18, + 'camAAVE', + 'Compounding Aave Market AAVE' + ), + + aaveId: + '0xd6df932a45c0f255f85145f286ea0b292b21c90b0xd05e3e715d945b59290df0ae8ef85c1bdb684744', + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '4nCf52ozAhJvfzk9Fv7FvFTg4VtKTKVEW6X6kg1FKMYM' + ), + vaultAddress: '0x87ee36f780ae843A78D5735867bc1c13792b7b11', + token: Token.deserializer( + ChainId.MATIC, + '0xD6DF932A45C0f255f85145f286eA0b292B21C90B', + 18, + 'AAVE', + 'Aave' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + 'C9M2n9nEygAcbRzhns1hTVBDTbwtaPUci6DrWTnkj2fA' + ), + vaultAddress: '0x61167073E31b1DAd85a3E531211c7B8F1E5cAE72', + token: Token.deserializer( + ChainId.MATIC, + '0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39', + 18, + 'LINK', + 'ChainLink Token' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '4TAKynX2eqkih6Cob4pBBCxtkgUtBR6QgvsSwA8y9joQ' + ), + vaultAddress: '0x98B5F32dd9670191568b661a3e847Ed764943875', + token: Token.deserializer( + ChainId.MATIC, + '0x172370d5Cd63279eFa6d502DAB29171933a610AF', + 18, + 'CRV', + 'Curve Dao Token' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '2n8LDgHqDMamjXvchFyTgU7o3YndcWVBLcTUFUx7C8Xp' + ), + vaultAddress: '0x37131aEDd3da288467B6EBe9A77C523A700E6Ca1', + token: Token.deserializer( + ChainId.MATIC, + '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6', + 8, + 'WBTC', + 'Wrapped BTC' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '8Yihy9U8n4KnMPn2G4iiWfUycDhKZMhyCQn5urMWsWVi' + ), + vaultAddress: CAMWBTC_VAULT_ADDRESS, + token: Token.deserializer( + ChainId.MATIC, + '0xBa6273A78a23169e01317bd0f6338547F869E8Df', + 8, + 'camWBTC', + 'Compounding Aave Market WBTC' + ), + aaveId: + '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd60xd05e3e715d945b59290df0ae8ef85c1bdb684744', + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-bal-vaults', + vaultAddress: '0xf6906b1Cf79Ab14c79DdC7D763c1A517cF9968A5', + token: Token.deserializer( + ChainId.MATIC, + '0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3', + 18, + 'BAL OLD', + 'Balancer' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-dquick-vaults', + vaultAddress: '0x9e6e3e8161Fffb31a6030E56a3E024842567154F', + token: Token.deserializer( + ChainId.MATIC, + '0xf28164A485B0B2C90639E47b0f377b4a438a16B1', + 18, + 'dQUICK OLD', + 'Dragon QUICK' + ), + depreciated: true, + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '79gzKS8x9REyvAsqgQfgpuD4xX8mpr5HzysJiUF628iE' + ), + vaultAddress: '0x701A1824e5574B0b6b1c8dA808B184a7AB7A2867', + token: Token.deserializer( + ChainId.MATIC, + '0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3', + 18, + 'BAL', + 'Balancer' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + '8VyL256uLZpZSMSPxYVqQcYckhvHQqqP1jKP2dZYWhnj' + ), + vaultAddress: '0x649Aa6E6b6194250C077DF4fB37c23EE6c098513', + token: Token.deserializer( + ChainId.MATIC, + '0xf28164A485B0B2C90639E47b0f377b4a438a16B1', + 18, + 'dQUICK', + 'Dragon QUICK' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: sdk.graph.modifyEndpoint( + 'EWE671kZdZnHoQ7dNzaKr4ZcYe67APDYZ1jBrptnB9km' + ), + vaultAddress: '0xF086dEdf6a89e7B16145b03a6CB0C0a9979F1433', + token: Token.deserializer( + ChainId.MATIC, + '0x385Eeac5cB85A38A9a07A70c73e0a3271CfB54A7', + 18, + 'GHST', + 'Aavegotchi GHST' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + chainId: ChainId.MATIC, + subgraph: + 'https://api.thegraph.com/subgraphs/name/0xlaozi/qi-dao-camdai-vaults', + vaultAddress: CAMDAI_VAULT_ADDRESS, + token: Token.deserializer( + ChainId.MATIC, + '0xE6C23289Ba5A9F0Ef31b8EB36241D5c800889b7b', + 18, + 'camDAI', + 'Compounding Aave Market DAI' + ), + aaveId: + '0x8f3cf7ad23cd3cadbd9735aff958023239c6a0630xd05e3e715d945b59290df0ae8ef85c1bdb684744', + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x57Cbf36788113237D64E46f25A88855c3dff1691', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x7d60F21072b585351dFd5E8b17109458D97ec120', + 18, + 'sdam3CRV', + 'Stake DAO am3CRV Strategy' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xff2c44Fb819757225a176e825255a01B3B8BB051', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x1a3acf6D19267E2d3e7f898f42803e90C9219062', + 18, + 'FXS', + 'Frax Share' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x7d36999a69f2B99BF3FB98866cBbE47aF43696C8', + chainId: ChainId.MATIC, + depreciated: true, + disabled: true, + token: Token.deserializer( + ChainId.MATIC, + '0xfe4546feFe124F30788c4Cc1BB9AA6907A7987F9', + 18, + 'cxETH', + 'CelsiusX ETH' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x506533B9C16eE2472A6BF37cc320aE45a0a24F11', + chainId: ChainId.MATIC, + depreciated: true, + disabled: true, + token: Token.deserializer( + ChainId.MATIC, + '0x64875Aaa68d1d5521666C67d692Ee0B926b08b2F', + 18, + 'cxADA', + 'CelsiusX Wrapped ADA' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x7CbF49E4214C7200AF986bc4aACF7bc79dd9C19a', + chainId: ChainId.MATIC, + depreciated: true, + disabled: true, + token: Token.deserializer( + ChainId.MATIC, + '0x9Bd9aD490dD3a52f096D229af4483b94D63BE618', + 18, + 'cxDOGE', + 'CelsiusX Wrapped DOGE' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x1F0aa72b980d65518e88841bA1dA075BD43fa933', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x51195e21BDaE8722B29919db56d95Ef51FaecA6C', + 18, + 'vGHST', + 'Gotchi Vault GHST' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x178f1c95C85Fe7221C7A6a3d6F12B7Da3253eeAe', + chainId: ChainId.MATIC, + depreciated: true, + token: Token.deserializer( + ChainId.MATIC, + '0xd85d1e945766fea5eda9103f918bd915fbca63e6', + 4, + 'CEL', + 'Celsius' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x1DCc1f864A4Bd0b8f4Ad33594B758b68e9Fa872c', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0xBbba073C31bF03b8ACf7c28EF0738DeCF3695683', + 18, + 'SAND', + 'The Sandbox Game' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0x305f113ff78255d4F8524c8F50C7300B91B10f6A', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270', + 18, + 'WMATIC', + 'Wrapped Matic' + ), + frontend: FRONTEND.MAI, + version: 1, + }, + { + vaultAddress: '0xaa19d0e397c964a35e6e80262c692dbfC9C23451', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0xf52B3250E026E0307d7d717AE0f331baAA4F83a8', + 18, + 'xxDAI', + 'Tetu xxDAI' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0x11826d20B6A16A22450978642404dA95B4640123', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x6c5e2E7dF0372f834B7F40D16Ff4333Cf49Af235', + 18, + 'xxLINK', + 'Tetu xxLINK' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xa3b0A659f2147D77A443f70D96b3cC95E7A26390', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0x1c954e8fe737f99f68fa1ccda3e51ebdb291948c', + 18, + 'KNC', + 'Kyber Network Crystal' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xCE0f1a5F4F2bC526A1495716184D719Ba93d8ebA', + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0xB197f73B582f76cfc96d269a3A99A3604316BA47', + 18, + 'aMAIDAI', + 'Arrakis Mai/Dai' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + chainId: ChainId.MATIC, + token: Token.deserializer( + ChainId.MATIC, + '0xfa68FB4628DFF1028CFEc22b4162FCcd0d45efb6', + 18, + 'MaticX', + 'Liquid Staking Matic' + ), + frontend: FRONTEND.MANHATTAN, + vaultAddress: '0x4b7509ce029656341D0B59D387D9B5312E41615a', + version: 2, + }, + // { + // chainId: ChainId.MATIC, + // token: Token.deserializer( + // ChainId.MATIC, + // '0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4', + // 18, + // 'stMatic', + // 'Staked Matic' + // ), + // frontend: FRONTEND.MANHATTAN, + // vaultAddress: '0x34fa22892256216a659D4f635354250b4D771458', + // version: 2, + // }, + ], + [ChainId.METIS]: [ + { + vaultAddress: '0x10DcBEe8afA39a847707e16Aea5eb34c6b01aBA9', + chainId: ChainId.METIS, + token: Token.deserializer( + ChainId.METIS, + '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000', + 18, + 'METIS', + 'Metis' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + { + vaultAddress: '0xC09c73F7B32573d178138E76C0e286BA21085c20', + chainId: ChainId.METIS, + token: Token.deserializer( + ChainId.METIS, + '0x420000000000000000000000000000000000000A', + 18, + 'WETH', + 'Wrapped Ether' + ), + frontend: FRONTEND.MAI, + version: 2, + }, + // { + // vaultAddress: '0xB89c1b3d9f335B9d8Bb16016F3d60160AE71041f', + // chainId: ChainId.METIS, + // token: Token.deserializer( + // ChainId.METIS, + // METIS_WBTC_ADDRESS, + // 8, + // 'WBTC', + // 'Wrapped BTC' + // ), + // frontend: FRONTEND.MAI, + // version: 2, + // }, + // { + // vaultAddress: '0x5A03716bd1f338D7849f5c9581AD5015ce0020B0', + // chainId: ChainId.METIS, + // token: Token.deserializer( + // ChainId.METIS, + // '0x433e43047b95cb83517abd7c9978bdf7005e9938', + // 8, + // 'm.WBTC', + // 'Metis Wrapped BTC' + // ), + // frontend: FRONTEND.MAI, + // version: 2, + // }, + ], +}; + +module.exports = { + vaults, + ChainId, + FRONTEND, +}; diff --git a/src/adaptors/quasar-vaults/index.js b/src/adaptors/quasar-vaults/index.js new file mode 100644 index 0000000000..fc3b0a3e85 --- /dev/null +++ b/src/adaptors/quasar-vaults/index.js @@ -0,0 +1,31 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const apy = async () => { + const vaults = await utils.getData( + 'https://api.quasar.fi/vaults' + ); + + // Vaults list that we will use on the return array + const mellowVault = vaults.find((vault) => vault.name === 'Unified Restaked LST' && vault.provider === 'mellow'); + const underlyingToken = `${mellowVault.network}:${mellowVault.strategyAssets[0].denom}` + + return [ + // Mellow Vault + { + poolMeta: "Mellow Finance Protocol. Lockup Period: Withdrawals are processed by risk curators within 1-7 days in batches.", + pool: mellowVault.address, + chain: utils.formatChain(mellowVault.network), + project: 'quasar-vaults', + symbol: "urLRT", + tvlUsd: (await axios.get(`https://coins.llama.fi/prices/current/${underlyingToken}`)).data.coins[`${underlyingToken}`]?.price * mellowVault.totalSupply, + apy: mellowVault.apy, + } + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.quasar.fi', +}; diff --git a/src/adaptors/quickswap/index.js b/src/adaptors/quickswap-dex/index.js similarity index 55% rename from src/adaptors/quickswap/index.js rename to src/adaptors/quickswap-dex/index.js index 70ad08b406..00ed400ee5 100644 --- a/src/adaptors/quickswap/index.js +++ b/src/adaptors/quickswap-dex/index.js @@ -1,7 +1,13 @@ +const sdk = require('@defillama/sdk'); const { request, gql } = require('graphql-request'); const utils = require('../utils'); -const url = 'https://polygon.furadao.org/subgraphs/name/quickswap'; +const url = sdk.graph.modifyEndpoint( + 'FnbpmBoXSidpFCghB5oxEb7XBUyGsSmyyXs9p8t3esvF' +); +const sushiPolygon = sdk.graph.modifyEndpoint( + '8NiXkxLRT3R22vpwLB4DXttpEf3X1LrKhe4T1tQ3jjbP' +); const query = gql` { @@ -39,37 +45,53 @@ const buildPool = (entry, chainString) => { const newObj = { pool: entry.id, chain: utils.formatChain(chainString), - project: 'quickswap', + project: 'quickswap-dex', symbol, tvlUsd: entry.totalValueLockedUSD, - apy: entry.apy, + apyBase: entry.apy1d, + apyBase7d: entry.apy7d, + underlyingTokens: [entry.token0.id, entry.token1.id], + volumeUsd1d: entry.volumeUSD1d, + volumeUsd7d: entry.volumeUSD7d, }; return newObj; }; -const topLvl = async (chainString, timestamp, url) => { +const topLvl = async (chainString, timestamp, url, version) => { const [block, blockPrior] = await utils.getBlocks( chainString, timestamp, // this is a hack, cause the above url has the wrong prefix so we cannot use it // note(!) not sure if i should keep this, or just remove quickswap from timetravel - ['https://api.thegraph.com/subgraphs/name/sushiswap/matic-exchange'] + [sushiPolygon] ); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [sushiPolygon], + 604800 + ); + // pull data - let dataNow = await request(url, query.replace('', block)); + let data = (await request(url, query.replace('', block))).pairs; // pull 24h offset data to calculate fees from swap volume - let dataPrior = await request( - url, - queryPrior.replace('', blockPrior) - ); + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; // calculate tvl - dataNow = await utils.tvl(dataNow.pairs, 'polygon'); + data = await utils.tvl(data, chainString); // calculate apy - let data = dataNow.map((el) => utils.apy(el, dataPrior.pairs, 'v2')); + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); // build pool objects data = data.map((el) => buildPool(el, chainString)); @@ -78,11 +100,12 @@ const topLvl = async (chainString, timestamp, url) => { }; const main = async (timestamp = null) => { - const data = await Promise.all([topLvl('polygon', timestamp, url)]); - return data.flat(); + const data = await Promise.all([topLvl('polygon', timestamp, url, 'v2')]); + return data.flat().filter((p) => utils.keepFinite(p) && p.tvlUsd < 5e6); }; module.exports = { timetravel: true, apy: main, + url: 'https://quickswap.exchange/#/pool', }; diff --git a/src/adaptors/quipuswap-stableswap/helpers.js b/src/adaptors/quipuswap-stableswap/helpers.js new file mode 100644 index 0000000000..f73f739dca --- /dev/null +++ b/src/adaptors/quipuswap-stableswap/helpers.js @@ -0,0 +1,32 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getFarms = async (projectName, filter) => { + const { data: pools } = await axios.get( + 'https://staking-api-mainnet.prod.quipuswap.com/v3/all-farms' + ); + + return pools.list.filter(filter).map(({ item: pool }) => { + const { underlyingTokens, symbol } = pool.tokens.reduce( + (acc, token) => { + acc['underlyingTokens'].push(token.contractAddress); + acc['symbol'].push(token.metadata.symbol); + return acc; + }, + { underlyingTokens: [], symbol: [] } + ); + return { + pool: pool.contractAddress, + chain: utils.formatChain('Tezos'), + project: projectName, + symbol: symbol.join('-'), + tvlUsd: parseFloat(pool.tvlInUsd), + apy: pool.apy, + rewardTokens: [pool.rewardToken.contractAddress], + underlyingTokens, + url: `https://quipuswap.com/farming/${pool.version}/${pool.id}`, + }; + }); +}; + +module.exports = { getFarms }; diff --git a/src/adaptors/quipuswap-stableswap/index.js b/src/adaptors/quipuswap-stableswap/index.js new file mode 100644 index 0000000000..d28d18b84f --- /dev/null +++ b/src/adaptors/quipuswap-stableswap/index.js @@ -0,0 +1,17 @@ +const { getFarms } = require('./helpers'); + +const projectName = 'quipuswap-stableswap'; + +const poolsFunction = async () => + getFarms( + projectName, + ({ item: pool }) => + pool.stakeStatus === 'ACTIVE' && + parseFloat(pool.tvlInUsd) > 10e3 && + pool.rewardToken.metadata.name.toLowerCase().includes('quipuswap') + ); + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/quoll/abi.json b/src/adaptors/quoll/abi.json new file mode 100644 index 0000000000..19cf005001 --- /dev/null +++ b/src/adaptors/quoll/abi.json @@ -0,0 +1,321 @@ +{ + "lpToken": [ + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "pool": [ + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "name": "quotePotentialWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "quo": [ + { + "inputs": [], + "name": "FACTOR_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "masterWombat": [ + { + "inputs": [], + "name": "basePartition", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boostedPartition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "factor", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardDebt", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "pendingWom", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfoV3", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint40", + "name": "periodFinish", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "sumOfFactors", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRate", + "type": "uint128" + }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "masterWombatRewarder": [ + { + "inputs": [], + "name": "rewardLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "wombatBooster": [ + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "masterWombatPid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "rewardPool", + "type": "address" + }, + { + "internalType": "bool", + "name": "shutdown", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/src/adaptors/quoll/index.js b/src/adaptors/quoll/index.js new file mode 100644 index 0000000000..3ff5ff4e7f --- /dev/null +++ b/src/adaptors/quoll/index.js @@ -0,0 +1,381 @@ +const sdk = require('@defillama/sdk'); +const {BigNumber, FixedFormat, FixedNumber} = require('@ethersproject/bignumber'); +const utils = require('../utils'); +const abi = require('./abi.json'); +const voterProxy = '0xe96c48C5FddC0DC1Df5Cf21d68A3D8b3aba68046'; +const masterWombat = '0x489833311676B566f888119c29bd997Dc6C95830'; +const wombatBooster = '0x6FCA396A8a2b623b24A998A5808c0E144Aa0689a'; +const quo = '0x08b450e4a48C04CDF6DB2bD4cf24057f7B9563fF'; +const wom = '0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1'; +const address0 = '0x' + '0'.repeat(40); +const chain = 'bsc'; +const {main, side, i8n, qwom, wmx, bnbx, stk, bnb} = { + main: 'MAIN POOL', + side: 'SIDE POOL', + i8n: 'INNOVATION POOL', + qwom: 'qWOM POOL', + wmx: 'wmxWOM POOL', + bnbx: 'BNBx POOL', + stk: 'stkBNB POOL', + bnb: 'BNB POOL (Shut Down)' +}; +const poolMetas = [ + main, + main, + bnb, + bnb, + bnb, + bnb, + main, + main, + side, + side, + wmx, + wmx, + i8n, + i8n, + i8n, + bnbx, + bnbx, + qwom, + qwom, + stk, + stk +]; + +Object.entries(abi).forEach(([contract, methods]) => { + abi[`${contract}List`] = methods; + abi[contract] = Object.fromEntries(methods.map(method => [method.name, method])); +}); + +const DefaultFixedFormat = FixedFormat.from({ + width: 256, + decimals: 18, + signed: true +}); +BigNumber.fromDecimal = function(decimal, decimals = DefaultFixedFormat.decimals) { + // replace comma added by prettify + return BigNumber.from(FixedNumber.from(decimal.replace(/,/g, ''), {...DefaultFixedFormat, decimals})._hex); +}; + +// Returns a string "1" followed by decimal "0"s +function getMultiplier(decimals = 18) { + return `1${decimals > 0 ? '0'.repeat(decimals) : ''}`; +} + +BigNumber.prototype.toDecimal = function(option) { + const { + decimals = DefaultFixedFormat.decimals, + precision, + removeTrailingZero = true + } = option ?? {}; + const fixedNumber = FixedNumber.fromValue(this, decimals, {...DefaultFixedFormat, decimals}); + const fixedStr = typeof precision === 'number' ? fixedNumber.round(precision).toString() : fixedNumber.toString(); + const [characteristic, originalMantissa = ''] = fixedStr.split('.'); + let mantissa = originalMantissa; + const currentPrecision = mantissa.length; + if (!removeTrailingZero && precision && currentPrecision < precision) { + mantissa = mantissa.padEnd(precision, '0'); + } + + if (removeTrailingZero) { + mantissa = mantissa.replace(/0+$/, ''); + } + + return mantissa ? characteristic + '.' + mantissa : characteristic; +}; + +BigNumber.prototype.changeDecimals = function(curDecimals, nextDecimals = 18) { + const diff = nextDecimals - curDecimals; + if (diff === 0) return this; + + const multiplier = getMultiplier(Math.abs(diff)); + + return diff > 0 ? this.mul(multiplier) : this.div(multiplier); +}; + +async function apy() { + const poolLength = await sdk.api.abi.call({ + abi: abi.wombatBooster.poolLength, + target: wombatBooster, + params: [], + chain + }).then(l => parseInt(l.output.toString())); + + const poolInfos = await sdk.api.abi.multiCall({ + abi: abi.wombatBooster.poolInfo, + calls: Array.from(Array(poolLength).keys()).map((pid) => ({ + target: wombatBooster, + params: [pid] + })), + chain, + }); + + const masterWombatPoolInfos = await sdk.api.abi.multiCall({ + abi: abi.masterWombat.poolInfoV3, + calls: poolInfos.output.map((pool) => ({ + target: masterWombat, + params: [pool.output.masterWombatPid] + })), + chain, + }); + + const voterProxyUserInfos = await sdk.api.abi.multiCall({ + abi: abi.masterWombat.userInfo, + calls: poolInfos.output.map((pool) => ({ + target: masterWombat, + params: [pool.output.masterWombatPid, voterProxy] + })), + chain, + }); + + const masterWombatBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: poolInfos.output.map((pool) => ({ + target: pool.output.lptoken, + params: [masterWombat] + })), + chain, + }); + + const lpTokenTargets = poolInfos.output.map((pool) => ({ + target: pool.output.lptoken, + params: [] + })); + + const lpSymbols = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: lpTokenTargets, + chain, + }); + + const lpPools = await sdk.api.abi.multiCall({ + abi: abi.lpToken.pool, + calls: lpTokenTargets, + chain, + }); + + const underlyingTokens = await sdk.api.abi.multiCall({ + abi: abi.lpToken.underlyingToken, + calls: lpTokenTargets, + chain, + }); + + const voterProxyUnderlyingAmounts = await sdk.api.abi.multiCall({ + abi: abi.pool.quotePotentialWithdraw, + calls: lpPools.output.map((pool, index) => { + return { + target: pool.output, + params: [ + underlyingTokens.output[index].output, + voterProxyUserInfos.output[index].output.amount + ], + }; + }), + chain, + }); + + const masterWombatUnderlyingAmounts = await sdk.api.abi.multiCall({ + abi: abi.pool.quotePotentialWithdraw, + calls: lpPools.output.map((pool, index) => { + return { + target: pool.output, + params: [ + underlyingTokens.output[index].output, + masterWombatBalances.output[index].output + ], + }; + }), + chain, + }); + + const quoCallParams = { + target: quo, + params: [], + chain + }; + const [ + quoFactor, + quoFactorDenominator, + quoMaxSupply, + quoTotalSupply, + + masterWombatBasePartition, + masterWombatBoostedPartition + ] = await Promise.all([ + sdk.api.abi.call({ + abi: abi.quo.factor, + ...quoCallParams + }), + sdk.api.abi.call({ + abi: abi.quo.FACTOR_DENOMINATOR, + ...quoCallParams + }), + sdk.api.abi.call({ + abi: abi.quo.maxSupply, + ...quoCallParams + }), + sdk.api.abi.call({ + abi: 'erc20:totalSupply', + ...quoCallParams + }), + + sdk.api.abi.call({ + ...quoCallParams, + abi: abi.masterWombat.basePartition, + target: masterWombat + }), + sdk.api.abi.call({ + ...quoCallParams, + abi: abi.masterWombat.boostedPartition, + target: masterWombat + }), + ]); + + const rewarderInfos = await Promise.all(masterWombatPoolInfos.output.map(async ({output: {rewarder}}) => { + if (rewarder === address0) return null; + + const rewardLength = await sdk.api.abi.call({ + abi: abi.masterWombatRewarder.rewardLength, + target: rewarder, + params: [], + chain + }); + + return sdk.api.abi.multiCall({ + abi: abi.masterWombatRewarder.rewardInfo, + chain, + calls: Array(+rewardLength.output).fill().map((empty, idx) => ({ + target: rewarder, + params: [idx], + })) + }); + })); + + const {pricesByAddress, pricesBySymbol} = await utils.getPrices(Array.from(new Set([ + ...underlyingTokens.output.map(({output}) => output), + ...rewarderInfos.flatMap(poolRewardInfos => !poolRewardInfos ? [] : poolRewardInfos.output.map(({rewardToken}) => rewardToken)), + wom, + quo + ])), chain); + // console.log(pricesBySymbol, pricesByAddress); + + const yearSeconds = 365 * 24 * 60 * 60; + const multiplier18 = getMultiplier(); + const getTokenPrice = tokenAddress => BigNumber.fromDecimal(pricesByAddress[tokenAddress.toLowerCase()]?.toString() || '0'); + const calculateApr = ({ + rewardRate, + rewardToken, + tvlToken, + tvlBalance + }) => { + const tvlTokenPrice = getTokenPrice(tvlToken); + if (tvlTokenPrice.isZero()) return BigNumber.from(0); + + return BigNumber.from(rewardRate) + .mul(yearSeconds) + .mul(getTokenPrice(rewardToken)) + .div(BigNumber.from(tvlBalance)) + .mul(multiplier18) + .div(tvlTokenPrice) + .mul(100); + }; + + return voterProxyUnderlyingAmounts.output.flatMap((voterProxyUnderlyingAmount, i) => { + const underlyingTokenAddress = underlyingTokens.output[i].output; + if (voterProxyUserInfos.output[i].output.amount === '0' || !voterProxyUnderlyingAmount.output) return []; + if (underlyingTokens.output[i].output.toLowerCase() === '0xE85aFCcDaFBE7F2B096f268e31ccE3da8dA2990A'.toLowerCase()) return []; // disable aBNBc (ankr bnb) + + let quollBalanceAmount = 0; + let apr = BigNumber.from(0); + const rewardTokens = new Set(); + if (voterProxyUnderlyingAmount.output) { + // quoll tvl + const quollBalance = voterProxyUnderlyingAmount.output.amount; + quollBalanceAmount = +BigNumber.from(quollBalance).mul(getTokenPrice(underlyingTokenAddress)).div(multiplier18).toDecimal(); + + const {rewardRate, sumOfFactors} = masterWombatPoolInfos.output[i].output; + const basePartition = BigNumber.from(masterWombatBasePartition.output); + const boostedPartition = BigNumber.from(masterWombatBoostedPartition.output); + const totalPartition = basePartition.add(boostedPartition); + // base and bonus wom rewardRate + let baseWomRewardRate = BigNumber.from(rewardRate).mul(basePartition).div(totalPartition); + + // boosted wom rewardRate + const {factor} = voterProxyUserInfos.output[i].output; + const boostedWomRewardRate = BigNumber.from(rewardRate).mul(boostedPartition).div(totalPartition).mul(factor).div(sumOfFactors); + + // bonus rewardRates + let poolRewardInfos = []; + if (rewarderInfos[i]) { + poolRewardInfos = rewarderInfos[i].output.flatMap(rewardInfo => { + const {output: {rewardToken, tokenPerSec}} = rewardInfo; + if (rewardToken.toLowerCase() === wom.toLowerCase()) { + baseWomRewardRate = baseWomRewardRate.add(tokenPerSec); + + return []; + } + + return rewardInfo; + }); + } + + if (!BigNumber.from(rewardRate).isZero()) { + rewardTokens.add(wom); + rewardTokens.add(quo); + } + + // quo rewardRate ref: https://docs.quoll.finance/understanding-quoll/token/tokenomics + const cliffCount = BigNumber.from(1e3); + const currentCliff = BigNumber.from(quoTotalSupply.output).mul(cliffCount).div(quoMaxSupply.output).add(quoTotalSupply.output !== quoMaxSupply.output ? 1 : 0); // add 1 for Math.ceil + const quoRewardRateMultipler = BigNumber.from(multiplier18).mul(quoFactor.output).div(quoFactorDenominator.output).mul(cliffCount.sub(currentCliff)).div(cliffCount); + const baseQuoRewardRate = baseWomRewardRate.mul(quoRewardRateMultipler).div(multiplier18); + const boostedQuoRewardRate = boostedWomRewardRate.mul(quoRewardRateMultipler).div(multiplier18); + + const masterWombatUnderlyingAmount = masterWombatUnderlyingAmounts.output[i].output.amount; + apr = apr + .add(calculateApr({ + rewardRate: baseWomRewardRate.mul(8).div(10), + rewardToken: wom, + tvlToken: underlyingTokenAddress, + tvlBalance: masterWombatUnderlyingAmount + })) + .add(calculateApr({ + rewardRate: baseQuoRewardRate, + rewardToken: quo, + tvlToken: underlyingTokenAddress, + tvlBalance: masterWombatUnderlyingAmount + })); + + + poolRewardInfos.forEach(({output: {tokenPerSec, rewardToken}}) => { + apr = apr.add(calculateApr({ + rewardRate: tokenPerSec, + rewardToken, + tvlToken: underlyingTokenAddress, + tvlBalance: masterWombatUnderlyingAmount + })) + rewardTokens.add(rewardToken); + }); + } + + + return { + pool: `${lpTokenTargets[i].target}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'quoll', + symbol: lpSymbols.output[i].output.replace('LP-', ''), + tvlUsd: quollBalanceAmount, + apy: +apr.toDecimal(), + underlyingTokens: [underlyingTokenAddress], + rewardTokens: Array.from(rewardTokens), + poolMeta: poolMetas[i] + }; + }); +} + +module.exports = { + timetravel: false, + apy, + url: 'https://quoll.finance/deposit' +}; diff --git a/src/adaptors/radiant-v1/abi.json b/src/adaptors/radiant-v1/abi.json new file mode 100644 index 0000000000..6e7c918aaa --- /dev/null +++ b/src/adaptors/radiant-v1/abi.json @@ -0,0 +1,794 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "premium", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidatedCollateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "LiquidationCall", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Paused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RebalanceStableBorrowRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Unpaused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "FLASHLOAN_PREMIUM_TOTAL", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LENDINGPOOL_REVISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_NUMBER_RESERVES", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STABLE_RATE_BORROW_SIZE_PERCENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "interestRateMode", + "type": "uint256" + }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "balanceFromBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceToBefore", + "type": "uint256" + } + ], + "name": "finalizeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiverAddress", + "type": "address" + }, + { "internalType": "address[]", "name": "assets", "type": "address[]" }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "modes", "type": "uint256[]" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "bytes", "name": "params", "type": "bytes" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { "internalType": "uint8", "name": "id", "type": "uint8" } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedIncome", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedVariableDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserAccountData", + "outputs": [ + { + "internalType": "uint256", + "name": "totalCollateralETH", + "type": "uint256" + }, + { "internalType": "uint256", "name": "totalDebtETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "availableBorrowsETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentLiquidationThreshold", + "type": "uint256" + }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { "internalType": "uint256", "name": "healthFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.UserConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "name": "initReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { "internalType": "address", "name": "debtAsset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "debtToCover", "type": "uint256" }, + { "internalType": "bool", "name": "receiveAToken", "type": "bool" } + ], + "name": "liquidationCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "rebalanceStableBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "repay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "configuration", "type": "uint256" } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "val", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { + "internalType": "address", + "name": "rateStrategyAddress", + "type": "address" + } + ], + "name": "setReserveInterestRateStrategyAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "bool", "name": "useAsCollateral", "type": "bool" } + ], + "name": "setUserUseReserveAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" } + ], + "name": "swapBorrowRateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } + ] + \ No newline at end of file diff --git a/src/adaptors/radiant-v1/abiDataProvider.json b/src/adaptors/radiant-v1/abiDataProvider.json new file mode 100644 index 0000000000..bbf43f504f --- /dev/null +++ b/src/adaptors/radiant-v1/abiDataProvider.json @@ -0,0 +1,233 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "addressesProvider", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADDRESSES_PROVIDER", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllATokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReservesTokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserveFactor", "type": "uint256" }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "isActive", "type": "bool" }, + { "internalType": "bool", "name": "isFrozen", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVariableDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveTokensAddresses", + "outputs": [ + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "currentATokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "scaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint40", + "name": "stableRateLastUpdated", + "type": "uint40" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/radiant-v1/index.js b/src/adaptors/radiant-v1/index.js new file mode 100644 index 0000000000..bffcb245d9 --- /dev/null +++ b/src/adaptors/radiant-v1/index.js @@ -0,0 +1,165 @@ +const superagent = require('superagent'); + +const utils = require('../utils'); +const pools = require('./pools.json'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const abiDataProvider = require('./abiDataProvider.json'); + +const url = 'https://newapi4.radiant.capital/42161.json'; + +const RDNT = '0x0c4681e6c0235179ec3d4f4fc4df3d14fdd96017'; + +// radiant has an early exit penalty of 50% +const earlyExitPenalty = 0.5; + +const sleep = async (ms) => { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); +}; + +const radiantAaveProtocolDataProvider = + '0xa3e42d11d8CC148160CC3ACED757FB44696a9CcA'; + +const apy = async (pools, dataTvl) => { + const maxCallsPerSec = 5; + const data = []; + for (const [i, pool] of pools.entries()) { + const interest = dataTvl.find( + (el) => el.tokenAddress === pool.interestBearing + ); + const debt = dataTvl.find((el) => el.tokenAddress === pool.debtBearing); + const output = ( + await sdk.api.abi.call({ + target: '0x2032b9A8e9F7e76768CA9271003d3e43E1616B1F', + abi: abi.find((a) => a.name === 'getReserveData'), + chain: 'arbitrum', + params: [pool.underlyingAsset], + }) + ).output; + + const configuration = ( + await sdk.api.abi.call({ + target: radiantAaveProtocolDataProvider, + abi: abiDataProvider.find( + (a) => a.name === 'getReserveConfigurationData' + ), + chain: 'arbitrum', + params: [pool.underlyingAsset], + }) + ).output; + + const liquidity = ( + await sdk.api.abi.call({ + target: pool.underlyingAsset, + abi: 'erc20:balanceOf', + chain: 'arbitrum', + params: [pool.interestBearing], + }) + ).output; + + const decimals = +( + await sdk.api.abi.call({ + target: pool.underlyingAsset, + abi: 'erc20:decimals', + chain: 'arbitrum', + }) + ).output; + + const depositApy = output.currentLiquidityRate / 1e25; + if ((i + 1) % maxCallsPerSec === 0) { + await sleep(1000); + } + + const borrowApy = output.currentVariableBorrowRate / 1e25; + if ((i + 1) % maxCallsPerSec === 0) { + await sleep(1000); + } + + const tvlUsd = (liquidity / 10 ** decimals) * interest.assetPrice; + const totalSupplyUsd = interest.poolValue * interest.assetPrice; + const totalBorrowUsd = totalSupplyUsd - tvlUsd; + + data.push({ + ...pool, + id: interest.tokenAddress, + symbol: pool.symbol, + tvlUsd, + depositApy, + borrowApy, + rewardApy: interest.apy * 100, + rewardApyBorrow: debt.apy * 100, + totalSupplyUsd, + totalBorrowUsd, + ltv: configuration.ltv / 1e4, + }); + } + return data; +}; + +const apyPool2 = async (pool2Info) => { + const pool2 = '0xc963ef7d977ECb0Ab71d835C4cb1Bf737f28d010'; + + return { + pool: pool2, + symbol: 'RDNT-ETH', + underlyingTokens: ['0x0c4681e6c0235179ec3d4f4fc4df3d14fdd96017'], + tvlUsd: pool2Info.data.totalLpStakedUSD, + apyReward: pool2Info.data.apr * 100, + rewardTokens: [RDNT], + project: 'radiant-v1', + chain: 'Arbitrum', + }; +}; + +const padHex = (hexstring, intSize = 256) => { + hexstring = hexstring.replace('0x', ''); + const length = intSize / 4 - hexstring.length; + for (let i = 0; i < length; i++) { + hexstring = '0' + hexstring; + } + return hexstring; +}; + +const topLvl = async (chainString, url) => { + const dataTvl = await utils.getData(url); + + let data = await apy(pools, dataTvl.lendingPoolRewards.data.poolAPRs); + + data = data.map((p) => { + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'radiant-v1', + symbol: utils.formatSymbol(p.symbol), + tvlUsd: p.tvlUsd, + apyBase: p.depositApy, + apyReward: p.rewardApy * earlyExitPenalty, + underlyingTokens: [p.underlyingAsset], + rewardTokens: [RDNT], + // borrow fields + apyBaseBorrow: p.borrowApy, + apyRewardBorrow: p.rewardApyBorrow * earlyExitPenalty, + totalSupplyUsd: p.totalSupplyUsd, + totalBorrowUsd: p.totalBorrowUsd, + ltv: p.ltv, + }; + }); + + let pool2Data = await apyPool2(dataTvl.pool2Info); + data.push(pool2Data); + + return data; +}; + +const main = async () => { + const data = await Promise.all([topLvl('arbitrum', url)]); + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.radiant.capital/#/markets', +}; diff --git a/src/adaptors/radiant-v1/pools.json b/src/adaptors/radiant-v1/pools.json new file mode 100644 index 0000000000..d65ec8ee05 --- /dev/null +++ b/src/adaptors/radiant-v1/pools.json @@ -0,0 +1,32 @@ +[ + { + "interestBearing": "0x4cD44E6fCfA68bf797c65889c74B26b8C2e5d4d3", + "debtBearing": "0x0e16bAE17C61789d8a96Ea6529d788B633C4c8B6", + "underlyingAsset": "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f", + "symbol": "WBTC" + }, + { + "interestBearing": "0xEf47CCC71EC8941B67DC679D1a5f78fACfD0ec3C", + "debtBearing": "0x9C3A8644A9cA181b90094be98dC19496F6b38a24", + "underlyingAsset": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + "symbol": "USDT" + }, + { + "interestBearing": "0x805ba50001779CeD4f59CfF63aea527D12B94829", + "debtBearing": "0xf92d501e74bd1e4308E6676C38Ab4d84389d7Bf3", + "underlyingAsset": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", + "symbol": "USDC" + }, + { + "interestBearing": "0x5293c6CA56b8941040b8D18f557dFA82cF520216", + "debtBearing": "0x2E9B46867469350E4889c280f74Bfa55Ca44fcd4", + "underlyingAsset": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "symbol": "DAI" + }, + { + "interestBearing": "0x15b53d277Af860f51c3E6843F8075007026BBb3a", + "debtBearing": "0x4e75D4bc81D9AD1a1abc972a3dd53d581e1CE16b", + "underlyingAsset": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "symbol": "WETH" + } +] diff --git a/src/adaptors/radiant-v2/abiChefIncentivesController.js b/src/adaptors/radiant-v2/abiChefIncentivesController.js new file mode 100644 index 0000000000..0c4e132659 --- /dev/null +++ b/src/adaptors/radiant-v2/abiChefIncentivesController.js @@ -0,0 +1,582 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + ], + name: 'BalanceUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + ], + name: 'ChefReserveEmpty', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + ], + name: 'ChefReserveLow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'Disqualified', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256[]', + name: 'startTimeOffsets', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'rewardsPerSeconds', + type: 'uint256[]', + }, + ], + name: 'EmissionScheduleAppended', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'uint8', name: 'version', type: 'uint8' }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'rewardsPerSecond', + type: 'uint256', + }, + { indexed: false, internalType: 'bool', name: 'persist', type: 'bool' }, + ], + name: 'RewardsPerSecondUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [], + name: 'accountedRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'addPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'afterLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'allPendingRewards', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + { internalType: 'uint256[]', name: '_allocPoints', type: 'uint256[]' }, + ], + name: 'batchUpdateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'beforeLockUpdate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bountyManager', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'claimAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'bool', name: '_execute', type: 'bool' }, + ], + name: 'claimBounty', + outputs: [{ internalType: 'bool', name: 'issueBaseBounty', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositedRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibilityEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'eligibilityExempt', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eligibleDataProvider', + outputs: [ + { + internalType: 'contract IEligibilityDataProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'emissionSchedule', + outputs: [ + { internalType: 'uint128', name: 'startTimeOffset', type: 'uint128' }, + { internalType: 'uint128', name: 'rewardsPerSecond', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emissionScheduleIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'endRewardTime', + outputs: [{ internalType: 'uint256', name: 'timestamp', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'uint256', name: '_balance', type: 'uint256' }, + { internalType: 'uint256', name: '_totalSupply', type: 'uint256' }, + ], + name: 'handleActionAfter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_user', type: 'address' }], + name: 'handleActionBefore', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_poolConfigurator', type: 'address' }, + { + internalType: 'contract IEligibilityDataProvider', + name: '_eligibleDataProvider', + type: 'address', + }, + { + internalType: 'contract IMiddleFeeDistribution', + name: '_rewardMinter', + type: 'address', + }, + { internalType: 'uint256', name: '_rewardsPerSecond', type: 'uint256' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAllPoolUpdate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastRPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'address[]', name: '_tokens', type: 'address[]' }, + ], + name: 'pendingRewards', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'persistRewardsPerSecond', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolConfigurator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint256', name: 'totalSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardPerShare', type: 'uint256' }, + { + internalType: 'contract IOnwardIncentivesController', + name: 'onwardIncentives', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'registerRewardDeposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'registeredTokens', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardMinter', + outputs: [ + { + internalType: 'contract IMiddleFeeDistribution', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_bountyManager', type: 'address' }, + ], + name: 'setBountyManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_newVal', type: 'bool' }], + name: 'setEligibilityEnabled', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_contract', type: 'address' }], + name: 'setEligibilityExempt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[]', + name: '_startTimeOffsets', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_rewardsPerSecond', + type: 'uint256[]', + }, + ], + name: 'setEmissionSchedule', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { + internalType: 'contract IOnwardIncentivesController', + name: '_incentives', + type: 'address', + }, + ], + name: 'setOnwardIncentives', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_rewardsPerSecond', type: 'uint256' }, + { internalType: 'bool', name: '_persist', type: 'bool' }, + ], + name: 'setRewardsPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'start', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTime', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'userBaseClaimable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'enterTime', type: 'uint256' }, + { internalType: 'uint256', name: 'lastClaimTime', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/radiant-v2/abiLendingPool.js b/src/adaptors/radiant-v2/abiLendingPool.js new file mode 100644 index 0000000000..a7b1a83709 --- /dev/null +++ b/src/adaptors/radiant-v2/abiLendingPool.js @@ -0,0 +1,739 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRateMode', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowRate', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'onBehalfOf', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint16', + name: 'referral', + type: 'uint16', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'target', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'initiator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'premium', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'referralCode', + type: 'uint16', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'collateralAsset', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'debtAsset', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'debtToCover', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidatedCollateralAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'receiveAToken', + type: 'bool', + }, + ], + name: 'LiquidationCall', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Paused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'RebalanceStableBorrowRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: true, + internalType: 'address', + name: 'repayer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + ], + name: 'ReserveDataUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralDisabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'ReserveUsedAsCollateralEnabled', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'rateMode', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'Unpaused', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'reserve', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'FLASHLOAN_PREMIUM_TOTAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'LENDINGPOOL_REVISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_NUMBER_RESERVES', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_STABLE_RATE_BORROW_SIZE_PERCENT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'interestRateMode', type: 'uint256' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'depositWithAutoDLP', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceFromBefore', type: 'uint256' }, + { internalType: 'uint256', name: 'balanceToBefore', type: 'uint256' }, + ], + name: 'finalizeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiverAddress', type: 'address' }, + { internalType: 'address[]', name: 'assets', type: 'address[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'modes', type: 'uint256[]' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'uint16', name: 'referralCode', type: 'uint16' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAddressesProvider', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.ReserveConfigurationMap', + name: 'configuration', + type: 'tuple', + }, + { internalType: 'uint128', name: 'liquidityIndex', type: 'uint128' }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentLiquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentVariableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'currentStableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { internalType: 'uint8', name: 'id', type: 'uint8' }, + ], + internalType: 'struct DataTypes.ReserveData', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedIncome', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveNormalizedVariableDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservesList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserAccountData', + outputs: [ + { internalType: 'uint256', name: 'totalCollateralETH', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebtETH', type: 'uint256' }, + { internalType: 'uint256', name: 'availableBorrowsETH', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentLiquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { internalType: 'uint256', name: 'healthFactor', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'getUserConfiguration', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'data', type: 'uint256' }, + ], + internalType: 'struct DataTypes.UserConfigurationMap', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { internalType: 'address', name: 'stableDebtAddress', type: 'address' }, + { internalType: 'address', name: 'variableDebtAddress', type: 'address' }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + ], + name: 'initReserve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'leverager', + outputs: [ + { internalType: 'contract ILeverager', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'collateralAsset', type: 'address' }, + { internalType: 'address', name: 'debtAsset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'debtToCover', type: 'uint256' }, + { internalType: 'bool', name: 'receiveAToken', type: 'bool' }, + ], + name: 'liquidationCall', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'rebalanceStableBorrowRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + { internalType: 'address', name: 'onBehalfOf', type: 'address' }, + ], + name: 'repay', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'configuration', type: 'uint256' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ILeverager', + name: '_leverager', + type: 'address', + }, + ], + name: 'setLeverager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_newOwner', type: 'address' }], + name: 'setNewOwner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'val', type: 'bool' }], + name: 'setPause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'rateStrategyAddress', type: 'address' }, + ], + name: 'setReserveInterestRateStrategyAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'bool', name: 'useAsCollateral', type: 'bool' }, + ], + name: 'setUserUseReserveAsCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'rateMode', type: 'uint256' }, + ], + name: 'swapBorrowRateMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/radiant-v2/abiProtocolDataProvider.js b/src/adaptors/radiant-v2/abiProtocolDataProvider.js new file mode 100644 index 0000000000..e7a171f8c1 --- /dev/null +++ b/src/adaptors/radiant-v2/abiProtocolDataProvider.js @@ -0,0 +1,147 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract ILendingPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct AaveProtocolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'availableLiquidity', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/radiant-v2/index.js b/src/adaptors/radiant-v2/index.js new file mode 100644 index 0000000000..61e7adba3e --- /dev/null +++ b/src/adaptors/radiant-v2/index.js @@ -0,0 +1,281 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiLendingPool = require('./abiLendingPool'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider'); +// const abiChefIncentivesController = require('./abiChefIncentivesController'); + +const utils = require('../utils'); + +const RDNT = '0x0c4681e6c0235179ec3d4f4fc4df3d14fdd96017'; + +// note: disabled rewards completely as they require locking of dLP tokens +// https://docs.radiant.capital/radiant/project-info/dlp/dlp-utility +// const earlyExitPenalty = 1 - 0.9; + +const chains = { + arbitrum: { + LendingPool: '0xE23B4AE3624fB6f7cDEF29bC8EAD912f1Ede6886', + ProtocolDataProvider: '0xdd109cb6f2b2aeebce01727a31d99e3149aa7e41', + url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69', + // RIZ Isolated Markets + IsolatedPools: [ + { pool: '0x32F9460386A842E43E3e09fA92Bb77412Aabf42B', provider: '0xFfd5D4606Fc44F80E58F755d3D2198968e293344', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // ZRO/USDC + { pool: '0x0C19836CcD6eAcb9E21693e1f27bde10218b6701', provider: '0x35DCFeCB7Bcc122766Fc5ed9c5e334377a6402C8', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // RDNT/USDC + { pool: '0xf3007F6d241EbF00140b94D92849B5ACf0D36133', provider: '0x43C7F97E9A6056C6BA9140DD1e2DDCF5051441Fe', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // rsETH/WETH + { pool: '0x3fEc9583827431F622A4b188b6c57CfFE8655b8e', provider: '0x368633123723CDbB711da83Fc6Fe7Ed918a4ad7F', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // ezETH/WETH + { pool: '0x6EF47f768aeAe173712Fe6a662666B1DBB08c66F', provider: '0xc4dA16B15c60952dE0a4CD459f42FC634462b689', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // PT-wstETH/WETH + { pool: '0x6B712099ab3Eb192F11E4964b35De8BAA7b15299', provider: '0x58a2d3774aDC5C44f8B5DBa943DefB86dD213a35', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // GMX/USDC + { pool: '0x6B392CeBb1C7f0D93D8CF99a25A21C118b347a16', provider: '0xd2dFe8487feF1361242b295013E29f6cfcA822bA', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // gmARB/USDC + { pool: '0x16910EC43fe08190aD228910B58656243c675822', provider: '0xf4664E39dB8f0A5812c5C6753BFd5d19863A104E', url: '0xacA72b23081f3786159edbca8e5FD2Ae71171C69' }, // USDY/USDC + ], + }, + bsc: { + LendingPool: '0xCcf31D54C3A94f67b8cEFF8DD771DE5846dA032c', + ProtocolDataProvider: '0x499e336041202cd4e55a1979e7511b3211033847', + url: '0x1029a53c7e8e00bf9272533cd1cbec395073a165', + // RIZ Isolated Markets + IsolatedPools: [ + { pool: '0x8E4660b30d09C94Ea77795727c55d69799a9Abd1', provider: '0xbE7C10bf9039Ca3F0A3BfA844A6Ee879bc4C0482', url: '0x1029A53C7e8e00Bf9272533CD1cbEc395073A165' }, // CAKE/USDT + { pool: '0x486a97Dd8341C7590238b583580C78DC9151B8a6', provider: '0xF2e9dD985929Fa37c990F4fae1905023640e36C2', url: '0x1029A53C7e8e00Bf9272533CD1cbEc395073A165' }, // FLOKI/USDT + { pool: '0xc4a09Dd3DcC7D95e0bD525eff7f2968514dE23b2', provider: '0xe986B0F64D97B0EA31542c2b05216326A00EeAEf', url: '0x1029A53C7e8e00Bf9272533CD1cbEc395073A165' }, // slisBNB/WBNB + ], + }, + base: { + LendingPool: '0x30798cFe2CCa822321ceed7e6085e633aAbC492F', + ProtocolDataProvider: '0x07d2DC09A1CbDD01e5f6Ca984b060A3Ff31b9EAF', + url: '0xe7f252d19ab96254144fbb0d94ebc0ff7ea0c541', + // RIZ Isolated Markets + IsolatedPools: [ + { pool: '0x260000459E0D1C46ADE027e552ADc911E0742b50', provider: '0x61CBCE4Fc0cD218Dbd187735399CF3ED98139fEb', url: '0x211DD83F6e49fd63c8Db4dbAeA5358256ACfB350' }, // AERO/USDC + { pool: '0x520411c27a950B731e0D4D5350E0CAEa51b1426F', provider: '0x88d875952a66a7CA396713744517d053Dc4cEf5b', url: '0x211DD83F6e49fd63c8Db4dbAeA5358256ACfB350' }, // wSuperOETHb/WETH + { pool: '0x17042A220b138b203f67fDF62fA7aDD8cB16ccAa', provider: '0x0496F4c03e810b7F640437Bc767f9B2209E454EF', url: '0x211DD83F6e49fd63c8Db4dbAeA5358256ACfB350' }, // ZRO/USDC + { pool: '0xD111c7DA1eBDf4D2fF2d234A61a806b03187CEC9', provider: '0xfa584191f50C61f7FC160d3fA1419Ec0c936204F', url: '0x211DD83F6e49fd63c8Db4dbAeA5358256ACfB350' }, // MAVIA/USDC + { pool: '0x02694DE4B5E0AB3bB9e27Fbd16e4a51E0ECE4cAC', provider: '0x902A2760A0958288093498A74b416eB1C45eC2FE', url: '0x211DD83F6e49fd63c8Db4dbAeA5358256ACfB350' }, // BRETT/USDC + ], + }, + ethereum: { + LendingPool: '0xA950974f64aA33f27F6C5e017eEE93BF7588ED07', + ProtocolDataProvider: '0x362f3BB63Cff83bd169aE1793979E9e537993813', + url: '0x70e507f1d20AeC229F435cd1EcaC6A7200119B9F', + }, +}; + +// Helper function to fetch pools from a specific lending pool +const fetchPoolsFromLendingPool = async (chain, lendingPool, protocolDataProvider, urlSuffix, poolMeta = null) => { + const reservesList = ( + await sdk.api.abi.call({ + target: lendingPool, + abi: abiLendingPool.find((m) => m.name === 'getReservesList'), + chain, + }) + ).output; + + if (!reservesList || reservesList.length === 0) { + return []; + } + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: lendingPool, + params: [i], + })), + abi: abiLendingPool.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' + ? reserveData[i].aTokenAddress + : null, + })), + chain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + // Try to get configuration from ProtocolDataProvider first, fallback to LendingPool's getConfiguration + let reserveConfigurationData; + try { + const configResult = await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: protocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + permitFailure: true, + }); + + // Check if all calls failed + const allFailed = configResult.output.every(o => !o.success || !o.output); + + if (allFailed) { + // Fallback: Use LendingPool's getConfiguration method + const configFromPool = await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: lendingPool, + params: [t], + })), + chain, + abi: abiLendingPool.find((n) => n.name === 'getConfiguration'), + }); + + // Parse configuration data from the returned tuple + reserveConfigurationData = configFromPool.output.map((o) => { + const data = o.output?.data || o.output; + // Decode the configuration bitmap + const ltv = Number((BigInt(data) >> BigInt(0)) & BigInt(0xFFFF)); + const liquidationThreshold = Number((BigInt(data) >> BigInt(16)) & BigInt(0xFFFF)); + const liquidationBonus = Number((BigInt(data) >> BigInt(32)) & BigInt(0xFFFF)); + const decimals = Number((BigInt(data) >> BigInt(48)) & BigInt(0xFF)); + const isActive = ((BigInt(data) >> BigInt(56)) & BigInt(1)) === BigInt(1); + const isFrozen = ((BigInt(data) >> BigInt(57)) & BigInt(1)) === BigInt(1); + const borrowingEnabled = ((BigInt(data) >> BigInt(58)) & BigInt(1)) === BigInt(1); + + return { + ltv, + liquidationThreshold, + liquidationBonus, + decimals, + isActive, + isFrozen, + borrowingEnabled, + }; + }); + } else { + reserveConfigurationData = configResult.output.map((o) => o.output); + } + } catch (error) { + return []; + } + + const pricesArray = reservesList.map((t) => `${chain}:${t}`); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList.map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${chain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + const ltv = config.ltv / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + // url for pools + const url = + `https://app.radiant.capital/#/asset-detail/${t}-${t}${urlSuffix}`.toLowerCase(); + + return { + pool: `${reserveData[i].aTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'radiant-v2', + chain, + tvlUsd, + apyBase, + underlyingTokens: [t], + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: poolMeta || (frozen ? 'frozen' : null), + url: `${url}-Borrow`, + }; + }); +}; + +const getApy = async () => { + const pools = await Promise.allSettled( + Object.keys(chains).map(async (chain) => { + const addresses = chains[chain]; + + // Fetch main pool + const mainPools = await fetchPoolsFromLendingPool( + chain, + addresses.LendingPool, + addresses.ProtocolDataProvider, + addresses.url + ); + + // Fetch isolated pools if they exist + let isolatedPools = []; + if (addresses.IsolatedPools && addresses.IsolatedPools.length > 0) { + const isolatedResults = await Promise.allSettled( + addresses.IsolatedPools.map(isolated => + fetchPoolsFromLendingPool( + chain, + isolated.pool, + isolated.provider, + isolated.url, + 'isolated' + ) + ) + ); + + isolatedPools = isolatedResults + .filter(r => r.status === 'fulfilled') + .map(r => r.value) + .flat(); + } + + // Combine main and isolated pools + return [...mainPools, ...isolatedPools]; + }) + ); + + // Log any rejected chains for debugging + pools.forEach((result, i) => { + const chain = Object.keys(chains)[i]; + if (result.status === 'rejected') { + console.error(`❌ ${chain} failed:`, result.reason?.message || result.reason); + } else if (result.value) { + console.log(`✅ ${chain}: ${result.value.length} pools`); + } + }); + + return pools + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => p !== null && utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/raft/abis/RSavingsRate.json b/src/adaptors/raft/abis/RSavingsRate.json new file mode 100644 index 0000000000..7c123b88c9 --- /dev/null +++ b/src/adaptors/raft/abis/RSavingsRate.json @@ -0,0 +1,28 @@ +{ + "issuanceRate": { + "inputs": [], + "name": "issuanceRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/raft/index.js b/src/adaptors/raft/index.js new file mode 100644 index 0000000000..e12b4c55b9 --- /dev/null +++ b/src/adaptors/raft/index.js @@ -0,0 +1,49 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const rSavingsRateAbi = require('./abis/RSavingsRate.json'); + +const RR = { + ethereum: '0xd2c0c4A6296D416C5Eb6Ae41d17aC4Db4bDD5296', + base: '0xA5b3FEe253f9DE67201dC8572Bd2CbB4a81c1bEc', +}; +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; + +async function chainApy(chain) { + const issuanceRate = await sdk.api.abi.call({ + target: RR[chain], + chain, + abi: rSavingsRateAbi.issuanceRate, + }); + const totalAssets = await sdk.api.abi.call({ + target: RR[chain], + chain, + abi: rSavingsRateAbi.totalAssets, + }); + + const apy = + 100 * + BigNumber(issuanceRate.output).times(SECONDS_PER_YEAR).div(1e18).toNumber(); + const tvlUsd = BigNumber(totalAssets.output).div(1e18).toNumber(); + + return { + pool: `${RR[chain]}-${chain}`.toLowerCase(), + project: 'raft', + symbol: 'R', + chain: utils.formatChain(chain), + poolMeta: 'R Savings Rate', + apy, + tvlUsd, + }; +} + +async function apy() { + return Promise.all(['ethereum', 'base'].map(chainApy)); +} + +module.exports = { + apy, + url: 'https://app.raft.fi/savings', +}; diff --git a/src/adaptors/rage-trade/index.js b/src/adaptors/rage-trade/index.js new file mode 100644 index 0000000000..8274ffbb4b --- /dev/null +++ b/src/adaptors/rage-trade/index.js @@ -0,0 +1,111 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils'); + +const getVaultMarketValue = { + inputs: [], + name: 'getVaultMarketValue', + outputs: [ + { + internalType: 'int256', + name: 'vaultMarketValue', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const addresses = { + tricryptoVault: '0x1d42783E7eeacae12EbC315D1D2D0E3C6230a068', + dnGmxJuniorVault: '0x8478AB5064EbAC770DdCE77E7D31D969205F041E', + dnGmxSeniorVault: '0xf9305009FbA7E381b3337b5fA157936d73c2CF36', +}; + +const poolsFunction = async () => { + const tvls = Object.fromEntries( + await Promise.all( + Object.entries(addresses).map(async ([name, address]) => { + let res = ( + await sdk.api.abi.call({ + abi: getVaultMarketValue, + target: address, + chain: 'arbitrum', + }) + ).output; + return [name, Number(ethers.utils.formatUnits(res, 6))]; + }) + ) + ); + + const tricryptoVaultApyData = await utils.getData( + 'https://apis.rage.trade/data/v2/get-tricrypto-vault-apy?networkName=arbmain' + ); + + const dnVaultsApyData = await utils.getData( + 'https://apis.rage.trade/data/v2/get-dn-gmx-apy-breakdown?networkName=arbmain' + ); + + const apys = { + tricryptoVault: { + base: + (tricryptoVaultApyData.result.tricryptoLpFees + + tricryptoVaultApyData.result.rageLpFees) * + 100, + reward: tricryptoVaultApyData.result.crvEmissions * 100, + }, + dnGmxJuniorVault: { + base: + dnVaultsApyData.result.juniorVault.glpTraderPnl + + dnVaultsApyData.result.juniorVault.btcBorrowApy + + dnVaultsApyData.result.juniorVault.ethBorrowApy, + reward: + dnVaultsApyData.result.juniorVault.glpRewardsPct + + dnVaultsApyData.result.juniorVault.esGmxRewards, + }, + dnGmxSeniorVault: { + base: dnVaultsApyData.result.seniorVault.aaveSupplyApy, + reward: dnVaultsApyData.result.seniorVault.glpRewardsPct, + }, + }; + + const tricryptoVault = { + pool: '0x1d42783E7eeacae12EbC315D1D2D0E3C6230a068', + chain: utils.formatChain('arbitrum'), + project: 'rage-trade', + symbol: utils.formatSymbol('80-20-Tricrypto'), + tvlUsd: tvls.tricryptoVault, + underlyingTokens: ['0x8e0B8c8BB9db49a46697F3a5Bb8A308e744821D2'], // tricrypto + apy: apys.tricryptoVault.base + apys.tricryptoVault.reward, + }; + + const dnGmxJuniorVault = { + pool: '0x8478AB5064EbAC770DdCE77E7D31D969205F041E', + chain: utils.formatChain('arbitrum'), + project: 'rage-trade', + symbol: 'GLP', + tvlUsd: tvls.dnGmxJuniorVault, + poolMeta: 'DN_GMX_JUNIOR', + underlyingTokens: ['0x2F546AD4eDD93B956C8999Be404cdCAFde3E89AE'], // sglp + apy: apys.dnGmxJuniorVault.base + apys.dnGmxJuniorVault.reward, + }; + + const dnGmxSeniorVault = { + pool: '0xf9305009FbA7E381b3337b5fA157936d73c2CF36', + chain: utils.formatChain('arbitrum'), + project: 'rage-trade', + symbol: utils.formatSymbol('USDC'), + tvlUsd: tvls.dnGmxSeniorVault, + poolMeta: 'DN_GMX_SENIOR', + underlyingTokens: ['0xff970a61a04b1ca14834a43f5de4533ebddb5cc8'], // usdc + apy: apys.dnGmxSeniorVault.base + apys.dnGmxSeniorVault.reward, + }; + + return [tricryptoVault, dnGmxJuniorVault, dnGmxSeniorVault]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.rage.trade/vaults', +}; diff --git a/src/adaptors/ramses-cl/abiGauge.json b/src/adaptors/ramses-cl/abiGauge.json new file mode 100644 index 0000000000..acc97ba512 --- /dev/null +++ b/src/adaptors/ramses-cl/abiGauge.json @@ -0,0 +1,449 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "name": "Bribe", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_positionHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "period", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "bool", "name": "caching", "type": "bool" } + ], + "name": "cachePeriodEarned", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "earned", + "outputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeCollector", + "outputs": [ + { + "internalType": "contract IFeeCollector", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "firstPeriod", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" }, + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "getPeriodReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "getPeriodReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getRewardForOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardTokens", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gaugeFactory", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "address", "name": "_nfpManager", "type": "address" }, + { "internalType": "address", "name": "_feeCollector", "type": "address" }, + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bytes32", "name": "", "type": "bytes32" } + ], + "name": "lastClaimByToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nfpManager", + "outputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bytes32", "name": "", "type": "bytes32" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "periodClaimedAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "periodEarned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "periodEarned", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "periodTotalBoostedSeconds", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IRamsesV2Pool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "positionHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "positionInfo", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint128", + "name": "boostedLiquidity", + "type": "uint128" + }, + { "internalType": "uint256", "name": "veRamTokenId", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewards", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "tokenTotalSupplyByPeriod", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "veRamTokenId", "type": "uint256" } + ], + "name": "veRamInfo", + "outputs": [ + { "internalType": "uint128", "name": "timesAttached", "type": "uint128" }, + { + "internalType": "uint128", + "name": "veRamBoostUsedRatio", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/ramses-cl/abiPair.json b/src/adaptors/ramses-cl/abiPair.json new file mode 100644 index 0000000000..5165c64bf6 --- /dev/null +++ b/src/adaptors/ramses-cl/abiPair.json @@ -0,0 +1,982 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" } + ], + "name": "boostInfos", + "outputs": [ + { + "internalType": "uint128", + "name": "totalBoostAmount", + "type": "uint128" + }, + { "internalType": "int128", "name": "totalVeRamAmount", "type": "int128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "bytes32", "name": "key", "type": "bytes32" } + ], + "name": "boostInfos", + "outputs": [ + { "internalType": "uint128", "name": "boostAmount", "type": "uint128" }, + { "internalType": "int128", "name": "veRamAmount", "type": "int128" }, + { "internalType": "int256", "name": "secondsDebtX96", "type": "int256" }, + { + "internalType": "int256", + "name": "boostedSecondsDebtX96", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boostedLiquidity", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" } + ], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" } + ], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "uint256", "name": "veRamTokenId", "type": "uint256" } + ], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { "internalType": "uint128", "name": "amount0", "type": "uint128" }, + { "internalType": "uint128", "name": "amount1", "type": "uint128" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_nfpManager", "type": "address" }, + { "internalType": "address", "name": "_veRam", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" }, + { "internalType": "uint24", "name": "_fee", "type": "uint24" }, + { "internalType": "int24", "name": "_tickSpacing", "type": "int24" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastPeriod", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" }, + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "uint256", "name": "veRamTokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nfpManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "observations", + "outputs": [ + { "internalType": "uint32", "name": "blockTimestamp", "type": "uint32" }, + { "internalType": "int56", "name": "tickCumulative", "type": "int56" }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { "internalType": "bool", "name": "initialized", "type": "bool" }, + { + "internalType": "uint160", + "name": "secondsPerBoostedLiquidityPeriodX128", + "type": "uint160" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32[]", "name": "secondsAgos", "type": "uint32[]" } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerBoostedLiquidityPeriodX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "period", "type": "uint32" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "periodCumulativesInside", + "outputs": [ + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "secondsPerBoostedLiquidityInsideX128", + "type": "uint160" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" } + ], + "name": "periods", + "outputs": [ + { "internalType": "uint32", "name": "previousPeriod", "type": "uint32" }, + { "internalType": "int24", "name": "startTick", "type": "int24" }, + { "internalType": "int24", "name": "lastTick", "type": "int24" }, + { + "internalType": "uint160", + "name": "endSecondsPerLiquidityPeriodX128", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "endSecondsPerBoostedLiquidityPeriodX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "boostedInRange", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "positionPeriodDebt", + "outputs": [ + { "internalType": "int256", "name": "secondsDebtX96", "type": "int256" }, + { + "internalType": "int256", + "name": "boostedSecondsDebtX96", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "period", "type": "uint256" }, + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" }, + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "positionPeriodSecondsInRange", + "outputs": [ + { + "internalType": "uint256", + "name": "periodSecondsInsideX96", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodBoostedSecondsInsideX96", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "key", "type": "bytes32" }], + "name": "positions", + "outputs": [ + { "internalType": "uint128", "name": "liquidity", "type": "uint128" }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, + { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" }, + { + "internalType": "uint256", + "name": "attachedVeRamId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { "internalType": "uint128", "name": "token0", "type": "uint128" }, + { "internalType": "uint128", "name": "token1", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32[]", "name": "slots", "type": "bytes32[]" } + ], + "name": "readStorage", + "outputs": [ + { "internalType": "bytes32[]", "name": "returnData", "type": "bytes32[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, + { "internalType": "int24", "name": "tick", "type": "int24" }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { "internalType": "uint8", "name": "feeProtocol", "type": "uint8" }, + { "internalType": "bool", "name": "unlocked", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int24", "name": "tickLower", "type": "int24" }, + { "internalType": "int24", "name": "tickUpper", "type": "int24" } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "secondsPerBoostedLiquidityInsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsInside", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "recipient", "type": "address" }, + { "internalType": "bool", "name": "zeroForOne", "type": "bool" }, + { "internalType": "int256", "name": "amountSpecified", "type": "int256" }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [ + { "internalType": "int256", "name": "amount0", "type": "int256" }, + { "internalType": "int256", "name": "amount1", "type": "int256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "int16", "name": "tick", "type": "int16" }], + "name": "tickBitmap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "int24", "name": "tick", "type": "int24" }], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { "internalType": "int128", "name": "liquidityNet", "type": "int128" }, + { + "internalType": "uint128", + "name": "boostedLiquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "boostedLiquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { "internalType": "uint32", "name": "secondsOutside", "type": "uint32" }, + { "internalType": "bool", "name": "initialized", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "veRam", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/ramses-cl/abiPairFactory.json b/src/adaptors/ramses-cl/abiPairFactory.json new file mode 100644 index 0000000000..08bf07bbd6 --- /dev/null +++ b/src/adaptors/ramses-cl/abiPairFactory.json @@ -0,0 +1,485 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "_pairImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "address", + "name": "msig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pairFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setPairFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_state", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pauser", + "type": "address" + } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ramses-cl/abiVoter.json b/src/adaptors/ramses-cl/abiVoter.json new file mode 100644 index 0000000000..7b8cf868b8 --- /dev/null +++ b/src/adaptors/ramses-cl/abiVoter.json @@ -0,0 +1,871 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeDistributer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clGaugeFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256[][]", + "name": "_nfpTokenIds", + "type": "uint256[][]" + } + ], + "name": "claimClGaugeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_fees", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "createCLGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distro", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "feeDistributers", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeDistributorFactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "fromTokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "toTokenId", "type": "uint256" } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "address[][]", + "name": "tokensVotes", + "type": "address[][]" + }, + { + "internalType": "uint256[][]", + "name": "tokensWeights", + "type": "uint256[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_gauges", "type": "address" }, + { + "internalType": "address", + "name": "_feeDistributorFactory", + "type": "address" + }, + { "internalType": "address", "name": "_minter", "type": "address" }, + { "internalType": "address", "name": "_msig", "type": "address" }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nfpManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "address[]", "name": "_rewards", "type": "address[]" } + ], + "name": "removeGaugeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "fromTokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "toTokenId", "type": "uint256" } + ], + "name": "resetVotes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_clFactory", "type": "address" }, + { + "internalType": "address", + "name": "_clGaugeFactory", + "type": "address" + } + ], + "name": "setClFactories", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setNfpManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "address[]", "name": "_rewards", "type": "address[]" } + ], + "name": "whitelistGaugeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/ramses-cl/estimateFee.ts b/src/adaptors/ramses-cl/estimateFee.ts new file mode 100644 index 0000000000..2aced15efb --- /dev/null +++ b/src/adaptors/ramses-cl/estimateFee.ts @@ -0,0 +1,322 @@ +// forked from uniswap.fish chads (see https://github.com/chunza2542/uniswap.fish) + +const bn = require('bignumber.js'); +const axios = require('axios'); + +interface Tick { + tickIdx: string; + liquidityNet: string; + price0: string; + price1: string; +} + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = ( + price: number, + token0Decimal: string, + token1Decimal: string +): number => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +const getPriceFromTick = ( + tick: number, + token0Decimal: string, + token1Decimal: string +): number => { + const sqrtPrice = new bn(Math.pow(Math.sqrt(1.0001), tick)).multipliedBy( + new bn(2).pow(96) + ); + const token0 = expandDecimals(1, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const L2 = mulDiv( + encodeSqrtPriceX96(token0), + encodeSqrtPriceX96(token1), + Q96 + ); + const price = mulDiv(L2, Q96, sqrtPrice) + .div(new bn(2).pow(96)) + .div(new bn(10).pow(token0Decimal)) + .pow(2); + + return price.toNumber(); +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 1) +interface TokensAmount { + amount0: number; + amount1: number; +} +const getTokensAmountFromDepositAmountUSD = ( + P: number, + Pl: number, + Pu: number, + priceUSDX: number, + priceUSDY: number, + depositAmountUSD: number +): TokensAmount => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount0: bn +): bn => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount1: bn +): bn => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = ( + price: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P: number, + lowerP: number, + upperP: number, + amount0: number, + amount1: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity: bn; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +const estimateFee = ( + liquidityDelta: bn, + liquidity: bn, + volume24H: number, + feeTier: string +): number => { + const feeTierPercentage = getFeeTierPercentage(feeTier); + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + + return feeTierPercentage * volume24H * liquidityPercentage; +}; + +const getLiquidityFromTick = (poolTicks: Tick[], tick: number): bn => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity: bn = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price: number | string | bn): bn => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n: number | string | bn, exp: number): bn => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a: bn, b: bn, multiplier: bn) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getFeeTierPercentage = (tier: string): number => { + if (tier === '100') return 0.01 / 100; + if (tier === '500') return 0.05 / 100; + if (tier === '3000') return 0.3 / 100; + if (tier === '10000') return 1 / 100; + return 0; +}; + +const getPoolTicks = async ( + poolAddress: string, + url: string +): Promise => { + const PAGE_SIZE = 3; + let result: Tick[] = []; + let page = 0; + while (true) { + const pool1 = await _getPoolTicksByPage(poolAddress, page, url); + const pool2 = await _getPoolTicksByPage(poolAddress, page + 1, url); + const pool3 = await _getPoolTicksByPage(poolAddress, page + 2, url); + + result = [...result, ...pool1, ...pool2, ...pool3]; + if (pool1.length === 0 || pool2.length === 0 || pool3.length === 0) { + break; + } + page += PAGE_SIZE; + } + return result; +}; + +const _getPoolTicksByPage = async ( + poolAddress: string, + page: number, + url: string +): Promise => { + let res; + try { + res = await _queryUniswap( + `{ + ticks(first: 1000, skip: ${ + page * 1000 + }, where: { poolAddress: "${poolAddress}" }, orderBy: tickIdx) { + tickIdx + liquidityNet + price0 + price1 + } + }`, + url + ); + } catch (e) { + console.log('_getPoolTicksByPage failed for', poolAddress); + return []; + } + + return res === undefined ? [] : res.ticks; +}; + +const _queryUniswap = async (query: string, url: string): Promise => { + const { data } = await axios({ + url, + method: 'post', + data: { + query, + }, + }); + + return data.data; +}; + +module.exports.EstimatedFees = async ( + poolAddress, + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + feeTier, + url, + volume +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + const poolTicks = await getPoolTicks(poolAddress, url); + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${poolAddress}`); + return { poolAddress, estimatedFee: 0 }; + } + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const estimatedFee = + P >= Pl && P <= Pu ? estimateFee(deltaL, L, volume, feeTier) : 0; + + return { poolAddress, estimatedFee }; +}; diff --git a/src/adaptors/ramses-cl/index.js b/src/adaptors/ramses-cl/index.js new file mode 100644 index 0000000000..06d22f5e6e --- /dev/null +++ b/src/adaptors/ramses-cl/index.js @@ -0,0 +1,328 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xAAA20D08e59F6561f242b08513D36266C5A29415'; +const voter = '0xAAA2564DEb34763E3d05162ed3f5C2658691f499'; +const RAM = '0xAAA6C1E32C55A7Bfa8066A6FAE9b42650F262418'; +const chains = { + arbitrum: sdk.graph.modifyEndpoint( + 'ATQTt3wRTgXy4canCh6t1yeczAz4ZuEkFQL2mrLXEMyQ' + ), +}; + +const superagent = require('superagent'); +const { EstimatedFees } = require('./estimateFee'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); +const { getCdpTotalSupply } = require('../nitron/helper'); + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // uni v3 subgraph reserves values are wrong! + // instead of relying on subgraph values, gonna pull reserve data from contracts + // new tvl calc + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: dataNow.map((p) => ({ + target: voter, + params: [p.id], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [RAM], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: dataNow.map((p) => ({ + target: p.id, + })), + abi: abiPair.find((m) => m.name === 'boostedLiquidity'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + dataNow = dataNow.map((p, i) => { + const x = tokenBalances.output.filter( + (item) => item.input.params[0] === p.id + ); + + return { + ...p, + reserve0: + x.find((item) => item.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((item) => item.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + supply: totalSupply[i], + gauge: gauges[i], + reward: rewardRate[i], + }; + }); + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + dataNow = dataNow.map((el, i) => + utils.apy(el, dataPrior, dataPrior7d, version, i) + ); + + const enableV3Apy = false; + if (enableV3Apy && chainString !== 'arbitrum') { + dataNow = dataNow.map((p, i) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + volumeUSD7d: dataPrior7d[i].volumeUSD, + })); + + // split up subgraph tick calls into n-batches + // (tick response can be in the thousands per pool) + const skip = 20; + let start = 0; + let stop = skip; + const pages = Math.floor(dataNow.length / skip); + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + let X = []; + for (let i = 0; i <= pages; i++) { + console.log(i); + let promises = dataNow.slice(start, stop).map((p) => { + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + return EstimatedFees( + p.id, + priceAssumption, + [ + p.token1_in_token0 * (1 - delta), + p.token1_in_token0 * (1 + delta), + ], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + url, + p.volumeUSD7d + ); + }); + X.push(await Promise.all(promises)); + start += skip; + stop += skip; + } + const d = {}; + X.flat().forEach((p) => { + d[p.poolAddress] = p.estimatedFee; + }); + + dataNow = dataNow.map((p) => ({ + ...p, + apy7d: ((d[p.id] * 52) / investmentAmount) * 100, + })); + } + + const tokenReward = 'arbitrum:0xAAA6C1E32C55A7Bfa8066A6FAE9b42650F262418'; + + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/arbitrum:0xAAA6C1E32C55A7Bfa8066A6FAE9b42650F262418` + ) + ).data.coins; + + return dataNow.map((p, i) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + const pairPrice = (p.totalValueLockedUSD * 1e18) / p.supply; + const totalRewardPerDay = + ((p.reward * 86400 * 4) / 1e18) * prices[tokenReward]?.price; + const apyReward = (totalRewardPerDay * 36500) / p.totalValueLockedUSD; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://cl.ramses.exchange/#/add/${token0}/${token1}/${feeTier}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'ramses-cl', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol: p.symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d * 0.25, + apyBase7d: p.apy7d * 0.25, + apyReward: apyReward, + rewardTokens: apyReward ? [RAM] : [], + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/ramses-hl/index.js b/src/adaptors/ramses-hl/index.js new file mode 100644 index 0000000000..e90e13b188 --- /dev/null +++ b/src/adaptors/ramses-hl/index.js @@ -0,0 +1,150 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const RAM = '0x13A466998Ce03Db73aBc2d4DF3bBD845Ed1f28E7'; +const PROJECT = 'ramses-hl'; +const CHAIN = 'hyperliquid'; +const SUBGRAPH = 'https://hyperevm.kingdomsubgraph.com/subgraphs/name/ramses-v3-pruned/'; + +const poolsQuery = gql` + query getPools($first: Int!, $skip: Int!) { + clPools( + first: $first + skip: $skip + orderBy: totalValueLockedUSD + orderDirection: desc + where: { gauge_not: null } + ) { + id + token0 { + id + symbol + } + token1 { + id + symbol + } + feeTier + tickSpacing + totalValueLockedUSD + gauge { + id + } + poolDayData(first: 7, orderBy: startOfDay, orderDirection: desc) { + volumeUSD + } + } + } +`; + +async function fetchAllPools() { + let allPools = []; + let skip = 0; + const first = 1000; + + while (true) { + const poolsData = await request(SUBGRAPH, poolsQuery, { first, skip }); + const pools = poolsData.clPools; + + if (pools.length === 0) break; + + allPools = allPools.concat(pools); + + if (pools.length < first) break; + + skip += first; + } + + return allPools; +} + +async function apy() { + try { + const pools = await fetchAllPools(); + + let ramsesPools = []; + try { + const ramsesApiData = await axios.get('https://api2.ramses.xyz/all-pools'); + if (ramsesApiData.data && Array.isArray(ramsesApiData.data.pools)) { + ramsesPools = ramsesApiData.data.pools; + } + } catch (error) { + console.error('Failed to fetch Ramses API data:', error.message); + } + + const aprMap = {}; + for (const pool of ramsesPools) { + if (pool.id) { + aprMap[pool.id.toLowerCase()] = { + lpApr: Number(pool.lpApr) || 0 + }; + } + } + + const results = []; + + for (const pool of pools) { + const tvlUsd = Number(pool.totalValueLockedUSD) || 0; + + if (!pool.gauge?.id) continue; + + const poolAddress = pool.id.toLowerCase(); + const apiData = aprMap[poolAddress]; + + if (!apiData) continue; + + const apyBase = 0; + let apyReward = 0; + const tickSpacing = parseInt(pool.tickSpacing); + + const apiPool = ramsesPools.find(p => p.id.toLowerCase() === poolAddress); + if (apiPool && apiPool.recommendedRanges) { + if (tickSpacing === 1 || tickSpacing === 5) { + const wideRange = apiPool.recommendedRanges.find(range => range.name === 'Wide'); + apyReward = wideRange ? wideRange.lpApr : apiData.lpApr || 0; + } else { + const narrowRange = apiPool.recommendedRanges.find(range => range.name === 'Narrow'); + apyReward = narrowRange ? narrowRange.lpApr : apiData.lpApr || 0; + } + } else { + apyReward = apiData.lpApr || 0; + } + + results.push({ + pool: `${poolAddress}-${utils.formatChain(CHAIN)}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT, + poolMeta: `CL ${(Number(pool.feeTier) / 10000).toFixed(2)}%`, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd, + apyBase, + apyBase7d: 0, + apyReward, + rewardTokens: apyReward > 0 ? [RAM] : [], + underlyingTokens: [ + pool.token0.id.toLowerCase(), + pool.token1.id.toLowerCase() + ], + url: `https://www.ramses.xyz/liquidity/${poolAddress}`, + volumeUsd1d: pool.poolDayData?.[0]?.volumeUSD + ? Number(pool.poolDayData[0].volumeUSD) + : 0, + volumeUsd7d: pool.poolDayData + ? pool.poolDayData.reduce((sum, day) => sum + Number(day.volumeUSD || 0), 0) + : 0, + }); + } + + return results.filter((p) => utils.keepFinite(p)); + + } catch (error) { + console.error('Error fetching Ramses CL data:', error); + return []; + } +} + +module.exports = { + timetravel: false, + apy: apy, +}; \ No newline at end of file diff --git a/src/adaptors/ramses-legacy/abiGauge.json b/src/adaptors/ramses-legacy/abiGauge.json new file mode 100644 index 0000000000..c6c1b192f5 --- /dev/null +++ b/src/adaptors/ramses-legacy/abiGauge.json @@ -0,0 +1,856 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "derivedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "derivedBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "derivedSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeDistributor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getRewardTokenIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stake", + "type": "address" + }, + { + "internalType": "address", + "name": "_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_forPair", + "type": "bool" + }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isStarted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pendingRewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "duplicateIndex", + "type": "uint256" + } + ], + "name": "removeExtraRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "removeRewardWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "rescueTrappedFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "storedRewardsPerUser", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "whitelistNotifiedRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ramses-legacy/abiPair.json b/src/adaptors/ramses-legacy/abiPair.json new file mode 100644 index 0000000000..831cb3c121 --- /dev/null +++ b/src/adaptors/ramses-legacy/abiPair.json @@ -0,0 +1,1041 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ramses-legacy/abiPairFactory.json b/src/adaptors/ramses-legacy/abiPairFactory.json new file mode 100644 index 0000000000..08bf07bbd6 --- /dev/null +++ b/src/adaptors/ramses-legacy/abiPairFactory.json @@ -0,0 +1,485 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_proxyAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "_pairImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "address", + "name": "msig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pairFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "name": "setImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setPairFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_state", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pauser", + "type": "address" + } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ramses-legacy/abiVoter.json b/src/adaptors/ramses-legacy/abiVoter.json new file mode 100644 index 0000000000..974b0ec181 --- /dev/null +++ b/src/adaptors/ramses-legacy/abiVoter.json @@ -0,0 +1,1297 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeDistributer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clGaugeFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_bribes", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_fees", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "createCLGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "createGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "finish", + "type": "uint256" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distro", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "feeDistributers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeDistributorFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gauges", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fromTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "toTokenId", + "type": "uint256" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "address[][]", + "name": "tokensVotes", + "type": "address[][]" + }, + { + "internalType": "uint256[][]", + "name": "tokensWeights", + "type": "uint256[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauges", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeDistributorFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_minter", + "type": "address" + }, + { + "internalType": "address", + "name": "_msig", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAlive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isGauge", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lastVoted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolForGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolVote", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_rewards", + "type": "address[]" + } + ], + "name": "removeGaugeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fromTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "toTokenId", + "type": "uint256" + } + ], + "name": "resetVotes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_clFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_clGaugeFactory", + "type": "address" + } + ], + "name": "setClFactories", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_council", + "type": "address" + } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usedWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_poolVote", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_weights", + "type": "uint256[]" + } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "weights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_rewards", + "type": "address[]" + } + ], + "name": "whitelistGaugeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/ramses-legacy/index.js b/src/adaptors/ramses-legacy/index.js new file mode 100644 index 0000000000..c5c04066b8 --- /dev/null +++ b/src/adaptors/ramses-legacy/index.js @@ -0,0 +1,174 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xAAA20D08e59F6561f242b08513D36266C5A29415'; +const voter = '0xAAA2564DEb34763E3d05162ed3f5C2658691f499'; +const RAM = '0xAAA6C1E32C55A7Bfa8066A6FAE9b42650F262418'; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: 'arbitrum', + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [RAM], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const derivedSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'derivedSupply'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + })), + abi: abiGauge.find((m) => m.name === 'totalSupply'), + chain: 'arbitrum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(RAM) + ), + ]; + const priceKeys = tokens.map((i) => `arbitrum:${i}`).join(','); + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let keys = ''; + for (const p of [...Array(pages).keys()]) { + keys = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `arbitrum:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${keys}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA) { + prices = { ...prices, ...p }; + } + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`arbitrum:${poolMeta.t0}`]?.price; + const p1 = prices[`arbitrum:${poolMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const pairPrice = (tvlUsd * 1e18) / totalSupply[i]; + const totalRewardPerDay = + ((rewardRate[i] * 86400) / 1e18) * prices[`arbitrum:${RAM}`]?.price; + + const apyReward = + (totalRewardPerDay * 36500) / + ((derivedSupply[i] * pairPrice) / 1e18) / + 2.5; + + return { + pool: p, + chain: utils.formatChain('arbitrum'), + project: 'ramses-legacy', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [RAM] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.ramses.exchange/liquidity', +}; diff --git a/src/adaptors/ratio-finance/index.ts b/src/adaptors/ratio-finance/index.ts new file mode 100644 index 0000000000..6e310f4c86 --- /dev/null +++ b/src/adaptors/ratio-finance/index.ts @@ -0,0 +1,55 @@ +const axios = require('axios').default; + +const utils = require('../utils'); + +const API_URL = 'https://mainbackend.ratio.finance/lpairs'; + +interface Pool { + address_id: string, + symbol: string, + tvlUsd: number; + ratioAPR: number; + baseAPR: number; + assets: [{ mint: string, account: string}], + status: string; + platform_name: string; +} + +type Pools = Array; + +const apy = async () => { + const data: Pools = (await axios.get(API_URL)).data; + const filteredData = data.filter( + (pool) => { + return pool.status == 'true' + }); + const pools = filteredData.map( + (pool) => { + let assets = pool.assets.map((assets) => { + return assets.mint + }) + let result: any = { + pool: `${pool.address_id}-solana`.toLowerCase(), + chain: utils.formatChain('solana'), + project: 'ratio-finance', + symbol: pool.symbol, + tvlUsd: pool.tvlUsd, + apyBase: pool.baseAPR, + apyReward: pool.ratioAPR, + underlyingTokens: assets, + poolMeta: 'Platform: ' + pool.platform_name, + }; + if (result.apyReward != 0) { + result.rewardTokens = ['ratioMVg27rSZbSvBopUvsdrGUzeALUfFma61mpxc8J'] + } + return result + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.ratio.finance/dashboard/available-vaults', +}; diff --git a/src/adaptors/raydium-amm/index.js b/src/adaptors/raydium-amm/index.js new file mode 100644 index 0000000000..3e8d3b7412 --- /dev/null +++ b/src/adaptors/raydium-amm/index.js @@ -0,0 +1,37 @@ +const utils = require('../utils'); + +const API_URL = + 'https://api-v3.raydium.io/pools/info/list?poolType=all&poolSortField=default&sortType=desc&pageSize=1000&page=1'; + +const apy = async () => { + const data = (await utils.getData(API_URL)).data.data; + + return data.map((pool) => { + const apyReward = pool.day.rewardApr.reduce((v, acc) => v + acc, 0); + return { + pool: pool.id, + chain: 'Solana', + project: 'raydium-amm', + symbol: `${pool.mintA.symbol}-${pool.mintB.symbol}`, + tvlUsd: pool.tvl, + apyBase: pool.day.feeApr, + apyReward, + rewardTokens: + apyReward > 0 + ? pool?.rewardDefaultInfos?.map((r) => r.mint?.address) + : [], + apyBase7d: pool.week.feeApr, + volumeUsd1d: pool.day.volume, + volumeUsd7d: pool.week.volume, + poolMeta: `${pool.type} - ${pool.feeRate * 100}%`, + url: + pool.type.toLowerCase() === 'concentrated' + ? `https://raydium.io/clmm/create-position/?pool_id=${pool.id}` + : `https://raydium.io/liquidity/increase/?mode=add&pool_id=${pool.id}`, + }; + }); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/realt-tokens/abi.json b/src/adaptors/realt-tokens/abi.json new file mode 100644 index 0000000000..d20e78091f --- /dev/null +++ b/src/adaptors/realt-tokens/abi.json @@ -0,0 +1,215 @@ +{ + "getReservesData": { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "getReservesData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseLTVasCollateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactor", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowingEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isFrozen", + "type": "bool" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "liquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "stableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPrincipalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableDebtLastUpdateTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalScaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInMarketReferenceCurrency", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableRateSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableRateSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableRateSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableRateSlope2", + "type": "uint256" + } + ], + "internalType": "struct IUiPoolDataProvider.AggregatedReserveData[]", + "name": "", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "marketReferenceCurrencyUnit", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "marketReferenceCurrencyPriceInUsd", + "type": "int256" + }, + { + "internalType": "int256", + "name": "networkBaseTokenPriceInUsd", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "networkBaseTokenPriceDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUiPoolDataProvider.BaseCurrencyInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/realt-tokens/index.js b/src/adaptors/realt-tokens/index.js new file mode 100644 index 0000000000..f54c312cd4 --- /dev/null +++ b/src/adaptors/realt-tokens/index.js @@ -0,0 +1,132 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const abi = require('./abi.json'); + +const SECONDS_PER_YEAR = BigNumber('31536000'); + +const USD_DECIMALS = 8; +const WEI_DECIMALS = 18; +const RAY_DECIMALS = 27; +const RAY_DECIMALS_PERCENTAGE = 29; +const LTV_PRECISION = 4; + +const RAY = BigNumber(10).pow(27); +const HALF_RAY = RAY.div(2); + +const chains = { + 100: 'xdai', +}; + +function rayMul(a, b) { + return HALF_RAY.plus(a.multipliedBy(b)).div(RAY); +} + +function calculateCompoundedInterest( + rate, + currentTimestamp, + lastUpdateTimestamp +) { + let compounded = BigNumber(0); + const timeDelta = BigNumber(currentTimestamp - lastUpdateTimestamp); + const ratePerSecond = BigNumber(rate).div(SECONDS_PER_YEAR); + if (timeDelta.gt(0)) { + const base = ratePerSecond; + const exp = timeDelta; + const expMinusOne = exp.minus(1); + const expMinusTwo = exp.gt(2) ? exp.minus(2) : 0; + const basePowerTwo = rayMul(base, base); + const basePowerThree = rayMul(basePowerTwo, base); + + const firstTerm = exp.multipliedBy(base); + const secondTerm = exp + .multipliedBy(expMinusOne) + .multipliedBy(basePowerTwo) + .div(2); + const thirdTerm = exp + .multipliedBy(expMinusOne) + .multipliedBy(expMinusTwo) + .multipliedBy(basePowerThree) + .div(6); + + compounded = RAY.plus(firstTerm).plus(secondTerm).plus(thirdTerm); + } + return compounded; +} + +async function callGetReservesData() { + let res = ( + await sdk.api.abi.call({ + abi: abi.getReservesData, + // NOTE that target is an AAVE-based UIPoolDataProvider address + target: '0x31d341fc1f2172a37e8fc4a6606e2f6620239feb', + // with param being the ILendingPoolAddressesProvider for RealT + params: ['0x0ade75f269a054673883319baa50e5e0360a775f'], + chain: chains[100].toLowerCase(), + }) + ).output; + + // Only WXDai is lendable + let wxdai = res[0]['0']; + + //console.log(sdk) + let latest_block = await sdk.api.util.getLatestBlock('xdai'); + + // get compoundeds of variable/stable borrow rates + let variableCompounded = calculateCompoundedInterest( + wxdai.variableBorrowRate, + latest_block.timestamp, + wxdai.lastUpdateTimestamp + ); + let stableCompounded = calculateCompoundedInterest( + wxdai.averageStableRate, + latest_block.timestamp, + wxdai.stableDebtLastUpdateTimestamp + ); + + // Needed to calc scaled -> non-scaled variable debt + let bigVariableBorrowIndex = BigNumber(wxdai.variableBorrowIndex); + + let totalVariableDebt = rayMul( + BigNumber(wxdai.totalScaledVariableDebt), + bigVariableBorrowIndex + ); + let totalStableDebt = BigNumber(wxdai.totalPrincipalStableDebt); + + if (variableCompounded.gt(0)) + totalVariableDebt = rayMul(totalVariableDebt, variableCompounded); + if (stableCompounded.gt(0)) + totalStableDebt = rayMul(totalStableDebt, stableCompounded); + + return [ + { + pool: wxdai.underlyingAsset + '-realt', + chain: utils.formatChain('xdai'), + project: 'realt-tokens', + symbol: wxdai.symbol, + tvlUsd: totalVariableDebt + .plus(totalStableDebt) + .plus(BigNumber(wxdai.availableLiquidity)) + .times( + BigNumber(wxdai.priceInMarketReferenceCurrency).div( + 10 ** USD_DECIMALS + ) + ) + .div(10 ** WEI_DECIMALS) + .toNumber(), + apy: utils.aprToApy( + parseFloat( + BigNumber(wxdai.liquidityRate) + .div(10 ** RAY_DECIMALS) + .times(100) + ) + ), + }, + ]; +} + +module.exports = { + timetravel: false, + apy: callGetReservesData, + url: 'https://realt.co/', +}; diff --git a/src/adaptors/reaper-farm/index.js b/src/adaptors/reaper-farm/index.js new file mode 100644 index 0000000000..d260ab8be3 --- /dev/null +++ b/src/adaptors/reaper-farm/index.js @@ -0,0 +1,68 @@ +const utils = require('../utils'); + +const baseUrl = 'https://2ch9hbg8hh.execute-api.us-east-1.amazonaws.com/dev/api'; +const ftmUrl = baseUrl+'/vaults/0xfa'; +const optUrl = baseUrl+'/vaults/0xa'; +const arbUrl = baseUrl+'/vaults/0xa4b1'; + +const networkMapping = { + 10: 'optimism', + 250: 'fantom', + 42161: 'arbitrum', +}; + +const main = async () => { + + const [ftmVaults, optVaults, arbVaults] = await Promise.all( + [ftmUrl, optUrl, arbUrl].map((u) => utils.getData(u)) + ); + + const vaultsMapping = { + 10: optVaults.data, + 250: ftmVaults.data, + 42161: arbVaults.data, + }; + + let data = []; + for (const chain of Object.keys(networkMapping)) { + let poolData = vaultsMapping[chain]; + Object.values(poolData).forEach((pool) => { + const vaultId = pool.address; + let symbol = pool.tokens.lpToken.symbol; + let underlyingTokens = []; + if (pool.tokens.underlyingTokens.length !== 0) { + underlyingTokens = pool.tokens.underlyingTokens.map((tokenObj) => { + return tokenObj.address; + }) + } else { + underlyingTokens.push(pool.tokens.lpToken.address); + } + + if (pool.yields.apy != 0) { + data.push({ + pool: `${vaultId}-${networkMapping[chain]}`.toLowerCase(), + chain: utils.formatChain(networkMapping[chain]), + project: 'reaper-farm', + symbol: symbol, + tvlUsd: pool.tvl.tvl, + apy: pool.yields.apy*100, + underlyingTokens: underlyingTokens, + }); + } + }) + } + return data.filter( + (p) => + ![ + '0x152d62dccc2c7c7930c4483cc2a24fefd23c24c2-fantom', + '0x5427f192137405e6a4143d1c3321359bab2dbd87-fantom', + ].includes(p.pool) + ); +}; + + +module.exports = { + timetravel: false, + apy: main, + url: 'https://reaper.farm/', +}; \ No newline at end of file diff --git a/src/adaptors/ref-finance/index.ts b/src/adaptors/ref-finance/index.ts new file mode 100644 index 0000000000..19eb704ed2 --- /dev/null +++ b/src/adaptors/ref-finance/index.ts @@ -0,0 +1,238 @@ +const axios = require('axios'); + +const FARM_V1_CONTRACT = 'v2.ref-farming.near'; +const FARM_V2_CONTRACT = 'boostfarm.ref-labs.near'; +const endpoint = 'https://rpc.mainnet.near.org/'; +const indexerUrl = 'https://indexer.ref.finance/'; +const sodakiApiUrl = 'https://api.stats.ref.finance/api'; +const STABLE_POOL_IDS = ['1910', '3020', '3364', '3433']; +const boostBlackList = ['3612']; + +const LP_TOKEN_DECIMALS = 24; +const LP_STABLE_TOKEN_DECIMALS = 18; + +async function call(contract, method, args = {}) { + const result = await axios.post(endpoint, { + jsonrpc: '2.0', + id: '1', + method: 'query', + params: { + request_type: 'call_function', + finality: 'final', + account_id: contract, + method_name: method, + args_base64: Buffer.from(JSON.stringify(args)).toString('base64'), + }, + }); + if (result.data.error) { + throw new Error(`${result.data.error.message}: ${result.data.error.data}`); + } + return JSON.parse(Buffer.from(result.data.result.result).toString()); +} + +async function commonCall(url, method, args = {}) { + const result = await axios({ + method: 'get', + url: url + method, + params: args, + }); + if (result.data.error) { + throw new Error(`${result.data.error.message}: ${result.data.error.data}`); + } + return result.data; +} + +function getListSeedsInfo() { + return call(FARM_V2_CONTRACT, 'list_seeds_info'); +} + +function getListSeedFarms(seed_id) { + return call(FARM_V2_CONTRACT, 'list_seed_farms', { seed_id }); +} + +function getPoolsByIds(poolIds) { + const ids = poolIds.join('|'); + if (!ids) return []; + return commonCall(indexerUrl, 'list-pools-by-ids', { ids }); +} + +async function get24hVolume(pool_id) { + const requestUrl = sodakiApiUrl + `/pool/${pool_id}/rolling24hvolume/sum`; + return commonCall(requestUrl, ''); +} + +function ftGetTokenMetadata(tokenId) { + return call(tokenId, 'ft_metadata'); +} + +function getTokenPrices() { + return commonCall(indexerUrl, 'list-token-price'); +} + +function getPoolFeeApr(dayVolume, pool) { + let result = '0'; + if (dayVolume) { + const { total_fee, tvl } = pool; + const revenu24h = (total_fee / 10000) * 0.8 * Number(dayVolume); + if (tvl > 0 && revenu24h > 0) { + const annualisedFeesPrct = ((revenu24h * 365) / tvl) * 100; + result = annualisedFeesPrct.toString(); + } + } + return result; +} + +async function getV2SeedFarmsPools() { + // get all seeds + let list_seeds = await getListSeedsInfo(); + list_seeds = list_seeds.filter( + (s) => !s.seed_id.includes('dclv2.ref-labs.nea') + ); + + // get all farms + const farmsPromiseList = []; + const poolIds = new Set(); + list_seeds.forEach((seed) => { + const { seed_id } = seed; + if (seed_id.indexOf('@') > -1) { + const poolId = seed_id.substring(seed_id.indexOf('@') + 1); + poolIds.add(poolId); + } + farmsPromiseList.push(getListSeedFarms(seed_id)); + }); + const temp_farms = await Promise.all(farmsPromiseList); + const list_farms = []; + temp_farms.forEach((farms) => { + const runningFarms = farms.filter((farm) => { + if (farm.status != 'Ended') return true; + }); + list_farms.push(runningFarms); + }); + // get all pools + const pools = await getPoolsByIds(Array.from(poolIds)); + // get all pools get24hVolume + const ids = Array.from(poolIds); + const promiseVolume = ids.map((poolId) => { + return get24hVolume(poolId); + }); + const allPools24Volume = await Promise.all(promiseVolume); + const tempMap = {}; + ids.forEach((id, index) => { + tempMap[id] = allPools24Volume[index]; + }); + + // organization + const seedsFarmsPools = []; + list_seeds.forEach((seed, index) => { + let pool = null; + if (seed.seed_id.indexOf('@') > -1) { + const id = seed.seed_id.substring(seed.seed_id.indexOf('@') + 1); + pool = pools.find((p) => { + if (+p.id == +id) return true; + }); + } + // filter no farms seed + if (list_farms[index].length > 0) { + const poolApy = getPoolFeeApr(tempMap[pool.id], pool); + seedsFarmsPools.push({ + id: seed.seed_id, + seed, + farmList: list_farms[index], + pool, + poolApy, + }); + } + }); + return seedsFarmsPools; +} + +function toReadableNumber(decimals, number) { + if (!decimals) return number; + + const wholeStr = number.substring(0, number.length - decimals) || '0'; + const fractionStr = number + .substring(number.length - decimals) + .padStart(decimals, '0') + .substring(0, decimals); + + return `${wholeStr}.${fractionStr}`.replace(/\.?0+$/, ''); +} + +async function getV2FarmData() { + const v2_list = await getV2SeedFarmsPools(); + const tokenPriceList = await getTokenPrices(); + const target_list = []; + // get all rewards meta data + const promise_new_list = v2_list.map(async (data) => { + const { farmList } = data; + const promise_farm_meta_data = farmList.map(async (farm) => { + const tokenId = farm.terms.reward_token; + const tokenMetadata = await ftGetTokenMetadata(tokenId); + farm.token_meta_data = tokenMetadata; + return farm; + }); + await Promise.all(promise_farm_meta_data); + }); + await Promise.all(promise_new_list); + v2_list.forEach(async (data) => { + const { seed, pool, farmList, poolApy } = data; + const { total_seed_amount } = seed; + // get seed tvl + const { tvl, id, shares_total_supply } = pool; + const DECIMALS = new Set(STABLE_POOL_IDS || []).has(id?.toString()) + ? LP_STABLE_TOKEN_DECIMALS + : LP_TOKEN_DECIMALS; + const seedTotalStakedAmount = toReadableNumber(DECIMALS, total_seed_amount); + const poolShares = Number(toReadableNumber(DECIMALS, shares_total_supply)); + const seedTvl = + poolShares == 0 + ? 0 + : Number( + ((Number(seedTotalStakedAmount) * tvl) / poolShares).toString() + ); + // get apy per farm + let totalApy = 0; + const rewardsTokens = []; + farmList.forEach((farm) => { + const { token_meta_data } = farm; + const { daily_reward, reward_token } = farm.terms; + const readableNumber = toReadableNumber( + token_meta_data.decimals, + daily_reward + ); + const reward_token_price = Number( + tokenPriceList[reward_token]?.price || 0 + ); + const apy = + seedTvl == 0 + ? 0 + : (Number(readableNumber) * 360 * reward_token_price) / seedTvl; + totalApy += Number(apy); + rewardsTokens.push(reward_token); + }); + const { token_symbols, token_account_ids } = pool; + const baseApy = poolApy / 2; + + if (boostBlackList.indexOf(pool.id) == -1) { + const target = { + pool: 'ref-pool-' + pool.id, + chain: 'NEAR', + project: 'ref-finance', + symbol: token_symbols?.join('-'), + tvlUsd: seedTvl, + apyReward: totalApy * 100, + apyBase: Number(baseApy), + underlyingTokens: token_account_ids, + rewardTokens: rewardsTokens, + }; + target_list.push(target); + } + }); + return target_list; +} + +module.exports = { + timetravel: false, + apy: getV2FarmData, + url: 'https://app.ref.finance/v2farms', +}; diff --git a/src/adaptors/reflexer/index.js b/src/adaptors/reflexer/index.js new file mode 100644 index 0000000000..5c065492df --- /dev/null +++ b/src/adaptors/reflexer/index.js @@ -0,0 +1,138 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const ETH_JOIN = '0x2D3cD7b81c93f188F3CB8aD87c8Acc73d6226e3A'; +const ETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const RAI = '0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919'; +const SAFEEngine = '0xCC88a9d330da1133Df3A7bD823B95e52511A6962'; +const collateralType = + '0x4554482d41000000000000000000000000000000000000000000000000000000'; +const collateralTypeName = 'ETH-A'; + +const ABI = { + collateralTypes: { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'collateralTypes', + outputs: [ + { + internalType: 'uint256', + name: 'debtAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accumulatedRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'safetyPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtCeiling', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtFloor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationPrice', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; +const API_URL = + 'https://subgraph.reflexer.finance/subgraphs/name/reflexer-labs/rai'; +const query = gql` + query getCollateralTypes { + collateralTypes { + id + liquidationCRatio + modifiedAt + } + } +`; +const liquidationCRatio = async () => { + const result = await request(API_URL, query); + return result.collateralTypes.find((e) => e.id === collateralTypeName) + ?.liquidationCRatio; +}; +const BIG_TEN = new BigNumber(10); +const main = async () => { + const balance = ( + await sdk.api.erc20.balanceOf({ + target: ETH, + owner: ETH_JOIN, + chain: 'ethereum', + }) + ).output; + + const collateralTypesCall = ( + await sdk.api.abi.call({ + target: SAFEEngine, + abi: ABI.collateralTypes, + params: [collateralType], + }) + ).output; + + const prices = (await utils.getPrices([`ethereum:${ETH}`, `ethereum:${RAI}`])) + .pricesByAddress; + const tvlUsd = new BigNumber(balance) + .div(BIG_TEN.pow(18)) + .times(prices[ETH.toLowerCase()]); + const totalBorrowUsd = new BigNumber(collateralTypesCall.debtAmount) + .div(BIG_TEN.pow(18)) + .times(prices[RAI.toLowerCase()]); + const debtCeilingUsd = new BigNumber(collateralTypesCall.debtCeiling) + .div(BIG_TEN.pow(45)) + .times(prices[RAI.toLowerCase()]); + const normalizRate = new BigNumber( + collateralTypesCall.accumulatedRate + ).dividedBy(BIG_TEN.pow(27)); + BigNumber.config({ POW_PRECISION: 100 }); + const stabilityFee = normalizRate.toNumber(); + const liquidationRatio = await liquidationCRatio(); + const ltv = 1 / Number(liquidationRatio); + return [ + { + pool: ETH_JOIN, + project: 'reflexer', + symbol: 'WETH', + chain: 'ethereum', + apy: 0, + tvlUsd: tvlUsd.toNumber(), + // borrow fields + apyBaseBorrow: ((stabilityFee - 1) / 1) * 100, + totalSupplyUsd: tvlUsd.toNumber(), + totalBorrowUsd: totalBorrowUsd.toNumber(), + debtCeilingUsd: debtCeilingUsd.toNumber(), + mintedCoin: 'RAI', + ltv, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://reflexer.finance/', +}; diff --git a/src/adaptors/rehold/abis/v1/Dual.json b/src/adaptors/rehold/abis/v1/Dual.json new file mode 100644 index 0000000000..3f70261312 --- /dev/null +++ b/src/adaptors/rehold/abis/v1/Dual.json @@ -0,0 +1,47 @@ +[ + { + "inputs": [], + "name": "tariffs", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, + { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "internalType": "struct DualTariff[]", + "name": "dt1", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/rehold/abis/v2/Dual.json b/src/adaptors/rehold/abis/v2/Dual.json new file mode 100644 index 0000000000..4a2eae7701 --- /dev/null +++ b/src/adaptors/rehold/abis/v2/Dual.json @@ -0,0 +1,939 @@ +[{ + "inputs": [{ + "internalType": "contract IVault", + "name": "_vault", + "type": "address" + }, { + "internalType": "contract IPriceFeed", + "name": "_priceFeed", + "type": "address" + }, { + "internalType": "address", + "name": "_WETH", + "type": "address" + }], + "stateMutability": "nonpayable", + "type": "constructor" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "DualClaimed", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "DualCreated", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "DualReplayed", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "address", + "name": "oldPriceFeed", + "type": "address" + }, { + "indexed": false, + "internalType": "address", + "name": "newPriceFeed", + "type": "address" + }], + "name": "PriceFeedUpdated", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + }], + "name": "RoleAdminChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }], + "name": "RoleGranted", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }], + "name": "RoleRevoked", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "address", + "name": "oldVault", + "type": "address" + }, { + "indexed": false, + "internalType": "address", + "name": "newVault", + "type": "address" + }], + "name": "VaultUpdated", + "type": "event" +}, { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "WETH", + "outputs": [{ + "internalType": "address", + "name": "", + "type": "address" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "minBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "maxBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "minQuoteAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "maxQuoteAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "bool", + "name": "enabled", + "type": "bool" + }], + "internalType": "struct DualTariff", + "name": "dualTariff", + "type": "tuple" + }], + "name": "addTariff", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint80", + "name": "baseRoundId", + "type": "uint80" + }, { + "internalType": "uint80", + "name": "quoteRoundId", + "type": "uint80" + }], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }], + "name": "countUserClaimedDuals", + "outputs": [{ + "internalType": "uint256", + "name": "count", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }], + "name": "countUserClosedDuals", + "outputs": [{ + "internalType": "uint256", + "name": "count", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }], + "name": "countUserOpenedDuals", + "outputs": [{ + "internalType": "uint256", + "name": "count", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "address", + "name": "_user", + "type": "address" + }, { + "internalType": "address", + "name": "inputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }], + "name": "create", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }], + "name": "createETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" +}, { + "inputs": [], + "name": "disable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "disableTariff", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "dualIndex", + "outputs": [{ + "internalType": "uint32", + "name": "", + "type": "uint32" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "enable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "enableTariff", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "enabled", + "outputs": [{ + "internalType": "bool", + "name": "", + "type": "bool" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }], + "name": "get", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "address", + "name": "user", + "type": "address" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "address", + "name": "inputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputQuoteAmount", + "type": "uint256" + }, { + "internalType": "address", + "name": "outputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "outputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "initialPrice", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "closedPrice", + "type": "uint256" + }, { + "internalType": "bool", + "name": "claimed", + "type": "bool" + }, { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "finishAt", + "type": "uint256" + }], + "internalType": "struct Dual", + "name": "dual", + "type": "tuple" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }], + "name": "getRoleAdmin", + "outputs": [{ + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "hasRole", + "outputs": [{ + "internalType": "bool", + "name": "", + "type": "bool" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "priceFeed", + "outputs": [{ + "internalType": "contract IPriceFeed", + "name": "", + "type": "address" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "uint80", + "name": "baseRoundId", + "type": "uint80" + }, { + "internalType": "uint80", + "name": "quoteRoundId", + "type": "uint80" + }], + "name": "replay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + }], + "name": "supportsInterface", + "outputs": [{ + "internalType": "bool", + "name": "", + "type": "bool" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "tariffs", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "minBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "maxBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "minQuoteAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "maxQuoteAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "bool", + "name": "enabled", + "type": "bool" + }], + "internalType": "struct DualTariff[]", + "name": "dt1", + "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "contract IPriceFeed", + "name": "_priceFeed", + "type": "address" + }], + "name": "updatePriceFeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "contract IVault", + "name": "_vault", + "type": "address" + }], + "name": "updateVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }], + "name": "user", + "outputs": [{ + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }, { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }], + "name": "userClaimedDuals", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "address", + "name": "user", + "type": "address" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "address", + "name": "inputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputQuoteAmount", + "type": "uint256" + }, { + "internalType": "address", + "name": "outputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "outputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "initialPrice", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "closedPrice", + "type": "uint256" + }, { + "internalType": "bool", + "name": "claimed", + "type": "bool" + }, { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "finishAt", + "type": "uint256" + }], + "internalType": "struct Dual[]", + "name": "duals", + "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }, { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }], + "name": "userClosedDuals", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "address", + "name": "user", + "type": "address" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "address", + "name": "inputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputQuoteAmount", + "type": "uint256" + }, { + "internalType": "address", + "name": "outputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "outputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "initialPrice", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "closedPrice", + "type": "uint256" + }, { + "internalType": "bool", + "name": "claimed", + "type": "bool" + }, { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "finishAt", + "type": "uint256" + }], + "internalType": "struct Dual[]", + "name": "duals", + "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "_user", + "type": "address" + }, { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "offset", + "type": "uint256" + }], + "name": "userOpenedDuals", + "outputs": [{ + "components": [{ + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "tariffId", + "type": "uint256" + }, { + "internalType": "address", + "name": "user", + "type": "address" + }, { + "internalType": "address", + "name": "baseToken", + "type": "address" + }, { + "internalType": "address", + "name": "quoteToken", + "type": "address" + }, { + "internalType": "address", + "name": "inputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputBaseAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "inputQuoteAmount", + "type": "uint256" + }, { + "internalType": "address", + "name": "outputToken", + "type": "address" + }, { + "internalType": "uint256", + "name": "outputAmount", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "stakingPeriod", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "yield", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "initialPrice", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "closedPrice", + "type": "uint256" + }, { + "internalType": "bool", + "name": "claimed", + "type": "bool" + }, { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, { + "internalType": "uint256", + "name": "finishAt", + "type": "uint256" + }], + "internalType": "struct Dual[]", + "name": "duals", + "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "vault", + "outputs": [{ + "internalType": "contract IVault", + "name": "", + "type": "address" + }], + "stateMutability": "view", + "type": "function" +}] diff --git a/src/adaptors/rehold/index.js b/src/adaptors/rehold/index.js new file mode 100644 index 0000000000..07dd96a68a --- /dev/null +++ b/src/adaptors/rehold/index.js @@ -0,0 +1,258 @@ +const BN = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const DualV1 = require('./abis/v1/Dual.json'); +const DualV2 = require('./abis/v2/Dual.json'); + +const CHAINS = { + bsc: { + dual: { + address: '0x3185b7c3a4e646fb23c6c04d979e61da7871b5c1', + abi: DualV1, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, + + polygon: { + dual: { + address: '0x868a943ca49a63eb0456a00ae098d470915eea0d', + abi: DualV2, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, + + arbitrum: { + dual: { + address: '0x868a943ca49a63eb0456a00ae098d470915eea0d', + abi: DualV2, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, + + optimism: { + dual: { + address: '0x868a943ca49a63eb0456a00ae098d470915eea0d', + abi: DualV2, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, + + avax: { + dual: { + address: '0x868a943ca49a63eb0456a00ae098d470915eea0d', + abi: DualV2, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, + + fantom: { + dual: { + address: '0x868a943ca49a63eb0456a00ae098d470915eea0d', + abi: DualV2, + }, + + vault: { + address: '0xd476ce848c61650e3051f7571f3ae437fe9a32e0', + }, + }, +}; + +const SLUG = 'rehold'; + +const POOL_META = + 'Calculated as: 24h yield * 365. APY is fixed, and extendable with no limits after the staking period ends'; + +function _map(array) { + return array.reduce((acc, item) => { + acc[item.input.target.toLowerCase()] = item.output; + return acc; + }, {}); +} + +async function _getPrices(chain, tokens) { + const [{ coins: prices1 }, prices2] = await Promise.all([ + utils.getData( + `https://coins.llama.fi/prices/current/${tokens + .map((t) => `${chain}:${t}`) + .join(',')}` + ), + + // DefiLlama missed some prices (e.g. VET, 0x6fdcdfef7c496407ccb0cec90f9c5aaa1cc8d888), + // so we're using our API as fallback prices + utils.getData('https://app.rehold.io/api/v1/rates'), + ]); + + return { + prices1: Object.values(prices1).reduce((acc, item) => { + acc[item.symbol.toUpperCase()] = item.price; + return acc; + }, {}), + + prices2: Object.entries(prices2).reduce((acc, [symbol, rate]) => { + const [baseTicker, quoteTicker] = symbol.toUpperCase().split('/'); + + if (quoteTicker === 'USD') { + acc[baseTicker] = rate.price; + } + + return acc; + }, {}), + }; +} + +async function _apy(chain) { + const pairs = {}; + const tokens = {}; + + const { output } = await sdk.api.abi.call({ + chain, + target: CHAINS[chain].dual.address, + abi: CHAINS[chain].dual.abi.find((m) => m.name === 'tariffs'), + }); + + output.forEach((tariff) => { + const { baseToken, quoteToken, stakingPeriod, yield: _yield } = tariff; + const apr = +new BN(_yield) + .div(stakingPeriod) + .times(24 * 365) + .div(1e6) + .toFixed(0); + + if (!tokens[baseToken] || tokens[baseToken] < apr) { + tokens[baseToken] = apr; + } + + if (!tokens[quoteToken] || tokens[quoteToken] < apr) { + tokens[quoteToken] = apr; + } + + if ( + !pairs[`${baseToken}-${quoteToken}`] || + pairs[`${baseToken}-${quoteToken}`] < apr + ) { + pairs[`${baseToken}-${quoteToken}`] = apr; + } + }); + + const pools = []; + + Object.entries(pairs).forEach(([symbol, apr], i) => { + const [baseToken, quoteToken] = symbol.split('-'); + + pools.push({ + pool: `${CHAINS[chain].vault.address}-${i}-${chain}`, // we don't have a specific contract address for each pool + chain: utils.formatChain(chain), + project: SLUG, + symbol, + apyBase: apr, + underlyingTokens: [baseToken, quoteToken], + }); + }); + + Object.entries(tokens).forEach(([token, apr]) => { + pools.push({ + pool: `${token}-${chain}`, + chain: utils.formatChain(chain), + project: SLUG, + symbol: token, + apyBase: apr, + underlyingTokens: [token], + }); + }); + + const tokenAddresses = Object.keys(tokens); + + const [{ output: _balances }, { output: _symbols }, { output: _decimals }] = + await Promise.all([ + sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: tokenAddresses.map((token) => ({ + target: token, + params: CHAINS[chain].vault.address, + })), + chain, + }), + + sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokenAddresses.map((token) => ({ + target: token, + })), + chain, + }), + + sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokenAddresses.map((token) => ({ + target: token, + })), + chain, + }), + ]); + + const symbols = _map(_symbols); + const decimals = _map(_decimals); + + const { prices1, prices2 } = await _getPrices(chain, tokenAddresses); + + const balances = _balances.reduce((acc, balance) => { + const token = balance.input.target.toLowerCase(); + const tokenSymbol = symbols[token]; + const tokenDecimals = +decimals[token]; + const tokenPrice = prices1[tokenSymbol] || prices2[tokenSymbol] || 0; + + acc[token] = +new BN(balance.output) + .div(10 ** tokenDecimals) + .times(tokenPrice) + .toFixed(2); + + return acc; + }, {}); + + pools.forEach((pool) => { + const [tokenA, tokenB] = pool.symbol.toLowerCase().split('-'); + + const balanceA = tokenA ? balances[tokenA] : 0; + const balanceB = tokenB ? balances[tokenB] : 0; + + const symbolA = tokenA && symbols[tokenA]; + const symbolB = tokenB && symbols[tokenB]; + + pool.symbol = [symbolA, symbolB].filter(Boolean).join('-'); + pool.tvlUsd = balanceA + balanceB; + pool.poolMeta = POOL_META; + }); + + return pools; +} + +async function apy() { + const pools = []; + + for (const chain in CHAINS) { + pools.push(...(await _apy(chain))); + } + + return pools; +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.rehold.io/?utm_source=DefiLlama', +}; diff --git a/src/adaptors/renzo/index.js b/src/adaptors/renzo/index.js new file mode 100644 index 0000000000..f663ca6486 --- /dev/null +++ b/src/adaptors/renzo/index.js @@ -0,0 +1,101 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +// Time constants +const MS_PER_SECOND = 1000; +const SECONDS_PER_DAY = 86400; +const THIRTY_DAYS_SECONDS = SECONDS_PER_DAY * 30; +const DAYS_PER_YEAR = 365; + +// Contract addresses constants +const RATE_PROVIDER_CONTRACT_ADDRESS = '0x387dBc0fB00b26fb085aa658527D5BE98302c84C'; +const EZETH_CONTRACT_ADDRESS = '0xbf5495efe5db9ce00f80364c8b423567e58d2110'; + +// Function ABI constants +const ERC20_ABI_totalSupply = 'erc20:totalSupply'; +const RATE_PROVIDER_ABI_getRate = 'function getRate() external view returns (uint256)'; + +const apy = async () => { + // Fetch current total supply of ezETH + const totalSupply = + ( + await sdk.api.abi.call({ + target: EZETH_CONTRACT_ADDRESS, + abi: ERC20_ABI_totalSupply, + }) + ).output / 1e18; + + // Calculate timestamp for 30d ago + const timestampNowMs = Date.now(); + const timestampNowSeconds = timestampNowMs / MS_PER_SECOND; + const timestamp30DaysAgoSeconds = timestampNowSeconds - THIRTY_DAYS_SECONDS; + + // Fetch block number for 30d ago + const block30dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp30DaysAgoSeconds}`) + ).data.height; + + if (block30dayAgo === 0 || typeof block30dayAgo !== 'number') { + throw new Error('RPC issue: Block number for 30d ago is invalid'); + } + + // Fetch current and 30d ago rates from the rate provider + const [rateNow, rate30d] = await Promise.all([ + sdk.api.abi.call({ + target: RATE_PROVIDER_CONTRACT_ADDRESS, + abi: RATE_PROVIDER_ABI_getRate, + }), + sdk.api.abi.call({ + target: RATE_PROVIDER_CONTRACT_ADDRESS, + abi: RATE_PROVIDER_ABI_getRate, + block: block30dayAgo, + }), + ]); + + if (rateNow.output == 0 || typeof rateNow.output !== 'string') { + throw new Error('RPC issue: Current rate is invalid'); + } + + if (rate30d.output == 0 || typeof rate30d.output !== 'string') { + throw new Error('RPC issue: 30d rate is invalid'); + } + + // Calculate APY for last 30 days + const rateChangePeriodDays = 30; + const rateStart = rate30d.output; + const rateEnd = rateNow.output; + const rateDelta = rateNow.output - rate30d.output; + if (rateDelta === 0) { + throw new Error("rateDelta is 0 -> apy30d would be 0, skipping"); + } + const apy30d = (1 + rateDelta / rateStart) ** (DAYS_PER_YEAR / rateChangePeriodDays) - 1 + + // Fetch ezETH price + const priceKey = `ethereum:${EZETH_CONTRACT_ADDRESS}`; + const ezethPriceUsd = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + if (ezethPriceUsd === 0 || typeof ezethPriceUsd !== 'number') { + throw new Error('Oracle issue: ezETH price is invalid'); + } + + // Calculate TVL + const tvlUsd = totalSupply * ezethPriceUsd; + + return [ + { + pool: EZETH_CONTRACT_ADDRESS , + chain: 'ethereum', + project: 'renzo', + symbol: 'ezETH', + apyBase: apy30d * 100, + tvlUsd: tvlUsd, + }, + ]; +}; + +module.exports = { + apy, + url: 'https://app.renzoprotocol.com', +}; diff --git a/src/adaptors/reserve-protocol/abi.js b/src/adaptors/reserve-protocol/abi.js new file mode 100644 index 0000000000..5922211843 --- /dev/null +++ b/src/adaptors/reserve-protocol/abi.js @@ -0,0 +1,485 @@ +module.exports = { + erc20Abi: [ + { + stateMutability: 'view', + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string' }], + }, + ], + rtokenAbi: [ + { + stateMutability: 'view', + type: 'function', + name: 'main', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'distributor', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'distribution', + outputs: [ + { + internalType: 'uint16', + name: 'rTokenDist', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'rsrDist', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + facadeAbi: [ + { + inputs: [], + name: 'UIntOutOfBounds', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract ITrading', + name: 'trader', + type: 'address', + }, + ], + name: 'auctionsSettleable', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'erc20s', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'backingOverview', + outputs: [ + { + internalType: 'uint192', + name: 'backing', + type: 'uint192', + }, + { + internalType: 'uint192', + name: 'overCollateralization', + type: 'uint192', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'targetName', + type: 'bytes32', + }, + ], + name: 'backupConfig', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'erc20s', + type: 'address[]', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'balancesAcrossAllTraders', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'erc20s', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'balances', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'balancesNeededByBackingManager', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'basketBreakdown', + outputs: [ + { + internalType: 'address[]', + name: 'erc20s', + type: 'address[]', + }, + { + internalType: 'uint192[]', + name: 'uoaShares', + type: 'uint192[]', + }, + { + internalType: 'bytes32[]', + name: 'targets', + type: 'bytes32[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'basketTokens', + outputs: [ + { + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'issue', + outputs: [ + { + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'deposits', + type: 'uint256[]', + }, + { + internalType: 'uint192[]', + name: 'depositsUoA', + type: 'uint192[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'maxIssuable', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IBackingManager', + name: 'bm', + type: 'address', + }, + ], + name: 'nextRecollateralizationAuction', + outputs: [ + { + internalType: 'bool', + name: 'canStart', + type: 'bool', + }, + { + internalType: 'contract IERC20', + name: 'sell', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'buy', + type: 'address', + }, + { + internalType: 'uint256', + name: 'sellAmount', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract RTokenP1', + name: 'rToken', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'pendingUnstakings', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'availableAt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + internalType: 'struct IFacadeRead.Pending[]', + name: 'unstakings', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'price', + outputs: [ + { + internalType: 'uint192', + name: 'low', + type: 'uint192', + }, + { + internalType: 'uint192', + name: 'high', + type: 'uint192', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'primeBasket', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'erc20s', + type: 'address[]', + }, + { + internalType: 'bytes32[]', + name: 'targetNames', + type: 'bytes32[]', + }, + { + internalType: 'uint192[]', + name: 'targetAmts', + type: 'uint192[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint48', + name: 'basketNonce', + type: 'uint48', + }, + ], + name: 'redeem', + outputs: [ + { + internalType: 'address[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'withdrawals', + type: 'uint256[]', + }, + { + internalType: 'bool', + name: 'isProrata', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRevenueTrader', + name: 'revenueTrader', + type: 'address', + }, + ], + name: 'revenueOverview', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'erc20s', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: 'canStart', + type: 'bool[]', + }, + { + internalType: 'uint256[]', + name: 'surpluses', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'minTradeAmounts', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRToken', + name: 'rToken', + type: 'address', + }, + ], + name: 'stToken', + outputs: [ + { + internalType: 'contract IStRSR', + name: 'stTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/reserve-protocol/index.js b/src/adaptors/reserve-protocol/index.js new file mode 100644 index 0000000000..ba30a89469 --- /dev/null +++ b/src/adaptors/reserve-protocol/index.js @@ -0,0 +1,267 @@ +const utils = require('../utils'); + +const { request, gql } = require('graphql-request'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); + +const { facadeAbi, rtokenAbi } = require('./abi'); + +const chains = [ + { + chainName: 'base', + facade: '0xeb2071e9b542555e90e6e4e1f83fa17423583991', + graph: + 'https://subgraph.satsuma-prod.com/327d6f1d3de6/reserve/reserve-base/api', + }, + { + chainName: 'ethereum', + facade: '0x2C7ca56342177343A2954C250702Fd464f4d0613', + graph: + 'https://subgraph.satsuma-prod.com/327d6f1d3de6/reserve/reserve-mainnet/api', + }, + { + chainName: 'arbitrum', + facade: '0x387A0C36681A22F728ab54426356F4CAa6bB48a9', + graph: + 'https://subgraph.satsuma-prod.com/327d6f1d3de6/reserve/reserve-arbitrum/api', + }, +]; + +const rtokenQuery = gql` + { + rtokens(orderBy: cumulativeUniqueUsers, orderDirection: desc) { + id + cumulativeUniqueUsers + targetUnits + rsrStaked + token { + name + symbol + lastPriceUSD + holderCount + transferCount + totalSupply + cumulativeVolume + } + } + } +`; + +const poolsMap = { + ethereum: { + 'acee1e4d-a73c-4e20-98f7-e87c13d446e4': 'apxeth', + '405d8dad-5c99-4c91-90d3-82813ade1ff1': 'sadai', + 'a349fea4-d780-4e16-973e-70ca9b606db2': 'sausdc', + '60d657c9-5f63-4771-a85b-2cf8d507ec00': 'sausdt', + '1d53fa29-b918-4d74-9508-8fcf8173ca51': 'sausdp', + 'cc110152-36c2-4e10-9c12-c5b4eb662143': 'cdai', + 'cefa9bb8-c230-459a-a855-3b94e96acd8c': 'cusdc', + '57647093-2868-4e65-97ab-9cae8ec74e7d': 'cusdt', + '6c2b7a5c-6c4f-49ea-a08c-0366b772f2c2': 'cusdp', + '1d876729-4445-4623-8b6b-c5290db5d100': 'cwbtc', + '1e5da7c6-59bb-49bd-9f97-4f4fceeffad4': 'ceth', + 'fa4d7ee4-0001-4133-9e8d-cf7d5d194a91': 'fusdc', + 'ed227286-abb0-4a34-ada5-39f7ebd81afb': 'fdai', + '6600934f-6323-447d-8a7d-67fbede8529d': 'fusdt', + '747c1d2a-c668-4682-b9f9-296708a3dd90': 'wsteth', + 'd4b3c522-6127-4b89-bedf-83641cdcd2eb': 'reth', + '7da72d09-56ca-4ec5-a45f-59114353e487': 'wcusdcv3', + 'f4d5b566-e815-4ca2-bb07-7bcd8bc797f1': 'wcusdtv3', + '8a20c472-142c-4442-b724-40f2183c073e': 'stkcvxmim-3lp3crv-f', + 'ad3d7253-fb8f-402f-a6f8-821bc0a055cb': 'stkcvxcrv3crypto', + '7394f1bc-840a-4ff0-9e87-5e0ef932943a': 'stkcvx3crv', + 'c04005c9-7e34-41a6-91c4-295834ed8ac0': 'stkcvxeusd3crv-f', + '325ad2d6-70b1-48d7-a557-c2c99a036f87': 'mrp-ausdc', + '1343a280-7812-4bc3-8f98-d1c37e11d271': 'mrp-ausdt', + 'b8bcdf8e-96ed-40ca-a7aa-aa048b9874e5': 'mrp-adai', + '7be52986-18c2-450f-b74b-d65fb1205bbf': 'mrp-aweth', + 'ff61171d-d7b0-4989-816c-b9bf02a15f00': 'mrp-awbtc', + 'eab8d63d-8a8f-48cb-8027-583508831d24': 'mrp-asteth', + '0f45d730-b279-4629-8e11-ccb5cc3038b4': 'cbeth', + 'c8a24fee-ec00-4f38-86c0-9f6daebc4225': 'sdai', + '55de30c3-bf9f-4d4e-9e0b-536a8ef5ab35': 'sfrax', + 'aa70268e-4b52-42bf-a116-608b370f9501': 'saethusdc', + 'd118f505-e75f-4152-bad3-49a2dc7482bf': 'saethpyusd', + '01146cce-9140-4e03-9a2e-82c99ccc42f1': 'stkcvxpyusdusdc', + '5b3aebb3-891d-47fc-92e2-927ada3d5b82': 'sfrxeth', + 'bf3815bb-1059-4f24-90a3-14998e8493fa': 're7weth', + 'a3ffd3fe-b21c-44eb-94d5-22c80057a600': 'stkcvxcrvusdusdt-f', + '755fcec6-f4fd-4150-9184-60f099206694': 'stkcvxcrvusdusdc-f', + 'd1dacce1-7815-420c-bb6d-d3c4320e1b2a': 'steakpyusd', + '043a8330-bc29-4164-aa1c-28de7bf87755': 'bbusdt', + 'a44febf3-34f6-4cd5-8ab1-f246ebe49f9e': 'steakusdc', + '152b7ce2-7193-475d-9b15-3f17fee66047': 'stkcvxeth+eth', + '74346f6f-c7ee-4506-a204-baf48e13decb': 'stkcvxeth+eth-f', + '66985a81-9c51-46ca-9977-42b4fe7bc6df': 'susde', + '90bfb3c2-5d35-4959-a275-ba5085b08aa3': 'ethx', + 'd8c4eff5-c8a9-46fc-a888-057c4c668e72': 'susds', + '423681e3-4787-40ce-ae43-e9f67c5269b3': 'woeth', + 'f981a304-bb6c-45b8-b0c5-fd2f515ad23a': 'saethusdt', + '85fc6934-c94d-4ebe-9c60-66beb363669f': 'saethrlusd', + }, + base: { + 'df65c4f4-e33a-481c-bac8-0c2252867c93': 'wcusdbcv3', + '0c8567f8-ba5b-41ad-80de-00a71895eb19': 'wcusdcv3', + '9d09b0be-f6c2-463a-ad2c-4552b3e12bd9': 'wsgusdbc', + '7e0661bf-8cf3-45e6-9424-31916d4c7b84': 'sabasusdc', + '833ec61b-f9e6-46ac-9eff-2785808b2389': 'sabasusdbc', + 'b90eba2e-ed29-414e-b16d-82f9c3eae707': 'meusd', + 'bde35fef-649f-4514-a564-e7e7da05eb52': 'wsamm-eusd/usdc', + '69c0fc74-dee5-4c60-9aed-a593661d54ea': 'wvamm-weth/aero', + '7b542141-5eed-4d70-bee6-0f9733beb362': 'wvamm-mog/weth', + 'be8a4206-6543-4690-a5c2-b3e032245aa2': 'wsamm-usdz/usdc', + '593056a0-1e39-451d-acc8-081526625ab3': 'wvamm-weth/cbbtc', + '8af246ee-cf26-4c8e-88f8-f2021a69e44d': 'wvamm-weth/well', + '7e15dae2-ba5c-4658-b1a2-efb908a15200': 'wvamm-weth/degen', + 'f388573e-5c0f-4dac-9f70-116a4aabaf17': 'wsuperoethb', + }, + arbitrum: { + 'd9c395b9-00d0-4426-a6b3-572a6dd68e54': 'wcusdcv3', + '85247b13-8180-44e7-b38c-4d324cc68a92': 'wcusdtv3', + 'd9fa8e14-0447-4207-9ae8-7810199dfa1f': 'saarbusdcn', + '3a6cc030-738d-4e19-8a40-e63e9c4d5a6f': 'saarbusdt', + }, +}; + +const rtokenTvl = (rtoken) => + (rtoken.token?.totalSupply / 1e18) * rtoken.token?.lastPriceUSD || 0; + +const apyChain = async (chainProps) => { + const { chainName, facade, graph } = chainProps; + const poolsData = (await utils.getData('https://yields.llama.fi/pools')) + ?.data; + + const poolsInfo = (poolsData || []) + .filter((pool) => chains.some((chain) => poolsMap[chain.chainName][pool.pool])) + .reduce((acc, pool) => { + const chain = pool.chain.toLowerCase() + const poolsByChain = acc[chain] || {} + acc[chain] = { + ...poolsByChain, + [poolsMap[chain][pool.pool]]: { + yield: pool.apyMean30d || 0, + underlyings: pool.underlyingTokens, + }, + } + return acc + }, {}) + + const { rtokens } = await request(graph, rtokenQuery); + + const filteredRtokens = rtokens.filter( + (rtoken) => rtoken && rtokenTvl(rtoken) > 10_000 + ); + + const rtokenAddresses = filteredRtokens.map((rtoken) => rtoken.id); + + const { output: mainAddresses } = await sdk.api.abi.multiCall({ + abi: rtokenAbi.find(({ name }) => name === 'main'), + chain: chainName, + calls: rtokenAddresses.map((rtokenAddress) => ({ + target: rtokenAddress, + params: [], + })), + }); + + const { output: distributorAddresses } = await sdk.api.abi.multiCall({ + chain: chainName, + abi: rtokenAbi.find(({ name }) => name === 'distributor'), + calls: mainAddresses.map(({ output: mainAddress }) => ({ + target: mainAddress, + params: [], + })), + }); + + const { output: distributions } = await sdk.api.abi.multiCall({ + chain: chainName, + abi: rtokenAbi.find(({ name }) => name === 'distribution'), + calls: distributorAddresses.map(({ output: distributorAddress }) => ({ + target: distributorAddress, + params: ['0x0000000000000000000000000000000000000001'], + })), + }); + + const { output: basketBreakdowns } = await sdk.api.abi.multiCall({ + chain: chainName, + abi: facadeAbi.find(({ name }) => name === 'basketBreakdown'), + calls: rtokenAddresses.map((rtokenAddress) => ({ + target: facade, + params: [rtokenAddress], + })), + }); + + const fallbackPools = Object.values(poolsInfo).reduce((acc, pools) => { + Object.keys(pools).forEach((pool) => { + acc[pool] = pools[pool] + }) + return acc + }); + + const reservePools = Promise.all( + filteredRtokens.map(async (rtoken, i) => { + if (!rtoken) return null; + + const { output: symbols } = await sdk.api.abi.multiCall({ + chain: chainName, + abi: 'erc20:symbol', + calls: basketBreakdowns[i].output.erc20s.map((erc20) => ({ + target: erc20, + params: [], + })), + }); + + let apyBase = BigNumber(0); + let totalShares = BigNumber(0); + const underlyingTokens = []; + + for (let j = 0; j < symbols.length; j++) { + const token = basketBreakdowns[i].output.erc20s[j]; + const shares = new BigNumber(basketBreakdowns[i].output.uoaShares[j]); + totalShares = totalShares.plus(shares); + + const symbol = symbols[j]?.output?.toLowerCase() + const pool = poolsInfo[chainName][symbol] || fallbackPools[symbol] + + if (pool?.yield) + apyBase = apyBase.plus(shares.times(new BigNumber(pool.yield))); + + if (pool?.underlyings?.length) + underlyingTokens.push(...pool.underlyings); + } + + if (!totalShares.isZero()) { + apyBase = apyBase.div(totalShares); + } + + return { + pool: rtoken.id, + chain: chainName, + project: 'reserve-protocol', + symbol: rtoken.token?.symbol, + tvlUsd: rtokenTvl(rtoken), + apyBase: + (apyBase.toNumber() * (distributions[i].output.rTokenDist || 10000)) / + 10000, // Revenue distribution to holders + apyReward: 0, + rewardTokens: [], + underlyingTokens: underlyingTokens, + url: `https://app.reserve.org/${chainName}/token/${rtoken.id}/overview`, + }; + }) + ); + + return reservePools; +}; + +const apy = async () => { + const pools = await Promise.all( + chains.map(async (chainProps) => await apyChain(chainProps)) + ); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/reservoir-protocol/index.js b/src/adaptors/reservoir-protocol/index.js new file mode 100644 index 0000000000..f617a2fdd3 --- /dev/null +++ b/src/adaptors/reservoir-protocol/index.js @@ -0,0 +1,168 @@ +const sdk = require('@defillama/sdk'); + +const { default: BigNumber } = require('bignumber.js'); + +const BIG_10 = new BigNumber('10'); +const utils = require('../utils'); + +const TOKEN = '0x738d1115B90efa71AE468F1287fc864775e23a31'; +const TARGET = '0x5475611Dffb8ef4d697Ae39df9395513b6E947d7'; + +const WSRUSD = '0xd3fD63209FA2D55B07A0f6db36C2f43900be3094'; + +const SAVING_MODULE = { + abis: { + currentRate: { + inputs: [], + name: 'currentRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + currentPrice: { + inputs: [], + name: 'currentPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; + + +const WSRUSD_ABI = { + abis: { + currentRate: { + inputs: [], + name: 'currentRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + currentPrice: { + inputs: [], + name: 'currentPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + convertToAssets: { + inputs: [ + { + name: 'shares', + type: 'uint256', + internalType: 'uint256' + } + ], + name: 'convertToAssets', + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + } + } +}; + +const main = async () => { + + const totalSupply = ( + await sdk.api.abi.call({ + target: TOKEN, + abi: 'erc20:totalSupply', + }) + ).output; + + const rate = ( + await sdk.api.abi.call({ + target: TARGET, + abi: SAVING_MODULE.abis.currentRate, + chain: 'ethereum', + }) + ).output; + + const price = ( + await sdk.api.abi.call({ + target: TARGET, + abi: SAVING_MODULE.abis.currentPrice, + chain: 'ethereum', + }) + ).output; + + const totalSupplyW = ( + await sdk.api.abi.call({ + target: WSRUSD, + abi: 'erc20:totalSupply', + }) + ).output; + + const rateW = ( + await sdk.api.abi.call({ + target: WSRUSD, + abi: WSRUSD_ABI.abis.currentRate, + chain: 'ethereum', + }) + ).output; + + const priceW = ( + await sdk.api.abi.call({ + target: WSRUSD, + abi: 'function convertToAssets(uint256 shares) external view returns (uint256 assets)', + params: [1000000000000000000n], + chain: 'ethereum', + }) + ).output; + + return [ + { + pool: TARGET, + symbol: 'srUSD', + project: 'reservoir-protocol', + chain: 'Ethereum', + tvlUsd: (totalSupply / 10 ** 18) * price / 10 ** 8, + apy: ((1 + rate / 10 ** 12) ** 365 - 1) * 100, + }, + { + pool: WSRUSD, + symbol: 'wsrUSD', + project: 'reservoir-protocol', + chain: 'Ethereum', + tvlUsd: (totalSupplyW / 10 ** 18) * priceW / 10 ** 18, + apy: ((1 + rateW / 10 ** 27) ** 31557600 - 1) * 100, + } + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.reservoir.xyz/', +}; diff --git a/src/adaptors/reservoir/index.js b/src/adaptors/reservoir/index.js new file mode 100644 index 0000000000..56e0eb3026 --- /dev/null +++ b/src/adaptors/reservoir/index.js @@ -0,0 +1,31 @@ +const { fetchURL } = require('../../helper/utils'); + +const API_URL = 'https://api.reservoir.fi/v1/pairs'; + +const getApy = async () => { + const { data: pairs } = await fetchURL(API_URL); + + return pairs.map((pair) => { + const symbols = pair.token0.symbol + '-' + pair.token1.symbol + const poolType = pair.curveId === 0 ? 'Constant Product' : 'Stable' + const tvlUSD = pair.token0.usdPrice * Number(pair.token0Reserve) + pair.token1.usdPrice * Number(pair.token1Reserve) + return { + pool: pair.address, + chain: 'Avalanche', + project: 'reservoir', + symbol: symbols, + tvlUsd: tvlUSD, + apyBase: pair.swapApr, + apyReward: pair.supplyApr, + rewardTokens: ['0x2e3b32730B4F6b6502BdAa9122df3B026eDE5391'], + underlyingTokens: [pair.token0.contractAddress, pair.token1.contractAddress], + poolMeta: poolType + } + }) +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.reservoir.fi/analytics', +}; diff --git a/src/adaptors/resolv/index.js b/src/adaptors/resolv/index.js new file mode 100644 index 0000000000..efa09bfa48 --- /dev/null +++ b/src/adaptors/resolv/index.js @@ -0,0 +1,180 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const ethers = require('ethers'); + +// RLP Constants +const RLP = '0x4956b52aE2fF65D74CA2d61207523288e4528f96'; +const rlpPriceStorage = '0xaE2364579D6cB4Bbd6695846C1D595cA9AF3574d'; +const topic0priceSet = + '0x2f0fe01aa6daff1c7bb411a324bdebe55dc2cd1e0ff2fc504b7569346e7d7d5a'; +const priceSetInterface = new ethers.utils.Interface([ + 'event PriceSet(bytes32 indexed key, uint256 price, uint256 timestamp);', +]); + +// stUSR Constants +const stUSR = '0x6c8984bc7DBBeDAf4F6b2FD766f16eBB7d10AAb4'; +const USR = '0x66a1E37c9b0eAddca17d3662D6c05F4DECf3e110'; +const rewardDistributor = '0x9F805FC8679e5F81a0683c3203ad48417efDAd12'; +const topic0rewardDistributed = + '0x8e97a7864cd6b584c022565df813008122c26e4c7e76117b80268b24c60c8c82'; +const rewardDistributedInterface = new ethers.utils.Interface([ + 'event RewardAllocated(bytes32 indexed _idempotencyKey, uint256 _totalShares, uint256 _totalUSRBefore, uint256 _totalUSRAfter, uint256 _stakingReward, uint256 _feeReward)', +]); + +const DAY_IN_MS = 24 * 60 * 60 * 1000; + +const getTotalSupply = async (tokenAddress, chain = 'ethereum') => { + try { + const { output } = await sdk.api.abi.call({ + target: tokenAddress, + abi: 'erc20:totalSupply', + chain, + }); + return output / 1e18; + } catch (error) { + console.error(`Error fetching total supply for ${tokenAddress}:`, error); + throw error; + } +}; + +const getTokenPrice = async (tokenAddress) => { + try { + const priceKey = `ethereum:${tokenAddress}`; + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + return data.coins[priceKey].price; + } catch (error) { + console.error(`Error fetching price for ${tokenAddress}:`, error); + throw error; + } +}; + +const calculateStUSRApy = (logDescription) => { + const { _totalUSRBefore, _totalUSRAfter, _totalShares } = logDescription.args; + const sharesRateBefore = _totalUSRBefore / _totalShares; + const sharesRateAfter = _totalUSRAfter / _totalShares; + return ((sharesRateAfter - sharesRateBefore) / sharesRateBefore) * 365; +}; + +const rlpPool = async () => { + try { + const totalSupply = await getTotalSupply(RLP); + const currentBlock = await sdk.api.util.getLatestBlock('ethereum'); + const currentDate = new Date(currentBlock.timestamp * 1000); + const previousStartOfDay = + new Date(currentDate).setHours(0, 0, 0, 0) - 2 * DAY_IN_MS; + + const [fromBlock] = await utils.getBlocksByTime( + [previousStartOfDay / 1000], + 'ethereum' + ); + const toBlock = currentBlock.block; + + const logs = ( + await sdk.api.util.getLogs({ + target: rlpPriceStorage, + topic: '', + fromBlock, + toBlock, + keys: [], + chain: 'ethereum', + topics: [topic0priceSet], + }) + ).output.sort((a, b) => a.blockNumber - b.blockNumber); + + let aprBase = 0; + if (logs.length >= 2) { + const lastLpPrice = priceSetInterface.parseLog(logs[logs.length - 1]).args + .price; + const previousLpPrice = priceSetInterface.parseLog(logs[logs.length - 2]) + .args.price; + + aprBase = ((lastLpPrice - previousLpPrice) / previousLpPrice) * 365; + } + + const price = + logs.length > 0 + ? priceSetInterface.parseLog(logs[logs.length - 1]).args.price / 1e18 + : await getTokenPrice(RLP); + const tvl = totalSupply * price; + + return { + pool: RLP, + symbol: 'RLP', + chain: 'ethereum', + project: 'resolv', + tvlUsd: tvl, + apyBase: aprBase * 100, + }; + } catch (error) { + console.error('Error fetching RLP pool data:', error); + throw error; + } +}; + +const stUsrPool = async () => { + try { + const totalSupply = await getTotalSupply(stUSR); + const price = await getTokenPrice(USR); + const tvl = totalSupply * price; + + const currentBlock = await sdk.api.util.getLatestBlock('ethereum'); + const currentDate = new Date(currentBlock.timestamp * 1000); + const previousStartOfDay = + new Date(currentDate).setHours(0, 0, 0, 0) - DAY_IN_MS; + + const [fromBlock] = await utils.getBlocksByTime( + [previousStartOfDay / 1000], + 'ethereum' + ); + const toBlock = currentBlock.block; + + const logs = ( + await sdk.api.util.getLogs({ + target: rewardDistributor, + topic: '', + fromBlock, + toBlock, + keys: [], + chain: 'ethereum', + topics: [topic0rewardDistributed], + }) + ).output.sort((a, b) => a.blockNumber - b.blockNumber); + + let aprBase = 0; + if (logs.length > 0) { + const parsedLog = rewardDistributedInterface.parseLog( + logs[logs.length - 1] + ); + aprBase = calculateStUSRApy(parsedLog); + } + + return { + pool: stUSR, + symbol: 'stUSR', + chain: 'ethereum', + project: 'resolv', + tvlUsd: tvl, + apyBase: aprBase * 100, + }; + } catch (error) { + console.error('Error fetching stUSR pool data:', error); + throw error; + } +}; + +const apy = async () => { + try { + return [await rlpPool(), await stUsrPool()]; + } catch (error) { + console.error('Error fetching APYs:', error); + throw error; + } +}; + +module.exports = { + apy, + url: 'https://www.resolv.xyz/', +}; diff --git a/src/adaptors/resupply/index.js b/src/adaptors/resupply/index.js new file mode 100644 index 0000000000..de84e2c2cc --- /dev/null +++ b/src/adaptors/resupply/index.js @@ -0,0 +1,81 @@ +const utils = require('../utils') +const { getERC4626Info } = require('../utils'); + +const SUPPORTED_PROTOCOLS = { + ethereum: ['curvelend', 'fraxlend'] +}; + +const fetchPairsForProtocol = async (chain, protocol) => { + try { + const response = await utils.getData(`https://api.hippo.army/v1/protocols/${chain}/${protocol}/pairs`); + return response.pairs || []; + } catch (error) { + console.error(`Error fetching ${protocol} pairs for ${chain}:`, error); + return []; + } +}; + +const formatPair = (pair, chain, protocol) => { + const apyRewardBorrow = pair.rewards.reduce((total, reward) => { + return total + parseFloat(reward.apr); + }, 0); + + const symbol = `${pair.underlying_token.symbol}`; + + return { + pool: `${pair.address.toLowerCase()}-${chain}`, + chain: utils.formatChain(chain), + project: 'resupply', + symbol: utils.formatSymbol(symbol), + tvlUsd: parseFloat(pair.total_underlying), + mintedCoin: pair.debt_token.symbol, + apyBase: parseFloat(pair.base_apr), + apyBaseBorrow: parseFloat(pair.borrow_cost_apr), + apyRewardBorrow: apyRewardBorrow, + totalSupplyUsd: parseFloat(pair.total_underlying), + totalBorrowUsd: parseFloat(pair.total_debt), + debtCeilingUsd: parseFloat(pair.borrow_limit), + ltv: parseFloat(pair.total_underlying) > 0 ? parseFloat(pair.total_debt) / parseFloat(pair.total_underlying) : 0, + underlyingTokens: [pair.underlying_token.address], + rewardTokens: pair.rewards.map(reward => reward.token_address), + poolMeta: `${protocol.charAt(0).toUpperCase() + protocol.slice(1)} - ${pair.pair_collateral_token.symbol} collateral`, + url: 'https://resupply.fi/supply', + }; +}; + +const main = async () => { + const allPools = []; + + for (const [chain, protocols] of Object.entries(SUPPORTED_PROTOCOLS)) { + for (const protocol of protocols) { + const pairs = await fetchPairsForProtocol(chain, protocol); + const formattedPairs = pairs.map(pair => formatPair(pair, chain, protocol)); + allPools.push(...formattedPairs); + } + } + const sreusd = await getERC4626Info( + '0x557AB1e003951A73c12D16F0fEA8490E39C33C35', + 'ethereum' + ); + + return allPools + .concat([ + { + symbol: 'sreUSD', + pool: `${sreusd.pool}-ethereum`, + project: 'resupply', + chain: 'Ethereum', + tvlUsd: sreusd.tvl / 1e18, + apyBase: sreusd.apyBase, + poolMeta: 'Savings reUSD', + url: 'https://resupply.fi/supply', + }, + ]) + .filter(pool => utils.keepFinite(pool)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://resupply.fi/', +}; \ No newline at end of file diff --git a/src/adaptors/retro/index.js b/src/adaptors/retro/index.js new file mode 100644 index 0000000000..906b22addf --- /dev/null +++ b/src/adaptors/retro/index.js @@ -0,0 +1,57 @@ +const utils = require('../utils'); + +const chain = 'Polygon'; + +const chainId = 137; + +const oRetro = '0x3a29cab2e124919d14a6f735b6033a3aad2b260f'; + +const getPoolsData = async () => { + const { data: pools = [] } = await utils.getData( + 'https://retro-backend-production.up.railway.app/api/v1/fusions' + ); + + const merklData = await utils.getData( + `https://api.angle.money/v2/merkl?chainIds%5B%5D=${chainId}&AMMs%5B%5D=retro` + ); + + const { data: assets = [] } = await utils.getData( + 'https://retro-backend-production.up.railway.app/api/v1/assets' + ); + + return pools.map((pool) => { + const token0 = assets?.find( + (asset) => + asset?.address.toLowerCase() === pool.token0?.address.toLowerCase() + ); + const token1 = assets?.find( + (asset) => + asset?.address.toLowerCase() === pool.token1?.address.toLowerCase() + ); + + const tvl0 = token0 && token0.price * pool.token0.underlyingReserve; + const tvl1 = token1 && token1.price * pool.token1.underlyingReserve; + + const tvl = (tvl0 || 0) + (tvl1 || 0); + + const merklPool = merklData[chainId].pools?.[pool.underlyingPool] ?? 0; + + return { + pool: `${pool?.address}-polygon`, + chain, + project: 'retro', + symbol: pool.symbol, + tvlUsd: tvl, + apyReward: merklPool?.meanAPR ?? 0, + rewardTokens: [oRetro], + underlyingTokens: [pool?.token0?.address, pool?.token1?.address], + url: `https://app.retro.finance/liquidity/add?currencyA=${token0?.address}¤cyB=${token1?.address}&rangeType=automatic`, + }; + }); +}; + +module.exports = { + timetravel: false, + apy: getPoolsData, + url: 'https://app.retro.finance/liquidity', +}; diff --git a/src/adaptors/return-finance/abiAAVEAvalanche.json b/src/adaptors/return-finance/abiAAVEAvalanche.json new file mode 100644 index 0000000000..3ad292b852 --- /dev/null +++ b/src/adaptors/return-finance/abiAAVEAvalanche.json @@ -0,0 +1,1168 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "aEthUSDC", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aaveV3Pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "_aaveV3Pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_aEthUSDC", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiAAVEPolygon.json b/src/adaptors/return-finance/abiAAVEPolygon.json new file mode 100644 index 0000000000..3ad292b852 --- /dev/null +++ b/src/adaptors/return-finance/abiAAVEPolygon.json @@ -0,0 +1,1168 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "aEthUSDC", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aaveV3Pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "_aaveV3Pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_aEthUSDC", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiBenqiAvalanche.json b/src/adaptors/return-finance/abiBenqiAvalanche.json new file mode 100644 index 0000000000..ed37fdbf71 --- /dev/null +++ b/src/adaptors/return-finance/abiBenqiAvalanche.json @@ -0,0 +1,1150 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "_qiUSDCn", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "qiUSDCn", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiConvex.json b/src/adaptors/return-finance/abiConvex.json new file mode 100644 index 0000000000..6aa7d81da9 --- /dev/null +++ b/src/adaptors/return-finance/abiConvex.json @@ -0,0 +1,1558 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkIncompleteRound", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkPriceZero", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkStalePrice", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "HarvestRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "crvRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "cvxRewards", + "type": "uint256" + } + ], + "name": "RescueRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "harvest", + "type": "bool" + } + ], + "name": "SetHarvestRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "SlippageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint24", + "name": "newSwapFee", + "type": "uint24" + } + ], + "name": "SwapFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkDataFeedCRVUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkDataFeedCVXUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexBooster", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexHandler", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexPoolId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convexRewards", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crv", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crvPriceUSD", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveDepositZap", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveLpToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvx", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvxPriceUSD", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "earnedCRV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "earnedCVX", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvestAndDepositRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "harvestRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IERC20", + "name": "usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "cvx", + "type": "address" + }, + { + "internalType": "address", + "name": "crv", + "type": "address" + }, + { + "internalType": "address", + "name": "curveLpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "curveDepositZap", + "type": "address" + }, + { + "internalType": "address", + "name": "convexBooster", + "type": "address" + }, + { + "internalType": "address", + "name": "convexRewards", + "type": "address" + }, + { + "internalType": "address", + "name": "convexHandler", + "type": "address" + }, + { + "internalType": "uint256", + "name": "convexPoolId", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "uniswapFee", + "type": "uint24" + }, + { + "internalType": "address", + "name": "uniswapV3Router", + "type": "address" + }, + { + "internalType": "address", + "name": "chainlinkDataFeedCVXUSD", + "type": "address" + }, + { + "internalType": "address", + "name": "chainlinkDataFeedCRVUSD", + "type": "address" + } + ], + "internalType": "struct IReturnFinanceConvexUSDCVault.Config", + "name": "config", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakedLpInConvex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapFee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV3Router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "newSwapFee", + "type": "uint24" + } + ], + "name": "updateSwapFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiCurveDEX.json b/src/adaptors/return-finance/abiCurveDEX.json new file mode 100644 index 0000000000..cc39a7f4a8 --- /dev/null +++ b/src/adaptors/return-finance/abiCurveDEX.json @@ -0,0 +1,1578 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkIncompleteRound", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkPriceZero", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkStalePrice", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "HarvestRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "newMultihopPath", + "type": "bytes" + } + ], + "name": "MultihopPathUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint24", + "name": "newSlippageAndFeeFactor", + "type": "uint24" + } + ], + "name": "NewSlippageAndFeeFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "crvRewards", + "type": "uint256" + } + ], + "name": "RescueRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "harvest", + "type": "bool" + } + ], + "name": "SetHarvestRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "SlippageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "ADDRESS_ZERO", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ageur", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkDataFeedCRVUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkDataFeedEURUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crv", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crvPriceEUR", + "outputs": [ + { + "internalType": "int256", + "name": "answer", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveLpToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveMinter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveZap", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "earnedCRV", + "outputs": [ + { + "internalType": "uint256", + "name": "toMint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "euroc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvestAndDepositRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "harvestRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IERC20", + "name": "euroc", + "type": "address" + }, + { + "internalType": "address", + "name": "ageur", + "type": "address" + }, + { + "internalType": "address", + "name": "usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "crv", + "type": "address" + }, + { + "internalType": "address", + "name": "weth", + "type": "address" + }, + { + "internalType": "address", + "name": "curveLpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "curveGauge", + "type": "address" + }, + { + "internalType": "address", + "name": "curveZap", + "type": "address" + }, + { + "internalType": "address", + "name": "curveMinter", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV3Router", + "type": "address" + }, + { + "internalType": "address", + "name": "chainlinkDataFeedCRVUSD", + "type": "address" + }, + { + "internalType": "address", + "name": "chainlinkDataFeedEURUSD", + "type": "address" + }, + { + "internalType": "uint24", + "name": "slippageAndFeeFactor", + "type": "uint24" + } + ], + "internalType": "struct IReturnFinanceCurveEUROCVault.Config", + "name": "config", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "multihopPath", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slippageAndFeeFactor", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakedLpInCurveGauge", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV3Router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "newMultihopPath", + "type": "bytes" + } + ], + "name": "updateMultihopPath", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "newSlippageAndFeeFactor", + "type": "uint24" + } + ], + "name": "updateSlippageAndFeeFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiEthenaEthereum.json b/src/adaptors/return-finance/abiEthenaEthereum.json new file mode 100644 index 0000000000..ca56f71aaf --- /dev/null +++ b/src/adaptors/return-finance/abiEthenaEthereum.json @@ -0,0 +1,1267 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "functionSig", + "type": "bytes4" + } + ], + "name": "FunctionCallNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "InconsistentArrayLengths", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "targetsCount", + "type": "uint256" + } + ], + "name": "BatchExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes4", + "name": "functionSig", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isAllowed", + "type": "bool" + } + ], + "name": "FunctionAllowlistUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "name": "allowedCalls", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "batchCall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "_sUsde", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "functionSig", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "isAllowed", + "type": "bool" + } + ], + "name": "toggleAllowedCalls", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vaultToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiLido.json b/src/adaptors/return-finance/abiLido.json new file mode 100644 index 0000000000..6470918629 --- /dev/null +++ b/src/adaptors/return-finance/abiLido.json @@ -0,0 +1,1250 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "AssetsShouldBeEqualToMsgVaule", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkIncompleteRound", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkPriceZero", + "type": "error" + }, + { + "inputs": [], + "name": "ChainlinkStalePrice", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC7535ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC7535ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC7535ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC7535ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "inputs": [], + "name": "WithdrawFailed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalUsdc", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "SlippageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainlinkDataFeedstETHETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveStETHETHPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stETH", + "type": "address" + }, + { + "internalType": "address", + "name": "_chainlinkDataFeedstETHETH", + "type": "address" + }, + { + "internalType": "address", + "name": "_curveStETHETHPool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_slippage", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "setSlippage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slippage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stETHPriceETH", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/abiMakerDAO.json b/src/adaptors/return-finance/abiMakerDAO.json new file mode 100644 index 0000000000..9d8a5ae2ba --- /dev/null +++ b/src/adaptors/return-finance/abiMakerDAO.json @@ -0,0 +1,1230 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxDeposit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxMint", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxRedeem", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "ERC4626ExceededMaxWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "wrongAddress", + "type": "address" + } + ], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "UnableToSweep", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "whitelistedAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "AddressWhitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "PoolDonation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalDai", + "type": "uint256" + } + ], + "name": "RescueFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "SlippageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callExternalContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_usdc", + "type": "address" + }, + { + "internalType": "address", + "name": "_dai", + "type": "address" + }, + { + "internalType": "address", + "name": "_sDai", + "type": "address" + }, + { + "internalType": "address", + "name": "_uniswapV3Router", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_slippage", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "rescueFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sDai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newSlippage", + "type": "uint256" + } + ], + "name": "setSlippage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slippage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "sweepFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "updatedAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV3Router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usdc", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/return-finance/index.js b/src/adaptors/return-finance/index.js new file mode 100644 index 0000000000..ba465094cb --- /dev/null +++ b/src/adaptors/return-finance/index.js @@ -0,0 +1,121 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const abiAAVEPolygon = require('./abiAAVEPolygon.json'); +const abiAAVEAvalanche = require('./abiAAVEAvalanche.json'); +const abiMakerDAO = require('./abiMakerDAO.json'); +const abiConvex = require('./abiConvex.json'); +const abiBenqi = require('./abiBenqiAvalanche.json'); +const abiCurveDex = require('./abiCurveDEX.json'); +const abiLido = require('./abiLido.json'); +const abiEthenaEthereum = require('./abiEthenaEthereum.json'); + +const getPoolData = async ({ contract, abi, chain, exchangeRate = 1 }) => { + const { output: tvlUsd } = await sdk.api.abi.call({ + target: contract, + abi: abi.find((m) => m.name === 'totalAssets'), + chain, + }); + + const { output: decimals } = await sdk.api.abi.call({ + target: contract, + abi: abi.find((m) => m.name === 'decimals'), + chain, + }); + + const poolsData = await utils.getData( + 'https://api.return.finance//api/our-pools' + ); + + const currentPool = poolsData.pools.find((pool) => { + const incomingChainParam = chain === 'avax' ? 'avalanche' : chain; + + return ( + pool.networkName.toLowerCase() === incomingChainParam && + pool.returnContractAddress.toLowerCase() === contract.toLowerCase() + ); + }); + + return { + pool: `${contract}-${chain}`, + chain, + project: 'return-finance', + symbol: currentPool?.poolPair, + tvlUsd: (tvlUsd / Math.pow(10, decimals)) * exchangeRate, + apyBase: currentPool?.apy, + }; +}; + +const getApy = async () => { + const ethExchangeRates = await utils.getData( + 'https://api.coinbase.com/v2/exchange-rates?currency=ETH' + ); + + const ethUsdExchangeRate = ethExchangeRates.data.rates.USDC; + + const aavePolygon = await getPoolData({ + contract: '0x0271a46c049293448c2d4794bcd51f953bf742e8', + abi: abiAAVEPolygon, + chain: 'polygon', + }); + + const aaveAvalanche = await getPoolData({ + contract: '0x0271A46c049293448C2d4794bCD51f953Bf742e8', + abi: abiAAVEAvalanche, + chain: 'avax', + }); + + const benqi = await getPoolData({ + contract: '0x3A3dAdbca3ec5a815431f45eca33EF1520388Ef2', + abi: abiBenqi, + chain: 'avax', + }); + + const makerDao = await getPoolData({ + contract: '0xD8785CDae9Ec24b8796c45E3a2D0F7b03194F826', + abi: abiMakerDAO, + chain: 'ethereum', + }); + + const convexFinance = await getPoolData({ + contract: '0x4D7F26a161a3e1fbE10C11e1c9abC05Fa43DdE67', + abi: abiConvex, + chain: 'ethereum', + }); + + const curveDEX = await getPoolData({ + contract: '0xc2d4d9070236bA4ffefd7cf565eb98d11bFeB8E1', + abi: abiCurveDex, + chain: 'ethereum', + }); + + const lido = await getPoolData({ + contract: '0x2C2f0FFbFA1B8b9C85400f1726e1bc0892e63D9F', + abi: abiLido, + chain: 'ethereum', + exchangeRate: Number(ethUsdExchangeRate), + }); + + const ethenaEthereum = await getPoolData({ + contract: '0x4cba5780Dcbee1c8B5220D24f4F54e14D796a31C', + abi: abiEthenaEthereum, + chain: 'ethereum', + }); + + return [ + aavePolygon, + aaveAvalanche, + benqi, + makerDao, + convexFinance, + curveDEX, + lido, + ethenaEthereum, + ].filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://return.finance', +}; diff --git a/src/adaptors/rezerve-money/index.js b/src/adaptors/rezerve-money/index.js new file mode 100644 index 0000000000..28d5fd02b6 --- /dev/null +++ b/src/adaptors/rezerve-money/index.js @@ -0,0 +1,180 @@ +const { ethers } = require('ethers'); +const sdk = require('@defillama/sdk'); + +const BigNumber = require('bignumber.js'); +const superagent = require('superagent'); + +const abi = { + balanceOf: 'erc20:balanceOf', + totalSupply: 'erc20:totalSupply', + totalAssets: 'function totalAssets() public view returns (uint256)', +}; + +const lstRZR = '0x67A298e5B65dB2b4616E05C3b455E017275f53cB'; +const RZR = '0xb4444468e444f89e1c2cac2f1d3ee7e336cbd1f5'; + +const chain = 'sonic'; + +const DECIMALS = new BigNumber((1e18).toString()); + +const COINS = [lstRZR, RZR]; + +const vaultMeta = { + [lstRZR]: { + asset: RZR, + symbol: 'lstRZR', + name: 'Liquid Staked Rezerve.money', + }, +}; + +const apy = async () => { + const prices = await getPrices(COINS); + const strategyApys = await Promise.all( + [lstRZR].map((vault) => calcErc4626PoolApy(vault, prices)) + ); + return strategyApys; +}; + +async function getPrices(addresses) { + const coins = getCoinsURI(addresses); + const url = `https://coins.llama.fi/prices/current/${coins}`; + return await fetchPrices(url); +} + +async function getPricesDaysBefore(addresses, days) { + const coins = getCoinsURI(addresses); + const timestamp = getTimestampDaysBefore(days); + const url = `https://coins.llama.fi/prices/historical/${timestamp}/${coins}`; + return await fetchPrices(url); +} + +async function fetchPrices(url) { + const prices = (await superagent.get(url)).body.coins; + const pricesByAddresses = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + return pricesByAddresses; +} + +function getCoinsURI(addresses) { + return `${addresses.map((address) => `${chain}:${address}`)}`; +} + +async function getBlockNumberDaysBefore(days) { + const daysBefore = getTimestampDaysBefore(days); + return await getBlockNumber(daysBefore); +} + +function getTimestampDaysBefore(days) { + return Math.floor(Date.now() / 1000) - 24 * 60 * 60 * days; +} + +async function getBlockNumber(timestamp) { + const response = await superagent.get( + `https://coins.llama.fi/block/sonic/${timestamp}` + ); + return response.body.height; +} + +async function calcErc4626PoolApy(vault, prices) { + const tvlUsd = await calcTvl(vault, prices); + + const sharePriceNow = await calcSharePrice(vault, prices); + + const sharePriceYesterday = await calcSharePrice(vault, prices, 1); + const aprBase = calcApr(sharePriceNow, sharePriceYesterday, 1); + + const sharePriceWeekBefore = await calcSharePrice(vault, prices, 7); + const aprBase7d = calcApr(sharePriceNow, sharePriceWeekBefore, 7); + + const apyBase = convertAprToApy(aprBase); + const apyBase7d = convertAprToApy(aprBase7d); + + return { + pool: `${vault}-${chain}`, + chain, + project: 'rezerve-money', + symbol: vaultMeta[vault].symbol, + tvlUsd, + underlyingTokens: [vaultMeta[vault].asset], + rewardTokens: [], + apyBase, + apyBase7d, + apyReward: 0, + poolMeta: vaultMeta[vault].name, + url: 'https://rezerve.money/liquid-staking?utm_source=defillama', + }; +} + +async function calcTvl(vault, prices) { + const asset = vaultMeta[vault].asset; + const price = prices[asset.toLowerCase()]; + const assets = await totalAssets(vault); + const tvlUsd = assets.multipliedBy(price).div(DECIMALS); + return tvlUsd.toNumber(); +} + +async function calcSharePrice(vault, prices, days = 0) { + let assetPrices = prices; + let block = 'latest'; + if (days > 0) { + assetPrices = await getPricesDaysBefore(COINS, days); + block = await getBlockNumberDaysBefore(days); + } + const assets = await calcAssets(vault, assetPrices, block); + const shares = await getShares(vault, block); + const sharePrice = getSharePrice(assets, shares); + return sharePrice; +} + +async function calcAssets(vault, prices, block = 'latest') { + const assets = await totalAssets(vault, block); + return assets; +} + +const totalAssets = async (vault, block = 'latest') => { + return new BigNumber(await callAbi(vault, abi.totalAssets, null, block)); +}; + +function calcApr(sharePriceNow, sharePriceBefore, daysBetween) { + return sharePriceBefore.isZero() + ? 0 + : sharePriceNow + .minus(sharePriceBefore) + .multipliedBy(36500) + .div(daysBetween) + .div(sharePriceBefore) + .toNumber(); +} + +function convertAprToApy(apr) { + const aprNormalized = apr / 100; + const n = 365 * 3; + return (Math.pow(1 + aprNormalized / n, n) - 1) * 100; +} + +async function getShares(vault, block = 'latest') { + return new BigNumber(await totalSupply(vault, block)); +} + +async function getSharePrice(assets, shares) { + return shares.isZero() ? new BigNumber(0) : assets.div(shares); +} + +async function callAbi(target, abi, params, block = 'latest') { + return (await sdk.api.abi.call({ target, abi, params, block, chain })).output; +} + +const totalSupply = async (token, block = 'latest') => { + return await callAbi(token, abi.totalSupply, null, block); +}; + +module.exports = { + timetravel: true, + apy, + url: 'https://rezerve.money', +}; diff --git a/src/adaptors/rheo/VeryLiquidVault.json b/src/adaptors/rheo/VeryLiquidVault.json new file mode 100644 index 0000000000..435893bcce --- /dev/null +++ b/src/adaptors/rheo/VeryLiquidVault.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"UPGRADE_INTERFACE_VERSION","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"addStrategy","inputs":[{"name":"strategy_","type":"address","internalType":"contract IVault"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"allowance","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"approve","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"asset","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"auth","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract Auth"}],"stateMutability":"view"},{"type":"function","name":"balanceOf","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"convertToAssets","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"convertToShares","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"deposit","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"eip712Domain","inputs":[],"outputs":[{"name":"fields","type":"bytes1","internalType":"bytes1"},{"name":"name","type":"string","internalType":"string"},{"name":"version","type":"string","internalType":"string"},{"name":"chainId","type":"uint256","internalType":"uint256"},{"name":"verifyingContract","type":"address","internalType":"address"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"extensions","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"type":"function","name":"feeRecipient","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"highWaterMark","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"auth_","type":"address","internalType":"contract Auth"},{"name":"asset_","type":"address","internalType":"contract IERC20"},{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"fundingAccount","type":"address","internalType":"address"},{"name":"firstDepositAmount","type":"uint256","internalType":"uint256"},{"name":"strategies_","type":"address[]","internalType":"contract IVault[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"initialize","inputs":[{"name":"auth_","type":"address","internalType":"contract Auth"},{"name":"asset_","type":"address","internalType":"contract IERC20"},{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"fundingAccount_","type":"address","internalType":"address"},{"name":"firstDepositAmount_","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isStrategy","inputs":[{"name":"strategy","type":"address","internalType":"contract IVault"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"maxDeposit","inputs":[{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"maxMint","inputs":[{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"maxRedeem","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"maxWithdraw","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"mint","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"multicall","inputs":[{"name":"data","type":"bytes[]","internalType":"bytes[]"}],"outputs":[{"name":"results","type":"bytes[]","internalType":"bytes[]"}],"stateMutability":"nonpayable"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"nonces","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"pause","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"paused","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"performanceFeePercent","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"permit","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"previewDeposit","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"previewMint","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"previewRedeem","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"previewWithdraw","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"proxiableUUID","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"rebalance","inputs":[{"name":"strategyFrom","type":"address","internalType":"contract IVault"},{"name":"strategyTo","type":"address","internalType":"contract IVault"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"maxSlippagePercent","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"rebalanceMaxSlippagePercent","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"redeem","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"removeStrategy","inputs":[{"name":"strategyToRemove","type":"address","internalType":"contract IVault"},{"name":"strategyToReceiveAssets","type":"address","internalType":"contract IVault"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"maxSlippagePercent","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"reorderStrategies","inputs":[{"name":"newStrategiesOrder","type":"address[]","internalType":"contract IVault[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeRecipient","inputs":[{"name":"feeRecipient_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setPerformanceFeePercent","inputs":[{"name":"performanceFeePercent_","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setRebalanceMaxSlippagePercent","inputs":[{"name":"rebalanceMaxSlippagePercent_","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setTotalAssetsCap","inputs":[{"name":"totalAssetsCap_","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"strategies","inputs":[{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"contract IVault"}],"stateMutability":"view"},{"type":"function","name":"strategies","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"contract IVault[]"}],"stateMutability":"view"},{"type":"function","name":"strategiesCount","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"total","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"totalAssetsCap","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"transfer","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"unpause","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"upgradeToAndCall","inputs":[{"name":"newImplementation","type":"address","internalType":"address"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"type":"function","name":"withdraw","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"AuthSet","inputs":[{"name":"auth","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"assets","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"DepositFailed","inputs":[{"name":"strategy","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"EIP712DomainChanged","inputs":[],"anonymous":false},{"type":"event","name":"FeeRecipientSet","inputs":[{"name":"feeRecipientBefore","type":"address","indexed":true,"internalType":"address"},{"name":"feeRecipientAfter","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"HighWaterMarkUpdated","inputs":[{"name":"highWaterMarkBefore","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"highWaterMarkAfter","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"name":"account","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"PerformanceFeeMinted","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"assets","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PerformanceFeePercentSet","inputs":[{"name":"performanceFeePercentBefore","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"performanceFeePercentAfter","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"RebalanceMaxSlippagePercentSet","inputs":[{"name":"oldRebalanceMaxSlippagePercent","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newRebalanceMaxSlippagePercent","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Rebalanced","inputs":[{"name":"strategyFrom","type":"address","indexed":true,"internalType":"address"},{"name":"strategyTo","type":"address","indexed":true,"internalType":"address"},{"name":"rebalancedAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"maxSlippagePercent","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"StrategyAdded","inputs":[{"name":"strategy","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"StrategyRemoved","inputs":[{"name":"strategy","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"StrategyReordered","inputs":[{"name":"strategyOld","type":"address","indexed":true,"internalType":"address"},{"name":"strategyNew","type":"address","indexed":true,"internalType":"address"},{"name":"index","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"TotalAssetsCapSet","inputs":[{"name":"totalAssetsCapBefore","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"totalAssetsCapAfter","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"name":"account","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"name":"implementation","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"VaultStatus","inputs":[{"name":"totalShares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"totalAssets","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"name":"sender","type":"address","indexed":true,"internalType":"address"},{"name":"receiver","type":"address","indexed":true,"internalType":"address"},{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"assets","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"WithdrawFailed","inputs":[{"name":"strategy","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"neededRole","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"AddressEmptyCode","inputs":[{"name":"target","type":"address","internalType":"address"}]},{"type":"error","name":"ArrayLengthMismatch","inputs":[{"name":"expectedLength","type":"uint256","internalType":"uint256"},{"name":"actualLength","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"CannotDepositToStrategies","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"remainingAssets","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"CannotWithdrawFromStrategies","inputs":[{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"missingAssets","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ECDSAInvalidSignature","inputs":[]},{"type":"error","name":"ECDSAInvalidSignatureLength","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ECDSAInvalidSignatureS","inputs":[{"name":"s","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"ERC1967InvalidImplementation","inputs":[{"name":"implementation","type":"address","internalType":"address"}]},{"type":"error","name":"ERC1967NonPayable","inputs":[]},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"allowance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"name":"spender","type":"address","internalType":"address"}]},{"type":"error","name":"ERC2612ExpiredSignature","inputs":[{"name":"deadline","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC2612InvalidSigner","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"ERC4626ExceededMaxDeposit","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"max","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC4626ExceededMaxMint","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"max","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC4626ExceededMaxRedeem","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"max","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC4626ExceededMaxWithdraw","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"assets","type":"uint256","internalType":"uint256"},{"name":"max","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"EnforcedPause","inputs":[]},{"type":"error","name":"ExpectedPause","inputs":[]},{"type":"error","name":"FailedCall","inputs":[]},{"type":"error","name":"InvalidAccountNonce","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"currentNonce","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidMaxSlippagePercent","inputs":[{"name":"maxSlippagePercent","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidStrategy","inputs":[{"name":"strategy","type":"address","internalType":"address"}]},{"type":"error","name":"MaxStrategiesExceeded","inputs":[{"name":"strategiesCount","type":"uint256","internalType":"uint256"},{"name":"maxStrategies","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"NullAddress","inputs":[]},{"type":"error","name":"NullAmount","inputs":[]},{"type":"error","name":"PerformanceFeePercentTooHigh","inputs":[{"name":"performanceFeePercent","type":"uint256","internalType":"uint256"},{"name":"maximumPerformanceFeePercent","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"TransferredAmountLessThanMin","inputs":[{"name":"assetsBefore","type":"uint256","internalType":"uint256"},{"name":"assetsAfter","type":"uint256","internalType":"uint256"},{"name":"slippage","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"maxSlippagePercent","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"UUPSUnauthorizedCallContext","inputs":[]},{"type":"error","name":"UUPSUnsupportedProxiableUUID","inputs":[{"name":"slot","type":"bytes32","internalType":"bytes32"}]}],"bytecode":{"object":"0x60a060405230608052348015610013575f80fd5b5061001c610029565b610024610029565b6100db565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100795760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100d85780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6080516157b26101015f395f81816126150152818161263e015261276e01526157b25ff3fe608060405260043610610366575f3560e01c80636e553f65116101c8578063b460af94116100fd578063d905777e1161009d578063df652d411161006d578063df652d41146109b0578063e74b981b146109cf578063ef8b30f7146109ee578063f34e121714610a0d575f80fd5b8063d905777e1461093d578063d9f9027f1461095c578063dd62ed3e1461097d578063de9375f21461099c575f80fd5b8063c6e6f592116100d8578063c6e6f592146108c1578063ce96cb77146108e0578063d505accf146108ff578063d574ea3d1461091e575f80fd5b8063b460af9414610864578063ba08765214610883578063c63d75b6146108a2575f80fd5b806395d89b4111610168578063ab3ffa1a11610143578063ab3ffa1a146107ca578063ac9650d8146107e9578063ad3cb1cc14610815578063b3d7f6b914610845575f80fd5b806395d89b4114610778578063a01e3f741461078c578063a9059cbb146107ab575f80fd5b80638456cb59116101a35780638456cb591461070a57806384b0196e1461071e578063907d54051461074557806394bf804d14610759575f80fd5b80636e553f65146106ad57806370a08231146106cc5780637ecebe00146106eb575f80fd5b8063317b72241161029e57806348f5b9801161023e57806352d1902d1161021957806352d1902d1461062a57806354fd4d501461063e5780635c975abb1461066b5780636e49db1c1461068e575f80fd5b806348f5b980146105e45780634cdad506146105f85780634f1ef28614610617575f80fd5b80633f4ba83a116102795780633f4ba83a14610589578063402d267d1461059d57806345f663dd146105bc57806346904840146105d0575f80fd5b8063317b72241461052a5780633644e5151461054957806338d52e0f1461055d575f80fd5b80631e8410da116103095780632489f7f7116102e45780632489f7f7146104b257806329d7b732146104c65780632e8ebaae146104e5578063313ce56714610504575f80fd5b80631e8410da14610460578063223e54791461047457806323b872dd14610493575f80fd5b8063095ea7b311610344578063095ea7b3146103d15780630a28a47714610400578063114fbced1461041f57806318160ddd14610440575f80fd5b806301e1d1141461036a57806306fdde031461039157806307a2d13a146103b2575b5f80fd5b348015610375575f80fd5b5061037e610a2c565b6040519081526020015b60405180910390f35b34801561039c575f80fd5b506103a5610b53565b6040516103889190614b78565b3480156103bd575f80fd5b5061037e6103cc366004614b8a565b610bf8565b3480156103dc575f80fd5b506103f06103eb366004614bc0565b610c12565b6040519015158152602001610388565b34801561040b575f80fd5b5061037e61041a366004614b8a565b610c43565b34801561042a575f80fd5b5061043e610439366004614b8a565b610c4f565b005b34801561044b575f80fd5b505f8051602061569d8339815191525461037e565b34801561046b575f80fd5b5061037e610c91565b34801561047f575f80fd5b5061043e61048e366004614bea565b610cb2565b34801561049e575f80fd5b506103f06104ad366004614c05565b610d09565b3480156104bd575f80fd5b5061037e610d3c565b3480156104d1575f80fd5b5061043e6104e0366004614d7b565b610d53565b3480156104f0575f80fd5b506103f06104ff366004614bea565b610f14565b34801561050f575f80fd5b50610518610f26565b60405160ff9091168152602001610388565b348015610535575f80fd5b5061043e610544366004614b8a565b610f2f565b348015610554575f80fd5b5061037e610f57565b348015610568575f80fd5b50610571610f60565b6040516001600160a01b039091168152602001610388565b348015610594575f80fd5b5061043e610f8e565b3480156105a8575f80fd5b5061037e6105b7366004614bea565b610fce565b3480156105c7575f80fd5b5061037e610fe8565b3480156105db575f80fd5b50610571610ff9565b3480156105ef575f80fd5b5061037e611031565b348015610603575f80fd5b5061037e610612366004614b8a565b611042565b61043e610625366004614e42565b61104d565b348015610635575f80fd5b5061037e61106c565b348015610649575f80fd5b506040805180820190915260058152640302e312e360dc1b60208201526103a5565b348015610676575f80fd5b505f8051602061573d8339815191525460ff166103f0565b348015610699575f80fd5b5061043e6106a8366004614ea1565b611087565b3480156106b8575f80fd5b5061037e6106c7366004614ee4565b6111c4565b3480156106d7575f80fd5b5061037e6106e6366004614bea565b6111df565b3480156106f6575f80fd5b5061037e610705366004614bea565b61120f565b348015610715575f80fd5b5061043e611219565b348015610729575f80fd5b50610732611253565b6040516103889796959493929190614f12565b348015610750575f80fd5b5061037e6112fc565b348015610764575f80fd5b5061037e610773366004614ee4565b61130d565b348015610783575f80fd5b506103a5611328565b348015610797575f80fd5b5061043e6107a6366004614fa8565b611366565b3480156107b6575f80fd5b506103f06107c5366004614bc0565b611542565b3480156107d5575f80fd5b5061043e6107e4366004614ea1565b611555565b3480156107f4575f80fd5b50610808610803366004615092565b611745565b60405161038891906150d0565b348015610820575f80fd5b506103a5604051806040016040528060058152602001640352e302e360dc1b81525081565b348015610850575f80fd5b5061037e61085f366004614b8a565b61182a565b34801561086f575f80fd5b5061037e61087e366004615133565b611836565b34801561088e575f80fd5b5061037e61089d366004615133565b611852565b3480156108ad575f80fd5b5061037e6108bc366004614bea565b61186e565b3480156108cc575f80fd5b5061037e6108db366004614b8a565b6118ad565b3480156108eb575f80fd5b5061037e6108fa366004614bea565b6118bf565b34801561090a575f80fd5b5061043e610919366004615172565b6118d4565b348015610929575f80fd5b50610571610938366004614b8a565b611a29565b348015610948575f80fd5b5061037e610957366004614bea565b611a6c565b348015610967575f80fd5b50610970611aa3565b60405161038891906151e3565b348015610988575f80fd5b5061037e61099736600461522e565b611ab5565b3480156109a7575f80fd5b50610571611afe565b3480156109bb575f80fd5b5061043e6109ca366004614b8a565b611b1d565b3480156109da575f80fd5b5061043e6109e9366004614bea565b611b38565b3480156109f9575f80fd5b5061037e610a08366004614b8a565b611b53565b348015610a18575f80fd5b5061043e610a27366004615092565b611b5e565b5f8051602061571d83398151915280545f9190825b81811015610b4d575f835f018281548110610a5e57610a5e61525a565b5f918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116915081906307a2d13a9082906370a0823190602401602060405180830381865afa158015610ab7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610adb919061526e565b6040518263ffffffff1660e01b8152600401610af991815260200190565b602060405180830381865afa158015610b14573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b38919061526e565b610b429086615299565b945050600101610a41565b50505090565b60605f5f8051602061567d8339815191525b9050806003018054610b76906152ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba2906152ac565b8015610bed5780601f10610bc457610100808354040283529160200191610bed565b820191905f5260205f20905b815481529060010190602001808311610bd057829003601f168201915b505050505091505090565b5f610c01611e20565b610c0a82611042565b90505b919050565b5f610c1b611e4f565b610c258383611e86565b9050610c3d60015f8051602061575d83398151915255565b92915050565b5f610c0a826001611eb0565b610c57611e4f565b5f8051602061565d833981519152610c6e81611ef4565b610c7782611f9e565b50610c8e60015f8051602061575d83398151915255565b50565b5f610c9a611e20565b505f805160206156fd8339815191525490565b905090565b610cba611e4f565b5f8051602061565d833981519152610cd181611ef4565b610cea82610cdd610f60565b610ce5611afe565b612006565b50610cf361222b565b610c8e60015f8051602061575d83398151915255565b5f610d12611e4f565b610d1d848484612283565b9050610d3560015f8051602061575d83398151915255565b9392505050565b5f610d45611e20565b610d4d611aa3565b51905090565b5f610d5c6122a6565b805490915060ff600160401b82041615906001600160401b03165f81158015610d825750825b90505f826001600160401b03166001148015610d9d5750303b155b905081158015610dab575080155b15610dc95760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610df357845460ff60401b1916600160401b1785555b604051632404341f60e21b81525f600482018190526024820152610e6a906001600160a01b038e1690639010d07c90604401602060405180830381865afa158015610e40573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e6491906152e4565b5f6122ce565b5f5b8651811015610ea157610e99878281518110610e8a57610e8a61525a565b60200260200101518d8f612006565b600101610e6c565b50610eb2662386f26fc100006122e8565b610ec08c8c8c8c8c8c611366565b8315610f0657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b5f610f1d611e20565b610c0a8261238a565b5f610cad6123fb565b610f37611e4f565b5f8051602061565d833981519152610f4e81611ef4565b610c77826122e8565b5f610cad61243d565b7f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e00546001600160a01b031690565b610f96611e4f565b5f8051602061565d833981519152610fad81611ef4565b610fb5612446565b50610fcc60015f8051602061575d83398151915255565b565b5f610c0a610fda6124a5565b610fe38461255c565b612593565b5f610ff1611e20565b610cad6125a2565b5f611002611e20565b507f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd02546001600160a01b031690565b5f61103a611e20565b610cad6125bb565b5f610c0a825f6125cf565b61105561260a565b61105e82612698565b61106882826126a2565b5050565b5f611075612763565b505f805160206156dd83398151915290565b61108f611e4f565b6110976127ac565b7f17a8e30262c1f919c33056d877a3c22b95c2f5e4dac44683c1c2323cd79fbdb06110c181611ef4565b6110cd82610fe36127d2565b91506110d88561238a565b61110557604051633ae252cd60e21b81526001600160a01b03861660048201526024015b60405180910390fd5b61110e8461238a565b61113657604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b836001600160a01b0316856001600160a01b03160361117357604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b825f0361119357604051630e5a744960e41b815260040160405180910390fd5b61119f858585856127e6565b506111a861222b565b6111be60015f8051602061575d83398151915255565b50505050565b5f6111cd611e4f565b6111d5612df2565b610c258383612f63565b5f805f8051602061567d8339815191525b6001600160a01b039093165f9081526020939093525050604090205490565b5f610c0a82612f80565b611221611e4f565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161124b81611ef4565b610fb5612fa8565b5f60608082808083815f805160206156bd833981519152805490915015801561127e57506001810154155b6112c25760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b60448201526064016110fc565b6112ca612ff0565b6112d261302e565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b5f611305611e20565b610cad6127d2565b5f611316611e4f565b61131e612df2565b610c258383613044565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f8051602061567d83398151915291610b76906152ac565b5f61136f6122a6565b805490915060ff600160401b82041615906001600160401b03165f811580156113955750825b90505f826001600160401b031660011480156113b05750303b155b9050811580156113be575080155b156113dc5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561140657845460ff60401b1916600160401b1785555b61140f8a613057565b6114198989613068565b6114228961307a565b61142a6130a5565b6114326130b5565b61143a6130b5565b6114426130b5565b6001600160a01b038b166114695760405163e99d5ac560e01b815260040160405180910390fd5b855f0361148957604051630e5a744960e41b815260040160405180910390fd5b5f8051602061563d83398151915280546001600160a01b0319166001600160a01b038d1690811782556040517ff8c4af92684d0fd7f652724eed9174e4842c3a2a49b2f0809fd721f6dd8b172d905f90a26114e45f19611f9e565b6114ee88886130bd565b50831561153557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050505050565b5f61154b611e4f565b610c258383613110565b61155d611e4f565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161158781611ef4565b6115908561238a565b6115b857604051633ae252cd60e21b81526001600160a01b03861660048201526024016110fc565b6115c18461238a565b6115e957604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b836001600160a01b0316856001600160a01b03160361162657604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b8215611715576040516370a0823160e01b81523060048201525f906001600160a01b038716906307a2d13a9082906370a0823190602401602060405180830381865afa158015611678573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061169c919061526e565b6040518263ffffffff1660e01b81526004016116ba91815260200190565b602060405180830381865afa1580156116d5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f9919061526e565b90506117058482612593565b9350611713868686866127e6565b505b61171e8561311d565b611726610a2c565b5f0361119f57604051630e5a744960e41b815260040160405180910390fd5b604080515f815260208101909152606090826001600160401b0381111561176e5761176e614c43565b6040519080825280602002602001820160405280156117a157816020015b606081526020019060019003908161178c5790505b5091505f5b83811015611822576117fd308686848181106117c4576117c461525a565b90506020028101906117d69190615312565b856040516020016117e99392919061536b565b60405160208183030381529060405261326e565b83828151811061180f5761180f61525a565b60209081029190910101526001016117a6565b505092915050565b5f610c0a8260016125cf565b5f61183f611e4f565b611847612df2565b610d1d8484846132e0565b5f61185b611e4f565b611863612df2565b610d1d8484846132fe565b5f8061187983610fce565b90505f5f1982146118935761188e825f611eb0565b611896565b5f195b90506118a581610fe386613312565b949350505050565b5f6118b6611e20565b610c0a82611b53565b5f610c0a6118cb61333f565b610fe3846133b6565b834211156118f85760405163313c898160e11b8152600481018590526024016110fc565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886119628c6001600160a01b03165f9081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f6119bc826133cc565b90505f6119cb828787876133f8565b9050896001600160a01b0316816001600160a01b031614611a12576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016110fc565b611a1d8a8a8a613424565b50505050505050505050565b5f611a32611e20565b5f8051602061571d833981519152805483908110611a5257611a5261525a565b5f918252602090912001546001600160a01b031692915050565b5f80611a77836118bf565b90505f5f198214611a9157611a8c825f611eb0565b611a94565b5f195b90506118a581610fe386613431565b6060611aad611e20565b610cad613447565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f5f8051602061563d8339815191525b546001600160a01b0316919050565b611b25611e4f565b5f611b2f81611ef4565b610c77826134b0565b611b40611e4f565b5f611b4a81611ef4565b610c778261358a565b5f610c0a825f611eb0565b611b66611e4f565b611b6e6127ac565b7f17a8e30262c1f919c33056d877a3c22b95c2f5e4dac44683c1c2323cd79fbdb0611b9881611ef4565b5f8051602061571d8339815191528054838114611bd257604051631f4bb7c160e31b815260048101829052602481018590526044016110fc565b5f5b81811015611cfa57611c0b868683818110611bf157611bf161525a565b9050602002016020810190611c069190614bea565b61238a565b611c5b57858582818110611c2157611c2161525a565b9050602002016020810190611c369190614bea565b604051633ae252cd60e21b81526001600160a01b0390911660048201526024016110fc565b5f611c67826001615299565b90505b82811015611cf157868682818110611c8457611c8461525a565b9050602002016020810190611c999190614bea565b6001600160a01b0316878784818110611cb457611cb461525a565b9050602002016020810190611cc99190614bea565b6001600160a01b031603611ce957868683818110611c2157611c2161525a565b600101611c6a565b50600101611bd4565b505f5b81811015611e06575f835f018281548110611d1a57611d1a61525a565b5f918252602090912001546001600160a01b03169050868683818110611d4257611d4261525a565b9050602002016020810190611d579190614bea565b845f018381548110611d6b57611d6b61525a565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555081878784818110611da957611da961525a565b9050602002016020810190611dbe9190614bea565b6001600160a01b0316826001600160a01b03167f11d8593881095d510e51d5617699f2674b01890b9f5816abfe33c40f4932882460405160405180910390a450600101611cfd565b5050505061106860015f8051602061575d83398151915255565b5f8051602061575d83398151915254600203610fcc57604051633ee5aeb560e01b815260040160405180910390fd5b5f8051602061575d833981519152805460011901611e8057604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f33611e93818585613424565b5060019392505050565b60015f8051602061575d83398151915255565b5f610d35611ebf82600a615463565b5f8051602061569d83398151915254611ed89190615299565b611ee0610a2c565b611eeb906001615299565b85919085613632565b611efc611afe565b6001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611f54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f789190615471565b610c8e5760405163e2517d3f60e01b8152336004820152602481018290526044016110fc565b7f83cbba01667a5ddf3820f0a2c4220dbc355a1a788c7094daad71b73a418b0d018054908290556040515f8051602061563d8339815191529190839082907ffff0e599b3c11909c76f6ae341845496f4754265c277920935aa989434b611cf905f90a3505050565b6001600160a01b03831661202d5760405163e99d5ac560e01b815260040160405180910390fd5b6120368361238a565b1561205f57604051633ae252cd60e21b81526001600160a01b03841660048201526024016110fc565b816001600160a01b0316836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c991906152e4565b6001600160a01b03161415806121505750806001600160a01b0316836001600160a01b031663de9375f26040518163ffffffff1660e01b8152600401602060405180830381865afa158015612120573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214491906152e4565b6001600160a01b031614155b1561217957604051633ae252cd60e21b81526001600160a01b03841660048201526024016110fc565b5f8051602061571d83398151915280546001810182555f8281527fbd3b60dada78b9553105038e485344c290642e896a2040a87e5442d9a8f189d390910180546001600160a01b0319166001600160a01b03871690811790915560405190917f3f008fd510eae7a9e7bee13513d7b83bef8003d488b5a3d0b0da4de71d6846f191a28054600a10156111be57805460405163a0c5dde760e01b81526004810191909152600a60248201526044016110fc565b7fbe95051ceb3f91d85436579dcb05e73839fcf7ec679038845ee9df7027ce18e36122615f8051602061569d8339815191525490565b612269610a2c565b6040805192835260208301919091520160405180910390a1565b5f33612290858285613674565b61229b8585856136bf565b506001949350505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c3d565b6122d661371c565b6122df8261358a565b611068816134b0565b670de0b6b3a7640000811115612314576040516322643c8760e21b8152600481018290526024016110fc565b7f851713d8b7886cdb5682ccb4d2dba1bf8cae30c699ce588016da31dab5d7f10180549082905560408051828152602081018490525f8051602061571d83398151915292917ff7e9c2b164c5e7510b6027354248eae9ab7974293420bcba68421fced24c4a2491015b60405180910390a1505050565b5f8051602061571d83398151915280545f9190825b818110156123f157846001600160a01b0316835f0182815481106123c5576123c561525a565b5f918252602090912001546001600160a01b0316036123e957506001949350505050565b60010161239f565b505f949350505050565b5f807f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e0090505f81546124379190600160a01b900460ff16615490565b91505090565b5f610cad613741565b61244e6137b4565b5f8051602061573d833981519152805460ff191681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a150565b5f8051602061571d83398151915280545f9190825b81811015610b4d5761255284845f0183815481106124da576124da61525a565b5f9182526020909120015460405163402d267d60e01b81523060048201526001600160a01b039091169063402d267d906024015b602060405180830381865afa158015612529573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061254d919061526e565b6137e3565b93506001016124ba565b5f612565613804565b61258c575f196125736125a2565b146125855761258061388a565b610c0a565b5f19610c0a565b5f92915050565b5f828218828410028218610d35565b5f5f8051602061563d8339815191525b60010154905090565b5f5f805160206156fd8339815191526125b2565b5f610d356125db610a2c565b6125e6906001615299565b6125f15f600a615463565b5f8051602061569d83398151915254611eeb9190615299565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061267a57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661266e6138a3565b6001600160a01b031614155b15610fcc5760405163703e46dd60e11b815260040160405180910390fd5b5f61106881611ef4565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156126fc575060408051601f3d908101601f191682019092526126f99181019061526e565b60015b61272457604051634c9c8ce360e01b81526001600160a01b03831660048201526024016110fc565b5f805160206156dd833981519152811461275457604051632a87526960e21b8152600481018290526024016110fc565b61275e83836138b7565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610fcc5760405163703e46dd60e11b815260040160405180910390fd5b6127b4613804565b15610fcc5760405163d93c066560e01b815260040160405180910390fd5b5f5f8051602061571d8339815191526125b2565b6040516370a0823160e01b81523060048201525f906001600160a01b038516906307a2d13a9082906370a0823190602401602060405180830381865afa158015612832573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612856919061526e565b6040518263ffffffff1660e01b815260040161287491815260200190565b602060405180830381865afa15801561288f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b3919061526e565b6040516370a0823160e01b81523060048201526001600160a01b038716906307a2d13a9082906370a0823190602401602060405180830381865afa1580156128fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612921919061526e565b6040518263ffffffff1660e01b815260040161293f91815260200190565b602060405180830381865afa15801561295a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061297e919061526e565b6129889190615299565b90505f612993610f60565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156129d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129fb919061526e565b90508315612a7a57604051632d182be560e21b815260048101859052306024820181905260448201526001600160a01b0387169063b460af94906064016020604051808303815f875af1158015612a54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a78919061526e565b505b5f612a83610f60565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612ac7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612aeb919061526e565b90505f612af883836152ff565b90508015612b8d57612b1d8782612b0d610f60565b6001600160a01b0316919061390c565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03881690636e553f65906044016020604051808303815f875af1158015612b67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8b919061526e565b505b6040516370a0823160e01b81523060048201525f906001600160a01b038916906307a2d13a9082906370a0823190602401602060405180830381865afa158015612bd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bfd919061526e565b6040518263ffffffff1660e01b8152600401612c1b91815260200190565b602060405180830381865afa158015612c36573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c5a919061526e565b6040516370a0823160e01b81523060048201526001600160a01b038b16906307a2d13a9082906370a0823190602401602060405180830381865afa158015612ca4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cc8919061526e565b6040518263ffffffff1660e01b8152600401612ce691815260200190565b602060405180830381865afa158015612d01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d25919061526e565b612d2f9190615299565b90505f612d458789670de0b6b3a76400006139c9565b9050612d518282615299565b861115612d90576040516304e32bab60e41b8152600481018790526024810183905260448101829052606481018990526084810188905260a4016110fc565b886001600160a01b03168a6001600160a01b03167f81a143d873eb13ec2d7efc6f49d2ce680716e4d295f3340c68e601c317fb1595858a604051612dde929190918252602082015260400190565b60405180910390a350505050505050505050565b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd01545f805160206156fd833981519152905f03612e2c5750565b5f612e35613a79565b82549091508082111561275e575f612e4d82846152ff565b90505f612e7782612e695f8051602061569d8339815191525490565b670de0b6b3a76400006139c9565b90505f612e91828760010154670de0b6b3a76400006139c9565b90505f612edf82612ea383600a615463565b5f8051602061569d83398151915254612ebc9190615299565b84612ec5610a2c565b612ed0906001615299565b612eda91906152ff565b6139c9565b90508015612f5a576002870154612eff906001600160a01b031682613acc565b612f0f612f0a613a79565b613b00565b600287015460408051838152602081018590526001600160a01b03909216917f74e325cf88102b892b2796a1db2f772360b0b33fbdea0c4e3ed24fa9755fe0c5910160405180910390a25b50505050505050565b5f612f6c6127ac565b612f768383613b49565b9050610c3d61222b565b5f807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006111f0565b612fb0613b95565b5f8051602061573d833981519152805460ff191660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833612487565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f805160206156bd83398151915291610b76906152ac565b60605f5f805160206156bd833981519152610b65565b5f61304d6127ac565b612f768383613bac565b61305f61371c565b610c8e81613bf8565b61307061371c565b6110688282613c7b565b61308261371c565b610c8e81604051806040016040528060018152602001603160f81b815250613ccb565b6130ad61371c565b610fcc613d2a565b610fcc61371c565b305f6130c882610fce565b9050808311156130f157818382604051633c8097d960e11b81526004016110fc939291906154a9565b5f6130fb84611b53565b905061310985848684613d32565b5050505050565b5f33611e938185856136bf565b5f8051602061571d8339815191525f5b815481101561275e57826001600160a01b0316825f0182815481106131545761315461525a565b5f918252602090912001546001600160a01b03160361326657805b825461317d906001906152ff565b8110156131fb5782613190826001615299565b815481106131a0576131a061525a565b5f9182526020909120015483546001600160a01b03909116908490839081106131cb576131cb61525a565b5f91825260209091200180546001600160a01b0319166001600160a01b039290921691909117905560010161316f565b50815482908061320d5761320d6154ca565b5f8281526020812082015f1990810180546001600160a01b03191690559091019091556040516001600160a01b038516917f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea491a2505050565b60010161312d565b60605f80846001600160a01b03168460405161328a91906154de565b5f60405180830381855af49150503d805f81146132c2576040519150601f19603f3d011682016040523d82523d5f602084013e6132c7565b606091505b50915091506132d7858383613f29565b95945050505050565b5f6132e96127ac565b6132f4848484613f85565b9050610d3561222b565b5f6133076127ac565b6132f4848484613fd2565b5f61331b613804565b61258c575f196133296125a2565b146125855761258061333961388a565b5f611eb0565b5f8051602061571d83398151915280545f9190825b81811015610b4d576133ac84845f0183815481106133745761337461525a565b5f9182526020909120015460405163ce96cb7760e01b81523060048201526001600160a01b039091169063ce96cb779060240161250e565b9350600101613354565b5f6133bf613804565b61258c576125808261401f565b5f610c0a6133d861243d565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f8061340888888888614032565b92509250925061341882826140fa565b50909695505050505050565b61275e83838360016141b2565b5f61343a613804565b61258c5761258082614295565b60605f8051602061571d8339815191528054604080516020808402820181019092528281529291908301828280156134a657602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311613488575b5050505050905090565b6706f05b59d3b200008111156134ea57604051639f267a1160e01b8152600481018290526706f05b59d3b2000060248201526044016110fc565b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd01545f805160206156fd83398151915280549091905f613528613a79565b90508215801561353757505f85115b801561354257508082105b156135505761355081613b00565b60018401859055604051859084907fec752fd140b0567ddecc3a75eacd13201c091536e7e0731dcf143f5ee461bff7905f90a35050505050565b6001600160a01b0381166135b15760405163e99d5ac560e01b815260040160405180910390fd5b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd0280546001600160a01b031981166001600160a01b038481169182179093556040515f805160206156fd833981519152939092169182907f15d80a013f22151bc7246e3bc132e12828cde19de98870475e3fa70840152721905f90a3505050565b5f61365f61363f8361429f565b801561365a57505f8480613655576136556154e9565b868809115b151590565b61366a8686866139c9565b6132d79190615299565b5f61367f8484611ab5565b90505f198110156111be57818110156136b157828183604051637dc7a0d960e11b81526004016110fc939291906154a9565b6111be84848484035f6141b2565b6001600160a01b0383166136e857604051634b637e8f60e11b81525f60048201526024016110fc565b6001600160a01b0382166137115760405163ec442f0560e01b81525f60048201526024016110fc565b61275e8383836142cb565b6137246143f1565b610fcc57604051631afcd79f60e31b815260040160405180910390fd5b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61376b61440a565b613773614472565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f8051602061573d8339815191525460ff16610fcc57604051638dfc202b60e01b815260040160405180910390fd5b5f805f6137f085856144b4565b90925090505f1980821883151502186132d7565b5f61381d5f8051602061573d8339815191525460ff1690565b80610cad575061382b611afe565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613866573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cad9190615471565b5f610cad6138966125a2565b61389e610a2c565b6144cc565b5f5f805160206156dd833981519152611b0e565b6138c0826144d8565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156139045761275e828261326e565b61106861453b565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261395d848261455a565b6111be576040516001600160a01b0384811660248301525f60448301526139bf91869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506145a3565b6111be84826145a3565b5f805f6139d6868661460f565b91509150815f036139fa578381816139f0576139f06154e9565b0492505050610d35565b818411613a1157613a11600385150260111861462b565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f80613a83610a2c565b90505f613a9b5f8051602061569d8339815191525490565b90505f8111613ab257670de0b6b3a7640000613ac5565b613ac582670de0b6b3a7640000836139c9565b9250505090565b6001600160a01b038216613af55760405163ec442f0560e01b81525f60048201526024016110fc565b6110685f83836142cb565b5f805160206156fd833981519152805482825560408051828152602081018590527f03f8f938dbe4475565f0cf1c3dcf09728208c2c6065e1f717102058c51e94d06910161237d565b5f80613b5483610fce565b905080841115613b7d57828482604051633c8097d960e11b81526004016110fc939291906154a9565b5f613b8785611b53565b90506118a533858784613d32565b5f8051602061573d8339815191525460ff166127b4565b5f80613bb78361186e565b905080841115613be05782848260405163284ff66760e01b81526004016110fc939291906154a9565b5f613bea8561182a565b90506118a533858388613d32565b613c0061371c565b7f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e005f80613c2c8461463c565b9150915081613c3c576012613c3e565b805b83546001600160a81b031916600160a01b60ff92909216919091026001600160a01b031916176001600160a01b0394909416939093179091555050565b613c8361371c565b5f8051602061567d8339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03613cbc8482615541565b50600481016111be8382615541565b613cd361371c565b5f805160206156bd8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102613d0c8482615541565b5060038101613d1b8382615541565b505f8082556001909101555050565b611e9d61371c565b613d3a6143f1565b15613d425750805b613d4e84848484614712565b5f8051602061571d83398151915280548391905f5b81811015613ef9578315613ef9575f835f018281548110613d8657613d8661525a565b5f91825260208220015460405163402d267d60e01b81523060048201526001600160a01b039091169250829063402d267d90602401602060405180830381865afa158015613dd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dfa919061526e565b90505f613e078783612593565b90508015613eeb57613e1c8382612b0d610f60565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03841690636e553f65906044016020604051808303815f875af1925050508015613e84575060408051601f3d908101601f19168201909252613e819181019061526e565b60015b613edd57826001600160a01b03167fb25cefcd019c9ac00557fa1cae5f952455cd9ad7b058f91d66e1bbe895e31ece82604051613ec391815260200190565b60405180910390a2613ed8835f612b0d610f60565b613eeb565b50613ee881886152ff565b96505b505050806001019050613d63565b508215612f5a5760405162aea97b60e61b81526004810186905260248101859052604481018490526064016110fc565b606082613f3e57613f3982614749565b610d35565b8151158015613f5557506001600160a01b0384163b155b15613f7e57604051639996b31560e01b81526001600160a01b03851660048201526024016110fc565b5080610d35565b5f80613f90836118bf565b905080851115613fb957828582604051633fa733bb60e21b81526004016110fc939291906154a9565b5f613fc386610c43565b90506132d73386868985614772565b5f80613fdd83611a6c565b90508085111561400657828582604051632e52afbb60e21b81526004016110fc939291906154a9565b5f61401086611042565b90506132d7338686848a614772565b5f610c0a61402c836111df565b5f6125cf565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561406b57505f915060039050826140f0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156140bc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166140e757505f9250600191508290506140f0565b92505f91508190505b9450945094915050565b5f82600381111561410d5761410d6155fb565b03614116575050565b600182600381111561412a5761412a6155fb565b036141485760405163f645eedf60e01b815260040160405180910390fd5b600282600381111561415c5761415c6155fb565b0361417d5760405163fce698f760e01b8152600481018290526024016110fc565b6003826003811115614191576141916155fb565b03611068576040516335e2f38360e21b8152600481018290526024016110fc565b5f8051602061567d8339815191526001600160a01b0385166141e95760405163e602df0560e01b81525f60048201526024016110fc565b6001600160a01b03841661421257604051634a1406b160e11b81525f60048201526024016110fc565b6001600160a01b038086165f9081526001830160209081526040808320938816835292905220839055811561310957836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161428691815260200190565b60405180910390a35050505050565b5f610c0a826111df565b5f60028260038111156142b4576142b46155fb565b6142be919061560f565b60ff166001149050919050565b5f8051602061567d8339815191526001600160a01b0384166143055781816002015f8282546142fa9190615299565b909155506143629050565b6001600160a01b0384165f90815260208290526040902054828110156143445784818460405163391434e360e21b81526004016110fc939291906154a9565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b03831661438057600281018054839003905561439e565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516143e391815260200190565b60405180910390a350505050565b5f6143fa6122a6565b54600160401b900460ff16919050565b5f5f805160206156bd83398151915281614422612ff0565b80519091501561443a57805160209091012092915050565b81548015614449579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f805160206156bd8339815191528161448a61302e565b8051909150156144a257805160209091012092915050565b60018201548015614449579392505050565b80820182811015905f90825b81029150509250929050565b5f806132d78484614952565b806001600160a01b03163b5f0361450d57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016110fc565b5f805160206156dd83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b3415610fcc5760405163b398979f60e01b815260040160405180910390fd5b5f805f8060205f8651602088015f8a5af192503d91505f5190508280156145995750811561458b5780600114614599565b5f866001600160a01b03163b115b9695505050505050565b5f8060205f8451602086015f885af1806145c2576040513d5f823e3d81fd5b50505f513d915081156145d95780600114156145e6565b6001600160a01b0384163b155b156111be57604051635274afe760e01b81526001600160a01b03851660048201526024016110fc565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290515f918291829182916001600160a01b03871691614682916154de565b5f60405180830381855afa9150503d805f81146146ba576040519150601f19603f3d011682016040523d82523d5f602084013e6146bf565b606091505b50915091508180156146d357506020815110155b15614706575f818060200190518101906146ed919061526e565b905060ff8111614704576001969095509350505050565b505b505f9485945092505050565b5f8211801561471f575080155b1561473d57604051630e5a744960e41b815260040160405180910390fd5b6111be84848484614962565b8051156147595780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f8051602061571d83398151915280548391905f5b8181101561490a57831561490a575f835f0182815481106147aa576147aa61525a565b5f91825260208220015460405163ce96cb7760e01b81523060048201526001600160a01b039091169250829063ce96cb7790602401602060405180830381865afa1580156147fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061481e919061526e565b90505f61482b8783612593565b905080156148fc57604051632d182be560e21b815260048101829052306024820181905260448201526001600160a01b0384169063b460af94906064016020604051808303815f875af19250505080156148a2575060408051601f3d908101601f1916820190925261489f9181019061526e565b60015b6148ee57826001600160a01b03167fa2269912b47133fae1d7f448c9284ea248951ac29b8c7c41d301f8721a38d10d826040516148e191815260200190565b60405180910390a26148fc565b506148f981886152ff565b96505b505050806001019050614787565b50821561493b5760405163e971065160e01b81526004810186905260248101859052604481018490526064016110fc565b61494888888888886149cd565b5050505050505050565b80820382811115905f90826144c0565b61497561496d610f60565b853085614a05565b61497f8382613acc565b826001600160a01b0316846001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d784846040516143e3929190918252602082015260400190565b5f811180156149da575081155b156149f857604051630e5a744960e41b815260040160405180910390fd5b6131098585858585614a3e565b6040516001600160a01b0384811660248301528381166044830152606482018390526111be9186918216906323b872dd9060840161398d565b826001600160a01b0316856001600160a01b031614614a6257614a62838683613674565b614a6c8382614ae5565b614a7e614a77610f60565b8584614b19565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8585604051614ad6929190918252602082015260400190565b60405180910390a45050505050565b6001600160a01b038216614b0e57604051634b637e8f60e11b81525f60048201526024016110fc565b611068825f836142cb565b6040516001600160a01b0383811660248301526044820183905261275e91859182169063a9059cbb9060640161398d565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610d356020830184614b4a565b5f60208284031215614b9a575f80fd5b5035919050565b6001600160a01b0381168114610c8e575f80fd5b8035610c0d81614ba1565b5f8060408385031215614bd1575f80fd5b8235614bdc81614ba1565b946020939093013593505050565b5f60208284031215614bfa575f80fd5b8135610d3581614ba1565b5f805f60608486031215614c17575f80fd5b8335614c2281614ba1565b92506020840135614c3281614ba1565b929592945050506040919091013590565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614c7f57614c7f614c43565b604052919050565b5f806001600160401b03841115614ca057614ca0614c43565b50601f8301601f1916602001614cb581614c57565b915050828152838383011115614cc9575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614cee575f80fd5b610d3583833560208501614c87565b5f82601f830112614d0c575f80fd5b81356001600160401b03811115614d2557614d25614c43565b8060051b614d3560208201614c57565b91825260208185018101929081019086841115614d50575f80fd5b6020860192505b83831015614599578235614d6a81614ba1565b825260209283019290910190614d57565b5f805f805f805f60e0888a031215614d91575f80fd5b8735614d9c81614ba1565b9650614daa60208901614bb5565b955060408801356001600160401b03811115614dc4575f80fd5b614dd08a828b01614cdf565b95505060608801356001600160401b03811115614deb575f80fd5b614df78a828b01614cdf565b945050614e0660808901614bb5565b925060a0880135915060c08801356001600160401b03811115614e27575f80fd5b614e338a828b01614cfd565b91505092959891949750929550565b5f8060408385031215614e53575f80fd5b8235614e5e81614ba1565b915060208301356001600160401b03811115614e78575f80fd5b8301601f81018513614e88575f80fd5b614e9785823560208401614c87565b9150509250929050565b5f805f8060808587031215614eb4575f80fd5b8435614ebf81614ba1565b93506020850135614ecf81614ba1565b93969395505050506040820135916060013590565b5f8060408385031215614ef5575f80fd5b823591506020830135614f0781614ba1565b809150509250929050565b60ff60f81b8816815260e060208201525f614f3060e0830189614b4a565b8281036040840152614f428189614b4a565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b81811015614f97578351835260209384019390920191600101614f79565b50909b9a5050505050505050505050565b5f805f805f8060c08789031215614fbd575f80fd5b8635614fc881614ba1565b95506020870135614fd881614ba1565b945060408701356001600160401b03811115614ff2575f80fd5b614ffe89828a01614cdf565b94505060608701356001600160401b03811115615019575f80fd5b61502589828a01614cdf565b935050608087013561503681614ba1565b9598949750929591949360a090920135925050565b5f8083601f84011261505b575f80fd5b5081356001600160401b03811115615071575f80fd5b6020830191508360208260051b850101111561508b575f80fd5b9250929050565b5f80602083850312156150a3575f80fd5b82356001600160401b038111156150b8575f80fd5b6150c48582860161504b565b90969095509350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561512757603f19878603018452615112858351614b4a565b945060209384019391909101906001016150f6565b50929695505050505050565b5f805f60608486031215615145575f80fd5b83359250602084013561515781614ba1565b9150604084013561516781614ba1565b809150509250925092565b5f805f805f805f60e0888a031215615188575f80fd5b873561519381614ba1565b965060208801356151a381614ba1565b95506040880135945060608801359350608088013560ff811681146151c6575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b602080825282518282018190525f918401906040840190835b818110156152235783516001600160a01b03168352602093840193909201916001016151fc565b509095945050505050565b5f806040838503121561523f575f80fd5b823561524a81614ba1565b91506020830135614f0781614ba1565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561527e575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c3d57610c3d615285565b600181811c908216806152c057607f821691505b6020821081036152de57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f602082840312156152f4575f80fd5b8151610d3581614ba1565b81810381811115610c3d57610c3d615285565b5f808335601e19843603018112615327575f80fd5b8301803591506001600160401b03821115615340575f80fd5b60200191503681900382131561508b575f80fd5b5f81518060208401855e5f93019283525090919050565b828482375f8382015f81526145998185615354565b6001815b60018411156153bb5780850481111561539f5761539f615285565b60018416156153ad57908102905b60019390931c928002615384565b935093915050565b5f826153d157506001610c3d565b816153dd57505f610c3d565b81600181146153f357600281146153fd57615419565b6001915050610c3d565b60ff84111561540e5761540e615285565b50506001821b610c3d565b5060208310610133831016604e8410600b841016171561543c575081810a610c3d565b6154485f198484615380565b805f190482111561545b5761545b615285565b029392505050565b5f610d3560ff8416836153c3565b5f60208284031215615481575f80fd5b81518015158114610d35575f80fd5b60ff8181168382160190811115610c3d57610c3d615285565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52603160045260245ffd5b5f610d358284615354565b634e487b7160e01b5f52601260045260245ffd5b601f82111561275e57805f5260205f20601f840160051c810160208510156155225750805b601f840160051c820191505b81811015613109575f815560010161552e565b81516001600160401b0381111561555a5761555a614c43565b61556e8161556884546152ac565b846154fd565b6020601f8211600181146155a0575f83156155895750848201515b5f19600385901b1c1916600184901b178455613109565b5f84815260208120601f198516915b828110156155cf57878501518255602094850194600190920191016155af565b50848210156155ec57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52602160045260245ffd5b5f60ff83168061562d57634e487b7160e01b5f52601260045260245ffd5b8060ff8416069150509291505056fe83cbba01667a5ddf3820f0a2c4220dbc355a1a788c7094daad71b73a418b0d00d1473398bb66596de5d1ea1fc8e303ff2ac23265adc9144b1b52065dc4f0934b52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd00851713d8b7886cdb5682ccb4d2dba1bf8cae30c699ce588016da31dab5d7f100cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a8aa94f2e8b958789c84ed7b76204f9060cbb7be85cf23ad0561b67bcf44e23664736f6c634300081a0033","sourceMap":"1100:24863:83:-:0;;;1171:4:30;1128:48;;3465:53:83;;;;;;;;;-1:-1:-1;2973:22:87;:20;:22::i;:::-;3489::83;:20;:22::i;:::-;1100:24863;;7709:422:29;3147:66;7898:15;;;;;;;7894:76;;;7936:23;;-1:-1:-1;;;7936:23:29;;;;;;;;;;;7894:76;7983:14;;-1:-1:-1;;;;;7983:14:29;;;:34;7979:146;;8033:33;;-1:-1:-1;;;;;;8033:33:29;-1:-1:-1;;;;;8033:33:29;;;;;8085:29;;158:50:91;;;8085:29:29;;146:2:91;131:18;8085:29:29;;;;;;;7979:146;7758:373;7709:422::o;14:200:91:-;1100:24863:83;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405260043610610366575f3560e01c80636e553f65116101c8578063b460af94116100fd578063d905777e1161009d578063df652d411161006d578063df652d41146109b0578063e74b981b146109cf578063ef8b30f7146109ee578063f34e121714610a0d575f80fd5b8063d905777e1461093d578063d9f9027f1461095c578063dd62ed3e1461097d578063de9375f21461099c575f80fd5b8063c6e6f592116100d8578063c6e6f592146108c1578063ce96cb77146108e0578063d505accf146108ff578063d574ea3d1461091e575f80fd5b8063b460af9414610864578063ba08765214610883578063c63d75b6146108a2575f80fd5b806395d89b4111610168578063ab3ffa1a11610143578063ab3ffa1a146107ca578063ac9650d8146107e9578063ad3cb1cc14610815578063b3d7f6b914610845575f80fd5b806395d89b4114610778578063a01e3f741461078c578063a9059cbb146107ab575f80fd5b80638456cb59116101a35780638456cb591461070a57806384b0196e1461071e578063907d54051461074557806394bf804d14610759575f80fd5b80636e553f65146106ad57806370a08231146106cc5780637ecebe00146106eb575f80fd5b8063317b72241161029e57806348f5b9801161023e57806352d1902d1161021957806352d1902d1461062a57806354fd4d501461063e5780635c975abb1461066b5780636e49db1c1461068e575f80fd5b806348f5b980146105e45780634cdad506146105f85780634f1ef28614610617575f80fd5b80633f4ba83a116102795780633f4ba83a14610589578063402d267d1461059d57806345f663dd146105bc57806346904840146105d0575f80fd5b8063317b72241461052a5780633644e5151461054957806338d52e0f1461055d575f80fd5b80631e8410da116103095780632489f7f7116102e45780632489f7f7146104b257806329d7b732146104c65780632e8ebaae146104e5578063313ce56714610504575f80fd5b80631e8410da14610460578063223e54791461047457806323b872dd14610493575f80fd5b8063095ea7b311610344578063095ea7b3146103d15780630a28a47714610400578063114fbced1461041f57806318160ddd14610440575f80fd5b806301e1d1141461036a57806306fdde031461039157806307a2d13a146103b2575b5f80fd5b348015610375575f80fd5b5061037e610a2c565b6040519081526020015b60405180910390f35b34801561039c575f80fd5b506103a5610b53565b6040516103889190614b78565b3480156103bd575f80fd5b5061037e6103cc366004614b8a565b610bf8565b3480156103dc575f80fd5b506103f06103eb366004614bc0565b610c12565b6040519015158152602001610388565b34801561040b575f80fd5b5061037e61041a366004614b8a565b610c43565b34801561042a575f80fd5b5061043e610439366004614b8a565b610c4f565b005b34801561044b575f80fd5b505f8051602061569d8339815191525461037e565b34801561046b575f80fd5b5061037e610c91565b34801561047f575f80fd5b5061043e61048e366004614bea565b610cb2565b34801561049e575f80fd5b506103f06104ad366004614c05565b610d09565b3480156104bd575f80fd5b5061037e610d3c565b3480156104d1575f80fd5b5061043e6104e0366004614d7b565b610d53565b3480156104f0575f80fd5b506103f06104ff366004614bea565b610f14565b34801561050f575f80fd5b50610518610f26565b60405160ff9091168152602001610388565b348015610535575f80fd5b5061043e610544366004614b8a565b610f2f565b348015610554575f80fd5b5061037e610f57565b348015610568575f80fd5b50610571610f60565b6040516001600160a01b039091168152602001610388565b348015610594575f80fd5b5061043e610f8e565b3480156105a8575f80fd5b5061037e6105b7366004614bea565b610fce565b3480156105c7575f80fd5b5061037e610fe8565b3480156105db575f80fd5b50610571610ff9565b3480156105ef575f80fd5b5061037e611031565b348015610603575f80fd5b5061037e610612366004614b8a565b611042565b61043e610625366004614e42565b61104d565b348015610635575f80fd5b5061037e61106c565b348015610649575f80fd5b506040805180820190915260058152640302e312e360dc1b60208201526103a5565b348015610676575f80fd5b505f8051602061573d8339815191525460ff166103f0565b348015610699575f80fd5b5061043e6106a8366004614ea1565b611087565b3480156106b8575f80fd5b5061037e6106c7366004614ee4565b6111c4565b3480156106d7575f80fd5b5061037e6106e6366004614bea565b6111df565b3480156106f6575f80fd5b5061037e610705366004614bea565b61120f565b348015610715575f80fd5b5061043e611219565b348015610729575f80fd5b50610732611253565b6040516103889796959493929190614f12565b348015610750575f80fd5b5061037e6112fc565b348015610764575f80fd5b5061037e610773366004614ee4565b61130d565b348015610783575f80fd5b506103a5611328565b348015610797575f80fd5b5061043e6107a6366004614fa8565b611366565b3480156107b6575f80fd5b506103f06107c5366004614bc0565b611542565b3480156107d5575f80fd5b5061043e6107e4366004614ea1565b611555565b3480156107f4575f80fd5b50610808610803366004615092565b611745565b60405161038891906150d0565b348015610820575f80fd5b506103a5604051806040016040528060058152602001640352e302e360dc1b81525081565b348015610850575f80fd5b5061037e61085f366004614b8a565b61182a565b34801561086f575f80fd5b5061037e61087e366004615133565b611836565b34801561088e575f80fd5b5061037e61089d366004615133565b611852565b3480156108ad575f80fd5b5061037e6108bc366004614bea565b61186e565b3480156108cc575f80fd5b5061037e6108db366004614b8a565b6118ad565b3480156108eb575f80fd5b5061037e6108fa366004614bea565b6118bf565b34801561090a575f80fd5b5061043e610919366004615172565b6118d4565b348015610929575f80fd5b50610571610938366004614b8a565b611a29565b348015610948575f80fd5b5061037e610957366004614bea565b611a6c565b348015610967575f80fd5b50610970611aa3565b60405161038891906151e3565b348015610988575f80fd5b5061037e61099736600461522e565b611ab5565b3480156109a7575f80fd5b50610571611afe565b3480156109bb575f80fd5b5061043e6109ca366004614b8a565b611b1d565b3480156109da575f80fd5b5061043e6109e9366004614bea565b611b38565b3480156109f9575f80fd5b5061037e610a08366004614b8a565b611b53565b348015610a18575f80fd5b5061043e610a27366004615092565b611b5e565b5f8051602061571d83398151915280545f9190825b81811015610b4d575f835f018281548110610a5e57610a5e61525a565b5f918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116915081906307a2d13a9082906370a0823190602401602060405180830381865afa158015610ab7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610adb919061526e565b6040518263ffffffff1660e01b8152600401610af991815260200190565b602060405180830381865afa158015610b14573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b38919061526e565b610b429086615299565b945050600101610a41565b50505090565b60605f5f8051602061567d8339815191525b9050806003018054610b76906152ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba2906152ac565b8015610bed5780601f10610bc457610100808354040283529160200191610bed565b820191905f5260205f20905b815481529060010190602001808311610bd057829003601f168201915b505050505091505090565b5f610c01611e20565b610c0a82611042565b90505b919050565b5f610c1b611e4f565b610c258383611e86565b9050610c3d60015f8051602061575d83398151915255565b92915050565b5f610c0a826001611eb0565b610c57611e4f565b5f8051602061565d833981519152610c6e81611ef4565b610c7782611f9e565b50610c8e60015f8051602061575d83398151915255565b50565b5f610c9a611e20565b505f805160206156fd8339815191525490565b905090565b610cba611e4f565b5f8051602061565d833981519152610cd181611ef4565b610cea82610cdd610f60565b610ce5611afe565b612006565b50610cf361222b565b610c8e60015f8051602061575d83398151915255565b5f610d12611e4f565b610d1d848484612283565b9050610d3560015f8051602061575d83398151915255565b9392505050565b5f610d45611e20565b610d4d611aa3565b51905090565b5f610d5c6122a6565b805490915060ff600160401b82041615906001600160401b03165f81158015610d825750825b90505f826001600160401b03166001148015610d9d5750303b155b905081158015610dab575080155b15610dc95760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610df357845460ff60401b1916600160401b1785555b604051632404341f60e21b81525f600482018190526024820152610e6a906001600160a01b038e1690639010d07c90604401602060405180830381865afa158015610e40573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e6491906152e4565b5f6122ce565b5f5b8651811015610ea157610e99878281518110610e8a57610e8a61525a565b60200260200101518d8f612006565b600101610e6c565b50610eb2662386f26fc100006122e8565b610ec08c8c8c8c8c8c611366565b8315610f0657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b5f610f1d611e20565b610c0a8261238a565b5f610cad6123fb565b610f37611e4f565b5f8051602061565d833981519152610f4e81611ef4565b610c77826122e8565b5f610cad61243d565b7f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e00546001600160a01b031690565b610f96611e4f565b5f8051602061565d833981519152610fad81611ef4565b610fb5612446565b50610fcc60015f8051602061575d83398151915255565b565b5f610c0a610fda6124a5565b610fe38461255c565b612593565b5f610ff1611e20565b610cad6125a2565b5f611002611e20565b507f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd02546001600160a01b031690565b5f61103a611e20565b610cad6125bb565b5f610c0a825f6125cf565b61105561260a565b61105e82612698565b61106882826126a2565b5050565b5f611075612763565b505f805160206156dd83398151915290565b61108f611e4f565b6110976127ac565b7f17a8e30262c1f919c33056d877a3c22b95c2f5e4dac44683c1c2323cd79fbdb06110c181611ef4565b6110cd82610fe36127d2565b91506110d88561238a565b61110557604051633ae252cd60e21b81526001600160a01b03861660048201526024015b60405180910390fd5b61110e8461238a565b61113657604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b836001600160a01b0316856001600160a01b03160361117357604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b825f0361119357604051630e5a744960e41b815260040160405180910390fd5b61119f858585856127e6565b506111a861222b565b6111be60015f8051602061575d83398151915255565b50505050565b5f6111cd611e4f565b6111d5612df2565b610c258383612f63565b5f805f8051602061567d8339815191525b6001600160a01b039093165f9081526020939093525050604090205490565b5f610c0a82612f80565b611221611e4f565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161124b81611ef4565b610fb5612fa8565b5f60608082808083815f805160206156bd833981519152805490915015801561127e57506001810154155b6112c25760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b60448201526064016110fc565b6112ca612ff0565b6112d261302e565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b5f611305611e20565b610cad6127d2565b5f611316611e4f565b61131e612df2565b610c258383613044565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f8051602061567d83398151915291610b76906152ac565b5f61136f6122a6565b805490915060ff600160401b82041615906001600160401b03165f811580156113955750825b90505f826001600160401b031660011480156113b05750303b155b9050811580156113be575080155b156113dc5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561140657845460ff60401b1916600160401b1785555b61140f8a613057565b6114198989613068565b6114228961307a565b61142a6130a5565b6114326130b5565b61143a6130b5565b6114426130b5565b6001600160a01b038b166114695760405163e99d5ac560e01b815260040160405180910390fd5b855f0361148957604051630e5a744960e41b815260040160405180910390fd5b5f8051602061563d83398151915280546001600160a01b0319166001600160a01b038d1690811782556040517ff8c4af92684d0fd7f652724eed9174e4842c3a2a49b2f0809fd721f6dd8b172d905f90a26114e45f19611f9e565b6114ee88886130bd565b50831561153557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050505050565b5f61154b611e4f565b610c258383613110565b61155d611e4f565b7f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a504161158781611ef4565b6115908561238a565b6115b857604051633ae252cd60e21b81526001600160a01b03861660048201526024016110fc565b6115c18461238a565b6115e957604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b836001600160a01b0316856001600160a01b03160361162657604051633ae252cd60e21b81526001600160a01b03851660048201526024016110fc565b8215611715576040516370a0823160e01b81523060048201525f906001600160a01b038716906307a2d13a9082906370a0823190602401602060405180830381865afa158015611678573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061169c919061526e565b6040518263ffffffff1660e01b81526004016116ba91815260200190565b602060405180830381865afa1580156116d5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f9919061526e565b90506117058482612593565b9350611713868686866127e6565b505b61171e8561311d565b611726610a2c565b5f0361119f57604051630e5a744960e41b815260040160405180910390fd5b604080515f815260208101909152606090826001600160401b0381111561176e5761176e614c43565b6040519080825280602002602001820160405280156117a157816020015b606081526020019060019003908161178c5790505b5091505f5b83811015611822576117fd308686848181106117c4576117c461525a565b90506020028101906117d69190615312565b856040516020016117e99392919061536b565b60405160208183030381529060405261326e565b83828151811061180f5761180f61525a565b60209081029190910101526001016117a6565b505092915050565b5f610c0a8260016125cf565b5f61183f611e4f565b611847612df2565b610d1d8484846132e0565b5f61185b611e4f565b611863612df2565b610d1d8484846132fe565b5f8061187983610fce565b90505f5f1982146118935761188e825f611eb0565b611896565b5f195b90506118a581610fe386613312565b949350505050565b5f6118b6611e20565b610c0a82611b53565b5f610c0a6118cb61333f565b610fe3846133b6565b834211156118f85760405163313c898160e11b8152600481018590526024016110fc565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886119628c6001600160a01b03165f9081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f6119bc826133cc565b90505f6119cb828787876133f8565b9050896001600160a01b0316816001600160a01b031614611a12576040516325c0072360e11b81526001600160a01b0380831660048301528b1660248201526044016110fc565b611a1d8a8a8a613424565b50505050505050505050565b5f611a32611e20565b5f8051602061571d833981519152805483908110611a5257611a5261525a565b5f918252602090912001546001600160a01b031692915050565b5f80611a77836118bf565b90505f5f198214611a9157611a8c825f611eb0565b611a94565b5f195b90506118a581610fe386613431565b6060611aad611e20565b610cad613447565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f5f8051602061563d8339815191525b546001600160a01b0316919050565b611b25611e4f565b5f611b2f81611ef4565b610c77826134b0565b611b40611e4f565b5f611b4a81611ef4565b610c778261358a565b5f610c0a825f611eb0565b611b66611e4f565b611b6e6127ac565b7f17a8e30262c1f919c33056d877a3c22b95c2f5e4dac44683c1c2323cd79fbdb0611b9881611ef4565b5f8051602061571d8339815191528054838114611bd257604051631f4bb7c160e31b815260048101829052602481018590526044016110fc565b5f5b81811015611cfa57611c0b868683818110611bf157611bf161525a565b9050602002016020810190611c069190614bea565b61238a565b611c5b57858582818110611c2157611c2161525a565b9050602002016020810190611c369190614bea565b604051633ae252cd60e21b81526001600160a01b0390911660048201526024016110fc565b5f611c67826001615299565b90505b82811015611cf157868682818110611c8457611c8461525a565b9050602002016020810190611c999190614bea565b6001600160a01b0316878784818110611cb457611cb461525a565b9050602002016020810190611cc99190614bea565b6001600160a01b031603611ce957868683818110611c2157611c2161525a565b600101611c6a565b50600101611bd4565b505f5b81811015611e06575f835f018281548110611d1a57611d1a61525a565b5f918252602090912001546001600160a01b03169050868683818110611d4257611d4261525a565b9050602002016020810190611d579190614bea565b845f018381548110611d6b57611d6b61525a565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555081878784818110611da957611da961525a565b9050602002016020810190611dbe9190614bea565b6001600160a01b0316826001600160a01b03167f11d8593881095d510e51d5617699f2674b01890b9f5816abfe33c40f4932882460405160405180910390a450600101611cfd565b5050505061106860015f8051602061575d83398151915255565b5f8051602061575d83398151915254600203610fcc57604051633ee5aeb560e01b815260040160405180910390fd5b5f8051602061575d833981519152805460011901611e8057604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f33611e93818585613424565b5060019392505050565b60015f8051602061575d83398151915255565b5f610d35611ebf82600a615463565b5f8051602061569d83398151915254611ed89190615299565b611ee0610a2c565b611eeb906001615299565b85919085613632565b611efc611afe565b6001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611f54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f789190615471565b610c8e5760405163e2517d3f60e01b8152336004820152602481018290526044016110fc565b7f83cbba01667a5ddf3820f0a2c4220dbc355a1a788c7094daad71b73a418b0d018054908290556040515f8051602061563d8339815191529190839082907ffff0e599b3c11909c76f6ae341845496f4754265c277920935aa989434b611cf905f90a3505050565b6001600160a01b03831661202d5760405163e99d5ac560e01b815260040160405180910390fd5b6120368361238a565b1561205f57604051633ae252cd60e21b81526001600160a01b03841660048201526024016110fc565b816001600160a01b0316836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120a5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c991906152e4565b6001600160a01b03161415806121505750806001600160a01b0316836001600160a01b031663de9375f26040518163ffffffff1660e01b8152600401602060405180830381865afa158015612120573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214491906152e4565b6001600160a01b031614155b1561217957604051633ae252cd60e21b81526001600160a01b03841660048201526024016110fc565b5f8051602061571d83398151915280546001810182555f8281527fbd3b60dada78b9553105038e485344c290642e896a2040a87e5442d9a8f189d390910180546001600160a01b0319166001600160a01b03871690811790915560405190917f3f008fd510eae7a9e7bee13513d7b83bef8003d488b5a3d0b0da4de71d6846f191a28054600a10156111be57805460405163a0c5dde760e01b81526004810191909152600a60248201526044016110fc565b7fbe95051ceb3f91d85436579dcb05e73839fcf7ec679038845ee9df7027ce18e36122615f8051602061569d8339815191525490565b612269610a2c565b6040805192835260208301919091520160405180910390a1565b5f33612290858285613674565b61229b8585856136bf565b506001949350505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610c3d565b6122d661371c565b6122df8261358a565b611068816134b0565b670de0b6b3a7640000811115612314576040516322643c8760e21b8152600481018290526024016110fc565b7f851713d8b7886cdb5682ccb4d2dba1bf8cae30c699ce588016da31dab5d7f10180549082905560408051828152602081018490525f8051602061571d83398151915292917ff7e9c2b164c5e7510b6027354248eae9ab7974293420bcba68421fced24c4a2491015b60405180910390a1505050565b5f8051602061571d83398151915280545f9190825b818110156123f157846001600160a01b0316835f0182815481106123c5576123c561525a565b5f918252602090912001546001600160a01b0316036123e957506001949350505050565b60010161239f565b505f949350505050565b5f807f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e0090505f81546124379190600160a01b900460ff16615490565b91505090565b5f610cad613741565b61244e6137b4565b5f8051602061573d833981519152805460ff191681557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a150565b5f8051602061571d83398151915280545f9190825b81811015610b4d5761255284845f0183815481106124da576124da61525a565b5f9182526020909120015460405163402d267d60e01b81523060048201526001600160a01b039091169063402d267d906024015b602060405180830381865afa158015612529573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061254d919061526e565b6137e3565b93506001016124ba565b5f612565613804565b61258c575f196125736125a2565b146125855761258061388a565b610c0a565b5f19610c0a565b5f92915050565b5f828218828410028218610d35565b5f5f8051602061563d8339815191525b60010154905090565b5f5f805160206156fd8339815191526125b2565b5f610d356125db610a2c565b6125e6906001615299565b6125f15f600a615463565b5f8051602061569d83398151915254611eeb9190615299565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061267a57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661266e6138a3565b6001600160a01b031614155b15610fcc5760405163703e46dd60e11b815260040160405180910390fd5b5f61106881611ef4565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156126fc575060408051601f3d908101601f191682019092526126f99181019061526e565b60015b61272457604051634c9c8ce360e01b81526001600160a01b03831660048201526024016110fc565b5f805160206156dd833981519152811461275457604051632a87526960e21b8152600481018290526024016110fc565b61275e83836138b7565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610fcc5760405163703e46dd60e11b815260040160405180910390fd5b6127b4613804565b15610fcc5760405163d93c066560e01b815260040160405180910390fd5b5f5f8051602061571d8339815191526125b2565b6040516370a0823160e01b81523060048201525f906001600160a01b038516906307a2d13a9082906370a0823190602401602060405180830381865afa158015612832573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612856919061526e565b6040518263ffffffff1660e01b815260040161287491815260200190565b602060405180830381865afa15801561288f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b3919061526e565b6040516370a0823160e01b81523060048201526001600160a01b038716906307a2d13a9082906370a0823190602401602060405180830381865afa1580156128fd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612921919061526e565b6040518263ffffffff1660e01b815260040161293f91815260200190565b602060405180830381865afa15801561295a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061297e919061526e565b6129889190615299565b90505f612993610f60565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156129d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129fb919061526e565b90508315612a7a57604051632d182be560e21b815260048101859052306024820181905260448201526001600160a01b0387169063b460af94906064016020604051808303815f875af1158015612a54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a78919061526e565b505b5f612a83610f60565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612ac7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612aeb919061526e565b90505f612af883836152ff565b90508015612b8d57612b1d8782612b0d610f60565b6001600160a01b0316919061390c565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03881690636e553f65906044016020604051808303815f875af1158015612b67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8b919061526e565b505b6040516370a0823160e01b81523060048201525f906001600160a01b038916906307a2d13a9082906370a0823190602401602060405180830381865afa158015612bd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bfd919061526e565b6040518263ffffffff1660e01b8152600401612c1b91815260200190565b602060405180830381865afa158015612c36573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c5a919061526e565b6040516370a0823160e01b81523060048201526001600160a01b038b16906307a2d13a9082906370a0823190602401602060405180830381865afa158015612ca4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cc8919061526e565b6040518263ffffffff1660e01b8152600401612ce691815260200190565b602060405180830381865afa158015612d01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d25919061526e565b612d2f9190615299565b90505f612d458789670de0b6b3a76400006139c9565b9050612d518282615299565b861115612d90576040516304e32bab60e41b8152600481018790526024810183905260448101829052606481018990526084810188905260a4016110fc565b886001600160a01b03168a6001600160a01b03167f81a143d873eb13ec2d7efc6f49d2ce680716e4d295f3340c68e601c317fb1595858a604051612dde929190918252602082015260400190565b60405180910390a350505050505050505050565b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd01545f805160206156fd833981519152905f03612e2c5750565b5f612e35613a79565b82549091508082111561275e575f612e4d82846152ff565b90505f612e7782612e695f8051602061569d8339815191525490565b670de0b6b3a76400006139c9565b90505f612e91828760010154670de0b6b3a76400006139c9565b90505f612edf82612ea383600a615463565b5f8051602061569d83398151915254612ebc9190615299565b84612ec5610a2c565b612ed0906001615299565b612eda91906152ff565b6139c9565b90508015612f5a576002870154612eff906001600160a01b031682613acc565b612f0f612f0a613a79565b613b00565b600287015460408051838152602081018590526001600160a01b03909216917f74e325cf88102b892b2796a1db2f772360b0b33fbdea0c4e3ed24fa9755fe0c5910160405180910390a25b50505050505050565b5f612f6c6127ac565b612f768383613b49565b9050610c3d61222b565b5f807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006111f0565b612fb0613b95565b5f8051602061573d833981519152805460ff191660011781557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833612487565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f805160206156bd83398151915291610b76906152ac565b60605f5f805160206156bd833981519152610b65565b5f61304d6127ac565b612f768383613bac565b61305f61371c565b610c8e81613bf8565b61307061371c565b6110688282613c7b565b61308261371c565b610c8e81604051806040016040528060018152602001603160f81b815250613ccb565b6130ad61371c565b610fcc613d2a565b610fcc61371c565b305f6130c882610fce565b9050808311156130f157818382604051633c8097d960e11b81526004016110fc939291906154a9565b5f6130fb84611b53565b905061310985848684613d32565b5050505050565b5f33611e938185856136bf565b5f8051602061571d8339815191525f5b815481101561275e57826001600160a01b0316825f0182815481106131545761315461525a565b5f918252602090912001546001600160a01b03160361326657805b825461317d906001906152ff565b8110156131fb5782613190826001615299565b815481106131a0576131a061525a565b5f9182526020909120015483546001600160a01b03909116908490839081106131cb576131cb61525a565b5f91825260209091200180546001600160a01b0319166001600160a01b039290921691909117905560010161316f565b50815482908061320d5761320d6154ca565b5f8281526020812082015f1990810180546001600160a01b03191690559091019091556040516001600160a01b038516917f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea491a2505050565b60010161312d565b60605f80846001600160a01b03168460405161328a91906154de565b5f60405180830381855af49150503d805f81146132c2576040519150601f19603f3d011682016040523d82523d5f602084013e6132c7565b606091505b50915091506132d7858383613f29565b95945050505050565b5f6132e96127ac565b6132f4848484613f85565b9050610d3561222b565b5f6133076127ac565b6132f4848484613fd2565b5f61331b613804565b61258c575f196133296125a2565b146125855761258061333961388a565b5f611eb0565b5f8051602061571d83398151915280545f9190825b81811015610b4d576133ac84845f0183815481106133745761337461525a565b5f9182526020909120015460405163ce96cb7760e01b81523060048201526001600160a01b039091169063ce96cb779060240161250e565b9350600101613354565b5f6133bf613804565b61258c576125808261401f565b5f610c0a6133d861243d565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f8061340888888888614032565b92509250925061341882826140fa565b50909695505050505050565b61275e83838360016141b2565b5f61343a613804565b61258c5761258082614295565b60605f8051602061571d8339815191528054604080516020808402820181019092528281529291908301828280156134a657602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311613488575b5050505050905090565b6706f05b59d3b200008111156134ea57604051639f267a1160e01b8152600481018290526706f05b59d3b2000060248201526044016110fc565b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd01545f805160206156fd83398151915280549091905f613528613a79565b90508215801561353757505f85115b801561354257508082105b156135505761355081613b00565b60018401859055604051859084907fec752fd140b0567ddecc3a75eacd13201c091536e7e0731dcf143f5ee461bff7905f90a35050505050565b6001600160a01b0381166135b15760405163e99d5ac560e01b815260040160405180910390fd5b7f8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd0280546001600160a01b031981166001600160a01b038481169182179093556040515f805160206156fd833981519152939092169182907f15d80a013f22151bc7246e3bc132e12828cde19de98870475e3fa70840152721905f90a3505050565b5f61365f61363f8361429f565b801561365a57505f8480613655576136556154e9565b868809115b151590565b61366a8686866139c9565b6132d79190615299565b5f61367f8484611ab5565b90505f198110156111be57818110156136b157828183604051637dc7a0d960e11b81526004016110fc939291906154a9565b6111be84848484035f6141b2565b6001600160a01b0383166136e857604051634b637e8f60e11b81525f60048201526024016110fc565b6001600160a01b0382166137115760405163ec442f0560e01b81525f60048201526024016110fc565b61275e8383836142cb565b6137246143f1565b610fcc57604051631afcd79f60e31b815260040160405180910390fd5b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61376b61440a565b613773614472565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f8051602061573d8339815191525460ff16610fcc57604051638dfc202b60e01b815260040160405180910390fd5b5f805f6137f085856144b4565b90925090505f1980821883151502186132d7565b5f61381d5f8051602061573d8339815191525460ff1690565b80610cad575061382b611afe565b6001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613866573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cad9190615471565b5f610cad6138966125a2565b61389e610a2c565b6144cc565b5f5f805160206156dd833981519152611b0e565b6138c0826144d8565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156139045761275e828261326e565b61106861453b565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261395d848261455a565b6111be576040516001600160a01b0384811660248301525f60448301526139bf91869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506145a3565b6111be84826145a3565b5f805f6139d6868661460f565b91509150815f036139fa578381816139f0576139f06154e9565b0492505050610d35565b818411613a1157613a11600385150260111861462b565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f80613a83610a2c565b90505f613a9b5f8051602061569d8339815191525490565b90505f8111613ab257670de0b6b3a7640000613ac5565b613ac582670de0b6b3a7640000836139c9565b9250505090565b6001600160a01b038216613af55760405163ec442f0560e01b81525f60048201526024016110fc565b6110685f83836142cb565b5f805160206156fd833981519152805482825560408051828152602081018590527f03f8f938dbe4475565f0cf1c3dcf09728208c2c6065e1f717102058c51e94d06910161237d565b5f80613b5483610fce565b905080841115613b7d57828482604051633c8097d960e11b81526004016110fc939291906154a9565b5f613b8785611b53565b90506118a533858784613d32565b5f8051602061573d8339815191525460ff166127b4565b5f80613bb78361186e565b905080841115613be05782848260405163284ff66760e01b81526004016110fc939291906154a9565b5f613bea8561182a565b90506118a533858388613d32565b613c0061371c565b7f0773e532dfede91f04b12a73d3d2acd361424f41f76b4fb79f090161e36b4e005f80613c2c8461463c565b9150915081613c3c576012613c3e565b805b83546001600160a81b031916600160a01b60ff92909216919091026001600160a01b031916176001600160a01b0394909416939093179091555050565b613c8361371c565b5f8051602061567d8339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03613cbc8482615541565b50600481016111be8382615541565b613cd361371c565b5f805160206156bd8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102613d0c8482615541565b5060038101613d1b8382615541565b505f8082556001909101555050565b611e9d61371c565b613d3a6143f1565b15613d425750805b613d4e84848484614712565b5f8051602061571d83398151915280548391905f5b81811015613ef9578315613ef9575f835f018281548110613d8657613d8661525a565b5f91825260208220015460405163402d267d60e01b81523060048201526001600160a01b039091169250829063402d267d90602401602060405180830381865afa158015613dd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613dfa919061526e565b90505f613e078783612593565b90508015613eeb57613e1c8382612b0d610f60565b604051636e553f6560e01b8152600481018290523060248201526001600160a01b03841690636e553f65906044016020604051808303815f875af1925050508015613e84575060408051601f3d908101601f19168201909252613e819181019061526e565b60015b613edd57826001600160a01b03167fb25cefcd019c9ac00557fa1cae5f952455cd9ad7b058f91d66e1bbe895e31ece82604051613ec391815260200190565b60405180910390a2613ed8835f612b0d610f60565b613eeb565b50613ee881886152ff565b96505b505050806001019050613d63565b508215612f5a5760405162aea97b60e61b81526004810186905260248101859052604481018490526064016110fc565b606082613f3e57613f3982614749565b610d35565b8151158015613f5557506001600160a01b0384163b155b15613f7e57604051639996b31560e01b81526001600160a01b03851660048201526024016110fc565b5080610d35565b5f80613f90836118bf565b905080851115613fb957828582604051633fa733bb60e21b81526004016110fc939291906154a9565b5f613fc386610c43565b90506132d73386868985614772565b5f80613fdd83611a6c565b90508085111561400657828582604051632e52afbb60e21b81526004016110fc939291906154a9565b5f61401086611042565b90506132d7338686848a614772565b5f610c0a61402c836111df565b5f6125cf565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561406b57505f915060039050826140f0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156140bc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166140e757505f9250600191508290506140f0565b92505f91508190505b9450945094915050565b5f82600381111561410d5761410d6155fb565b03614116575050565b600182600381111561412a5761412a6155fb565b036141485760405163f645eedf60e01b815260040160405180910390fd5b600282600381111561415c5761415c6155fb565b0361417d5760405163fce698f760e01b8152600481018290526024016110fc565b6003826003811115614191576141916155fb565b03611068576040516335e2f38360e21b8152600481018290526024016110fc565b5f8051602061567d8339815191526001600160a01b0385166141e95760405163e602df0560e01b81525f60048201526024016110fc565b6001600160a01b03841661421257604051634a1406b160e11b81525f60048201526024016110fc565b6001600160a01b038086165f9081526001830160209081526040808320938816835292905220839055811561310957836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161428691815260200190565b60405180910390a35050505050565b5f610c0a826111df565b5f60028260038111156142b4576142b46155fb565b6142be919061560f565b60ff166001149050919050565b5f8051602061567d8339815191526001600160a01b0384166143055781816002015f8282546142fa9190615299565b909155506143629050565b6001600160a01b0384165f90815260208290526040902054828110156143445784818460405163391434e360e21b81526004016110fc939291906154a9565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b03831661438057600281018054839003905561439e565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516143e391815260200190565b60405180910390a350505050565b5f6143fa6122a6565b54600160401b900460ff16919050565b5f5f805160206156bd83398151915281614422612ff0565b80519091501561443a57805160209091012092915050565b81548015614449579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f805160206156bd8339815191528161448a61302e565b8051909150156144a257805160209091012092915050565b60018201548015614449579392505050565b80820182811015905f90825b81029150509250929050565b5f806132d78484614952565b806001600160a01b03163b5f0361450d57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016110fc565b5f805160206156dd83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b3415610fcc5760405163b398979f60e01b815260040160405180910390fd5b5f805f8060205f8651602088015f8a5af192503d91505f5190508280156145995750811561458b5780600114614599565b5f866001600160a01b03163b115b9695505050505050565b5f8060205f8451602086015f885af1806145c2576040513d5f823e3d81fd5b50505f513d915081156145d95780600114156145e6565b6001600160a01b0384163b155b156111be57604051635274afe760e01b81526001600160a01b03851660048201526024016110fc565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290515f918291829182916001600160a01b03871691614682916154de565b5f60405180830381855afa9150503d805f81146146ba576040519150601f19603f3d011682016040523d82523d5f602084013e6146bf565b606091505b50915091508180156146d357506020815110155b15614706575f818060200190518101906146ed919061526e565b905060ff8111614704576001969095509350505050565b505b505f9485945092505050565b5f8211801561471f575080155b1561473d57604051630e5a744960e41b815260040160405180910390fd5b6111be84848484614962565b8051156147595780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f8051602061571d83398151915280548391905f5b8181101561490a57831561490a575f835f0182815481106147aa576147aa61525a565b5f91825260208220015460405163ce96cb7760e01b81523060048201526001600160a01b039091169250829063ce96cb7790602401602060405180830381865afa1580156147fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061481e919061526e565b90505f61482b8783612593565b905080156148fc57604051632d182be560e21b815260048101829052306024820181905260448201526001600160a01b0384169063b460af94906064016020604051808303815f875af19250505080156148a2575060408051601f3d908101601f1916820190925261489f9181019061526e565b60015b6148ee57826001600160a01b03167fa2269912b47133fae1d7f448c9284ea248951ac29b8c7c41d301f8721a38d10d826040516148e191815260200190565b60405180910390a26148fc565b506148f981886152ff565b96505b505050806001019050614787565b50821561493b5760405163e971065160e01b81526004810186905260248101859052604481018490526064016110fc565b61494888888888886149cd565b5050505050505050565b80820382811115905f90826144c0565b61497561496d610f60565b853085614a05565b61497f8382613acc565b826001600160a01b0316846001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d784846040516143e3929190918252602082015260400190565b5f811180156149da575081155b156149f857604051630e5a744960e41b815260040160405180910390fd5b6131098585858585614a3e565b6040516001600160a01b0384811660248301528381166044830152606482018390526111be9186918216906323b872dd9060840161398d565b826001600160a01b0316856001600160a01b031614614a6257614a62838683613674565b614a6c8382614ae5565b614a7e614a77610f60565b8584614b19565b826001600160a01b0316846001600160a01b0316866001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8585604051614ad6929190918252602082015260400190565b60405180910390a45050505050565b6001600160a01b038216614b0e57604051634b637e8f60e11b81525f60048201526024016110fc565b611068825f836142cb565b6040516001600160a01b0383811660248301526044820183905261275e91859182169063a9059cbb9060640161398d565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610d356020830184614b4a565b5f60208284031215614b9a575f80fd5b5035919050565b6001600160a01b0381168114610c8e575f80fd5b8035610c0d81614ba1565b5f8060408385031215614bd1575f80fd5b8235614bdc81614ba1565b946020939093013593505050565b5f60208284031215614bfa575f80fd5b8135610d3581614ba1565b5f805f60608486031215614c17575f80fd5b8335614c2281614ba1565b92506020840135614c3281614ba1565b929592945050506040919091013590565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614c7f57614c7f614c43565b604052919050565b5f806001600160401b03841115614ca057614ca0614c43565b50601f8301601f1916602001614cb581614c57565b915050828152838383011115614cc9575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614cee575f80fd5b610d3583833560208501614c87565b5f82601f830112614d0c575f80fd5b81356001600160401b03811115614d2557614d25614c43565b8060051b614d3560208201614c57565b91825260208185018101929081019086841115614d50575f80fd5b6020860192505b83831015614599578235614d6a81614ba1565b825260209283019290910190614d57565b5f805f805f805f60e0888a031215614d91575f80fd5b8735614d9c81614ba1565b9650614daa60208901614bb5565b955060408801356001600160401b03811115614dc4575f80fd5b614dd08a828b01614cdf565b95505060608801356001600160401b03811115614deb575f80fd5b614df78a828b01614cdf565b945050614e0660808901614bb5565b925060a0880135915060c08801356001600160401b03811115614e27575f80fd5b614e338a828b01614cfd565b91505092959891949750929550565b5f8060408385031215614e53575f80fd5b8235614e5e81614ba1565b915060208301356001600160401b03811115614e78575f80fd5b8301601f81018513614e88575f80fd5b614e9785823560208401614c87565b9150509250929050565b5f805f8060808587031215614eb4575f80fd5b8435614ebf81614ba1565b93506020850135614ecf81614ba1565b93969395505050506040820135916060013590565b5f8060408385031215614ef5575f80fd5b823591506020830135614f0781614ba1565b809150509250929050565b60ff60f81b8816815260e060208201525f614f3060e0830189614b4a565b8281036040840152614f428189614b4a565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b81811015614f97578351835260209384019390920191600101614f79565b50909b9a5050505050505050505050565b5f805f805f8060c08789031215614fbd575f80fd5b8635614fc881614ba1565b95506020870135614fd881614ba1565b945060408701356001600160401b03811115614ff2575f80fd5b614ffe89828a01614cdf565b94505060608701356001600160401b03811115615019575f80fd5b61502589828a01614cdf565b935050608087013561503681614ba1565b9598949750929591949360a090920135925050565b5f8083601f84011261505b575f80fd5b5081356001600160401b03811115615071575f80fd5b6020830191508360208260051b850101111561508b575f80fd5b9250929050565b5f80602083850312156150a3575f80fd5b82356001600160401b038111156150b8575f80fd5b6150c48582860161504b565b90969095509350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561512757603f19878603018452615112858351614b4a565b945060209384019391909101906001016150f6565b50929695505050505050565b5f805f60608486031215615145575f80fd5b83359250602084013561515781614ba1565b9150604084013561516781614ba1565b809150509250925092565b5f805f805f805f60e0888a031215615188575f80fd5b873561519381614ba1565b965060208801356151a381614ba1565b95506040880135945060608801359350608088013560ff811681146151c6575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b602080825282518282018190525f918401906040840190835b818110156152235783516001600160a01b03168352602093840193909201916001016151fc565b509095945050505050565b5f806040838503121561523f575f80fd5b823561524a81614ba1565b91506020830135614f0781614ba1565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561527e575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c3d57610c3d615285565b600181811c908216806152c057607f821691505b6020821081036152de57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f602082840312156152f4575f80fd5b8151610d3581614ba1565b81810381811115610c3d57610c3d615285565b5f808335601e19843603018112615327575f80fd5b8301803591506001600160401b03821115615340575f80fd5b60200191503681900382131561508b575f80fd5b5f81518060208401855e5f93019283525090919050565b828482375f8382015f81526145998185615354565b6001815b60018411156153bb5780850481111561539f5761539f615285565b60018416156153ad57908102905b60019390931c928002615384565b935093915050565b5f826153d157506001610c3d565b816153dd57505f610c3d565b81600181146153f357600281146153fd57615419565b6001915050610c3d565b60ff84111561540e5761540e615285565b50506001821b610c3d565b5060208310610133831016604e8410600b841016171561543c575081810a610c3d565b6154485f198484615380565b805f190482111561545b5761545b615285565b029392505050565b5f610d3560ff8416836153c3565b5f60208284031215615481575f80fd5b81518015158114610d35575f80fd5b60ff8181168382160190811115610c3d57610c3d615285565b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52603160045260245ffd5b5f610d358284615354565b634e487b7160e01b5f52601260045260245ffd5b601f82111561275e57805f5260205f20601f840160051c810160208510156155225750805b601f840160051c820191505b81811015613109575f815560010161552e565b81516001600160401b0381111561555a5761555a614c43565b61556e8161556884546152ac565b846154fd565b6020601f8211600181146155a0575f83156155895750848201515b5f19600385901b1c1916600184901b178455613109565b5f84815260208120601f198516915b828110156155cf57878501518255602094850194600190920191016155af565b50848210156155ec57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52602160045260245ffd5b5f60ff83168061562d57634e487b7160e01b5f52601260045260245ffd5b8060ff8416069150509291505056fe83cbba01667a5ddf3820f0a2c4220dbc355a1a788c7094daad71b73a418b0d00d1473398bb66596de5d1ea1fc8e303ff2ac23265adc9144b1b52065dc4f0934b52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0052c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8133214f360747da779e5436efd7332b025d67830fc92a23fa9b9e5e4b87fd00851713d8b7886cdb5682ccb4d2dba1bf8cae30c699ce588016da31dab5d7f100cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a8aa94f2e8b958789c84ed7b76204f9060cbb7be85cf23ad0561b67bcf44e23664736f6c634300081a0033","sourceMap":"1100:24863:83:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7094:420;;;;;;;;;;;;;:::i;:::-;;;160:25:91;;;148:2;133:18;7094:420:83;;;;;;;;2697:144:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;13036:240:87:-;;;;;;;;;;-1:-1:-1;13036:240:87;;;;;:::i;:::-;;:::i;8589:210::-;;;;;;;;;;-1:-1:-1;8589:210:87;;;;;:::i;:::-;;:::i;:::-;;;1758:14:91;;1751:22;1733:41;;1721:2;1706:18;8589:210:87;1593:187:91;8732:147:33;;;;;;;;;;-1:-1:-1;8732:147:33;;;;;:::i;:::-;;:::i;6827:155:87:-;;;;;;;;;;-1:-1:-1;6827:155:87;;;;;:::i;:::-;;:::i;:::-;;3877:152:31;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;4008:14:31;3877:152;;7789:112:89;;;;;;;;;;;;;:::i;11907:172:83:-;;;;;;;;;;-1:-1:-1;11907:172:83;;;;;:::i;:::-;;:::i;9087:230:87:-;;;;;;;;;;-1:-1:-1;9087:230:87;;;;;:::i;:::-;;:::i;24466:117:83:-;;;;;;;;;;;;;:::i;4078:658::-;;;;;;;;;;-1:-1:-1;4078:658:83;;;;;:::i;:::-;;:::i;25239:126::-;;;;;;;;;;-1:-1:-1;25239:126:83;;;;;:::i;:::-;;:::i;8320:203:87:-;;;;;;;;;;;;;:::i;:::-;;;5887:4:91;5875:17;;;5857:36;;5845:2;5830:18;8320:203:87;5715:184:91;11504:235:83;;;;;;;;;;-1:-1:-1;11504:235:83;;;;;:::i;:::-;;:::i;3085:112:32:-;;;;;;;;;;;;;:::i;6882:153:33:-;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;6250:32:91;;;6232:51;;6220:2;6205:18;6882:153:33;6086:203:91;6450:97:87;;;;;;;;;;;;;:::i;4981:175:83:-;;;;;;;;;;-1:-1:-1;4981:175:83;;;;;:::i;:::-;;:::i;13793:123:87:-;;;;;;;;;;;;;:::i;8549:110:89:-;;;;;;;;;;;;;:::i;8154:128::-;;;;;;;;;;;;;:::i;8931:146:33:-;;;;;;;;;;-1:-1:-1;8931:146:33;;;;;:::i;:::-;;:::i;4161:214:30:-;;;;;;:::i;:::-;;:::i;3708:134::-;;;;;;;;;;;;;:::i;25873:88:83:-;;;;;;;;;;-1:-1:-1;25947:7:83;;;;;;;;;;;;-1:-1:-1;;;25947:7:83;;;;25873:88;;2496:145:37;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;2625:9:37;;;2496:145;;16113:696:83;;;;;;;;;;-1:-1:-1;16113:696:83;;;;;:::i;:::-;;:::i;6492:227:89:-;;;;;;;;;;-1:-1:-1;6492:227:89;;;;;:::i;:::-;;:::i;4087:171:31:-;;;;;;;;;;-1:-1:-1;4087:171:31;;;;;:::i;:::-;;:::i;2824:154:32:-;;;;;;;;;;-1:-1:-1;2824:154:32;;;;;:::i;:::-;;:::i;6247:88:87:-;;;;;;;;;;;;;:::i;5172:903:39:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;24699:140:83:-;;;;;;;;;;;;;:::i;6812:221:89:-;;;;;;;;;;-1:-1:-1;6812:221:89;;;;;:::i;:::-;;:::i;2954:148:31:-;;;;;;;;;;;;;:::i;3600:820:87:-;;;;;;;;;;-1:-1:-1;3600:820:87;;;;;:::i;:::-;;:::i;8842:202::-;;;;;;;;;;-1:-1:-1;8842:202:87;;;;;:::i;:::-;;:::i;13099:1005:83:-;;;;;;;;;;-1:-1:-1;13099:1005:83;;;;;:::i;:::-;;:::i;1518:484:35:-;;;;;;;;;;-1:-1:-1;1518:484:35;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1819:58:30:-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1819:58:30;;;;;8535:143:33;;;;;;;;;;-1:-1:-1;8535:143:33;;;;;:::i;:::-;;:::i;7126:251:89:-;;;;;;;;;;-1:-1:-1;7126:251:89;;;;;:::i;:::-;;:::i;7470:247::-;;;;;;;;;;-1:-1:-1;7470:247:89;;;;;:::i;:::-;;:::i;5391:459:83:-;;;;;;;;;;-1:-1:-1;5391:459:83;;;;;:::i;:::-;;:::i;12751:240:87:-;;;;;;;;;;-1:-1:-1;12751:240:87;;;;;:::i;:::-;;:::i;6069:174:83:-;;;;;;;;;;-1:-1:-1;6069:174:83;;;;;:::i;:::-;;:::i;2098:672:32:-;;;;;;;;;;-1:-1:-1;2098:672:32;;;;;:::i;:::-;;:::i;24192:152:83:-;;;;;;;;;;-1:-1:-1;24192:152:83;;;;;:::i;:::-;;:::i;6481:451::-;;;;;;;;;;-1:-1:-1;6481:451:83;;;;;:::i;:::-;;:::i;23720:114::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4689:195:31:-;;;;;;;;;;-1:-1:-1;4689:195:31;;;;;:::i;:::-;;:::i;13656:104:87:-;;;;;;;;;;;;;:::i;10746:211:83:-;;;;;;;;;;-1:-1:-1;10746:211:83;;;;;:::i;:::-;;:::i;11117:147::-;;;;;;;;;;-1:-1:-1;11117:147:83;;;;;:::i;:::-;;:::i;8338::33:-;;;;;;;;;;-1:-1:-1;8338:147:33;;;;;:::i;:::-;;:::i;14462:1054:83:-;;;;;;;;;;-1:-1:-1;14462:1054:83;;;;;:::i;:::-;;:::i;7094:420::-;-1:-1:-1;;;;;;;;;;;7300:20:83;;7185:13;;2048:30;7185:13;7330:178;7354:6;7350:1;:10;7330:178;;;7381:15;7399:1;:13;;7413:1;7399:16;;;;;;;;:::i;:::-;;;;;;;;;;;7463:33;;-1:-1:-1;;;7463:33:83;;7490:4;7463:33;;;6232:51:91;-1:-1:-1;;;;;7399:16:83;;;;-1:-1:-1;7399:16:83;;7438:24;;7399:16;;7463:18;;6205::91;;7463:33:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7438:59;;;;;;;;;;;;;160:25:91;;148:2;133:18;;14:177;7438:59:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7429:68;;;;:::i;:::-;;-1:-1:-1;;7362:3:83;;7330:178;;;;7200:314;;7094:420;:::o;2697:144:31:-;2742:13;2767:22;-1:-1:-1;;;;;;;;;;;2792:18:31;2767:43;;2827:1;:7;;2820:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2697:144;:::o;13036:240:87:-;13210:7;392:25:90;:23;:25::i;:::-;13240:29:87::1;13262:6;13240:21;:29::i;:::-;13233:36;;427:1:90;13036:240:87::0;;;:::o;8589:210::-;8735:4;3395:21:38;:19;:21::i;:::-;8762:30:87::1;8776:7;8785:6;8762:13;:30::i;:::-;8755:37;;3437:20:38::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;3437:20;8589:210:87;;;;:::o;8732:147:33:-;8802:7;8828:44;8845:6;8853:18;8828:16;:44::i;6827:155:87:-;3395:21:38;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;4637:20:87::1;4652:4;4637:14;:20::i;:::-;6940:35:::2;6959:15;6940:18;:35::i;:::-;3426:1:38::1;3437:20:::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;3437:20;6827:155:87;:::o;7789:112:89:-;7852:7;392:25:90;:23;:25::i;:::-;-1:-1:-1;;;;;;;;;;;;8045:44:89;;7789:112::o;7878:16::-:1;7871:23;;7789:112:::0;:::o;11907:172:83:-;3395:21:38;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;4637:20:87::2;4652:4;4637:14;:20::i;:::-;12023:49:83::3;12036:9;12047:7;:5;:7::i;:::-;12064:6;:4;:6::i;:::-;12023:12;:49::i;:::-;5060:1:87::2;5071:18:::1;:16;:18::i;:::-;3437:20:38::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;9087:230:87;9247:4;3395:21:38;:19;:21::i;:::-;9274:36:87::1;9293:4;9299:2;9303:6;9274:18;:36::i;:::-;9267:43;;3437:20:38::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;3437:20;9087:230:87;;;;;:::o;24466:117:83:-;24531:7;392:25:90;:23;:25::i;:::-;24557:12:83::1;:10;:12::i;:::-;:19;24550:26;;24466:117:::0;:::o;4078:658::-;4158:30:29;4191:26;:24;:26::i;:::-;4302:15;;4158:59;;-1:-1:-1;4302:15:29;-1:-1:-1;;;4302:15:29;;;4301:16;;-1:-1:-1;;;;;4348:14:29;4279:19;4724:16;;:34;;;;;4744:14;4724:34;4704:54;;4768:17;4788:11;-1:-1:-1;;;;;4788:16:29;4803:1;4788:16;:50;;;;-1:-1:-1;4816:4:29;4808:25;:30;4788:50;4768:70;;4854:12;4853:13;:30;;;;;4871:12;4870:13;4853:30;4849:91;;;4906:23;;-1:-1:-1;;;4906:23:29;;;;;;;;;;;4849:91;4949:18;;-1:-1:-1;;4949:18:29;4966:1;4949:18;;;4977:67;;;;5011:22;;-1:-1:-1;;;;5011:22:29;-1:-1:-1;;;5011:22:29;;;4977:67;4373:42:83::1;::::0;-1:-1:-1;;;4373:42:83;;555:4:81::1;4373:42:83;::::0;::::1;16821:25:91::0;;;16862:18;;;16855:34;4349:70:83::1;::::0;-1:-1:-1;;;;;4373:19:83;::::1;::::0;::::1;::::0;16794:18:91;;4373:42:83::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4417:1;4349:23;:70::i;:::-;4435:9;4430:135;4454:11;:18;4450:1;:22;4430:135;;;4493:61;4506:11;4518:1;4506:14;;;;;;;;:::i;:::-;;;;;;;4530:6;4547:5;4493:12;:61::i;:::-;4474:3;;4430:135;;;;4574:61;1444:7;4574:31;:61::i;:::-;4646:83;4663:5;4670:6;4678:5;4685:7;4694:14;4710:18;4646:16;:83::i;:::-;5068:14:29::0;5064:101;;;5098:23;;-1:-1:-1;;;;5098:23:29;;;5140:14;;-1:-1:-1;17309:50:91;;5140:14:29;;17297:2:91;17282:18;5140:14:29;;;;;;;5064:101;4092:1079;;;;;4078:658:83;;;;;;;:::o;25239:126::-;25314:4;392:25:90;:23;:25::i;:::-;25337:21:83::1;25349:8;25337:11;:21::i;8320:203:87:-:0;8472:5;8500:16;:14;:16::i;11504:235:83:-;3395:21:38;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;4637:20:87::1;4652:4;4637:14;:20::i;:::-;11671:61:83::2;11703:28;11671:31;:61::i;3085:112:32:-:0;3144:7;3170:20;:18;:20::i;6882:153:33:-;4209:22;7019:8;-1:-1:-1;;;;;7019:8:33;;6882:153::o;6450:97:87:-;3395:21:38;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;4637:20:87::1;4652:4;4637:14;:20::i;:::-;6530:10:::2;:8;:10::i;:::-;3426:1:38::1;3437:20:::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;3437:20;6450:97:87:o;4981:175:83:-;5060:7;5086:63;5095:25;:23;:25::i;:::-;5122:26;5139:8;5122:16;:26::i;:::-;5086:8;:63::i;13793:123:87:-;13866:7;392:25:90;:23;:25::i;:::-;13892:17:87::1;:15;:17::i;8549:110:89:-:0;8611:7;392:25:90;:23;:25::i;:::-;-1:-1:-1;8800:43:89;;-1:-1:-1;;;;;8800:43:89;;7789:112::o;8154:128::-;8225:7;392:25:90;:23;:25::i;:::-;8251:24:89::1;:22;:24::i;8931:146:33:-:0;8999:7;9025:45;9042:6;9050:19;9025:16;:45::i;4161:214:30:-;2655:13;:11;:13::i;:::-;4276:36:::1;4294:17;4276;:36::i;:::-;4322:46;4344:17;4363:4;4322:21;:46::i;:::-;4161:214:::0;;:::o;3708:134::-;3777:7;2926:20;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;;3708:134:30;:::o;16113:696:83:-;3395:21:38;:19;:21::i;:::-;4850:32:87::1;:30;:32::i;:::-;667:28:81::3;4637:20:87;4652:4;4637:14;:20::i;:::-;16365:60:83::4;16374:18;16394:30;:28;:30::i;16365:60::-;16344:81;;16441:25;16453:12;16441:11;:25::i;:::-;16436:77;;16475:38;::::0;-1:-1:-1;;;16475:38:83;;-1:-1:-1;;;;;6250:32:91;;16475:38:83::4;::::0;::::4;6232:51:91::0;6205:18;;16475:38:83::4;;;;;;;;16436:77;16528:23;16540:10;16528:11;:23::i;:::-;16523:73;;16560:36;::::0;-1:-1:-1;;;16560:36:83;;-1:-1:-1;;;;;6250:32:91;;16560:36:83::4;::::0;::::4;6232:51:91::0;6205:18;;16560:36:83::4;6086:203:91::0;16523:73:83::4;16626:10;-1:-1:-1::0;;;;;16610:26:83::4;:12;-1:-1:-1::0;;;;;16610:26:83::4;::::0;16606:75:::4;;16645:36;::::0;-1:-1:-1;;;16645:36:83;;-1:-1:-1;;;;;6250:32:91;;16645:36:83::4;::::0;::::4;6232:51:91::0;6205:18;;16645:36:83::4;6086:203:91::0;16606:75:83::4;16695:6;16705:1;16695:11:::0;16691:36:::4;;16715:12;;-1:-1:-1::0;;;16715:12:83::4;;;;;;;;;;;16691:36;16738:64;16749:12;16763:10;16775:6;16783:18;16738:10;:64::i;:::-;5060:1:87::3;5071:18:::2;:16;:18::i;:::-;3437:20:38::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;3437:20;16113:696:83;;;;:::o;6492:227:89:-;6651:7;3395:21:38;:19;:21::i;:::-;2534::89::1;:19;:21::i;:::-;6681:31:::2;6695:6;6703:8;6681:13;:31::i;4087:171:31:-:0;4152:7;;-1:-1:-1;;;;;;;;;;;4196:18:31;-1:-1:-1;;;;;4231:20:31;;;:11;:20;;;;;;;;-1:-1:-1;;4231:20:31;;;;;4087:171::o;2824:154:32:-;2926:7;2952:19;2965:5;2952:12;:19::i;6247:88:87:-;3395:21:38;:19;:21::i;:::-;730:26:81::1;4637:20:87;4652:4;4637:14;:20::i;:::-;6320:8:::2;:6;:8::i;5172:903:39:-:0;5270:13;5297:18;;5270:13;;;5297:18;5270:13;-1:-1:-1;;;;;;;;;;;5776:13:39;;5510:45;;-1:-1:-1;5776:18:39;:43;;;;-1:-1:-1;5798:16:39;;;;:21;5776:43;5768:77;;;;-1:-1:-1;;;5768:77:39;;17572:2:91;5768:77:39;;;17554:21:91;17611:2;17591:18;;;17584:30;-1:-1:-1;;;17630:18:91;;;17623:51;17691:18;;5768:77:39;17370:345:91;5768:77:39;5907:13;:11;:13::i;:::-;5934:16;:14;:16::i;:::-;6042;;;6026:1;6042:16;;;;;;;;;-1:-1:-1;;;5856:212:39;;;-1:-1:-1;5856:212:39;;-1:-1:-1;5964:13:39;;-1:-1:-1;5999:4:39;;-1:-1:-1;6026:1:39;-1:-1:-1;6042:16:39;-1:-1:-1;5856:212:39;-1:-1:-1;;5172:903:39:o;24699:140:83:-;24776:7;392:25:90;:23;:25::i;:::-;24802:30:83::1;:28;:30::i;6812:221:89:-:0;6968:7;3395:21:38;:19;:21::i;:::-;2534::89::1;:19;:21::i;:::-;6998:28:::2;7009:6;7017:8;6998:10;:28::i;2954:148:31:-:0;3086:9;3079:16;;3001:13;;-1:-1:-1;;;;;;;;;;;2064:20:31;3079:16;;;:::i;3600:820:87:-;4158:30:29;4191:26;:24;:26::i;:::-;4302:15;;4158:59;;-1:-1:-1;4302:15:29;-1:-1:-1;;;4302:15:29;;;4301:16;;-1:-1:-1;;;;;4348:14:29;4279:19;4724:16;;:34;;;;;4744:14;4724:34;4704:54;;4768:17;4788:11;-1:-1:-1;;;;;4788:16:29;4803:1;4788:16;:50;;;;-1:-1:-1;4816:4:29;4808:25;:30;4788:50;4768:70;;4854:12;4853:13;:30;;;;;4871:12;4870:13;4853:30;4849:91;;;4906:23;;-1:-1:-1;;;4906:23:29;;;;;;;;;;;4849:91;4949:18;;-1:-1:-1;;4949:18:29;4966:1;4949:18;;;4977:67;;;;5011:22;;-1:-1:-1;;;;5011:22:29;-1:-1:-1;;;5011:22:29;;;4977:67;3836:22:87::1;3851:6;3836:14;:22::i;:::-;3868:28;3881:5;3888:7;3868:12;:28::i;:::-;3906:25;3925:5;3906:18;:25::i;:::-;3941:24;:22;:24::i;:::-;3975:17;:15;:17::i;:::-;4002:18;:16;:18::i;:::-;4030:24;:22;:24::i;:::-;-1:-1:-1::0;;;;;4069:28:87;::::1;4065:54;;4106:13;;-1:-1:-1::0;;;4106:13:87::1;;;;;;;;;;;4065:54;4133:19;4156:1;4133:24:::0;4129:49:::1;;4166:12;;-1:-1:-1::0;;;4166:12:87::1;;;;;;;;;;;4129:49;-1:-1:-1::0;;;;;;;;;;;4250:15:87;;-1:-1:-1;;;;;;4250:15:87::1;-1:-1:-1::0;;;;;4250:15:87;::::1;::::0;;::::1;::::0;;4280:23:::1;::::0;::::1;::::0;-1:-1:-1;;4280:23:87::1;4314:37;-1:-1:-1::0;;4314:18:87::1;:37::i;:::-;4362:51;4376:15;4393:19;4362:13;:51::i;:::-;3826:594;5068:14:29::0;5064:101;;;5098:23;;-1:-1:-1;;;;5098:23:29;;;5140:14;;-1:-1:-1;17309:50:91;;5140:14:29;;17297:2:91;17282:18;5140:14:29;;;;;;;5064:101;4092:1079;;;;;3600:820:87;;;;;;:::o;8842:202::-;8984:4;3395:21:38;:19;:21::i;:::-;9011:26:87::1;9026:2;9030:6;9011:14;:26::i;13099:1005:83:-:0;3395:21:38;:19;:21::i;:::-;730:26:81::2;4637:20:87;4652:4;4637:14;:20::i;:::-;13339:29:83::3;13351:16;13339:11;:29::i;:::-;13334:85;;13377:42;::::0;-1:-1:-1;;;13377:42:83;;-1:-1:-1;;;;;6250:32:91;;13377:42:83::3;::::0;::::3;6232:51:91::0;6205:18;;13377:42:83::3;6086:203:91::0;13334:85:83::3;13434:36;13446:23;13434:11;:36::i;:::-;13429:99;;13479:49;::::0;-1:-1:-1;;;13479:49:83;;-1:-1:-1;;;;;6250:32:91;;13479:49:83::3;::::0;::::3;6232:51:91::0;6205:18;;13479:49:83::3;6086:203:91::0;13429:99:83::3;13562:23;-1:-1:-1::0;;;;;13542:43:83::3;:16;-1:-1:-1::0;;;;;13542:43:83::3;::::0;13538:105:::3;;13594:49;::::0;-1:-1:-1;;;13594:49:83;;-1:-1:-1;;;;;6250:32:91;;13594:49:83::3;::::0;::::3;6232:51:91::0;6205:18;;13594:49:83::3;6086:203:91::0;13538:105:83::3;13658:10:::0;;13654:291:::3;;13742:41;::::0;-1:-1:-1;;;13742:41:83;;13777:4:::3;13742:41;::::0;::::3;6232:51:91::0;13684:22:83::3;::::0;-1:-1:-1;;;;;13709:32:83;::::3;::::0;::::3;::::0;;;13742:26:::3;::::0;6205:18:91;;13742:41:83::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13709:75;;;;;;;;;;;;;160:25:91::0;;148:2;133:18;;14:177;13709:75:83::3;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13684:100;;13807:32;13816:6;13824:14;13807:8;:32::i;:::-;13798:41;;13853:81;13864:16;13882:23;13907:6;13915:18;13853:10;:81::i;:::-;13670:275;13654:291;13954:33;13970:16;13954:15;:33::i;:::-;14058:13;:11;:13::i;:::-;14075:1;14058:18:::0;14054:43:::3;;14085:12;;-1:-1:-1::0;;;14085:12:83::3;;;;;;;;;;;1518:484:35::0;1684:12;;;1620:20;1684:12;;;;;;;;1586:22;;1795:4;-1:-1:-1;;;;;1783:24:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1773:34;;1822:9;1817:155;1837:15;;;1817:155;;;1886:75;1923:4;1943;;1948:1;1943:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1952;1930:30;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1886:28;:75::i;:::-;1873:7;1881:1;1873:10;;;;;;;;:::i;:::-;;;;;;;;;;:88;1854:3;;1817:155;;;;1981:14;1518:484;;;;:::o;8535:143:33:-;8601:7;8627:44;8644:6;8652:18;8627:16;:44::i;7126:251:89:-;7301:7;3395:21:38;:19;:21::i;:::-;2534::89::1;:19;:21::i;:::-;7331:39:::2;7346:6;7354:8;7364:5;7331:14;:39::i;7470:247::-:0;7643:7;3395:21:38;:19;:21::i;:::-;2534::89::1;:19;:21::i;:::-;7673:37:::2;7686:6;7694:8;7704:5;7673:12;:37::i;5391:459:83:-:0;5467:7;5486:26;5515:20;5526:8;5515:10;:20::i;:::-;5486:49;;5601:26;-1:-1:-1;;5630:18:83;:39;:143;;5716:57;5733:18;5753:19;5716:16;:57::i;:::-;5630:143;;;-1:-1:-1;;5630:143:83;5601:172;;5790:53;5799:18;5819:23;5833:8;5819:13;:23::i;5790:53::-;5783:60;5391:459;-1:-1:-1;;;;5391:459:83:o;12751:240:87:-;12925:7;392:25:90;:23;:25::i;:::-;12955:29:87::1;12977:6;12955:21;:29::i;6069:174:83:-:0;6146:7;6172:64;6181:28;:26;:28::i;:::-;6211:24;6229:5;6211:17;:24::i;2098:672:32:-;2319:8;2301:15;:26;2297:97;;;2350:33;;-1:-1:-1;;;2350:33:32;;;;;160:25:91;;;133:18;;2350:33:32;14:177:91;2297:97:32;2404:18;1279:95;2463:5;2470:7;2479:5;2486:16;2496:5;-1:-1:-1;;;;;1954:16:36;1597:7;1954:16;;;1005:21;1954:16;;;;;:18;;;;;;;;;1537:452;2486:16:32;2435:78;;;;;;19566:25:91;;;;-1:-1:-1;;;;;19627:32:91;;;19607:18;;;19600:60;19696:32;;;;19676:18;;;19669:60;19745:18;;;19738:34;19788:19;;;19781:35;19832:19;;;19825:35;;;19538:19;;2435:78:32;;;;;;;;;;;;2425:89;;;;;;2404:110;;2525:12;2540:28;2557:10;2540:16;:28::i;:::-;2525:43;;2579:14;2596:28;2610:4;2616:1;2619;2622;2596:13;:28::i;:::-;2579:45;;2648:5;-1:-1:-1;;;;;2638:15:32;:6;-1:-1:-1;;;;;2638:15:32;;2634:88;;2676:35;;-1:-1:-1;;;2676:35:32;;-1:-1:-1;;;;;20063:32:91;;;2676:35:32;;;20045:51:91;20132:32;;20112:18;;;20105:60;20018:18;;2676:35:32;19871:300:91;2634:88:32;2732:31;2741:5;2748:7;2757:5;2732:8;:31::i;:::-;2287:483;;;2098:672;;;;;;;:::o;24192:152:83:-;24265:6;392:25:90;:23;:25::i;:::-;-1:-1:-1;;;;;;;;;;;24290:47:83;;24331:5;;24290:47;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;24290:47:83::1;::::0;24192:152;-1:-1:-1;;24192:152:83:o;6481:451::-;6556:7;6575:24;6602:18;6614:5;6602:11;:18::i;:::-;6575:45;;6686:27;-1:-1:-1;;6716:16:83;:37;:139;;6800:55;6817:16;6835:19;6800:16;:55::i;:::-;6716:139;;;-1:-1:-1;;6716:139:83;6686:169;;6872:53;6881:19;6902:22;6918:5;6902:15;:22::i;23720:114::-;23780:15;392:25:90;:23;:25::i;:::-;23814:13:83::1;:11;:13::i;4689:195:31:-:0;-1:-1:-1;;;;;4848:20:31;;;4769:7;4848:20;;;:13;:20;;;;;;;;:29;;;;;;;;;;;;;4689:195::o;13656:104:87:-;13702:4;-1:-1:-1;;;;;;;;;;;13725:22:87;:28;-1:-1:-1;;;;;13725:28:87;;13656:104;-1:-1:-1;13656:104:87:o;10746:211:83:-;3395:21:38;:19;:21::i;:::-;555:4:81::1;4637:20:87;555:4:81::0;4637:14:87::1;:20::i;:::-;10901:49:83::2;10927:22;10901:25;:49::i;11117:147::-:0;3395:21:38;:19;:21::i;:::-;555:4:81::1;4637:20:87;555:4:81::0;4637:14:87::1;:20::i;:::-;11226:31:83::2;11243:13;11226:16;:31::i;8338:147:33:-:0;8407:7;8433:45;8450:6;8458:19;8433:16;:45::i;14462:1054:83:-;3395:21:38;:19;:21::i;:::-;4850:32:87::1;:30;:32::i;:::-;667:28:81::2;4637:20:87;4652:4;4637:14;:20::i;:::-;-1:-1:-1::0;;;;;;;;;;;14721:20:83;;14755:35;;::::3;14751:102;;14799:54;::::0;-1:-1:-1;;;14799:54:83;;::::3;::::0;::::3;16821:25:91::0;;;16862:18;;;16855:34;;;16794:18;;14799:54:83::3;16639:256:91::0;14751:102:83::3;14869:9;14864:390;14888:6;14884:1;:10;14864:390;;;14920:34;14932:18;;14951:1;14932:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;14920:11;:34::i;:::-;14915:95;;14987:18;;15006:1;14987:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;14963:47;::::0;-1:-1:-1;;;14963:47:83;;-1:-1:-1;;;;;6250:32:91;;;14963:47:83::3;::::0;::::3;6232:51:91::0;6205:18;;14963:47:83::3;6086:203:91::0;14915:95:83::3;15029:9;15041:5;:1:::0;15045::::3;15041:5;:::i;:::-;15029:17;;15024:220;15052:6;15048:1;:10;15024:220;;;15112:18;;15131:1;15112:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;15087:46:83::3;:18;;15106:1;15087:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;15087:46:83::3;::::0;15083:147:::3;;15188:18;;15207:1;15188:21;;;;;;;:::i;15083:147::-;15060:3;;15024:220;;;-1:-1:-1::0;14896:3:83::3;;14864:390;;;;15269:9;15264:246;15288:6;15284:1;:10;15264:246;;;15315:18;15336:1;:13;;15350:1;15336:16;;;;;;;;:::i;:::-;;::::0;;;::::3;::::0;;;::::3;::::0;-1:-1:-1;;;;;15336:16:83::3;::::0;-1:-1:-1;15385:18:83;;15404:1;15385:21;;::::3;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;15366:1;:13;;15380:1;15366:16;;;;;;;;:::i;:::-;;;;;;;;;:40;;;;;-1:-1:-1::0;;;;;15366:40:83::3;;;;;-1:-1:-1::0;;;;;15366:40:83::3;;;;;;15497:1;15473:18;;15492:1;15473:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;15425:74:83::3;15451:11;-1:-1:-1::0;;;;;15425:74:83::3;;;;;;;;;;;-1:-1:-1::0;15296:3:83::3;;15264:246;;;;14621:895;;4892:1:87::2;3437:20:38::0;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283;523:133:90;-1:-1:-1;;;;;;;;;;;4476:9:38;1991:1;4476:20;581:68:90;;619:30;;-1:-1:-1;;;619:30:90;;;;;;;;;;;3470:384:38;-1:-1:-1;;;;;;;;;;;3670:9:38;;-1:-1:-1;;3670:20:38;3666:88;;3713:30;;-1:-1:-1;;;3713:30:38;;;;;;;;;;;3666:88;1991:1;3828:19;;3470:384::o;5191:186:31:-;5264:4;966:10:34;5318:31:31;966:10:34;5334:7:31;5343:5;5318:8;:31::i;:::-;-1:-1:-1;5366:4:31;;5191:186;-1:-1:-1;;;5191:186:31:o;3860:283:38:-;1949:1;-1:-1:-1;;;;;;;;;;;4113:23:38;3860:283::o;10972:213:33:-;11069:7;11095:83;11125:23;11069:7;11125:2;:23;:::i;:::-;-1:-1:-1;;;;;;;;;;;4008:14:31;11109:39:33;;;;:::i;:::-;11150:13;:11;:13::i;:::-;:17;;11166:1;11150:17;:::i;:::-;11095:6;;:83;11169:8;11095:13;:83::i;5475:208:87:-;5542:6;:4;:6::i;:::-;-1:-1:-1;;;;;5542:14:87;;5557:4;966:10:34;5542:34:87;;-1:-1:-1;;;;;;5542:34:87;;;;;;;;;;22035:25:91;;;;-1:-1:-1;;;;;22096:32:91;22076:18;;;22069:60;22008:18;;5542:34:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5537:140;;5599:67;;-1:-1:-1;;;5599:67:87;;966:10:34;5599:67:87;;;22596:51:91;22663:18;;;22656:34;;;22569:18;;5599:67:87;22422:274:91;7050:297:87;7210:17;;;7237:35;;;;7287:53;;-1:-1:-1;;;;;;;;;;;2528:24:87;7210:17;7237:35;;7210:17;;7287:53;;7121:26;;7287:53;7111:236;;7050:297;:::o;17184:661:83:-;-1:-1:-1;;;;;17277:32:83;;17273:58;;17318:13;;-1:-1:-1;;;17318:13:83;;;;;;;;;;;17273:58;17345:22;17357:9;17345:11;:22::i;:::-;17341:70;;;17376:35;;-1:-1:-1;;;17376:35:83;;-1:-1:-1;;;;;6250:32:91;;17376:35:83;;;6232:51:91;6205:18;;17376:35:83;6086:203:91;17341:70:83;17446:6;-1:-1:-1;;;;;17425:27:83;:9;-1:-1:-1;;;;;17425:15:83;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;17425:27:83;;;:65;;;;17485:5;-1:-1:-1;;;;;17456:34:83;17464:9;-1:-1:-1;;;;;17464:14:83;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;17456:34:83;;;17425:65;17421:138;;;17513:35;;-1:-1:-1;;;17513:35:83;;-1:-1:-1;;;;;6250:32:91;;17513:35:83;;;6232:51:91;6205:18;;17513:35:83;6086:203:91;17421:138:83;-1:-1:-1;;;;;;;;;;;17642:29:83;;;;;;;-1:-1:-1;17642:29:83;;;;;;;;;-1:-1:-1;;;;;;17642:29:83;-1:-1:-1;;;;;17642:29:83;;;;;;;;17686:33;;17642:29;;17686:33;;;17733:20;;1303:2;-1:-1:-1;17729:109:83;;;17801:20;;17779:59;;-1:-1:-1;;;17779:59:83;;;;;16821:25:91;;;;1303:2:83;16862:18:91;;;16855:34;16794:18;;17779:59:83;16639:256:91;5795:100:87;5847:41;5859:13;-1:-1:-1;;;;;;;;;;;4008:14:31;;3877:152;5859:13:87;5874;:11;:13::i;:::-;5847:41;;;16821:25:91;;;16877:2;16862:18;;16855:34;;;;16794:18;5847:41:87;;;;;;;5795:100::o;5969:244:31:-;6056:4;966:10:34;6112:37:31;6128:4;966:10:34;6143:5:31;6112:15;:37::i;:::-;6159:26;6169:4;6175:2;6179:5;6159:9;:26::i;:::-;-1:-1:-1;6202:4:31;;5969:244;-1:-1:-1;;;;5969:244:31:o;9071:205:29:-;9129:30;;3147:66;9186:27;8819:122;2153:221:89;6929:20:29;:18;:20::i;:::-;2277:31:89::1;2294:13;2277:16;:31::i;:::-;2318:49;2344:22;2318:25;:49::i;18839:543:83:-:0;1986:4:87;18940:28:83;:38;18936:106;;;18987:55;;-1:-1:-1;;;18987:55:83;;;;;160:25:91;;;133:18;;18987:55:83;14:177:91;18936:106:83;19167:30;;;19207:61;;;;19283:92;;;16821:25:91;;;16877:2;16862:18;;16855:34;;;-1:-1:-1;;;;;;;;;;;2048:30:83;19167;19283:92;;16794:18:91;19283:92:83;;;;;;;;18926:456;;18839:543;:::o;25446:331::-;-1:-1:-1;;;;;;;;;;;25612:20:83;;25506:4;;2048:30;25506:4;25642:107;25666:6;25662:1;:10;25642:107;;;25717:8;-1:-1:-1;;;;;25697:28:83;:1;:13;;25711:1;25697:16;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;25697:16:83;:28;25693:45;;-1:-1:-1;25734:4:83;;25446:331;-1:-1:-1;;;;25446:331:83:o;25693:45::-;25674:3;;25642:107;;;-1:-1:-1;25765:5:83;;25446:331;-1:-1:-1;;;;25446:331:83:o;6617:221:33:-;6709:5;;4209:22;6726:47;-1:-1:-1;1157:7:34;6790:21:33;;:41;;;-1:-1:-1;;;6790:21:33;;;;:41;:::i;:::-;6783:48;;;6617:221;:::o;4015:109:39:-;4068:7;4094:23;:21;:23::i;3478:178:37:-;2226:16;:14;:16::i;:::-;-1:-1:-1;;;;;;;;;;;3595:17:37;;-1:-1:-1;;3595:17:37::1;::::0;;3627:22:::1;966:10:34::0;3636:12:37::1;3627:22;::::0;-1:-1:-1;;;;;6250:32:91;;;6232:51;;6220:2;6205:18;3627:22:37::1;;;;;;;3526:130;3478:178::o:0;20163:359:83:-;-1:-1:-1;;;;;;;;;;;20339:20:83;;20220:17;;2048:30;20220:17;20369:147;20393:6;20389:1;:10;20369:147;;;20432:73;20451:9;20462:1;:13;;20476:1;20462:16;;;;;;;;:::i;:::-;;;;;;;;;;;:42;;-1:-1:-1;;;20462:42:83;;20498:4;20462:42;;;6232:51:91;-1:-1:-1;;;;;20462:16:83;;;;:27;;6205:18:91;;20462:42:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20432:18;:73::i;:::-;20420:85;-1:-1:-1;20401:3:83;;20369:147;;11540:318:87;11686:7;11716:21;:19;:21::i;:::-;:135;;-1:-1:-1;;11768:17:87;:15;:17::i;:::-;:38;:83;;11838:13;:11;:13::i;:::-;11716:135;;11768:83;-1:-1:-1;;11716:135:87;;;11752:1;11709:142;11540:318;-1:-1:-1;;11540:318:87:o;5617:111:76:-;5675:7;5312:5;;;5709;;;5311:36;5306:42;;5701:20;5071:294;13987:120:87;14036:7;-1:-1:-1;;;;;;;;;;;14062:22:87;:38;;;14055:45;;13987:120;:::o;8360:141:89:-;8416:7;-1:-1:-1;;;;;;;;;;;8442:29:89;1114:186;11309:213:33;11406:7;11432:83;11446:13;:11;:13::i;:::-;:17;;11462:1;11446:17;:::i;:::-;11481:23;1157:7:34;11481:2:33;:23;:::i;:::-;-1:-1:-1;;;;;;;;;;;4008:14:31;11465:39:33;;;;:::i;4578:312:30:-;4658:4;-1:-1:-1;;;;;4667:6:30;4650:23;;;:120;;;4764:6;-1:-1:-1;;;;;4728:42:30;:32;:30;:32::i;:::-;-1:-1:-1;;;;;4728:42:30;;;4650:120;4633:251;;;4844:29;;-1:-1:-1;;;4844:29:30;;;;;;;;;;;5239:103:87;555:4:81;4637:20:87;555:4:81;4637:14:87;:20::i;6032:538:30:-;6149:17;-1:-1:-1;;;;;6131:50:30;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6131:52:30;;;;;;;;-1:-1:-1;;6131:52:30;;;;;;;;;;;;:::i;:::-;;;6127:437;;6493:60;;-1:-1:-1;;;6493:60:30;;-1:-1:-1;;;;;6250:32:91;;6493:60:30;;;6232:51:91;6205:18;;6493:60:30;6086:203:91;6127:437:30;-1:-1:-1;;;;;;;;;;;6225:40:30;;6221:120;;6292:34;;-1:-1:-1;;;6292:34:30;;;;;160:25:91;;;133:18;;6292:34:30;14:177:91;6221:120:30;6354:54;6384:17;6403:4;6354:29;:54::i;:::-;6184:235;6032:538;;:::o;5007:213::-;5081:4;-1:-1:-1;;;;;5090:6:30;5073:23;;5069:145;;5174:29;;-1:-1:-1;;;5174:29:30;;;;;;;;;;;6019:122:87;6089:21;:19;:21::i;:::-;6085:49;;;6119:15;;-1:-1:-1;;;6119:15:87;;;;;;;;;;;24921:152:83;24983:7;-1:-1:-1;;;;;;;;;;;25009:28:83;1911:183;22183:1413;22437:35;;-1:-1:-1;;;22437:35:83;;22466:4;22437:35;;;6232:51:91;22305:20:83;;-1:-1:-1;;;;;22410:26:83;;;;;;;22437:20;;6205:18:91;;22437:35:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22410:63;;;;;;;;;;;;;160:25:91;;148:2;133:18;;14:177;22410:63:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22357:37;;-1:-1:-1;;;22357:37:83;;22388:4;22357:37;;;6232:51:91;-1:-1:-1;;;;;22328:28:83;;;;;;;22357:22;;6205:18:91;;22357:37:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22328:67;;;;;;;;;;;;;160:25:91;;148:2;133:18;;14:177;22328:67:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:145;;;;:::i;:::-;22305:168;;22484:21;22515:7;:5;:7::i;:::-;22508:40;;-1:-1:-1;;;22508:40:83;;22542:4;22508:40;;;6232:51:91;-1:-1:-1;;;;;22508:25:83;;;;;;;6205:18:91;;22508:40:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22484:64;-1:-1:-1;22562:10:83;;22558:155;;22643:59;;-1:-1:-1;;;22643:59:83;;;;;23515:25:91;;;22681:4:83;23556:18:91;;;23549:60;;;23625:18;;;23618:60;-1:-1:-1;;;;;22643:21:83;;;;;23488:18:91;;22643:59:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;22558:155;22722:20;22752:7;:5;:7::i;:::-;22745:40;;-1:-1:-1;;;22745:40:83;;22779:4;22745:40;;;6232:51:91;-1:-1:-1;;;;;22745:25:83;;;;;;;6205:18:91;;22745:40:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22722:63;-1:-1:-1;22795:14:83;22812:28;22827:13;22722:63;22812:28;:::i;:::-;22795:45;-1:-1:-1;22855:10:83;;22851:208;;22881:57;22918:10;22931:6;22888:7;:5;:7::i;:::-;-1:-1:-1;;;;;22881:28:83;;:57;:28;:57::i;:::-;23007:41;;-1:-1:-1;;;23007:41:83;;;;;22035:25:91;;;23042:4:83;22076:18:91;;;22069:60;-1:-1:-1;;;;;23007:18:83;;;;;22008::91;;23007:41:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;22851:208;23200:35;;-1:-1:-1;;;23200:35:83;;23229:4;23200:35;;;6232:51:91;23069:19:83;;-1:-1:-1;;;;;23173:26:83;;;;;;;23200:20;;6205:18:91;;23200:35:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23173:63;;;;;;;;;;;;;160:25:91;;148:2;133:18;;14:177;23173:63:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23120:37;;-1:-1:-1;;;23120:37:83;;23151:4;23120:37;;;6232:51:91;-1:-1:-1;;;;;23091:28:83;;;;;;;23120:22;;6205:18:91;;23120:37:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23091:67;;;;;;;;;;;;;160:25:91;;148:2;133:18;;14:177;23091:67:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:145;;;;:::i;:::-;23069:167;;23247:16;23266:48;23278:18;23298:6;1986:4:87;23266:11:83;:48::i;:::-;23247:67;-1:-1:-1;23343:22:83;23354:11;23247:67;23343:22;:::i;:::-;23328:12;:37;23324:168;;;23388:93;;-1:-1:-1;;;23388:93:83;;;;;24227:25:91;;;24268:18;;;24261:34;;;24311:18;;;24304:34;;;24354:18;;;24347:34;;;24397:19;;;24390:35;;;24199:19;;23388:93:83;23968:463:91;23324:168:83;23549:10;-1:-1:-1;;;;;23507:82:83;23526:12;-1:-1:-1;;;;;23507:82:83;;23562:6;23570:18;23507:82;;;;;;16821:25:91;;;16877:2;16862:18;;16855:34;16809:2;16794:18;;16639:256;23507:82:83;;;;;;;;22295:1301;;;;;;22183:1413;;;;:::o;4991:969:89:-;5119:24;;-1:-1:-1;;;;;;;;;;;1253:31:89;5040:33;5119:29;5115:42;;5150:7;4991:969::o;5115:42::-;5167:18;5188:6;:4;:6::i;:::-;5234:16;;5167:27;;-1:-1:-1;5264:32:89;;;5260:694;;;5312:29;5344:32;5357:19;5344:10;:32;:::i;:::-;5312:64;;5390:25;5418:58;5430:21;5453:13;-1:-1:-1;;;;;;;;;;;4008:14:31;;3877:152;5453:13:89;1986:4:87;5418:11:89;:58::i;:::-;5390:86;;5490:17;5510:65;5522:17;5541:1;:24;;;1986:4:87;5510:11:89;:65::i;:::-;5490:85;-1:-1:-1;5589:17:89;5625:94;5490:85;5664:23;5589:17;5664:2;:23;:::i;:::-;-1:-1:-1;;;;;;;;;;;4008:14:31;5648:39:89;;;;:::i;:::-;5709:9;5689:13;:11;:13::i;:::-;:17;;5705:1;5689:17;:::i;:::-;:29;;;;:::i;:::-;5625:11;:94::i;:::-;5589:130;-1:-1:-1;5738:13:89;;5734:210;;5777:15;;;;5771:33;;-1:-1:-1;;;;;5777:15:89;5794:9;5771:5;:33::i;:::-;5822:25;5840:6;:4;:6::i;:::-;5822:17;:25::i;:::-;5891:15;;;;5870:59;;;16821:25:91;;;16877:2;16862:18;;16855:34;;;-1:-1:-1;;;;;5891:15:89;;;;5870:59;;16794:18:91;5870:59:89;;;;;;;5734:210;5298:656;;;;5030:930;;;4991:969::o;9387:256:87:-;9575:7;4850:32;:30;:32::i;:::-;9605:31:::2;9619:6;9627:8;9605:13;:31::i;:::-;9598:38;;5071:18:::1;:16;:18::i;1259:164:36:-:0;1319:7;;1005:21;1364:19;886:156;3170:176:37;1979:19;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;3288:16:37;;-1:-1:-1;;3288:16:37::1;3300:4;3288:16;::::0;;3319:20:::1;966:10:34::0;3326:12:37::1;887:96:34::0;6299:155:39;6440:7;6433:14;;6353:13;;-1:-1:-1;;;;;;;;;;;2839:21:39;6433:14;;;:::i;6681:161::-;6738:13;6763:23;-1:-1:-1;;;;;;;;;;;6789:19:39;2720:156;9688:250:87;9873:7;4850:32;:30;:32::i;:::-;9903:28:::2;9914:6;9922:8;9903:10;:28::i;5095:114:33:-:0;6929:20:29;:18;:20::i;:::-;5170:32:33::1;5195:6;5170:24;:32::i;2263:147:31:-:0;6929:20:29;:18;:20::i;:::-;2365:38:31::1;2388:5;2395:7;2365:22;:38::i;1832:125:32:-:0;6929:20:29;:18;:20::i;:::-;1916:34:32::1;1940:4;1916:34;;;;;;;;;;;;;-1:-1:-1::0;;;1916:34:32::1;;::::0;:23:::1;:34::i;2684:111:38:-:0;6929:20:29;:18;:20::i;:::-;2754:34:38::1;:32;:34::i;2266:60:37:-:0;6929:20:29;:18;:20::i;7570:442:87:-;7692:4;7665:16;7727:20;7692:4;7727:10;:20::i;:::-;7707:40;;7783:9;7761:19;:31;7757:111;;;7827:8;7837:19;7858:9;7801:67;;-1:-1:-1;;;7801:67:87;;;;;;;;;;:::i;7757:111::-;7879:14;7896:35;7911:19;7896:14;:35::i;:::-;7879:52;;7941:64;7950:15;7967:8;7977:19;7998:6;7941:8;:64::i;:::-;7655:357;;;7570:442;;:::o;4453:178:31:-;4522:4;966:10:34;4576:27:31;966:10:34;4593:2:31;4597:5;4576:9;:27::i;18144:532:83:-;-1:-1:-1;;;;;;;;;;;18204:32:83;18277:393;18301:20;;18297:24;;18277:393;;;18366:8;-1:-1:-1;;;;;18346:28:83;:1;:13;;18360:1;18346:16;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;18346:16:83;:28;18342:318;;18411:1;18394:135;18418:20;;:24;;18441:1;;18418:24;:::i;:::-;18414:1;:28;18394:135;;;18490:1;18504:5;:1;18508;18504:5;:::i;:::-;18490:20;;;;;;;;:::i;:::-;;;;;;;;;;;18471:16;;-1:-1:-1;;;;;18490:20:83;;;;18471:1;;18485;;18471:16;;;;;;:::i;:::-;;;;;;;;;;:39;;-1:-1:-1;;;;;;18471:39:83;-1:-1:-1;;;;;18471:39:83;;;;;;;;;;-1:-1:-1;18444:3:83;18394:135;;;-1:-1:-1;18546:19:83;;:1;;:19;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;18546:19:83;;;;;-1:-1:-1;;;;;;18546:19:83;;;;;;;;;18588:34;;-1:-1:-1;;;;;18588:34:83;;;;;;6184:235:30;6032:538;;:::o;18342:318:83:-;18323:3;;18277:393;;3916:253:63;3999:12;4024;4038:23;4065:6;-1:-1:-1;;;;;4065:19:63;4085:4;4065:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4023:67;;;;4107:55;4134:6;4142:7;4151:10;4107:26;:55::i;:::-;4100:62;3916:253;-1:-1:-1;;;;;3916:253:63:o;9983:280:87:-;10187:7;4850:32;:30;:32::i;:::-;10217:39:::2;10232:6;10240:8;10250:5;10217:14;:39::i;:::-;10210:46;;5071:18:::1;:16;:18::i;10308:276::-:0;10510:7;4850:32;:30;:32::i;:::-;10540:37:::2;10553:6;10561:8;10571:5;10540:12;:37::i;11903:339::-:0;12006:7;12032:21;:19;:21::i;:::-;:203;;-1:-1:-1;;12084:17:87;:15;:17::i;:::-;:38;:151;;12183:52;12200:13;:11;:13::i;:::-;12215:19;12183:16;:52::i;21312:363:83:-;-1:-1:-1;;;;;;;;;;;21491:20:83;;21372:17;;2048:30;21372:17;21521:148;21545:6;21541:1;:10;21521:148;;;21584:74;21603:9;21614:1;:13;;21628:1;21614:16;;;;;;;;:::i;:::-;;;;;;;;;;;:43;;-1:-1:-1;;;21614:43:83;;21651:4;21614:43;;;6232:51:91;-1:-1:-1;;;;;21614:16:83;;;;:28;;6205:18:91;;21614:43:83;6086:203:91;21584:74:83;21572:86;-1:-1:-1;21553:3:83;;21521:148;;12287:189:87;12391:7;12417:21;:19;:21::i;:::-;:52;;12445:24;12463:5;12445:17;:24::i;4946:176:39:-;5023:7;5049:66;5082:20;:18;:20::i;:::-;5104:10;4049:4:73;4043:11;-1:-1:-1;;;4067:23:73;;4119:4;4110:14;;4103:39;;;;4171:4;4162:14;;4155:34;4227:4;4212:20;;;3874:374;6887:260:72;6972:7;6992:17;7011:18;7031:16;7051:25;7062:4;7068:1;7071;7074;7051:10;:25::i;:::-;6991:85;;;;;;7086:28;7098:5;7105:8;7086:11;:28::i;:::-;-1:-1:-1;7131:9:72;;6887:260;-1:-1:-1;;;;;;6887:260:72:o;9982:128:31:-;10066:37;10075:5;10082:7;10091:5;10098:4;10066:8;:37::i;12521:185:87:-;12623:7;12649:21;:19;:21::i;:::-;:50;;12677:22;12693:5;12677:15;:22::i;23909:126:83:-;23954:15;-1:-1:-1;;;;;;;;;;;23981:47:83;;;;;;;;;;;;;;;;;;;;23988:40;23981:47;;;23988:40;23981:47;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23981:47:83;;;;;;;;;;;;;;;;;;;;;;;23909:126;:::o;2826:887:89:-;617:6;2916:22;:56;2912:179;;;2995:85;;-1:-1:-1;;;2995:85:89;;;;;16821:25:91;;;617:6:89;16862:18:91;;;16855:34;16794:18;;2995:85:89;16639:256:91;2912:179:89;3214:24;;-1:-1:-1;;;;;;;;;;;3278:16:89;;1253:31;;3214:24;3101:33;3325:6;:4;:6::i;:::-;3304:27;-1:-1:-1;3401:32:89;;:62;;;;;3462:1;3437:22;:26;3401:62;:98;;;;;3489:10;3467:19;:32;3401:98;3397:158;;;3515:29;3533:10;3515:17;:29::i;:::-;3565:24;;;:49;;;3629:77;;3592:22;;3654:27;;3629:77;;;;;2902:811;;;;2826:887;:::o;3809:364::-;-1:-1:-1;;;;;3881:27:89;;3877:53;;3917:13;;-1:-1:-1;;;3917:13:89;;;;;;;;;;;3877:53;4045:15;;;-1:-1:-1;;;;;;4070:31:89;;-1:-1:-1;;;;;4070:31:89;;;;;;;;;4116:50;;-1:-1:-1;;;;;;;;;;;1253:31:89;4045:15;;;;;;4116:50;;3941:33;;4116:50;3867:306;;3809:364;:::o;11054:238:76:-;11155:7;11209:76;11225:26;11242:8;11225:16;:26::i;:::-;:59;;;;;11283:1;11268:11;11255:25;;;;;:::i;:::-;11265:1;11262;11255:25;:29;11225:59;34914:9:77;34907:17;;34795:145;11209:76:76;11181:25;11188:1;11191;11194:11;11181:6;:25::i;:::-;:104;;;;:::i;11726:476:31:-;11825:24;11852:25;11862:5;11869:7;11852:9;:25::i;:::-;11825:52;;-1:-1:-1;;11891:16:31;:36;11887:309;;;11966:5;11947:16;:24;11943:130;;;12025:7;12034:16;12052:5;11998:60;;-1:-1:-1;;;11998:60:31;;;;;;;;;;:::i;11943:130::-;12114:57;12123:5;12130:7;12158:5;12139:16;:24;12165:5;12114:8;:57::i;6586:300::-;-1:-1:-1;;;;;6669:18:31;;6665:86;;6710:30;;-1:-1:-1;;;6710:30:31;;6737:1;6710:30;;;6232:51:91;6205:18;;6710:30:31;6086:203:91;6665:86:31;-1:-1:-1;;;;;6764:16:31;;6760:86;;6803:32;;-1:-1:-1;;;6803:32:31;;6832:1;6803:32;;;6232:51:91;6205:18;;6803:32:31;6086:203:91;6760:86:31;6855:24;6863:4;6869:2;6873:5;6855:7;:24::i;7082:141:29:-;7149:17;:15;:17::i;:::-;7144:73;;7189:17;;-1:-1:-1;;;7189:17:29;;;;;;;;;;;4130:191:39;4185:7;2073:95;4243:17;:15;:17::i;:::-;4262:20;:18;:20::i;:::-;4221:92;;;;;;25503:25:91;;;;25544:18;;25537:34;;;;25587:18;;;25580:34;4284:13:39;25630:18:91;;;25623:34;4307:4:39;25673:19:91;;;25666:61;25475:19;;4221:92:39;;;;;;;;;;;;4211:103;;;;;;4204:110;;4130:191;:::o;2909:126:37:-;-1:-1:-1;;;;;;;;;;;2625:9:37;;;2967:62;;3003:15;;-1:-1:-1;;;3003:15:37;;;;;;;;;;;3912:199:76;3980:7;4000:12;4014:14;4032:12;4039:1;4042;4032:6;:12::i;:::-;3999:45;;-1:-1:-1;3999:45:76;-1:-1:-1;;;5312:5:76;;;34914:9:77;;34907:17;5311:36:76;5306:42;4061:43;5071:294;8146:110:87;8199:4;8222:8;-1:-1:-1;;;;;;;;;;;2625:9:37;;;;2496:145;8222:8:87;:27;;;;8234:6;:4;:6::i;:::-;-1:-1:-1;;;;;8234:13:87;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;13471:130::-;13516:7;13542:52;13561:17;:15;:17::i;:::-;13580:13;:11;:13::i;:::-;13542:18;:52::i;1441:138:53:-;1493:7;-1:-1:-1;;;;;;;;;;;1519:47:53;1899:163:70;2264:344:53;2355:37;2374:17;2355:18;:37::i;:::-;2407:36;;-1:-1:-1;;;;;2407:36:53;;;;;;;;2458:11;;:15;2454:148;;2489:53;2518:17;2537:4;2489:28;:53::i;2454:148::-;2573:18;:16;:18::i;5084:380:60:-;5199:47;;;-1:-1:-1;;;;;22614:32:91;;5199:47:60;;;22596:51:91;22663:18;;;;22656:34;;;5199:47:60;;;;;;;;;;22569:18:91;;;;5199:47:60;;;;;;;;-1:-1:-1;;;;;5199:47:60;-1:-1:-1;;;5199:47:60;;;5262:44;5214:13;5199:47;5262:23;:44::i;:::-;5257:201;;5349:43;;-1:-1:-1;;;;;22614:32:91;;;5349:43:60;;;22596:51:91;5389:1:60;22663:18:91;;;22656:34;5322:71:60;;5342:5;;5364:13;;;;;22569:18:91;;5349:43:60;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5349:43:60;;;;;;;;;;;5322:19;:71::i;:::-;5407:40;5427:5;5434:12;5407:19;:40::i;7242:3683:76:-;7324:14;7375:12;7389:11;7404:12;7411:1;7414;7404:6;:12::i;:::-;7374:42;;;;7498:4;7506:1;7498:9;7494:365;;7833:11;7827:3;:17;;;;;:::i;:::-;;7820:24;;;;;;7494:365;7984:4;7969:11;:19;7965:142;;8008:84;5312:5;8028:16;;5311:36;940:4:68;5306:42:76;8008:11;:84::i;:::-;8359:17;8510:11;8507:1;8504;8497:25;8902:12;8932:15;;;8917:31;;9067:22;;;;;9800:1;9781;:15;;9780:21;;10033;;;10029:25;;10018:36;10103:21;;;10099:25;;10088:36;10175:21;;;10171:25;;10160:36;10246:21;;;10242:25;;10231:36;10319:21;;;10315:25;;10304:36;10393:21;;;10389:25;;;10378:36;9309:12;;;;9305:23;;;9330:1;9301:31;8622:18;;;8612:29;;;9416:11;;;;8665:19;;;;9160:14;;;;9409:18;;;;10868:13;;-1:-1:-1;;7242:3683:76;;;;;:::o;4240:240:89:-;4278:7;4297:20;4320:13;:11;:13::i;:::-;4297:36;;4343:20;4366:13;-1:-1:-1;;;;;;;;;;;4008:14:31;;3877:152;4366:13:89;4343:36;;4411:1;4396:12;:16;:77;;1986:4:87;4396:77:89;;;4415:48;4427:12;1986:4:87;4450:12:89;4415:11;:48::i;:::-;4389:84;;;;4240:240;:::o;8714:208:31:-;-1:-1:-1;;;;;8784:21:31;;8780:91;;8828:32;;-1:-1:-1;;;8828:32:31;;8857:1;8828:32;;;6232:51:91;6205:18;;8828:32:31;6086:203:91;8780:91:31;8880:35;8896:1;8900:7;8909:5;8880:7;:35::i;6061:313:89:-;-1:-1:-1;;;;;;;;;;;6236:16:89;;6262:33;;;6310:57;;;16821:25:91;;;16877:2;16862:18;;16855:34;;;6310:57:89;;16794:18:91;6310:57:89;16639:256:91;9123:392:33;9198:7;9217:17;9237:20;9248:8;9237:10;:20::i;:::-;9217:40;;9280:9;9271:6;:18;9267:110;;;9338:8;9348:6;9356:9;9312:54;;-1:-1:-1;;;9312:54:33;;;;;;;;;;:::i;9267:110::-;9387:14;9404:22;9419:6;9404:14;:22::i;:::-;9387:39;-1:-1:-1;9436:48:33;966:10:34;9459:8:33;9469:6;9477;9436:8;:48::i;2709:128:37:-;-1:-1:-1;;;;;;;;;;;2625:9:37;;;2774:8;2496:145;9558:380:33;9630:7;9649:17;9669;9677:8;9669:7;:17::i;:::-;9649:37;;9709:9;9700:6;:18;9696:107;;;9764:8;9774:6;9782:9;9741:51;;-1:-1:-1;;;9741:51:33;;;;;;;;;;:::i;9696:107::-;9813:14;9830:19;9842:6;9830:11;:19::i;:::-;9813:36;-1:-1:-1;9859:48:33;966:10:34;9882:8:33;9892:6;9900;9859:8;:48::i;5215:304::-;6929:20:29;:18;:20::i;:::-;4209:22:33;5300:24:::1;::::0;5395:28:::1;5416:6:::0;5395:20:::1;:28::i;:::-;5357:66;;;;5457:7;:28;;5483:2;5457:28;;;5467:13;5457:28;5433:52:::0;;-1:-1:-1;;;;;;5495:17:33;-1:-1:-1;;;5433:52:33::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;;5495:17:33;;-1:-1:-1;;;;;5495:17:33;;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;;5215:304:33:o;2416:216:31:-;6929:20:29;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;2581:7:31;:15:::1;2591:5:::0;2581:7;:15:::1;:::i;:::-;-1:-1:-1::0;2606:9:31::1;::::0;::::1;:19;2618:7:::0;2606:9;:19:::1;:::i;3599:330:39:-:0;6929:20:29;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;3766:7:39;:14:::1;3776:4:::0;3766:7;:14:::1;:::i;:::-;-1:-1:-1::0;3790:10:39::1;::::0;::::1;:20;3803:7:::0;3790:10;:20:::1;:::i;:::-;-1:-1:-1::0;3891:1:39::1;3875:17:::0;;;3902:16:::1;::::0;;::::1;:20:::0;-1:-1:-1;;3599:330:39:o;2801:183:38:-;6929:20:29;:18;:20::i;7704:1408:83:-;7820:17;:15;:17::i;:::-;7816:92;;;-1:-1:-1;7891:6:83;7816:92;7918:48;7933:6;7941:8;7951:6;7959;7918:14;:48::i;:::-;-1:-1:-1;;;;;;;;;;;8110:20:83;;8003:6;;2048:30;7977:23;8140:866;8164:6;8160:1;:10;8140:866;;;8251:31;;8277:5;8251:31;8297:15;8315:1;:13;;8329:1;8315:16;;;;;;;;:::i;:::-;;;;;;;;;;8374:34;;-1:-1:-1;;;8374:34:83;;8402:4;8374:34;;;6232:51:91;-1:-1:-1;;;;;8315:16:83;;;;-1:-1:-1;8315:16:83;;8374:19;;6205:18:91;;8374:34:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8345:63;;8422:21;8446:45;8455:15;8472:18;8446:8;:45::i;:::-;8422:69;-1:-1:-1;8510:17:83;;8506:490;;8547:62;8584:8;8595:13;8554:7;:5;:7::i;8547:62::-;8690:46;;-1:-1:-1;;;8690:46:83;;;;;22035:25:91;;;8730:4:83;22076:18:91;;;22069:60;-1:-1:-1;;;;;8690:16:83;;;;;22008:18:91;;8690:46:83;;;;;;;;;;;;;;;;;;;-1:-1:-1;8690:46:83;;;;;;;;-1:-1:-1;;8690:46:83;;;;;;;;;;;;:::i;:::-;;;8686:296;;8866:8;-1:-1:-1;;;;;8844:47:83;;8877:13;8844:47;;;;160:25:91;;148:2;133:18;;14:177;8844:47:83;;;;;;;;8913:50;8950:8;8961:1;8920:7;:5;:7::i;8913:50::-;8686:296;;;-1:-1:-1;8759:32:83;8778:13;8759:32;;:::i;:::-;;;8686:296;8177:829;;;8172:3;;;;;8140:866;;;-1:-1:-1;9019:19:83;;9015:90;;9047:58;;-1:-1:-1;;;9047:58:83;;;;;28630:25:91;;;28671:18;;;28664:34;;;28714:18;;;28707:34;;;28603:18;;9047:58:83;28428:319:91;4437:582:63;4581:12;4610:7;4605:408;;4633:19;4641:10;4633:7;:19::i;:::-;4605:408;;;4857:17;;:22;:49;;;;-1:-1:-1;;;;;;4883:18:63;;;:23;4857:49;4853:119;;;4933:24;;-1:-1:-1;;;4933:24:63;;-1:-1:-1;;;;;6250:32:91;;4933:24:63;;;6232:51:91;6205:18;;4933:24:63;6086:203:91;4853:119:63;-1:-1:-1;4992:10:63;4985:17;;9985:413:33;10076:7;10095:17;10115:18;10127:5;10115:11;:18::i;:::-;10095:38;;10156:9;10147:6;:18;10143:108;;;10215:5;10222:6;10230:9;10188:52;;-1:-1:-1;;;10188:52:33;;;;;;;;;;:::i;10143:108::-;10261:14;10278:23;10294:6;10278:15;:23::i;:::-;10261:40;-1:-1:-1;10311:56:33;966:10:34;10335:8:33;10345:5;10352:6;10360;10311:9;:56::i;10443:405::-;10532:7;10551:17;10571:16;10581:5;10571:9;:16::i;:::-;10551:36;;10610:9;10601:6;:18;10597:106;;;10667:5;10674:6;10682:9;10642:50;;-1:-1:-1;;;10642:50:33;;;;;;;;;;:::i;10597:106::-;10713:14;10730:21;10744:6;10730:13;:21::i;:::-;10713:38;-1:-1:-1;10761:56:33;966:10:34;10785:8:33;10795:5;10802:6;10810;10761:9;:56::i;7972:153::-;8037:7;8063:55;8080:16;8090:5;8080:9;:16::i;:::-;8098:19;8063:16;:55::i;5203:1551:72:-;5329:17;;;6283:66;6270:79;;6266:164;;;-1:-1:-1;6381:1:72;;-1:-1:-1;6385:30:72;;-1:-1:-1;6417:1:72;6365:54;;6266:164;6541:24;;;6524:14;6541:24;;;;;;;;;28979:25:91;;;29052:4;29040:17;;29020:18;;;29013:45;;;;29074:18;;;29067:34;;;29117:18;;;29110:34;;;6541:24:72;;28951:19:91;;6541:24:72;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6541:24:72;;-1:-1:-1;;6541:24:72;;;-1:-1:-1;;;;;;;6579:20:72;;6575:113;;-1:-1:-1;6631:1:72;;-1:-1:-1;6635:29:72;;-1:-1:-1;6631:1:72;;-1:-1:-1;6615:62:72;;6575:113;6706:6;-1:-1:-1;6714:20:72;;-1:-1:-1;6714:20:72;;-1:-1:-1;5203:1551:72;;;;;;;;;:::o;7280:532::-;7375:20;7366:5;:29;;;;;;;;:::i;:::-;;7362:444;;7280:532;;:::o;7362:444::-;7471:29;7462:5;:38;;;;;;;;:::i;:::-;;7458:348;;7523:23;;-1:-1:-1;;;7523:23:72;;;;;;;;;;;7458:348;7576:35;7567:5;:44;;;;;;;;:::i;:::-;;7563:243;;7634:46;;-1:-1:-1;;;7634:46:72;;;;;160:25:91;;;133:18;;7634:46:72;14:177:91;7563:243:72;7710:30;7701:5;:39;;;;;;;;:::i;:::-;;7697:109;;7763:32;;-1:-1:-1;;;7763:32:72;;;;;160:25:91;;;133:18;;7763:32:72;14:177:91;10957:487:31;-1:-1:-1;;;;;;;;;;;;;;;;11122:19:31;;11118:89;;11164:32;;-1:-1:-1;;;11164:32:31;;11193:1;11164:32;;;6232:51:91;6205:18;;11164:32:31;6086:203:91;11118:89:31;-1:-1:-1;;;;;11220:21:31;;11216:90;;11264:31;;-1:-1:-1;;;11264:31:31;;11292:1;11264:31;;;6232:51:91;6205:18;;11264:31:31;6086:203:91;11216:90:31;-1:-1:-1;;;;;11315:20:31;;;;;;;:13;;;:20;;;;;;;;:29;;;;;;;;;:37;;;11362:76;;;;11412:7;-1:-1:-1;;;;;11396:31:31;11405:5;-1:-1:-1;;;;;11396:31:31;;11421:5;11396:31;;;;160:25:91;;148:2;133:18;;14:177;11396:31:31;;;;;;;;11055:389;10957:487;;;;:::o;8173:112:33:-;8236:7;8262:16;8272:5;8262:9;:16::i;32020:122:76:-;32088:4;32129:1;32117:8;32111:15;;;;;;;;:::i;:::-;:19;;;;:::i;:::-;:24;;32134:1;32111:24;32104:31;;32020:122;;;:::o;7201:1170:31:-;-1:-1:-1;;;;;;;;;;;;;;;;7343:18:31;;7339:546;;7497:5;7479:1;:14;;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;7339:546:31;;-1:-1:-1;7339:546:31;;-1:-1:-1;;;;;7555:17:31;;7533:19;7555:17;;;;;;;;;;;7590:19;;;7586:115;;;7661:4;7667:11;7680:5;7636:50;;-1:-1:-1;;;7636:50:31;;;;;;;;;;:::i;7586:115::-;-1:-1:-1;;;;;7821:17:31;;:11;:17;;;;;;;;;;7841:19;;;;7821:39;;7339:546;-1:-1:-1;;;;;7899:16:31;;7895:429;;8062:14;;;:23;;;;;;;7895:429;;;-1:-1:-1;;;;;8275:15:31;;:11;:15;;;;;;;;;;:24;;;;;;7895:429;8354:2;-1:-1:-1;;;;;8339:25:31;8348:4;-1:-1:-1;;;;;8339:25:31;;8358:5;8339:25;;;;160::91;;148:2;133:18;;14:177;8339:25:31;;;;;;;;7276:1095;7201:1170;;;:::o;8485:120:29:-;8535:4;8558:26;:24;:26::i;:::-;:40;-1:-1:-1;;;8558:40:29;;;;;;-1:-1:-1;8485:120:29:o;7057:687:39:-;7107:7;-1:-1:-1;;;;;;;;;;;7107:7:39;7202:13;:11;:13::i;:::-;7229:18;;7181:34;;-1:-1:-1;7229:22:39;7225:513;;7274:22;;;;;;;;7057:687;-1:-1:-1;;7057:687:39:o;7225:513::-;7571:13;;7602:15;;7598:130;;7644:10;7057:687;-1:-1:-1;;;7057:687:39:o;7598:130::-;7700:13;7693:20;;;;;7057:687;:::o;7965:723::-;8018:7;-1:-1:-1;;;;;;;;;;;8018:7:39;8116:16;:14;:16::i;:::-;8146:21;;8092:40;;-1:-1:-1;8146:25:39;8142:540;;8194:25;;;;;;;;7965:723;-1:-1:-1;;7965:723:39:o;8142:540::-;8506:16;;;;8540:18;;8536:136;;8585:13;7965:723;-1:-1:-1;;;7965:723:39:o;1693:240:76:-;1830:5;;;1859:6;;;;;1754:12;;1859:6;1892:24;1888:1;:28;1879:37;;1794:133;1693:240;;;;;:::o;4217:150::-;4285:7;4307:14;4325:12;4332:1;4335;4325:6;:12::i;1671:281:53:-;1748:17;-1:-1:-1;;;;;1748:29:53;;1781:1;1748:34;1744:119;;1805:47;;-1:-1:-1;;;1805:47:53;;-1:-1:-1;;;;;6250:32:91;;1805:47:53;;;6232:51:91;6205:18;;1805:47:53;6086:203:91;1744:119:53;-1:-1:-1;;;;;;;;;;;1872:73:53;;-1:-1:-1;;;;;;1872:73:53;-1:-1:-1;;;;;1872:73:53;;;;;;;;;;1671:281::o;6113:122::-;6163:9;:13;6159:70;;6199:19;;-1:-1:-1;;;6199:19:53;;;;;;;;;;;9592:480:60;9675:4;9691:12;9713:18;9741:19;9875:4;9872:1;9865:4;9859:11;9852:4;9846;9842:15;9839:1;9832:5;9825;9820:60;9809:71;;9907:16;9893:30;;9957:1;9951:8;9936:23;;9985:7;:80;;;;-1:-1:-1;9997:15:60;;:67;;10048:11;10063:1;10048:16;9997:67;;;10044:1;10023:5;-1:-1:-1;;;;;10015:26:60;;:30;9997:67;9978:87;9592:480;-1:-1:-1;;;;;;9592:480:60:o;8370:720::-;8450:18;8478:19;8616:4;8613:1;8606:4;8600:11;8593:4;8587;8583:15;8580:1;8573:5;8566;8561:60;8673:7;8663:176;;8717:4;8711:11;8762:16;8759:1;8754:3;8739:40;8808:16;8803:3;8796:29;8663:176;-1:-1:-1;;8916:1:60;8910:8;8866:16;;-1:-1:-1;8942:15:60;;:68;;8994:11;9009:1;8994:16;;8942:68;;;-1:-1:-1;;;;;8960:26:60;;;:31;8942:68;8938:146;;;9033:40;;-1:-1:-1;;;9033:40:60;;-1:-1:-1;;;;;6250:32:91;;9033:40:60;;;6232:51:91;6205:18;;9033:40:60;6086:203:91;1027:550:76;1088:12;;-1:-1:-1;;1471:1:76;1468;1461:20;1501:9;;;;1549:11;;;1535:12;;;;1531:30;;;;;1027:550;-1:-1:-1;;1027:550:76:o;1776:194:68:-;1881:10;1875:4;1868:24;1918:4;1912;1905:18;1949:4;1943;1936:18;5662:550:33;5856:43;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5856:43:33;-1:-1:-1;;;5856:43:33;;;5816:93;;5729:7;;;;;;;;-1:-1:-1;;;;;5816:26:33;;;:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5769:140;;;;5923:7;:39;;;;;5960:2;5934:15;:22;:28;;5923:39;5919:260;;;5978:24;6016:15;6005:38;;;;;;;;;;;;:::i;:::-;5978:65;-1:-1:-1;6081:15:33;6061:35;;6057:112;;6124:4;;6136:16;;-1:-1:-1;5662:550:33;-1:-1:-1;;;;5662:550:33:o;6057:112::-;5964:215;5919:260;-1:-1:-1;6196:5:33;;;;-1:-1:-1;5662:550:33;-1:-1:-1;;;5662:550:33:o;10746:291:87:-;10935:1;10926:6;:10;:25;;;;-1:-1:-1;10940:11:87;;10926:25;10922:50;;;10960:12;;-1:-1:-1;;;10960:12:87;;;;;;;;;;;10922:50;10982:48;10997:6;11005:8;11015:6;11023;10982:14;:48::i;5559:487:63:-;5690:17;;:21;5686:354;;5887:10;5881:17;5943:15;5930:10;5926:2;5922:19;5915:44;5686:354;6010:19;;-1:-1:-1;;;6010:19:63;;;;;;;;;;;9301:1233:83;-1:-1:-1;;;;;;;;;;;9583:20:83;;9476:6;;2048:30;9449:24;9613:743;9637:6;9633:1;:10;9613:743;;;9724:32;;9751:5;9724:32;9771:15;9789:1;:13;;9803:1;9789:16;;;;;;;;:::i;:::-;;;;;;;;;;9850:35;;-1:-1:-1;;;9850:35:83;;9879:4;9850:35;;;6232:51:91;-1:-1:-1;;;;;9789:16:83;;;;-1:-1:-1;9789:16:83;;9850:20;;6205:18:91;;9850:35:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9820:65;;9899:22;9924:47;9933:16;9951:19;9924:8;:47::i;:::-;9899:72;-1:-1:-1;9990:18:83;;9986:360;;10091:63;;-1:-1:-1;;;10091:63:83;;;;;23515:25:91;;;10133:4:83;23556:18:91;;;23549:60;;;23625:18;;;23618:60;-1:-1:-1;;;;;10091:17:83;;;;;23488:18:91;;10091:63:83;;;;;;;;;;;;;;;;;;;-1:-1:-1;10091:63:83;;;;;;;;-1:-1:-1;;10091:63:83;;;;;;;;;;;;:::i;:::-;;;10087:245;;10287:8;-1:-1:-1;;;;;10264:49:83;;10298:14;10264:49;;;;160:25:91;;148:2;133:18;;14:177;10264:49:83;;;;;;;;10087:245;;;-1:-1:-1;10177:34:83;10197:14;10177:34;;:::i;:::-;;;10087:245;9650:706;;;9645:3;;;;;9613:743;;;-1:-1:-1;10369:20:83;;10365:95;;10398:62;;-1:-1:-1;;;10398:62:83;;;;;28630:25:91;;;28671:18;;;28664:34;;;28714:18;;;28707:34;;;28603:18;;10398:62:83;28428:319:91;10365:95:83;10471:56;10487:6;10495:8;10505:5;10512:6;10520;10471:15;:56::i;:::-;9439:1095;;;9301:1233;;;;;:::o;2052:240:76:-;2189:5;;;2218:6;;;;;2113:12;;2218:6;2251:24;34795:145:77;11586:841:33;12256:74;12290:7;:5;:7::i;:::-;12300:6;12316:4;12323:6;12256:26;:74::i;:::-;12340:23;12346:8;12356:6;12340:5;:23::i;:::-;12395:8;-1:-1:-1;;;;;12379:41:33;12387:6;-1:-1:-1;;;;;12379:41:33;;12405:6;12413;12379:41;;;;;;16821:25:91;;;16877:2;16862:18;;16855:34;16809:2;16794:18;;16639:256;11152:343:87;11385:1;11376:6;:10;:25;;;;-1:-1:-1;11390:11:87;;11376:25;11372:50;;;11410:12;;-1:-1:-1;;;11410:12:87;;;;;;;;;;;11372:50;11432:56;11448:6;11456:8;11466:5;11473:6;11481;11432:15;:56::i;1618:188:60:-;1745:53;;-1:-1:-1;;;;;29766:32:91;;;1745:53:60;;;29748:51:91;29835:32;;;29815:18;;;29808:60;29884:18;;;29877:34;;;1718:81:60;;1738:5;;1760:18;;;;;29721::91;;1745:53:60;29546:371:91;12494:925:33;12681:5;-1:-1:-1;;;;;12671:15:33;:6;-1:-1:-1;;;;;12671:15:33;;12667:84;;12702:38;12718:5;12725:6;12733;12702:15;:38::i;:::-;13260:20;13266:5;13273:6;13260:5;:20::i;:::-;13290:57;13320:7;:5;:7::i;:::-;13330:8;13340:6;13290:22;:57::i;:::-;13390:5;-1:-1:-1;;;;;13363:49:33;13380:8;-1:-1:-1;;;;;13363:49:33;13372:6;-1:-1:-1;;;;;13363:49:33;;13397:6;13405;13363:49;;;;;;16821:25:91;;;16877:2;16862:18;;16855:34;16809:2;16794:18;;16639:256;13363:49:33;;;;;;;;12494:925;;;;;:::o;9240:206:31:-;-1:-1:-1;;;;;9310:21:31;;9306:89;;9354:30;;-1:-1:-1;;;9354:30:31;;9381:1;9354:30;;;6232:51:91;6205:18;;9354:30:31;6086:203:91;9306:89:31;9404:35;9412:7;9429:1;9433:5;9404:7;:35::i;1219:160:60:-;1328:43;;-1:-1:-1;;;;;22614:32:91;;;1328:43:60;;;22596:51:91;22663:18;;;22656:34;;;1301:71:60;;1321:5;;1343:14;;;;;22569:18:91;;1328:43:60;22422:274:91;196:289;238:3;276:5;270:12;303:6;298:3;291:19;359:6;352:4;345:5;341:16;334:4;329:3;325:14;319:47;411:1;404:4;395:6;390:3;386:16;382:27;375:38;474:4;467:2;463:7;458:2;450:6;446:15;442:29;437:3;433:39;429:50;422:57;;;196:289;;;;:::o;490:220::-;639:2;628:9;621:21;602:4;659:45;700:2;689:9;685:18;677:6;659:45;:::i;715:226::-;774:6;827:2;815:9;806:7;802:23;798:32;795:52;;;843:1;840;833:12;795:52;-1:-1:-1;888:23:91;;715:226;-1:-1:-1;715:226:91:o;946:131::-;-1:-1:-1;;;;;1021:31:91;;1011:42;;1001:70;;1067:1;1064;1057:12;1082:134;1150:20;;1179:31;1150:20;1179:31;:::i;1221:367::-;1289:6;1297;1350:2;1338:9;1329:7;1325:23;1321:32;1318:52;;;1366:1;1363;1356:12;1318:52;1405:9;1392:23;1424:31;1449:5;1424:31;:::i;:::-;1474:5;1552:2;1537:18;;;;1524:32;;-1:-1:-1;;;1221:367:91:o;1785:263::-;1860:6;1913:2;1901:9;1892:7;1888:23;1884:32;1881:52;;;1929:1;1926;1919:12;1881:52;1968:9;1955:23;1987:31;2012:5;1987:31;:::i;2053:508::-;2130:6;2138;2146;2199:2;2187:9;2178:7;2174:23;2170:32;2167:52;;;2215:1;2212;2205:12;2167:52;2254:9;2241:23;2273:31;2298:5;2273:31;:::i;:::-;2323:5;-1:-1:-1;2380:2:91;2365:18;;2352:32;2393:33;2352:32;2393:33;:::i;:::-;2053:508;;2445:7;;-1:-1:-1;;;2525:2:91;2510:18;;;;2497:32;;2053:508::o;2566:127::-;2627:10;2622:3;2618:20;2615:1;2608:31;2658:4;2655:1;2648:15;2682:4;2679:1;2672:15;2698:275;2769:2;2763:9;2834:2;2815:13;;-1:-1:-1;;2811:27:91;2799:40;;-1:-1:-1;;;;;2854:34:91;;2890:22;;;2851:62;2848:88;;;2916:18;;:::i;:::-;2952:2;2945:22;2698:275;;-1:-1:-1;2698:275:91:o;2978:450::-;3043:5;3075:1;-1:-1:-1;;;;;3091:6:91;3088:30;3085:56;;;3121:18;;:::i;:::-;-1:-1:-1;3187:2:91;3166:15;;-1:-1:-1;;3162:29:91;3193:4;3158:40;3216:21;3158:40;3216:21;:::i;:::-;3207:30;;;3260:6;3253:5;3246:21;3300:3;3291:6;3286:3;3282:16;3279:25;3276:45;;;3317:1;3314;3307:12;3276:45;3366:6;3361:3;3354:4;3347:5;3343:16;3330:43;3420:1;3413:4;3404:6;3397:5;3393:18;3389:29;3382:40;2978:450;;;;;:::o;3433:222::-;3476:5;3529:3;3522:4;3514:6;3510:17;3506:27;3496:55;;3547:1;3544;3537:12;3496:55;3569:80;3645:3;3636:6;3623:20;3616:4;3608:6;3604:17;3569:80;:::i;3660:804::-;3722:5;3775:3;3768:4;3760:6;3756:17;3752:27;3742:55;;3793:1;3790;3783:12;3742:55;3833:6;3820:20;-1:-1:-1;;;;;3855:6:91;3852:30;3849:56;;;3885:18;;:::i;:::-;3931:6;3928:1;3924:14;3958:30;3982:4;3978:2;3974:13;3958:30;:::i;:::-;4024:19;;;4068:4;4100:15;;;4096:26;;;4059:14;;;;4134:15;;;4131:35;;;4162:1;4159;4152:12;4131:35;4198:4;4190:6;4186:17;4175:28;;4212:221;4228:6;4223:3;4220:15;4212:221;;;4310:3;4297:17;4327:31;4352:5;4327:31;:::i;:::-;4371:18;;4418:4;4245:14;;;;4409;;;;4212:221;;4469:1241;4673:6;4681;4689;4697;4705;4713;4721;4774:3;4762:9;4753:7;4749:23;4745:33;4742:53;;;4791:1;4788;4781:12;4742:53;4830:9;4817:23;4849:31;4874:5;4849:31;:::i;:::-;4899:5;-1:-1:-1;4923:38:91;4957:2;4942:18;;4923:38;:::i;:::-;4913:48;;5012:2;5001:9;4997:18;4984:32;-1:-1:-1;;;;;5031:6:91;5028:30;5025:50;;;5071:1;5068;5061:12;5025:50;5094;5136:7;5127:6;5116:9;5112:22;5094:50;:::i;:::-;5084:60;;;5197:2;5186:9;5182:18;5169:32;-1:-1:-1;;;;;5216:8:91;5213:32;5210:52;;;5258:1;5255;5248:12;5210:52;5281;5325:7;5314:8;5303:9;5299:24;5281:52;:::i;:::-;5271:62;;;5352:39;5386:3;5375:9;5371:19;5352:39;:::i;:::-;5342:49;-1:-1:-1;5464:3:91;5449:19;;5436:33;;-1:-1:-1;5548:3:91;5533:19;;5520:33;-1:-1:-1;;;;;5565:32:91;;5562:52;;;5610:1;5607;5600:12;5562:52;5633:71;5696:7;5685:8;5674:9;5670:24;5633:71;:::i;:::-;5623:81;;;4469:1241;;;;;;;;;;:::o;6546:585::-;6623:6;6631;6684:2;6672:9;6663:7;6659:23;6655:32;6652:52;;;6700:1;6697;6690:12;6652:52;6739:9;6726:23;6758:31;6783:5;6758:31;:::i;:::-;6808:5;-1:-1:-1;6864:2:91;6849:18;;6836:32;-1:-1:-1;;;;;6880:30:91;;6877:50;;;6923:1;6920;6913:12;6877:50;6946:22;;6999:4;6991:13;;6987:27;-1:-1:-1;6977:55:91;;7028:1;7025;7018:12;6977:55;7051:74;7117:7;7112:2;7099:16;7094:2;7090;7086:11;7051:74;:::i;:::-;7041:84;;;6546:585;;;;;:::o;7136:661::-;7254:6;7262;7270;7278;7331:3;7319:9;7310:7;7306:23;7302:33;7299:53;;;7348:1;7345;7338:12;7299:53;7387:9;7374:23;7406:31;7431:5;7406:31;:::i;:::-;7456:5;-1:-1:-1;7513:2:91;7498:18;;7485:32;7526:33;7485:32;7526:33;:::i;:::-;7136:661;;7578:7;;-1:-1:-1;;;;7658:2:91;7643:18;;7630:32;;7761:2;7746:18;7733:32;;7136:661::o;7802:367::-;7870:6;7878;7931:2;7919:9;7910:7;7906:23;7902:32;7899:52;;;7947:1;7944;7937:12;7899:52;7992:23;;;-1:-1:-1;8091:2:91;8076:18;;8063:32;8104:33;8063:32;8104:33;:::i;:::-;8156:7;8146:17;;;7802:367;;;;;:::o;8174:1238::-;8580:3;8575;8571:13;8563:6;8559:26;8548:9;8541:45;8622:3;8617:2;8606:9;8602:18;8595:31;8522:4;8649:46;8690:3;8679:9;8675:19;8667:6;8649:46;:::i;:::-;8743:9;8735:6;8731:22;8726:2;8715:9;8711:18;8704:50;8777:33;8803:6;8795;8777:33;:::i;:::-;8841:2;8826:18;;8819:34;;;-1:-1:-1;;;;;8890:32:91;;8884:3;8869:19;;8862:61;8910:3;8939:19;;8932:35;;;9004:22;;;8998:3;8983:19;;8976:51;9076:13;;9098:22;;;9148:2;9174:15;;;;-1:-1:-1;9136:15:91;;;;-1:-1:-1;9217:169:91;9231:6;9228:1;9225:13;9217:169;;;9292:13;;9280:26;;9335:2;9361:15;;;;9326:12;;;;9253:1;9246:9;9217:169;;;-1:-1:-1;9403:3:91;;8174:1238;-1:-1:-1;;;;;;;;;;;8174:1238:91:o;9417:1108::-;9571:6;9579;9587;9595;9603;9611;9664:3;9652:9;9643:7;9639:23;9635:33;9632:53;;;9681:1;9678;9671:12;9632:53;9720:9;9707:23;9739:31;9764:5;9739:31;:::i;:::-;9789:5;-1:-1:-1;9846:2:91;9831:18;;9818:32;9859:33;9818:32;9859:33;:::i;:::-;9911:7;-1:-1:-1;9969:2:91;9954:18;;9941:32;-1:-1:-1;;;;;9985:30:91;;9982:50;;;10028:1;10025;10018:12;9982:50;10051;10093:7;10084:6;10073:9;10069:22;10051:50;:::i;:::-;10041:60;;;10154:2;10143:9;10139:18;10126:32;-1:-1:-1;;;;;10173:8:91;10170:32;10167:52;;;10215:1;10212;10205:12;10167:52;10238;10282:7;10271:8;10260:9;10256:24;10238:52;:::i;:::-;10228:62;;;10342:3;10331:9;10327:19;10314:33;10356;10381:7;10356:33;:::i;:::-;9417:1108;;;;-1:-1:-1;9417:1108:91;;;;;10488:3;10473:19;;;10460:33;;-1:-1:-1;;9417:1108:91:o;10530:374::-;10600:8;10610:6;10664:3;10657:4;10649:6;10645:17;10641:27;10631:55;;10682:1;10679;10672:12;10631:55;-1:-1:-1;10705:20:91;;-1:-1:-1;;;;;10737:30:91;;10734:50;;;10780:1;10777;10770:12;10734:50;10817:4;10809:6;10805:17;10793:29;;10877:3;10870:4;10860:6;10857:1;10853:14;10845:6;10841:27;10837:38;10834:47;10831:67;;;10894:1;10891;10884:12;10831:67;10530:374;;;;;:::o;10909:455::-;11006:6;11014;11067:2;11055:9;11046:7;11042:23;11038:32;11035:52;;;11083:1;11080;11073:12;11035:52;11123:9;11110:23;-1:-1:-1;;;;;11148:6:91;11145:30;11142:50;;;11188:1;11185;11178:12;11142:50;11227:77;11296:7;11287:6;11276:9;11272:22;11227:77;:::i;:::-;11323:8;;11201:103;;-1:-1:-1;10909:455:91;-1:-1:-1;;;;10909:455:91:o;11369:780::-;11529:4;11577:2;11566:9;11562:18;11607:2;11596:9;11589:21;11630:6;11665;11659:13;11696:6;11688;11681:22;11734:2;11723:9;11719:18;11712:25;;11796:2;11786:6;11783:1;11779:14;11768:9;11764:30;11760:39;11746:53;;11834:2;11826:6;11822:15;11855:1;11865:255;11879:6;11876:1;11873:13;11865:255;;;11972:2;11968:7;11956:9;11948:6;11944:22;11940:36;11935:3;11928:49;12000:40;12033:6;12024;12018:13;12000:40;:::i;:::-;11990:50;-1:-1:-1;12075:2:91;12098:12;;;;12063:15;;;;;11901:1;11894:9;11865:255;;;-1:-1:-1;12137:6:91;;11369:780;-1:-1:-1;;;;;;11369:780:91:o;12154:508::-;12231:6;12239;12247;12300:2;12288:9;12279:7;12275:23;12271:32;12268:52;;;12316:1;12313;12306:12;12268:52;12361:23;;;-1:-1:-1;12460:2:91;12445:18;;12432:32;12473:33;12432:32;12473:33;:::i;:::-;12525:7;-1:-1:-1;12584:2:91;12569:18;;12556:32;12597:33;12556:32;12597:33;:::i;:::-;12649:7;12639:17;;;12154:508;;;;;:::o;12667:1037::-;12778:6;12786;12794;12802;12810;12818;12826;12879:3;12867:9;12858:7;12854:23;12850:33;12847:53;;;12896:1;12893;12886:12;12847:53;12935:9;12922:23;12954:31;12979:5;12954:31;:::i;:::-;13004:5;-1:-1:-1;13061:2:91;13046:18;;13033:32;13074:33;13033:32;13074:33;:::i;:::-;13126:7;-1:-1:-1;13206:2:91;13191:18;;13178:32;;-1:-1:-1;13309:2:91;13294:18;;13281:32;;-1:-1:-1;13391:3:91;13376:19;;13363:33;13440:4;13427:18;;13415:31;;13405:59;;13460:1;13457;13450:12;13405:59;12667:1037;;;;-1:-1:-1;12667:1037:91;;;;13483:7;13563:3;13548:19;;13535:33;;-1:-1:-1;13667:3:91;13652:19;;;13639:33;;12667:1037;-1:-1:-1;;12667:1037:91:o;13933:653::-;14139:2;14151:21;;;14221:13;;14124:18;;;14243:22;;;14091:4;;14322:15;;;14296:2;14281:18;;;14091:4;14365:195;14379:6;14376:1;14373:13;14365:195;;;14444:13;;-1:-1:-1;;;;;14440:39:91;14428:52;;14509:2;14535:15;;;;14500:12;;;;14476:1;14394:9;14365:195;;;-1:-1:-1;14577:3:91;;13933:653;-1:-1:-1;;;;;13933:653:91:o;14591:388::-;14659:6;14667;14720:2;14708:9;14699:7;14695:23;14691:32;14688:52;;;14736:1;14733;14726:12;14688:52;14775:9;14762:23;14794:31;14819:5;14794:31;:::i;:::-;14844:5;-1:-1:-1;14901:2:91;14886:18;;14873:32;14914:33;14873:32;14914:33;:::i;15671:127::-;15732:10;15727:3;15723:20;15720:1;15713:31;15763:4;15760:1;15753:15;15787:4;15784:1;15777:15;15803:184;15873:6;15926:2;15914:9;15905:7;15901:23;15897:32;15894:52;;;15942:1;15939;15932:12;15894:52;-1:-1:-1;15965:16:91;;15803:184;-1:-1:-1;15803:184:91:o;15992:127::-;16053:10;16048:3;16044:20;16041:1;16034:31;16084:4;16081:1;16074:15;16108:4;16105:1;16098:15;16124:125;16189:9;;;16210:10;;;16207:36;;;16223:18;;:::i;16254:380::-;16333:1;16329:12;;;;16376;;;16397:61;;16451:4;16443:6;16439:17;16429:27;;16397:61;16504:2;16496:6;16493:14;16473:18;16470:38;16467:161;;16550:10;16545:3;16541:20;16538:1;16531:31;16585:4;16582:1;16575:15;16613:4;16610:1;16603:15;16467:161;;16254:380;;;:::o;16900:251::-;16970:6;17023:2;17011:9;17002:7;16998:23;16994:32;16991:52;;;17039:1;17036;17029:12;16991:52;17071:9;17065:16;17090:31;17115:5;17090:31;:::i;17720:128::-;17787:9;;;17808:11;;;17805:37;;;17822:18;;:::i;18189:521::-;18266:4;18272:6;18332:11;18319:25;18426:2;18422:7;18411:8;18395:14;18391:29;18387:43;18367:18;18363:68;18353:96;;18445:1;18442;18435:12;18353:96;18472:33;;18524:20;;;-1:-1:-1;;;;;;18556:30:91;;18553:50;;;18599:1;18596;18589:12;18553:50;18632:4;18620:17;;-1:-1:-1;18663:14:91;18659:27;;;18649:38;;18646:58;;;18700:1;18697;18690:12;18715:211;18756:3;18794:5;18788:12;18838:6;18831:4;18824:5;18820:16;18815:3;18809:36;18900:1;18864:16;;18889:13;;;-1:-1:-1;18864:16:91;;18715:211;-1:-1:-1;18715:211:91:o;18931:343::-;19160:6;19152;19147:3;19134:33;19116:3;19195:6;19190:3;19186:16;19222:1;19218:2;19211:13;19240:28;19265:2;19257:6;19240:28;:::i;20429:375::-;20517:1;20535:5;20549:249;20570:1;20560:8;20557:15;20549:249;;;20620:4;20615:3;20611:14;20605:4;20602:24;20599:50;;;20629:18;;:::i;:::-;20679:1;20669:8;20665:16;20662:49;;;20693:16;;;;20662:49;20776:1;20772:16;;;;;20732:15;;20549:249;;;20429:375;;;;;;:::o;20809:902::-;20858:5;20888:8;20878:80;;-1:-1:-1;20929:1:91;20943:5;;20878:80;20977:4;20967:76;;-1:-1:-1;21014:1:91;21028:5;;20967:76;21059:4;21077:1;21072:59;;;;21145:1;21140:174;;;;21052:262;;21072:59;21102:1;21093:10;;21116:5;;;21140:174;21177:3;21167:8;21164:17;21161:43;;;21184:18;;:::i;:::-;-1:-1:-1;;21240:1:91;21226:16;;21299:5;;21052:262;;21398:2;21388:8;21385:16;21379:3;21373:4;21370:13;21366:36;21360:2;21350:8;21347:16;21342:2;21336:4;21333:12;21329:35;21326:77;21323:203;;;-1:-1:-1;21435:19:91;;;21511:5;;21323:203;21558:42;-1:-1:-1;;21583:8:91;21577:4;21558:42;:::i;:::-;21636:6;21632:1;21628:6;21624:19;21615:7;21612:32;21609:58;;;21647:18;;:::i;:::-;21685:20;;20809:902;-1:-1:-1;;;20809:902:91:o;21716:140::-;21774:5;21803:47;21844:4;21834:8;21830:19;21824:4;21803:47;:::i;22140:277::-;22207:6;22260:2;22248:9;22239:7;22235:23;22231:32;22228:52;;;22276:1;22273;22266:12;22228:52;22308:9;22302:16;22361:5;22354:13;22347:21;22340:5;22337:32;22327:60;;22383:1;22380;22373:12;22971:148;23059:4;23038:12;;;23052;;;23034:31;;23077:13;;23074:39;;;23093:18;;:::i;24436:345::-;-1:-1:-1;;;;;24656:32:91;;;;24638:51;;24720:2;24705:18;;24698:34;;;;24763:2;24748:18;;24741:34;24626:2;24611:18;;24436:345::o;24786:127::-;24847:10;24842:3;24838:20;24835:1;24828:31;24878:4;24875:1;24868:15;24902:4;24899:1;24892:15;24918:189;25047:3;25072:29;25097:3;25089:6;25072:29;:::i;25112:127::-;25173:10;25168:3;25164:20;25161:1;25154:31;25204:4;25201:1;25194:15;25228:4;25225:1;25218:15;26430:518;26532:2;26527:3;26524:11;26521:421;;;26568:5;26565:1;26558:16;26612:4;26609:1;26599:18;26682:2;26670:10;26666:19;26663:1;26659:27;26653:4;26649:38;26718:4;26706:10;26703:20;26700:47;;;-1:-1:-1;26741:4:91;26700:47;26796:2;26791:3;26787:12;26784:1;26780:20;26774:4;26770:31;26760:41;;26851:81;26869:2;26862:5;26859:13;26851:81;;;26928:1;26914:16;;26895:1;26884:13;26851:81;;27124:1299;27250:3;27244:10;-1:-1:-1;;;;;27269:6:91;27266:30;27263:56;;;27299:18;;:::i;:::-;27328:97;27418:6;27378:38;27410:4;27404:11;27378:38;:::i;:::-;27372:4;27328:97;:::i;:::-;27474:4;27505:2;27494:14;;27522:1;27517:649;;;;28210:1;28227:6;28224:89;;;-1:-1:-1;28279:19:91;;;28273:26;28224:89;-1:-1:-1;;27081:1:91;27077:11;;;27073:24;27069:29;27059:40;27105:1;27101:11;;;27056:57;28326:81;;27487:930;;27517:649;26377:1;26370:14;;;26414:4;26401:18;;-1:-1:-1;;27553:20:91;;;27671:222;27685:7;27682:1;27679:14;27671:222;;;27767:19;;;27761:26;27746:42;;27874:4;27859:20;;;;27827:1;27815:14;;;;27701:12;27671:222;;;27675:3;27921:6;27912:7;27909:19;27906:201;;;27982:19;;;27976:26;-1:-1:-1;;28065:1:91;28061:14;;;28077:3;28057:24;28053:37;28049:42;28034:58;28019:74;;27906:201;-1:-1:-1;;;;28153:1:91;28137:14;;;28133:22;28120:36;;-1:-1:-1;27124:1299:91:o;29155:127::-;29216:10;29211:3;29207:20;29204:1;29197:31;29247:4;29244:1;29237:15;29271:4;29268:1;29261:15;29287:254;29317:1;29351:4;29348:1;29344:12;29375:3;29365:134;;29421:10;29416:3;29412:20;29409:1;29402:31;29456:4;29453:1;29446:15;29484:4;29481:1;29474:15;29365:134;29531:3;29524:4;29521:1;29517:12;29513:22;29508:27;;;29287:254;;;;:::o","linkReferences":{},"immutableReferences":{"40091":[{"start":9749,"length":32},{"start":9790,"length":32},{"start":10094,"length":32}]}},"methodIdentifiers":{"DOMAIN_SEPARATOR()":"3644e515","UPGRADE_INTERFACE_VERSION()":"ad3cb1cc","addStrategy(address)":"223e5479","allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","asset()":"38d52e0f","auth()":"de9375f2","balanceOf(address)":"70a08231","convertToAssets(uint256)":"07a2d13a","convertToShares(uint256)":"c6e6f592","decimals()":"313ce567","deposit(uint256,address)":"6e553f65","eip712Domain()":"84b0196e","feeRecipient()":"46904840","highWaterMark()":"1e8410da","initialize(address,address,string,string,address,uint256)":"a01e3f74","initialize(address,address,string,string,address,uint256,address[])":"29d7b732","isStrategy(address)":"2e8ebaae","maxDeposit(address)":"402d267d","maxMint(address)":"c63d75b6","maxRedeem(address)":"d905777e","maxWithdraw(address)":"ce96cb77","mint(uint256,address)":"94bf804d","multicall(bytes[])":"ac9650d8","name()":"06fdde03","nonces(address)":"7ecebe00","pause()":"8456cb59","paused()":"5c975abb","performanceFeePercent()":"48f5b980","permit(address,address,uint256,uint256,uint8,bytes32,bytes32)":"d505accf","previewDeposit(uint256)":"ef8b30f7","previewMint(uint256)":"b3d7f6b9","previewRedeem(uint256)":"4cdad506","previewWithdraw(uint256)":"0a28a477","proxiableUUID()":"52d1902d","rebalance(address,address,uint256,uint256)":"6e49db1c","rebalanceMaxSlippagePercent()":"907d5405","redeem(uint256,address,address)":"ba087652","removeStrategy(address,address,uint256,uint256)":"ab3ffa1a","reorderStrategies(address[])":"f34e1217","setFeeRecipient(address)":"e74b981b","setPerformanceFeePercent(uint256)":"df652d41","setRebalanceMaxSlippagePercent(uint256)":"317b7224","setTotalAssetsCap(uint256)":"114fbced","strategies()":"d9f9027f","strategies(uint256)":"d574ea3d","strategiesCount()":"2489f7f7","symbol()":"95d89b41","totalAssets()":"01e1d114","totalAssetsCap()":"45f663dd","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd","unpause()":"3f4ba83a","upgradeToAndCall(address,bytes)":"4f1ef286","version()":"54fd4d50","withdraw(uint256,address,address)":"b460af94"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.26+commit.8a97fa7a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"neededRole\",\"type\":\"bytes32\"}],\"name\":\"AccessControlUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"ArrayLengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"remainingAssets\",\"type\":\"uint256\"}],\"name\":\"CannotDepositToStrategies\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"missingAssets\",\"type\":\"uint256\"}],\"name\":\"CannotWithdrawFromStrategies\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ECDSAInvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"ECDSAInvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"ECDSAInvalidSignatureS\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"ERC1967InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERC1967NonPayable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"ERC2612ExpiredSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC2612InvalidSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"ERC4626ExceededMaxDeposit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"ERC4626ExceededMaxMint\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"ERC4626ExceededMaxRedeem\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"ERC4626ExceededMaxWithdraw\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EnforcedPause\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExpectedPause\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"currentNonce\",\"type\":\"uint256\"}],\"name\":\"InvalidAccountNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"InvalidMaxSlippagePercent\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"strategy\",\"type\":\"address\"}],\"name\":\"InvalidStrategy\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"strategiesCount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxStrategies\",\"type\":\"uint256\"}],\"name\":\"MaxStrategiesExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NullAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NullAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"performanceFeePercent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumPerformanceFeePercent\",\"type\":\"uint256\"}],\"name\":\"PerformanceFeePercentTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assetsBefore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"assetsAfter\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"slippage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"TransferredAmountLessThanMin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"auth\",\"type\":\"address\"}],\"name\":\"AuthSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DepositFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"EIP712DomainChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeRecipientBefore\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeRecipientAfter\",\"type\":\"address\"}],\"name\":\"FeeRecipientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"highWaterMarkBefore\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"highWaterMarkAfter\",\"type\":\"uint256\"}],\"name\":\"HighWaterMarkUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"PerformanceFeeMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"performanceFeePercentBefore\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"performanceFeePercentAfter\",\"type\":\"uint256\"}],\"name\":\"PerformanceFeePercentSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldRebalanceMaxSlippagePercent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newRebalanceMaxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"RebalanceMaxSlippagePercentSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategyFrom\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategyTo\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rebalancedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"Rebalanced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategy\",\"type\":\"address\"}],\"name\":\"StrategyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategy\",\"type\":\"address\"}],\"name\":\"StrategyRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategyOld\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategyNew\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"StrategyReordered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"totalAssetsCapBefore\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"totalAssetsCapAfter\",\"type\":\"uint256\"}],\"name\":\"TotalAssetsCapSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalShares\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalAssets\",\"type\":\"uint256\"}],\"name\":\"VaultStatus\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPGRADE_INTERFACE_VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IVault\",\"name\":\"strategy_\",\"type\":\"address\"}],\"name\":\"addStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"asset\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"auth\",\"outputs\":[{\"internalType\":\"contract Auth\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"convertToAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"convertToShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eip712Domain\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"fields\",\"type\":\"bytes1\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifyingContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"extensions\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"highWaterMark\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract Auth\",\"name\":\"auth_\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"asset_\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"fundingAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"firstDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"contract IVault[]\",\"name\":\"strategies_\",\"type\":\"address[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract Auth\",\"name\":\"auth_\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"asset_\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"fundingAccount_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"firstDepositAmount_\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IVault\",\"name\":\"strategy\",\"type\":\"address\"}],\"name\":\"isStrategy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"maxDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"maxMint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"maxRedeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"maxWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"multicall\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"results\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"performanceFeePercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"previewDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"previewMint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"previewRedeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"previewWithdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IVault\",\"name\":\"strategyFrom\",\"type\":\"address\"},{\"internalType\":\"contract IVault\",\"name\":\"strategyTo\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"rebalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebalanceMaxSlippagePercent\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"redeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IVault\",\"name\":\"strategyToRemove\",\"type\":\"address\"},{\"internalType\":\"contract IVault\",\"name\":\"strategyToReceiveAssets\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSlippagePercent\",\"type\":\"uint256\"}],\"name\":\"removeStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IVault[]\",\"name\":\"newStrategiesOrder\",\"type\":\"address[]\"}],\"name\":\"reorderStrategies\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeRecipient_\",\"type\":\"address\"}],\"name\":\"setFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"performanceFeePercent_\",\"type\":\"uint256\"}],\"name\":\"setPerformanceFeePercent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rebalanceMaxSlippagePercent_\",\"type\":\"uint256\"}],\"name\":\"setRebalanceMaxSlippagePercent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalAssetsCap_\",\"type\":\"uint256\"}],\"name\":\"setTotalAssetsCap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"strategies\",\"outputs\":[{\"internalType\":\"contract IVault\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"strategies\",\"outputs\":[{\"internalType\":\"contract IVault[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"strategiesCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalAssets\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"total\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalAssetsCap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Size (https://size.credit/)\",\"custom:security-contact\":\"security@size.credit\",\"details\":\"Extends PerformanceVault to manage multiple strategy vaults for asset allocation. By default, the performance fee is 0.\",\"errors\":{\"AccessControlUnauthorizedAccount(address,bytes32)\":[{\"details\":\"The `account` is missing a role.\"}],\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"ECDSAInvalidSignature()\":[{\"details\":\"The signature derives the `address(0)`.\"}],\"ECDSAInvalidSignatureLength(uint256)\":[{\"details\":\"The signature has an invalid length.\"}],\"ECDSAInvalidSignatureS(bytes32)\":[{\"details\":\"The signature has an S value that is in the upper half order.\"}],\"ERC1967InvalidImplementation(address)\":[{\"details\":\"The `implementation` of the proxy is invalid.\"}],\"ERC1967NonPayable()\":[{\"details\":\"An upgrade function sees `msg.value > 0` that may be lost.\"}],\"ERC20InsufficientAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\",\"params\":{\"allowance\":\"Amount of tokens a `spender` is allowed to operate with.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC20InsufficientBalance(address,uint256,uint256)\":[{\"details\":\"Indicates an error related to the current `balance` of a `sender`. Used in transfers.\",\"params\":{\"balance\":\"Current balance for the interacting account.\",\"needed\":\"Minimum amount required to perform a transfer.\",\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidApprover(address)\":[{\"details\":\"Indicates a failure with the `approver` of a token to be approved. Used in approvals.\",\"params\":{\"approver\":\"Address initiating an approval operation.\"}}],\"ERC20InvalidReceiver(address)\":[{\"details\":\"Indicates a failure with the token `receiver`. Used in transfers.\",\"params\":{\"receiver\":\"Address to which tokens are being transferred.\"}}],\"ERC20InvalidSender(address)\":[{\"details\":\"Indicates a failure with the token `sender`. Used in transfers.\",\"params\":{\"sender\":\"Address whose tokens are being transferred.\"}}],\"ERC20InvalidSpender(address)\":[{\"details\":\"Indicates a failure with the `spender` to be approved. Used in approvals.\",\"params\":{\"spender\":\"Address that may be allowed to operate on tokens without being their owner.\"}}],\"ERC2612ExpiredSignature(uint256)\":[{\"details\":\"Permit deadline has expired.\"}],\"ERC2612InvalidSigner(address,address)\":[{\"details\":\"Mismatched signature.\"}],\"ERC4626ExceededMaxDeposit(address,uint256,uint256)\":[{\"details\":\"Attempted to deposit more assets than the max amount for `receiver`.\"}],\"ERC4626ExceededMaxMint(address,uint256,uint256)\":[{\"details\":\"Attempted to mint more shares than the max amount for `receiver`.\"}],\"ERC4626ExceededMaxRedeem(address,uint256,uint256)\":[{\"details\":\"Attempted to redeem more shares than the max amount for `receiver`.\"}],\"ERC4626ExceededMaxWithdraw(address,uint256,uint256)\":[{\"details\":\"Attempted to withdraw more assets than the max amount for `receiver`.\"}],\"EnforcedPause()\":[{\"details\":\"The operation failed because the contract is paused.\"}],\"ExpectedPause()\":[{\"details\":\"The operation failed because the contract is not paused.\"}],\"FailedCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"InvalidAccountNonce(address,uint256)\":[{\"details\":\"The nonce used for an `account` is not the expected current nonce.\"}],\"InvalidInitialization()\":[{\"details\":\"The contract is already initialized.\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"EIP712DomainChanged()\":{\"details\":\"MAY be emitted to signal that the domain could have changed.\"},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\"},\"addStrategy(address)\":{\"details\":\"Only callable by addresses with VAULT_MANAGER_ROLE\",\"params\":{\"strategy_\":\"The new strategy to add\"}},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"asset()\":{\"details\":\"See {IERC4626-asset}. \"},\"auth()\":{\"details\":\"The Auth contract manages roles and access control for vault operationsExternal integrators can use this to query permissions but should not rely on its internal logic directly\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"convertToAssets(uint256)\":{\"details\":\"See {IERC4626-convertToAssets}. \"},\"convertToShares(uint256)\":{\"details\":\"See {IERC4626-convertToShares}. \"},\"decimals()\":{\"details\":\"Returns the decimals places of the token.\"},\"deposit(uint256,address)\":{\"details\":\"Prevents reentrancy, mints performance fees\"},\"eip712Domain()\":{\"details\":\"returns the fields and values that describe the domain separator used by this contract for EIP-712 signature.\"},\"initialize(address,address,string,string,address,uint256)\":{\"details\":\"Sets up all inherited contracts and makes the first deposit to prevent inflation attacks\",\"params\":{\"asset_\":\"The address of the asset\",\"auth_\":\"The address of the Auth contract\",\"firstDepositAmount_\":\"The amount of the first deposit, which will be treated as dead shares\",\"fundingAccount_\":\"The address of the funding account for the first deposit, which will be treated as dead shares\",\"name_\":\"The name of the vault\",\"symbol_\":\"The symbol of the vault\"}},\"initialize(address,address,string,string,address,uint256,address[])\":{\"params\":{\"asset_\":\"The address of the asset\",\"auth_\":\"The address of the Auth contract\",\"firstDepositAmount\":\"The amount of the first deposit, which will be treated as dead shares\",\"fundingAccount\":\"The address of the funding account for the first deposit, which will be treated as dead shares\",\"name_\":\"The name of the vault\",\"strategies_\":\"The initial strategies to add to the vault\",\"symbol_\":\"The symbol of the vault\"}},\"isStrategy(address)\":{\"params\":{\"strategy\":\"The strategy to check\"},\"returns\":{\"_0\":\"True if the strategy is in the vault\"}},\"maxDeposit(address)\":{\"details\":\"The maximum amount that can be deposited is the minimum between this receiver specific limit and the maximum asset amount that can be deposited to all strategies\"},\"maxMint(address)\":{\"details\":\"The maximum amount that can be minted is the minimum between this receiver specific limit and the maximum asset amount that can be minted to all strategies, converted to shares\"},\"maxRedeem(address)\":{\"details\":\"The maximum amount that can be redeemed is the minimum between this owner specific limit and the maximum asset amount that can be redeemed from all strategies, converted to shares\"},\"maxWithdraw(address)\":{\"details\":\"The maximum amount that can be withdrawn is the minimum between this owner specific limit and the maximum asset amount that can be withdrawn from all strategies\"},\"mint(uint256,address)\":{\"details\":\"Prevents reentrancy, mints performance fees\"},\"multicall(bytes[])\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Receives and executes a batch of function calls on this contract.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"Returns the current nonce for `owner`. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases ``owner``'s nonce by one. This prevents a signature from being used multiple times.\"},\"pause()\":{\"details\":\"Only addresses with GUARDIAN_ROLE can pause the vault\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"Sets `value` as the allowance of `spender` over ``owner``'s tokens, given ``owner``'s signed approval. IMPORTANT: The same issues {IERC20-approve} has related to transaction ordering also apply here. Emits an {Approval} event. Requirements: - `spender` cannot be the zero address. - `deadline` must be a timestamp in the future. - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` over the EIP712-formatted function arguments. - the signature must use ``owner``'s current nonce (see {nonces}). For more information on the signature format, see the https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. CAUTION: See Security Considerations above.\"},\"previewDeposit(uint256)\":{\"details\":\"See {IERC4626-previewDeposit}. \"},\"previewMint(uint256)\":{\"details\":\"See {IERC4626-previewMint}. \"},\"previewRedeem(uint256)\":{\"details\":\"See {IERC4626-previewRedeem}. \"},\"previewWithdraw(uint256)\":{\"details\":\"See {IERC4626-previewWithdraw}. \"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"rebalance(address,address,uint256,uint256)\":{\"details\":\"Only callable by addresses with STRATEGIST_ROLETransfers assets from one strategy to anotherWe have maxSlippagePercent <= PERCENT since rebalanceMaxSlippagePercent has already been checked in setRebalanceMaxSlippagePercent\",\"params\":{\"amount\":\"The amount of assets to transfer\",\"maxSlippagePercent\":\"The maximum slippage percent allowed for the rebalance\",\"strategyFrom\":\"The strategy to transfer assets from\",\"strategyTo\":\"The strategy to transfer assets to\"}},\"rebalanceMaxSlippagePercent()\":{\"returns\":{\"_0\":\"The rebalance max slippage percent\"}},\"redeem(uint256,address,address)\":{\"details\":\"Prevents reentrancy, mints performance fees\"},\"removeStrategy(address,address,uint256,uint256)\":{\"details\":\"Only callable by addresses with GUARDIAN_ROLEUsing `amount` = 0 will forfeit all assets from `strategyToRemove`Using `amount` = type(uint256).max will attempt to transfer the entire balance from `strategyToRemove`If `convertToAssets(balanceOf)` > `maxWithdraw`, e.g. due to pause/withdraw limits, the _rebalance step will revert, so an appropriate `amount` should be usedReverts if totalAssets() == 0 at the end of the operation, which can happen if the call is performed with 100% slippage\",\"params\":{\"amount\":\"The amount of assets to transfer\",\"maxSlippagePercent\":\"The maximum slippage percent allowed for the rebalance\",\"strategyToReceiveAssets\":\"The strategy to receive the assets\",\"strategyToRemove\":\"The strategy to remove\"}},\"reorderStrategies(address[])\":{\"details\":\"Only callable by addresses with STRATEGIST_ROLEVerifies that the new strategies order is valid and that there are no duplicatesClears current strategies and adds them in the new order\",\"params\":{\"newStrategiesOrder\":\"The new strategies order\"}},\"setFeeRecipient(address)\":{\"details\":\"Only callable by addresses with DEFAULT_ADMIN_ROLE\",\"params\":{\"feeRecipient_\":\"The new fee recipient\"}},\"setPerformanceFeePercent(uint256)\":{\"details\":\"Only callable by addresses with DEFAULT_ADMIN_ROLE\",\"params\":{\"performanceFeePercent_\":\"The new performance fee percent\"}},\"setRebalanceMaxSlippagePercent(uint256)\":{\"details\":\"Only callable by addresses with VAULT_MANAGER_ROLE\",\"params\":{\"rebalanceMaxSlippagePercent_\":\"The new rebalance max slippage percent\"}},\"setTotalAssetsCap(uint256)\":{\"details\":\"Only addresses with VAULT_MANAGER_ROLE can set the vault capLowering the total assets cap does not affect existing deposited assets\",\"params\":{\"totalAssetsCap_\":\"The new total assets cap\"}},\"strategies()\":{\"returns\":{\"_0\":\"The strategies in the vault\"}},\"strategies(uint256)\":{\"params\":{\"index\":\"The index of the strategy\"},\"returns\":{\"_0\":\"The strategy at the given index\"}},\"strategiesCount()\":{\"returns\":{\"_0\":\"The number of strategies in the vault\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalAssets()\":{\"details\":\"The total assets is the sum of the assets in all strategies\"},\"totalAssetsCap()\":{\"details\":\"Expressed in units of the underlying ERC20 `asset()`. A value of type(uint256).max means no cap is enforced. This limit is used to restrict deposits/mints to avoid excessive exposure.The vault's totalAssets can get higher than the cap in case of donations, accrued yield, etc.\",\"returns\":{\"_0\":\"The maximum totalAssets allowed in the vault\"}},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`.\"},\"unpause()\":{\"details\":\"Only addresses with VAULT_MANAGER_ROLE can unpause the vault\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"version()\":{\"returns\":{\"_0\":\"The version of the vault\"}},\"withdraw(uint256,address,address)\":{\"details\":\"Prevents reentrancy, mints performance fees\"}},\"stateVariables\":{\"DEFAULT_MAX_SLIPPAGE_PERCENT\":{\"details\":\"The default maximum slippage percent for rebalancing in PERCENT\"},\"MAX_STRATEGIES\":{\"details\":\"The maximum number of strategies that can be added to the vault\"}},\"title\":\"VeryLiquidVault\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addStrategy(address)\":{\"notice\":\"Adds a new strategy to the vault\"},\"auth()\":{\"notice\":\"Returns the address of the Auth contract used for permission checks\"},\"feeRecipient()\":{\"notice\":\"Returns the fee recipient\"},\"highWaterMark()\":{\"notice\":\"Returns the high water mark\"},\"initialize(address,address,string,string,address,uint256)\":{\"notice\":\"Initializes the BaseVault with necessary parameters\"},\"initialize(address,address,string,string,address,uint256,address[])\":{\"notice\":\"Initializes the VeryLiquidVault with strategies\"},\"isStrategy(address)\":{\"notice\":\"Returns true if the strategy is in the vault\"},\"pause()\":{\"notice\":\"Pauses the vault\"},\"performanceFeePercent()\":{\"notice\":\"Returns the performance fee percent\"},\"rebalance(address,address,uint256,uint256)\":{\"notice\":\"Rebalances assets between two strategies\"},\"rebalanceMaxSlippagePercent()\":{\"notice\":\"Returns the rebalance max slippage percent\"},\"removeStrategy(address,address,uint256,uint256)\":{\"notice\":\"Removes a strategy from the vault and transfers all assets, if any, to another strategy\"},\"reorderStrategies(address[])\":{\"notice\":\"Reorders the strategies\"},\"setFeeRecipient(address)\":{\"notice\":\"Sets the fee recipient\"},\"setPerformanceFeePercent(uint256)\":{\"notice\":\"Sets the performance fee percent\"},\"setRebalanceMaxSlippagePercent(uint256)\":{\"notice\":\"Sets the rebalance max slippage percent\"},\"setTotalAssetsCap(uint256)\":{\"notice\":\"Sets the maximum total assets of the vault\"},\"strategies()\":{\"notice\":\"Returns the strategies in the vault\"},\"strategies(uint256)\":{\"notice\":\"Returns the strategy at the given index\"},\"strategiesCount()\":{\"notice\":\"Returns the number of strategies in the vault\"},\"totalAssetsCap()\":{\"notice\":\"Returns the maximum amount of underlying assets that the vault can hold.\"},\"unpause()\":{\"notice\":\"Unpauses the vault\"},\"version()\":{\"notice\":\"Returns the version of the vault\"}},\"notice\":\"Very Liquid Vault that distributes assets across multiple strategies\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/VeryLiquidVault.sol\":\"VeryLiquidVault\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@a16z/erc4626-tests/=lib/erc4626-tests/\",\":@aave/=lib/aave-v3-origin/src/\",\":@axelar-network/axelar-gmp-sdk-solidity/=lib/openzeppelin-community-contracts/lib/axelar-gmp-sdk-solidity/\",\":@chimera/=lib/chimera/src/\",\":@create2deployer/=lib/create2deployer/contracts/\",\":@crytic/properties/=lib/properties/\",\":@openzeppelin-community-contracts/=lib/openzeppelin-community-contracts/\",\":@openzeppelin-contracts-upgradeable/=lib/openzeppelin-community-contracts/lib/@openzeppelin-contracts-upgradeable/\",\":@openzeppelin-contracts/=lib/openzeppelin-community-contracts/lib/@openzeppelin-contracts/\",\":@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":@openzeppelin/=lib/openzeppelin-contracts/\",\":@recon/=lib/setup-helpers/src/\",\":@rv/ercx/=lib/ercx-tests/\",\":@script/=script/\",\":@src/=src/\",\":@test/=test/\",\":@zk-email/contracts/=lib/openzeppelin-community-contracts/lib/zk-email-verify/packages/contracts/\",\":@zk-email/email-tx-builder/=lib/openzeppelin-community-contracts/lib/email-tx-builder/packages/contracts/\",\":ERC4626/=lib/properties/lib/ERC4626/contracts/\",\":aave-v3-origin/=lib/aave-v3-origin/\",\":axelar-gmp-sdk-solidity/=lib/openzeppelin-community-contracts/lib/axelar-gmp-sdk-solidity/contracts/\",\":chimera/=lib/chimera/src/\",\":console3/=lib/console3/src/\",\":create2deployer/=lib/create2deployer/\",\":ds-test/=lib/ercx-tests/lib/forge-std/lib/ds-test/src/\",\":email-tx-builder/=lib/openzeppelin-community-contracts/lib/email-tx-builder/\",\":erc4626-tests/=lib/erc4626-tests/\",\":ercx-tests/=lib/ercx-tests/src/\",\":ercx/=lib/ercx-tests/src/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-community-contracts/=lib/openzeppelin-community-contracts/contracts/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\",\":properties/=lib/properties/contracts/\",\":setup-helpers/=lib/setup-helpers/src/\",\":solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/\",\":solmate/=lib/properties/lib/solmate/src/\",\":zk-email-verify/=lib/openzeppelin-community-contracts/lib/zk-email-verify/\"]},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol\":{\"keccak256\":\"0x0d4d7d19a052a2ef9d17b28450133631188b895e1755747fa8ad0280aadfb534\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://838551e10cc07e570b70aee1078e490658d3a0ab8f4adfd4f3f2a565200753da\",\"dweb:/ipfs/QmceT7R3Pqzywyxr3MSEA7VXU4axZAPS6BLy92iV97rGdG\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/access/extensions/AccessControlEnumerableUpgradeable.sol\":{\"keccak256\":\"0xaec38804089a16494f7d45ebbbeab78fe05e5dc4bc2eae1d2af458fe999fb43c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://04796408e2c4a1051afb23319e9505edb595a3d9c663ff5d6fcfb8e185ab1d93\",\"dweb:/ipfs/Qma8ZTi4kGyqg45SyNibbJSqMF7broiQnJPHhEGLcZyF9U\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0xdb4d24ee2c087c391d587cd17adfe5b3f9d93b3110b1388c2ab6c7c0ad1dcd05\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ab7b6d5b9e2b88176312967fe0f0e78f3d9a1422fa5e4b64e2440c35869b5d08\",\"dweb:/ipfs/QmXKYWWyzcLg1B2k7Sb1qkEXgLCYfXecR9wYW5obRzWP1Q\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol\":{\"keccak256\":\"0x574a7451e42724f7de29e2855c392a8a5020acd695169466a18459467d719d63\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5bc189f63b639ee173dd7b6fecc39baf7113bf161776aea22b34c57fdd1872ec\",\"dweb:/ipfs/QmZAf2VtjDLRULqjJkde6LNsxAg12tUqpPqgUQQZbAjgtZ\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol\":{\"keccak256\":\"0xa0e86b70fa5a7bd63795161c0882676fde6a18bbb1991938ef014fb0184b4b13\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1727a5d693a56ed6af48bace20d8ec26232f0a8f78ff482c5a691cc5c348a019\",\"dweb:/ipfs/QmdXaYmoETBqAv4YBnSmZyuoovjQMsDjfjnCnBFqXhhQEB\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol\":{\"keccak256\":\"0x4c6100a8ab53ef249c937067f7d9779ee0966fb55b39903628c169428fdeee76\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2b96738706660e46a7d77d13e14191d658b87720e2000a52c02890505183c118\",\"dweb:/ipfs/QmRUjhpmBAEmVEqD4L5LznnDR9gQdgXg17kZExC9N55Q63\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol\":{\"keccak256\":\"0xbfe5549cecc504b56c529ba14178bd6e30b31e43c4f45aa5ab918dc8525a2946\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4a7f398ddf1699fa9ff66b97889a13ccfe971979d0b0e9d40227dd33776e5981\",\"dweb:/ipfs/QmaZPFDKzSwRevg8PoLuTX7DvQyLPRU1PBqwXc5XrWhgZQ\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://08e39f23d5b4692f9a40803e53a8156b72b4c1f9902a88cd65ba964db103dab9\",\"dweb:/ipfs/QmPKn6EYDgpga7KtpkA8wV2yJCYGMtc9K4LkJfhKX2RVSV\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol\":{\"keccak256\":\"0xe5775eb1fb17165cd191e8f8b2232dbea8765e7e610eaa3d6e52feead793ec5a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://352614aea75c3d913cbcabb528be3d6c3335c3c77da41d59486a3193069dd095\",\"dweb:/ipfs/QmR3Nabxfme6tHrAMJCyK4MWZtpund2c4R7aFKmea3sGZM\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/NoncesUpgradeable.sol\":{\"keccak256\":\"0x778f4a1546a1c6c726ecc8e2348a2789690fb8f26e12bd9d89537669167b79a4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://851d3dfe724e918ff0a064b206e1ef46b27ab0df2aa2c8af976973a22ef59827\",\"dweb:/ipfs/Qmd4wb7zX8ueYhMVBy5PJjfsANK3Ra3pKPN7qQkNsdwGHn\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol\":{\"keccak256\":\"0xa6bf6b7efe0e6625a9dcd30c5ddf52c4c24fe8372f37c7de9dbf5034746768d5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8c353ee3705bbf6fadb84c0fb10ef1b736e8ca3ca1867814349d1487ed207beb\",\"dweb:/ipfs/QmcugaPssrzGGE8q4YZKm2ZhnD3kCijjcgdWWg76nWt3FY\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol\":{\"keccak256\":\"0x361126a17677994081cd9cb69c3f50cffff6e920d25cb7e428acdb1ae41d1866\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://19ae787a7dd001269cd60a394b1a5261b78925a0fc3a6f927beb2986a9aa56cf\",\"dweb:/ipfs/QmYLfXiuKmcRgTDBEDXMMjXU8t6JxsspUmjxYzqWS55oEv\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol\":{\"keccak256\":\"0xd45a5b1d0e451376b08e1bc7e332426c24382053300acf0ac667be1b8abb6cc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://824eb0b8c71db8b95b707218d8540c2046a2fefc642e74b343ae90e5c72e2b52\",\"dweb:/ipfs/QmdQTZTomqxRrySDNdv1FEyh3ZWibxwC9FRdcV3DCuASpx\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol\":{\"keccak256\":\"0xc8ed8d2056934b7675b695dec032f2920c2f5c6cf33a17ca85650940675323ab\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3c8ccc75d1cd792d192aa09e54dd49ea35fe85baa9fcd17486f29227d9f29b89\",\"dweb:/ipfs/QmbboSbFUEiM9tdEgBwuTRb7bykFoJXZ7dsSr1PSREJXMr\"]},\"lib/openzeppelin-contracts/contracts/access/IAccessControl.sol\":{\"keccak256\":\"0x4d9a2b261b56a1e4a37bb038151dec98b952fed16de2bdfdda27e38e2b12b530\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f724110f7aeb6151af800ab8c12e6060b29bda9e013f0ccb331eb754d6a7cbf0\",\"dweb:/ipfs/QmUcjzCZpxtUPdEThtAzE1f9LvuJiUGZxTdH9N6bHrb5Cf\"]},\"lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol\":{\"keccak256\":\"0xca774fbe0568762efdc1a7cba31f09549c7fa96dbe97410f4843fa2f0bc000a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0187ffdbf3d61b6d86cba4fcd9826e53d876987d620533ee84c681bdaf0f3ba3\",\"dweb:/ipfs/QmVJDqdJv6uzHY7ifncfv2QJep8XTzS3bGb4s5Exhuv86m\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0x9b6b3e7803bc5f2f8cd7ad57db8ac1def61a9930a5a3107df4882e028a9605d7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da62d6be1f5c6edf577f0cb45666a8aa9c2086a4bac87d95d65f02e2f4c36a4b\",\"dweb:/ipfs/QmNkpvBpoCMvX8JwAFNSc5XxJ2q5BXJpL5L1txb4QkqVFF\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0xde7e9fd9aee8d4f40772f96bb3b58836cbc6dfc0227014a061947f8821ea9724\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11fea9f8bc98949ac6709f0c1699db7430d2948137aa94d5a9e95a91f61a710a\",\"dweb:/ipfs/QmQdfRXxQjwP6yn3DVo1GHPpriKNcFghSPi94Z1oKEFUNS\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol\":{\"keccak256\":\"0xb25a4f11fa80c702bf5cd85adec90e6f6f507f32f4a8e6f5dbc31e8c10029486\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6917f8a323e7811f041aecd4d9fd6e92455a6fba38a797ac6f6e208c7912b79d\",\"dweb:/ipfs/QmShuYv55wYHGi4EFkDB8QfF7ZCHoKk2efyz3AWY1ExSq7\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0xce41876e78d1badc0512229b4d14e4daf83bc1003d7f83978d18e0e56f965b9c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a2608291cb038b388d80b79a06b6118a42f7894ff67b7da10ec0dbbf5b2973ba\",\"dweb:/ipfs/QmWohqcBLbcxmA4eGPhZDXe5RYMMEEpFq22nfkaUMvTfw1\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol\":{\"keccak256\":\"0x7b6690c21e94a45b825631a12581b40a753ea827de5ac9127a6b5833411317f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://00045f2c18d7866618c65819fe180a9a9dab25c1974fab35069bdac9cf624b6b\",\"dweb:/ipfs/QmYk62QRqGHJ3rjqfEtbfEGFHWsenv5tNMbeMfq5HkTP44\"]},\"lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol\":{\"keccak256\":\"0x92aa1df62dc3d33f1656d63bede0923e0df0b706ad4137c8b10b0a8fe549fd92\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c5c0f29195ad64cbe556da8e257dac8f05f78c53f90323c0d2accf8e6922d33a\",\"dweb:/ipfs/QmQ61TED8uaCZwcbh8KkgRSsCav7x7HbcGHwHts3U4DmUP\"]},\"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol\":{\"keccak256\":\"0xc42facb5094f2f35f066a7155bda23545e39a3156faef3ddc00185544443ba7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d3b36282ab029b46bd082619a308a2ea11c309967b9425b7b7a6eb0b0c1c3196\",\"dweb:/ipfs/QmP2YVfDB2FoREax3vJu7QhDnyYRMw52WPrCD4vdT2kuDA\"]},\"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol\":{\"keccak256\":\"0x880da465c203cec76b10d72dbd87c80f387df4102274f23eea1f9c9b0918792b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://399594cd8bb0143bc9e55e0f1d071d0d8c850a394fb7a319d50edd55d9ed822b\",\"dweb:/ipfs/QmbPZzgtT6LEm9CMqWfagQFwETbV1ztpECBB1DtQHrKiRz\"]},\"lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol\":{\"keccak256\":\"0x8decfa54cec979c824b044b8128cd91d713f72c71fd7dfa54974624d8c949898\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://271f914261a19d87117a777e0924ada545c16191ef9b00cc40b0134fc14ebc70\",\"dweb:/ipfs/QmdvVNWHGHQrGGPonZJs5NuzTevTjZRM2zayKrDJf7WBA2\"]},\"lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol\":{\"keccak256\":\"0xc59a78b07b44b2cf2e8ab4175fca91e8eca1eee2df7357b8d2a8833e5ea1f64c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5aa4f07e65444784c29cd7bfcc2341b34381e4e5b5da9f0c5bd00d7f430e66fa\",\"dweb:/ipfs/QmWRMh4Q9DpaU9GvsiXmDdoNYMyyece9if7hnfLz7uqzWM\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db\",\"dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x70f2f713b13b7ce4610bcd0ac9fec0f3cc43693b043abcb8dc40a42a726eb330\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c13d13304ac79a83ab1c30168967d19e2203342ebbd6a9bbce4db7550522dcbf\",\"dweb:/ipfs/QmeN5jKMN2vw5bhacr6tkg78afbTTZUeaacNHqjWt4Ew1r\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x27dbc90e5136ffe46c04f7596fc2dbcc3acebd8d504da3d93fdb8496e6de04f6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea8b92e4245d75a5579c10f22f118f7b4ba07c57341f181f0b2a85ff8663de3\",\"dweb:/ipfs/Qme3Ss5ByjmkxxkMdLpyu7fQ1PCtjNFH1wEFszt2BZePiG\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x982c5cb790ab941d1e04f807120a71709d4c313ba0bfc16006447ffbd27fbbd5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8150ceb4ac947e8a442b2a9c017e01e880b2be2dd958f1fa9bc405f4c5a86508\",\"dweb:/ipfs/QmbcBmFX66AY6Kbhnd5gx7zpkgqnUafo43XnmayAM7zVdB\"]},\"lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaaa1d17c1129b127a4a401db2fbd72960e2671474be3d08cae71ccdc42f7624c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cb2f27cd3952aa667e198fba0d9b7bcec52fbb12c16f013c25fe6fb52b29cc0e\",\"dweb:/ipfs/QmeuohBFoeyDPZA9JNCTEDz3VBfBD4EABWuWXVhHAuEpKR\"]},\"lib/openzeppelin-contracts/contracts/utils/Arrays.sol\":{\"keccak256\":\"0x55a4fdb408e3db950b48f4a6131e538980be8c5f48ee59829d92d66477140cd6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3e1ad251e692822ce1494135a4ecb5b97c19b90aa82418fd2959ce32017953fd\",\"dweb:/ipfs/QmT6N7mf6heZYhY2BAQ5kwZp9o3SXzGVdkMqUszx67WRDN\"]},\"lib/openzeppelin-contracts/contracts/utils/Comparators.sol\":{\"keccak256\":\"0x302eecd8cf323b4690e3494a7d960b3cbce077032ab8ef655b323cdd136cec58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://49ba706f1bc476d68fe6c1fad75517acea4e9e275be0989b548e292eb3a3eacd\",\"dweb:/ipfs/QmeBpvcdGWzWMKTQESUCEhHgnEQYYATVwPxLMxa6vMT7jC\"]},\"lib/openzeppelin-contracts/contracts/utils/Errors.sol\":{\"keccak256\":\"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf\",\"dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB\"]},\"lib/openzeppelin-contracts/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol\":{\"keccak256\":\"0x67672e4ca1dafdcc661d4eba8475cfac631fa0933309258e3af7644b92e1fb26\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://30192451f05ea5ddb0c18bd0f9003f098505836ba19c08a9c365adf829454da2\",\"dweb:/ipfs/QmfCuZSCTyCdFoSKn7MSaN6hZksnQn9ZhrZDAdRTCbwGu2\"]},\"lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x81c274a60a7ae232ae3dc9ff3a4011b4849a853c13b0832cd3351bb1bb2f0dae\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9da0c20dc74358a2a76330818f3bac9d1e2ce3371aec847b9cbf5d147fbae4f6\",\"dweb:/ipfs/QmeczhmnFv1hbXKGLwbYXY6Rrytc9a5A2YaRi5QMMgjPnb\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x69f54c02b7d81d505910ec198c11ed4c6a728418a868b906b4a0cf29946fda84\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8e25e4bdb7ae1f21d23bfee996e22736fc0ab44cfabedac82a757b1edc5623b9\",\"dweb:/ipfs/QmQdWQvB6JCP9ZMbzi8EvQ1PTETqkcTWrbcVurS7DKpa5n\"]},\"lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol\":{\"keccak256\":\"0x26670fef37d4adf55570ba78815eec5f31cb017e708f61886add4fc4da665631\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b16d45febff462bafd8a5669f904796a835baf607df58a8461916d3bf4f08c59\",\"dweb:/ipfs/QmU2eJFpjmT4vxeJWJyLeQb8Xht1kdB8Y6MKLDPFA9WPux\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x79796192ec90263f21b464d5bc90b777a525971d3de8232be80d9c4f9fb353b8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f6fda447a62815e8064f47eff0dd1cf58d9207ad69b5d32280f8d7ed1d1e4621\",\"dweb:/ipfs/QmfDRc7pxfaXB2Dh9np5Uf29Na3pQ7tafRS684wd3GLjVL\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x1225214420c83ebcca88f2ae2b50f053aaa7df7bd684c3e878d334627f2edfc6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6c5fab4970634f9ab9a620983dc1c8a30153981a0b1a521666e269d0a11399d3\",\"dweb:/ipfs/QmVRnBC575MESGkEHndjujtR7qub2FzU9RWy9eKLp4hPZB\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8\",\"dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03\",\"dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ\"]},\"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol\":{\"keccak256\":\"0xecd5f3c702f549fb88555e44e5f2415a4dfd6db09081aec7e98c26b6a3739c06\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed40e907a6d80458a0556a609d0d3991d718c20f9f1f21475e5ec739af523231\",\"dweb:/ipfs/QmejkwADsZRxkusNU94sswMJfpLrbq8RkJTbNccUEQpc7Y\"]},\"src/Auth.sol\":{\"keccak256\":\"0x2f108092253eedadac5a8efbb9916307ddb50f104a7dba2d8673033744536b35\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e58db9ad4a7c3e5d3978a11ef4193da8f7519100913b52e14d31c200fcad2bb0\",\"dweb:/ipfs/QmdbpLGnc9FjGAK6SC2X9mw9TfnrtCTx71YkHypzcQ6NR8\"]},\"src/IVault.sol\":{\"keccak256\":\"0x091b24377a23e5729da0e837dc31757be79ae83622c8fa7f9bbd7629eaf5ca22\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b34a58352f0ee3797f290ab36278773aeabfeebedef8675b7933201c869330dd\",\"dweb:/ipfs/QmQUTZkyCHjjXRKosDQRJcCkbrHGGP3uhTRaSEG3UnUwEd\"]},\"src/VeryLiquidVault.sol\":{\"keccak256\":\"0xd57f496413ef2a33718f9bb9c7832673abba2825457769446afd3d55e86026d4\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e20119b89fe3231dab9549ac65ac912a30f82666b11211deefbc5a993ecb5347\",\"dweb:/ipfs/QmTs9KLqQHBLxgyLoeLCAeQZmgqcLq1JKh6SbLWUB6naaU\"]},\"src/utils/BaseVault.sol\":{\"keccak256\":\"0x4de7701fa4e90b2c95e2cfe9ba4b0d357e16babb29a270881bea09c2c711753f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3c5df8747931a42f198e9ebdff8a699e5c7267bdb8e744527a8eeb9b5e057b4c\",\"dweb:/ipfs/QmNUpisG5vp5ppTyxTA5VRfRgJh6P6zCfNQRmvLbdZ5PeG\"]},\"src/utils/PerformanceVault.sol\":{\"keccak256\":\"0x97a143757550307521cd3b5d5a8f45fdf307e38ccdad149dd5a41fcfc2c7ca3f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b24a4bf4da2ba37919fd50b5dc55ceb505f6963becd686bad97f3f6acc1e9cd2\",\"dweb:/ipfs/QmQ1AFFsmZbBwKnhyBxk3ctjcdrekmrfcUHiiCmzFeX8sG\"]},\"src/utils/ReentrancyGuardUpgradeableWithViewModifier.sol\":{\"keccak256\":\"0x9f05fa0ee789165434647ee899927f23ccb642c2a3fab6b614545777b3ad5752\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://87d9debee76870bc4cbf6ec069c880cd204e5a78bdb5df1029335d0b6b89dff1\",\"dweb:/ipfs/QmYWsfvkRZi8Y7yKe72FJUbwmU8TQwBnmS3zrpzr6S8coS\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.26+commit.8a97fa7a"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"type":"error","name":"AccessControlUnauthorizedAccount"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"type":"error","name":"AddressEmptyCode"},{"inputs":[{"internalType":"uint256","name":"expectedLength","type":"uint256"},{"internalType":"uint256","name":"actualLength","type":"uint256"}],"type":"error","name":"ArrayLengthMismatch"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"remainingAssets","type":"uint256"}],"type":"error","name":"CannotDepositToStrategies"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"missingAssets","type":"uint256"}],"type":"error","name":"CannotWithdrawFromStrategies"},{"inputs":[],"type":"error","name":"ECDSAInvalidSignature"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"type":"error","name":"ECDSAInvalidSignatureLength"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"type":"error","name":"ECDSAInvalidSignatureS"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"type":"error","name":"ERC1967InvalidImplementation"},{"inputs":[],"type":"error","name":"ERC1967NonPayable"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"ERC20InsufficientAllowance"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"ERC20InsufficientBalance"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"type":"error","name":"ERC20InvalidApprover"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"type":"error","name":"ERC20InvalidReceiver"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"type":"error","name":"ERC20InvalidSender"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"type":"error","name":"ERC20InvalidSpender"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"type":"error","name":"ERC2612ExpiredSignature"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"type":"error","name":"ERC2612InvalidSigner"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"type":"error","name":"ERC4626ExceededMaxDeposit"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"type":"error","name":"ERC4626ExceededMaxMint"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"type":"error","name":"ERC4626ExceededMaxRedeem"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"type":"error","name":"ERC4626ExceededMaxWithdraw"},{"inputs":[],"type":"error","name":"EnforcedPause"},{"inputs":[],"type":"error","name":"ExpectedPause"},{"inputs":[],"type":"error","name":"FailedCall"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"type":"error","name":"InvalidAccountNonce"},{"inputs":[],"type":"error","name":"InvalidInitialization"},{"inputs":[{"internalType":"uint256","name":"maxSlippagePercent","type":"uint256"}],"type":"error","name":"InvalidMaxSlippagePercent"},{"inputs":[{"internalType":"address","name":"strategy","type":"address"}],"type":"error","name":"InvalidStrategy"},{"inputs":[{"internalType":"uint256","name":"strategiesCount","type":"uint256"},{"internalType":"uint256","name":"maxStrategies","type":"uint256"}],"type":"error","name":"MaxStrategiesExceeded"},{"inputs":[],"type":"error","name":"NotInitializing"},{"inputs":[],"type":"error","name":"NullAddress"},{"inputs":[],"type":"error","name":"NullAmount"},{"inputs":[{"internalType":"uint256","name":"performanceFeePercent","type":"uint256"},{"internalType":"uint256","name":"maximumPerformanceFeePercent","type":"uint256"}],"type":"error","name":"PerformanceFeePercentTooHigh"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"type":"error","name":"SafeERC20FailedOperation"},{"inputs":[{"internalType":"uint256","name":"assetsBefore","type":"uint256"},{"internalType":"uint256","name":"assetsAfter","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxSlippagePercent","type":"uint256"}],"type":"error","name":"TransferredAmountLessThanMin"},{"inputs":[],"type":"error","name":"UUPSUnauthorizedCallContext"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"type":"error","name":"UUPSUnsupportedProxiableUUID"},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"spender","type":"address","indexed":true},{"internalType":"uint256","name":"value","type":"uint256","indexed":false}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"auth","type":"address","indexed":true}],"type":"event","name":"AuthSet","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"uint256","name":"assets","type":"uint256","indexed":false},{"internalType":"uint256","name":"shares","type":"uint256","indexed":false}],"type":"event","name":"Deposit","anonymous":false},{"inputs":[{"internalType":"address","name":"strategy","type":"address","indexed":true},{"internalType":"uint256","name":"amount","type":"uint256","indexed":false}],"type":"event","name":"DepositFailed","anonymous":false},{"inputs":[],"type":"event","name":"EIP712DomainChanged","anonymous":false},{"inputs":[{"internalType":"address","name":"feeRecipientBefore","type":"address","indexed":true},{"internalType":"address","name":"feeRecipientAfter","type":"address","indexed":true}],"type":"event","name":"FeeRecipientSet","anonymous":false},{"inputs":[{"internalType":"uint256","name":"highWaterMarkBefore","type":"uint256","indexed":false},{"internalType":"uint256","name":"highWaterMarkAfter","type":"uint256","indexed":false}],"type":"event","name":"HighWaterMarkUpdated","anonymous":false},{"inputs":[{"internalType":"uint64","name":"version","type":"uint64","indexed":false}],"type":"event","name":"Initialized","anonymous":false},{"inputs":[{"internalType":"address","name":"account","type":"address","indexed":false}],"type":"event","name":"Paused","anonymous":false},{"inputs":[{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"shares","type":"uint256","indexed":false},{"internalType":"uint256","name":"assets","type":"uint256","indexed":false}],"type":"event","name":"PerformanceFeeMinted","anonymous":false},{"inputs":[{"internalType":"uint256","name":"performanceFeePercentBefore","type":"uint256","indexed":true},{"internalType":"uint256","name":"performanceFeePercentAfter","type":"uint256","indexed":true}],"type":"event","name":"PerformanceFeePercentSet","anonymous":false},{"inputs":[{"internalType":"uint256","name":"oldRebalanceMaxSlippagePercent","type":"uint256","indexed":false},{"internalType":"uint256","name":"newRebalanceMaxSlippagePercent","type":"uint256","indexed":false}],"type":"event","name":"RebalanceMaxSlippagePercentSet","anonymous":false},{"inputs":[{"internalType":"address","name":"strategyFrom","type":"address","indexed":true},{"internalType":"address","name":"strategyTo","type":"address","indexed":true},{"internalType":"uint256","name":"rebalancedAmount","type":"uint256","indexed":false},{"internalType":"uint256","name":"maxSlippagePercent","type":"uint256","indexed":false}],"type":"event","name":"Rebalanced","anonymous":false},{"inputs":[{"internalType":"address","name":"strategy","type":"address","indexed":true}],"type":"event","name":"StrategyAdded","anonymous":false},{"inputs":[{"internalType":"address","name":"strategy","type":"address","indexed":true}],"type":"event","name":"StrategyRemoved","anonymous":false},{"inputs":[{"internalType":"address","name":"strategyOld","type":"address","indexed":true},{"internalType":"address","name":"strategyNew","type":"address","indexed":true},{"internalType":"uint256","name":"index","type":"uint256","indexed":true}],"type":"event","name":"StrategyReordered","anonymous":false},{"inputs":[{"internalType":"uint256","name":"totalAssetsCapBefore","type":"uint256","indexed":true},{"internalType":"uint256","name":"totalAssetsCapAfter","type":"uint256","indexed":true}],"type":"event","name":"TotalAssetsCapSet","anonymous":false},{"inputs":[{"internalType":"address","name":"from","type":"address","indexed":true},{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"value","type":"uint256","indexed":false}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"account","type":"address","indexed":false}],"type":"event","name":"Unpaused","anonymous":false},{"inputs":[{"internalType":"address","name":"implementation","type":"address","indexed":true}],"type":"event","name":"Upgraded","anonymous":false},{"inputs":[{"internalType":"uint256","name":"totalShares","type":"uint256","indexed":false},{"internalType":"uint256","name":"totalAssets","type":"uint256","indexed":false}],"type":"event","name":"VaultStatus","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":true},{"internalType":"address","name":"receiver","type":"address","indexed":true},{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"uint256","name":"assets","type":"uint256","indexed":false},{"internalType":"uint256","name":"shares","type":"uint256","indexed":false}],"type":"event","name":"Withdraw","anonymous":false},{"inputs":[{"internalType":"address","name":"strategy","type":"address","indexed":true},{"internalType":"uint256","name":"amount","type":"uint256","indexed":false}],"type":"event","name":"WithdrawFailed","anonymous":false},{"inputs":[],"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"contract IVault","name":"strategy_","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"addStrategy"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"stateMutability":"view","type":"function","name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"auth","outputs":[{"internalType":"contract Auth","name":"","type":"address"}]},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function","name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function","name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}]},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"feeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"highWaterMark","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"contract Auth","name":"auth_","type":"address"},{"internalType":"contract IERC20","name":"asset_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"fundingAccount","type":"address"},{"internalType":"uint256","name":"firstDepositAmount","type":"uint256"},{"internalType":"contract IVault[]","name":"strategies_","type":"address[]"}],"stateMutability":"nonpayable","type":"function","name":"initialize"},{"inputs":[{"internalType":"contract Auth","name":"auth_","type":"address"},{"internalType":"contract IERC20","name":"asset_","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"fundingAccount_","type":"address"},{"internalType":"uint256","name":"firstDepositAmount_","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"initialize"},{"inputs":[{"internalType":"contract IVault","name":"strategy","type":"address"}],"stateMutability":"view","type":"function","name":"isStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"stateMutability":"view","type":"function","name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"stateMutability":"view","type":"function","name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function","name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"pause"},{"inputs":[],"stateMutability":"view","type":"function","name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"performanceFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"stateMutability":"nonpayable","type":"function","name":"permit"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function","name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function","name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function","name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function","name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"contract IVault","name":"strategyFrom","type":"address"},{"internalType":"contract IVault","name":"strategyTo","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxSlippagePercent","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"rebalance"},{"inputs":[],"stateMutability":"view","type":"function","name":"rebalanceMaxSlippagePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"contract IVault","name":"strategyToRemove","type":"address"},{"internalType":"contract IVault","name":"strategyToReceiveAssets","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxSlippagePercent","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"removeStrategy"},{"inputs":[{"internalType":"contract IVault[]","name":"newStrategiesOrder","type":"address[]"}],"stateMutability":"nonpayable","type":"function","name":"reorderStrategies"},{"inputs":[{"internalType":"address","name":"feeRecipient_","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"setFeeRecipient"},{"inputs":[{"internalType":"uint256","name":"performanceFeePercent_","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setPerformanceFeePercent"},{"inputs":[{"internalType":"uint256","name":"rebalanceMaxSlippagePercent_","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setRebalanceMaxSlippagePercent"},{"inputs":[{"internalType":"uint256","name":"totalAssetsCap_","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"setTotalAssetsCap"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function","name":"strategies","outputs":[{"internalType":"contract IVault","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"strategies","outputs":[{"internalType":"contract IVault[]","name":"","type":"address[]"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"strategiesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"totalAssets","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"totalAssetsCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"nonpayable","type":"function","name":"unpause"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"payable","type":"function","name":"upgradeToAndCall"},{"inputs":[],"stateMutability":"pure","type":"function","name":"version","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"function","name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{"DOMAIN_SEPARATOR()":{"details":"Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}."},"addStrategy(address)":{"details":"Only callable by addresses with VAULT_MANAGER_ROLE","params":{"strategy_":"The new strategy to add"}},"allowance(address,address)":{"details":"See {IERC20-allowance}."},"approve(address,uint256)":{"details":"See {IERC20-approve}. NOTE: If `value` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address."},"asset()":{"details":"See {IERC4626-asset}. "},"auth()":{"details":"The Auth contract manages roles and access control for vault operationsExternal integrators can use this to query permissions but should not rely on its internal logic directly"},"balanceOf(address)":{"details":"See {IERC20-balanceOf}."},"constructor":{"custom:oz-upgrades-unsafe-allow":"constructor"},"convertToAssets(uint256)":{"details":"See {IERC4626-convertToAssets}. "},"convertToShares(uint256)":{"details":"See {IERC4626-convertToShares}. "},"decimals()":{"details":"Returns the decimals places of the token."},"deposit(uint256,address)":{"details":"Prevents reentrancy, mints performance fees"},"eip712Domain()":{"details":"returns the fields and values that describe the domain separator used by this contract for EIP-712 signature."},"initialize(address,address,string,string,address,uint256)":{"details":"Sets up all inherited contracts and makes the first deposit to prevent inflation attacks","params":{"asset_":"The address of the asset","auth_":"The address of the Auth contract","firstDepositAmount_":"The amount of the first deposit, which will be treated as dead shares","fundingAccount_":"The address of the funding account for the first deposit, which will be treated as dead shares","name_":"The name of the vault","symbol_":"The symbol of the vault"}},"initialize(address,address,string,string,address,uint256,address[])":{"params":{"asset_":"The address of the asset","auth_":"The address of the Auth contract","firstDepositAmount":"The amount of the first deposit, which will be treated as dead shares","fundingAccount":"The address of the funding account for the first deposit, which will be treated as dead shares","name_":"The name of the vault","strategies_":"The initial strategies to add to the vault","symbol_":"The symbol of the vault"}},"isStrategy(address)":{"params":{"strategy":"The strategy to check"},"returns":{"_0":"True if the strategy is in the vault"}},"maxDeposit(address)":{"details":"The maximum amount that can be deposited is the minimum between this receiver specific limit and the maximum asset amount that can be deposited to all strategies"},"maxMint(address)":{"details":"The maximum amount that can be minted is the minimum between this receiver specific limit and the maximum asset amount that can be minted to all strategies, converted to shares"},"maxRedeem(address)":{"details":"The maximum amount that can be redeemed is the minimum between this owner specific limit and the maximum asset amount that can be redeemed from all strategies, converted to shares"},"maxWithdraw(address)":{"details":"The maximum amount that can be withdrawn is the minimum between this owner specific limit and the maximum asset amount that can be withdrawn from all strategies"},"mint(uint256,address)":{"details":"Prevents reentrancy, mints performance fees"},"multicall(bytes[])":{"custom:oz-upgrades-unsafe-allow-reachable":"delegatecall","details":"Receives and executes a batch of function calls on this contract."},"name()":{"details":"Returns the name of the token."},"nonces(address)":{"details":"Returns the current nonce for `owner`. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases ``owner``'s nonce by one. This prevents a signature from being used multiple times."},"pause()":{"details":"Only addresses with GUARDIAN_ROLE can pause the vault"},"paused()":{"details":"Returns true if the contract is paused, and false otherwise."},"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)":{"details":"Sets `value` as the allowance of `spender` over ``owner``'s tokens, given ``owner``'s signed approval. IMPORTANT: The same issues {IERC20-approve} has related to transaction ordering also apply here. Emits an {Approval} event. Requirements: - `spender` cannot be the zero address. - `deadline` must be a timestamp in the future. - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` over the EIP712-formatted function arguments. - the signature must use ``owner``'s current nonce (see {nonces}). For more information on the signature format, see the https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. CAUTION: See Security Considerations above."},"previewDeposit(uint256)":{"details":"See {IERC4626-previewDeposit}. "},"previewMint(uint256)":{"details":"See {IERC4626-previewMint}. "},"previewRedeem(uint256)":{"details":"See {IERC4626-previewRedeem}. "},"previewWithdraw(uint256)":{"details":"See {IERC4626-previewWithdraw}. "},"proxiableUUID()":{"details":"Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier."},"rebalance(address,address,uint256,uint256)":{"details":"Only callable by addresses with STRATEGIST_ROLETransfers assets from one strategy to anotherWe have maxSlippagePercent <= PERCENT since rebalanceMaxSlippagePercent has already been checked in setRebalanceMaxSlippagePercent","params":{"amount":"The amount of assets to transfer","maxSlippagePercent":"The maximum slippage percent allowed for the rebalance","strategyFrom":"The strategy to transfer assets from","strategyTo":"The strategy to transfer assets to"}},"rebalanceMaxSlippagePercent()":{"returns":{"_0":"The rebalance max slippage percent"}},"redeem(uint256,address,address)":{"details":"Prevents reentrancy, mints performance fees"},"removeStrategy(address,address,uint256,uint256)":{"details":"Only callable by addresses with GUARDIAN_ROLEUsing `amount` = 0 will forfeit all assets from `strategyToRemove`Using `amount` = type(uint256).max will attempt to transfer the entire balance from `strategyToRemove`If `convertToAssets(balanceOf)` > `maxWithdraw`, e.g. due to pause/withdraw limits, the _rebalance step will revert, so an appropriate `amount` should be usedReverts if totalAssets() == 0 at the end of the operation, which can happen if the call is performed with 100% slippage","params":{"amount":"The amount of assets to transfer","maxSlippagePercent":"The maximum slippage percent allowed for the rebalance","strategyToReceiveAssets":"The strategy to receive the assets","strategyToRemove":"The strategy to remove"}},"reorderStrategies(address[])":{"details":"Only callable by addresses with STRATEGIST_ROLEVerifies that the new strategies order is valid and that there are no duplicatesClears current strategies and adds them in the new order","params":{"newStrategiesOrder":"The new strategies order"}},"setFeeRecipient(address)":{"details":"Only callable by addresses with DEFAULT_ADMIN_ROLE","params":{"feeRecipient_":"The new fee recipient"}},"setPerformanceFeePercent(uint256)":{"details":"Only callable by addresses with DEFAULT_ADMIN_ROLE","params":{"performanceFeePercent_":"The new performance fee percent"}},"setRebalanceMaxSlippagePercent(uint256)":{"details":"Only callable by addresses with VAULT_MANAGER_ROLE","params":{"rebalanceMaxSlippagePercent_":"The new rebalance max slippage percent"}},"setTotalAssetsCap(uint256)":{"details":"Only addresses with VAULT_MANAGER_ROLE can set the vault capLowering the total assets cap does not affect existing deposited assets","params":{"totalAssetsCap_":"The new total assets cap"}},"strategies()":{"returns":{"_0":"The strategies in the vault"}},"strategies(uint256)":{"params":{"index":"The index of the strategy"},"returns":{"_0":"The strategy at the given index"}},"strategiesCount()":{"returns":{"_0":"The number of strategies in the vault"}},"symbol()":{"details":"Returns the symbol of the token, usually a shorter version of the name."},"totalAssets()":{"details":"The total assets is the sum of the assets in all strategies"},"totalAssetsCap()":{"details":"Expressed in units of the underlying ERC20 `asset()`. A value of type(uint256).max means no cap is enforced. This limit is used to restrict deposits/mints to avoid excessive exposure.The vault's totalAssets can get higher than the cap in case of donations, accrued yield, etc.","returns":{"_0":"The maximum totalAssets allowed in the vault"}},"totalSupply()":{"details":"See {IERC20-totalSupply}."},"transfer(address,uint256)":{"details":"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `value`."},"transferFrom(address,address,uint256)":{"details":"See {IERC20-transferFrom}. Skips emitting an {Approval} event indicating an allowance update. This is not required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `value`. - the caller must have allowance for ``from``'s tokens of at least `value`."},"unpause()":{"details":"Only addresses with VAULT_MANAGER_ROLE can unpause the vault"},"upgradeToAndCall(address,bytes)":{"custom:oz-upgrades-unsafe-allow-reachable":"delegatecall","details":"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event."},"version()":{"returns":{"_0":"The version of the vault"}},"withdraw(uint256,address,address)":{"details":"Prevents reentrancy, mints performance fees"}},"version":1},"userdoc":{"kind":"user","methods":{"addStrategy(address)":{"notice":"Adds a new strategy to the vault"},"auth()":{"notice":"Returns the address of the Auth contract used for permission checks"},"feeRecipient()":{"notice":"Returns the fee recipient"},"highWaterMark()":{"notice":"Returns the high water mark"},"initialize(address,address,string,string,address,uint256)":{"notice":"Initializes the BaseVault with necessary parameters"},"initialize(address,address,string,string,address,uint256,address[])":{"notice":"Initializes the VeryLiquidVault with strategies"},"isStrategy(address)":{"notice":"Returns true if the strategy is in the vault"},"pause()":{"notice":"Pauses the vault"},"performanceFeePercent()":{"notice":"Returns the performance fee percent"},"rebalance(address,address,uint256,uint256)":{"notice":"Rebalances assets between two strategies"},"rebalanceMaxSlippagePercent()":{"notice":"Returns the rebalance max slippage percent"},"removeStrategy(address,address,uint256,uint256)":{"notice":"Removes a strategy from the vault and transfers all assets, if any, to another strategy"},"reorderStrategies(address[])":{"notice":"Reorders the strategies"},"setFeeRecipient(address)":{"notice":"Sets the fee recipient"},"setPerformanceFeePercent(uint256)":{"notice":"Sets the performance fee percent"},"setRebalanceMaxSlippagePercent(uint256)":{"notice":"Sets the rebalance max slippage percent"},"setTotalAssetsCap(uint256)":{"notice":"Sets the maximum total assets of the vault"},"strategies()":{"notice":"Returns the strategies in the vault"},"strategies(uint256)":{"notice":"Returns the strategy at the given index"},"strategiesCount()":{"notice":"Returns the number of strategies in the vault"},"totalAssetsCap()":{"notice":"Returns the maximum amount of underlying assets that the vault can hold."},"unpause()":{"notice":"Unpauses the vault"},"version()":{"notice":"Returns the version of the vault"}},"version":1}},"settings":{"remappings":["@a16z/erc4626-tests/=lib/erc4626-tests/","@aave/=lib/aave-v3-origin/src/","@axelar-network/axelar-gmp-sdk-solidity/=lib/openzeppelin-community-contracts/lib/axelar-gmp-sdk-solidity/","@chimera/=lib/chimera/src/","@create2deployer/=lib/create2deployer/contracts/","@crytic/properties/=lib/properties/","@openzeppelin-community-contracts/=lib/openzeppelin-community-contracts/","@openzeppelin-contracts-upgradeable/=lib/openzeppelin-community-contracts/lib/@openzeppelin-contracts-upgradeable/","@openzeppelin-contracts/=lib/openzeppelin-community-contracts/lib/@openzeppelin-contracts/","@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/","@openzeppelin/=lib/openzeppelin-contracts/","@recon/=lib/setup-helpers/src/","@rv/ercx/=lib/ercx-tests/","@script/=script/","@src/=src/","@test/=test/","@zk-email/contracts/=lib/openzeppelin-community-contracts/lib/zk-email-verify/packages/contracts/","@zk-email/email-tx-builder/=lib/openzeppelin-community-contracts/lib/email-tx-builder/packages/contracts/","ERC4626/=lib/properties/lib/ERC4626/contracts/","aave-v3-origin/=lib/aave-v3-origin/","axelar-gmp-sdk-solidity/=lib/openzeppelin-community-contracts/lib/axelar-gmp-sdk-solidity/contracts/","chimera/=lib/chimera/src/","console3/=lib/console3/src/","create2deployer/=lib/create2deployer/","ds-test/=lib/ercx-tests/lib/forge-std/lib/ds-test/src/","email-tx-builder/=lib/openzeppelin-community-contracts/lib/email-tx-builder/","erc4626-tests/=lib/erc4626-tests/","ercx-tests/=lib/ercx-tests/src/","ercx/=lib/ercx-tests/src/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/","openzeppelin-community-contracts/=lib/openzeppelin-community-contracts/contracts/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/","properties/=lib/properties/contracts/","setup-helpers/=lib/setup-helpers/src/","solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/","solmate/=lib/properties/lib/solmate/src/","zk-email-verify/=lib/openzeppelin-community-contracts/lib/zk-email-verify/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"src/VeryLiquidVault.sol":"VeryLiquidVault"},"evmVersion":"cancun","libraries":{}},"sources":{"lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol":{"keccak256":"0x0d4d7d19a052a2ef9d17b28450133631188b895e1755747fa8ad0280aadfb534","urls":["bzz-raw://838551e10cc07e570b70aee1078e490658d3a0ab8f4adfd4f3f2a565200753da","dweb:/ipfs/QmceT7R3Pqzywyxr3MSEA7VXU4axZAPS6BLy92iV97rGdG"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/access/extensions/AccessControlEnumerableUpgradeable.sol":{"keccak256":"0xaec38804089a16494f7d45ebbbeab78fe05e5dc4bc2eae1d2af458fe999fb43c","urls":["bzz-raw://04796408e2c4a1051afb23319e9505edb595a3d9c663ff5d6fcfb8e185ab1d93","dweb:/ipfs/Qma8ZTi4kGyqg45SyNibbJSqMF7broiQnJPHhEGLcZyF9U"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"keccak256":"0xdb4d24ee2c087c391d587cd17adfe5b3f9d93b3110b1388c2ab6c7c0ad1dcd05","urls":["bzz-raw://ab7b6d5b9e2b88176312967fe0f0e78f3d9a1422fa5e4b64e2440c35869b5d08","dweb:/ipfs/QmXKYWWyzcLg1B2k7Sb1qkEXgLCYfXecR9wYW5obRzWP1Q"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol":{"keccak256":"0x574a7451e42724f7de29e2855c392a8a5020acd695169466a18459467d719d63","urls":["bzz-raw://5bc189f63b639ee173dd7b6fecc39baf7113bf161776aea22b34c57fdd1872ec","dweb:/ipfs/QmZAf2VtjDLRULqjJkde6LNsxAg12tUqpPqgUQQZbAjgtZ"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol":{"keccak256":"0xa0e86b70fa5a7bd63795161c0882676fde6a18bbb1991938ef014fb0184b4b13","urls":["bzz-raw://1727a5d693a56ed6af48bace20d8ec26232f0a8f78ff482c5a691cc5c348a019","dweb:/ipfs/QmdXaYmoETBqAv4YBnSmZyuoovjQMsDjfjnCnBFqXhhQEB"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PermitUpgradeable.sol":{"keccak256":"0x4c6100a8ab53ef249c937067f7d9779ee0966fb55b39903628c169428fdeee76","urls":["bzz-raw://2b96738706660e46a7d77d13e14191d658b87720e2000a52c02890505183c118","dweb:/ipfs/QmRUjhpmBAEmVEqD4L5LznnDR9gQdgXg17kZExC9N55Q63"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol":{"keccak256":"0xbfe5549cecc504b56c529ba14178bd6e30b31e43c4f45aa5ab918dc8525a2946","urls":["bzz-raw://4a7f398ddf1699fa9ff66b97889a13ccfe971979d0b0e9d40227dd33776e5981","dweb:/ipfs/QmaZPFDKzSwRevg8PoLuTX7DvQyLPRU1PBqwXc5XrWhgZQ"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"keccak256":"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397","urls":["bzz-raw://08e39f23d5b4692f9a40803e53a8156b72b4c1f9902a88cd65ba964db103dab9","dweb:/ipfs/QmPKn6EYDgpga7KtpkA8wV2yJCYGMtc9K4LkJfhKX2RVSV"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol":{"keccak256":"0xe5775eb1fb17165cd191e8f8b2232dbea8765e7e610eaa3d6e52feead793ec5a","urls":["bzz-raw://352614aea75c3d913cbcabb528be3d6c3335c3c77da41d59486a3193069dd095","dweb:/ipfs/QmR3Nabxfme6tHrAMJCyK4MWZtpund2c4R7aFKmea3sGZM"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/NoncesUpgradeable.sol":{"keccak256":"0x778f4a1546a1c6c726ecc8e2348a2789690fb8f26e12bd9d89537669167b79a4","urls":["bzz-raw://851d3dfe724e918ff0a064b206e1ef46b27ab0df2aa2c8af976973a22ef59827","dweb:/ipfs/Qmd4wb7zX8ueYhMVBy5PJjfsANK3Ra3pKPN7qQkNsdwGHn"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol":{"keccak256":"0xa6bf6b7efe0e6625a9dcd30c5ddf52c4c24fe8372f37c7de9dbf5034746768d5","urls":["bzz-raw://8c353ee3705bbf6fadb84c0fb10ef1b736e8ca3ca1867814349d1487ed207beb","dweb:/ipfs/QmcugaPssrzGGE8q4YZKm2ZhnD3kCijjcgdWWg76nWt3FY"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol":{"keccak256":"0x361126a17677994081cd9cb69c3f50cffff6e920d25cb7e428acdb1ae41d1866","urls":["bzz-raw://19ae787a7dd001269cd60a394b1a5261b78925a0fc3a6f927beb2986a9aa56cf","dweb:/ipfs/QmYLfXiuKmcRgTDBEDXMMjXU8t6JxsspUmjxYzqWS55oEv"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol":{"keccak256":"0xd45a5b1d0e451376b08e1bc7e332426c24382053300acf0ac667be1b8abb6cc2","urls":["bzz-raw://824eb0b8c71db8b95b707218d8540c2046a2fefc642e74b343ae90e5c72e2b52","dweb:/ipfs/QmdQTZTomqxRrySDNdv1FEyh3ZWibxwC9FRdcV3DCuASpx"],"license":"MIT"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol":{"keccak256":"0xc8ed8d2056934b7675b695dec032f2920c2f5c6cf33a17ca85650940675323ab","urls":["bzz-raw://3c8ccc75d1cd792d192aa09e54dd49ea35fe85baa9fcd17486f29227d9f29b89","dweb:/ipfs/QmbboSbFUEiM9tdEgBwuTRb7bykFoJXZ7dsSr1PSREJXMr"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/IAccessControl.sol":{"keccak256":"0x4d9a2b261b56a1e4a37bb038151dec98b952fed16de2bdfdda27e38e2b12b530","urls":["bzz-raw://f724110f7aeb6151af800ab8c12e6060b29bda9e013f0ccb331eb754d6a7cbf0","dweb:/ipfs/QmUcjzCZpxtUPdEThtAzE1f9LvuJiUGZxTdH9N6bHrb5Cf"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol":{"keccak256":"0xca774fbe0568762efdc1a7cba31f09549c7fa96dbe97410f4843fa2f0bc000a3","urls":["bzz-raw://0187ffdbf3d61b6d86cba4fcd9826e53d876987d620533ee84c681bdaf0f3ba3","dweb:/ipfs/QmVJDqdJv6uzHY7ifncfv2QJep8XTzS3bGb4s5Exhuv86m"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"keccak256":"0x9b6b3e7803bc5f2f8cd7ad57db8ac1def61a9930a5a3107df4882e028a9605d7","urls":["bzz-raw://da62d6be1f5c6edf577f0cb45666a8aa9c2086a4bac87d95d65f02e2f4c36a4b","dweb:/ipfs/QmNkpvBpoCMvX8JwAFNSc5XxJ2q5BXJpL5L1txb4QkqVFF"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"keccak256":"0xde7e9fd9aee8d4f40772f96bb3b58836cbc6dfc0227014a061947f8821ea9724","urls":["bzz-raw://11fea9f8bc98949ac6709f0c1699db7430d2948137aa94d5a9e95a91f61a710a","dweb:/ipfs/QmQdfRXxQjwP6yn3DVo1GHPpriKNcFghSPi94Z1oKEFUNS"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol":{"keccak256":"0xb25a4f11fa80c702bf5cd85adec90e6f6f507f32f4a8e6f5dbc31e8c10029486","urls":["bzz-raw://6917f8a323e7811f041aecd4d9fd6e92455a6fba38a797ac6f6e208c7912b79d","dweb:/ipfs/QmShuYv55wYHGi4EFkDB8QfF7ZCHoKk2efyz3AWY1ExSq7"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0xce41876e78d1badc0512229b4d14e4daf83bc1003d7f83978d18e0e56f965b9c","urls":["bzz-raw://a2608291cb038b388d80b79a06b6118a42f7894ff67b7da10ec0dbbf5b2973ba","dweb:/ipfs/QmWohqcBLbcxmA4eGPhZDXe5RYMMEEpFq22nfkaUMvTfw1"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol":{"keccak256":"0x7b6690c21e94a45b825631a12581b40a753ea827de5ac9127a6b5833411317f0","urls":["bzz-raw://00045f2c18d7866618c65819fe180a9a9dab25c1974fab35069bdac9cf624b6b","dweb:/ipfs/QmYk62QRqGHJ3rjqfEtbfEGFHWsenv5tNMbeMfq5HkTP44"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol":{"keccak256":"0x92aa1df62dc3d33f1656d63bede0923e0df0b706ad4137c8b10b0a8fe549fd92","urls":["bzz-raw://c5c0f29195ad64cbe556da8e257dac8f05f78c53f90323c0d2accf8e6922d33a","dweb:/ipfs/QmQ61TED8uaCZwcbh8KkgRSsCav7x7HbcGHwHts3U4DmUP"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol":{"keccak256":"0xc42facb5094f2f35f066a7155bda23545e39a3156faef3ddc00185544443ba7d","urls":["bzz-raw://d3b36282ab029b46bd082619a308a2ea11c309967b9425b7b7a6eb0b0c1c3196","dweb:/ipfs/QmP2YVfDB2FoREax3vJu7QhDnyYRMw52WPrCD4vdT2kuDA"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"keccak256":"0x880da465c203cec76b10d72dbd87c80f387df4102274f23eea1f9c9b0918792b","urls":["bzz-raw://399594cd8bb0143bc9e55e0f1d071d0d8c850a394fb7a319d50edd55d9ed822b","dweb:/ipfs/QmbPZzgtT6LEm9CMqWfagQFwETbV1ztpECBB1DtQHrKiRz"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol":{"keccak256":"0x8decfa54cec979c824b044b8128cd91d713f72c71fd7dfa54974624d8c949898","urls":["bzz-raw://271f914261a19d87117a777e0924ada545c16191ef9b00cc40b0134fc14ebc70","dweb:/ipfs/QmdvVNWHGHQrGGPonZJs5NuzTevTjZRM2zayKrDJf7WBA2"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol":{"keccak256":"0xc59a78b07b44b2cf2e8ab4175fca91e8eca1eee2df7357b8d2a8833e5ea1f64c","urls":["bzz-raw://5aa4f07e65444784c29cd7bfcc2341b34381e4e5b5da9f0c5bd00d7f430e66fa","dweb:/ipfs/QmWRMh4Q9DpaU9GvsiXmDdoNYMyyece9if7hnfLz7uqzWM"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7","urls":["bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db","dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0x70f2f713b13b7ce4610bcd0ac9fec0f3cc43693b043abcb8dc40a42a726eb330","urls":["bzz-raw://c13d13304ac79a83ab1c30168967d19e2203342ebbd6a9bbce4db7550522dcbf","dweb:/ipfs/QmeN5jKMN2vw5bhacr6tkg78afbTTZUeaacNHqjWt4Ew1r"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0x27dbc90e5136ffe46c04f7596fc2dbcc3acebd8d504da3d93fdb8496e6de04f6","urls":["bzz-raw://0ea8b92e4245d75a5579c10f22f118f7b4ba07c57341f181f0b2a85ff8663de3","dweb:/ipfs/Qme3Ss5ByjmkxxkMdLpyu7fQ1PCtjNFH1wEFszt2BZePiG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x982c5cb790ab941d1e04f807120a71709d4c313ba0bfc16006447ffbd27fbbd5","urls":["bzz-raw://8150ceb4ac947e8a442b2a9c017e01e880b2be2dd958f1fa9bc405f4c5a86508","dweb:/ipfs/QmbcBmFX66AY6Kbhnd5gx7zpkgqnUafo43XnmayAM7zVdB"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0xaaa1d17c1129b127a4a401db2fbd72960e2671474be3d08cae71ccdc42f7624c","urls":["bzz-raw://cb2f27cd3952aa667e198fba0d9b7bcec52fbb12c16f013c25fe6fb52b29cc0e","dweb:/ipfs/QmeuohBFoeyDPZA9JNCTEDz3VBfBD4EABWuWXVhHAuEpKR"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Arrays.sol":{"keccak256":"0x55a4fdb408e3db950b48f4a6131e538980be8c5f48ee59829d92d66477140cd6","urls":["bzz-raw://3e1ad251e692822ce1494135a4ecb5b97c19b90aa82418fd2959ce32017953fd","dweb:/ipfs/QmT6N7mf6heZYhY2BAQ5kwZp9o3SXzGVdkMqUszx67WRDN"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Comparators.sol":{"keccak256":"0x302eecd8cf323b4690e3494a7d960b3cbce077032ab8ef655b323cdd136cec58","urls":["bzz-raw://49ba706f1bc476d68fe6c1fad75517acea4e9e275be0989b548e292eb3a3eacd","dweb:/ipfs/QmeBpvcdGWzWMKTQESUCEhHgnEQYYATVwPxLMxa6vMT7jC"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Errors.sol":{"keccak256":"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123","urls":["bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf","dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol":{"keccak256":"0x67672e4ca1dafdcc661d4eba8475cfac631fa0933309258e3af7644b92e1fb26","urls":["bzz-raw://30192451f05ea5ddb0c18bd0f9003f098505836ba19c08a9c365adf829454da2","dweb:/ipfs/QmfCuZSCTyCdFoSKn7MSaN6hZksnQn9ZhrZDAdRTCbwGu2"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol":{"keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","urls":["bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b","dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x81c274a60a7ae232ae3dc9ff3a4011b4849a853c13b0832cd3351bb1bb2f0dae","urls":["bzz-raw://9da0c20dc74358a2a76330818f3bac9d1e2ce3371aec847b9cbf5d147fbae4f6","dweb:/ipfs/QmeczhmnFv1hbXKGLwbYXY6Rrytc9a5A2YaRi5QMMgjPnb"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x69f54c02b7d81d505910ec198c11ed4c6a728418a868b906b4a0cf29946fda84","urls":["bzz-raw://8e25e4bdb7ae1f21d23bfee996e22736fc0ab44cfabedac82a757b1edc5623b9","dweb:/ipfs/QmQdWQvB6JCP9ZMbzi8EvQ1PTETqkcTWrbcVurS7DKpa5n"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol":{"keccak256":"0x26670fef37d4adf55570ba78815eec5f31cb017e708f61886add4fc4da665631","urls":["bzz-raw://b16d45febff462bafd8a5669f904796a835baf607df58a8461916d3bf4f08c59","dweb:/ipfs/QmU2eJFpjmT4vxeJWJyLeQb8Xht1kdB8Y6MKLDPFA9WPux"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x79796192ec90263f21b464d5bc90b777a525971d3de8232be80d9c4f9fb353b8","urls":["bzz-raw://f6fda447a62815e8064f47eff0dd1cf58d9207ad69b5d32280f8d7ed1d1e4621","dweb:/ipfs/QmfDRc7pxfaXB2Dh9np5Uf29Na3pQ7tafRS684wd3GLjVL"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0x1225214420c83ebcca88f2ae2b50f053aaa7df7bd684c3e878d334627f2edfc6","urls":["bzz-raw://6c5fab4970634f9ab9a620983dc1c8a30153981a0b1a521666e269d0a11399d3","dweb:/ipfs/QmVRnBC575MESGkEHndjujtR7qub2FzU9RWy9eKLp4hPZB"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54","urls":["bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8","dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3","urls":["bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03","dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol":{"keccak256":"0xecd5f3c702f549fb88555e44e5f2415a4dfd6db09081aec7e98c26b6a3739c06","urls":["bzz-raw://ed40e907a6d80458a0556a609d0d3991d718c20f9f1f21475e5ec739af523231","dweb:/ipfs/QmejkwADsZRxkusNU94sswMJfpLrbq8RkJTbNccUEQpc7Y"],"license":"MIT"},"src/Auth.sol":{"keccak256":"0x2f108092253eedadac5a8efbb9916307ddb50f104a7dba2d8673033744536b35","urls":["bzz-raw://e58db9ad4a7c3e5d3978a11ef4193da8f7519100913b52e14d31c200fcad2bb0","dweb:/ipfs/QmdbpLGnc9FjGAK6SC2X9mw9TfnrtCTx71YkHypzcQ6NR8"],"license":"MIT"},"src/IVault.sol":{"keccak256":"0x091b24377a23e5729da0e837dc31757be79ae83622c8fa7f9bbd7629eaf5ca22","urls":["bzz-raw://b34a58352f0ee3797f290ab36278773aeabfeebedef8675b7933201c869330dd","dweb:/ipfs/QmQUTZkyCHjjXRKosDQRJcCkbrHGGP3uhTRaSEG3UnUwEd"],"license":"MIT"},"src/VeryLiquidVault.sol":{"keccak256":"0xd57f496413ef2a33718f9bb9c7832673abba2825457769446afd3d55e86026d4","urls":["bzz-raw://e20119b89fe3231dab9549ac65ac912a30f82666b11211deefbc5a993ecb5347","dweb:/ipfs/QmTs9KLqQHBLxgyLoeLCAeQZmgqcLq1JKh6SbLWUB6naaU"],"license":"MIT"},"src/utils/BaseVault.sol":{"keccak256":"0x4de7701fa4e90b2c95e2cfe9ba4b0d357e16babb29a270881bea09c2c711753f","urls":["bzz-raw://3c5df8747931a42f198e9ebdff8a699e5c7267bdb8e744527a8eeb9b5e057b4c","dweb:/ipfs/QmNUpisG5vp5ppTyxTA5VRfRgJh6P6zCfNQRmvLbdZ5PeG"],"license":"MIT"},"src/utils/PerformanceVault.sol":{"keccak256":"0x97a143757550307521cd3b5d5a8f45fdf307e38ccdad149dd5a41fcfc2c7ca3f","urls":["bzz-raw://b24a4bf4da2ba37919fd50b5dc55ceb505f6963becd686bad97f3f6acc1e9cd2","dweb:/ipfs/QmQ1AFFsmZbBwKnhyBxk3ctjcdrekmrfcUHiiCmzFeX8sG"],"license":"MIT"},"src/utils/ReentrancyGuardUpgradeableWithViewModifier.sol":{"keccak256":"0x9f05fa0ee789165434647ee899927f23ccb642c2a3fab6b614545777b3ad5752","urls":["bzz-raw://87d9debee76870bc4cbf6ec069c880cd204e5a78bdb5df1029335d0b6b89dff1","dweb:/ipfs/QmYWsfvkRZi8Y7yKe72FJUbwmU8TQwBnmS3zrpzr6S8coS"],"license":"MIT"}},"version":1},"id":83} \ No newline at end of file diff --git a/src/adaptors/rheo/api.js b/src/adaptors/rheo/api.js new file mode 100755 index 0000000000..5ef8fec232 --- /dev/null +++ b/src/adaptors/rheo/api.js @@ -0,0 +1,172 @@ +const fetch = require('node-fetch'); + +/* +export interface Market { + id: string; + name: string; + api_base_url: string; + documentation_url: string; + chain: string; + base_symbol: string; + quote_symbol: string; + collateral_token: { + address: string; + decimals: number; + }; + debt_token: { + address: string; + decimals: number; + }; + data_params: { + weth: string; + underlying_collateral_token: string; + underlying_borrow_token: string; + variable_pool: string; + borrow_a_token_v1_5: string; + }; + fee_config: { + swap_fee_apr: number; + fragmentation_fee: number; + liquidation_reward_percent: number; + overdue_collateral_protocol_percent: number; + collateral_protocol_percent: number; + fee_recipient: string; + }; + risk_config: { + cr_opening: number; + cr_liquidation: number; + minimum_credit_borrow_a_token: number; + borrow_a_token_cap: number; + min_tenor: number; + max_tenor: number; + }; + oracle_params: { + price_feed: string; + variable_pool_borrow_rate_stale_rate_interval: number; + }; +} + +interface GetMarketsResponse { + markets_by_chain: Record +} + +interface GetTvlResponse { + total_tvl_usd: number; + collateral_tvl: number; + collateral_tvl_usd: number; + debt_tvl: number; + debt_tvl_usd: number; + total_borrow: number; + total_borrow_usd: number; +} + +interface GetBestRateResponse { + tenors: number[]; + aprs: Array; + contributing_curves: + { + curve: { + curve_relative_time_aprs: number[]; + curve_relative_time_market_rate_multipliers: number[]; + curve_relative_time_tenors: number[]; + id: string; + block_number: number; + block_timestamp: string; + transaction_hash: string; + transfer_from: string; + max_due_date: number; + user_address: string; + depth: number; + }, + apr: number; + depth_used_borrow_token: number; + depth_used_collateral_token: number; + }[][] +} + +interface GetMarketsLiquidityResponse { + [market_id: string]: { + total_liquidity_usd: number; + sell_side_liquidity_usd: number; + buy_side_liquidity_usd: number; + sell_liquidity: number; + buy_liquidity: number; + }; +} +*/ + +const ENDPOINT = 'https://api.rheo.xyz'; + +async function getMarkets() /*: Promise*/ { + const getMarketsResponse /*: GetMarketsResponse*/ = await fetch( + `${ENDPOINT}/` + ).then((res) => res.json()); + return Object.values(getMarketsResponse.markets_by_chain).flat(); +} + +async function getMarketsLiquidity( + market /*: Market*/ +) /*: Promise*/ { + const getMarketsLiquidityResponse /*: GetMarketsLiquidityResponse*/ = + await fetch(`${ENDPOINT}/markets-liquidity`).then((res) => res.json()); + return getMarketsLiquidityResponse; +} + +async function getTvl(market /*: Market*/) /*: Promise*/ { + const getTvlResponse /*: GetTvlResponse*/ = await fetch( + `${ENDPOINT}${market.api_base_url}/market-tvl` + ).then((res) => res.json()); + return getTvlResponse; +} + +async function lendingAPR( + market /*: Market*/, + tenor /*: number*/, + depth /*: number*/ +) /*: Promise*/ { + const getBestRateResponse /*: GetBestRateResponse*/ = await fetch( + `${ENDPOINT}${market.api_base_url}/best-rate-for-tenors-scl/`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ tenors: [tenor], depth }), + } + ).then((res) => res.json()); + const apr18decimals = getBestRateResponse.aprs[0]; + if (typeof apr18decimals === 'string') { + return undefined; + } + return apr18decimals / 1e16; +} + +async function borrowingAPR( + market /*: Market*/, + tenor /*: number*/, + depth /*: number*/ +) /*: Promise*/ { + const getBestRateResponse /*: GetBestRateResponse*/ = await fetch( + `${ENDPOINT}${market.api_base_url}/best-rate-for-tenors-bcl/`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ tenors: [tenor], depth }), + } + ).then((res) => res.json()); + const apr18decimals = getBestRateResponse.aprs[0]; + if (typeof apr18decimals === 'string') { + return undefined; + } + return apr18decimals / 1e16; +} + +module.exports = { + getMarkets, + getTvl, + lendingAPR, + borrowingAPR, + getMarketsLiquidity, +}; diff --git a/src/adaptors/rheo/index.js b/src/adaptors/rheo/index.js new file mode 100755 index 0000000000..a90611dcba --- /dev/null +++ b/src/adaptors/rheo/index.js @@ -0,0 +1,90 @@ +const { + borrowingAPR, + getMarkets, + lendingAPR, + getTvl, + getMarketsLiquidity, +} = require('./api'); +const sdk = require('@defillama/sdk'); +const AaveV3Pool = require('../aave-v3/poolAbi'); +const { apy: veryLiquidVaultsApy } = require('./very-liquid-vaults'); + +const AaveProtocolDataProvider = { + ethereum: '0x41393e5e337606dc3821075Af65AeE84D7688CBD', + optimism: '0x7F23D86Ee20D869112572136221e173428DD740B', + arbitrum: '0x7F23D86Ee20D869112572136221e173428DD740B', + polygon: '0x7F23D86Ee20D869112572136221e173428DD740B', + fantom: '0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654', + avax: '0x374a2592f0265b3bb802d75809e61b1b5BbD85B7', + metis: '0xC01372469A17b6716A38F00c277533917B6859c0', + base: '0xd82a47fdebB5bf5329b09441C3DaB4b5df2153Ad', + xdai: '0x57038C3e3Fe0a170BB72DE2fD56E98e4d1a69717', + bsc: '0x23dF2a19384231aFD114b036C14b6b03324D79BC', + scroll: '0xe2108b60623C6Dcf7bBd535bD15a451fd0811f7b', + era: '0x5F2A704cE47B373c908fE8A29514249469b52b99', + lido: '0x08795CFE08C7a81dCDFf482BbAAF474B240f31cD', // on ethereum + etherfi: '0xE7d490885A68f00d9886508DF281D67263ed5758', // on ethereum +}; + +const TENOR_DAYS = 3; +const DAYS_TO_SECONDS = 24 * 60 * 60; + +const DEPTH_BORROW_TOKEN = 10; + +function uppercaseFirst(str /*: string*/) /*: string*/ { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +async function apy() /*: Promise*/ { + const [markets, marketsLiquidity] = await Promise.all([ + getMarkets(), + getMarketsLiquidity(), + ]); + + const pools = await Promise.all( + markets.map(async (market) => { + const tvl = await getTvl(market); + const uppercaseChain = uppercaseFirst(market.chain); + let apyBase = await lendingAPR( + market, + TENOR_DAYS * DAYS_TO_SECONDS, + DEPTH_BORROW_TOKEN + ); + if (apyBase === undefined) { + // no limit borrow offers available, use Aave v3 as a variable-rate lending pool + const { output: getReserveData } = await sdk.api.abi.call({ + target: AaveProtocolDataProvider[market.chain], + abi: AaveV3Pool.find((m) => m.name === 'getReserveData'), + params: [market.debt_token.address], + chain: market.chain, + }); + apyBase = getReserveData.liquidityRate / 10 ** 25; + } + return { + pool: `rheo-${market.id}`, + chain: uppercaseFirst(market.chain), + project: 'rheo', + symbol: market.base_symbol, + tvlUsd: marketsLiquidity[market.id].buy_side_liquidity_usd, + apyBase, + underlyingTokens: [market.debt_token.address], + url: `https://app.rheo.xyz/borrow?action=market&type=lend&market_id=${market.id}`, + apyBaseBorrow: await borrowingAPR( + market, + TENOR_DAYS * DAYS_TO_SECONDS, + DEPTH_BORROW_TOKEN + ), + totalSupplyUsd: tvl.debt_tvl_usd, + totalBorrowUsd: tvl.total_borrow_usd, + ltv: 1e18 / market.risk_config.cr_liquidation, + poolMeta: `${TENOR_DAYS}-day maturity`, + }; + }) + ); + const veryLiquidVaults = await veryLiquidVaultsApy(); + return [...pools, ...veryLiquidVaults]; +} + +module.exports = { + apy, +}; diff --git a/src/adaptors/rheo/very-liquid-vaults.js b/src/adaptors/rheo/very-liquid-vaults.js new file mode 100644 index 0000000000..431eb1c318 --- /dev/null +++ b/src/adaptors/rheo/very-liquid-vaults.js @@ -0,0 +1,198 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils'); +const VeryLiquidVaultABI = require('./VeryLiquidVault.json'); + +const DEPLOYMENT_BLOCKS = { + base: 35109672, + ethereum: 23320146, +}; + +const VERY_LIQUID_VAULTS = { + base: ['0xf4D43A8570Dad86595fc079c633927aa936264F4'], + ethereum: [ + '0x3AdF08AFe804691cA6d76742367cc50A24a1F4A1', + '0x13dDa6fD149a4Da0f2012F16e70925586ee603b8', + ], +}; + +/* +interface VaultStatus { + timestamp: number; + totalShares: number; + totalAssets: number; +} +*/ + +function uppercaseFirst(str /*: string*/) /*: string*/ { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +async function getLastVaultStatusLog(vault, chain) /*: Promise*/ { + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + const vaultInterface = new ethers.utils.Interface(VeryLiquidVaultABI.abi); + const topic = vaultInterface.getEventTopic('VaultStatus'); + const logs = await sdk.api.util.getLogs({ + target: vault, + topic: '', + toBlock, + fromBlock: DEPLOYMENT_BLOCKS[chain], + keys: [], + topics: [topic], + chain, + }); + const sortedLogs = logs.output.sort((a, b) => b.blockNumber - a.blockNumber); + const lastLog = sortedLogs[0]; + const decodedLog = vaultInterface.parseLog(lastLog); + const timestamp = await sdk.api.util.getTimestamp(lastLog.blockNumber, chain); + const vaultStatus = { + timestamp: timestamp, + totalShares: Number(decodedLog.args.totalShares.toString()), + totalAssets: Number(decodedLog.args.totalAssets.toString()), + }; + return vaultStatus; +} + +function getAPY( + status0 /*: VaultStatus */, + status1 /*: VaultStatus */ +) /*: number */ { + // Calculate time difference in years + const timeDiffSeconds = status1.timestamp - status0.timestamp; + const timeDiffYears = timeDiffSeconds / (365 * 24 * 60 * 60); + + // Calculate share price ratio (assets per share) + const sharePrice0 = status0.totalAssets / status0.totalShares; + const sharePrice1 = status1.totalAssets / status1.totalShares; + + // Calculate the growth rate + const growthRate = (sharePrice1 - sharePrice0) / sharePrice0; + + // Convert to APY (annualized) + const apy = Math.pow(1 + growthRate, 1 / timeDiffYears) - 1; + + // Return as percentage (multiply by 100) + return apy * 100; +} + +async function apy() /*: Promise*/ { + const chains = Object.keys(VERY_LIQUID_VAULTS); + + const chainResults = await Promise.all( + chains.map(async (chain) => { + const vaults = VERY_LIQUID_VAULTS[chain]; + + const [assets, symbols, totalAssets, totalSupply, decimals] = + await Promise.all([ + sdk.api.abi + .multiCall({ + abi: VeryLiquidVaultABI.abi.find(({ name }) => name === 'asset'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)), + + sdk.api.abi + .multiCall({ + abi: 'erc20:symbol', + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)), + + sdk.api.abi + .multiCall({ + abi: VeryLiquidVaultABI.abi.find( + ({ name }) => name === 'totalAssets' + ), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)), + + sdk.api.abi + .multiCall({ + abi: VeryLiquidVaultABI.abi.find( + ({ name }) => name === 'totalSupply' + ), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)), + + sdk.api.abi + .multiCall({ + abi: 'erc20:decimals', + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)), + ]); + + const assetsSymbols = await sdk.api.abi + .multiCall({ + abi: 'erc20:symbol', + calls: assets.map((asset) => ({ + target: asset, + })), + chain, + }) + .then(({ output }) => output.map(({ output }) => output)); + + const prices = await Promise.all( + vaults.map(async (vault, i) => { + const res = await axios.get( + `https://coins.llama.fi/prices/current/${chain}:${assets[i]}` + ); + return res.data.coins[`${chain}:${assets[i]}`].price; + }) + ); + + const lastVaultStatusLogPerVault = await Promise.all( + vaults.map((vault) => getLastVaultStatusLog(vault, chain)) + ); + + const apyBasePerVault = lastVaultStatusLogPerVault.map( + (lastVaultStatusLog, i) => { + const currentStatus = { + timestamp: Math.floor(new Date().getTime() / 1000), + totalShares: Number(totalSupply[i]), + totalAssets: Number(totalAssets[i]), + }; + return getAPY(lastVaultStatusLog, currentStatus); + } + ); + + return vaults.map((vault, i) => ({ + pool: `rheo-vlv-${vault}`, + chain: uppercaseFirst(chain), + apyBase: apyBasePerVault[i], + project: 'rheo', + symbol: symbols[i], + tvlUsd: (totalAssets[i] * prices[i]) / 10 ** decimals[i], + underlyingTokens: [assets[i]], + url: `https://veryliquid.xyz/${chain}/vault/${vault}`, + totalSupplyUsd: (totalAssets[i] * prices[i]) / 10 ** decimals[i], + poolMeta: symbols[i].replace('vlv', '').replace(assetsSymbols[i], ''), + })); + }) + ); + + return chainResults.flat(); +} + +module.exports = { + apy, +}; diff --git a/src/adaptors/rhino.fi/index.js b/src/adaptors/rhino.fi/index.js new file mode 100644 index 0000000000..9584c203d7 --- /dev/null +++ b/src/adaptors/rhino.fi/index.js @@ -0,0 +1,129 @@ +const sdk = require('@defillama/sdk'); +const utils = require("../utils"); + +const APP_URL = 'https://app.rhino.fi' +const API_URL = 'https://api.rhino.fi/apytvl/all' +const BEEFY_API_URL = 'https://api.beefy.finance' + +const CHAINS = { + ETHEREUM: 'Ethereum', + ARBITRUM: 'Arbitrum', + POLYGON: 'Polygon' +} + +const TVL_ADDRESSES = { + [CHAINS.ETHEREUM]: '0x5d22045daceab03b158031ecb7d9d06fad24609b', + [CHAINS.POLYGON]: '0xda7EeB4049dA84596937127855B50271ad1687E7', + [CHAINS.ARBITRUM]: '0xCA8E436347a46502E353Cc36b58FE3bB9214D7Fd' +} + +const YIELD_TOKENS = { + [CHAINS.ETHEREUM]: [ + {address: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', chain: CHAINS.ETHEREUM, token: 'WSTETH'}, + {address: '0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9', chain: CHAINS.ETHEREUM, token: 'CUSDT'}, + {address: '0x341c05c0e9b33c0e38d64de76516b2ce970bb3be', chain: CHAINS.ETHEREUM, token: 'DSETH'}, + {address: '0x7C07F7aBe10CE8e33DC6C5aD68FE033085256A84', chain: CHAINS.ETHEREUM, token: 'ICETH'}, + {address: '0x9ee91F9f426fA633d227f7a9b000E28b9dfd8599', chain: CHAINS.ETHEREUM, token: 'STMATIC'}, + {address: '0x3b27f92c0e212c671ea351827edf93db27cc0c65', chain: CHAINS.ETHEREUM, token: 'YVUSDT'}, + ], + [CHAINS.ARBITRUM]: [ + { + address: '0xd496ea90a454ea49e30a8fd9e053c186d4fc897d', + chain: CHAINS.ARBITRUM, + token: 'mooStargateUSDC', + beefyId: 'stargate-arb-usdc' + }, + ], + [CHAINS.POLYGON]: [ + { + address: '0x1c480521100c962f7da106839a5a504b5a7457a1', + chain: CHAINS.POLYGON, + token: 'mooStargateUSDT', + beefyId: 'stargate-polygon-usdt' + } + ] +} + +const getTokenSlug = (address, chain, coingeckoSlug) => `${coingeckoSlug ? 'coingecko' : chain.toLowerCase()}:${coingeckoSlug || address.toLowerCase()}` + +const getTokenPrices = async (tokens) => { + const l1TokenQuery = tokens.map(({address, chain, coingeckoSlug}) => getTokenSlug(address, chain, coingeckoSlug)); + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${l1TokenQuery}` + ); + + return Object.fromEntries( + tokens.map(({address, chain, token, coingeckoSlug}) => { + const {decimals = 0, price = 0, symbol = token} = data.coins[getTokenSlug(address, chain, coingeckoSlug)] || {}; + return [address, {price, decimals, symbol}]; + }) + ); +}; + + +const getBeefyPrices = async () => { + return utils.getData(`${BEEFY_API_URL}/vaults`) +} + + +const getTVL = async (chain, tokens) => { + return (await sdk.api.abi.multiCall({ + calls: tokens.map(({address}) => ({ + target: address.toLowerCase(), + params: [TVL_ADDRESSES[chain].toLowerCase()] + })), + abi: 'erc20:balanceOf', + chain: chain.toLowerCase() + })).output.map(({output}) => output) +} + +const findBeefyPrice = (beefyId, vaults) => { + const {pricePerFullShare = 0, tokenDecimals: decimals = 18} = vaults.find(({id}) => id === beefyId) || {} + return {price: pricePerFullShare / 10 ** 18, decimals} +} + +const getApy = async () => { + const apy = await utils.getData(API_URL); + const beefyUsdPrices = await getBeefyPrices() + + const tvlPerChain = ( + await Promise.all(Object.keys(YIELD_TOKENS).map(chain => { + return getTVL(chain, YIELD_TOKENS[chain]) + }))) + .flat() + const usdPrices = (await Promise.all(Object.keys(YIELD_TOKENS) + .map((chain) => getTokenPrices(YIELD_TOKENS[chain])))) + .reduce((acc, usdPrices) => { + return { + ...acc, + ...usdPrices + } + }, {}) + return Object.values(YIELD_TOKENS) + .flat() + .map(({address, chain, token, beefyId}, index) => { + const {apy: apyBase} = apy[token] + const tvl = tvlPerChain[index] || 0 + const { + price: usdPrice, + decimals + } = beefyId ? findBeefyPrice(beefyId, beefyUsdPrices) : usdPrices[address] || {price: 0, decimals: 18} + const tvlUsd = (tvl / 10 ** decimals) * usdPrice + + return ({ + pool: `${address}-${chain}-rhino.fi`.toLowerCase(), + chain, + project: 'rhino.fi', + tvlUsd, + apyBase, + symbol: token, + url: `${APP_URL}/invest/${token}?utm_source=defillama&utm_medium=listing&utm_campaign=external` + }) + }) +} + +module.exports = { + timetravel: false, + apy: getApy, + url: `${APP_URL}/invest?utm_source=defillama&utm_medium=listing&utm_campaign=external`, +}; diff --git a/src/adaptors/rho-markets/index.js b/src/adaptors/rho-markets/index.js new file mode 100644 index 0000000000..0cd1ebb5d3 --- /dev/null +++ b/src/adaptors/rho-markets/index.js @@ -0,0 +1,99 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abis = require('./rho-markets.json'); +const ethers = require('ethers'); + +const markets_state = '0xeF7ceDe2D4E053ccf2A58f977a1F1eDC8782Ecc5'; +const chain = utils.formatChain('Scroll'); +const project = 'rho-markets'; + +function calculateApy(ratePerSecond, compoundingsPerYear) { + ratePerSecond = BigInt(ratePerSecond); + compoundingsPerYear = BigInt(compoundingsPerYear); + + if (ratePerSecond === 0n) return 0; + + const SCALE = BigInt(1e18); + + function pow(base, exponent) { + let result = SCALE; + let basePow = base; + + while (exponent > 0n) { + if (exponent % 2n === 1n) { + result = (result * basePow) / SCALE; + } + basePow = (basePow * basePow) / SCALE; + exponent /= 2n; + } + + return result; + } + const compounded = pow(SCALE + ratePerSecond, compoundingsPerYear); + const rawData = (compounded - SCALE) * 100n; + + const data = ethers.utils.formatEther(rawData); + return Number(data); +} + +const apy = async () => { + const allMarketsMetadata = ( + await sdk.api.abi.call({ + target: markets_state, + abi: abis.find((m) => m.name === 'getActiveMarketsInfo'), + chain: 'scroll', + }) + ).output; + + const pools = allMarketsMetadata.map((marketInfo, i) => { + const pool = `${marketInfo.token}-${chain}`.toLowerCase(); + const underlyingSymbol = marketInfo.underlyingSymbol; + + const poolMeta = `Rho ${underlyingSymbol} Market`; + const tvlUsd = Number(ethers.utils.formatEther(marketInfo.tvl)); + const ltv = Number(ethers.utils.formatEther(marketInfo.ltv)); + const totalSupplyUsd = Number( + ethers.utils.formatEther(marketInfo.totalSupply) + ); + const totalBorrowUsd = Number( + ethers.utils.formatEther(marketInfo.totalBorrows) + ); + + const blocksPerYear = marketInfo.blocksPerYear; + const borrowRatePerBlock = marketInfo.borrowRatePerBlock; + const supplyRatePerBlock = marketInfo.supplyRatePerBlock; + const timestampsPerYear = marketInfo.timestampsPerYear; + + const base = blocksPerYear > 0 ? blocksPerYear : timestampsPerYear; + + const apyBase = calculateApy(supplyRatePerBlock, base); + + const apyBaseBorrow = calculateApy(borrowRatePerBlock, base); + + const url = `https://dapp.rhomarkets.xyz/market/${underlyingSymbol}`; + + return { + pool, + chain, + project, + poolMeta, + ltv, + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + apyBase, + apyBaseBorrow, + symbol: underlyingSymbol, + underlyingTokens: [marketInfo.underlying], + url, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://dapp.rhomarkets.xyz/', +}; diff --git a/src/adaptors/rho-markets/rho-markets.json b/src/adaptors/rho-markets/rho-markets.json new file mode 100644 index 0000000000..9ccda10854 --- /dev/null +++ b/src/adaptors/rho-markets/rho-markets.json @@ -0,0 +1,99 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_comptroller", + "type": "address", + "internalType": "address" + }, + { "name": "_oracle", "type": "address", "internalType": "address" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "comptroller", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract Comptroller" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getActiveMarketsInfo", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct MarketStateV2.MarketsInfo[]", + "components": [ + { "name": "tvl", "type": "uint256", "internalType": "uint256" }, + { "name": "ltv", "type": "uint256", "internalType": "uint256" }, + { + "name": "totalSupply", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalBorrows", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "supplyRatePerBlock", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "borrowRatePerBlock", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "blocksPerYear", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "timestampsPerYear", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "token", "type": "address", "internalType": "address" }, + { + "name": "underlying", + "type": "address", + "internalType": "address" + }, + { "name": "symbol", "type": "string", "internalType": "string" }, + { + "name": "underlyingSymbol", + "type": "string", + "internalType": "string" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "oracle", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract PriceOracleV2" + } + ], + "stateMutability": "view" + } +] diff --git a/src/adaptors/ribbon/index.js b/src/adaptors/ribbon/index.js new file mode 100644 index 0000000000..0c5987f2a5 --- /dev/null +++ b/src/adaptors/ribbon/index.js @@ -0,0 +1,134 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); +const { mean } = require('lodash'); +const utils = require('../utils'); + +const API = { + Avalanche: sdk.graph.modifyEndpoint('AmJzFkqot9NjxPCRLK8yXopYt3rtS736ZEX2zEFg7Tz2'), + Ethereum: sdk.graph.modifyEndpoint('3GhHcRwF6yH7WXGcJJvac9B5MHPuoXhS9uxc49TPqLf6'), +}; + +const getNWeekApy = (perf, weekN) => { + return ( + ((1 + + (perf[weekN]?.pricePerShare - perf[weekN - 1]?.pricePerShare) / + perf[weekN - 1]?.pricePerShare) ** + 52 - + 1) * + 100 + ); +}; + +const PerfQuery = gql` + query PerfQuery($id: ID = "") { + vaultPerformanceUpdates(orderBy: round, where: { vault_: { id: $id } }) { + pricePerShare + round + id + timestamp + vault { + id + underlyingSymbol + totalBalance + } + } + } +`; + +const VaultsQuery = gql` + query VaultsQuery { + vaults { + id + name + underlyingSymbol + underlyingName + underlyingDecimals + underlyingAsset + totalBalance + symbol + } + } +`; + +const chainsMap = { + Avalanche: 'avax', + Ethereum: 'ethereum', +}; + +const apyChain = async (chain) => { + const { vaults } = await request(API[chain], VaultsQuery); + const vaultPerfs = await Promise.all( + vaults.map( + async (vault) => + ( + await request(API[chain], PerfQuery, { id: vault.id }) + ).vaultPerformanceUpdates + ) + ); + + const { pricesByAddress: prices } = await utils.getPrices( + vaults.map(({ underlyingAsset }) => underlyingAsset), + chainsMap[chain] + ); + + const pools = vaults.map((vault, i) => { + // remove deprecated APE pool + if (vault.id === '0xc0cf10dd710aefb209d9dc67bc746510ffd98a53') return {}; + const perf = vaultPerfs[i]; + + const fee = 0.12; + const apy = mean( + [1, 2, 3, 4].map((n) => { + const nWeekApy = getNWeekApy(perf, perf.length - n - 1); + return nWeekApy > 0 ? nWeekApy * (1 - fee) : nWeekApy; + }) + ); + + // for 7d IL we use the current weeks performance, if positive -> no IL, otherwise use that + // value as the IL + const weekN = perf.length - 1; + const weeklyPerf = + (perf[weekN]?.pricePerShare - perf[weekN - 1]?.pricePerShare) / + perf[weekN - 1]?.pricePerShare; + const il7d = weeklyPerf > 0 ? null : weeklyPerf; + + const price = prices[vault.underlyingAsset]; + + let symbol = vault.symbol.replace('-THETA', '').slice(1); + symbol = symbol.includes('yvUSDC') ? 'USDC' : symbol; + + return { + pool: vault.id, + project: 'ribbon', + chain: chain, + symbol, + tvlUsd: price * (vault.totalBalance / 10 ** vault.underlyingDecimals), + apyBase: apy, + underlyingTokens: [vault.underlyingAsset], + poolMeta: vault.name.includes('Put') ? 'Put-Selling' : 'Covered-Call', + il7d, + apyBaseInception: + ((perf[perf.length - 1]?.pricePerShare - perf[0]?.pricePerShare) / + perf[0]?.pricePerShare) * + 100, + }; + }); + + return pools; +}; + +const apy = async () => { + const chains = Object.keys(chainsMap); + + const pools = await Promise.all( + chains.map(async (chain) => await apyChain(chain)) + ); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.ribbon.finance/', +}; diff --git a/src/adaptors/robo-vault/index.js b/src/adaptors/robo-vault/index.js index 10d87fab70..eab2e29ab0 100644 --- a/src/adaptors/robo-vault/index.js +++ b/src/adaptors/robo-vault/index.js @@ -1,21 +1,23 @@ const utils = require('../utils'); const poolsFunction = async () => { - const vaultData = await utils.getData('https://api.robo-vault.com/vaults'); + const vaultData = await utils.getData('https://api.v2.robo-vault.com/vaults'); return vaultData - .filter((p) => p.status.toLowerCase() === 'active') + .filter((p) => p.status.toLowerCase() === 'active' && p.tvlUsd > 10_000) .map((item) => ({ pool: item.addr, chain: utils.formatChain(item.chain), project: 'robo-vault', symbol: utils.formatSymbol(item.symbol).replace('sAMM-', ''), tvlUsd: item.tvlUsd, - apy: item.apy3d * 100, + apyBase: item.apy1d * 100, + apyBase7d: item.apy7d * 100 })); }; module.exports = { timetravel: false, apy: poolsFunction, + url: 'https://www.robo-vault.com/', }; diff --git a/src/adaptors/rocifi-v2/abi.js b/src/adaptors/rocifi-v2/abi.js new file mode 100644 index 0000000000..2d21ee1549 --- /dev/null +++ b/src/adaptors/rocifi-v2/abi.js @@ -0,0 +1,118 @@ +module.exports = { + pool: { + symbol: { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + underlyingToken: { + inputs: [], + name: 'underlyingToken', + outputs: [ + { + internalType: 'contract IERC20MetadataUpgradeable', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, + limitManager: { + poolToBorrowedAmount: { + inputs: [{ internalType: 'contract IPool', name: '', type: 'address' }], + name: 'poolToBorrowedAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + }, + settingsProvider: { + getPools: { + inputs: [], + name: 'getPools', + outputs: [ + { + internalType: 'contract IPool[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getPoolToScoreLtvs: { + inputs: [ + { + internalType: 'contract IPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint16', + name: 'score', + type: 'uint16', + }, + ], + name: 'getPoolToScoreLtvs', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + getInterestSettings: { + inputs: [ + { + internalType: 'contract IPool', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint16', + name: 'score', + type: 'uint16', + }, + { + internalType: 'uint256', + name: 'ltv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + ], + name: 'getInterestSettings', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'interest', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + internalType: 'struct ISettingsProvider.InterestSettings', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + }, +}; diff --git a/src/adaptors/rocifi-v2/index.js b/src/adaptors/rocifi-v2/index.js new file mode 100644 index 0000000000..f883b36c3f --- /dev/null +++ b/src/adaptors/rocifi-v2/index.js @@ -0,0 +1,219 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { default: BigNumber } = require('bignumber.js'); +const { + utils: { formatEther }, +} = require('ethers'); +const abi = require('./abi'); + +const GRAPH_URL = sdk.graph.modifyEndpoint('42Yjxm8KTaBKfnzycNEhizZxd8jDfgnH9F5kWkzBikAq'); + +const chain = 'polygon'; + +const ONE_HOUR = 3600; +const ONE_DAY = ONE_HOUR * 24; +const ONE_WEEK = ONE_DAY * 7; +const ONE_YEAR = ONE_HOUR * 8760; + +const ROCI_SETTINGS_PROVIDER = '0xb2e577a112A6F2C6d3d511ade2AD512cEA312a6d'; +const ROCI_LIMIT_MANAGER = '0x347892c2c0C230f0803127F4E1137b3e975F57E4'; + +const getDtPricesQuery = (pool) => gql` + query RociFiDtPrices { + dtPriceUpdates( + orderBy: "timestamp" + orderDirection: "desc" + first: 10 + where: { + market: "${pool.toLowerCase()}", + timestamp_gte: ${Math.floor(Date.now() / 1000) - ONE_WEEK} + } + ) { + dtPrice + timestamp + } + } +`; + +const getApy = async (pool) => { + const graphData = await request(GRAPH_URL, getDtPricesQuery(pool)); + if ( + !graphData?.dtPriceUpdates?.length || + graphData.dtPriceUpdates.length === 1 + ) + return 0; + + const { dtPriceUpdates } = graphData; + + const priceUpdateA = dtPriceUpdates[0]; + + const priceUpdateB = + dtPriceUpdates.find( + (p) => priceUpdateA.timestamp - p.timestamp >= ONE_DAY + ) || dtPriceUpdates[dtPriceUpdates.length - 1]; + + const timestampDiff = + Number(priceUpdateA.timestamp) - Number(priceUpdateB.timestamp); + + const apy = BigNumber(priceUpdateA.dtPrice) + .minus(priceUpdateB.dtPrice) + .dividedBy(priceUpdateB.dtPrice) + .multipliedBy(ONE_YEAR) + .dividedBy(timestampDiff) + .multipliedBy(100) + .toNumber(); + + return apy; +}; + +const getPricesByAddresses = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .map((address) => `${chain}:${address}`) + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + return Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); +}; + +async function getPools() { + const pools = ( + await sdk.api.abi.call({ + target: ROCI_SETTINGS_PROVIDER, + abi: abi.settingsProvider.getPools, + chain, + }) + ).output; + + return Promise.all( + await pools.map(async (pool) => { + const [symbol, underlyingToken] = await Promise.all( + ['symbol', 'underlyingToken'].map(async (method) => { + const response = await sdk.api.abi.call({ + target: pool, + chain, + abi: abi.pool[method], + }); + + return response.output; + }) + ); + + const [underlyingDecimals, underlyingSymbol, poolTvl] = await Promise.all( + ['decimals', 'symbol', 'balanceOf'].map(async (method) => { + const response = await sdk.api.abi.call({ + target: underlyingToken, + abi: `erc20:${method}`, + chain, + params: method === 'balanceOf' ? [pool] : undefined, + }); + return response.output; + }) + ); + + const totalBorrowed = ( + await sdk.api.abi.call({ + target: ROCI_LIMIT_MANAGER, + chain, + abi: abi.limitManager.poolToBorrowedAmount, + params: [pool], + }) + ).output; + + const scoreTenLTVs = ( + await sdk.api.abi.call({ + target: ROCI_SETTINGS_PROVIDER, + chain, + abi: abi.settingsProvider.getPoolToScoreLtvs, + params: [pool, 10], + }) + ).output; + + const ltv = + parseFloat(formatEther(scoreTenLTVs[scoreTenLTVs.length - 1])) / 100; + + const scoreTenBorrowSettings = ( + await sdk.api.abi.call({ + target: ROCI_SETTINGS_PROVIDER, + chain, + abi: abi.settingsProvider.getInterestSettings, + params: [pool, 10, scoreTenLTVs[0], 7 * ONE_DAY], + }) + ).output; + + const apyBaseBorrow = parseFloat( + formatEther(scoreTenBorrowSettings.interest) + ); + + return { + address: pool, + symbol, + underlyingToken: underlyingToken?.toLowerCase(), + underlyingDecimals, + underlyingSymbol, + tvl: poolTvl, + totalBorrowed, + apyBaseBorrow, + ltv, + }; + }) + ); +} + +async function getPoolData() { + const pools = await getPools(); + const prices = await getPricesByAddresses( + pools.map((pool) => pool.underlyingToken) + ); + + return Promise.all( + pools.map(async (pool, index) => { + const price = prices[pool.underlyingToken]; + + const decimals = Number(pool.underlyingDecimals); + + const totalSupply = BigNumber(pool.tvl).plus(pool.totalBorrowed); + + const [tvlUsd, totalSupplyUsd, totalBorrowUsd] = [ + pool.tvl, + totalSupply, + pool.totalBorrowed, + ].map((value) => + BigNumber(value).shiftedBy(-decimals).multipliedBy(price).toNumber() + ); + + const apyBase = await getApy(pool.address); + + return { + pool: `${pool.address}-${chain}`, + chain, + project: 'rocifi-v2', + symbol: pool.symbol, + tvlUsd, + apyBase, + underlyingTokens: [pool.underlyingToken], + poolMeta: `RociFi ${pool.underlyingSymbol} lending pool`, + totalBorrowUsd, + totalSupplyUsd, + apyBaseBorrow: pool.apyBaseBorrow, + ltv: pool.ltv, + }; + }) + ); +} + +module.exports = { + timetravel: false, + apy: getPoolData, + url: 'https://roci.fi/app/markets', +}; diff --git a/src/adaptors/rocket-pool/abi.js b/src/adaptors/rocket-pool/abi.js new file mode 100644 index 0000000000..6c17c1f461 --- /dev/null +++ b/src/adaptors/rocket-pool/abi.js @@ -0,0 +1,27 @@ +module.exports = [ + { + inputs: [ + { internalType: 'uint256', name: 'offset', type: 'uint256' }, + { internalType: 'uint256', name: 'limit', type: 'uint256' }, + ], + name: 'getMinipoolCountPerStatus', + outputs: [ + { internalType: 'uint256', name: 'initialisedCount', type: 'uint256' }, + { internalType: 'uint256', name: 'prelaunchCount', type: 'uint256' }, + { internalType: 'uint256', name: 'stakingCount', type: 'uint256' }, + { internalType: 'uint256', name: 'withdrawableCount', type: 'uint256' }, + { internalType: 'uint256', name: 'dissolvedCount', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '_networkContractName', type: 'string' }, + ], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/rocket-pool/index.js b/src/adaptors/rocket-pool/index.js new file mode 100644 index 0000000000..4556ac33c1 --- /dev/null +++ b/src/adaptors/rocket-pool/index.js @@ -0,0 +1,97 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abi = require('./abi.js'); +const rethAbi = require('./rethAbi.js'); + +const rocketMinipoolManager = '0x6293B8abC1F36aFB22406Be5f96D893072A8cF3a'; +const rocketVault = '0x3bDC69C4E5e13E52A65f5583c23EFB9636b469d6'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const token = '0xae78736cd615f374d3085123a210448e74fc6393'; //reth + +// mostly copy pasta from tvl adapter +const getApy = async () => { + // Get ETH staked for rETH, which is given by users and Node Operators + // Get minipool count per status + let offset = 0; + const limit = 400, + statusesCount = 5; + let minipool_count_per_status = new Array(statusesCount).fill(0); + + while (true) { + const { output: activeMinipoolCount } = await sdk.api.abi.call({ + target: rocketMinipoolManager, + params: [offset, limit], + abi: abi.find((m) => m.name === 'getMinipoolCountPerStatus'), + chain: 'ethereum', + }); + + const activeMinipoolCount_arr = [...Array(statusesCount).keys()].map( + (i) => activeMinipoolCount[i.toString()] + ); + minipool_count_per_status = minipool_count_per_status.map( + (sum, idx) => sum + parseInt(activeMinipoolCount[idx]) + ); + if (activeMinipoolCount_arr.reduce((a, b) => a + parseInt(b), 0) < limit) { + break; + } + offset += limit; + } + + // Get ETH balance of multiple rocketpool contracts as well as RPL staked + const [ + { output: rocketDepositPoolBalance }, + { output: rocketTokenRETHBalance }, + ] = await Promise.all([ + sdk.api.abi.call({ + target: rocketVault, + params: ['rocketDepositPool'], + abi: abi.find((m) => m.name === 'balanceOf'), + chain: 'ethereum', + }), + sdk.api.abi.call({ + target: rocketVault, + params: ['rocketTokenRETH'], + abi: abi.find((m) => m.name === 'balanceOf'), + chain: 'ethereum', + }), + ]); + + // ETH staked in Rocketpool pools + const unmatched_minipools = minipool_count_per_status[0] * 16; // Unmatched minipools + const pending_minipools = minipool_count_per_status[1] * 32; // Pending minipools (matched but not staking yet) + const staking_minipools = minipool_count_per_status[2] * 32; // Staking minipools + const withdrawable_minipools = minipool_count_per_status[3] * 32; // Withdrawable minipools + + const ETH_TVL = + staking_minipools + + pending_minipools + + unmatched_minipools + + withdrawable_minipools + + parseFloat(rocketDepositPoolBalance) / 1e18 + + parseFloat(rocketTokenRETHBalance) / 1e18; + + const apyData = (await axios.get('https://api.rocketpool.net/api/apr')).data; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'rocket-pool', + symbol: 'rETH', + tvlUsd: ETH_TVL * ethPrice, + apyBase: Number(apyData.yearlyAPR), + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://stake.rocketpool.net/', +}; diff --git a/src/adaptors/rocket-pool/rethAbi.js b/src/adaptors/rocket-pool/rethAbi.js new file mode 100644 index 0000000000..3709a1cf53 --- /dev/null +++ b/src/adaptors/rocket-pool/rethAbi.js @@ -0,0 +1,295 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract RocketStorageInterface', + name: '_rocketStorageAddress', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'EtherDeposited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'ethAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'TokensBurned', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'ethAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'TokensMinted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_rethAmount', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'subtractedValue', type: 'uint256' }, + ], + name: 'decreaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositExcess', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'depositExcessCollateral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getCollateralRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_rethAmount', type: 'uint256' }], + name: 'getEthValue', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getExchangeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_ethAmount', type: 'uint256' }], + name: 'getRethValue', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTotalCollateral', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'addedValue', type: 'uint256' }, + ], + name: 'increaseAllowance', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_ethAmount', type: 'uint256' }, + { internalType: 'address', name: '_to', type: 'address' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, +]; diff --git a/src/adaptors/rocky/config.js b/src/adaptors/rocky/config.js new file mode 100644 index 0000000000..4fc289b5ad --- /dev/null +++ b/src/adaptors/rocky/config.js @@ -0,0 +1,9 @@ +const config = { + sei: { + chainName: 'sei', + USDr: '0x53fdd705873d8259d6d179901fc3fdcb5339f921', + sUSDr: '0xc0029b98f09c9062056c14c0329d3a114a098617', + }, +}; + +module.exports = { config }; diff --git a/src/adaptors/rocky/index.js b/src/adaptors/rocky/index.js new file mode 100644 index 0000000000..f12964e4ab --- /dev/null +++ b/src/adaptors/rocky/index.js @@ -0,0 +1,61 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const { config } = require('./config'); +const BigNumber = require('bignumber.js'); + +// function getEstimatedAPR is misleading, it returns the estimated APY +const getEstimatedAPR = + 'function estimatedAPR() external view returns (uint256)'; +const getTotalAssets = 'function totalAssets() external view returns (uint256)'; + +const getsUSDrData = async (chain, chainConfig) => { + const { chainName, USDr, sUSDr } = chainConfig; + let estimatedAPY; + let totalAssets; + const api = new sdk.ChainApi({ chain }); + [estimatedAPY, totalAssets] = await Promise.all([ + api.call({ + abi: getEstimatedAPR, + target: sUSDr, + }), + api.call({ + abi: getTotalAssets, + target: sUSDr, + }), + ]); + + const tvlUsd = new BigNumber( + ethers.utils.formatUnits(totalAssets, 18) + ).toNumber(); + const apyBase = new BigNumber( + ethers.utils.formatUnits(estimatedAPY, 16) + ).toNumber(); + + return { + pool: `${sUSDr}-rocky`.toLowerCase(), + chain: utils.formatChain(chainName), + project: 'rocky', + symbol: 'sUSDr', + tvlUsd: tvlUsd, + apyBase: apyBase, + rewardTokens: [USDr], + underlyingTokens: [USDr], + poolMeta: 'saving', + }; +}; + +const main = async () => { + const markets = []; + for (let [chain, data] of Object.entries(config)) { + const result = await getsUSDrData(chain, data); + markets.push(result); + } + return markets; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.rocky.cash/earn', +}; diff --git a/src/adaptors/rodeo/abis.json b/src/adaptors/rodeo/abis.json new file mode 100644 index 0000000000..221dcf9635 --- /dev/null +++ b/src/adaptors/rodeo/abis.json @@ -0,0 +1,116 @@ +{ + "peekPools": { + "inputs": [ + { + "internalType": "address[]", + "name": "pools", + "type": "address[]" + } + ], + "name": "peekPools", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "peekPoolInfos" : { + "inputs": [ + { + "internalType": "address[]", + "name": "pools", + "type": "address[]" + } + ], + "name": "peekPoolInfos", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "", + "type": "bool[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/rodeo/index.js b/src/adaptors/rodeo/index.js new file mode 100644 index 0000000000..7384592956 --- /dev/null +++ b/src/adaptors/rodeo/index.js @@ -0,0 +1,180 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abi = require('./abis.json'); + +const investorHelper = '0x6f456005A7CfBF0228Ca98358f60E6AE1d347E18'; +const allPools = [ + { + asset: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", + address: "0x0032F5E1520a66C6E572e96A11fBF54aea26f9bE", + slug: "usdc-v1", + }, +]; + +const YEAR = (365 * 24 * 60 * 60); +const weiDecimals = 1000000000000000000; + + +const poolInfo = async (chain) => { + const yieldPools = allPools.map((pool) => { + return {...pool}; + }); + + const peekPools = ( + await sdk.api.abi.multiCall({ + target: investorHelper, + chain, + abi: abi.peekPools, + calls: yieldPools.map((pool) => ({ + params: [[pool.address]], + })), + }) + ).output; + + const peekPoolInfos = ( + await sdk.api.abi.multiCall({ + target: investorHelper, + chain, + abi: abi.peekPoolInfos, + calls: yieldPools.map((pool) => ({ + params: [[pool.address]], + })), + }) + ).output; + + const getOutput = ({output}) => output.map(({output}) => output); + const [symbol, decimals] = await Promise.all( + ['symbol', 'decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: yieldPools.map((token, i) => ({ + target: peekPoolInfos[i].output[0][0], + })), + chain, + }) + ) + ).then((data) => data.map(getOutput)); + const dTokenDecimals = decimals.map((decimal) => + Math.pow(10, Number(decimal)) + ); + + const underlyingTokens = peekPoolInfos.map((pool) => pool.output[0][0]); + + yieldPools.map((pool, i) => { + + const values = peekPools[i].output; + + pool.index = values[0][0]; + pool.share = values[1][0]; + pool.supply = values[2][0]; + pool.borrow = values[3][0]; + pool.rate = values[4][0]; + pool.price = values[5][0]; + pool.utilization = 0; + pool.underlyingToken = underlyingTokens[i]; + pool.symbol = symbol[i]; + pool.decimals = dTokenDecimals[i]; + + if (pool.supply > 0) { + pool.utilization = pool.borrow / pool.supply; + } + }); + + return {yieldPools}; +}; + +function calculateTvl(amount, price, decimals) { + // amount * underlying price = total pool balance in USD + const tvl = (parseFloat(amount) / decimals) * (price / weiDecimals); + return tvl; +} + +const getApy = async () => { + const yieldPools = (await poolInfo('arbitrum')).yieldPools; + + const symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: yieldPools.map((p) => ({ target: p.underlyingToken })), + chain: 'arbitrum', + }) + ).output.map((o) => o.output); + + const pools = yieldPools.map((pool, i) => { + + const totalSupplyUsd = calculateTvl( + pool.supply, + pool.price, + pool.decimals + ); + const totalBorrowUsd = calculateTvl( + pool.borrow, + pool.price, + pool.decimals + ); + + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const borrowAPR = pool.rate * YEAR / weiDecimals * 100; + const lendingAPR = pool.rate * YEAR * pool.utilization / weiDecimals * 100; + + return (readyToExport = exportFormatter( + pool.address, + 'Arbitrum', + symbol[i], + tvlUsd, + lendingAPR, + 0, + pool.underlyingToken, + [allPools[0].asset], + `https://www.rodeofinance.xyz/farm`, + borrowAPR, + 0, + totalSupplyUsd, + totalBorrowUsd, + 0 + )); + }); + + return pools; +}; + +function exportFormatter( + pool, + chain, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingToken, + rewardTokens, + url, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv +) { + return { + pool, + chain, + project: 'rodeo', + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [underlyingToken], + rewardTokens, + url, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + }; +} + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/rook/index.js b/src/adaptors/rook/index.js deleted file mode 100755 index 5df3f0f82a..0000000000 --- a/src/adaptors/rook/index.js +++ /dev/null @@ -1,106 +0,0 @@ -const { request, gql } = require('graphql-request'); - -const utils = require('../utils'); -const pools = require('./pools.json'); - -const url = - 'https://api.thegraph.com/subgraphs/name/keeperdao/keeperdao-staging'; - -const query1 = gql` - { - liquidityPoolSupplies { - id - supply - } - } -`; - -const query2 = gql` - { - underlyingTokens { - id - kToken { - id - } - } - } -`; - -const tvl = (entry, priceData, pools) => { - entry = { ...entry }; - const pool = pools.find((el) => el.address === entry.id); - entry.name = pool.idFrontEnd; - entry.scaledSupplyUsd = - (Number(entry.supply) / 10 ** pool.decimals) * priceData[pool.id].usd; - - return entry; -}; - -const getRookPerYear = (data, priceData) => { - // roughly 90 days for each act - // const baseRookReward = 200000; - // const decayParam = 0.7; - // const n = 3; // this will increment with every new act - // const rookRewardsAct = baseRookReward * decayParam ** n; // will be 98000 for act 3 - const rookRewardsAct = 36500; - const nbActsPerYear = 4; // basically the quarters - const lpShareOfRewards = 0.2; // LPs get 20% of the rewards per act (this can change via governance) - - const rookYearlyRewards = - (rookRewardsAct * nbActsPerYear * lpShareOfRewards) / data.length; - const rookYearlyRewardsUsd = rookYearlyRewards * priceData.rook.usd; - - return rookYearlyRewardsUsd; -}; - -const buildPool = (entry, rookYearlyRewardsUsd, chainString) => { - const newObj = { - pool: entry.kToken.id, - chain: utils.formatChain(chainString), - project: 'rook', - symbol: utils.formatSymbol(entry.name), - tvlUsd: entry.scaledSupplyUsd, - apy: (rookYearlyRewardsUsd / entry.scaledSupplyUsd) * 100, - }; - - return newObj; -}; - -const topLvl = async (chainString, url) => { - // get price data - const tokens = 'renbtc,dai,usd-coin,ethereum,weth,rook'; - const priceData = await utils.getCGpriceData(tokens, true); - - // pull data - let supplyData = await request(url, query1); - let data = await request(url, query2); - data = data.underlyingTokens; - - // add supply to data object - for (const el of data) { - el['supply'] = supplyData.liquidityPoolSupplies.find( - (i) => i.id === el.id - ).supply; - } - - // calculate tvl - data = data.map((el) => tvl(el, priceData, pools)); - - // get rook reward - const rookYearlyRewardsUsd = getRookPerYear(data, priceData); - - // build pool objects - data = data.map((el) => buildPool(el, rookYearlyRewardsUsd, chainString)); - - return data; -}; - -const main = async () => { - const data = await Promise.all([topLvl('ethereum', url)]); - return data.flat(); -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/rook/pools.json b/src/adaptors/rook/pools.json deleted file mode 100644 index ec4f6d65d1..0000000000 --- a/src/adaptors/rook/pools.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "id": "ethereum", - "idFrontEnd": "ETH", - "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "decimals": 18 - }, - { - "id": "weth", - "idFrontEnd": "WETH", - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "decimals": 18 - }, - { - "id": "dai", - "idFrontEnd": "DAI", - "address": "0x6b175474e89094c44da98b954eedeac495271d0f", - "decimals": 18 - }, - { - "id": "usd-coin", - "idFrontEnd": "USDC", - "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - "decimals": 6 - }, - { - "id": "renbtc", - "idFrontEnd": "renBTC", - "address": "0xeb4c2781e4eba804ce9a9803c67d0893436bb27d", - "decimals": 8 - } -] diff --git a/src/adaptors/saddle-finance/abi.js b/src/adaptors/saddle-finance/abi.js new file mode 100644 index 0000000000..028bcc9514 --- /dev/null +++ b/src/adaptors/saddle-finance/abi.js @@ -0,0 +1,665 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'fees', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'invariant', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'AddLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: false, + internalType: 'uint8', + name: 'tokenIndex', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'protocolFee', + type: 'uint256', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newAdminFee', + type: 'uint256', + }, + ], + name: 'NewAdminFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newSwapFee', + type: 'uint256', + }, + ], + name: 'NewSwapFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newWithdrawFee', + type: 'uint256', + }, + ], + name: 'NewWithdrawFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'initialTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'futureTime', + type: 'uint256', + }, + ], + name: 'RampA', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'RemoveLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'fees', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'invariant', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'RemoveLiquidityImbalance', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'boughtId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensBought', + type: 'uint256', + }, + ], + name: 'RemoveLiquidityOne', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'currentA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'StopRampA', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'buyer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensSold', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensBought', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint128', + name: 'soldId', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'boughtId', + type: 'uint128', + }, + ], + name: 'TokenSwap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [], + name: 'MAX_BPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'minToMint', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'addLiquidity', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'calculateRemoveLiquidity', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + { internalType: 'uint8', name: 'tokenIndex', type: 'uint8' }, + ], + name: 'calculateRemoveLiquidityOneToken', + outputs: [ + { + internalType: 'uint256', + name: 'availableTokenAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'tokenIndexFrom', type: 'uint8' }, + { internalType: 'uint8', name: 'tokenIndexTo', type: 'uint8' }, + { internalType: 'uint256', name: 'dx', type: 'uint256' }, + ], + name: 'calculateSwap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'bool', name: 'deposit', type: 'bool' }, + ], + name: 'calculateTokenAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'contract IERC20', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'flashLoanFeeBPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getA', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAPrecise', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getAdminBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: 'index', type: 'uint8' }], + name: 'getToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: 'index', type: 'uint8' }], + name: 'getTokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + name: 'getTokenIndex', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVirtualPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: '_pooledTokens', + type: 'address[]', + }, + { internalType: 'uint8[]', name: 'decimals', type: 'uint8[]' }, + { internalType: 'string', name: 'lpTokenName', type: 'string' }, + { internalType: 'string', name: 'lpTokenSymbol', type: 'string' }, + { internalType: 'uint256', name: '_a', type: 'uint256' }, + { internalType: 'uint256', name: '_fee', type: 'uint256' }, + { internalType: 'uint256', name: '_adminFee', type: 'uint256' }, + { + internalType: 'address', + name: 'lpTokenTargetAddress', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolFeeShareBPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'futureA', type: 'uint256' }, + { internalType: 'uint256', name: 'futureTime', type: 'uint256' }, + ], + name: 'rampA', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256[]', name: 'minAmounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidity', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'maxBurnAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidityImbalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + { internalType: 'uint8', name: 'tokenIndex', type: 'uint8' }, + { internalType: 'uint256', name: 'minAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidityOneToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newAdminFee', type: 'uint256' }], + name: 'setAdminFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newFlashLoanFeeBPS', type: 'uint256' }, + { + internalType: 'uint256', + name: 'newProtocolFeeShareBPS', + type: 'uint256', + }, + ], + name: 'setFlashLoanFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newSwapFee', type: 'uint256' }], + name: 'setSwapFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stopRampA', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'tokenIndexFrom', type: 'uint8' }, + { internalType: 'uint8', name: 'tokenIndexTo', type: 'uint8' }, + { internalType: 'uint256', name: 'dx', type: 'uint256' }, + { internalType: 'uint256', name: 'minDy', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'swap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'swapStorage', + outputs: [ + { internalType: 'uint256', name: 'initialA', type: 'uint256' }, + { internalType: 'uint256', name: 'futureA', type: 'uint256' }, + { internalType: 'uint256', name: 'initialATime', type: 'uint256' }, + { internalType: 'uint256', name: 'futureATime', type: 'uint256' }, + { internalType: 'uint256', name: 'swapFee', type: 'uint256' }, + { internalType: 'uint256', name: 'adminFee', type: 'uint256' }, + { internalType: 'contract LPToken', name: 'lpToken', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawAdminFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/saddle-finance/gaugeAbi.js b/src/adaptors/saddle-finance/gaugeAbi.js new file mode 100644 index 0000000000..c3f6d4bfb8 --- /dev/null +++ b/src/adaptors/saddle-finance/gaugeAbi.js @@ -0,0 +1,565 @@ +module.exports = [ + { + name: 'Deposit', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'Withdraw', + inputs: [ + { name: 'provider', type: 'address', indexed: true }, + { name: 'value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'UpdateLiquidityLimit', + inputs: [ + { name: 'user', type: 'address', indexed: false }, + { name: 'original_balance', type: 'uint256', indexed: false }, + { name: 'original_supply', type: 'uint256', indexed: false }, + { name: 'working_balance', type: 'uint256', indexed: false }, + { name: 'working_supply', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'CommitOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'ApplyOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'Transfer', + inputs: [ + { name: '_from', type: 'address', indexed: true }, + { name: '_to', type: 'address', indexed: true }, + { name: '_value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'Approval', + inputs: [ + { name: '_owner', type: 'address', indexed: true }, + { name: '_spender', type: 'address', indexed: true }, + { name: '_value', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [ + { name: '_lp_token', type: 'address' }, + { name: '_minter', type: 'address' }, + { name: '_admin', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'view', + type: 'function', + name: 'integrate_checkpoint', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'user_checkpoint', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claimable_tokens', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'claimed_reward', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_token', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'claimable_reward', + inputs: [ + { name: '_user', type: 'address' }, + { name: '_reward_token', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_rewards_receiver', + inputs: [{ name: '_receiver', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claim_rewards', + inputs: [], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claim_rewards', + inputs: [{ name: '_addr', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claim_rewards', + inputs: [ + { name: '_addr', type: 'address' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'kick', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deposit', + inputs: [{ name: '_value', type: 'uint256' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deposit', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_addr', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deposit', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_addr', type: 'address' }, + { name: '_claim_rewards', type: 'bool' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'withdraw', + inputs: [{ name: '_value', type: 'uint256' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'withdraw', + inputs: [ + { name: '_value', type: 'uint256' }, + { name: '_claim_rewards', type: 'bool' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'transfer', + inputs: [ + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'transferFrom', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'approve', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'permit', + inputs: [ + { name: '_owner', type: 'address' }, + { name: '_spender', type: 'address' }, + { name: '_value', type: 'uint256' }, + { name: '_deadline', type: 'uint256' }, + { name: '_v', type: 'uint8' }, + { name: '_r', type: 'bytes32' }, + { name: '_s', type: 'bytes32' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'increaseAllowance', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_added_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'decreaseAllowance', + inputs: [ + { name: '_spender', type: 'address' }, + { name: '_subtracted_value', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_reward', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_distributor', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_reward_distributor', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_distributor', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deposit_reward_token', + inputs: [ + { name: '_reward_token', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_killed', + inputs: [{ name: '_is_killed', type: 'bool' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_ownership', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'accept_transfer_ownership', + inputs: [], + outputs: [], + }, + { + stateMutability: 'view', + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'minter', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'sdl_token', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'controller', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'voting_escrow', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'veboost_proxy', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'lp_token', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'version', + inputs: [], + outputs: [{ name: '', type: 'string' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'DOMAIN_SEPARATOR', + inputs: [], + outputs: [{ name: '', type: 'bytes32' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'nonces', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_epoch_time', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'allowance', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'working_balances', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'working_supply', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'period', + inputs: [], + outputs: [{ name: '', type: 'int128' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'period_timestamp', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'integrate_inv_supply', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'integrate_inv_supply_of', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'integrate_checkpoint_of', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'integrate_fraction', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'inflation_rate', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'reward_count', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'reward_tokens', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'reward_data', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'token', type: 'address' }, + { name: 'distributor', type: 'address' }, + { name: 'period_finish', type: 'uint256' }, + { name: 'rate', type: 'uint256' }, + { name: 'last_update', type: 'uint256' }, + { name: 'integral', type: 'uint256' }, + ], + }, + ], + }, + { + stateMutability: 'view', + type: 'function', + name: 'rewards_receiver', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'reward_integral_for', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_killed', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + }, +]; diff --git a/src/adaptors/saddle-finance/gaugeControllerAbi.js b/src/adaptors/saddle-finance/gaugeControllerAbi.js new file mode 100644 index 0000000000..8eaabc7ce6 --- /dev/null +++ b/src/adaptors/saddle-finance/gaugeControllerAbi.js @@ -0,0 +1,487 @@ +module.exports = [ + { + name: 'CommitOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'ApplyOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'VotingEnabled', + inputs: [{ name: 'voting_enabled', type: 'bool', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'AddType', + inputs: [ + { name: 'name', type: 'string', indexed: false }, + { name: 'type_id', type: 'int128', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewTypeWeight', + inputs: [ + { name: 'type_id', type: 'int128', indexed: false }, + { name: 'time', type: 'uint256', indexed: false }, + { name: 'weight', type: 'uint256', indexed: false }, + { name: 'total_weight', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewGaugeWeight', + inputs: [ + { name: 'gauge_address', type: 'address', indexed: false }, + { name: 'time', type: 'uint256', indexed: false }, + { name: 'weight', type: 'uint256', indexed: false }, + { name: 'total_weight', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'VoteForGauge', + inputs: [ + { name: 'time', type: 'uint256', indexed: false }, + { name: 'user', type: 'address', indexed: false }, + { name: 'gauge_addr', type: 'address', indexed: false }, + { name: 'weight', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewGauge', + inputs: [ + { name: 'addr', type: 'address', indexed: false }, + { name: 'gauge_type', type: 'int128', indexed: false }, + { name: 'weight', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [ + { name: '_token', type: 'address' }, + { name: '_voting_escrow', type: 'address' }, + { name: '_veboost_proxy', type: 'address' }, + { name: '_admin', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_ownership', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + gas: 39445, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'apply_transfer_ownership', + inputs: [], + outputs: [], + gas: 41536, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_voting_enabled', + inputs: [{ name: '_voting_enabled', type: 'bool' }], + outputs: [], + gas: 39505, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_types', + inputs: [{ name: '_addr', type: 'address' }], + outputs: [{ name: '', type: 'int128' }], + gas: 3105, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_gauge', + inputs: [ + { name: 'addr', type: 'address' }, + { name: 'gauge_type', type: 'int128' }, + ], + outputs: [], + gas: 9355936476, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_gauge', + inputs: [ + { name: 'addr', type: 'address' }, + { name: 'gauge_type', type: 'int128' }, + { name: 'weight', type: 'uint256' }, + ], + outputs: [], + gas: 9355936476, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'checkpoint', + inputs: [], + outputs: [], + gas: 9265868764, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'checkpoint_gauge', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + gas: 9320254139, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_relative_weight', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 11293, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_relative_weight', + inputs: [ + { name: 'addr', type: 'address' }, + { name: 'time', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 11293, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'gauge_relative_weight_write', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 9320264858, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'gauge_relative_weight_write', + inputs: [ + { name: 'addr', type: 'address' }, + { name: 'time', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 9320264858, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_type', + inputs: [{ name: '_name', type: 'string' }], + outputs: [], + gas: 9355872388, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_type', + inputs: [ + { name: '_name', type: 'string' }, + { name: 'weight', type: 'uint256' }, + ], + outputs: [], + gas: 9355872388, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'change_type_weight', + inputs: [ + { name: 'type_id', type: 'int128' }, + { name: 'weight', type: 'uint256' }, + ], + outputs: [], + gas: 9355717527, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'change_gauge_weight', + inputs: [ + { name: 'addr', type: 'address' }, + { name: 'weight', type: 'uint256' }, + ], + outputs: [], + gas: 9410175915, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'vote_for_gauge_weights', + inputs: [ + { name: '_gauge_addr', type: 'address' }, + { name: '_user_weight', type: 'uint256' }, + ], + outputs: [], + gas: 9375128672, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_gauge_weight', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 5443, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_type_weight', + inputs: [{ name: 'type_id', type: 'int128' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 5413, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_total_weight', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 5122, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_weights_sum_per_type', + inputs: [{ name: 'type_id', type: 'int128' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 5473, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 2970, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3000, + }, + { + stateMutability: 'view', + type: 'function', + name: 'token', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3030, + }, + { + stateMutability: 'view', + type: 'function', + name: 'voting_escrow', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3060, + }, + { + stateMutability: 'view', + type: 'function', + name: 'veboost_proxy', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3090, + }, + { + stateMutability: 'view', + type: 'function', + name: 'n_gauge_types', + inputs: [], + outputs: [{ name: '', type: 'int128' }], + gas: 3120, + }, + { + stateMutability: 'view', + type: 'function', + name: 'n_gauges', + inputs: [], + outputs: [{ name: '', type: 'int128' }], + gas: 3150, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_type_names', + inputs: [{ name: 'arg0', type: 'int128' }], + outputs: [{ name: '', type: 'string' }], + gas: 13756, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauges', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3255, + }, + { + stateMutability: 'view', + type: 'function', + name: 'vote_user_slopes', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'slope', type: 'uint256' }, + { name: 'power', type: 'uint256' }, + { name: 'end', type: 'uint256' }, + ], + }, + ], + gas: 8045, + }, + { + stateMutability: 'view', + type: 'function', + name: 'vote_user_power', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3536, + }, + { + stateMutability: 'view', + type: 'function', + name: 'last_user_vote', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 3832, + }, + { + stateMutability: 'view', + type: 'function', + name: 'points_weight', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'uint256' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'bias', type: 'uint256' }, + { name: 'slope', type: 'uint256' }, + ], + }, + ], + gas: 5868, + }, + { + stateMutability: 'view', + type: 'function', + name: 'time_weight', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3626, + }, + { + stateMutability: 'view', + type: 'function', + name: 'points_sum', + inputs: [ + { name: 'arg0', type: 'int128' }, + { name: 'arg1', type: 'uint256' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { name: 'bias', type: 'uint256' }, + { name: 'slope', type: 'uint256' }, + ], + }, + ], + gas: 5938, + }, + { + stateMutability: 'view', + type: 'function', + name: 'time_sum', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3465, + }, + { + stateMutability: 'view', + type: 'function', + name: 'points_total', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3565, + }, + { + stateMutability: 'view', + type: 'function', + name: 'time_total', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3480, + }, + { + stateMutability: 'view', + type: 'function', + name: 'points_type_weight', + inputs: [ + { name: 'arg0', type: 'int128' }, + { name: 'arg1', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 3901, + }, + { + stateMutability: 'view', + type: 'function', + name: 'time_type_weight', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3585, + }, + { + stateMutability: 'view', + type: 'function', + name: 'voting_enabled', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + gas: 3570, + }, +]; diff --git a/src/adaptors/saddle-finance/gaugeMinterAbi.js b/src/adaptors/saddle-finance/gaugeMinterAbi.js new file mode 100644 index 0000000000..72b0f3c31e --- /dev/null +++ b/src/adaptors/saddle-finance/gaugeMinterAbi.js @@ -0,0 +1,279 @@ +module.exports = [ + { + name: 'Minted', + inputs: [ + { name: 'recipient', type: 'address', indexed: true }, + { name: 'gauge', type: 'address', indexed: false }, + { name: 'minted', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'UpdateMiningParameters', + inputs: [ + { name: 'time', type: 'uint256', indexed: false }, + { name: 'rate', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'CommitNextEmission', + inputs: [{ name: 'rate', type: 'uint256', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'CommitEmergencyReturn', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'ApplyEmergencyReturn', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'CommitOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'ApplyOwnership', + inputs: [{ name: 'admin', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [ + { name: '_token', type: 'address' }, + { name: '_controller', type: 'address' }, + { name: '_emergency_return', type: 'address' }, + { name: '_admin', type: 'address' }, + ], + outputs: [], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'update_mining_parameters', + inputs: [], + outputs: [], + gas: 155943, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'start_epoch_time_write', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 158152, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'future_epoch_time_write', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 158341, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'mint', + inputs: [{ name: 'gauge_addr', type: 'address' }], + outputs: [], + gas: 268280, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'mint_many', + inputs: [{ name: 'gauge_addrs', type: 'address[8]' }], + outputs: [], + gas: 1745103, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'mint_for', + inputs: [ + { name: 'gauge_addr', type: 'address' }, + { name: '_for', type: 'address' }, + ], + outputs: [], + gas: 270873, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'toggle_approve_mint', + inputs: [{ name: 'minting_user', type: 'address' }], + outputs: [], + gas: 38141, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'recover_balance', + inputs: [{ name: '_coin', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + gas: 14650, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_next_emission', + inputs: [{ name: '_rate_per_week', type: 'uint256' }], + outputs: [], + gas: 39683, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_emergency_return', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + gas: 39715, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'apply_transfer_emergency_return', + inputs: [], + outputs: [], + gas: 41806, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_ownership', + inputs: [{ name: 'addr', type: 'address' }], + outputs: [], + gas: 39775, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'apply_transfer_ownership', + inputs: [], + outputs: [], + gas: 41866, + }, + { + stateMutability: 'view', + type: 'function', + name: 'mining_epoch', + inputs: [], + outputs: [{ name: '', type: 'int128' }], + gas: 2850, + }, + { + stateMutability: 'view', + type: 'function', + name: 'start_epoch_time', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 2880, + }, + { + stateMutability: 'view', + type: 'function', + name: 'rate', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 2910, + }, + { + stateMutability: 'view', + type: 'function', + name: 'committed_rate', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 2940, + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_start', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + gas: 2970, + }, + { + stateMutability: 'view', + type: 'function', + name: 'token', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3000, + }, + { + stateMutability: 'view', + type: 'function', + name: 'controller', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3030, + }, + { + stateMutability: 'view', + type: 'function', + name: 'minted', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + gas: 3592, + }, + { + stateMutability: 'view', + type: 'function', + name: 'allowed_to_mint_for', + inputs: [ + { name: 'arg0', type: 'address' }, + { name: 'arg1', type: 'address' }, + ], + outputs: [{ name: '', type: 'bool' }], + gas: 3622, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_emergency_return', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3120, + }, + { + stateMutability: 'view', + type: 'function', + name: 'emergency_return', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3150, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3180, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3210, + }, +]; diff --git a/src/adaptors/saddle-finance/index.js b/src/adaptors/saddle-finance/index.js new file mode 100644 index 0000000000..b11ec5ea65 --- /dev/null +++ b/src/adaptors/saddle-finance/index.js @@ -0,0 +1,221 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abi = require('./abi'); +const gaugeAbi = require('./gaugeAbi'); +const gaugeControllerAbi = require('./gaugeControllerAbi'); +const gaugeMinterAbi = require('./gaugeMinterAbi'); + +const gaugeController = '0x99Cb6c36816dE2131eF2626bb5dEF7E5cc8b9B14'; +const gaugeMinter = '0x358fE82370a1B9aDaE2E3ad69D6cF9e503c96018'; + +const sdl = '0xf1dc500fde233a4055e25e5bbf516372bc4f6871'; + +const subgraph = sdk.graph.modifyEndpoint('79UL5SaLLsbXqC8Ks6v3fwWHR1FRs636FFRHn55o5SWq'); + +const apy = async () => { + const n_gauges = ( + await sdk.api.abi.call({ + target: gaugeController, + abi: gaugeControllerAbi.find((m) => m.name === 'n_gauges'), + chain: 'ethereum', + permitFailure: true, + }) + ).output; + + // includes LiqV5 and root gauges (which are used together with child gauges on arbitrum) + const gauges = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(n_gauges)).keys()].map((i) => ({ + target: gaugeController, + params: [i], + })), + abi: gaugeControllerAbi.find((m) => m.name === 'gauges'), + chain: 'ethereum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gaugeRelativeWeight = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((gauge) => ({ + target: gaugeController, + params: [gauge], + })), + abi: gaugeControllerAbi.find((m) => m.name === 'gauge_relative_weight'), + chain: 'ethereum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const inflationRate = ( + await sdk.api.abi.call({ + target: gaugeMinter, + abi: gaugeMinterAbi.find((m) => m.name === 'rate'), + chain: 'ethereum', + permitFailure: true, + }) + ).output; + + const lpToken = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((gauge) => ({ + target: gauge, + })), + abi: gaugeAbi.find((m) => m.name === 'lp_token'), + chain: 'ethereum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + calls: lpToken.map((lp) => ({ + target: lp, + })), + abi: 'erc20:totalSupply', + chain: 'ethereum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const balanceOf = ( + await sdk.api.abi.multiCall({ + calls: lpToken.map((lp, i) => ({ + target: lp, + params: gauges[i], + })), + abi: 'erc20:balanceOf', + chain: 'ethereum', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const lpTokenRelWeightMap = {}; + for (const [i, weight] of gaugeRelativeWeight.entries()) { + if (lpToken[i]) { + lpTokenRelWeightMap[lpToken[i].toLowerCase()] = { + gaugeWeight: weight, + gaugeShare: balanceOf[i] / totalSupply[i], + }; + } + } + + const q = gql` + query MyQuery { + dailyVolumes(orderBy: timestamp, orderDirection: desc) { + id + timestamp + volume + swap { + id + lpToken + swapFee + virtualPrice + withdrawFee + tokens { + symbol + address + decimals + } + } + } + } + `; + const dailyVolume = (await request(subgraph, q)).dailyVolumes; + // filter to most recent values per pool + let pools = dailyVolume.filter( + (obj, index, self) => + index === self.findIndex((t) => t.swap.id === obj.swap.id) + ); + + // get prices + const uniqueTokens = [ + ...new Set( + pools.map((p) => p.swap.tokens.map((t) => t.address.toLowerCase())).flat() + ), + ] + .concat(sdl) + .map((t) => `ethereum:${t}`) + .join(','); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${uniqueTokens}`) + ).data.coins; + + const finalPools = await Promise.all( + pools.map(async (p, i) => { + const tokenAddresses = ( + await sdk.api.abi.multiCall({ + calls: p.swap.tokens.map((_, j) => ({ + target: p.swap.id, + params: [j], + })), + chain: 'ethereum', + abi: abi.find((m) => m.name === 'getToken'), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokenBalances = ( + await sdk.api.abi.multiCall({ + calls: p.swap.tokens.map((_, j) => ({ + target: p.swap.id, + params: [j], + })), + chain: 'ethereum', + abi: abi.find((m) => m.name === 'getTokenBalance'), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tvlUsd = tokenAddresses.reduce((acc, t, i) => { + const tokenPrice = prices[`ethereum:${t.toLowerCase()}`]?.price; + const tokenDecimals = p.swap.tokens.find( + (token) => token.address.toLowerCase() === t.toLowerCase() + )?.decimals; + return acc + (tokenPrice * tokenBalances[i]) / 10 ** tokenDecimals; + }, 0); + + // swap apr + const apr = ((365 * p.volume * (p.swap.swapFee / 1e10)) / tvlUsd) * 100; + + // sdl apr + const gaugeWeight = + lpTokenRelWeightMap[p.swap.lpToken.toLowerCase()]?.gaugeWeight / 1e18; + const rate = inflationRate / 1e18; // sdl per second + const gaugeShare = + lpTokenRelWeightMap[p.swap.lpToken.toLowerCase()]?.gaugeShare; + const gaugeTvl = gaugeShare * tvlUsd; + const apyReward = + ((rate * 86400 * 365 * prices[`ethereum:${sdl}`]?.price * gaugeWeight) / + gaugeTvl) * + 100 * + 0.4; // lower bound + + return { + pool: p.swap.id, + symbol: p.swap.tokens.map((t) => t.symbol).join('-'), + chain: 'Ethereum', + project: 'saddle-finance', + tvlUsd, + apyBase: utils.aprToApy(apr), + apyReward, + rewardTokens: apyReward > 0 ? [sdl] : null, + underlyingTokens: p.swap.tokens.map((t) => t.address), + }; + }) + ); + + return finalPools.filter( + (p) => + utils.keepFinite(p) && + p.pool !== '0x4f6a43ad7cba042606decaca730d4ce0a57ac62e' // ren pool + ); +}; + +module.exports = { + apy, + url: 'https://saddle.exchange/#/pools', +}; diff --git a/src/adaptors/sandclock/abi.js b/src/adaptors/sandclock/abi.js new file mode 100644 index 0000000000..e6b9290f05 --- /dev/null +++ b/src/adaptors/sandclock/abi.js @@ -0,0 +1,14 @@ +module.exports = { + balanceOf: 'erc20:balanceOf', + totalSupply: 'erc20:totalSupply', + totalAssets: 'function totalAssets() public view returns (uint256)', + totalCollateral: 'function totalCollateral() public view returns (uint256)', + totalDebt: 'function totalDebt() public view returns (uint256)', + getStETH: 'function getStETHByWstETH(uint256) public view returns (uint256)', + usdcBalance: 'function usdcBalance() public view returns (uint256)', + slippage: 'function slippageTolerance() public view returns (uint256)', + ethToUsdc: 'function ethToUsdc(uint256) public view returns (uint256)', + lqtyGain: + 'function getDepositorLQTYGain(address) public view returns (uint256)', + rewardRate: 'function rewardRate() public view returns (uint256)', +}; diff --git a/src/adaptors/sandclock/index.js b/src/adaptors/sandclock/index.js new file mode 100644 index 0000000000..39e1c3574d --- /dev/null +++ b/src/adaptors/sandclock/index.js @@ -0,0 +1,315 @@ +const { ethers } = require('ethers'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi'); +const BigNumber = require('bignumber.js'); // support decimal points +const superagent = require('superagent'); + +const AMBER = '0xdb369eEB33fcfDCd1557E354dDeE7d6cF3146A11'; +const EMERALD = '0x4c406C068106375724275Cbff028770C544a1333'; +const OPAL = '0x096697720056886b905D0DEB0f06AfFB8e4665E5'; + +const LUSD = '0x5f98805A4E8be255a32880FDeC7F6728C6568bA0'; +const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; +const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; +const LQTY = '0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D'; +const WSTETH = '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'; + +const QUARTZ = '0xbA8A621b4a54e61C442F5Ec623687e2a942225ef'; +const STAKED_QUARTZ = '0x0A36F9565c6FB862509aD8d148941968344a55D8'; + +const STABILITY_POOL = '0x66017D22b0f8556afDd19FC67041899Eb65a21bb'; +const PRICE_CONVERTER = '0xD76B0Ff4A487CaFE4E19ed15B73f12f6A92095Ca'; + +const chain = 'ethereum'; + +const DECIMALS = new BigNumber((1e18).toString()); +const USDC_DECIMALS = new BigNumber(1e6).toString(); + +const COINS = [LUSD, USDC, WETH, LQTY, QUARTZ]; + +const vaultMeta = { + // it has to be string literal keys + '0xdb369eEB33fcfDCd1557E354dDeE7d6cF3146A11': { + asset: LUSD, + symbol: 'LUSD', + name: 'Amber', + }, + '0x096697720056886b905D0DEB0f06AfFB8e4665E5': { + asset: USDC, + symbol: 'USDC', + name: 'Opal', + }, + '0x4c406C068106375724275Cbff028770C544a1333': { + asset: WETH, + symbol: 'WETH', + name: 'Emerald', + }, +}; + +const apy = async () => { + const prices = await getPrices(COINS); + + const strategyApys = await Promise.all( + [AMBER, OPAL, EMERALD].map((vault) => calcErc4626PoolApy(vault, prices)) + ); + const stakingApy = await calcQuartzStakingApy(prices); + return [...strategyApys, stakingApy]; +}; + +async function getPrices(addresses) { + const coins = getCoinsURI(addresses); + const url = `https://coins.llama.fi/prices/current/${coins}`; + return await fetchPrices(url); +} + +async function getPricesDaysBefore(addresses, days) { + const coins = getCoinsURI(addresses); + const timestamp = getTimestampDaysBefore(days); + const url = `https://coins.llama.fi/prices/historical/${timestamp}/${coins}`; + return await fetchPrices(url); +} + +async function fetchPrices(url) { + const prices = (await superagent.get(url)).body.coins; + + const pricesByAddresses = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesByAddresses; +} + +function getCoinsURI(addresses) { + return `${addresses.map((address) => `${chain}:${address}`)}`; +} + +async function getBlockNumberDaysBefore(days) { + const daysBefore = getTimestampDaysBefore(days); + return await getBlockNumber(daysBefore); +} + +function getTimestampDaysBefore(days) { + return Math.floor(Date.now() / 1000) - 24 * 60 * 60 * days; +} + +async function getBlockNumber(timestamp) { + const response = await superagent.get( + `https://coins.llama.fi/block/ethereum/${timestamp}` + ); + return response.body.height; +} + +async function calcErc4626PoolApy(vault, prices) { + const tvlUsd = await calcTvl(vault, prices); + + const sharePriceNow = await calcSharePrice(vault, prices); + + const sharePriceYesterday = await calcSharePrice(vault, prices, 1); + const apyBase = calcApy(sharePriceNow, sharePriceYesterday, 1); + + const sharePriceWeekBefore = await calcSharePrice(vault, prices, 7); + const apyBase7d = calcApy(sharePriceNow, sharePriceWeekBefore, 7); + + return { + pool: `${vault}-${chain}`, + chain, + project: 'sandclock', + symbol: vaultMeta[vault].symbol, + tvlUsd, + underlyingTokens: [vaultMeta[vault].asset], + rewardTokens: [QUARTZ], + apyBase, + apyBase7d, + apyReward: 15, // QUARTZ will be airdropped to depositors of Amber, Opal and Emerald vaults + poolMeta: vaultMeta[vault].name, + url: 'https://app.sandclock.org/', + }; +} + +async function calcTvl(vault, prices) { + const asset = vaultMeta[vault].asset; + const price = prices[asset.toLowerCase()]; + const assets = await totalAssets(vault); + const decimals = asset == USDC ? USDC_DECIMALS : DECIMALS; + let tvlUsd = assets.multipliedBy(price).div(decimals); + if (vault === AMBER) { + const lqtyPrice = prices[LQTY.toLowerCase()]; + const lqtyUsd = await calcLqtyUsd(lqtyPrice); + tvlUsd = tvlUsd.plus(lqtyUsd); + } + return tvlUsd.toNumber(); +} + +async function calcLqtyUsd(price, block = 'latest') { + const lqtyBalance = new BigNumber(await balanceOf(LQTY, AMBER, block)); + const lqtyGain = await callAbi(STABILITY_POOL, abi.lqtyGain, AMBER, block); + return lqtyBalance.plus(lqtyGain).multipliedBy(price).div(DECIMALS); +} + +async function calcSharePrice(vault, prices, days = 0) { + let assetPrices = prices; + let block = 'latest'; + if (days > 0) { + assetPrices = await getPricesDaysBefore(COINS, days); + block = await getBlockNumberDaysBefore(days); + } + const assets = await calcAssets(vault, assetPrices, block); + const shares = await getShares(vault, block); + const sharePrice = getSharePrice(assets, shares); + return sharePrice; +} + +async function calcAssets(vault, prices, block = 'latest') { + let assets = await totalAssets(vault, block); + if (vault === AMBER) { + const asset = vaultMeta[vault].asset; + const lusdPrice = prices[asset.toLowerCase()]; + const lqtyPrice = prices[LQTY.toLowerCase()]; + const lqtyAsset = await calcLqtyAsset(lqtyPrice, lusdPrice, block); + assets = assets.plus(lqtyAsset); + } + return assets; +} + +const totalAssets = async (vault, block = 'latest') => { + if (vault == EMERALD) { + // convert ethers.BigNumber to BigNumber to support decimal points + return new BigNumber((await totalEmeraldAssets(block)).toString()); + } else if (vault == OPAL) { + // convert ethers.BigNumber to BigNumber to support decimal points + return new BigNumber((await totalOpalAssets(block)).toString()); + } + return new BigNumber(await callAbi(vault, abi.totalAssets, null, block)); +}; + +const totalEmeraldAssets = async (block = 'latest') => { + const wstEth = await totalCollateral(EMERALD, block); + const stEthCollateral = await callAbi(WSTETH, abi.getStETH, wstEth, block); + const wethDebt = await totalDebt(EMERALD, block); + const float = ethers.BigNumber.from(await balanceOf(WETH, EMERALD, block)); + return float.add(stEthCollateral).sub(wethDebt); +}; + +const totalOpalAssets = async (block = 'latest') => { + const collateral = ethers.BigNumber.from(await totalCollateral(OPAL, block)); + const usdcBalance = await callAbi(OPAL, abi.usdcBalance, null, block); + const wethDebt = await totalDebt(OPAL, block); + const sharesInvested = await balanceOf(EMERALD, OPAL, block); + const emeraldAssets = await totalEmeraldAssets(block); + const emeraldShares = await totalSupply(EMERALD, block); + const wethInvested = emeraldAssets.mul(sharesInvested).div(emeraldShares); + let total = collateral.add(usdcBalance); + + if (wethInvested.gt(wethDebt)) { + const wethProfit = wethInvested.sub(wethDebt); + const usdcProfit = ethers.BigNumber.from( + await ethToUsdc(wethProfit, block) + ); + const slippage = await callAbi(OPAL, abi.slippage, null, block); + const profit = usdcProfit.mul(slippage).div((1e18).toString()); + total = total.add(profit); + } else if (wethInvested.lt(wethDebt)) { + const wethLoss = ethers.BigNumber.from(wethDebt).sub(wethInvested); + const usdcLoss = await ethToUsdc(wethLoss, block); + total = total.sub(usdcLoss); + } + + return total; +}; + +const ethToUsdc = async (wethValue, block = 'latest') => { + return await callAbi( + PRICE_CONVERTER, + abi.ethToUsdc, + wethValue.toString(), + block + ); +}; + +async function calcLqtyAsset(lqtyPrice, lusdPrice, block = 'latest') { + const lqtyBalance = new BigNumber(await balanceOf(LQTY, AMBER, block)); + const lqtyGain = await callAbi(STABILITY_POOL, abi.lqtyGain, AMBER, block); + return lqtyBalance.plus(lqtyGain).multipliedBy(lqtyPrice).div(lusdPrice); +} + +function calcApy(sharePriceNow, sharePriceBefore, daysBetween) { + return sharePriceBefore.isZero() + ? 0 + : sharePriceNow + .minus(sharePriceBefore) + .multipliedBy(36500) + .div(daysBetween) + .div(sharePriceBefore) + .toNumber(); +} + +const totalCollateral = async (vault, block = 'latest') => { + return await callAbi(vault, abi.totalCollateral, null, block); +}; + +const totalDebt = async (vault, block = 'latest') => { + return await callAbi(vault, abi.totalDebt, null, block); +}; + +const balanceOf = async (token, address, block = 'latest') => { + return await callAbi(token, abi.balanceOf, address, block); +}; + +const totalSupply = async (token, block = 'latest') => { + return await callAbi(token, abi.totalSupply, null, block); +}; + +async function getShares(vault, block = 'latest') { + return new BigNumber(await totalSupply(vault, block)); +} + +async function getSharePrice(assets, shares) { + return shares.isZero() ? new BigNumber(0) : assets.div(shares); +} + +async function callAbi(target, abi, params, block = 'latest') { + return (await sdk.api.abi.call({ target, abi, params, block, chain })).output; +} + +async function calcQuartzStakingApy(prices) { + const stakedQuartz = await balanceOf(QUARTZ, STAKED_QUARTZ); + const quartzPrice = prices[QUARTZ.toLowerCase()]; + const tvlUsd = new BigNumber(stakedQuartz.toString()) + .multipliedBy(quartzPrice) + .div(DECIMALS) + .toNumber(); + const rewardRate = await callAbi(STAKED_QUARTZ, abi.rewardRate, null); + const supply = await totalSupply(STAKED_QUARTZ); + const annualRewardUsd = new BigNumber(rewardRate.toString()) + .multipliedBy(365 * 24 * 60 * 60) + .multipliedBy(prices[WETH.toLowerCase()]) + .div(supply); + const apyReward = annualRewardUsd + .multipliedBy(100) + .div(quartzPrice) + .toNumber(); + return { + pool: `${STAKED_QUARTZ}-${chain}`, + chain, + project: 'sandclock', + symbol: 'QUARTZ', + tvlUsd, + underlyingTokens: [QUARTZ], + rewardTokens: [WETH], + apyBase: 0, + apyBase7d: 0, + apyReward, + poolMeta: 'Staked Quartz', + url: 'https://app.sandclock.org/', + }; +} + +module.exports = { + timetravel: true, + apy, + url: 'https://sandclock.org', +}; diff --git a/src/adaptors/saucerswap-v1/index.js b/src/adaptors/saucerswap-v1/index.js new file mode 100644 index 0000000000..efa4c981fc --- /dev/null +++ b/src/adaptors/saucerswap-v1/index.js @@ -0,0 +1,182 @@ +/* + Saucerswap Reward Calculations: + + 1. To Calculate Lp Fee (apyBase) + Reference https://docs.saucerswap.finance/features/liquidity + Fee Share = 24 Volume (5-day avg) * 0.25 / 100 + Yearly Fees = Fee Share *365 + LP Fee = Yearly Fees / Liquidity (5-day avg) * 100 + Rewards are put back into the LP. + + 2. To Calculate Reward for Providing LP (apyReward) + Reference https://docs.saucerswap.finance/features/farm + Rewarded in SAUCE and HBAR tokens + Farm APR = (Weight * (Emission (SAUCE) * Price in USD (SAUCE) + (Emission (HBAR) * Price in USD (HBAR)) / Staked LP in USD * annualized + API (Farms) provide Emissions in per minute so annualized would be = 60*24*365 + Also farms api's emission fields already incorporate the weight of the farming incentives. + If one of the tokens in the LP is HBARX, add partner apy from stader's (apy / 2) since it is a 50/50 LP. +*/ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const protocolSlug = 'saucerswap-v1'; +const baseUrl = 'https://api.saucerswap.finance'; +const staderUrl = + 'https://server.saucerswap.finance/api/v1/partners/stader/stats'; +const apis = { + farms: `${baseUrl}/farms`, + pools: `${baseUrl}/pools`, + fiveDAvg: `${baseUrl}/pools/5day-avg`, + stader: staderUrl, +}; +const chain = 'hedera'; +const minutesAnnualized = BigNumber(60 * 24 * 365); +const sauceTokenSymbol = 'SAUCE'; +const hbarTokenSymbol = 'HBAR'; +const hbarXTokenSymbol = 'HBARX'; +const emissionTokens = [sauceTokenSymbol, hbarTokenSymbol, hbarXTokenSymbol]; + +const calculateTokenTVLUsd = (token, tokenReserve) => { + const tokenDecimal = BigNumber(token.decimals); + const bigTokenReserve = BigNumber(tokenReserve); + const tokenPrice = BigNumber(token.priceUsd); + if (tokenDecimal && tokenPrice) { + return bigTokenReserve + .div(BigNumber(10).pow(tokenDecimal)) + .times(tokenPrice); + } else { + return null; + } +}; + +const main = async () => { + const [farmData, poolsData, fiveDAvgData] = await Promise.all( + ['farms', 'pools', 'fiveDAvg'].map((key) => utils.getData(apis[key])) + ); + let emissionPriceUsd = {}; + // get emission tokens' id and price from pool data + for (let i = 0; i < poolsData.length; i++) { + const pool = poolsData[i]; + if (emissionTokens.length === 0) { + break; + } + let tokenA = pool.tokenA; + let tokenB = pool.tokenB; + let indexOfA = emissionTokens.indexOf(tokenA.symbol); + if (indexOfA >= 0) { + emissionPriceUsd[tokenA.symbol] = { + price: tokenA.priceUsd, + id: tokenA.id, + }; + emissionTokens.splice(indexOfA, 1); + } + let indexOfB = emissionTokens.indexOf(tokenB.symbol); + if (indexOfB >= 0) { + emissionPriceUsd[tokenB.symbol] = { + price: tokenB.priceUsd, + id: tokenB.id, + }; + emissionTokens.splice(indexOfB, 1); + } + } + let fiveDayVolLookup = {}; + let fiveDayPoolIds = Object.keys(fiveDAvgData); + for (let i = 0; i < fiveDayPoolIds.length; i++) { + const poolId = fiveDayPoolIds[i]; + const pool = fiveDAvgData[poolId]; + fiveDayVolLookup[poolId] = { + volume: pool?.volume, + liquidity: pool?.liquidity, + }; + } + let farmDataLookup = {}; + for (let i = 0; i < farmData.length; i++) { + const pool = farmData[i]; + farmDataLookup[pool.poolId] = { + id: pool.id, + poolId: pool.poolId, + sauceEmissions: pool.sauceEmissions, + hbarEmissions: pool.hbarEmissions, + staked: pool.staked, + }; + } + // hbarx pools get staderAPY / 2 since they are staked in one of the pairs. + // const staderApy = BigNumber(staderData.apy); + // const staderPoolApy = staderApy.div(BigNumber(2)); + let data = poolsData + .map((pool) => { + // skip if pool id doesn't exist or we don't have farm data + if (pool.id === undefined || farmDataLookup[pool.id] === undefined) { + return null; + } + const tokenA = pool.tokenA; + const tokenB = pool.tokenB; + const tokenReserveA = pool.tokenReserveA; + const tokenReserveB = pool.tokenReserveB; + const poolId = pool.id; + const lpToken = pool.lpToken; + const poolAddress = lpToken.id; + const poolName = lpToken.name; + const poolSymbol = lpToken.symbol; + //lp fee apr + const fiveDayVolume = fiveDayVolLookup[poolId]; + const volume = BigNumber(fiveDayVolume?.volume); + const liquidity = BigNumber(fiveDayVolume?.liquidity); + const feeShare = volume.times(BigNumber(0.25)).div(BigNumber(100)); + const yearlyFee = feeShare.times(BigNumber(365)); + const lpAwardApr = yearlyFee.div(liquidity).times(BigNumber(100)); // in percentage + //farming apr + const tokenATvlUsd = calculateTokenTVLUsd(tokenA, tokenReserveA); + const tokenBTvlUsd = calculateTokenTVLUsd(tokenB, tokenReserveB); + const lpTvlUsd = tokenATvlUsd.plus(tokenBTvlUsd); + const lpReserve = BigNumber(pool.lpTokenReserve); + const farmData = farmDataLookup[poolId]; + const farmingLpStaked = BigNumber(farmData.staked); + const farmingStakedToTotalLpRatio = farmingLpStaked.div(lpReserve); + const farmingStakedTvlUsd = farmingStakedToTotalLpRatio.times(lpTvlUsd); + const emissionSauce = BigNumber(farmData.sauceEmissions); + const emissionHbar = BigNumber(farmData.hbarEmissions); + const totalEmissionSauceUsdPerYear = emissionSauce + .times(emissionPriceUsd[sauceTokenSymbol].price) + .times(minutesAnnualized); + const totalEmissionHbarUsdPerYear = emissionHbar + .times(emissionPriceUsd[hbarTokenSymbol].price) + .times(minutesAnnualized); + const totalEmissionUsd = totalEmissionSauceUsdPerYear.plus( + totalEmissionHbarUsdPerYear + ); + let baseFarmApr = totalEmissionUsd.div(farmingStakedTvlUsd).times(100); // in percentage + // look up reward token ids; + let rewardTokens = [ + emissionPriceUsd[sauceTokenSymbol].id, + emissionPriceUsd[hbarTokenSymbol].id, + ]; + // add stader apy if pool contains HBARX token + if ( + tokenA.symbol === hbarXTokenSymbol || + tokenB.symbol === hbarXTokenSymbol + ) { + // baseFarmApr = baseFarmApr.plus(staderPoolApy); + baseFarmApr = baseFarmApr; + } + return { + pool: `${poolAddress}`, + // poolMeta: `${poolName}`, + chain: chain, + project: protocolSlug, + symbol: utils.formatSymbol(poolSymbol), + tvlUsd: farmingStakedTvlUsd.toNumber(), + apyBase: lpAwardApr.toNumber(), + apyReward: baseFarmApr.toNumber(), + rewardTokens: rewardTokens, + underlyingTokens: [tokenA.id, tokenB.id], + }; + }) + .filter((data) => data !== null); + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.saucerswap.finance/farm', +}; diff --git a/src/adaptors/save/index.js b/src/adaptors/save/index.js new file mode 100755 index 0000000000..b8f78d9619 --- /dev/null +++ b/src/adaptors/save/index.js @@ -0,0 +1,100 @@ +const fetch = require('node-fetch'); + +const utils = require('../utils'); + +const baseUrl = 'https://api.solend.fi'; +const configEndpoint = `${baseUrl}/v1/markets/configs`; +const reservesEndpoint = `${baseUrl}/v1/reserves`; + +const main = async () => { + const configResponse = await fetch(`${configEndpoint}?deployment=production`); + + const config = await configResponse.json(); + + const reservesConfigs = config.flatMap((market) => + market.reserves.map((reserve) => ({ + ...reserve, + marketName: market.name, + })) + ); + + // note(slasher): seems like the solend team has made changes to the reserveEndpoint, splitting up requests + const tokenIds = reservesConfigs.map((reserve) => reserve.address); + const reserves = []; + const maxIds = 50; + for (let i = 0; i <= tokenIds.length; i += maxIds) { + const tokens = tokenIds.slice(i, i + maxIds).join(','); + const reservesResponse = await fetch(`${reservesEndpoint}?ids=${tokens}`); + const res = (await reservesResponse.json()).results; + + if (res === undefined) continue; + reserves.push(res); + } + + return reserves.flat().map((reserveData, index) => { + const reserveConfig = reservesConfigs[index]; + const liquidity = reserveData.reserve.liquidity; + const collateral = reserveData.reserve.collateral; + const apyBase = Number(reserveData.rates.supplyInterest); + const apyBaseBorrow = Number(reserveData.rates.borrowInterest); + const apyReward = reserveData.rewards.reduce( + (acc, reward) => + reward.side === 'supply' ? (Number(reward.apy) || 0) + acc : acc, + 0 + ); + const apyRewardBorrow = reserveData.rewards.reduce( + (acc, reward) => + reward.side === 'borrow' ? (Number(reward.apy) || 0) + acc : acc, + 0 + ); + + const rewardTokens = reserveData.rewards + .filter((r) => r.side == 'supply') + .map((r) => + r?.rewardMint === 'SLND_OPTION' + ? 'SLNDpmoWTVADgEdndyvWzroNL7zSi1dF9PC3xHGtPwp' + : r?.rewardMint + ); + const secondaryString = + reserveConfig.marketName.charAt(0).toUpperCase() + + reserveConfig.marketName.slice(1) + + ' Pool'; + + // available liquidity + const tvlUsd = + (Number(liquidity.availableAmount) / 10 ** liquidity.mintDecimals) * + (liquidity.marketPrice / 10 ** 18); + + // total borrow + const totalBorrowUsd = + (Number(liquidity.borrowedAmountWads / 1e18) / + 10 ** liquidity.mintDecimals) * + (liquidity.marketPrice / 10 ** 18); + + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + return { + pool: reserveConfig.address, + chain: utils.formatChain('solana'), + project: 'save', + symbol: `${reserveConfig.liquidityToken.symbol}`, + poolMeta: secondaryString, + tvlUsd, + apyBase, + apyReward, + rewardTokens: apyReward > 0 ? rewardTokens : [], + underlyingTokens: [reserveData.reserve.liquidity.mintPubkey], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: apyRewardBorrow > 0 ? apyRewardBorrow : null, + ltv: reserveData.reserve.config.loanToValueRatio / 100, + }; + }); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://solend.fi/pools', +}; diff --git a/src/adaptors/scale/abiGauge.json b/src/adaptors/scale/abiGauge.json new file mode 100644 index 0000000000..73b1030685 --- /dev/null +++ b/src/adaptors/scale/abiGauge.json @@ -0,0 +1,727 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_stake", "type": "address" }, + { "internalType": "address", "name": "_ebribe", "type": "address" }, + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "bool", "name": "_forPair", "type": "bool" }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "BribeTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "notifier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_t", "type": "address" }], + "name": "addBribeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tks", "type": "address[]" } + ], + "name": "addBribeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "address", + "name": "_rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "addReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribe", + "outputs": [ + { "internalType": "contract IBribe", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "bribeTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribesListLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "depositAllFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "earnedBy", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "earnings", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeTaker", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "address[]", "name": "tokens", "type": "address[]" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "getRewardForDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isBribeToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isReward", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { "internalType": "uint256", "name": "_reward", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "payouts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "payoutsNotified", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_t", "type": "address" }], + "name": "removeBribeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tks", "type": "address[]" } + ], + "name": "removeBribeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amt", "type": "uint256" }, + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "address", "name": "_to", "type": "address" } + ], + "name": "rescue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewardData", + "outputs": [ + { + "internalType": "address", + "name": "rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardsDuration", + "type": "uint256" + }, + { "internalType": "uint256", "name": "periodFinish", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" } + ], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tkn", "type": "address" } + ], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_b", "type": "address" }], + "name": "setBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_ft", "type": "address" }], + "name": "setFeeTaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_b", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "address", + "name": "_rewardsDistributor", + "type": "address" + } + ], + "name": "setRewardsDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "totalFeesPayouts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [ + { + "internalType": "contract IVotingEscrow", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { "internalType": "contract IVoter", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/scale/abiPair.json b/src/adaptors/scale/abiPair.json new file mode 100644 index 0000000000..6d9b89a18a --- /dev/null +++ b/src/adaptors/scale/abiPair.json @@ -0,0 +1,684 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/scale/abiPairFactory.json b/src/adaptors/scale/abiPairFactory.json new file mode 100644 index 0000000000..a6f8cccc23 --- /dev/null +++ b/src/adaptors/scale/abiPairFactory.json @@ -0,0 +1,274 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE_NEW", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "feesOverrides", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_stable", "type": "bool" }], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" } + ], + "name": "getRealFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hotload", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_stable", "type": "bool" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pair", "type": "address" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFeesOverrides", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pauser", "type": "address" } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/scale/abiVoter.json b/src/adaptors/scale/abiVoter.json new file mode 100644 index 0000000000..24d50d75e6 --- /dev/null +++ b/src/adaptors/scale/abiVoter.json @@ -0,0 +1,989 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "gaugeRewards", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "allowedRewards", + "type": "address[]" + } + ], + "name": "GaugeAndBribeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pooladdr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_gtokens", + "type": "address[][]" + }, + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_btokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimEverything", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" } + ], + "name": "createGaugeMultiple", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "initialSetup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_gauges", "type": "address" }, + { "internalType": "address", "name": "_bribes", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ms", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "pausedGauges", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pokable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeesPerMillion", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeesTaker", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_ids", "type": "uint256[]" } + ], + "name": "resetOverride", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "resetOverride", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" }, + { "internalType": "address", "name": "_nb", "type": "address" } + ], + "name": "setBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setGaugable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_ms", "type": "address" }], + "name": "setGov", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_g", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setPausedGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_b", "type": "bool" }], + "name": "setPokable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_pf", "type": "uint256" }], + "name": "setProtocolFeesPerMillion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pft", "type": "address" } + ], + "name": "setProtocolFeesTaker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_pools", "type": "address[]" }, + { "internalType": "bool[]", "name": "_b", "type": "bool[]" } + ], + "name": "setUnvotablePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "unvotable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/scale/index.js b/src/adaptors/scale/index.js new file mode 100644 index 0000000000..65a0492a2c --- /dev/null +++ b/src/adaptors/scale/index.js @@ -0,0 +1,144 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); + +const pairFactory = '0xEd8db60aCc29e14bC867a497D94ca6e3CeB5eC04'; +const voter = '0x46ABb88Ae1F2a35eA559925D99Fdc5441b592687'; +const SCALE = '0x54016a4848a38f257B6E96331F7404073Fd9c32C'; + +const getApy = async () => { + //We are looking for the pools that have gauge rewards, NOT the raw trade fee rewards + const allPairsLength = ( + await sdk.api.abi.call({ + target: voter, + abi: abiVoter.find((m) => m.name === 'length'), + chain: 'base', + }) + ).output; + + console.log('allPairsLength', allPairsLength); + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'pools'), + chain: 'base', + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'base', + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'base', + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'base', + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: [SCALE], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'base', + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(SCALE) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let keys = ''; + for (const p of [...Array(pages).keys()]) { + keys = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `base:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${keys}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA) { + prices = { ...prices, ...p }; + } + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`base:${poolMeta.t0}`]?.price; + const p1 = prices[`base:${poolMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const rewardPerSec = + (rewardRate[i] / 1e18) * prices[`base:${SCALE}`]?.price; + const apyReward = ((rewardPerSec * 86400 * 365) / tvlUsd) * 100; + + return { + pool: p, + chain: utils.formatChain('base'), + project: 'scale', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [SCALE] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://base.equalizer.exchange/liquidity', +}; diff --git a/src/adaptors/scallop-lend/index.js b/src/adaptors/scallop-lend/index.js new file mode 100644 index 0000000000..e935d3cf52 --- /dev/null +++ b/src/adaptors/scallop-lend/index.js @@ -0,0 +1,74 @@ +const axios = require('axios'); +const utils = require('../utils') + +const baseUrl = 'https://sdk.api.scallop.io/api'; +const marketEndpoint = `${baseUrl}/market/migrate`; +const spoolsEndpoint = `${baseUrl}/spools/migrate`; +const borrowIncentiveEndpoint = `${baseUrl}/borrowIncentivePools`; + +const main = async () => { + let [market, spools, borrowIncentive] = await Promise.all([axios.get(marketEndpoint), axios.get(spoolsEndpoint), axios.get(borrowIncentiveEndpoint)]); + + const supplyRewards = {}; + const rewardTokenPool = {}; + spools.data.spools.forEach((spool) => { + if(spool.rewardApr <= 0) { + return; + } + supplyRewards[spool.coinType] = { + rewardApr: spool.rewardApr, + rewardCoinType: spool.rewardCoinType, + }; + if(rewardTokenPool[spool.coinType] === undefined) { + rewardTokenPool[spool.coinType] = []; + } + rewardTokenPool[spool.coinType].push(spool.rewardCoinType); + }); + + const borrowRewards = {}; + borrowIncentive.data.forEach((borrow) => { + borrow.rewards.forEach((reward) => { + if (borrowRewards[borrow.coinType] === undefined) { + borrowRewards[borrow.coinType] = []; + } + borrowRewards[borrow.coinType].push({ + rewardApr: reward.rewardApr, + rewardCoinType: reward.coinType, + }); + if(rewardTokenPool[borrow.coinType] === undefined) { + rewardTokenPool[borrow.coinType] = []; + } + rewardTokenPool[borrow.coinType].push(reward.coinType); + }); + }); + + const arr = []; + market.data.pools.forEach((pool) => { + const supplyUsd = parseFloat(pool.supplyCoin) * parseFloat(pool.coinPrice); + const borrowUsd = parseFloat(pool.borrowCoin) * parseFloat(pool.coinPrice); + const collateralFactor = market.data.collaterals.find((collateral) => collateral.coinType === pool.coinType); + arr.push({ + chain: 'Sui', + project: 'scallop-lend', + pool: pool.coinType, + symbol: pool.symbol, + tvlUsd: supplyUsd - borrowUsd, + apyBase: parseFloat(pool.supplyApy * 100), + apyReward: supplyRewards[pool.coinType] ? parseFloat(supplyRewards[pool.coinType].rewardApr * 100) : null, + rewardTokens: rewardTokenPool[pool.coinType] ? Array.from(new Set(rewardTokenPool[pool.coinType])) : null, + totalSupplyUsd: supplyUsd, + totalBorrowUsd: borrowUsd, + apyBaseBorrow: parseFloat(pool.borrowApy * 100), + apyRewardBorrow: borrowRewards[pool.coinType] ? parseFloat(borrowRewards[pool.coinType].reduce((prev, curr) => prev + curr.rewardApr, 0) * 100) : null, + ltv: Number(parseFloat(collateralFactor ? collateralFactor.collateralFactor : 0).toFixed(2)), + }); + }); + + return utils.removeDuplicates(arr) +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.scallop.io/', +}; diff --git a/src/adaptors/sceptre-liquid/index.js b/src/adaptors/sceptre-liquid/index.js new file mode 100644 index 0000000000..d29865122b --- /dev/null +++ b/src/adaptors/sceptre-liquid/index.js @@ -0,0 +1,96 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const { formatChain } = require('../utils'); +const axios = require('axios'); + +const CONFIG = { + SFLR_ADDRESS: '0x12e605bc104e93b45e1ad99f9e555f659051c2bb', + WFLR_ADDRESS: '0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d', + FLARE_CHAIN: 'flare', + PRICE_API: 'https://coins.llama.fi/prices/current', + REWARDS_API: 'https://rewards.sceptre.fi/v1/flare', + TIMEOUT_MS: 10000, + RETRY_ATTEMPTS: 3, + RETRY_DELAY_MS: 1000, +}; + +const ABI = { + totalPooledFlr: { + inputs: [], + name: 'totalPooledFlr', + outputs: [{ type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; + +async function fetchWithRetry(url, options = {}) { + for (let i = 0; i < CONFIG.RETRY_ATTEMPTS; i++) { + try { + const response = await axios.get(url, { + timeout: CONFIG.TIMEOUT_MS, + ...options + }); + return response.data; + } catch (error) { + if (i === CONFIG.RETRY_ATTEMPTS - 1) throw error; + await new Promise(resolve => setTimeout(resolve, CONFIG.RETRY_DELAY_MS * Math.pow(2, i))); + } + } +} + +async function fetchTotalPooledFlr() { + const { output } = await sdk.api.abi.call({ + target: CONFIG.SFLR_ADDRESS, + abi: ABI.totalPooledFlr, + chain: CONFIG.FLARE_CHAIN, + }); + return new BigNumber(output); +} + +async function fetchFlarePrice() { + const priceKey = `${CONFIG.FLARE_CHAIN}:${CONFIG.WFLR_ADDRESS.toLowerCase()}`; + const pricesResponse = await fetchWithRetry(`${CONFIG.PRICE_API}/${priceKey}`); + return new BigNumber(pricesResponse.coins[priceKey].price); +} + +function calculateTvl(totalPooledFlr, flarePrice) { + return totalPooledFlr.dividedBy(1e18).multipliedBy(flarePrice); +} + +async function fetchStakingApy() { + const apyResponse = await fetchWithRetry(CONFIG.REWARDS_API); + return new BigNumber(apyResponse.apy); +} + +async function main() { + try { + const [totalPooledFlr, flarePrice, stakingApy] = await Promise.all([ + fetchTotalPooledFlr(), + fetchFlarePrice(), + fetchStakingApy(), + ]); + + const tvlUsd = calculateTvl(totalPooledFlr, flarePrice); + + return [{ + pool: CONFIG.SFLR_ADDRESS, + chain: formatChain(CONFIG.FLARE_CHAIN), + project: 'sceptre-liquid', + symbol: 'sFLR', + tvlUsd: tvlUsd.toNumber(), + apyBase: stakingApy.multipliedBy(100).toNumber(), + underlyingTokens: [CONFIG.WFLR_ADDRESS], + poolMeta: 'Unstaking Cooldown: 14.5days' + }]; + } catch (error) { + console.error('Error fetching data:', error.message); + throw new Error(`Failed to fetch data: ${error.message}`); + } +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://flare.sceptre.fi/', +}; diff --git a/src/adaptors/scream/abi.js b/src/adaptors/scream/abi.js new file mode 100644 index 0000000000..db1dd40106 --- /dev/null +++ b/src/adaptors/scream/abi.js @@ -0,0 +1,3 @@ +module.exports ={ + comptrollerABI: [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"action","type":"string"},{"indexed":false,"internalType":"bool","name":"pauseState","type":"bool"}],"name":"ActionPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"string","name":"action","type":"string"},{"indexed":false,"internalType":"bool","name":"pauseState","type":"bool"}],"name":"ActionPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSpeed","type":"uint256"}],"name":"CompSpeedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"compDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compBorrowIndex","type":"uint256"}],"name":"DistributedBorrowerComp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":true,"internalType":"address","name":"supplier","type":"address"},{"indexed":false,"internalType":"uint256","name":"compDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compSupplyIndex","type":"uint256"}],"name":"DistributedSupplierComp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"Failure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketEntered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketExited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"MarketListed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newBorrowCap","type":"uint256"}],"name":"NewBorrowCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldBorrowCapGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newBorrowCapGuardian","type":"address"}],"name":"NewBorrowCapGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCloseFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCloseFactorMantissa","type":"uint256"}],"name":"NewCloseFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCollateralFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralFactorMantissa","type":"uint256"}],"name":"NewCollateralFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLiquidationIncentiveMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLiquidationIncentiveMantissa","type":"uint256"}],"name":"NewLiquidationIncentive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPauseGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newPauseGuardian","type":"address"}],"name":"NewPauseGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract PriceOracle","name":"oldPriceOracle","type":"address"},{"indexed":false,"internalType":"contract PriceOracle","name":"newPriceOracle","type":"address"}],"name":"NewPriceOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract CToken","name":"cToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"newSupplyCap","type":"uint256"}],"name":"NewSupplyCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldSupplyCapGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newSupplyCapGuardian","type":"address"}],"name":"NewSupplyCapGuardian","type":"event"},{"constant":false,"inputs":[{"internalType":"contract Unitroller","name":"unitroller","type":"address"}],"name":"_become","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_borrowGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_mintGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newBorrowCapGuardian","type":"address"}],"name":"_setBorrowCapGuardian","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"_setBorrowPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newCloseFactorMantissa","type":"uint256"}],"name":"_setCloseFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"uint256","name":"newCollateralFactorMantissa","type":"uint256"}],"name":"_setCollateralFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"cTokens","type":"address[]"},{"internalType":"uint256[]","name":"speeds","type":"uint256[]"}],"name":"_setCompSpeeds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newLiquidationIncentiveMantissa","type":"uint256"}],"name":"_setLiquidationIncentive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken[]","name":"cTokens","type":"address[]"},{"internalType":"uint256[]","name":"newBorrowCaps","type":"uint256[]"}],"name":"_setMarketBorrowCaps","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken[]","name":"cTokens","type":"address[]"},{"internalType":"uint256[]","name":"newSupplyCaps","type":"uint256[]"}],"name":"_setMarketSupplyCaps","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"_setMintPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPauseGuardian","type":"address"}],"name":"_setPauseGuardian","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract PriceOracle","name":"newOracle","type":"address"}],"name":"_setPriceOracle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"_setSeizePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newSupplyCapGuardian","type":"address"}],"name":"_setSupplyCapGuardian","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"_setTransferPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"_supportMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountAssets","outputs":[{"internalType":"contract CToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allMarkets","outputs":[{"internalType":"contract CToken","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"borrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"borrowCapGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowCaps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"borrowVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"contract CToken[]","name":"cTokens","type":"address[]"}],"name":"claimComp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"holders","type":"address[]"},{"internalType":"contract CToken[]","name":"cTokens","type":"address[]"},{"internalType":"bool","name":"borrowers","type":"bool"},{"internalType":"bool","name":"suppliers","type":"bool"}],"name":"claimComp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"claimComp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"closeFactorMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compBorrowState","outputs":[{"internalType":"uint224","name":"index","type":"uint224"},{"internalType":"uint32","name":"block","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"compBorrowerIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"compClaimThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"compInitialIndex","outputs":[{"internalType":"uint224","name":"","type":"uint224"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"compRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compSpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"compSupplierIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compSupplyState","outputs":[{"internalType":"uint224","name":"index","type":"uint224"},{"internalType":"uint32","name":"block","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"comptrollerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"cTokens","type":"address[]"}],"name":"enterMarkets","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cTokenAddress","type":"address"}],"name":"exitMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllMarkets","outputs":[{"internalType":"contract CToken[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAssetsIn","outputs":[{"internalType":"contract CToken[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCompAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"cTokenModify","type":"address"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"},{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"getHypotheticalAccountLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isComptroller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"liquidateBorrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"liquidateBorrowVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"}],"name":"liquidateCalculateSeizeTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"liquidationIncentiveMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"markets","outputs":[{"internalType":"bool","name":"isListed","type":"bool"},{"internalType":"uint256","name":"collateralFactorMantissa","type":"uint256"},{"internalType":"bool","name":"isComped","type":"bool"},{"internalType":"enum ComptrollerV2Storage.Version","name":"version","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"mintAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"actualMintAmount","type":"uint256"},{"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"mintVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"internalType":"contract PriceOracle","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pauseGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingComptrollerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeemAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"redeemVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"payer","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"repayBorrowAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"payer","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"actualRepayAmount","type":"uint256"},{"internalType":"uint256","name":"borrowerIndex","type":"uint256"}],"name":"repayBorrowVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"seizeAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"seizeGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cTokenCollateral","type":"address"},{"internalType":"address","name":"cTokenBorrowed","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"seizeTokens","type":"uint256"}],"name":"seizeVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supplyCapGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyCaps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"transferTokens","type":"uint256"}],"name":"transferAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"transferGuardianPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"cToken","type":"address"},{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"transferTokens","type":"uint256"}],"name":"transferVerify","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] +} \ No newline at end of file diff --git a/src/adaptors/scream/index.js b/src/adaptors/scream/index.js new file mode 100644 index 0000000000..d7fb4690c0 --- /dev/null +++ b/src/adaptors/scream/index.js @@ -0,0 +1,116 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); +const { comptrollerABI } = require('./abi'); + +const API_URL = sdk.graph.modifyEndpoint( + '5HSMXwr8MjGvXgsur1xJdx9FV47qkaUxttYSsnZ2G3F4' +); +const COMPTROLLER_ADDRESS = '0x3d3094Aec3b63C744b9fe56397D36bE568faEBdF'; + +const BLOCK_TIME = 1; +const BLOCKS_PER_YEAR = BLOCK_TIME * 60 * 60 * 24 * 365; + +const query = gql` + { + markets { + id + underlyingSymbol + supplyRate + cash + underlyingPriceUSD + totalBorrows + underlyingAddress + collateralFactor + borrowRate + } + } +`; + +const getRewardTokenApr = async (marketsData) => { + const key = 'coingecko:scream'; + const rewardTokenPrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key]?.price; + + const compSpeeds = ( + await sdk.api.abi.multiCall({ + calls: marketsData.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: m.id, + })), + chain: 'fantom', + abi: comptrollerABI.find((m) => m.name === 'compSpeeds'), + }) + ).output.map((i) => i.output); + + const rewardsPerBlock = marketsData.map((market, i) => ({ + market: market.id, + reward: Number(compSpeeds[i]), + totalBorrowUSD: + Number(market.totalBorrows) * Number(market.underlyingPriceUSD), + totalSupplyUSD: + (Number(market.cash) + Number(market.totalBorrows)) * + Number(market.underlyingPriceUSD), + })); + + const apr = rewardsPerBlock.reduce( + (acc, { market, reward, totalBorrowUSD, totalSupplyUSD }) => { + return { + ...acc, + [market.toLowerCase()]: { + apyReward: + (((reward / 10 ** 18) * BLOCKS_PER_YEAR * rewardTokenPrice) / + totalSupplyUSD) * + 100, + apyRewardBorrow: + (((reward / 10 ** 18) * BLOCKS_PER_YEAR * rewardTokenPrice) / + totalBorrowUSD) * + 100, + }, + }; + }, + {} + ); + + return apr; +}; + +const getApy = async () => { + const marketsData = await request(API_URL, query); + + const rewardTokenApr = await getRewardTokenApr(marketsData.markets); + + const pools = marketsData.markets.map((market) => { + return { + pool: market.id, + chain: utils.formatChain('fantom'), + project: 'scream', + symbol: market.underlyingSymbol, + tvlUsd: market.underlyingPriceUSD * market.cash, + apyBase: Number(market.supplyRate) * 100, + apyReward: rewardTokenApr[market.id.toLowerCase()].apyReward, + rewardTokens: ['0xe0654c8e6fd4d733349ac7e09f6f23da256bf475'], + underlyingTokens: [market.underlyingAddress], + // borrow fields + totalSupplyUsd: + (Number(market.cash) + Number(market.totalBorrows)) * + Number(market.underlyingPriceUSD), + totalBorrowUsd: + Number(market.totalBorrows) * Number(market.underlyingPriceUSD), + apyBaseBorrow: market.borrowRate * 100, + apyRewardBorrow: rewardTokenApr[market.id.toLowerCase()].apyRewardBorrow, + ltv: Number(market.collateralFactor), + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://scream.sh/lend', +}; diff --git a/src/adaptors/scrub-invest/abi.js b/src/adaptors/scrub-invest/abi.js new file mode 100644 index 0000000000..4bf0b4d283 --- /dev/null +++ b/src/adaptors/scrub-invest/abi.js @@ -0,0 +1,2030 @@ +module.exports = { + windAndCheck: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [], + name: 'BORROWPERCENT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'FEEPERCENT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'HUNDREDPERCENT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'UNBORROWPERCENT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'address', + name: '_to', + type: 'address', + }, + { + internalType: 'address', + name: 'routerAddr', + type: 'address', + }, + ], + name: '_estimateSwap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'checkMembership', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'compoundThreshold', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'deposited', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'extraRewardRoute', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAccountLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentBorrowAmount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentBorrowableSafeLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentBorrowableUnSafeLiquidity', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentSuppliedAmount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentTotalCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRewardsExternal', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserInfo', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'dollarValue', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deposited', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastAPR', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentBorrow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'currentSafeLiquidityFree', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupplied', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastCompoundTime', + type: 'uint256', + }, + ], + internalType: 'struct WindAndCheck.UserInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_tokenAddressToLoop', + type: 'address', + }, + { + internalType: 'address', + name: '_rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: '_routerAddress', + type: 'address', + }, + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + { + internalType: 'address[]', + name: '_TOKENS', + type: 'address[]', + }, + { + internalType: 'bool', + name: '_isCurve', + type: 'bool', + }, + { + internalType: 'address[]', + name: '_routeAddress', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: '_stable', + type: 'bool[]', + }, + { + internalType: 'uint256', + name: '_BORROWPERCENT', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_UNBORROWPERCENT', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_FEEPERCENT', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_HUNDREDPERCENT', + type: 'uint256', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAPR', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastCompoundTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'routerAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_borrowPercent', + type: 'uint256', + }, + ], + name: 'setBorrowPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rewardTokenExtra', + type: 'address', + }, + { + internalType: 'address[]', + name: '_extraRewardRoute', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: '_extraRewardStable', + type: 'bool[]', + }, + { + internalType: 'bool', + name: '_isCurveExtra', + type: 'bool', + }, + ], + name: 'setExtraRewardRoute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_feePercent', + type: 'uint256', + }, + ], + name: 'setFeePercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_hundredPercent', + type: 'uint256', + }, + ], + name: 'setHundredPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: '_isCurve', + type: 'bool', + }, + ], + name: 'setIsCurve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rewardToken', + type: 'address', + }, + ], + name: 'setRewardToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_routeAddress', + type: 'address[]', + }, + ], + name: 'setRouteAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_routerAddress', + type: 'address', + }, + ], + name: 'setRouterAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool[]', + name: '_stable', + type: 'bool[]', + }, + ], + name: 'setStable', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_tokenAddressToLoop', + type: 'address', + }, + ], + name: 'setTokenAddressToLoop', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + ], + name: 'setTreasury', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_unBorrowPercent', + type: 'uint256', + }, + ], + name: 'setUnBorrowPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenOut', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'swapCurve', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'tokenAddressToLoop', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrowed', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupplied', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'val', + type: 'uint256', + }, + ], + name: 'typeConvert', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'withdrawn', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + compounders: [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'contractInfo', + outputs: [ + { + internalType: 'address', + name: 'wantAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'zapTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'routerAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'rewardToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'FEEPERCENT', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'HUNDREDPERCENT', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isStable', + type: 'bool', + }, + { + internalType: 'address', + name: 'gauge', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'deposited', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentTotalCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRewardsExternal', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserInfo', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'dollarValue', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deposited', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'withdrawn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastAPR', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastCompoundTime', + type: 'uint256', + }, + ], + internalType: 'struct AutoCompounder.UserInfo', + name: 'userInfo', + type: 'tuple', + }, + { + internalType: 'address', + name: 'token0', + type: 'address', + }, + { + internalType: 'address', + name: 'token1', + type: 'address', + }, + { + internalType: 'uint256', + name: 'reserve0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserve1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalSupply', + type: 'uint256', + }, + ], + internalType: 'struct AutoCompounder.ExtendedInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_want', + type: 'address', + }, + { + internalType: 'address', + name: '_rewardToken', + type: 'address', + }, + { + internalType: 'address', + name: '_routerAddress', + type: 'address', + }, + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + { + internalType: 'address[]', + name: '_routeAddress', + type: 'address[]', + }, + { + internalType: 'bool[]', + name: '_stable', + type: 'bool[]', + }, + { + internalType: 'uint256', + name: '_FEEPERCENT', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_HUNDREDPERCENT', + type: 'uint256', + }, + { + internalType: 'bool', + name: '_isStable', + type: 'bool', + }, + { + internalType: 'address', + name: '_zapTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: '_gauge', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAPR', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastCompoundTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_feePercent', + type: 'uint256', + }, + ], + name: 'setFeePercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_hundredPercent', + type: 'uint256', + }, + ], + name: 'setHundredPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rewardToken', + type: 'address', + }, + ], + name: 'setRewardToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_routeAddress', + type: 'address[]', + }, + ], + name: 'setRouteAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_routerAddress', + type: 'address', + }, + ], + name: 'setRouterAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool[]', + name: '_stable', + type: 'bool[]', + }, + ], + name: 'setStable', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + ], + name: 'setTreasury', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_wantAddress', + type: 'address', + }, + ], + name: 'setWantAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_zapTokenAddress', + type: 'address', + }, + ], + name: 'setZapTokenAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalCollateral', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'val', + type: 'uint256', + }, + ], + name: 'typeConvert', + outputs: [ + { + internalType: 'int128', + name: '', + type: 'int128', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'withdrawn', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'zapAndStake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + lpAbi: [ + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'burn', + outputs: [ + { + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'claimFees', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'getAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [ + { + internalType: 'uint256', + name: '_reserve0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_reserve1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_blockTimestampLast', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'metadata', + outputs: [ + { + internalType: 'uint256', + name: 'dec0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'dec1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'r0', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'r1', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'st', + type: 'bool', + }, + { + internalType: 'address', + name: 't0', + type: 'address', + }, + { + internalType: 'address', + name: 't1', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'mint', + outputs: [ + { + internalType: 'uint256', + name: 'liquidity', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'v', + type: 'uint8', + }, + { + internalType: 'bytes32', + name: 'r', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 's', + type: 'bytes32', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'swap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'tokens', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'src', + type: 'address', + }, + { + internalType: 'address', + name: 'dst', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + ercAbi: [ + { + inputs: [ + { + internalType: 'string', + name: 'name_', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol_', + type: 'string', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/scrub-invest/index.js b/src/adaptors/scrub-invest/index.js new file mode 100644 index 0000000000..00d7735b0d --- /dev/null +++ b/src/adaptors/scrub-invest/index.js @@ -0,0 +1,244 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { windAndCheck, compounders, lpAbi, ercAbi } = require('./abi'); + +const CHAIN = 'kava'; + +const PROJECT_NAME = 'scrub-invest'; + +const vaults = { + USDt: '0xfA8f4Fd6D961ECf25e3406a1e6a22A3671678a65', + + KAVA: '0xC00804268b8Ce19D2276A81292a6E28277bf3591', +}; + +const vaultsLP = { + 'TIGER/LION': '0x9e890FBD4295D92c41fA12a2083b51C387699Fd8', +}; +const tokens = [ + { + name: 'USDt', + decimals: 6, + address: '0x919C1c267BC06a7039e03fcc2eF738525769109c', + tokens: ['0x919C1c267BC06a7039e03fcc2eF738525769109c'], + }, + { + name: 'KAVA', + decimals: 18, + address: '0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b', + tokens: ['0xc86c7C0eFbd6A49B35E8714C5f59D99De09A225b'], + }, + { + name: 'TIGER/LION', + decimals: 18, + address: '0x78Ef6D3E3d0da9B2248C11BE11743B4C573ADd25', + tokens: [ + '0x990e157fC8a492c28F5B50022F000183131b9026', + '0x471F79616569343e8e84a66F342B7B433b958154', + ], + lp: true, + }, +]; +const getOutput = ({ output }) => output.map(({ output }) => output); + +const unwrapLP = async (chain, lpTokens) => { + const [tokens, getReserves, totalSupply] = await Promise.all( + ['tokens', 'getReserves', 'totalSupply'].map((method) => + sdk.api.abi.multiCall({ + abi: lpAbi.find(({ name }) => name === method), + calls: lpTokens.map((token) => ({ + target: token, + })), + chain, + }) + ) + ).then((data) => data.map(getOutput)); + const token0Addresses = tokens.map((token) => token[0]); + const token1Addresses = tokens.map((token) => token[1]); + const token0 = tokens.map((token) => `${chain}:${token[0]}`); + const token1 = tokens.map((token) => `${chain}:${token[1]}`); + const token0Decimals = ( + await sdk.api.abi.multiCall({ + abi: ercAbi.find(({ name }) => name === 'decimals'), + calls: token0Addresses.map((token) => ({ + target: token, + })), + chain, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + const token1Decimals = ( + await sdk.api.abi.multiCall({ + abi: ercAbi.find(({ name }) => name === 'decimals'), + calls: token1Addresses.map((token) => ({ + target: token, + })), + chain, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + const token0Price = await getPrices(token0); + const token1Price = await getPrices(token1); + const lpMarkets = lpTokens.map((lpToken) => { + return { lpToken }; + }); + + lpMarkets.map((token, i) => { + if (isNaN(token0Price[token0Addresses[i].toLowerCase()])) { + token.lpPrice = + (2 * + ((getReserves[i]._reserve1 / token1Decimals[i]) * + token1Price[token1Addresses[i].toLowerCase()])) / + (totalSupply[i] / 1e18); + } else if (isNaN(token1Price[token1Addresses[i].toLowerCase()])) { + token.lpPrice = + (2 * + ((getReserves[i]._reserve0 / token0Decimals[i]) * + token0Price[token1Addresses[i].toLowerCase()])) / + (totalSupply[i] / 1e18); + } else { + token.lpPrice = + ((getReserves[i]._reserve0 / token0Decimals[i]) * + token0Price[token0Addresses[i].toLowerCase()] + + (getReserves[i]._reserve1 / token1Decimals[i]) * + token1Price[token1Addresses[i].toLowerCase()]) / + (totalSupply[i] / 1e18); + } + console.log( + 'LP Price Info', + token.lpPrice, + token0Decimals[i], + token1Decimals[i], + totalSupply[i], + getReserves[i]._reserve0, + getReserves[i]._reserve1, + token0Addresses[i].toLowerCase(), + token1Addresses[i].toLowerCase(), + token0Price[token0Addresses[i].toLowerCase()], + token1Price[token1Addresses[i].toLowerCase()] + ); + }); + + const lpPrices = {}; + lpMarkets.map((lp) => { + lpPrices[lp.lpToken.toLowerCase()] = lp.lpPrice; + }); + + return lpPrices; +}; + +const getInfos = async () => { + const vaultInfo = await ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: Object.entries(vaults).map((vault) => ({ + target: vault[1], + params: ['0x0000000000000000000000000000000000000000'], + })), + abi: windAndCheck.find(({ name }) => name === 'getUserInfo'), + }) + ).output.map(({ output }) => output); + const vaultsLpInfo = await ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: Object.entries(vaultsLP).map((vault) => ({ + target: vault[1], + params: ['0x0000000000000000000000000000000000000000'], + })), + abi: compounders.find(({ name }) => name === 'getUserInfo'), + }) + ).output.map(({ output }) => output); + return [...vaultInfo, ...vaultsLpInfo]; +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price ?? 1, + }), + {} + ); + + return pricesByAddress; +}; +const convertAPR2APY = (apr) => { + return (apy = ((apr / (365 * 72) + 1) ** (365 * 72) - 1) * 100); +}; + +const calcApy = async () => { + const pricesTokens = await getPrices( + tokens + .filter((token) => !token.lp) + .map((token) => token.address) + .map((token) => `${CHAIN}:` + token) + ); + const lpPrices = await unwrapLP( + CHAIN, + tokens.filter((token) => token.lp === true).map((token) => token.address) + ); + const prices = { + ...pricesTokens, + ...lpPrices, + }; + + const infos = await getInfos(); + + const pools = tokens.map((token, i) => { + const symbol = token.name; + const tokenAddress = token.address; + const tokxens = token.tokens; + + const vaultAddress = + vaults[symbol]?.toLowerCase() ?? vaultsLP[symbol]?.toLowerCase(); + + const decimals = token.decimals; + let price = prices[tokenAddress.toLowerCase()]; + + const info = infos[i]; + console.log( + 'INFOS', + symbol, + token.lp ? info.userInfo.totalCollateral ?? 0 : info.totalSupplied ?? 0, + price + ); + const tvlUsd = + ((token.lp + ? info.userInfo.totalCollateral ?? 0 + : info.totalSupplied ?? 0) / + 10 ** decimals) * + price; + const apyBase = convertAPR2APY( + (token.lp ? info.userInfo.lastAPR ?? 0 : info.lastAPR ?? 0) / 1e6 + ); + + return { + pool: vaultAddress, + chain: CHAIN, + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + underlyingTokens: tokxens, + rewardTokens: [tokenAddress], + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: calcApy, + url: 'https://invest.scrub.money', +}; diff --git a/src/adaptors/sdai/bridgeinterestreceiver.js b/src/adaptors/sdai/bridgeinterestreceiver.js new file mode 100644 index 0000000000..159104362e --- /dev/null +++ b/src/adaptors/sdai/bridgeinterestreceiver.js @@ -0,0 +1,216 @@ +module.exports=[ + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Claimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "claim", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentEpochBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dripRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epochLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "lastClaimTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextClaimEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "previewClaimable", + "outputs": [ + { + "internalType": "uint256", + "name": "claimable", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newClaimer", + "type": "address" + } + ], + "name": "setClaimer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultAPY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wxdai", + "outputs": [ + { + "internalType": "contract IWXDAI", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] \ No newline at end of file diff --git a/src/adaptors/sdai/erc20.js b/src/adaptors/sdai/erc20.js new file mode 100644 index 0000000000..5365f21bc7 --- /dev/null +++ b/src/adaptors/sdai/erc20.js @@ -0,0 +1,222 @@ +module.exports= [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/src/adaptors/sdai/index.js b/src/adaptors/sdai/index.js new file mode 100644 index 0000000000..ad9f947c71 --- /dev/null +++ b/src/adaptors/sdai/index.js @@ -0,0 +1,53 @@ +const utils = require('../utils'); +const bridgeInterestReceiverABI = require('./bridgeinterestreceiver'); +const sdk = require('@defillama/sdk'); + +const chains = { + xdai: { + sDAI: '0xaf204776c7245bF4147c2612BF6e5972Ee483701', + wxDAI: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', + interestreceiver: '0x670daeaF0F1a5e336090504C68179670B5059088', + } +}; + +async function getApy() { + const vaultAPY = ( + await sdk.api.abi.call({ + chain: 'xdai', + abi: bridgeInterestReceiverABI.find((m) => m.name === 'vaultAPY'), + target: chains.xdai.interestreceiver, + }) + ).output; + return vaultAPY / 1e16; +} +async function getTVL() { + // wxDAI balance of sDAI vault + const tvl = ( + await sdk.api.abi.call({ + chain: 'xdai', + abi: 'erc20:balanceOf', + target: chains.xdai.wxDAI, + params: chains.xdai.sDAI, + }) + ).output; + // get wxDAI price + const wxDAIPrice = await utils.getPrices([chains.xdai.wxDAI], 'xdai'); + const tvlUSD = (tvl * wxDAIPrice.pricesBySymbol.wxdai) / 1e18; + return tvlUSD; +} +async function sDAIPool() { + const sDAIPoolData = { + pool: chains.xdai.sDAI, + chain: utils.formatChain('xdai'), + project: 'sdai', + symbol: 'sDAI', + apy: await getApy(), + tvlUsd: await getTVL(), + }; + return [sDAIPoolData]; +} +module.exports = { + timetravel: false, + apy: sDAIPool, + url: 'https://agave.finance/sdai/', +}; diff --git a/src/adaptors/seamless-v2/erc20-abi.json b/src/adaptors/seamless-v2/erc20-abi.json new file mode 100644 index 0000000000..668d6979f0 --- /dev/null +++ b/src/adaptors/seamless-v2/erc20-abi.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/src/adaptors/seamless-v2/index.js b/src/adaptors/seamless-v2/index.js new file mode 100644 index 0000000000..3528e58202 --- /dev/null +++ b/src/adaptors/seamless-v2/index.js @@ -0,0 +1,241 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const BigNumber = require('bignumber.js'); + +const utils = require('../utils'); +const lendingAdapterAbi = require('./lending-adapter-abi.json'); +const leverageManagerAbi = require('./leverage-manager-abi.json'); +const leverageTokenAbi = require('./leverage-token-abi.json'); +const erc20Abi = require('./erc20-abi.json'); + +const SECONDS_PER_DAY = 86400; +const SECONDS_PER_YEAR = 31536000; +const LEVERAGE_TOKEN_DECIMALS = 18; +const COMPOUNDING_PERIODS = 1; +const chains = ['ethereum', 'base']; + +const LEVERAGE_MANAGER_ADDRESS = { + ethereum: '0x5C37EB148D4a261ACD101e2B997A0F163Fb3E351', + base: '0x38Ba21C6Bf31dF1b1798FCEd07B4e9b07C5ec3a8' +}; + +const LEVERAGE_MANAGER_DEPLOYMENT_BLOCK = { + ethereum: 23471226, + base: 31051780 +}; + +const getLeverageTokens = async (chain, toBlock) => { + const iface = new ethers.utils.Interface([ + 'event LeverageTokenCreated(address indexed token, address collateralAsset, address debtAsset, (address lendingAdapter, address rebalanceAdapter, uint256 mintTokenFee, uint256 redeemTokenFee) config)', + ]); + const leverageTokenCreatedEvents = ( + await sdk.api2.util.getLogs({ + chain, + target: LEVERAGE_MANAGER_ADDRESS[chain], + topics: ["0xc3f4681fb2a57a13e121c6f24fe319c8572bb001497f2b74712695625ee9028e"], + fromBlock: LEVERAGE_MANAGER_DEPLOYMENT_BLOCK[chain], + keys: [], + toBlock, + }) + ); + + const leverageTokens = leverageTokenCreatedEvents.output.map((ev) => iface.parseLog(ev).args).map((ev) => { + return { + address: ev.token, + collateralAsset: ev.collateralAsset, + debtAsset: ev.debtAsset, + lendingAdapter: ev.config[0] + } + }); + + const collateralDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: erc20Abi.find(({ name }) => name === 'decimals'), + calls: leverageTokens.map(({ collateralAsset }) => ({ target: collateralAsset })), + permitFailure: true, + }) + ).output.map(({ output, success }) => success ? output : null); + + const debtDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: erc20Abi.find(({ name }) => name === 'decimals'), + calls: leverageTokens.map(({ debtAsset }) => ({ target: debtAsset })), + permitFailure: true, + }) + ).output.map(({ output, success }) => success ? output : null); + + const symbols = ( + await sdk.api.abi.multiCall({ + chain, + abi: leverageTokenAbi.find(({ name }) => name === 'symbol'), + calls: leverageTokens.map(({ address }) => ({ target: address })), + permitFailure: true, + }) + ).output.map(({ output, success }) => success ? output : null); + + return leverageTokens.map(({ address, collateralAsset, lendingAdapter }, i) => { + return { + address, + collateralAsset, + lendingAdapter, + collateralDecimals: collateralDecimals[i], + debtDecimals: debtDecimals[i], + symbol: symbols[i] + }; + }); +}; + +function formatUnitsToNumber(value, decimals) { + return Number(ethers.utils.formatUnits(value, decimals)); +} + +function calculateApy(endValue, startValue, timeWindow, compoundingPeriods, decimals) { + const endValueNumber = formatUnitsToNumber(endValue, decimals); + + const startValueNumber = formatUnitsToNumber(startValue, decimals); + + const timeWindowNumber = Number(timeWindow); + + const apr = + (endValueNumber / startValueNumber) ** + (SECONDS_PER_YEAR / timeWindowNumber) - + 1; + + return ((1 + apr / compoundingPeriods) ** compoundingPeriods - 1) * 100; +} + +const getLeverageTokenTvlsUsd = async (chain, leverageTokens) => { + const totalCollaterals = ( + await sdk.api.abi.multiCall({ + chain, + abi: lendingAdapterAbi.find(({ name }) => name === 'getCollateral'), + calls: leverageTokens.map(({ lendingAdapter }) => ({ target: lendingAdapter })), + permitFailure: true, + }) + ).output.map(({ output, success }) => success ? output : null); + + const { pricesByAddress } = await utils.getPrices( + leverageTokens.map(({ collateralAsset }) => collateralAsset), + chain + ); + + return totalCollaterals.map((totalCollateral, i) => { + const collateralAsset = leverageTokens[i].collateralAsset; + + return (totalCollateral !== null && leverageTokens[i].collateralDecimals !== null && pricesByAddress[collateralAsset.toLowerCase()] !== null) + ? BigNumber(totalCollateral).multipliedBy(BigNumber(pricesByAddress[collateralAsset.toLowerCase()])).dividedBy(BigNumber(10).pow(leverageTokens[i].collateralDecimals)).toNumber() + : null; + }); +} + +const getLtPricesInDebtAsset = async (chain, blockNumber, leverageTokens) => { + const equityInDebtAsset = ( + await sdk.api.abi.multiCall({ + chain, + abi: leverageManagerAbi.find(({ name }) => name === 'getLeverageTokenState'), + calls: leverageTokens.map(({ address }) => ({ target: LEVERAGE_MANAGER_ADDRESS[chain], params: [address] })), + block: blockNumber, + permitFailure: true + }) + ).output.map(({ output, success }) => success ? output.equity : null); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: leverageManagerAbi.find(({ name }) => name === 'getFeeAdjustedTotalSupply'), + calls: leverageTokens.map(({ address }) => ({ target: LEVERAGE_MANAGER_ADDRESS[chain], params: [address] })), + block: blockNumber, + permitFailure: true + }) + ).output.map(({ output }) => output); + + return equityInDebtAsset.map((equity, i) => + equity ? BigInt(equity) * BigInt(10 ** LEVERAGE_TOKEN_DECIMALS) / + BigInt(totalSupply[i]) : null + ); +}; + +const leverageTokenApys = async (chain) => { + const latestBlock = await sdk.api.util.getLatestBlock(chain); + const prevBlock1Day = await sdk.api.util.lookupBlock( + latestBlock.timestamp - SECONDS_PER_DAY, + { chain } + ); + const prevBlock7Day = await sdk.api.util.lookupBlock( + latestBlock.timestamp - 7 * SECONDS_PER_DAY, + { chain } + ); + + const allLeverageTokens = await getLeverageTokens(chain, latestBlock.number); + + const latestBlockPricesInDebtAsset = await getLtPricesInDebtAsset( + chain, + latestBlock.number, + allLeverageTokens + ); + + const prevBlock1DayPricesInDebtAsset = await getLtPricesInDebtAsset( + chain, + prevBlock1Day.number, + allLeverageTokens + ); + + const prevBlock7DayPricesInDebtAsset = await getLtPricesInDebtAsset( + chain, + prevBlock7Day.number, + allLeverageTokens + ); + + const leverageTokenTvlsUsd = await getLeverageTokenTvlsUsd( + chain, + allLeverageTokens + ); + + const pools = allLeverageTokens.map(({ address, collateralAsset, debtDecimals, symbol }, i) => { + const apyBase = calculateApy( + latestBlockPricesInDebtAsset[i], + prevBlock1DayPricesInDebtAsset[i], + latestBlock.timestamp - prevBlock1Day.timestamp, + COMPOUNDING_PERIODS, + debtDecimals + ); + + const apyBase7d = calculateApy( + latestBlockPricesInDebtAsset[i], + prevBlock7DayPricesInDebtAsset[i], + latestBlock.timestamp - prevBlock7Day.timestamp, + COMPOUNDING_PERIODS, + debtDecimals + ); + + const pool = { + pool: `${address}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'seamless-v2', + symbol, + tvlUsd: leverageTokenTvlsUsd[i], + apyBase, + apyBase7d, + underlyingTokens: [collateralAsset], + }; + + return pool; + }); + + return pools; +}; + +const apy = async () => { + const results = await Promise.all( + chains.map((chain) => leverageTokenApys(chain)) + ); + return results.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.seamlessprotocol.com', +}; diff --git a/src/adaptors/seamless-v2/lending-adapter-abi.json b/src/adaptors/seamless-v2/lending-adapter-abi.json new file mode 100644 index 0000000000..cd48f194ec --- /dev/null +++ b/src/adaptors/seamless-v2/lending-adapter-abi.json @@ -0,0 +1,448 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILeverageManager", + "name": "_leverageManager", + "type": "address" + }, + { + "internalType": "contract IMorpho", + "name": "_morpho", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "LendingAdapterAlreadyInUse", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "Id", + "name": "morphoMarketId", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "address", + "name": "loanToken", + "type": "address" + }, + { + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "irm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lltv", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct MarketParams", + "name": "marketParams", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "authorizedCreator", + "type": "address" + } + ], + "name": "MorphoLendingAdapterInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "MorphoLendingAdapterUsed", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "authorizedCreator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "name": "convertCollateralToDebtAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "name": "convertDebtToCollateralAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollateralAsset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollateralInDebtAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDebtAsset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEquityInCollateralAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEquityInDebtAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLiquidationPenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "_morphoMarketId", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_authorizedCreator", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isUsed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "leverageManager", + "outputs": [ + { + "internalType": "contract ILeverageManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "marketParams", + "outputs": [ + { + "internalType": "address", + "name": "loanToken", + "type": "address" + }, + { + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "irm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lltv", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "morpho", + "outputs": [ + { + "internalType": "contract IMorpho", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "morphoMarketId", + "outputs": [ + { + "internalType": "Id", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "postLeverageTokenCreation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "removeCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/seamless-v2/leverage-manager-abi.json b/src/adaptors/seamless-v2/leverage-manager-abi.json new file mode 100644 index 0000000000..679a151c57 --- /dev/null +++ b/src/adaptors/seamless-v2/leverage-manager-abi.json @@ -0,0 +1,2007 @@ +[ + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "FeeTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidCollateralRatios", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidLeverageTokenAssets", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "initialCollateralRatio", + "type": "uint256" + } + ], + "name": "InvalidLeverageTokenInitialCollateralRatio", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "InvalidLeverageTokenStateAfterRebalance", + "type": "error" + }, + { + "inputs": [], + "name": "LeverageTokenNotEligibleForRebalance", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "NotRebalancer", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actual", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "SlippageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressTreasury", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "DefaultManagementFeeAtCreationSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IBeaconProxyFactory", + "name": "leverageTokenFactory", + "type": "address" + } + ], + "name": "LeverageManagerInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "leverageToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "enum ExternalAction", + "name": "action", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "LeverageTokenActionFeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "debtAsset", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ILendingAdapter", + "name": "lendingAdapter", + "type": "address" + }, + { + "internalType": "contract IRebalanceAdapterBase", + "name": "rebalanceAdapter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintTokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokenFee", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LeverageTokenConfig", + "name": "config", + "type": "tuple" + } + ], + "name": "LeverageTokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "leverageToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sharesFee", + "type": "uint256" + } + ], + "name": "ManagementFeeCharged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "ManagementFeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralInDebtAsset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "equity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralRatio", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LeverageTokenState", + "name": "stateBefore", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateralInDebtAsset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "equity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralRatio", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct LeverageTokenState", + "name": "stateAfter", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum ActionType", + "name": "actionType", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct RebalanceAction[]", + "name": "actions", + "type": "tuple[]" + } + ], + "name": "Rebalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "enum ExternalAction", + "name": "action", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "TreasuryActionFeeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "name": "TreasurySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "chargeManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "enum Math.Rounding", + "name": "rounding", + "type": "uint8" + } + ], + "name": "convertCollateralToDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "enum Math.Rounding", + "name": "rounding", + "type": "uint8" + } + ], + "name": "convertCollateralToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "enum Math.Rounding", + "name": "rounding", + "type": "uint8" + } + ], + "name": "convertDebtToCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "enum Math.Rounding", + "name": "rounding", + "type": "uint8" + } + ], + "name": "convertSharesToCollateral", + "outputs": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "enum Math.Rounding", + "name": "rounding", + "type": "uint8" + } + ], + "name": "convertSharesToDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "equityInCollateralAsset", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "equityInCollateralAsset", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract ILendingAdapter", + "name": "lendingAdapter", + "type": "address" + }, + { + "internalType": "contract IRebalanceAdapterBase", + "name": "rebalanceAdapter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintTokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokenFee", + "type": "uint256" + } + ], + "internalType": "struct LeverageTokenConfig", + "name": "tokenConfig", + "type": "tuple" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "name": "createNewLeverageToken", + "outputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minShares", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getDefaultManagementFeeAtCreation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getFeeAdjustedTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLastManagementFeeAccrualTimestamp", + "outputs": [ + { + "internalType": "uint120", + "name": "", + "type": "uint120" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "enum ExternalAction", + "name": "action", + "type": "uint8" + } + ], + "name": "getLeverageTokenActionFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenCollateralAsset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "collateralAsset", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenConfig", + "outputs": [ + { + "components": [ + { + "internalType": "contract ILendingAdapter", + "name": "lendingAdapter", + "type": "address" + }, + { + "internalType": "contract IRebalanceAdapterBase", + "name": "rebalanceAdapter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintTokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokenFee", + "type": "uint256" + } + ], + "internalType": "struct LeverageTokenConfig", + "name": "config", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenDebtAsset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "debtAsset", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLeverageTokenFactory", + "outputs": [ + { + "internalType": "contract IBeaconProxyFactory", + "name": "factory", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenInitialCollateralRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenLendingAdapter", + "outputs": [ + { + "internalType": "contract ILendingAdapter", + "name": "adapter", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenRebalanceAdapter", + "outputs": [ + { + "internalType": "contract IRebalanceAdapterBase", + "name": "module", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getLeverageTokenState", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateralInDebtAsset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "equity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralRatio", + "type": "uint256" + } + ], + "internalType": "struct LeverageTokenState", + "name": "state", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + } + ], + "name": "getManagementFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTreasury", + "outputs": [ + { + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ExternalAction", + "name": "action", + "type": "uint8" + } + ], + "name": "getTreasuryActionFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "initialAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "treasury", + "type": "address" + }, + { + "internalType": "contract IBeaconProxyFactory", + "name": "leverageTokenFactory", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxCollateral", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "leverageToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "enum ActionType", + "name": "actionType", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct RebalanceAction[]", + "name": "actions", + "type": "tuple[]" + }, + { + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "rebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minCollateral", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setDefaultManagementFeeAtCreation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ExternalAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setTreasuryActionFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILeverageToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxShares", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "treasuryFee", + "type": "uint256" + } + ], + "internalType": "struct ActionData", + "name": "actionData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/seamless-v2/leverage-token-abi.json b/src/adaptors/seamless-v2/leverage-token-abi.json new file mode 100644 index 0000000000..49de45f527 --- /dev/null +++ b/src/adaptors/seamless-v2/leverage-token-abi.json @@ -0,0 +1,717 @@ +[ + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ERC2612ExpiredSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC2612InvalidSigner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentNonce", + "type": "uint256" + } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "name": "LeverageTokenInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_leverageManager", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/securo-finance/abiLci.json b/src/adaptors/securo-finance/abiLci.json new file mode 100644 index 0000000000..4f7cc9feb6 --- /dev/null +++ b/src/adaptors/securo-finance/abiLci.json @@ -0,0 +1,16 @@ +{ + "getAPR": { + "inputs": [], + "name": "getAPR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + "getAllPoolInUSD": { + "inputs": [], + "name": "getAllPoolInUSD", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/securo-finance/index.js b/src/adaptors/securo-finance/index.js new file mode 100644 index 0000000000..a5184a8d51 --- /dev/null +++ b/src/adaptors/securo-finance/index.js @@ -0,0 +1,105 @@ +const sdk = require('@defillama/sdk'); +const abiLci = require('./abiLci.json'); + +const config = { + bsc: { + vaults: { + LCIBsc: '0x8FD52c2156a0475e35E0FEf37Fa396611062c9b6', + }, + }, + aurora: { + vaults: { + BNIAurora: '0x72eB6E3f163E8CFD1Ebdd7B2f4ffB60b6e420448', + }, + }, + polygon: { + vaults: { + BNIPolygon: '0xF9258759bADb75a9eAb16933ADd056c9F4E489b6', + }, + }, + avax: { + vaults: { + MWIAvalanche: '0x5aCBd5b82edDae114EC0703c86d163bD0107367c', + BNIAvalanche: '0xe76367024ca3AEeC875A03BB395f54D7c6A82eb0', + }, + }, +}; + +const getApy = async () => { + const apys = await Promise.all( + Object.keys(config).map(async (chain) => { + const vaults = Object.values(config[chain].vaults); + const balances = ( + await sdk.api.abi.multiCall({ + abi: abiLci.getAPR, + calls: vaults.map((i) => ({ target: i })), + chain, + }) + ).output.map(({ output }) => ((1 + output / 1e18 / 52) ** 52 - 1) * 100); + return balances; + }) + ); + + const tvls = await Promise.all( + Object.keys(config).map(async (chain) => { + const vaults = Object.values(config[chain].vaults); + const balances = ( + await sdk.api.abi.multiCall({ + abi: abiLci.getAllPoolInUSD, + calls: vaults.map((i) => ({ target: i })), + chain, + }) + ).output.map(({ output }) => output / 1e18); + return balances; + }) + ); + + return [ + { + pool: config.bsc.vaults.LCIBsc, + chain: 'Binance', + project: 'securo-finance', + symbol: `USDT`, + tvlUsd: Number(tvls[0]), + apy: Number(apys[0]), + }, + { + pool: config.aurora.vaults.BNIAurora, + chain: 'Aurora', + project: 'securo-finance', + symbol: `USDT`, + tvlUsd: Number(tvls[1]), + apy: Number(apys[1]), + }, + { + pool: config.polygon.vaults.BNIPolygon, + chain: 'Polygon', + project: 'securo-finance', + symbol: `USDT`, + tvlUsd: Number(tvls[2]), + apy: Number(apys[2]), + }, + { + pool: config.avax.vaults.MWIAvalanche, + chain: 'Avalanche', + project: 'securo-finance', + symbol: `USDT`, + tvlUsd: Number(tvls[3][0]), + apy: Number(apys[3][0]), + }, + { + pool: config.avax.vaults.BNIAvalanche, + chain: 'Avalanche', + project: 'securo-finance', + symbol: `USDT`, + tvlUsd: Number(tvls[3][1]), + apy: Number(apys[3][1]), + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.securo.finance/', +}; diff --git a/src/adaptors/segment-finance/index.js b/src/adaptors/segment-finance/index.js new file mode 100644 index 0000000000..186bd2640e --- /dev/null +++ b/src/adaptors/segment-finance/index.js @@ -0,0 +1,220 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('../compound-v2/abi'); + +const COMPTROLLER_ADDRESS = '0xcD7C4F508652f33295F0aEd075936Cd95A4D2911'; +const CHAIN = 'bob'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 2; +const PROJECT_NAME = 'segment-finance'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const borrowCaps = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'borrowCaps'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + underlyingTokens: [token], + rewardTokens: [], + url: 'https://app.segment.finance/#//market/' + market, + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + debtCeilingUsd: (borrowCaps[i] / 1e18) * price, + }; + } + return poolReturned; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/sendit/index.js b/src/adaptors/sendit/index.js new file mode 100644 index 0000000000..fcc243d464 --- /dev/null +++ b/src/adaptors/sendit/index.js @@ -0,0 +1,198 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const API_BASE = 'https://backend.sendit.fun/api'; +const WSOL_MINT = 'So11111111111111111111111111111111111111112'; + +const fetchAllVerifiedMarketPools = async () => { + try { + const response = await axios.get(`${API_BASE}/accounts/verified-markets/pools`); + return response.data?.data?.pools || []; + } catch (error) { + return []; + } +}; + +const fetchSolVaults = async () => { + try { + const response = await axios.get(`${API_BASE}/sol-vaults`); + // Return the full response data to include solPrice + return response.data || { vaults: [], solPrice: null }; + } catch (error) { + return { vaults: [], solPrice: null }; + } +}; + +const fetchSingleSidedVaults = async () => { + try { + const response = await axios.get(`${API_BASE}/single-sided-vaults`); + const vaults = response.data?.vaults || []; + return Array.isArray(vaults) ? vaults : []; + } catch (error) { + return []; + } +}; + +const formatSolReservePool = (market, poolData) => { + const solReserve = poolData.solReserve; + const nonSolReserve = poolData.nonSolReserve; + const tokenSymbol = nonSolReserve?.metadata?.symbol || 'UNKNOWN'; + + // Use supplyInterest which is already in decimal format (e.g., 0.469 = 46.9%) + const supplyApr = Number(solReserve?.supplyInterest || 0) * 100; + + // Extract incentive APR from the object structure + let apyReward = 0; + if (poolData.incentiveApr && poolData.incentiveApr.currentAPR) { + apyReward = Number(poolData.incentiveApr.currentAPR) * 100; + } + + // Calculate TVL following DefiLlama's standard for lending protocols + const totalSupplyUsd = Number(solReserve?.totalSupplyUsd || 0); + const totalBorrowUsd = Number(solReserve?.totalBorrowUsd || 0); + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + // Get borrow APR if available + const borrowApr = Number(solReserve?.borrowInterest || 0) * 100; + + return { + pool: `${market.lendingMarketId}-solana`.toLowerCase(), + chain: utils.formatChain('solana'), + project: 'sendit', + symbol: 'SOL', + poolMeta: `SOL in ${tokenSymbol} market`, + tvlUsd: tvlUsd, + apyBase: supplyApr, + apyReward: apyReward > 0 ? apyReward : null, + rewardTokens: nonSolReserve?.mintAddress ? [nonSolReserve.mintAddress] : [], + underlyingTokens: [WSOL_MINT], + url: `https://sendit.fun/market/${market.lendingMarketId}`, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + apyBaseBorrow: borrowApr > 0 ? borrowApr : null + }; +}; + +const getVaultCategoryName = (vaultAddress) => { + const vaultNames = { + '7EyBhsXnLUWTj5wKWmeGDDDJXcWRXiUa2YuFbwCQrNH2': 'SOL Blue Chip Vault', + '5iNq4uB73mjkJKru7g9FSXk3biA2jnvP6McYn6bezazT': 'SOL Mid Cap Vault', + '6nVHK1wcg7hJVaLct7A5KJtjgi5XhSrgEFbQvoagtHbQ': 'SOL Small Cap Vault' + }; + + return vaultNames[vaultAddress] || 'SOL Vault'; +}; + +const formatSolVaultPool = (vault, solPrice) => { + // Calculate average APR from deployed positions + let avgApr = 0; + if (vault?.deployedPositions && vault.deployedPositions.length > 0) { + const totalValue = vault.deployedPositions.reduce((sum, pos) => sum + (pos.depositedValueSol || 0), 0); + avgApr = vault.deployedPositions.reduce((sum, pos) => + sum + ((pos.apr || 0) * (pos.depositedValueSol || 0) / totalValue), 0 + ); + } + + const tvlUsd = Number(vault?.totalValueLockedSol || 0) * solPrice; + const vaultName = getVaultCategoryName(vault?.vaultAddress); + + return { + pool: `${vault?.vaultAddress}-solana`.toLowerCase(), + chain: utils.formatChain('solana'), + project: 'sendit', + symbol: 'SOL', + poolMeta: vaultName, + tvlUsd: tvlUsd, + apyBase: avgApr * 100, // Convert to percentage + underlyingTokens: [WSOL_MINT], + url: 'https://sendit.fun/earn' + }; +}; + +const formatSingleSidedVaultPool = (vault) => { + const tokenSymbol = vault?.tokenSymbol || 'UNKNOWN'; + + return { + pool: `${vault?.vaultAddress}-solana`.toLowerCase(), + chain: utils.formatChain('solana'), + project: 'sendit', + symbol: tokenSymbol, + poolMeta: `${tokenSymbol} Vault`, + tvlUsd: Number(vault?.tvlBreakdown?.usd?.totalAssets || 0), + apyBase: vault?.apr ? Number(vault.apr) : 0, // apr is already in percentage + underlyingTokens: vault?.depositTokenMint ? [vault.depositTokenMint] : [], + url: 'https://sendit.fun/earn' + }; +}; + +const poolsFunction = async () => { + const pools = []; + + try { + const [verifiedMarketPools, solVaultsData, singleSidedVaults] = await Promise.all([ + fetchAllVerifiedMarketPools(), + fetchSolVaults(), + fetchSingleSidedVaults() + ]); + + // Extract SOL price and vaults from the response + const solPrice = solVaultsData?.solPrice || 195; // Fallback to 195 if no price + const solVaults = solVaultsData?.vaults || []; + + // Process verified market pools + verifiedMarketPools.forEach(poolData => { + if (poolData && poolData.solReserve) { + try { + const pool = formatSolReservePool( + { lendingMarketId: poolData.marketAddress }, + poolData + ); + if (pool) { + pools.push(pool); + } + } catch (err) { + // Silently skip pools that fail to format + } + } + }); + + solVaults.forEach(vault => { + try { + const pool = formatSolVaultPool(vault, solPrice); + if (pool) { + pools.push(pool); + } + } catch (err) { + // Silently skip vaults that fail to format + } + }); + + singleSidedVaults.forEach(vault => { + try { + const pool = formatSingleSidedVaultPool(vault); + if (pool) { + pools.push(pool); + } + } catch (err) { + // Silently skip vaults that fail to format + } + }); + } catch (error) { + // Return whatever pools we were able to collect + } + + const validPools = pools.filter(pool => + pool && + pool.project === 'sendit' && + typeof pool.tvlUsd === 'number' && + !isNaN(pool.tvlUsd) + ); + + return validPools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://sendit.fun' +}; diff --git a/src/adaptors/sense/index.js b/src/adaptors/sense/index.js new file mode 100644 index 0000000000..dd15406b44 --- /dev/null +++ b/src/adaptors/sense/index.js @@ -0,0 +1,283 @@ +const utils = require('../utils'); + +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const { format } = require('date-fns'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); + +const graphEndpoint = sdk.graph.modifyEndpoint('GiBzr9juc4hMmyj6KstUnoaacux4wB5jsdgCV38W3Zwt'); + +const query = gql` + { + pools { + series { + maturity + adapter + pt + underlying + underlyingName + targetName + target + decimals + issuance + adapterMeta { + number + } + } + targetBalance + pTBalance + underlyingVolume + initScale + ts + lpShareTotalSupply + impliedRate + address + } + } +`; + +const abi = { + scale: { + inputs: [], + name: 'scale', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +}; + +const ONE_DAY_SECONDS = 24 * 60 * 60; +const ONE_YEAR_DAYS = 365; +const SECONDS_PER_YEAR = ONE_DAY_SECONDS * ONE_YEAR_DAYS; + +const targetToTicker = (target) => { + if (target === 'wstETH') { + return 'stETH'; + } else { + return target; + } +}; + +const underlyingToTicker = (underlying) => { + if (underlying === 'WETH') { + return 'ETH'; + } else { + return underlying; + } +}; + +const toISODate = (timestamp) => + new Date(timestamp * 1000).toISOString().substr(0, 10); + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .map((address) => `ethereum:${address}`) + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateSpaceData = async (pool, targetPrices) => { + const ttm = + parseInt(pool.series.maturity) - Math.floor(new Date().getTime() / 1000); + + if (ttm <= 0) { + // If the pool is past maturity, it's essentially just wrapped Target w.o. rewards + return [ + pool.targetAPYBase.toString(), + new BigNumber(pool.targetBalance) + .plus(pool.pTBalance) + .times(targetPrices[pool.series.target]) + .toNumber(), + ]; + } + + let { output: scale } = await sdk.api.abi.call({ + target: pool.series.adapter, + abi: abi.scale, + chain: 'ethereum', + }); + scale = new BigNumber(scale).div('1e+18'); + + const rate = new BigNumber(pool.impliedRate).div(100); + const stretchedRate = new BigNumber( + rate.plus(1).toNumber() ** + new BigNumber(1) + .div(new BigNumber(pool.ts).times(SECONDS_PER_YEAR)) + .toNumber() + ).minus(1); + + const targetPerPT = new BigNumber(1) + .div( + stretchedRate.plus(1).toNumber() ** + new BigNumber(ttm).times(pool.ts).toNumber() + ) + .div(scale); + + const targetInUnderlying = new BigNumber(pool.targetBalance).times(scale); + const ptInUnderlying = new BigNumber(pool.pTBalance) + .times(targetPerPT) + .times(scale); + const total = ptInUnderlying.plus(targetInUnderlying); + const weightedPTApy = new BigNumber(pool.impliedRate).times( + ptInUnderlying.div(total) + ); + const weightedTargetApy = new BigNumber(pool.targetAPYBase).times( + targetInUnderlying.div(total) + ); + + const timeSinceInit = + Math.floor(new Date().getTime() / 1000) - parseInt(pool.series.issuance); + + // Extrapolate the volume we've seen since issuance out into a yearly value (note that this is a very rough estimate). + const estVolumePerYear = new BigNumber(pool.underlyingVolume) + .div(timeSinceInit / ONE_DAY_SECONDS) + .times(ONE_YEAR_DAYS); + // Space fees are taken as a percent of yield, so use the current PT implied rate as the base yield from which to take. + // Then, determine the percent of the current pool our estimated yearly volume is (even if the pool won't be around for a year, + // since we're calculating apy) and use that to weight the avg additional underlying we collect per underlying traded. + const estYieldFromFees = new BigNumber(pool.impliedRate) + .div(100) + .times(0.05) + .times(estVolumePerYear.div(total)); + + const targetTvl = new BigNumber(pool.targetBalance).times( + targetPrices[pool.series.target] + ); + const ptTvl = BigNumber(pool.pTBalance) + .times(targetPerPT) + .times(targetPrices[pool.series.target]); + + return [ + // Take the apy as the weighted sum of the Target and PT APYs, plus the estimated yield from fees. + weightedPTApy.plus(weightedTargetApy).plus(estYieldFromFees).toString(), + targetTvl.plus(ptTvl).toNumber(), + ]; +}; + +const main = async () => { + let { pools } = await request(graphEndpoint, query); + + const yields = (await superagent.get('https://yields.llama.fi/pools')).body + .data; + + pools = pools.map((pool) => { + const y = yields + .filter((y) => y.symbol === targetToTicker(pool.series.targetName)) + .reduce( + (acc, cur) => + acc === null ? cur : cur.tvlUsd > acc.tvlUsd ? cur : acc, + null + ); + + if (y == null) return pool; + + return { targetAPYBase: y.apyBase, targetAPY: y.apy, ...pool }; + }); + + const targetTokens = [...new Set(pools.map((pool) => pool.series.target))]; + const targetPrices = await getPrices(targetTokens); + + const ptAdapterMap = {}; + for (const { series } of pools) { + const { pt, adapter } = series; + ptAdapterMap[pt] = adapter; + } + + const adapterDecimalsMap = {}; + for (const { series } of pools) { + const { decimals, adapter } = series; + adapterDecimalsMap[adapter] = decimals; // Decimals are constant for all Series of a particular adapter + } + + const ptTotalSupplys = new Map( + await Promise.all( + Object.entries(ptAdapterMap).map(async ([ptToken, adapterAddress]) => [ + ptToken, + new BigNumber( + ( + await sdk.api.erc20.totalSupply({ + target: ptToken, + chain: 'ethereum', + }) + ).output + ) + .div(10 ** parseInt(adapterDecimalsMap[adapterAddress])) + .toString(), + ]) + ) + ); + + // SENSE PTS + const pts = pools.map((pool) => ({ + pool: pool.series.pt, + chain: 'Ethereum', + project: 'sense', + symbol: `PT-${underlyingToTicker(pool.series.underlyingName)} ${ + pool.series.targetName + }-${pool.series.adapterMeta.number}`, + tvlUsd: new BigNumber(ptTotalSupplys.get(pool.series.pt)) + .times(targetPrices[pool.series.target]) + .toNumber(), + apyBase: parseFloat(pool.impliedRate), + apyReward: 0, + rewardTokens: [], + underlyingTokens: [pool.series.underlying], + poolMeta: `Maturing ${toISODate(pool.series.maturity)}`, + })); + + pools = await Promise.all( + pools + .filter((pool) => !!pool.targetAPYBase) + .map(async (pool) => { + const [apyBase, tvlUsd] = await calculateSpaceData(pool, targetPrices); + return { + apyBase, + tvlUsd, + ...pool, + }; + }) + ); + + // SENSE SPACE POOLS + const spacePools = pools.map((pool) => ({ + pool: pool.address, + chain: 'Ethereum', + project: 'sense', + symbol: `SPACE-${pool.series.targetName}`, + tvlUsd: pool.tvlUsd, + apyBase: parseFloat(pool.apyBase), + apyReward: 0, + rewardTokens: [], + underlyingTokens: [pool.series.pt, pool.series.target], + poolMeta: `Maturing ${toISODate(pool.series.maturity)}`, + })); + + return [...pts, ...spacePools].filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.sense.finance', +}; diff --git a/src/adaptors/sensi/index.js b/src/adaptors/sensi/index.js new file mode 100644 index 0000000000..fe4302ba6a --- /dev/null +++ b/src/adaptors/sensi/index.js @@ -0,0 +1,28 @@ +const { symbol } = require('../impermax-v2/abi'); +const { REWARD_TOKEN } = require('../line-token-rewards/config'); +const utils = require('../utils') + +const SY_pool = async() => { + + console.log("running") + const TVL = Number(await utils.getData('https://api.llama.fi/tvl/sensi')) + const APY = await utils.getData("https://sensi-autotask-rebalance.sensible-finance.workers.dev/syAPR") + + const SY_pool_metrics = { + pool: '0x21B656d3818A1dD07B800c1FE728fB81921af3A3', + chain: utils.formatChain('bsc'), + project: 'sensi', + symbol: 'BNB', + tvlUsd: TVL, + apy: APY, + poolMeta: "Automated Farm", + } + + return [SY_pool_metrics] +} + +module.exports = { + timetravel: false, + apy: SY_pool, + url: "https://app.sensi.fi/", +} diff --git a/src/adaptors/sentiment/abi.json b/src/adaptors/sentiment/abi.json new file mode 100644 index 0000000000..79dfa645c8 --- /dev/null +++ b/src/adaptors/sentiment/abi.json @@ -0,0 +1,119 @@ +[ + { + "inputs": [ + { + "internalType": "contract Registry", + "name": "_registry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "contract LToken", + "name": "lToken", + "type": "address" + } + ], + "name": "getLToken", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "lToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shareValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "internalType": "struct ILTokenDataProvider.LTokenObject", + "name": "lTokenObject", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLTokens", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "lToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shareValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "internalType": "struct ILTokenDataProvider.LTokenObject[]", + "name": "lTokens", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/sentiment/index.js b/src/adaptors/sentiment/index.js new file mode 100644 index 0000000000..6239041345 --- /dev/null +++ b/src/adaptors/sentiment/index.js @@ -0,0 +1,135 @@ +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const marketDataABI = require('./abi'); + +const marketConfig = { + '0x4c8e1656E042A206EEf7e8fcff99BaC667E4623e': { + name: 'LUSDT', + symbol: 'USDT', + decimals: 6, + underlyingAddress: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + }, + '0x0dDB1eA478F8eF0E22C7706D2903a41E94B1299B': { + name: 'LUSDC', + symbol: 'USDC', + decimals: 6, + underlyingAddress: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + }, + '0xb190214D5EbAc7755899F2D96E519aa7a5776bEC': { + name: 'LETH', + symbol: 'ETH', + decimals: 18, + underlyingAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + '0x2E9963ae673A885b6bfeDa2f80132CE28b784C40': { + name: 'LFrax', + symbol: 'FRAX', + decimals: 18, + underlyingAddress: '0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F', + }, + '0x21202227Bc15276E40d53889Bc83E59c3CccC121': { + name: 'LARB', + symbol: 'ARB', + decimals: 18, + underlyingAddress: '0x912CE59144191C1204E64559FE8253a0e49E6548', + }, + '0xe520C46d5Dab5bB80aF7Dc8b821f47deB4607DB2': { + name: 'LWBTC', + symbol: 'WBTC', + decimals: 8, + underlyingAddress: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', + }, + '0x37E6a0EcB9e8E5D90104590049a0A197E1363b67': { + name: 'LOHM', + symbol: 'OHM', + decimals: 9, + underlyingAddress: '0x6E6a3D8F1AfFAc703B1aEF1F43B8D2321bE40043', + }, +}; + +function getSupplyAndBorrowRate(liquidity, borrows, borrowRatePerBlock) { + const utilization = BigNumber(borrows).isZero() + ? BigNumber(0) + : BigNumber(borrows).times(10000).div(BigNumber(liquidity).plus(borrows)); + + const borrowAPR = BigNumber(borrowRatePerBlock).times(31556952); + const supplyAPR = utilization.times(borrowAPR).div(10000); + return [supplyAPR, borrowAPR]; +} + +async function getMarketsState() { + const marketsOnChainState = ( + await sdk.api.abi.call({ + target: '0x711cc1578bc995bc0e27292cb1a340835d277c18', + abi: marketDataABI.find((m) => m.name === 'getLTokens'), + chain: 'arbitrum', + }) + ).output; + + const marketsState = []; + + marketsOnChainState.forEach((state) => { + const [supplyAPR, borrowAPR] = getSupplyAndBorrowRate( + state.liquidity, + state.borrows, + state.borrowRate + ); + marketsState.push({ + liquidity: state.liquidity, + borrows: state.borrows, + supplyAPY: supplyAPR.div(10 ** 16), + borrowAPY: borrowAPR.div(10 ** 16), + market: state.lToken, + }); + }); + + return marketsState; +} + +const apy = async () => { + const apyData = await getMarketsState(); + const pools = []; + const prices = ( + await utils.getPrices( + Object.values(marketConfig).map((value) => value['underlyingAddress']), + 'arbitrum' + ) + ).pricesByAddress; + + apyData.forEach((market) => { + const config = marketConfig[market['market']]; + const decimals = BigNumber(10 ** config.decimals); + const tvl = BigNumber(market['liquidity']) + .div(decimals) + .times(BigNumber(prices[config.underlyingAddress.toLowerCase()])); + pools.push({ + pool: `${market['market']}-arbitrum`.toLowerCase(), + chain: utils.formatChain('arbitrum'), + project: 'sentiment', + symbol: utils.formatSymbol(config['symbol']), + tvlUsd: tvl.toNumber(), + apyBase: parseFloat(market['supplyAPY']), + underlyingTokens: [config.underlyingAddress], + apyBaseBorrow: parseFloat(market['borrowAPY']), + totalSupplyUsd: BigNumber(market['liquidity']) + .div(decimals) + .plus(BigNumber(market['borrows']).div(decimals)) + .times(BigNumber(prices[config.underlyingAddress.toLowerCase()])) + .toNumber(), + totalBorrowUsd: BigNumber(market['borrows']) + .div(decimals) + .times(BigNumber(prices[config.underlyingAddress.toLowerCase()])) + .toNumber(), + ltv: 1, + }); + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://arbitrum.sentiment.xyz/lending', +}; diff --git a/src/adaptors/sft-protocol/index.js b/src/adaptors/sft-protocol/index.js new file mode 100644 index 0000000000..6313be1c2f --- /dev/null +++ b/src/adaptors/sft-protocol/index.js @@ -0,0 +1,48 @@ +const utils = require('../utils'); + +const stakingPool = "0xE86D3dBd8233F1BFA22679cB57FaB3428E9654f7"; +const sdkChain = 'filecoin' + +async function getTotalLockedFIL() { + const result = await utils.getData('https://ww8.sftproject.io/api/c/api/v1/public/dashboard/info'); + let totalLocked = 0; + if (result.data.combined !== null) { + for (let node of result.data.combined) { + totalLocked += node.AccountAsset; + } + } + if (result.data.independent !== null) { + for (let node of result.data.independent) { + totalLocked += node.AccountAsset; + } + } + return totalLocked; +} + + +const getApy = async () => { + + const apyInfo = await utils.getData('https://ww8.sftproject.io/api/c/api/v1/public/farm/apy?token=AIzaSyC_5Tj4ir8peMmxP6KPPiayXLcpL9kIwqc'); + const apy = apyInfo.data; + + const totalLockedFIL = await getTotalLockedFIL(); + const filecoinPrice = (await utils.getData('https://coins.llama.fi/prices/current/coingecko:filecoin'))['coins']['coingecko:filecoin']['price']; + + const tvlUsd = totalLockedFIL * filecoinPrice; + + return [{ + pool: `${stakingPool}-${sdkChain}`.toLowerCase(), + symbol: 'SFT', + project: 'sft-protocol', + chain: sdkChain, + tvlUsd, + apy, + poolMeta: '6 month lock' + }] +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.sftproject.io/#/mint', +}; \ No newline at end of file diff --git a/src/adaptors/shadow-exchange-clmm/index.js b/src/adaptors/shadow-exchange-clmm/index.js new file mode 100644 index 0000000000..1b72ed581e --- /dev/null +++ b/src/adaptors/shadow-exchange-clmm/index.js @@ -0,0 +1,150 @@ +const axios = require('axios'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const SHADOW = '0x3333b97138D4b086720b5aE8A7844b1345a33333'; +const PROJECT = 'shadow-exchange-clmm'; +const CHAIN = 'sonic'; +const SUBGRAPH = 'https://shadow.kingdomsubgraph.com/subgraphs/name/core-pruned'; + +const poolsQuery = gql` + query getPools($first: Int!, $skip: Int!) { + clPools( + first: $first + skip: $skip + orderBy: totalValueLockedUSD + orderDirection: desc + where: { gauge_not: null } + ) { + id + token0 { + id + symbol + } + token1 { + id + symbol + } + feeTier + tickSpacing + totalValueLockedUSD + gauge { + id + } + poolDayData(first: 7, orderBy: startOfDay, orderDirection: desc) { + volumeUSD + } + } + } +`; + +async function fetchAllPools() { + let allPools = []; + let skip = 0; + const first = 1000; + + while (true) { + const poolsData = await request(SUBGRAPH, poolsQuery, { first, skip }); + const pools = poolsData.clPools; + + if (pools.length === 0) break; + + allPools = allPools.concat(pools); + + if (pools.length < first) break; + + skip += first; + } + + return allPools; +} + +async function apy() { + try { + const pools = await fetchAllPools(); + + let shadowPools = []; + try { + const shadowApiData = await axios.get('https://shadow-api-v2-production.up.railway.app/mixed-pairs?includeTokens=False'); + if (shadowApiData.data && Array.isArray(shadowApiData.data.pairs)) { + shadowPools = shadowApiData.data.pairs; + } + } catch (error) { + console.error('Failed to fetch Shadow API data:', error.message); + } + + const aprMap = {}; + for (const pool of shadowPools) { + if (pool.id) { + aprMap[pool.id.toLowerCase()] = { + lpApr: Number(pool.lpApr) || 0 + }; + } + } + + const results = []; + + for (const pool of pools) { + const tvlUsd = Number(pool.totalValueLockedUSD) || 0; + + if (!pool.gauge?.id) continue; + + const poolAddress = pool.id.toLowerCase(); + const apiData = aprMap[poolAddress]; + + if (!apiData) continue; + + const apyBase = 0; + let apyReward = 0; + const tickSpacing = parseInt(pool.tickSpacing); + + const apiPool = shadowPools.find(p => p.id.toLowerCase() === poolAddress); + if (apiPool && apiPool.recommendedRangesNew) { + if (tickSpacing === 1 || tickSpacing === 5) { + const wideRange = apiPool.recommendedRangesNew.find(range => range.name === 'Wide'); + apyReward = wideRange ? wideRange.lpApr : apiData.lpApr || 0; + } else { + const narrowRange = apiPool.recommendedRangesNew.find(range => range.name === 'Narrow'); + apyReward = narrowRange ? narrowRange.lpApr : apiData.lpApr || 0; + } + } else { + apyReward = apiData.lpApr || 0; + } + + results.push({ + pool: `${poolAddress}-${utils.formatChain(CHAIN)}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT, + poolMeta: `CL ${(Number(pool.feeTier) / 10000).toFixed(2)}%`, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd, + apyBase, + apyBase7d: 0, + apyReward, + rewardTokens: apyReward > 0 ? [SHADOW] : [], + underlyingTokens: [ + pool.token0.id.toLowerCase(), + pool.token1.id.toLowerCase() + ], + url: `https://www.shadow.so/liquidity/${poolAddress}`, + volumeUsd1d: pool.poolDayData?.[0]?.volumeUSD + ? Number(pool.poolDayData[0].volumeUSD) + : 0, + volumeUsd7d: pool.poolDayData + ? pool.poolDayData.reduce((sum, day) => sum + Number(day.volumeUSD || 0), 0) + : 0, + }); + } + + return results.filter((p) => utils.keepFinite(p)); + + } catch (error) { + console.error('Error fetching Shadow CL data:', error); + return []; + } +} + +module.exports = { + timetravel: false, + apy: apy, +}; \ No newline at end of file diff --git a/src/adaptors/sharpe-magnum/ABI.js b/src/adaptors/sharpe-magnum/ABI.js new file mode 100644 index 0000000000..9e1990026a --- /dev/null +++ b/src/adaptors/sharpe-magnum/ABI.js @@ -0,0 +1,1035 @@ +abi = [ + { + "inputs": [], + "name": "DEFAULT_LIQUIDATION_CLOSE_FACTOR", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "HEALTH_FACTOR_LIQUIDATION_THRESHOLD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "addressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolTokenBorrowedAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolTokenCollateralAddress", + "type": "address" + } + ], + "name": "computeLiquidationRepayAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "toRepay", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getAdvancedMarketData", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pSupplyIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "lastUpdateTimestamp", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "p2pSupplyDelta", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pBorrowDelta", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "marketsCreated_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getAverageBorrowRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getAverageSupplyRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCurrentBorrowBalanceInOf", + "outputs": [ + { + "internalType": "uint256", + "name": "balanceInP2P", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOnPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getCurrentP2PBorrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getCurrentP2PSupplyIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCurrentSupplyBalanceInOf", + "outputs": [ + { + "internalType": "uint256", + "name": "balanceInP2P", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOnPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCurrentUserBorrowRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCurrentUserSupplyRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getEnteredMarkets", + "outputs": [ + { + "internalType": "address[]", + "name": "enteredMarkets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getIndexes", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pSupplyIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowIndex", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getMainMarketData", + "outputs": [ + { + "internalType": "uint256", + "name": "avgSupplyRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "avgBorrowRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getMarketConfiguration", + "outputs": [ + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "bool", + "name": "isCreated", + "type": "bool" + }, + { + "internalType": "bool", + "name": "p2pDisabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPartiallyPaused", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "reserveFactor", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "p2pIndexCursor", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "getNextUserBorrowRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "nextBorrowRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceInP2P", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOnPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "getNextUserSupplyRatePerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "nextSupplyRatePerYear", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceInP2P", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOnPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getRatesPerYear", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pSupplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "p2pBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getTotalMarketBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolBorrowAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getTotalMarketSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "p2pSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupplyAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupplyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getUserBalanceStates", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "internalType": "struct Types.LiquidityData", + "name": "assetData", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getUserHealthFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_withdrawnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowedAmount", + "type": "uint256" + } + ], + "name": "getUserHypotheticalBalanceStates", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "internalType": "struct Types.LiquidityData", + "name": "assetData", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_withdrawnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_borrowedAmount", + "type": "uint256" + } + ], + "name": "getUserHypotheticalHealthFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "healthFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + }, + { + "internalType": "contract IPriceOracleGetter", + "name": "_oracle", + "type": "address" + } + ], + "name": "getUserLiquidityDataForAsset", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenUnit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ltv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "debt", + "type": "uint256" + } + ], + "internalType": "struct Types.AssetLiquidityData", + "name": "assetData", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "getUserMaxCapacitiesForAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "withdrawable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowable", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "isLiquidatable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "isMarketCreated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "isMarketCreatedAndNotPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolToken", + "type": "address" + } + ], + "name": "isMarketCreatedAndNotPausedNorPartiallyPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "morpho", + "outputs": [ + { + "internalType": "contract IMorpho", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract ILendingPool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] + +module.exports = {abi} \ No newline at end of file diff --git a/src/adaptors/sharpe-magnum/index.js b/src/adaptors/sharpe-magnum/index.js new file mode 100644 index 0000000000..afe78377e3 --- /dev/null +++ b/src/adaptors/sharpe-magnum/index.js @@ -0,0 +1,106 @@ +const utils = require('../utils'); +const axios = require('axios'); +const ethers = require('ethers'); +const {abi} = require("./ABI") +const {vaultAbi} = require("./vaultAbi") +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); + +async function fetchSmaApr() { + const url = 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma'; + const response = await axios.get(url); + return response.data.data.smaApr; +} + +async function getCurrentUserBorrowRate(vaultAddress) { + + const poolToken = '0x030bA81f1c18d280636F32af80b9AAd02Cf0854e'; + + const rate = ( + await sdk.api.abi.call({ + target: "0x507fA343d0A90786d86C7cd885f5C49263A91FF4", + chain: "ethereum", + abi: abi.find((m) => m.name === 'getCurrentUserBorrowRatePerYear'), + params : [ poolToken, vaultAddress] + }) + ).output; + + return ethers.BigNumber.from(rate); +} + +async function apy(vaultAddress) { + + const bRate = await getCurrentUserBorrowRate(vaultAddress); + //borrow rate is in ray (1E27) + let brate = bRate.div(ethers.BigNumber.from(10).pow(17)); + let newBrate = parseFloat(brate.toString()) * 0.00000001; + const sRate = await fetchSmaApr(); + + const leverage = ( + await sdk.api.abi.call({ + target: vaultAddress, + chain: "ethereum", + abi: vaultAbi.find((m) => m.name === 'vaultsLeverage') + }) + ).output; + + // if vault working on 3x leverage + if(leverage == 2){ + return (3.00 * sRate) - (2.00 * parseFloat(newBrate.toString())); + } + // if vault working on 2x leverage + else if(leverage == 1){ + return (2.00 * sRate) - ( parseFloat(newBrate.toString())); + } + // if vault working on 1x leverage + else{ + return sRate + } + +} + +async function getTVLInUSD(vaultAddress) { + const tvl = ( + await sdk.api.abi.call({ + target: vaultAddress, + chain: "ethereum", + abi: vaultAbi.find((m) => m.name === 'getVaultsActualBalance') + }) + ).output; + + const address = "ethereum:0x0000000000000000000000000000000000000000"; + const response = await fetch(`https://coins.llama.fi/prices/current/${address}`); + const data = await response.json(); + const ethData = data.coins[address]; + if (!ethData) { + throw new Error(`ETH data not found for address ${address}`); + } + const ethPrice = ethData.price; + + const tvlUSD = ethers.utils.formatEther(tvl) * ethPrice; + + return tvlUSD; +} + +const getApy = async () => { + const vaultAddress = "0xfc85db895e070017ab9c84cb65b911d56b729ee9"; + const apyVal = await apy(vaultAddress) + const tvlUSD = await getTVLInUSD(vaultAddress); + + const Eth = { + pool: '0xfc85db895e070017ab9c84cb65b911d56b729ee9-ethereum', + chain: utils.formatChain('Ethereum'), + project: 'sharpe-magnum', + symbol: utils.formatSymbol('ETH'), + tvlUsd : tvlUSD, + apy: apyVal, + }; + + return [Eth]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://dapp.sharpe.ai/vaults/1/StEth', +}; \ No newline at end of file diff --git a/src/adaptors/sharpe-magnum/vaultAbi.js b/src/adaptors/sharpe-magnum/vaultAbi.js new file mode 100644 index 0000000000..30b67d02ce --- /dev/null +++ b/src/adaptors/sharpe-magnum/vaultAbi.js @@ -0,0 +1,30 @@ +vaultAbi = [ + { + "inputs": [], + "name": "vaultsLeverage", + "outputs": [ + { + "internalType": "enum MagEth.Leverage", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVaultsActualBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] + +module.exports = {vaultAbi} \ No newline at end of file diff --git a/src/adaptors/sherlock/index.js b/src/adaptors/sherlock/index.js index 2bf913cf61..1d07d22ce6 100644 --- a/src/adaptors/sherlock/index.js +++ b/src/adaptors/sherlock/index.js @@ -1,5 +1,5 @@ const utils = require('../utils'); -const Web3 = require('web3'); +const sdk = require('@defillama/sdk'); const sherlockV2ABI = require('./sherlockV2abi.json'); @@ -8,27 +8,25 @@ const SherlockV2Contract = '0x0865a889183039689034dA55c1Fd12aF5083eabF'; const apy = async () => { // Fetch APY const apyData = await utils.getData( - 'https://mainnet.indexer.sherlock.xyz/staking' + 'https://mainnet-indexer.sherlock.xyz/staking' ); - const web3 = new Web3(process.env.INFURA_CONNECTION); - - // Fetch V2 pool TVL - const sherlockContract = new web3.eth.Contract( - sherlockV2ABI.abi, - SherlockV2Contract - ); - const v2TVL = web3.utils.toBN( - await sherlockContract.methods.totalTokenBalanceStakers().call() - ); + const v2TVL = ( + await sdk.api.abi.call({ + target: SherlockV2Contract, + abi: sherlockV2ABI.abi.find((m) => m.name === 'totalTokenBalanceStakers'), + chain: 'ethereum', + }) + ).output; const usdcPool = { pool: 'sherlock-v2-usdc', chain: utils.formatChain('ethereum'), project: 'sherlock', symbol: utils.formatSymbol('USDC'), - tvlUsd: v2TVL.toNumber() / 1e6, + tvlUsd: v2TVL / 1e6, apy: apyData.usdc_apy, + underlyingTokens: ['0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'], }; return [usdcPool]; @@ -37,4 +35,5 @@ const apy = async () => { module.exports = { timetravel: false, apy, + url: 'https://app.sherlock.xyz/stake', }; diff --git a/src/adaptors/shmonad/index.js b/src/adaptors/shmonad/index.js new file mode 100644 index 0000000000..9ae8df47dc --- /dev/null +++ b/src/adaptors/shmonad/index.js @@ -0,0 +1,194 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +// Time constants +const SECONDS_PER_DAY = 86400; +const DAYS_PER_YEAR = 365; + +// Contract address +const SHMONAD_CONTRACT = '0x1B68626dCa36c7fE922fD2d55E4f631d962dE19c'; + +// ABI for contract functions +const SHMONAD_ABI = { + getAtomicCapital: 'function getAtomicCapital() view returns (uint256 allocated, uint256 distributed)', + getCurrentAssets: 'function getCurrentAssets() view returns (uint256)', + getWorkingCapital: 'function getWorkingCapital() view returns (uint256 staked, uint256 reserved)', + totalAssets: 'function totalAssets() external view returns (uint256)', + totalSupply: 'erc20:totalSupply', + symbol: 'erc20:symbol', +}; + +const apy = async () => { + // Get current timestamp + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - SECONDS_PER_DAY; + + // Fetch block numbers for current and 1 day ago + const [blockNow, block1dayAgo] = await Promise.all([ + axios + .get(`https://coins.llama.fi/block/monad/${now}`) + .then((r) => r.data.height), + axios + .get(`https://coins.llama.fi/block/monad/${timestamp1dayAgo}`) + .then((r) => r.data.height), + ]); + + if (!blockNow || !block1dayAgo) { + throw new Error('RPC issue: Failed to fetch block numbers'); + } + + // Fetch current totalAssets, totalSupply, and symbol + const [totalAssetsNow, totalSupplyNow, symbol] = await Promise.all([ + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.totalAssets, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.totalSupply, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.symbol, + chain: 'monad', + }), + ]); + + // Fetch 1 day ago totalAssets and totalSupply + const [totalAssets1dayAgo, totalSupply1dayAgo] = await Promise.all([ + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.totalAssets, + chain: 'monad', + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.totalSupply, + chain: 'monad', + block: block1dayAgo, + }), + ]); + + if ( + !totalAssetsNow.output || + !totalSupplyNow.output || + !totalAssets1dayAgo.output || + !totalSupply1dayAgo.output + ) { + throw new Error('RPC issue: Failed to fetch contract data'); + } + + // Calculate share values (multiply by 1e18 to handle decimals) + const shareValueNow = + (BigInt(totalAssetsNow.output) * BigInt(1e18)) / + BigInt(totalSupplyNow.output); + const shareValue1dayAgo = + (BigInt(totalAssets1dayAgo.output) * BigInt(1e18)) / + BigInt(totalSupply1dayAgo.output); + + if (shareValue1dayAgo === 0n) { + throw new Error('RPC issue: Previous share value is zero'); + } + + // Calculate proportion: shareValueNow / shareValue1dayAgo + // Multiply by 1e18 to maintain precision + const proportion = + Number((shareValueNow * BigInt(1e18)) / shareValue1dayAgo) / 1e18; + + if (proportion <= 0) { + throw new Error('RPC issue: Invalid proportion calculated'); + } + + // Calculate APY using the formula: + // APY = ((1 + ((proportion - 1) / 365)) ** 365 - 1) * 100 + // This is equivalent to: APY = (proportion ** 365 - 1) * 100 + const apyBase = (Math.pow(proportion, DAYS_PER_YEAR) - 1) * 100; + + // Calculate TVL using the same methodology as the TVL adaptor + // TVL = staked + reserved + allocated - distributed + currentAssets + const [atomicCapital, currentAssetsValue, workingCapital] = await Promise.all([ + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.getAtomicCapital, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.getCurrentAssets, + chain: 'monad', + block: blockNow, + }), + sdk.api.abi.call({ + target: SHMONAD_CONTRACT, + abi: SHMONAD_ABI.getWorkingCapital, + chain: 'monad', + block: blockNow, + }), + ]); + + if ( + !atomicCapital.output || + !currentAssetsValue.output || + !workingCapital.output + ) { + throw new Error('RPC issue: Failed to fetch TVL data'); + } + + // Extract values from the results + // getAtomicCapital returns a tuple: {allocated, distributed} or [allocated, distributed] + const allocated = atomicCapital.output.allocated || atomicCapital.output[0]; + const distributed = atomicCapital.output.distributed || atomicCapital.output[1]; + + // getWorkingCapital returns a tuple: {staked, reserved} or [staked, reserved] + const staked = workingCapital.output.staked || workingCapital.output[0]; + const reserved = workingCapital.output.reserved || workingCapital.output[1]; + + // Calculate TVL: staked + reserved + allocated - distributed + currentAssets + const tvlBigInt = + BigInt(staked) + + BigInt(reserved) + + BigInt(allocated) - + BigInt(distributed) + + BigInt(currentAssetsValue.output); + + // Convert to number (assuming 18 decimals for MON) + const tvlMon = Number(tvlBigInt) / 1e18; + + // Get MON native token price to convert to USD + let tvlUsd; + try { + const monPriceResponse = await axios.get( + 'https://coins.llama.fi/prices/current/coingecko:monad' + ); + const monPrice = + monPriceResponse.data.coins['coingecko:monad']?.price || 1; + tvlUsd = tvlMon * monPrice; + } catch (error) { + // If price lookup fails, use TVL in MON as-is (assuming 1:1 with USD) + tvlUsd = tvlMon; + } + + return [ + { + pool: SHMONAD_CONTRACT.toLowerCase(), + chain: 'monad', + project: 'shmonad', + symbol: 'shMON', + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], // MON + }, + ]; +}; + +module.exports = { + apy, + url: 'https://shmonad.xyz', +}; + diff --git a/src/adaptors/shoebill-v1/abi.js b/src/adaptors/shoebill-v1/abi.js new file mode 100644 index 0000000000..948e59e398 --- /dev/null +++ b/src/adaptors/shoebill-v1/abi.js @@ -0,0 +1,194 @@ +const protocolDataProviderAbi = [ + { + inputs: [], + name: 'getAllAggregatedReservesData', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'string', + name: 'internalSymbol', + type: 'string', + }, + { + internalType: 'address', + name: 'internalAddress', + type: 'address', + }, + { + internalType: 'string', + name: 'externalSymbol', + type: 'string', + }, + { + internalType: 'address', + name: 'externalAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + internalType: + 'struct ShoebillProtocolDataProvider.TokenDataInternal', + name: 'token', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'ltv', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowingEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'stableBorrowRateEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + ], + internalType: 'struct ShoebillProtocolDataProvider.ReserveConfig', + name: 'configuration', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'liquidityIndex', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableBorrowIndex', + type: 'uint256', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'bool', + name: 'isCollateral', + type: 'bool', + }, + { + internalType: 'address', + name: 'yieldAddress', + type: 'address', + }, + ], + internalType: 'struct ShoebillProtocolDataProvider.ReserveOverview', + name: 'overview', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'oraclePrice', + type: 'uint256', + }, + ], + internalType: + 'struct ShoebillProtocolDataProvider.AggregatedReserveData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { + protocolDataProviderAbi, +}; diff --git a/src/adaptors/shoebill-v1/externalData.js b/src/adaptors/shoebill-v1/externalData.js new file mode 100644 index 0000000000..2375adeb8b --- /dev/null +++ b/src/adaptors/shoebill-v1/externalData.js @@ -0,0 +1,151 @@ +const axios = require('axios'); + +const getKsdEarn = async () => { + try { + const resp = await axios.get(`https://prod.kokoa-api.com/earn/status`); + + const result = { + supplyRate: resp.data.apy, + totalRate: Number(resp.data.apy), + underlyingAddress: '0x4fa62f1f404188ce860c8f0041d6ac3765a72e67', + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.4, + realizedApy: Number(resp.data.apy) / 2, + }; + + return result; + } catch (e) { + console.error(e); + return { + supplyRate: 0, + totalRate: 0, + underlyingAddress: '0x22e3ac1e6595b64266e0b062e01fae31d9cdd578', + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.4, + realizedApy: 0, + }; + } +}; +const get4nutsApr = async () => { + try { + const resp = await axios.get(`https://prod.kokonut-api.com/pools`); + + const data = resp.data.pools.find((e) => e.symbol === '4NUTS'); + const result = { + supplyRate: data.baseApr, + totalRate: Number(data.baseApr) + Number(data.stakingApr), + underlyingAddress: '0x22e3ac1e6595b64266e0b062e01fae31d9cdd578', + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.4, + realizedApy: (Number(data.baseApr) + Number(data.stakingApr)) / 2, + }; + + return result; + } catch (e) { + console.error(e); + return { + supplyRate: 0, + totalRate: 0, + underlyingAddress: '0x22e3ac1e6595b64266e0b062e01fae31d9cdd578', + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.4, + realizedApy: 0, + }; + } +}; +const getStKlayApr = async () => { + try { + const resp = await axios.get(`https://stake.ly/api/stats/stKlay/apr`); + + const result = { + supplyRate: resp.data.value, + totalRate: Number(resp.data.value), + underlyingAddress: '0xf80f2b22932fcec6189b9153aa18662b15cc9c00', + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.9, + realizedApy: Number(resp.data.value) * (1 - 1), + }; + + return result; + } catch (e) { + console.error(e); + return { + ksdApy: 0, + }; + } +}; + +const getRecentPoolInfo = async () => { + try { + const resp = await axios.get( + `https://ss.klayswap.com/stat/recentPoolInfo.min.json` + ); + + const result = { + common: resp.data.common, + recentPool: resp.data.recentPool, + }; + + return result.recentPool + .map((pool, i) => { + if (i === 0) return; + return { + underlyingAddress: pool[1], + rewardRate: pool[25], + airdropRate: pool[26], + feeRate: pool[27], + totalRate: Number(pool[25]), + treasuryFeeRate: 0.1, + incentiveFeeRate: 0.4, + realizedApy: Number(pool[25]) * (1 - 0.1 - 0.4), + }; + }) + .filter((e) => e); + } catch (e) { + console.error(e); + return { + common: null, + recentPool: [], + }; + } +}; +const getLeveragePoolInfo = async () => { + try { + const resp = await axios.get( + `https://ss.klayswap.com/stat/leverage.min.json` + ); + + const result = { + common: resp.data.common, + leveragePool: resp.data.leveragePool, + }; + + return result.leveragePool.single + .map((pool, i) => { + if (i === 0) return; + return { + underlyingAddress: pool[2], + rewardRate: pool[20], + supplyRate: pool[21], + totalRate: pool[22], + treasuryFeeRate: 0, + realizedApy: Number(pool[20]) + Number(pool[21]), + }; + }) + .filter((e) => e); + } catch (e) { + console.error(e); + return { + common: null, + leveragePool: [], + }; + } +}; + +module.exports = { + getKsdEarn, + get4nutsApr, + getStKlayApr, + getRecentPoolInfo, + getLeveragePoolInfo, +}; diff --git a/src/adaptors/shoebill-v1/index.js b/src/adaptors/shoebill-v1/index.js new file mode 100644 index 0000000000..516f19542c --- /dev/null +++ b/src/adaptors/shoebill-v1/index.js @@ -0,0 +1,173 @@ +// /** +// * interface Pool { +// pool: string; +// chain: string; +// project: string; +// symbol: string; +// tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd +// apyBase?: number; +// apyReward?: number; +// rewardTokens?: Array; +// underlyingTokens?: Array; +// poolMeta?: string; +// url?: string; +// // optional lending protocol specific fields: +// apyBaseBorrow?: number; +// apyRewardBorrow?: number; +// totalSupplyUsd?: number; +// totalBorrowUsd?: number; +// ltv?: number; // btw [0, 1] +// } +// */ + +// const { ethers } = require('ethers/lib'); +// const { protocolDataProviderAbi } = require('./abi'); +// const { +// getKsdEarn, +// getStKlayApr, +// getRecentPoolInfo, +// getLeveragePoolInfo, +// get4nutsApr, +// } = require('./externalData'); +// const shoebillDataProviderAddress = +// '0xBdc26Ba6a0ebFD83c76CEf76E8F9eeb7714A5884'; + +// const ethersProvider = new ethers.providers.JsonRpcProvider( +// 'https://klaytn.blockpi.network/v1/rpc/public' +// ); + +// const dataProvider = new ethers.Contract( +// shoebillDataProviderAddress, +// protocolDataProviderAbi, +// ethersProvider +// ); +// const SECONDS_PER_YEAR = 31536000; + +// async function getExtenralYieldApr() { +// const lpPool = await Promise.all([ +// getKsdEarn(), +// get4nutsApr(), +// getStKlayApr(), +// getRecentPoolInfo(), +// ]); +// const singlePool = await getLeveragePoolInfo(); + +// return { singlePool, lpPool }; +// } +// async function poolsFunction() { +// const aggregatedData = await dataProvider.getAllAggregatedReservesData(); +// const { lpPool, singlePool } = await getExtenralYieldApr(); + +// let totalDepositedCollateral = 0; +// let totalDepositedCollateralYieldApr = 0; +// let totalDepositedLend = 0; +// const data = aggregatedData.map((e) => { +// let yieldApr = +// (e.overview.isCollateral +// ? lpPool?.find( +// (t) => +// t?.underlyingAddress?.toLowerCase() === +// e.token.externalAddress?.toLowerCase() +// )?.realizedApy +// : singlePool?.find( +// (t) => +// t?.underlyingAddress?.toLowerCase() === +// e.token.externalAddress?.toLowerCase() +// )?.realizedApy) || 0; + +// const variableBorrowAPR = Number(e.overview.variableBorrowRate) / 1e27; +// const variableBorrowAPY = +// (1 + variableBorrowAPR / SECONDS_PER_YEAR) ** SECONDS_PER_YEAR - 1; + +// const depositAPR = Number(e.overview.liquidityRate) / 1e27; +// const depositAPY = +// (1 + depositAPR / SECONDS_PER_YEAR) ** SECONDS_PER_YEAR - 1; + +// const totalDeposit = +// Number(e.overview.availableLiquidity.add(e.overview.totalVariableDebt)) / +// 10 ** e.configuration.decimals; +// const totalBorrow = +// Number(e.overview.totalVariableDebt) / 10 ** e.configuration.decimals; +// const totalDepositInUSD = (totalDeposit * e.oraclePrice) / 1e8; +// if (!e.overview.isCollateral) { +// let beforeYieldApr = yieldApr; +// yieldApr = (yieldApr * (totalDeposit - totalBorrow)) / totalDeposit; +// if (isNaN(yieldApr)) yieldApr = beforeYieldApr; +// } + +// let toLendApr = 0; +// if (e.overview.isCollateral) { +// let info = lpPool?.find( +// (t) => +// t?.underlyingAddress?.toLowerCase() === +// e.token.externalAddress?.toLowerCase() +// ); +// toLendApr = info?.totalRate * info?.incentiveFeeRate || 0; +// totalDepositedCollateral += totalDepositInUSD; +// } else { +// totalDepositedLend += totalDepositInUSD; +// } +// return { +// pool: `${e.token.externalAddress}-Klaytn`?.toLowerCase(), +// chain: 'Klaytn', +// project: 'shoebill-v1', +// symbol: e.token.externalSymbol, +// tvlUsd: +// Number(e.overview.availableLiquidity.mul(e.oraclePrice)) / +// 10 ** e.configuration.decimals / +// 1e8, + +// totalSupplyUsd: totalDepositInUSD, +// totalBorrowUsd: +// Number(e.overview.totalVariableDebt.mul(e.oraclePrice)) / +// 10 ** e.configuration.decimals / +// 1e8, +// ltv: 0, +// //apyBase +// apyBaseBorrow: variableBorrowAPY, + +// // +// toLendApr, +// isCollateral: e.overview.isCollateral, +// yieldApr, +// depositAPY: depositAPY, +// }; +// }); +// let poolsData = data +// .map((e) => { +// if (e.isCollateral) { +// totalDepositedCollateralYieldApr += +// (e.totalSupplyUsd / totalDepositedCollateral) * e.toLendApr; +// } + +// return { ...e }; +// }) +// .map((t) => { +// if (!t.isCollateral) { +// let tmp = isNaN(totalDepositedCollateralYieldApr) +// ? 0 +// : totalDepositedCollateralYieldApr; +// t.yieldApr += (totalDepositedCollateral / totalDepositedLend) * tmp; +// } +// const yieldApy = +// (1 + t.yieldApr / 100 / SECONDS_PER_YEAR) ** SECONDS_PER_YEAR - 1; +// const depositApy = t.depositAPY; +// delete t.depositAPY; +// delete t.toLendApr; +// delete t.isCollateral; +// delete t.yieldApr; + +// return { +// ...t, +// apyBase: (depositApy + yieldApy) * 100, +// apyBaseBorrow: t.apyBaseBorrow * 100, +// }; +// }); +// return poolsData; +// } + +// module.exports = { +// timetravel: false, +// apy: poolsFunction, +// url: 'https://app.shoebill.finance/', +// }; diff --git a/src/adaptors/sideshift/index.js b/src/adaptors/sideshift/index.js new file mode 100644 index 0000000000..2a0f4058f4 --- /dev/null +++ b/src/adaptors/sideshift/index.js @@ -0,0 +1,23 @@ +const utils = require('../utils'); + +const main = async () => { + const stats = await utils.getData('https://sideshift.ai/api/v2/xai/stats'); + + return [ + { + pool: '0x3808708e761b988d23ae011ed0e12674fb66bd62', + chain: utils.formatChain('ethereum'), + project: 'sideshift', + symbol: utils.formatSymbol('svXAI'), + tvlUsd: Number(stats.totalValueLocked), + apy: Number(stats.latestAnnualPercentageYield), + underlyingTokens: ['0x35e78b3982e87ecfd5b3f3265b601c046cdbe232'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://sideshift.ai/staking', +}; diff --git a/src/adaptors/silo-v1/index.js b/src/adaptors/silo-v1/index.js new file mode 100644 index 0000000000..7882ca8749 --- /dev/null +++ b/src/adaptors/silo-v1/index.js @@ -0,0 +1,370 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js'); +const ethers = require('ethers'); + +const utils = require('../utils'); + +BigNumber.config({ EXPONENTIAL_AT: [-1e9, 1e9] }); + +// 2.2.8 +const url = + 'https://api.thegraph.com/subgraphs/id/QmZwDpzNPEdDFMmSghyBC6wZ3aAjJqFB2xrAsrcLCPwVQk'; + +const fallbackBlacklist = ['0x6543ee07cf5dd7ad17aeecf22ba75860ef3bbaaa']; + +const pageSizeLimit = 100; + +const getAssetsAbi = { + inputs: [], + name: 'getAssets', + outputs: [ + { + internalType: 'address[]', + name: 'assets', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getBalanceAbi = { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getDecimalsAbi = { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getAssetStateAbi = { + inputs: [], + name: 'getAssetsWithState', + outputs: [ + { + internalType: 'address[]', + name: 'assets', + type: 'address[]', + }, + { + components: [ + { + internalType: 'contract IShareToken', + name: 'collateralToken', + type: 'address', + }, + { + internalType: 'contract IShareToken', + name: 'collateralOnlyToken', + type: 'address', + }, + { + internalType: 'contract IShareToken', + name: 'debtToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'totalDeposits', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralOnlyDeposits', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowAmount', + type: 'uint256', + }, + ], + internalType: 'struct IBaseSilo.AssetStorage[]', + name: 'assetsStorage', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const START_BLOCK_ETHEREUM = 15307294; +const SILO_FACTORY_ETHEREUM = '0x4D919CEcfD4793c0D47866C8d0a02a0950737589'; + +const query = gql` + { + markets(where: { totalValueLockedUSD_gt: 100 }) { + id + name + totalValueLockedUSD + totalBorrowBalanceUSD + inputToken { + id + symbol + decimals + # totalSupply + lastPriceUSD + } + marketAssets { + id + balance + supply + protectedSupply + tokenPriceUSD + maximumLTV + dToken { + totalSupply + derivativeConversion + } + asset { + id + decimals + lastPriceUSD + } + } + rates { + rate + side + token { + id + symbol + } + } + # 2.0.3 + outputToken { + id + lastPriceUSD + } + } + } +`; + +async function getSiloAddressesToAssetBalances(block, silos) { + const { output: assets } = await sdk.api.abi.multiCall({ + abi: getAssetsAbi, + calls: silos.map((i) => ({ target: i })), + block, + }); + + const tokenAddressAndSiloAddressPairs = assets + .map((i) => i.output.map((j) => [j, i.input.target])) + .flat(); + + // We put all silo addresses from tokenAddressAndSiloAddressPairs into an array + // We can then associate the balances/decimals with the silos based on their indexes + // siloAddressesToResultIndex, assetAddressesToResultIndex, balances & decimals align with each other by index + // i.e. we maintain parity of their indexes + + const siloAddressesParityIndexed = tokenAddressAndSiloAddressPairs.map( + (entry) => entry[1] + ); + + const { output: balancesRaw } = await sdk.api.abi.multiCall({ + abi: getBalanceAbi, + calls: tokenAddressAndSiloAddressPairs.map((i) => ({ + target: i[0], + params: [i[1]], + })), + block, + }); + + const balances = balancesRaw.map((entry) => entry.output); + + const { output: decimalsRaw } = await sdk.api.abi.multiCall({ + abi: getDecimalsAbi, + calls: tokenAddressAndSiloAddressPairs.map((i) => ({ target: i[0] })), + block, + }); + + const decimals = decimalsRaw.map((entry) => entry.output); + + let parityIndex = 0; + let siloAddressToAssetBalanceResults = {}; + for (let balance of balances) { + let siloAddress = siloAddressesParityIndexed[parityIndex]; + let assetAddress = tokenAddressAndSiloAddressPairs[parityIndex][0]; + let assetDecimals = decimals[parityIndex]; + let assetBalance = new BigNumber( + ethers.utils.formatUnits(balances[parityIndex], assetDecimals) + ).toString(); + if (!siloAddressToAssetBalanceResults[siloAddress]) { + siloAddressToAssetBalanceResults[siloAddress] = []; + } + siloAddressToAssetBalanceResults[siloAddress].push({ + siloAddress, + assetAddress, + assetBalance, + }); + parityIndex++; + } + + return siloAddressToAssetBalanceResults; +} + +const main = async () => { + const latestBlock = await sdk.api.util.getLatestBlock('ethereum'); + const latestBlockNumber = latestBlock.number; + + // market data + const data = await request(url, query); + + const siloAddresses = data.markets + .map((item) => ethers.utils.getAddress(item.id)) + .filter( + (address) => fallbackBlacklist.indexOf(address.toLowerCase()) === -1 + ); + + const siloAddressesToAssetBalances = await getSiloAddressesToAssetBalances( + latestBlockNumber, + siloAddresses + ); + + const markets = []; + + let tokenAddressToLastPriceUsd = {}; + + for (let market of data.markets) { + const { + id, + name, + totalValueLockedUSD, + inputToken, + outputToken, // 2.0.3 + marketAssets, + rates, + totalBorrowBalanceUSD, + } = market; + + if (fallbackBlacklist.indexOf(id.toLowerCase()) === -1) { + let siloChecksumAddress = ethers.utils.getAddress(id); + let inputTokenChecksumAddress = ethers.utils.getAddress(inputToken.id); + + for (let outputTokenEntry of outputToken) { + let checksumAddress = ethers.utils.getAddress(outputTokenEntry.id); + if (!tokenAddressToLastPriceUsd[checksumAddress]) { + tokenAddressToLastPriceUsd[checksumAddress] = + outputTokenEntry.lastPriceUSD ? outputTokenEntry.lastPriceUSD : 0; + } + } + + if (!tokenAddressToLastPriceUsd[inputTokenChecksumAddress]) { + tokenAddressToLastPriceUsd[inputTokenChecksumAddress] = + inputToken.lastPriceUSD ? inputToken.lastPriceUSD : 0; + } + + let underlyingAssetAddresses = []; + let siloAssetBalances = siloAddressesToAssetBalances[siloChecksumAddress]; + + let tvlUsd = new BigNumber(0); + for (let siloAssetBalanceEntry of siloAssetBalances) { + if ( + siloAssetBalanceEntry.assetAddress === + '0xd7C9F0e536dC865Ae858b0C0453Fe76D13c3bEAc' + ) { + continue; + } + underlyingAssetAddresses.push(siloAssetBalanceEntry.assetAddress); + let useAssetPrice = tokenAddressToLastPriceUsd[ + siloAssetBalanceEntry.assetAddress + ] + ? tokenAddressToLastPriceUsd[siloAssetBalanceEntry.assetAddress] + : 0; + tvlUsd = tvlUsd.plus( + new BigNumber(siloAssetBalanceEntry.assetBalance).multipliedBy( + tokenAddressToLastPriceUsd[siloAssetBalanceEntry.assetAddress] + ) + ); + } + + let inputTokenBorrowRateObject = rates.find( + (rate) => rate.token.id === inputToken.id && rate.side === 'BORROWER' + ); + let inputTokenSupplyRateObject = rates.find( + (rate) => rate.token.id === inputToken.id && rate.side === 'LENDER' + ); + + let inputMarketAsset = marketAssets.filter( + (marketAsset) => marketAsset.asset.id === inputToken.id + )?.[0]; + + let ltvInputToken = new BigNumber(inputMarketAsset?.maximumLTV) + .dividedBy(100) + .toNumber(); + + let totalBorrowUsdInputTokenRaw = new BigNumber( + inputMarketAsset?.dToken.totalSupply + ) + .multipliedBy(inputMarketAsset?.dToken.derivativeConversion) + .decimalPlaces(0, 1) + .toString(); + let totalBorrowUsdInputToken = new BigNumber( + ethers.utils.formatUnits( + totalBorrowUsdInputTokenRaw, + inputMarketAsset?.asset?.decimals + ) + ) + .multipliedBy(inputMarketAsset?.asset?.lastPriceUSD) + .toString(); + + let totalSupplyUsdInputTokenRaw = new BigNumber(inputMarketAsset?.supply) + .minus(inputMarketAsset?.protectedSupply) + .toString(); + let totalSupplyUsdInputToken = new BigNumber( + ethers.utils.formatUnits( + totalSupplyUsdInputTokenRaw, + inputMarketAsset?.asset?.decimals + ) + ) + .multipliedBy(inputMarketAsset?.asset?.lastPriceUSD) + .toString(); + + markets.push({ + pool: `${market.id}-ethereum`, + chain: 'Ethereum', + project: 'silo-v1', + symbol: utils.formatSymbol(name), + tvlUsd: tvlUsd.toNumber(), + apyBase: Number(inputTokenSupplyRateObject.rate), + apyBaseBorrow: Number(inputTokenBorrowRateObject.rate), + url: `https://app.silo.finance/silo/${market.id}`, + underlyingTokens: underlyingAssetAddresses, + ltv: ltvInputToken, + totalBorrowUsd: totalBorrowUsdInputToken, + totalSupplyUsd: totalSupplyUsdInputToken, + }); + } + } + + return markets; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/silo-v2/index.js b/src/adaptors/silo-v2/index.js new file mode 100644 index 0000000000..83a3836daa --- /dev/null +++ b/src/adaptors/silo-v2/index.js @@ -0,0 +1,661 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const BigNumber = require('bignumber.js'); +const ethers = require('ethers'); + +const utils = require('../utils'); + +BigNumber.config({ EXPONENTIAL_AT: [-1e9, 1e9] }); + +const XAI = '0xd7c9f0e536dc865ae858b0c0453fe76d13c3beac' +const blacklistedSilos = ["0x6543ee07cf5dd7ad17aeecf22ba75860ef3bbaaa",]; + +const badDebtSilos = { + sonic: [ + "0xCCdDbBbd1E36a6EDA3a84CdCee2040A86225Ba71", // wmetaUSD - Sonic + "0xEd9777944A2Fb32504a410D23f246463B3f40908", // USDC (wmetaUSD) - Sonic + "0x6e8C150224D6e9B646889b96EFF6f7FD742e2C22", // wmetaUSD - Sonic + "0x0aB02DD08c1555d1a20C76a6EA30e3E36f3e06d4", // scUSD (wmetaUSD) - Sonic + "0x75c550776c191A8F6aE22EdC742aD2788723B66E", // wmetaUSD - Sonic + "0xc6ee9A58D5270e53fD1361946899b6D0553142B4", // scUSD (wmetaUSD) - Sonic + "0x501Ee3D6cB84004c7970cA24f3daC07D61A25e4D", // wmetaUSD - Sonic + "0x1A089424F52502139888fa4c0ED2FA088e9E1d51", // USDC (wmetaUSD) - Sonic + "0x1c1791911483E98875D162355feC47f37613f0FB", // wmetaS - Sonic + "0x8c98b43BF61F2B07c4D26f85732217948Fca2a90", // wS (wmetaS) - Sonic + "0xA1627a0E1d0ebcA9326D2219B84Df0c600bed4b1", // USDC - Sonic (Stream-impacted) + "0xb1412442aa998950f2f652667d5Eba35fE66E43f", // scUSD - Sonic (Stream-impacted) + "0x27968d36b937DcB26F33902fA489E5b228b104BE", // dUSD - Sonic (Stream-impacted) + "0x76DF755A9f40463F14d0a2b7Cba3Ccf05404eEdf", // dUSD - Sonic (Stream-impacted) + "0xAF1BDaE843d90c546DE5001f7b107B46e1a26Aa9", // dUSD - Sonic (Stream-impacted) + "0x5954ce6671d97D24B782920ddCdBB4b1E63aB2De", // USDC - Sonic (Stream-impacted) + "0x4935FaDB17df859667Cc4F7bfE6a8cB24f86F8d0", // USDC - Sonic (Stream-impacted) + "0x219656F33c58488D09d518BaDF50AA8CdCAcA2Aa", // ETH - Sonic (Stream-impacted) + ].map(entry => entry.toLowerCase()), + ethereum: [ + "0x1dE3bA67Da79A81Bc0c3922689c98550e4bd9bc2", // USDC - ethereum (Stream-impacted) + ].map(entry => entry.toLowerCase()), + arbitrum: [ + "0xACb7432a4BB15402CE2afe0A7C9D5b738604F6F9", // USDC - Arbitrum (Stream-impacted) + "0x2433D6AC11193b4695D9ca73530de93c538aD18a", // USDC - Arbitrum (Stream-impacted) + ].map(entry => entry.toLowerCase()), + avax: [ + "0x672b77f0538b53Dc117C9dDfEb7377A678d321a6", // USDC - Avalanche (Stream-impacted) + "0xE0fc62e685E2b3183b4B88b1fE674cFEc55a63F7", // USDT - Avalanche (Stream-impacted) + "0x9C4D4800b489d217724155399CD64D07Eae603f3", // AUSD - Avalanche (Stream-impacted) + "0x7437ac81457Fa98fFB2d0C8f9943ecfE4813e2f1", // BTC.b - Avalanche (Stream-impacted) + ].map(entry => entry.toLowerCase()), +}; + +const badDebtVaults = { + sonic: [ + "0xcca902f2d3d265151f123d8ce8FdAc38ba9745ed", // USDC - Sonic (Stream-impacted) + "0x2bc6F1406D736Cc09631676c992Abbf2CeD789e7", // USDC - Sonic (Stream-impacted) + "0xF75AE954D30217B4EE70DbFB33f04162aa3Cf260", // USDC - Sonic (Stream-impacted) + "0xb47cB414aaB743C977DfD1FDB758f971907e810e", // USDC - Sonic (Stream-impacted) + "0xF6F87073cF8929C206A77b0694619DC776F89885", // USDC - Sonic (Stream-impacted) + "0x391b3F70E254d582588B27e97E48D1CFcdf0BE7e", // scUSD - Sonic (Stream-impacted) + "0x9A1BF5365edBB99C2c61CA6D9ffAd0B705ACfc6F", // dUSD - Sonic (Stream-impacted) + "0xb6A23cB29e512Df41876B28D7A848BD831f9c5Ba", // scUSD - Sonic (Stream-impacted) + "0xf6bC16B79c469b94Cdd25F3e2334DD4FEE47A581", // USDC - Sonic (Stream-impacted) + "0xCc7bDB3FF050D65918b96e4BDf1060a1aA0bB409", // ETH - Sonic (Stream-impacted) + ].map(entry => entry.toLowerCase()), + ethereum: [ + "0x8399C8Fc273bD165C346Af74A02e65f10e4FD78F", // USDC - ethereum (Stream-impacted) + ].map(entry => entry.toLowerCase()), + arbitrum: [ + "0x7C1C43Df1B08A7de4e25E7a8f5867efDCc812B95", // USDC - Arbitrum (Stream-impacted) + "0x2BA39e5388aC6C702Cb29AEA78d52aa66832f1ee", // USDC - Arbitrum (Stream-impacted) + "0xac69CFe6BB269CeBF8ab4764d7E678C3658b99f2", // USDC - Arbitrum (Stream-impacted) + ].map(entry => entry.toLowerCase()), + avalanche: [ + "0x4dc1ce9b9f9EF00c144BfAD305f16c62293dC0E8", // USDC - Avalanche (Stream-impacted) + "0x1f8E769B5B6010B2C2BBCd68629EA1a0a0Eda7E3", // BTC.b - Avalanche (Stream-impacted) + "0x6c09bfdc1df45D6c4Ff78Dc9F1C13aF29eB335d4", // USDC - Avalanche (Stream-impacted) + "0x3d7B0c3997E48fA3FC96cd057d1fb4E5F891835B", // AUSD - Avalanche (Stream-impacted) + "0x36E2AA296E798Ca6262DC5Fad5F5660e638d5402", // USDC - Avalanche (Stream-impacted) + ].map(entry => entry.toLowerCase()), +}; + +const getAssetAbiV2 = "address:asset"; +const getSiloConfigMarketId = "uint256:SILO_ID"; +const getAssetBalanceAbi = "function balanceOf(address account) external view returns (uint256)"; +const getAssetSymbolAbi = "function symbol() public view returns (string memory)"; +const getAssetDecimalsAbi = "function decimals() public view returns (uint256)"; +const getSiloStorageAbi = "function getSiloStorage() external view returns (uint192 daoAndDeployerRevenue, uint64 interestRateTimestamp, uint256 protectedAssets, uint256 collateralAssets, uint256 debtAssets)"; +const getSiloAssetBorrowAprAbi = "function getBorrowAPR(address _silo) external view returns (uint256 borrowAPR)"; +const getSiloAssetDepositAprAbi = "function getDepositAPR(address _silo) external view returns (uint256 depositAPR)"; +const getSiloAssetMaxLtvAbi = "function getMaxLtv(address _silo) external view returns (uint256 maxLtv)"; +const getAssetStateAbiV2 = 'function getTotalAssetsStorage(uint8 _assetType) external view returns (uint256 totalAssetsByType)'; +const getIncentiveProgramAbi = 'function incentivesPrograms(bytes32) external view returns (uint256 index, address rewardToken, uint104 emissionPerSecond, uint40 lastUpdateTimestamp, uint40 distributionEnd)'; + +const configV2 = { + sonic: { + chainName: "Sonic", + deployments: [ + { + START_BLOCK: 2672166, + SILO_FACTORY: '0xa42001d6d2237d2c74108fe360403c4b796b7170', // Silo V2 Sonic (Main) + SILO_LENS: "0xB6AdBb29f2D8ae731C7C72036A7FD5A7E970B198", + SILO_ADDRESS_TO_INCENTIVE_PROGRAM: { + "0x4E216C15697C1392fE59e1014B009505E05810Df": { + controller: "0x0dd368Cd6D8869F2b21BA3Cb4fd7bA107a2e3752", + name: "wS_sUSDC_008", + id: "0x77535f73555344435f3030380000000000000000000000000000000000000000", + } + }, + SUBGRAPH_URL: 'https://api.thegraph.com/subgraphs/id/QmdZHcgScfYHSAmosSrrRC4YYk5sV1QENsnUrUbFH6G7Cs', + }, + { + START_BLOCK: 25244110, + SILO_FACTORY: '0xa42001d6d2237d2c74108fe360403c4b796b7170', // Silo V2 Sonic (Main Revised) + SILO_LENS: "0x925D5466d4D5b01995E20e1245924aDa6415126a", + SUBGRAPH_URL: 'https://api.thegraph.com/subgraphs/id/QmdZHcgScfYHSAmosSrrRC4YYk5sV1QENsnUrUbFH6G7Cs', + } + ], + }, + arbitrum: { + chainName: "Arbitrum", + deployments: [ + { + START_BLOCK: 334531851, + SILO_FACTORY: '0x384DC7759d35313F0b567D42bf2f611B285B657C', // Silo V2 Arbitrum (Main) + SILO_LENS: '0x8fBe8229a8959d0623C73B91121B12Cea79D739f', + } + ], + }, + ethereum: { + chainName: "Ethereum", + deployments: [ + { + START_BLOCK: 22616413, + SILO_FACTORY: '0x22a3cF6149bFa611bAFc89Fd721918EC3Cf7b581', // Silo V2 Ethereum (Main) + SILO_LENS: '0xF5875422734412EBbF6D4A074b7dE0a276BcDC88', + } + ], + }, + avax: { + chainName: "Avalanche", + deployments: [ + { + START_BLOCK: 64050356, + SILO_FACTORY: '0x92cECB67Ed267FF98026F814D813fDF3054C6Ff9', // Silo V2 Avalanche (Main) + SILO_LENS: '0x626B6fd8Cb764F1776BF7d65049D998D5a9f6c0A', + } + ], + }, +} + +async function getSiloData(api, deploymentData) { + + // Handle V2 silos + let siloData = []; + let assetAddressToSymbol = {}; + let assetAddressToDecimals = {}; + let siloAddressToMarketId = {}; + let siloAddressToConfigAddress = {}; + if(configV2[api.chain]) { + const { + siloAddresses: siloArrayV2, + siloAddressesToSiloConfigAddress, + } = await getSilosV2(api, deploymentData); + const assetsV2 = await api.multiCall({ + abi: getAssetAbiV2, + calls: siloArrayV2.map(i => ({ target: i })), + }); + const assetBalancesV2 = await api.multiCall({ + abi: getAssetBalanceAbi, + calls: assetsV2.map((asset, i) => ({ target: asset, params: [siloArrayV2[i]] })), + }); + const assetBorrowAPR = await api.multiCall({ + abi: getSiloAssetBorrowAprAbi, + calls: siloArrayV2.map((siloAddress, i) => ({ target: deploymentData.SILO_LENS, params: [siloAddress] })), + }); + const assetDepositAPR = await api.multiCall({ + abi: getSiloAssetDepositAprAbi, + calls: siloArrayV2.map((siloAddress, i) => ({ target: deploymentData.SILO_LENS, params: [siloAddress] })), + }); + const assetMaxLTV = await api.multiCall({ + abi: getSiloAssetMaxLtvAbi, + calls: siloArrayV2.map((siloAddress, i) => ({ target: deploymentData.SILO_LENS, params: [siloAddress] })), + }); + const siloStorage = await api.multiCall({ + abi: getSiloStorageAbi, + calls: siloArrayV2.map((siloAddress, i) => ({ target: siloAddress, params: [] })), + }); + let siloAddressToIncentiveResults = {}; + if(deploymentData.SILO_ADDRESS_TO_INCENTIVE_PROGRAM) { + siloAddressToIncentiveResults = Object.assign({}, deploymentData.SILO_ADDRESS_TO_INCENTIVE_PROGRAM); + const siloIncentiveProgramData = await api.multiCall({ + abi: getIncentiveProgramAbi, + calls: Object.entries(deploymentData.SILO_ADDRESS_TO_INCENTIVE_PROGRAM).map(([siloAddress, incentiveProgramEntry], i) => ({ target: incentiveProgramEntry.controller, params: [incentiveProgramEntry.id] })), + }); + for(const [index, siloAddress] of Object.keys(deploymentData.SILO_ADDRESS_TO_INCENTIVE_PROGRAM).entries()) { + siloAddressToIncentiveResults[siloAddress].result = { + index: siloIncentiveProgramData[index].index, + rewardToken: siloIncentiveProgramData[index].rewardToken, + emissionPerSecond: siloIncentiveProgramData[index].emissionPerSecond, + lastUpdateTimestamp: siloIncentiveProgramData[index].lastUpdateTimestamp, + distributionEnd: siloIncentiveProgramData[index].distributionEnd, + }; + } + } + siloData = assetsV2.map((asset, i) => [ + asset, + siloArrayV2[i], + assetBalancesV2[i], + assetBorrowAPR[i], + assetDepositAPR[i], + assetMaxLTV[i], + siloStorage[i].protectedAssets, + siloStorage[i].collateralAssets, + siloStorage[i].debtAssets, + siloAddressToIncentiveResults?.[siloArrayV2?.[i]] ? siloAddressToIncentiveResults[siloArrayV2[i]] : false, + ]); + let uniqueAssetAddresses = [...new Set(assetsV2)]; + const assetSymbols = await api.multiCall({ + abi: getAssetSymbolAbi, + calls: uniqueAssetAddresses.map((asset, i) => ({ target: asset })), + }); + const assetDecimals = await api.multiCall({ + abi: getAssetDecimalsAbi, + calls: uniqueAssetAddresses.map((asset, i) => ({ target: asset })), + }); + for(let [index, assetAddress] of uniqueAssetAddresses.entries()) { + assetAddressToSymbol[assetAddress] = assetSymbols[index]; + assetAddressToDecimals[assetAddress] = assetDecimals[index]; + } + let uniqueSiloConfigAddresses = [...new Set(Object.values(siloAddressesToSiloConfigAddress))]; + const siloConfigMarketIds = await api.multiCall({ + abi: getSiloConfigMarketId, + calls: uniqueSiloConfigAddresses.map((siloConfig, i) => ({ target: siloConfig })), + }); + let siloConfigAddressToMarketId = {}; + for(let [index, siloConfigAddress] of uniqueSiloConfigAddresses.entries()) { + siloConfigAddressToMarketId[siloConfigAddress] = siloConfigMarketIds[index]; + } + for(let [siloAddress, siloConfigAddress] of Object.entries(siloAddressesToSiloConfigAddress)) { + siloAddressToConfigAddress[siloAddress] = siloConfigAddress; + siloAddressToMarketId[siloAddress] = siloConfigAddressToMarketId[siloConfigAddress]; + } + } + + let assetPrices = await utils.getPrices(siloData.map(entry => entry[0]), api.chain); + + let assetDataBySilo = {}; + for( + let [ + assetAddress, + siloAddress, + assetBalance, + assetBorrowAPR, + assetDepositAPR, + assetMaxLTV, + protectedAssetBalance, + collateralAssetBalance, + debtAssetBalance, + incentiveProgramResults, + ] of siloData + ) { + + let assetBalanceFormatted = new BigNumber( + ethers.utils.formatUnits( + assetBalance, + assetAddressToDecimals[assetAddress] + ) + ).toString(); + + let assetBalanceValueUSD = new BigNumber( + ethers.utils.formatUnits( + assetBalance, + assetAddressToDecimals[assetAddress] + ) + ) + .multipliedBy(assetPrices.pricesByAddress[assetAddress.toLowerCase()] ? assetPrices.pricesByAddress[assetAddress.toLowerCase()] : 0) + .toString(); + + let assetBorrowAprFormatted = new BigNumber( + ethers.utils.formatUnits( + assetBorrowAPR, + 16 + ) + ).toString(); + + let assetMaxLtvFormatted = new BigNumber( + ethers.utils.formatUnits( + assetMaxLTV, + 18 + ) + ).toString(); + + let assetDepositAprFormatted = new BigNumber( + ethers.utils.formatUnits( + assetDepositAPR, + 16 + ) + ).toString(); + + let totalBorrowValueUSD = new BigNumber( + ethers.utils.formatUnits( + debtAssetBalance, + assetAddressToDecimals[assetAddress] + ) + ) + .multipliedBy(assetPrices.pricesByAddress[assetAddress.toLowerCase()] ? assetPrices.pricesByAddress[assetAddress.toLowerCase()] : 0) + .toString(); + + let totalSupplyRaw = new BigNumber(collateralAssetBalance).toString(); + let totalSupplyValueUSD = new BigNumber( + ethers.utils.formatUnits( + totalSupplyRaw, + assetAddressToDecimals[assetAddress] + ) + ) + .multipliedBy(assetPrices.pricesByAddress[assetAddress.toLowerCase()] ? assetPrices.pricesByAddress[assetAddress.toLowerCase()] : 0) + .toString(); + + let boostedAprFormatted = 0; + let rewardTokens = []; + if(incentiveProgramResults?.result?.emissionPerSecond) { + let emissionsPerYearRewardToken = new BigNumber(incentiveProgramResults?.result.emissionPerSecond).multipliedBy(60).multipliedBy(60).multipliedBy(24).multipliedBy(365); + let emissionsPerYearUSD = new BigNumber( + ethers.utils.formatUnits( + emissionsPerYearRewardToken.toString(), + assetAddressToDecimals[incentiveProgramResults?.result?.rewardToken] + ) + ) + .multipliedBy(assetPrices.pricesByAddress[incentiveProgramResults?.result?.rewardToken.toLowerCase()]) + .toString(); + rewardTokens.push(incentiveProgramResults?.result?.rewardToken); + boostedAprFormatted = new BigNumber(new BigNumber(emissionsPerYearUSD).multipliedBy(100).toString()).dividedBy(new BigNumber(totalSupplyValueUSD)).toString(); + } + + assetDataBySilo[siloAddress] = { + assetAddress: assetAddress, + assetSymbol: assetAddressToSymbol[assetAddress], + assetDecimals: assetAddressToDecimals[assetAddress], + assetBalanceRaw: assetBalance, + assetBalanceFormatted: assetBalanceFormatted, + assetBalanceValueUSD: assetBalanceValueUSD, + assetPrice: assetPrices.pricesByAddress[assetAddress.toLowerCase()], + assetBorrowAprRaw: assetBorrowAPR, + assetDepositAprRaw: assetDepositAPR, + assetBorrowAprFormatted: assetBorrowAprFormatted, + assetDepositAprFormatted: assetDepositAprFormatted, + marketId: siloAddressToMarketId[siloAddress], + siloConfig: siloAddressToConfigAddress[siloAddress], + totalSupplyRaw: totalSupplyRaw, + totalSupplyValueUSD: totalSupplyValueUSD, + totalBorrowRaw: debtAssetBalance, + totalBorrowValueUSD: totalBorrowValueUSD, + assetMaxLtvRaw: assetMaxLTV, + assetMaxLtvFormatted: assetMaxLtvFormatted, + boostedAprFormatted, + rewardTokens, + } + } + + return assetDataBySilo; +} + +async function getSilosV2(chainApi, deploymentData) { + const chain = chainApi.chain; + let logs = []; + let siloAddresses = []; + let siloAddressesToSiloConfigAddress = {}; + if(configV2[chain]) { + let latestBlock = await sdk.api.util.getLatestBlock(chain); + const iface = new ethers.utils.Interface([ + 'event NewSilo(address indexed implementation, address indexed token0, address indexed token1, address silo0, address silo1, address siloConfig)', + ]); + const { SILO_FACTORY, START_BLOCK } = deploymentData; + let logChunk = await sdk.api2.util.getLogs({ + target: SILO_FACTORY, + topics: ['0x3d6b896c73b628ec6ba0bdfe3cdee1356ea2af31af2a97bbd6b532ca6fa00acb'], + keys: [], + fromBlock: START_BLOCK, + toBlock: latestBlock.block, + chain: chain, + }); + logs = [...logs, ...logChunk.output.map((event) => iface.parseLog(event))]; + + siloAddresses = logs.flatMap((log) => { + + let silo0 = log.args[3]; + let silo1 = log.args[4]; + let siloConfig = log.args[5]; + + siloAddressesToSiloConfigAddress[silo0] = siloConfig; + siloAddressesToSiloConfigAddress[silo1] = siloConfig; + + return [silo0, silo1].filter( + (address) => ((blacklistedSilos.indexOf(address.toLowerCase()) === -1) && (badDebtSilos[chain]?.indexOf(address.toLowerCase()) === -1)) + ); + }); + + } + + return { siloAddresses, siloAddressesToSiloConfigAddress }; +} + +async function getVaultData(api, deploymentData, chain) { + + // Handle V2 Vaults + let rawVaultData = {}; + let assetDataByVault = {}; + let assetsForPriceData = []; + let subgraphVaults; + let filteredSubgraphVaults = []; + if(deploymentData?.SUBGRAPH_URL) { + const vaultQuery = gql` + { + vaults { + id + name + totalSupply + assetRatio + decimals + performanceFee + asset { + symbol + name + id + decimals + } + } + } + `; + subgraphVaults = await request(deploymentData?.SUBGRAPH_URL, vaultQuery); + + // Only collect data for vaults with a positive supply & which aren't in the badDebtVaults list + filteredSubgraphVaults = subgraphVaults?.vaults.filter((vault) => (vault?.totalSupply && new BigNumber(vault.totalSupply).isGreaterThan(0) && (badDebtVaults[chain]?.indexOf(vault.id.toLowerCase()) === -1))); + + for(let vault of filteredSubgraphVaults) { + rawVaultData[vault.id] = { + id: vault.id, + name: vault.name, + totalSupply: vault.totalSupply, + assetRatio: vault.assetRatio, + asset: vault.asset, + performanceFee: vault.performanceFee ? ethers.utils.formatUnits(vault.performanceFee, 16) : 0, + } + if(vault?.asset?.id && assetsForPriceData?.indexOf(vault?.asset?.id) === -1) { + assetsForPriceData.push(vault?.asset?.id); + } + } + + } + + let assetPrices = await utils.getPrices(assetsForPriceData, api.chain); + + if(deploymentData?.SUBGRAPH_URL) { + const VAULT_POSITION_BATCH_SIZE = 10; + let vaultBatches = []; + let vaultIdToPositionMetadata = {}; + for (let i = 0; i < filteredSubgraphVaults?.length; i += VAULT_POSITION_BATCH_SIZE) { + const batch = filteredSubgraphVaults.slice(i, i + VAULT_POSITION_BATCH_SIZE); + vaultBatches.push(batch); + } + + for (let vaultBatch of vaultBatches) { + + let vaultAddresses = vaultBatch.map((vault) => vault.id); + + const vaultPositionsBatchQuery = gql` + query vaultPositionQuery($account_in: [String!]) { + positions(where: {account_in: $account_in}) { + account { + id + } + sTokenBalance + market { + id + collateralRatio + rates(where: {side: LENDER}) { + rate + } + } + sToken { + asset { + id + } + decimals + symbol + } + } + } + `; + const vaultPositions = await request(deploymentData?.SUBGRAPH_URL, vaultPositionsBatchQuery, { + account_in: vaultAddresses + }); + + for(let vaultPosition of vaultPositions?.positions) { + let vaultAccountId = vaultPosition?.account?.id; + let underlyingAssetAmount = new BigNumber(vaultPosition?.sTokenBalance).multipliedBy(vaultPosition?.market?.collateralRatio).toFixed(0); + if(!vaultIdToPositionMetadata[vaultAccountId]) { + vaultIdToPositionMetadata[vaultAccountId] = { + totalUnderlyingAssets: underlyingAssetAmount, + totalUnderlyingAssetsUSD: ethers.utils.formatUnits(new BigNumber(underlyingAssetAmount).multipliedBy(assetPrices.pricesByAddress[vaultPosition?.sToken?.asset?.id.toLowerCase()]).toFixed(0), vaultPosition?.sToken?.decimals), + positions: [{ + rates: vaultPosition?.market?.rates, + underlyingAssetSymbol: vaultPosition?.sToken?.symbol, + underlyingAssetAmount, + underlyingAssetAmountUSD: ethers.utils.formatUnits(new BigNumber(underlyingAssetAmount).multipliedBy(assetPrices.pricesByAddress[vaultPosition?.sToken?.asset?.id.toLowerCase()]).toFixed(0), vaultPosition?.sToken?.decimals), + underlyingAssetDecimals: vaultPosition?.sToken?.decimals, + }] + } + } else { + vaultIdToPositionMetadata[vaultAccountId].totalUnderlyingAssets = new BigNumber(vaultIdToPositionMetadata[vaultAccountId].totalUnderlyingAssets).plus(underlyingAssetAmount).toString(); + vaultIdToPositionMetadata[vaultAccountId].totalUnderlyingAssetsUSD = new BigNumber(vaultIdToPositionMetadata[vaultAccountId].totalUnderlyingAssetsUSD).plus(new BigNumber(ethers.utils.formatUnits(new BigNumber(underlyingAssetAmount).multipliedBy(assetPrices.pricesByAddress[vaultPosition?.sToken?.asset?.id.toLowerCase()]).toFixed(0), vaultPosition?.sToken?.decimals))).toFixed(0), + vaultIdToPositionMetadata[vaultAccountId].positions.push({ + rates: vaultPosition?.market?.rates, + underlyingAssetSymbol: vaultPosition?.sToken?.symbol, + underlyingAssetAmount, + underlyingAssetAmountUSD: ethers.utils.formatUnits(new BigNumber(underlyingAssetAmount).multipliedBy(assetPrices.pricesByAddress[vaultPosition?.sToken?.asset?.id.toLowerCase()]).toFixed(0), vaultPosition?.sToken?.decimals), + underlyingAssetDecimals: vaultPosition?.sToken?.decimals, + }) + } + } + + } + + for(let matchAddress of Object.keys(vaultIdToPositionMetadata)) { + if(rawVaultData[matchAddress]) { + let totalRate = "0"; + for(let position of vaultIdToPositionMetadata[matchAddress].positions) { + let positionRatio = new BigNumber(position.underlyingAssetAmountUSD).dividedBy(new BigNumber(vaultIdToPositionMetadata[matchAddress].totalUnderlyingAssetsUSD)).toString(); + let effectiveRate = new BigNumber(positionRatio).multipliedBy(new BigNumber(position.rates[0].rate)).toString(); + totalRate = new BigNumber(totalRate).plus(new BigNumber(effectiveRate)).toString(); + } + // subtract performance fee + totalRate = new BigNumber(totalRate).multipliedBy(new BigNumber(1).minus(new BigNumber(rawVaultData[matchAddress].performanceFee).dividedBy(100))).toString() + rawVaultData[matchAddress].apyBase = totalRate; + } + } + } + + for( + let [ + vaultAddress, + { + id, + name, + totalSupply, + assetRatio, + asset, + decimals, + apyBase, + } + ] of Object.entries(rawVaultData) + ) { + + let assetDepositedBalance = new BigNumber(assetRatio).multipliedBy(totalSupply) + let assetDepositedBalanceFormatted = ethers.utils.formatUnits( + assetDepositedBalance.toFixed(0), + decimals + ) + + let assetDepositedBalanceValueUSD = new BigNumber( + assetDepositedBalanceFormatted + ) + .multipliedBy(assetPrices.pricesByAddress[asset.id.toLowerCase()]) + .toString(); + + assetDataByVault[vaultAddress] = { + assetAddress: asset.id, + assetSymbol: asset.symbol, + assetDecimals: asset.decimals, + assetPrice: assetPrices.pricesByAddress[asset.id.toLowerCase()], + vaultId: name, + apyBase, + totalSupplyRaw: assetDepositedBalance.toString(), + totalSupplyFormatted: assetDepositedBalanceFormatted.toString(), + totalSupplyValueUSD: assetDepositedBalanceValueUSD, + } + + // console.log({assetDataByVault}) + + } + + return assetDataByVault; +} + +const main = async () => { + + const markets = []; + + for(let [chain, config] of Object.entries(configV2)) { + + const api = new sdk.ChainApi({ chain }); + + const vaultPoolIds = []; + const marketPoolIds = []; + + for(let deploymentData of config.deployments) { + + let siloData = await getSiloData(api, deploymentData); + + for(let [siloAddress, siloInfo] of Object.entries(siloData)) { + let marketPoolId = `${siloInfo.marketId}-${siloAddress}-${chain}`; + if(marketPoolIds.indexOf(marketPoolId) === -1) { + let marketData = { + pool: marketPoolId, + chain: config.chainName, + project: 'silo-v2', + symbol: utils.formatSymbol(siloInfo.assetSymbol), + tvlUsd: new BigNumber(siloInfo.assetBalanceValueUSD).toNumber(), + apyBase: new BigNumber(siloInfo.assetDepositAprFormatted).toNumber(), + apyBaseBorrow: new BigNumber(siloInfo.assetBorrowAprFormatted).toNumber(), + url: `https://v2.silo.finance/markets/${chain}/${siloInfo.marketId}`, + underlyingTokens: [siloInfo.assetAddress], + ltv: Number(siloInfo.assetMaxLtvFormatted), + totalBorrowUsd: Number(Number(siloInfo.totalBorrowValueUSD).toFixed(2)), + totalSupplyUsd: Number(Number(siloInfo.totalSupplyValueUSD).toFixed(2)), + poolMeta: `${siloInfo.marketId}`, + ...(siloInfo.boostedAprFormatted && { + apyReward: new BigNumber(siloInfo.boostedAprFormatted).toNumber(), + rewardTokens: siloInfo.rewardTokens, + }) + }; + + marketPoolIds.push(marketPoolId); + markets.push(marketData); + } + } + + let vaultData = await getVaultData(api, deploymentData, chain); + + for(let [vaultAddress, vaultInfo] of Object.entries(vaultData)) { + let vaultPoolId = `${vaultInfo.vaultId}-${vaultAddress}-${chain}`; + if( + (new BigNumber(vaultInfo.apyBase).toNumber() > 0) && + (Number(Number(vaultInfo.totalSupplyValueUSD).toFixed(2)) > 0) && + (vaultPoolIds.indexOf(vaultPoolId) === -1) + ) { + let marketData = { + pool: vaultPoolId, + chain: config.chainName, + project: 'silo-v2', + symbol: utils.formatSymbol(vaultInfo.assetSymbol), + tvlUsd: Number(Number(vaultInfo.totalSupplyValueUSD).toFixed(2)), + apyBase: new BigNumber(vaultInfo.apyBase).toNumber(), + url: `https://app.silo.finance/vaults/${chain === 'avax' ? 'avalanche': chain}/${vaultAddress}?action=deposit`, + underlyingTokens: [vaultInfo.assetAddress], + totalSupplyUsd: Number(Number(vaultInfo.totalSupplyValueUSD).toFixed(2)), + poolMeta: `${vaultInfo.vaultId}`, + }; + vaultPoolIds.push(vaultPoolId) + markets.push(marketData); + } + } + + } + + } + + return markets; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/single-finance/abis.js b/src/adaptors/single-finance/abis.js new file mode 100644 index 0000000000..9ca7cc6bc5 --- /dev/null +++ b/src/adaptors/single-finance/abis.js @@ -0,0 +1,219 @@ +module.exports = { + VaultABI: [ + { + inputs: [], + name: 'totalToken', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vaultDebtVal', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'config', + outputs: [ + { + internalType: 'contract IVaultConfig', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + + Erc20ABI: [ + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + ConfigurableInterestVaultConfigABI: [ + { + inputs: [ + { + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'floating', + type: 'uint256', + }, + ], + name: 'getInterestRate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReservePoolBps', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + BigBangABI: [ + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'poolInfo', + outputs: [ + { + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastRewardBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'singlePerBlock', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/single-finance/index.js b/src/adaptors/single-finance/index.js new file mode 100644 index 0000000000..2b4b7185f1 --- /dev/null +++ b/src/adaptors/single-finance/index.js @@ -0,0 +1,376 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const superagent = require('superagent'); + +const { + VaultABI, + ConfigurableInterestVaultConfigABI, + Erc20ABI, + BigBangABI, +} = require('./abis'); + +const project = 'single-finance'; + +const poolApiEndpoint = 'https://api.singlefinance.io/api/vaults'; +const lyfPoolApiEndpoint = 'https://api.singlefinance.io/api/info/farms' + +const singleToken = { + cronos: '0x0804702a4E749d39A35FDe73d1DF0B1f1D6b8347'.toLowerCase(), + fantom: '0x8cc97b50fe87f31770bcdcd6bc8603bc1558380b'.toLowerCase(), + arbitrum: '0x55853edc67aa68ec2e3903ac00f2bc5bf2ca8db0'.toLowerCase(), +}; + +const singleVaultAddress = { + cronos: '0x3710000815c45d715af84f35919a6f2a901b7548'.toLowerCase(), + fantom: '0xE87158503f831244E67af248E02bb1cc1CEfA841'.toLowerCase(), + arbitrum: '0xdd19f71FacE7E136035e6dc6da79FBE9E9c62D72'.toLowerCase(), +}; + +const bigBang = { + cronos: '0x1Ae8a7C582C3f9F9117d5Bc2863F2eD16cBd29cb'.toLowerCase(), + fantom: '0x7C770a787B430582AbccE88886e9E4E24A457A61'.toLowerCase(), + arbitrum: '0x490Eba9a1F0d4A2311B6c158eFAbdd259Af5030a'.toLowerCase(), +}; + +const blocksPerYear = (secondsPerBlock) => + (60 / secondsPerBlock) * 60 * 24 * 365; + +const blocksPerYears = { + cronos: blocksPerYear(5.8), + fantom: blocksPerYear(1.2), + arbitrum: blocksPerYear(0.25), +}; + +const chainMapping = { + cronos: { + id: 25 + }, + fantom: { + id: 250 + }, + arbitrum: { + id: 42161 + } +} + +const dexMapping = { + vvs: { + name: "VVS Finance" + }, + mmf: { + name: "MMFinance" + }, + spooky: { + name: "SpookySwap" + }, + sushi: { + name: "SushiSwap" + }, + camelot: { + name: "Camelot" + } +} + +const availablePools = { + cronos: ['CRO', 'USDC', 'VVS', 'MMF', 'USDT', 'VERSA', 'ARGO', 'bCRO', 'VNO'], + fantom: ['FTM', 'USDC', 'fUSDT'], + arbitrum: ['WETH', 'USDC', 'USDT', 'MAGIC', 'DPX', 'RDPX'], + // cronos: ['CRO',], + // fantom:[], +}; + +const getApyBase = ( + borrowingInterest, + totalBorrow, + totalSupply, + lendingPerformanceFee +) => { + return ( + borrowingInterest * + (totalBorrow / totalSupply) * + (1 - lendingPerformanceFee) * + 100 + ); +}; + +const getApyReward = ( + stakedTvl, + allocPoint, + totalAllocPoint, + singlePerBlock, + singlePrice, + blocksPerYear +) => { + return ( + (((allocPoint / totalAllocPoint) * singlePerBlock * singlePrice) / + stakedTvl) * + blocksPerYear * + 100 + ); +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const priceItems = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return priceItems; +}; + +const secondToYearlyInterestRate = (rate) => + (Number(rate) * (60 * 60 * 24 * 365)) / 1000000000000000000; + +const getPriceInUsd = (item, decimal, price) => { + return (Number(item) / 10 ** Number(decimal)) * price; +}; + +const multiCallOutput = async (abi, calls, chain) => { + const res = await sdk.api.abi.multiCall({ + abi: abi, + calls: calls, + chain: chain, + }); + + return res.output.map(({ output }) => output); +}; + +const getLendingApy = async (chain) => { + const chainId = chainMapping[chain]?.id + const allPools = await utils.getData( + `${poolApiEndpoint}?chainid=${chainId}` + ); + + const pools = allPools.data.filter((pool) => { + const symbol = pool.token.symbol; + return availablePools[chain].includes(symbol); + }); + + const singlePrice = await getPrices([chain + ':' + singleToken[chain]]); + + const totalSupply = await multiCallOutput( + VaultABI.find(({ name }) => name === 'totalToken'), + pools.map((pool) => ({ target: pool.address })), + chain + ); + + const totalSupplyToken = await multiCallOutput( + VaultABI.find(({ name }) => name === 'totalSupply'), + pools.map((pool) => ({ target: pool.address })), + chain + ); + + const totalBorrowed = await multiCallOutput( + VaultABI.find(({ name }) => name === 'vaultDebtVal'), + pools.map((pool) => ({ target: pool.address })), + chain + ); + + const decimals = await multiCallOutput( + VaultABI.find(({ name }) => name === 'decimals'), + pools.map((pool) => ({ target: pool.address })), + chain + ); + + const configs = await multiCallOutput( + VaultABI.find(({ name }) => name === 'config'), + pools.map((pool) => ({ target: pool.address })), + chain + ); + + const totalToken = await multiCallOutput( + Erc20ABI.find(({ name }) => name === 'balanceOf'), + pools.map((pool) => ({ + target: pool.token.id, + params: [pool.address], + })), + chain + ); + + const interestRate = await multiCallOutput( + ConfigurableInterestVaultConfigABI.find( + ({ name }) => name === 'getInterestRate' + ), + configs.map((config, i) => { + return { + target: config, + params: [totalBorrowed[i].toString(), totalToken[i].toString()], + }; + }), + chain + ); + const totalIbStaked = await multiCallOutput( + VaultABI.find(({ name }) => name === 'balanceOf'), + configs.map((config, i) => { + return { + target: pools[i].address, + params: bigBang[chain], + }; + }), + chain + ); + + const lendingPerformanceFeeBps = await multiCallOutput( + ConfigurableInterestVaultConfigABI.find( + ({ name }) => name === 'getReservePoolBps' + ), + configs.map((config, i) => { + return { + target: config, + }; + }), + chain + ); + + const allocPoint = await multiCallOutput( + BigBangABI.find(({ name }) => name === 'poolInfo'), + pools.map((pool) => ({ + params: [pool.fairLaunchPoolId], + target: bigBang[chain], + })), + chain + ); + + const totalAllocPoint = await multiCallOutput( + BigBangABI.find(({ name }) => name === 'totalAllocPoint'), + [{ target: bigBang[chain] }], + chain + ); + + const singlePerBlock = await multiCallOutput( + BigBangABI.find(({ name }) => name === 'singlePerBlock'), + [{ target: bigBang[chain] }], + chain + ); + + const singleVaultDeimals = await multiCallOutput( + VaultABI.find(({ name }) => name === 'decimals'), + [{ target: singleVaultAddress[chain] }], + chain + ); + + const prices = await getPrices( + pools.map((pool) => { + return chain + ':' + pool.token.id; + }) + ); + + const res = pools.map((pool, idx) => { + const tokenAddress = pool.token.id.toLowerCase(); + const totalSupplyUsd = getPriceInUsd( + totalSupply[idx], + decimals[idx], + prices[tokenAddress] + ); + const totalBorrowUsd = getPriceInUsd( + totalBorrowed[idx], + decimals[idx], + prices[tokenAddress] + ); + const lendingPerformanceFee = Number(lendingPerformanceFeeBps[idx]) / 10000; + + const apyBase = getApyBase( + secondToYearlyInterestRate(interestRate[idx]), + totalBorrowed[idx], + totalSupply[idx], + lendingPerformanceFee + ); + + let conversionRate = 1; + + if (totalSupplyToken[idx] && Number(totalSupplyToken[idx]) > 0) { + conversionRate = totalSupply[idx] / totalSupplyToken[idx]; + } + + const stakedTvl = + (Number(totalIbStaked[idx]) / Math.pow(10, decimals[idx])) * + prices[tokenAddress] * + conversionRate; + + const apyReward = getApyReward( + stakedTvl, + allocPoint[idx].allocPoint, + totalAllocPoint[0], + singlePerBlock[0] / Math.pow(10, singleVaultDeimals[0]), + singlePrice[singleToken[chain]], + blocksPerYears[chain] + ); + + return { + pool: pool.address, + chain: utils.formatChain(chain), + project, + symbol: pool.token.symbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBaseBorrow: secondToYearlyInterestRate(interestRate[idx]) * 100, + totalSupplyUsd, + totalBorrowUsd, + apyBase, + apyReward: chain === 'cronos' ? apyReward : 0, + underlyingTokens: [pool.token.id], + rewardTokens: chain === 'cronos' ? [singleToken[chain]] : [], + ltv: 0, + }; + }); + return res; +}; + +const getLYFApy = async (chain, dex) => { + const chainId = chainMapping[chain]?.id + const allPools = (await utils.getData( + `${lyfPoolApiEndpoint}?dex=${dex}&chainid=${chainId}` + )).data.farms; + + return allPools.map((raw) => ({ + pool: `${raw.lpToken.address[chainId]}-${dex}-farming-${chain}`, + chain: utils.formatChain(chain), + project, + symbol: `${raw.token0.symbol}-${raw.token1.symbol}`, + poolMeta: dexMapping[dex].name, + tvlUsd: raw.tvlInUSD, + apyBase: utils.aprToApy((raw.tradingFeeApr + raw.autoCompoundDexYieldPercent) * (1 - raw.perfFee) * 100 ) + raw.manualHarvestDexYieldPercent * (1 - raw.perfFee) * 100, + apyReward: 0, + underlyingTokens: [ + raw.token0.address[chainId], + raw.token1.address[chainId] + ] + })) +} + +const apy = async () => { + const cronosPools = await getLendingApy('cronos'); + const fantomPools = await getLendingApy('fantom'); + const arbitrumPools = await getLendingApy('arbitrum'); + const cronosVvsPools = await getLYFApy('cronos', 'vvs'); + const cronosMmfPools = await getLYFApy('cronos', 'mmf'); + const fantomSpookyPools = await getLYFApy('fantom', 'spooky'); + const arbitrumSushiPools = await getLYFApy('arbitrum', 'sushi'); + const arbitrumCamelotPools = await getLYFApy('arbitrum', 'camelot'); + return [ + ...cronosPools, + ...fantomPools, + ...arbitrumPools, + ...cronosVvsPools, + ...cronosMmfPools, + ...fantomSpookyPools, + ...arbitrumSushiPools, + ...arbitrumCamelotPools, + ].filter(i => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.singlefinance.io/', +}; diff --git a/src/adaptors/singularity-finance/index.js b/src/adaptors/singularity-finance/index.js new file mode 100644 index 0000000000..1244eea5e0 --- /dev/null +++ b/src/adaptors/singularity-finance/index.js @@ -0,0 +1,143 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const baseVaultRegistry = "0xe260c97949bB01E49c0af64a3525458197851657"; +const USDC = { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6, symbol: "USDC" }; + +async function getApy() { + const numberOfVaults = (await sdk.api.abi.call({ + abi: 'function nrOfVaults() view returns (uint256)', + target: baseVaultRegistry, + chain: "base" + })).output; + + const batchSize = 100; + + let results = []; + + for (let i = 0; i < numberOfVaults; i += batchSize) { + const dynaVaults = (await sdk.api.abi.call({ + abi: 'function getVaults(uint256 offset, uint256 size) view returns (tuple(address vault, uint8 vaultType, bool active)[] memory)', + target: baseVaultRegistry, + chain: "base", + params: [ + BigInt(i), + BigInt(batchSize), + ], + })).output; + + // vault type: 3 = beta, 4 = production + const activeVaultsInProdOrBeta = dynaVaults.filter(vault => vault.active && (vault.vaultType == 3 || vault.vaultType == 4)); + const vaultInfos = await multiGetERC4626Infos(activeVaultsInProdOrBeta.map(vault => vault.vault), "base"); + + const subResults = await Promise.all(activeVaultsInProdOrBeta.map(async (vault, index) => { + const referenceAssetAddress = (await sdk.api.abi.call({ + abi: 'function referenceAsset() view returns (address)', + target: vault.vault, + chain: "base", + })).output; + + const referenceAssetSymbol = (await sdk.api.abi.call({ + abi: 'function symbol() view returns (string)', + target: referenceAssetAddress, + chain: "base", + })).output; + + const { tvl, apyBase, ...rest } = vaultInfos[index]; + + const tvlUsd = referenceAssetAddress == USDC.address ? tvl : (await sdk.api.abi.call({ + abi: 'function tokenValueInQuoteAsset(address base, uint256 amount, address quote) view returns (uint256 value)', + target: vault.vault, + chain: "base", + params: [ + referenceAssetAddress, + tvl, + USDC.address, + ], + })).output; + + return { + pool: vault.vault, + chain: "base", + project: 'singularity-finance', + symbol: utils.formatSymbol(referenceAssetSymbol), + tvlUsd: tvlUsd / 10 ** USDC.decimals, + apyBase, + url: `https://singularityfinance.ai/vaults/${vault.vault}:8453`, + }; + })); + + if (subResults != []) results.push(...subResults); + } + + return results; +} + +// multicall version of getERC4625Info found in utils +async function multiGetERC4626Infos( + addresses, + chain, + timestamp = Math.floor(Date.now() / 1e3), + { + assetUnit = '100000000000000000', + totalAssetsAbi = 'uint:totalAssets', + convertToAssetsAbi = 'function convertToAssets(uint256 shares) external view returns (uint256)', + } = {} +) { + const DAY = 24 * 3600; + + const [blockNow, blockYesterday] = await Promise.all( + [timestamp, timestamp - DAY].map((time) => + axios + .get(`https://coins.llama.fi/block/${chain}/${time}`) + .then((r) => r.data.height) + ) + ); + + const allTotalAssets = (await sdk.api.abi.multiCall({ + calls: addresses.map(a => ({ + target: a, + })), + block: blockNow, + abi: totalAssetsAbi, + chain + })).output.map(result => result.output); + + const allPriceNow = (await sdk.api.abi.multiCall({ + calls: addresses.map(a => ({ + target: a, + params: [assetUnit], + })), + block: blockNow, + abi: convertToAssetsAbi, + chain + })).output.map(result => result.output); + + const allPriceYesterday = (await sdk.api.abi.multiCall({ + calls: addresses.map(a => ({ + target: a, + params: [assetUnit], + })), + block: blockYesterday, + abi: convertToAssetsAbi, + chain + })).output.map(result => result.output); + + const apy = (priceNow, priceYesterday) => (priceNow / priceYesterday) ** 365 * 100 - 100; + + return await Promise.all( + addresses.map((address, index) => ({ + pool: address, + chain, + tvl: allTotalAssets[index], + apyBase: apy(allPriceNow[index], allPriceYesterday[index]), + })) + ); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; + diff --git a/src/adaptors/sir/index.js b/src/adaptors/sir/index.js new file mode 100644 index 0000000000..e71e9f278b --- /dev/null +++ b/src/adaptors/sir/index.js @@ -0,0 +1,422 @@ +const axios = require("axios"); +const utils = require("../utils"); +const { ethers } = require("ethers"); + +const ETHEREUM_SUBGRAPH_URL = + "https://api.goldsky.com/api/public/project_cmfgjrwjojbpm01x2dfgte8tr/subgraphs/sir-ethereum-subgraph-1/2.0.3/gn"; +const HYPER_SUBGRAPH_URL = + "https://api.goldsky.com/api/public/project_cmfgjrwjojbpm01x2dfgte8tr/subgraphs/sir-hyperevm-subgraph-1/2.0.3/gn"; + +const ETHEREUM_SIR = + "0x4Da4fb565Dcd5D5C5dB495205c109bA983A8ABa2".toLowerCase(); +const HYPER_SIR = + "0xA06D0c5a8ADb7134903CA13D1FC0641731E2B766".toLowerCase(); + +// SIR token decimals +const SIR_DECIMALS = 12; + +// 30 day lookback for fee compounding +const DAYS_LOOKBACK = 30; +const SECONDS_IN_DAY = 24 * 60 * 60; +const LOOKBACK_SECONDS = DAYS_LOOKBACK * SECONDS_IN_DAY; +const SECONDS_IN_YEAR = 365 * SECONDS_IN_DAY; + +// Uniswap V3 / HyperSwap V3 pool ABI (minimal for slot0) +const POOL_ABI = [ + "function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)", + "function token0() external view returns (address)", + "function token1() external view returns (address)", +]; + +// Uniswap V3 Factory ABI for getPool +const FACTORY_ABI = [ + "function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool)", +]; + +// Two chains, two subgraphs +const CHAIN_CONFIGS = [ + { + key: "ethereum", + priceKey: "ethereum", // DefiLlama price chain slug + chain: "Ethereum", + subgraphUrl: ETHEREUM_SUBGRAPH_URL, + sirAddress: ETHEREUM_SIR, + urlPrefix: "https://app.sir.trading/liquidity?vault=", + // DEX config for SIR price + rpcUrl: "https://eth.llamarpc.com", + dexFactory: "0x1F98431c8aD98523631AE4a59f267346ea31F984", // Uniswap V3 Factory + nativeWrapped: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH + nativeDecimals: 18, + dexFeeTier: 10000, // 1% fee tier + }, + { + key: "hyperliquid-l1", + priceKey: "Hyperliquid", // DefiLlama price chain slug + chain: "Hyperliquid L1", + subgraphUrl: HYPER_SUBGRAPH_URL, + sirAddress: HYPER_SIR, + urlPrefix: "https://hype.sir.trading/liquidity?vault=", + // DEX config for SIR price + rpcUrl: "https://rpc.hyperliquid.xyz/evm", + dexFactory: "0xB1c0fa0B789320044A6F623cFe5eBda9562602E3", // HyperSwap V3 Factory + nativeWrapped: "0x5555555555555555555555555555555555555555", // WHYPE + nativeDecimals: 18, + dexFeeTier: 10000, // 1% fee tier + }, +]; + +// Helpers +async function querySubgraph(subgraphUrl, query, variables = {}) { + const res = await axios.post(subgraphUrl, { + query, + variables, + }); + if (res.data.errors) { + throw new Error(JSON.stringify(res.data.errors)); + } + return res.data.data; +} + +/** + * Fetch SIR price in native token (ETH/HYPE) from DEX (Uniswap V3 / HyperSwap V3) + * Returns SIR price in native token units + */ +async function fetchSirPriceFromDex(chainCfg) { + try { + const provider = new ethers.providers.JsonRpcProvider(chainCfg.rpcUrl); + + const factory = new ethers.Contract( + chainCfg.dexFactory, + FACTORY_ABI, + provider + ); + + // Get pool address for SIR/Native pair + const poolAddress = await factory.getPool( + chainCfg.sirAddress, + chainCfg.nativeWrapped, + chainCfg.dexFeeTier + ); + + if ( + !poolAddress || + poolAddress === "0x0000000000000000000000000000000000000000" + ) { + console.log(`No DEX pool found for SIR on ${chainCfg.chain}`); + return 0; + } + + const pool = new ethers.Contract(poolAddress, POOL_ABI, provider); + + // Get token order and slot0 + const [token0, slot0] = await Promise.all([pool.token0(), pool.slot0()]); + + const sqrtPriceX96 = slot0.sqrtPriceX96; + const Q96 = ethers.BigNumber.from(2).pow(96); + + // Calculate price from sqrtPriceX96 + // price = (sqrtPriceX96 / 2^96)^2 + // This gives token1/token0 ratio in raw terms + const sqrtPriceX96Num = Number(sqrtPriceX96.toString()); + const Q96Num = Number(Q96.toString()); + const rawPrice = Math.pow(sqrtPriceX96Num / Q96Num, 2); + + const sirIsToken0 = + token0.toLowerCase() === chainCfg.sirAddress.toLowerCase(); + + // Adjust for decimals: price * 10^(token0Decimals - token1Decimals) + let nativePerSir; + if (sirIsToken0) { + // rawPrice = native/SIR in raw terms + // Adjust: native per SIR = rawPrice * 10^(SIR_DECIMALS - nativeDecimals) + nativePerSir = rawPrice * Math.pow(10, SIR_DECIMALS - chainCfg.nativeDecimals); + } else { + // rawPrice = SIR/native in raw terms + // We need native/SIR, so invert: 1/rawPrice + // Adjust: native per SIR = (1/rawPrice) * 10^(SIR_DECIMALS - nativeDecimals) + nativePerSir = (1 / rawPrice) * Math.pow(10, SIR_DECIMALS - chainCfg.nativeDecimals); + } + + return nativePerSir; + } catch (error) { + console.log(`Error fetching SIR price from DEX on ${chainCfg.chain}:`, error.message); + return 0; + } +} + +/** + * Fetch all active vaults for a given chain. + * Vault.exists + * Vault.collateralToken { id, symbol, decimals } + * Vault.lockedLiquidity + * Vault.teaSupply + * Vault.reserveLPers + * Vault.rate + */ +async function fetchVaultsForChain(chainCfg) { + const query = ` + query getVaults { + vaults(where: { exists: true }) { + id + collateralToken { + id + symbol + decimals + } + debtToken { + symbol + } + leverageTier + lockedLiquidity + teaSupply + reserveLPers + rate + } + } + `; + + const { vaults } = await querySubgraph(chainCfg.subgraphUrl, query); + return vaults || []; +} + +/** + * Fetch fee events for a vault in the last 1 day for a given chain. + */ +async function fetchFeesForVault(chainCfg, vaultId, timestampThreshold) { + const query = ` + query getVaultFees($vaultId: Bytes!, $timestampThreshold: BigInt!) { + fees( + where: { + vaultId: $vaultId + timestamp_gte: $timestampThreshold + } + ) { + lpApy + timestamp + } + } + `; + + const { fees } = await querySubgraph( + chainCfg.subgraphUrl, + query, + { + vaultId, + timestampThreshold: String(timestampThreshold), + } + ); + + return fees || []; +} + +/** + * Fees APY: compound lpApy over last 1 day and annualize. + */ +function computeFeesApy(fees) { + if (!fees || fees.length === 0) { + return 0; + } + + const compoundReturn = fees.reduce((prod, fee) => { + const lpApy = Number(fee.lpApy) || 0; + return prod * (1 + lpApy); + }, 1); + + if (compoundReturn <= 0) { + return 0; + } + + const annualized = + Math.pow(compoundReturn, 365 / DAYS_LOOKBACK) - 1; + + return annualized * 100; +} + +/** + * Compute SIR rewards APY from vault fields. + * - rate is scaled by 1e12 and per second + * - reserveLPers and collateralToken.decimals give LP collateral + * - POL is excluded via externalLpRatio + * The SIR address is chain specific and passed in. + */ +function computeSirRewardsApy(vault, sirPriceInCollateral, sirAddress) { + const ratePerSecond = Number(vault.rate || 0) / 1e12; + if (!ratePerSecond) return 0; + + const annualSirRewards = ratePerSecond * SECONDS_IN_YEAR; + + const collateralDecimals = Number(vault.collateralToken.decimals); + + const totalLpCollateral = + Number(vault.reserveLPers || 0) / Math.pow(10, collateralDecimals); + + const teaSupply = Number(vault.teaSupply || 0); + const lockedLiquidity = Number(vault.lockedLiquidity || 0); + + let externalLpRatio = 0; + if (teaSupply > 0) { + externalLpRatio = Math.max( + 0, + (teaSupply - lockedLiquidity) / teaSupply + ); + } + + const vaultCollateral = totalLpCollateral * externalLpRatio; + if (vaultCollateral <= 0) return 0; + + let annualRewardsValue; + const collateralIsSir = + vault.collateralToken.id.toLowerCase() === sirAddress; + + if (collateralIsSir) { + annualRewardsValue = annualSirRewards; + } else { + annualRewardsValue = annualSirRewards * sirPriceInCollateral; + } + + if (!Number.isFinite(annualRewardsValue) || annualRewardsValue <= 0) { + return 0; + } + + return (annualRewardsValue / vaultCollateral) * 100; +} + +/** + * TVL in USD: LP collateral * collateral price in USD. + */ +function computeTvlUsd(vault, collateralPriceUsd) { + if (!collateralPriceUsd || collateralPriceUsd <= 0) return 0; + + const collateralDecimals = Number(vault.collateralToken.decimals); + + const vaultCollateral = + Number(vault.reserveLPers || 0) / Math.pow(10, collateralDecimals); + + if (vaultCollateral <= 0) return 0; + + return vaultCollateral * collateralPriceUsd; +} + +/** + * Build one price map across both chains. + */ +async function fetchPrices(allVaults) { + const coins = new Set(); + + // collateral tokens + for (const { chainCfg, vault } of allVaults) { + const token = vault.collateralToken.id; + coins.add(`${chainCfg.priceKey}:${token.toLowerCase()}`); + } + + // Native wrapped tokens for SIR price conversion + for (const chainCfg of CHAIN_CONFIGS) { + coins.add(`${chainCfg.priceKey}:${chainCfg.nativeWrapped.toLowerCase()}`); + } + + const coinList = Array.from(coins); + if (coinList.length === 0) return {}; + + const prices = await utils.getPrices(coinList); + return prices; +} + +// Main adaptor function + +async function apy() { + const now = Math.floor(Date.now() / 1000); + const timestampThreshold = now - LOOKBACK_SECONDS; + + // Collect vaults from both chains with their chain config attached + const allVaults = []; + for (const chainCfg of CHAIN_CONFIGS) { + const vaults = await fetchVaultsForChain(chainCfg); + for (const vault of vaults) { + allVaults.push({ chainCfg, vault }); + } + } + + if (!allVaults.length) return []; + + // Fetch prices and SIR DEX prices in parallel + const [prices, ...sirDexPrices] = await Promise.all([ + fetchPrices(allVaults), + ...CHAIN_CONFIGS.map((cfg) => fetchSirPriceFromDex(cfg)), + ]); + + // Build SIR price map per chain (in native token) + const sirPriceInNative = {}; + CHAIN_CONFIGS.forEach((cfg, idx) => { + sirPriceInNative[cfg.key] = sirDexPrices[idx]; + }); + + const pools = []; + + for (const { chainCfg, vault } of allVaults) { + const chainKey = chainCfg.key; + const chainName = chainCfg.chain; + const sirAddress = chainCfg.sirAddress; + + const collateralAddress = vault.collateralToken.id.toLowerCase(); + + const collateralPriceUsd = prices.pricesByAddress[collateralAddress] || 0; + + // Get native token price in USD + const nativePriceUsd = + prices.pricesByAddress[chainCfg.nativeWrapped.toLowerCase()] || 0; + + // Calculate SIR price in USD from DEX price + const sirInNative = sirPriceInNative[chainKey] || 0; + const sirPriceUsd = sirInNative * nativePriceUsd; + + const tvlUsd = computeTvlUsd(vault, collateralPriceUsd); + if (!Number.isFinite(tvlUsd) || tvlUsd <= 0) { + continue; + } + + const fees = await fetchFeesForVault( + chainCfg, + vault.id, + timestampThreshold + ); + const feesApy = computeFeesApy(fees); + + const sirPriceInCollateral = + collateralPriceUsd > 0 && sirPriceUsd > 0 + ? sirPriceUsd / collateralPriceUsd + : 0; + + const sirRewardsApy = computeSirRewardsApy( + vault, + sirPriceInCollateral, + sirAddress + ); + + const vaultIdDecimal = parseInt(vault.id, 16); + const poolId = `${sirAddress}-${vaultIdDecimal}-${chainKey}`; + const symbol = `${utils.formatSymbol(vault.collateralToken.symbol || "UNKNOWN")}-${utils.formatSymbol(vault.debtToken.symbol || "UNKNOWN")}`; + const poolMeta = `Leverage ratio: ${1+2**(Number(vault.leverageTier))}`; + const url = `${chainCfg.urlPrefix}${vault.id}`; + + pools.push({ + pool: poolId, + chain: chainName, // "Ethereum" or "Hyperliquid L1" + project: "sir", + symbol, + tvlUsd, + apyBase: feesApy || 0, + apyReward: sirRewardsApy || 0, + rewardTokens: [sirAddress], + underlyingTokens: [collateralAddress], + poolMeta, + url, + }); + } + + return pools; +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/sithswap/index.js b/src/adaptors/sithswap/index.js new file mode 100644 index 0000000000..28db6dd4ec --- /dev/null +++ b/src/adaptors/sithswap/index.js @@ -0,0 +1,71 @@ +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const API_URL = 'https://api.sithswap.info/'; +const FEE_PRECISION = 1000000; + +const pairsDataQuery = gql` + { + pairs(first: 10, orderBy: totalValueLockedUSD, orderDirection: desc, where: {totalValueLockedUSD_gt: 10000}) { + id + totalValueLockedUSD + feeTier + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const dayDataQuery = gql` + { + pairdaydatas(first: 1, skip:1, orderBy: date orderDirection: desc, where:{pair_in: ""}) { + id + dailyVolumeUSD + } + } +`; +const getApy = async () => { + // APR is retrieved using our api, tvl pairs etc trough subgraph + const { pairs: pairs } = await request(API_URL, pairsDataQuery,); + + const poolInfo = await Promise.all( + pairs.map(async (pool) => { + const underlyingTokens = [pool.token0.id, pool.token1.id]; + const symbol = utils.formatSymbol(`${pool.token0.symbol}-${pool.token1.symbol}`) + const { pairdaydatas: pairDayData } = await request(API_URL, dayDataQuery.replace('', pool.id),); + const dailyFee = pairDayData[0] ? pairDayData[0].dailyVolumeUSD * pool.feeTier / FEE_PRECISION : 0 + const apy = (dailyFee * 36500) / pool.totalValueLockedUSD; + const url = `https://app.sithswap.com/add/${pool.id}`; + return { + pool: pool.id, + chain: 'starknet', + project: 'sithswap', + symbol, + tvlUsd: Number(pool.totalValueLockedUSD), + apyBase: apy, + underlyingTokens, + url + }; + }) + ); + return poolInfo; + +}; + +async function main() { + let data = await getApy(); + return data; +} + +module.exports = { + timetravel: false, + apy: main, +}; + diff --git a/src/adaptors/sky-lending/abiSUSDS.json b/src/adaptors/sky-lending/abiSUSDS.json new file mode 100644 index 0000000000..73880596e2 --- /dev/null +++ b/src/adaptors/sky-lending/abiSUSDS.json @@ -0,0 +1,720 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "usdsJoin_", "type": "address" }, + { "internalType": "address", "name": "vow_", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "implementation", "type": "address" } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { "inputs": [], "name": "UUPSUnauthorizedCallContext", "type": "error" }, + { + "inputs": [ + { "internalType": "bytes32", "name": "slot", "type": "bytes32" } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Deny", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "chi", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "diff", + "type": "uint256" + } + ], + "name": "Drip", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "name": "File", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Referral", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "usr", + "type": "address" + } + ], + "name": "Rely", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chi", + "outputs": [{ "internalType": "uint192", "name": "", "type": "uint192" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "convertToAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "convertToShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "usr", "type": "address" }], + "name": "deny", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "uint16", "name": "referral", "type": "uint16" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "drip", + "outputs": [ + { "internalType": "uint256", "name": "nChi", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "what", "type": "bytes32" }, + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "name": "file", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getImplementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "uint16", "name": "referral", "type": "uint16" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "bytes", "name": "signature", "type": "bytes" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "redeem", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "usr", "type": "address" }], + "name": "rely", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rho", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ssr", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "usds", + "outputs": [ + { "internalType": "contract UsdsLike", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "usdsJoin", + "outputs": [ + { "internalType": "contract UsdsJoinLike", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vat", + "outputs": [ + { "internalType": "contract VatLike", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vow", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "wards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/sky-lending/index.js b/src/adaptors/sky-lending/index.js new file mode 100644 index 0000000000..ad37e45f46 --- /dev/null +++ b/src/adaptors/sky-lending/index.js @@ -0,0 +1,466 @@ +const ethers = require('ethers'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abiSUSDS = require('./abiSUSDS.json'); + +const HOUR = 60 * 60; +const DAY = 24 * HOUR; +const SECONDS_PER_YEAR = 365 * DAY; +const RAY_PRECISION = 27; +const RAY = new BigNumber(10).pow(RAY_PRECISION); + +const MCD_JUG = { + address: '0x19c0976f590D67707E62397C87829d896Dc0f1F1', + abis: { + ilks: { + constant: true, + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'ilks', + outputs: [ + { + internalType: 'uint256', + name: 'duty', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'rho', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const CDP_MANAGER = { + address: '0x5ef30b9986345249bc32d8928B7ee64DE9435E39', + abis: { + urns: { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'urns', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ilks: { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'ilks', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + owns: { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'owns', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + cdpi: { + constant: true, + inputs: [], + name: 'cdpi', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }, +}; +const ILK_REGISTRY = { + address: '0x5a464C28D19848f44199D003BeF5ecc87d090F87', + abis: { + gem: { + inputs: [{ internalType: 'bytes32', name: 'ilk', type: 'bytes32' }], + name: 'gem', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ilkData: { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'ilkData', + outputs: [ + { + internalType: 'uint96', + name: 'pos', + type: 'uint96', + }, + { + internalType: 'address', + name: 'join', + type: 'address', + }, + { + internalType: 'address', + name: 'gem', + type: 'address', + }, + { + internalType: 'uint8', + name: 'dec', + type: 'uint8', + }, + { + internalType: 'uint96', + name: 'class', + type: 'uint96', + }, + { + internalType: 'address', + name: 'pip', + type: 'address', + }, + { + internalType: 'address', + name: 'xlip', + type: 'address', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + list: { + inputs: [], + name: 'list', + outputs: [{ internalType: 'bytes32[]', name: '', type: 'bytes32[]' }], + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const MCD_VAT = { + address: '0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B', + abis: { + ilks: { + constant: true, + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'ilks', + outputs: [ + { internalType: 'uint256', name: 'Art', type: 'uint256' }, + { internalType: 'uint256', name: 'rate', type: 'uint256' }, + { internalType: 'uint256', name: 'spot', type: 'uint256' }, + { internalType: 'uint256', name: 'line', type: 'uint256' }, + { internalType: 'uint256', name: 'dust', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }, +}; + +const MCD_SPOT = { + address: '0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3', + abis: { + ilks: { + constant: true, + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'ilks', + outputs: [ + { internalType: 'contract PipLike', name: 'pip', type: 'address' }, + { internalType: 'uint256', name: 'mat', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }, +}; + +MCD_POT = { + address: '0x197e90f9fad81970ba7976f33cbd77088e5d7cf7', + abis: { + Pie: { + constant: true, + inputs: [], + name: 'Pie', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + dsr: { + constant: true, + inputs: [], + name: 'dsr', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + chi: { + constant: true, + inputs: [], + name: 'chi', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }, +}; + +async function dsr() { + const [Pie, chi, dsr] = await Promise.all( + ['Pie', 'chi', 'dsr'].map( + async (name) => + ( + await sdk.api.abi.call({ + target: MCD_POT.address, + abi: MCD_POT.abis[name], + }) + ).output + ) + ); + const tvlUsd = BigNumber(Pie).times(chi).div(1e18).div(RAY); // check against https://makerburn.com/#/ + const apy = + (BigNumber(dsr).div(RAY).toNumber() ** (60 * 60 * 24 * 365) - 1) * 100; + + return { + pool: MCD_POT.address, + project: 'sky-lending', + symbol: 'DAI', + chain: 'ethereum', + poolMeta: 'DSR', + apy, + tvlUsd: tvlUsd.toNumber(), + }; +} + +function onlyUnique(value, index, self) { + return self.indexOf(value) === index; +} + +const getPrices = async (addresses) => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const main = async () => { + const dsrPool = dsr(); + const ilkIds = ( + await sdk.api.abi.call({ + target: ILK_REGISTRY.address, + abi: ILK_REGISTRY.abis.list, + chain: 'ethereum', + }) + ).output; + const ilkDatas = ( + await sdk.api.abi.multiCall({ + calls: ilkIds.map((ilkId) => ({ + target: ILK_REGISTRY.address, + params: [ilkId], + })), + abi: ILK_REGISTRY.abis.ilkData, + requery: true, + }) + ).output.map((x) => x.output); + const joins = ilkDatas.map((e) => e['1']); + const gems = ilkDatas.map((e) => e.gem); + const symbols = ilkDatas.map((e) => e.symbol); + const decimals = ilkDatas.map((e) => e['3']); + + const ilksDatas = ( + await sdk.api.abi.multiCall({ + calls: ilkIds.map((ilkId) => ({ + target: MCD_JUG.address, + params: [ilkId], + })), + abi: MCD_JUG.abis.ilks, + requery: true, + }) + ).output.map((x) => x.output); + + const ilks = ( + await sdk.api.abi.multiCall({ + calls: ilkIds.map((ilkId) => ({ + target: MCD_VAT.address, + params: [ilkId], + })), + abi: MCD_VAT.abis.ilks, + requery: true, + }) + ).output.map((x) => x.output); + const spots = ( + await sdk.api.abi.multiCall({ + calls: ilkIds.map((ilkId) => ({ + target: MCD_SPOT.address, + params: [ilkId], + })), + abi: MCD_SPOT.abis.ilks, + requery: true, + }) + ).output.map((x) => x.output); + const rate = ilksDatas.map((e) => e.duty); + const tokenBalances = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: gems.map((address, index) => { + return { target: address, params: [joins[index]] }; + }), + chain: 'ethereum', + requery: false, + permitFailure: true, + }) + ).output.map((e) => e.output); + + const mapPrice = gems.map((address) => `ethereum:${address}`); + const prices = await getPrices(mapPrice); + const blackList = [ + '0x3435353434383264343130303030303030303030303030303030303030303030', + '0x3432343135343264343130303030303030303030303030303030303030303030', + '0x3078353734323534343332643433303030303030303030303030303030303030', + ]; + + return joins + .map((_, index) => { + const normalizRate = new BigNumber(rate[index]).dividedBy(RAY); + BigNumber.config({ POW_PRECISION: 100 }); + const stabilityFee = normalizRate.pow(SECONDS_PER_YEAR).minus(1); + const art = new BigNumber(ilks[index].Art).div(1e18); + const debtScalingFactor = new BigNumber(ilks[index].rate).div(1e27); + const totalBorrowUsd = debtScalingFactor.multipliedBy(art); + const debtCeilingUsd = new BigNumber(ilks[index].line).div(1e45); + const tvlUsd = new BigNumber(tokenBalances[index]) + .dividedBy(new BigNumber(10).pow(decimals[index])) + .multipliedBy(prices[gems[index].toLowerCase()]) + .toNumber(); + const spot = spots[index]; + const liquidationRatio = new BigNumber(spot.mat).div(1e27); + return { + pool: joins[index], + project: 'sky-lending', + symbol: symbols[index], + chain: 'ethereum', + poolMeta: !blackList.includes(ilkIds[index]) + ? ethers.utils.parseBytes32String(ilkIds[index]) + : '', + apy: 0, + tvlUsd: tvlUsd, + // borrow fields + apyBaseBorrow: stabilityFee.toNumber() * 100, + totalSupplyUsd: tvlUsd, + totalBorrowUsd: totalBorrowUsd.toNumber(), + debtCeilingUsd: debtCeilingUsd.toNumber(), + mintedCoin: 'DAI', + ltv: 1 / Number(liquidationRatio.toNumber()), + }; + }) + .concat([await dsrPool]) + .filter((e) => e.tvlUsd !== NaN) + .filter((e) => e.tvlUsd !== 0) + .filter((e) => e.tvlUsd); +}; + +const susdsAPY = async () => { + const USDS = '0xdC035D45d973E3EC169d2276DDab16f1e407384F'; + const sUSDS = '0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD'; + + const totalSupply = + ( + await sdk.api.abi.call({ + target: sUSDS, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const key = `ethereum:${sUSDS}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${key}`) + ).data.coins[key].price; + + // sky savings rate + const RAY = 1e27; + const ssr = + ( + await sdk.api.abi.call({ + target: sUSDS, + abi: abiSUSDS.find((m) => m.name === 'ssr'), + }) + ).output / RAY; + + const secPerYear = 60 * 60 * 24 * 365; + + // https://github.com/makerdao/sdai/blob/susds/src/SUsds.sol + const nChi = Math.pow(ssr, secPerYear) * RAY; + + const apy = (nChi / RAY - 1) * 100; + + return [ + { + pool: sUSDS, + symbol: 'SUSDS', + project: 'sky-lending', + chain: 'ethereum', + tvlUsd: totalSupply * price, + apy, + underlyingTokens: [USDS], + }, + ]; +}; + +const apy = async () => { + const pools = await Promise.all([main(), susdsAPY()]); + return pools.flat(); +}; + +module.exports = { + apy, + url: 'https://sky.money/', +}; diff --git a/src/adaptors/smardex-amm/abis.js b/src/adaptors/smardex-amm/abis.js new file mode 100644 index 0000000000..7ad4ce68ad --- /dev/null +++ b/src/adaptors/smardex-amm/abis.js @@ -0,0 +1,572 @@ +module.exports = { + farmingRangeABI: [ + { + inputs: [ + { internalType: 'address', name: '_rewardManager', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'campaignID', + type: 'uint256', + }, + { + indexed: false, + internalType: 'contract IERC20', + name: 'stakingToken', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IERC20', + name: 'rewardToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'startBlock', + type: 'uint256', + }, + ], + name: 'AddCampaignInfo', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'campaignID', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint256', + name: 'phase', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'endBlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerBlock', + type: 'uint256', + }, + ], + name: 'AddRewardInfo', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'campaign', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'campaign', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'campaignID', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint256', + name: 'phase', + type: 'uint256', + }, + ], + name: 'RemoveRewardInfo', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardInfoLimit', + type: 'uint256', + }, + ], + name: 'SetRewardInfoLimit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'campaignID', + type: 'uint256', + }, + { + indexed: true, + internalType: 'uint256', + name: 'phase', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'endBlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerBlock', + type: 'uint256', + }, + ], + name: 'UpdateRewardInfo', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'campaign', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: '_stakingToken', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: '_rewardToken', + type: 'address', + }, + { internalType: 'uint256', name: '_startBlock', type: 'uint256' }, + ], + name: 'addCampaignInfo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256', name: '_endBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_rewardPerBlock', type: 'uint256' }, + ], + name: 'addRewardInfo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256[]', name: '_endBlock', type: 'uint256[]' }, + { + internalType: 'uint256[]', + name: '_rewardPerBlock', + type: 'uint256[]', + }, + ], + name: 'addRewardInfoMultiple', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'arbitrumBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: '_token', type: 'address' }, + { internalType: 'address', name: '_from', type: 'address' }, + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'attemptTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'campaignInfo', + outputs: [ + { + internalType: 'contract IERC20', + name: 'stakingToken', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'rewardToken', + type: 'address', + }, + { internalType: 'uint256', name: 'startBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardPerShare', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStaked', type: 'uint256' }, + { internalType: 'uint256', name: 'totalRewards', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'campaignInfoLen', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'campaignRewardInfo', + outputs: [ + { internalType: 'uint256', name: 'endBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardPerBlock', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'currentEndBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'currentRewardPerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + { internalType: 'bool', name: '_approveMax', type: 'bool' }, + { internalType: 'uint256', name: '_deadline', type: 'uint256' }, + { internalType: 'uint8', name: '_v', type: 'uint8' }, + { internalType: 'bytes32', name: '_r', type: 'bytes32' }, + { internalType: 'bytes32', name: '_s', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_from', type: 'uint256' }, + { internalType: 'uint256', name: '_to', type: 'uint256' }, + { internalType: 'uint256', name: '_endBlock', type: 'uint256' }, + ], + name: 'getMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: '_campaignIDs', type: 'uint256[]' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'massUpdateCampaigns', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingReward', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'removeLastRewardInfo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'rewardInfoLen', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardInfoLimit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardManager', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_updatedRewardInfoLimit', + type: 'uint256', + }, + ], + name: 'setRewardInfoLimit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + ], + name: 'updateCampaign', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: '_campaignID', type: 'uint256[]' }, + { + internalType: 'uint256[][]', + name: '_rewardIndex', + type: 'uint256[][]', + }, + { internalType: 'uint256[][]', name: '_endBlock', type: 'uint256[][]' }, + { + internalType: 'uint256[][]', + name: '_rewardPerBlock', + type: 'uint256[][]', + }, + ], + name: 'updateCampaignsRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256', name: '_rewardIndex', type: 'uint256' }, + { internalType: 'uint256', name: '_endBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_rewardPerBlock', type: 'uint256' }, + ], + name: 'updateRewardInfo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256[]', name: '_rewardIndex', type: 'uint256[]' }, + { internalType: 'uint256[]', name: '_endBlock', type: 'uint256[]' }, + { + internalType: 'uint256[]', + name: '_rewardPerBlock', + type: 'uint256[]', + }, + ], + name: 'updateRewardMultiple', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/smardex-amm/index.js b/src/adaptors/smardex-amm/index.js new file mode 100644 index 0000000000..d945c3f2f2 --- /dev/null +++ b/src/adaptors/smardex-amm/index.js @@ -0,0 +1,521 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { + utils: { formatEther }, + constants: { WeiPerEther }, + BigNumber, +} = require('ethers'); +const utils = require('../utils'); +const { farmingRangeABI } = require('./abis'); + +const API_KEY = process.env.SMARDEX_SUBGRAPH_API_KEY; +const project = 'smardex-amm'; + +const BASE_URL = 'https://smardex.io/liquidity'; +const DAYS_IN_YEAR = 365; +const SECONDS_IN_DAY = 86400; + +// Smardex gateway for subgraph queries, for each chain +const ENDPOINT_BASE = 'https://subgraph.smardex.io/defillama'; + +// Smardex seed USDN token available on Ethereum +const SUSDN_TOKEN_ADDRESS = '0xf67e2dc041b8a3c39d066037d29f500757b1e886'; +const SUSDE_TOKEN_ADDRESS = '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497'; + +const CONFIG = { + ethereum: { + ENDPOINT: `${ENDPOINT_BASE}/ethereum`, + SDEX_TOKEN_ADDRESS: '0x5de8ab7e27f6e7a1fff3e5b337584aa43961beef', + FARMING_RANGE_ADDRESS: '0x7d85C0905a6E1Ab5837a0b57cD94A419d3a77523', + TIME_BETWEEN_BLOCK: 12, + STAKING_ADDRESS: '0x80497049b005Fd236591c3CD431DBD6E06eB1A31', + }, + arbitrum: { + ENDPOINT: `${ENDPOINT_BASE}/arbitrum`, + SDEX_TOKEN_ADDRESS: '0xabD587f2607542723b17f14d00d99b987C29b074', + FARMING_RANGE_ADDRESS: '0x53D165DF0414bD02E91747775450934BF2257f69', + TIME_BETWEEN_BLOCK: 0.25, + }, + polygon: { + ENDPOINT: `${ENDPOINT_BASE}/polygon`, + SDEX_TOKEN_ADDRESS: '0x6899fAcE15c14348E1759371049ab64A3a06bFA6', + FARMING_RANGE_ADDRESS: '0x7DB73A1e526db36c40e508b09428420c1fA8e46b', + TIME_BETWEEN_BLOCK: 2.2, + }, + bsc: { + ENDPOINT: `${ENDPOINT_BASE}/bsc`, + SDEX_TOKEN_ADDRESS: '0xFdc66A08B0d0Dc44c17bbd471B88f49F50CdD20F', + FARMING_RANGE_ADDRESS: '0xb891Aeb2130805171796644a2af76Fc7Ff25a0b9', + TIME_BETWEEN_BLOCK: 3, + }, + base: { + ENDPOINT: `${ENDPOINT_BASE}/base`, + SDEX_TOKEN_ADDRESS: '0xFd4330b0312fdEEC6d4225075b82E00493FF2e3f', + FARMING_RANGE_ADDRESS: '0xa5D378c05192E3f1F365D6298921879C4D51c5a3', + TIME_BETWEEN_BLOCK: 2, + }, +}; + +const EXCEPTIONS = { + ethereum: [ + { + tokenAddress: SUSDN_TOKEN_ADDRESS, + symbol: 'sUSDN', + customHandler: async ({ + chainString, + block, + farmsWithRewards, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS, + }) => { + const prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${chainString}:${SUSDN_TOKEN_ADDRESS}` + ) + ).coins; + const susdnPrice = + prices[`${chainString}:${SUSDN_TOKEN_ADDRESS}`]?.price || 0; + const totalSupply = + ( + await sdk.api.abi.call({ + target: SUSDN_TOKEN_ADDRESS, + abi: 'erc20:totalSupply', + chain: chainString, + }) + ).output / 1e18; + const rewardApy = campaignRewardAPY( + farmsWithRewards.find( + (farm) => + farm.pairAddress.toLowerCase() === + SUSDN_TOKEN_ADDRESS.toLowerCase() + ), + block, + susdnPrice, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS + ); + + const sUSDeApy = await getsUSDeApy(susdnPrice); + const apyBase = rewardApy + sUSDeApy; + return { + pool: SUSDN_TOKEN_ADDRESS, + symbol: 'sUSDN', + project, + chain: utils.formatChain(chainString), + tvlUsd: totalSupply * susdnPrice, + apyBase, + }; + }, + }, + ], +}; + +const query = gql` + { + pairs(first: 500, orderBy: reserveUSD, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + fictiveReserve0 + fictiveReserve1 + volumeUSD + totalSupply + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 500 orderBy: reserveUSD orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const queryLastBlock = gql` + { + _meta { + block { + number + } + } + } +`; + +/** + * GraphQL request helper function that authenticates to Smardex subgraph gateway + */ +const gqlRequest = (url, query, variables = null) => { + return request(url, query, variables, { + 'x-api-key': API_KEY, + }); +}; + +const getFarmsWithRewards = async ( + chainString, + STAKING_ADDRESS, + FARMING_RANGE_ADDRESS +) => { + // Get staking total shares and campaigns length + const campaignInfoLen = ( + await sdk.api.abi.call({ + target: FARMING_RANGE_ADDRESS, + abi: farmingRangeABI.find(({ name }) => name === 'campaignInfoLen'), + chain: chainString, + }) + ).output; + + // Get each campaigns info and rewards length + const [campaignInfos, rewardInfoLens] = await Promise.all([ + sdk.api.abi.multiCall({ + target: FARMING_RANGE_ADDRESS, + abi: farmingRangeABI.find(({ name }) => name === 'campaignInfo'), + chain: chainString, + calls: [...Array.from(Array(parseInt(campaignInfoLen, 10)).keys())] + .slice(STAKING_ADDRESS ? 1 : 0) + .map((campaignId) => ({ + target: FARMING_RANGE_ADDRESS, + params: [campaignId], + })), + }), + sdk.api.abi.multiCall({ + target: FARMING_RANGE_ADDRESS, + abi: farmingRangeABI.find(({ name }) => name === 'rewardInfoLen'), + chain: chainString, + calls: [...Array.from(Array(parseInt(campaignInfoLen, 10)).keys())] + .slice(STAKING_ADDRESS ? 1 : 0) + .map((campaignId) => ({ + target: FARMING_RANGE_ADDRESS, + params: [campaignId], + })), + }), + ]); + + const campaignRewardInfoCalls = []; + rewardInfoLens.output.forEach((rewardInfoLen) => { + const campaignRewardLength = parseInt(rewardInfoLen.output, 10); + + for ( + let rewardInfoId = 0; + rewardInfoId < campaignRewardLength; + rewardInfoId += 1 + ) { + campaignRewardInfoCalls.push({ + methodName: FARMING_RANGE_ADDRESS, + params: [rewardInfoLen.input.params[0], rewardInfoId.toString()], + }); + } + }); + + // Get all segments of reward info per campaign + const campaignRewardInfo = ( + await sdk.api.abi.multiCall({ + target: FARMING_RANGE_ADDRESS, + abi: farmingRangeABI.find(({ name }) => name === 'campaignRewardInfo'), + chain: chainString, + calls: campaignRewardInfoCalls, + }) + ).output; + + // Build campaigns with attributes + const farmsWithRewards = []; + campaignInfos.output.forEach(({ input, output }) => { + const campaignId = input.params[0].toString(); + const rewards = campaignRewardInfo + .filter( + (campaignRewards) => + campaignRewards.success && + campaignRewards.input.params[0].toString() === campaignId + ) + .map((campaignRewards) => ({ + endBlock: parseInt(campaignRewards.output.endBlock, 10), + rewardPerBlock: BigNumber.from(campaignRewards.output.rewardPerBlock), + })) + .sort((a, b) => (a.endBlock > b.endBlock ? 1 : -1)); + + farmsWithRewards.push({ + id: campaignId, + pairAddress: output.stakingToken, + startBlock: parseInt(output.startBlock, 10), + lastRewardBlock: parseInt(output.lastRewardBlock, 10), + // accRewardPerShare: BigNumber.from(output.accRewardPerShare), + totalStaked: BigNumber.from(output.totalStaked), + totalRewards: BigNumber.from(output.totalRewards), + rewards, + }); + }); + + return farmsWithRewards; +}; + +const applyPoolExceptions = async ( + chainString, + block, + farmsWithRewards, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS +) => { + if (!EXCEPTIONS[chainString]) return []; + + const exceptions = EXCEPTIONS[chainString]; + const exceptionPools = []; + + for (const exception of exceptions) { + const pool = await exception.customHandler({ + chainString, + block, + farmsWithRewards, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS, + }); + + exceptionPools.push(pool); + } + return exceptionPools; +}; + +// Computes rewards as APY from Farming Campaigns +const campaignRewardAPY = ( + campaign, + currentBlockNumber, + poolPrice, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS +) => { + let apr = 0; + if ( + sdexPrice && + campaign && + currentBlockNumber > campaign.startBlock && + campaign.rewards.length !== 0 && + parseInt(campaign.totalStaked) !== 0 + ) { + for (let i = 0; i < campaign.rewards.length; i += 1) { + const reward = campaign.rewards[i]; + + if (currentBlockNumber < reward.endBlock) { + const aprBN = reward.rewardPerBlock + .mul( + parseInt(campaign.id, 10) === 0 && STAKING_ADDRESS ? 1 : WeiPerEther + ) + .mul(BLOCKS_PER_YEAR) + .mul(100) + .div(campaign.totalStaked); + + apr = (parseFloat(formatEther(aprBN)) * sdexPrice) / poolPrice; + break; + } + } + } + + return apr; +}; + +const topTvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const { + SDEX_TOKEN_ADDRESS, + FARMING_RANGE_ADDRESS, + TIME_BETWEEN_BLOCK, + STAKING_ADDRESS, + } = CONFIG[chainString]; + const BLOCKS_PER_YEAR = Math.floor( + (SECONDS_IN_DAY * DAYS_IN_YEAR) / TIME_BETWEEN_BLOCK + ); + const currentTimestamp = timestamp || Math.floor(Date.now() / 1000); + const timestampPrior = currentTimestamp - SECONDS_IN_DAY; + const timestampPrior7d = currentTimestamp - 7 * SECONDS_IN_DAY; + + let [block, blockPrior, blockPrior7d] = await utils.getBlocksByTime( + [currentTimestamp, timestampPrior, timestampPrior7d], + chainString + ); + + const lastIndexedBlock = (await gqlRequest(url, queryLastBlock))._meta.block + .number; + if (block > lastIndexedBlock) { + // If the block is not indexed yet, we use the last indexed block + block = lastIndexedBlock; + } + + // pull data + let queryC = query; + let dataNow = (await gqlRequest(url, queryC.replace('', block))) + .pairs; + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + const dataPrior = ( + await gqlRequest(url, queryPriorC.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await gqlRequest(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + dataNow = await utils.tvl(dataNow, chainString); + dataNow = dataNow.map((el) => + utils.apy({ ...el, feeTier: 9000 }, dataPrior, dataPrior7d, version) + ); + + const prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${chainString}:${SDEX_TOKEN_ADDRESS}` + ) + ).coins; + const sdexPrice = prices[`${chainString}:${SDEX_TOKEN_ADDRESS}`]?.price || 0; + const farmsWithRewards = await getFarmsWithRewards( + chainString, + STAKING_ADDRESS, + FARMING_RANGE_ADDRESS + ); + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const url = `${BASE_URL}/add?tokenA=${token0}&tokenB=${token1}`; + const poolPrice = + parseFloat(p.totalSupply) > 0 + ? (parseFloat(p.reserve0) * p.price0 + + parseFloat(p.reserve1) * p.price1) / + parseFloat(p.totalSupply) + : 1; + + const apyReward = campaignRewardAPY( + farmsWithRewards.find( + (farm) => farm.pairAddress.toLowerCase() === p.id.toLowerCase() + ), + block, + poolPrice, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS + ); + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project, + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward, + rewardTokens: apyReward > 0 ? [SDEX_TOKEN_ADDRESS] : [], + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + // Apply pool exceptions + const exceptionPools = await applyPoolExceptions( + chainString, + block, + farmsWithRewards, + sdexPrice, + BLOCKS_PER_YEAR, + STAKING_ADDRESS + ); + + // Combine data with pool exceptions + return [...dataNow, ...exceptionPools]; +}; + +const main = async (timestamp = null) => { + if (API_KEY === undefined) { + throw new Error('Missing SMARDEX_SUBGRAPH_API_KEY environment variable'); + } + // Getting configuration keys as array of chains + const chains = Object.keys(CONFIG); + + // Fetching data for each chain in parallel + const resultData = await Promise.allSettled( + chains.map(async (chain) => { + const data = await topTvl( + chain, + CONFIG[chain].ENDPOINT, + query, + queryPrior, + 'custom', + timestamp + ); + + return data; + }) + ); + + return resultData + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter(utils.keepFinite); +}; + +/** + * NOTE: + * This method is almost entirely taken from the Ethena adapter (src/adaptors/ethena/index.js) + * We need to calculate the APY of sUSDe because sUSDN contains the yield of sUSDe. + */ +const getsUSDeApy = async (sUSDNPrice) => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: SUSDE_TOKEN_ADDRESS, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const tvlUsd = totalSupply * sUSDNPrice; + + const currentBlock = await sdk.api.util.getLatestBlock('ethereum'); + const toBlock = currentBlock.number; + const topic = + '0xbb28dd7cd6be6f61828ea9158a04c5182c716a946a6d2f31f4864edb87471aa6'; + const logs = ( + await sdk.api.util.getLogs({ + target: '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497', + topic: '', + toBlock, + fromBlock: 19026137, + keys: [], + topics: [topic], + chain: 'ethereum', + }) + ).output.sort((a, b) => b.blockNumber - a.blockNumber); + + // rewards are now beeing streamed every 8hours, which we scale up to a year + const rewardsReceived = parseInt(logs[0].data / 1e18); + const aprBase = ((rewardsReceived * 3 * 365) / tvlUsd) * 100; + // weekly compoounding + const apyBase = utils.aprToApy(aprBase, 52); + return apyBase; +}; + +module.exports = { + timetravel: false, + apy: main, + url: BASE_URL, +}; diff --git a/src/adaptors/smardex-usdn/abis.js b/src/adaptors/smardex-usdn/abis.js new file mode 100644 index 0000000000..3b97d18236 --- /dev/null +++ b/src/adaptors/smardex-usdn/abis.js @@ -0,0 +1,1286 @@ +module.exports = { + usdnABI: [ + { + inputs: [ + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'address', name: 'rebaser', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AccessControlBadConfirmation', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'bytes32', name: 'neededRole', type: 'bytes32' }, + ], + name: 'AccessControlUnauthorizedAccount', + type: 'error', + }, + { inputs: [], name: 'ECDSAInvalidSignature', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'length', type: 'uint256' }], + name: 'ECDSAInvalidSignatureLength', + type: 'error', + }, + { + inputs: [{ internalType: 'bytes32', name: 's', type: 'bytes32' }], + name: 'ECDSAInvalidSignatureS', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'approver', type: 'address' }], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'spender', type: 'address' }], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'deadline', type: 'uint256' }], + name: 'ERC2612ExpiredSignature', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'signer', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'ERC2612InvalidSigner', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'currentNonce', type: 'uint256' }, + ], + name: 'InvalidAccountNonce', + type: 'error', + }, + { inputs: [], name: 'InvalidShortString', type: 'error' }, + { + inputs: [{ internalType: 'string', name: 'str', type: 'string' }], + name: 'StringTooLong', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'UsdnInsufficientSharesBalance', + type: 'error', + }, + { inputs: [], name: 'UsdnInvalidDivisor', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'value', type: 'uint256' }], + name: 'UsdnMaxTokensExceeded', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [], + name: 'EIP712DomainChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldDivisor', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newDivisor', + type: 'uint256', + }, + ], + name: 'Rebase', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IRebaseCallback', + name: 'newHandler', + type: 'address', + }, + ], + name: 'RebaseHandlerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, + ], + name: 'RoleAdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleRevoked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_DIVISOR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINTER_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MIN_DIVISOR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REBASER_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: 'balance_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'value', type: 'uint256' }], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'burnFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'value', type: 'uint256' }], + name: 'burnShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'burnSharesFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amountTokens', type: 'uint256' }, + ], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: 'shares_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amountShares', type: 'uint256' }, + ], + name: 'convertToTokens', + outputs: [{ internalType: 'uint256', name: 'tokens_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amountShares', type: 'uint256' }, + ], + name: 'convertToTokensRoundUp', + outputs: [{ internalType: 'uint256', name: 'tokens_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'divisor', + outputs: [{ internalType: 'uint256', name: 'divisor_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'eip712Domain', + outputs: [ + { internalType: 'bytes1', name: 'fields', type: 'bytes1' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'version', type: 'string' }, + { internalType: 'uint256', name: 'chainId', type: 'uint256' }, + { internalType: 'address', name: 'verifyingContract', type: 'address' }, + { internalType: 'bytes32', name: 'salt', type: 'bytes32' }, + { internalType: 'uint256[]', name: 'extensions', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxTokens', + outputs: [ + { internalType: 'uint256', name: 'maxTokens_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'mintShares', + outputs: [ + { internalType: 'uint256', name: 'mintedTokens_', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newDivisor', type: 'uint256' }, + ], + name: 'rebase', + outputs: [ + { internalType: 'bool', name: 'rebased_', type: 'bool' }, + { internalType: 'uint256', name: 'oldDivisor_', type: 'uint256' }, + { internalType: 'bytes', name: 'callbackResult_', type: 'bytes' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rebaseHandler', + outputs: [ + { + internalType: 'contract IRebaseCallback', + name: 'rebaseHandler_', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + internalType: 'address', + name: 'callerConfirmation', + type: 'address', + }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IRebaseCallback', + name: 'newHandler', + type: 'address', + }, + ], + name: 'setRebaseHandler', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'sharesOf', + outputs: [{ internalType: 'uint256', name: 'shares_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalShares', + outputs: [{ internalType: 'uint256', name: 'shares_', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { internalType: 'uint256', name: 'totalSupply_', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferShares', + outputs: [{ internalType: 'bool', name: 'success_', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferSharesFrom', + outputs: [{ internalType: 'bool', name: 'success_', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + wUsdnABI: [ + { + type: 'function', + name: 'DOMAIN_SEPARATOR', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'SHARES_RATIO', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'USDN', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IUsdn', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { + name: 'spender', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [ + { + name: '', + type: 'uint8', + internalType: 'uint8', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [ + { + name: '', + type: 'string', + internalType: 'string', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'nonces', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'permit', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'deadline', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'v', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'r', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 's', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'previewUnwrap', + inputs: [ + { + name: 'wusdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'usdnAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewUnwrapShares', + inputs: [ + { + name: 'wusdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'usdnSharesAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewWrap', + inputs: [ + { + name: 'usdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'wrappedAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewWrapShares', + inputs: [ + { + name: 'usdnShares', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'wrappedAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'redemptionRate', + inputs: [], + outputs: [ + { + name: 'usdnAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [ + { + name: '', + type: 'string', + internalType: 'string', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalUsdnBalance', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalUsdnShares', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { + name: 'to', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { + name: 'from', + type: 'address', + internalType: 'address', + }, + { + name: 'to', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'unwrap', + inputs: [ + { + name: 'wusdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'to', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: 'usdnAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'unwrap', + inputs: [ + { + name: 'wusdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'usdnAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'wrap', + inputs: [ + { + name: 'usdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'to', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: 'wrappedAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'wrap', + inputs: [ + { + name: 'usdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'wrappedAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'wrapShares', + inputs: [ + { + name: 'usdnShares', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'to', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: 'wrappedAmount_', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Unwrap', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'wusdnAmount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'usdnAmount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Wrap', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'usdnAmount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'wusdnAmount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'WusdnInsufficientBalance', + inputs: [ + { + name: 'usdnAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { + type: 'error', + name: 'WusdnWrapZeroAmount', + inputs: [], + }, + ], +}; diff --git a/src/adaptors/smardex-usdn/index.js b/src/adaptors/smardex-usdn/index.js new file mode 100644 index 0000000000..192b12d2db --- /dev/null +++ b/src/adaptors/smardex-usdn/index.js @@ -0,0 +1,156 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { + usdnABI, + wUsdnABI, +} = require('./abis'); + +const DAYS_IN_YEAR = 365; +const SECONDS_IN_DAY = 86400; +const SECONDS_IN_A_YEAR = DAYS_IN_YEAR * SECONDS_IN_DAY; + +const CONFIGS = [ + { + chain: 'ethereum', + USDN_TOKEN_ADDRESS: '0xde17a000BA631c5d7c2Bd9FB692EFeA52D90DEE2', + WUSDN_TOKEN_ADDRESS: '0x99999999999999Cc837C997B882957daFdCb1Af9', + USDN_PROTOCOL_ADDRESS: '0x656cB8C6d154Aad29d8771384089be5B5141f01a', + USDN_PROTOCOL_FIRST_DEPOSIT: 1737663167, + }, +]; + +const getUsdnPriceAtTimestamp = async (chainConfig, timestamp) => { + const prices = ( + await utils.getData( + `https://coins.llama.fi/prices/historical/${timestamp}/${chainConfig.chain}:${chainConfig.USDN_TOKEN_ADDRESS}` + ) + ).coins; + const usdnResult = prices[`${chainConfig.chain}:${chainConfig.USDN_TOKEN_ADDRESS}`]; + if (usdnResult === undefined) { + throw new Error('No price data found for USDN'); + } + return usdnResult.price; +}; + +async function fetchUSDNData(chainConfig, timestamp) { + const [block] = await utils.getBlocksByTime([timestamp], chainConfig.chain); + + const usdnDivisorCall = sdk.api.abi.call({ + target: chainConfig.USDN_TOKEN_ADDRESS, + abi: usdnABI.find((m) => m.name === 'divisor'), + chain: chainConfig.chain, + block, + }); + + const usdnTotalSupplyCall = sdk.api.abi.call({ + target: chainConfig.USDN_TOKEN_ADDRESS, + abi: usdnABI.find((m) => m.name === 'totalSupply'), + chain: chainConfig.chain, + block, + }); + + const wUsdnSharesRatioCall = sdk.api.abi.call({ + target: chainConfig.WUSDN_TOKEN_ADDRESS, + abi: wUsdnABI.find((m) => m.name === 'SHARES_RATIO'), + chain: chainConfig.chain, + block, + }); + + const [ + usdnDivisor, + usdnTotalSupply, + wUsdnSharesRatio, + ] = await Promise.all([ + usdnDivisorCall, + usdnTotalSupplyCall, + wUsdnSharesRatioCall, + ]); + + const usdnPrice = await getUsdnPriceAtTimestamp(chainConfig, timestamp); + const formattedUsdnPrice = BigInt(Math.round(usdnPrice * 10 ** 18)); + const usdnDivisorOutput = BigInt(usdnDivisor.output); + + return { + usdnDivisor: usdnDivisorOutput, + usdnTotalSupply: BigInt(usdnTotalSupply.output), + wusdnPrice: + (BigInt(wUsdnSharesRatio.output) * formattedUsdnPrice) / + usdnDivisorOutput, + }; +} + +const computeUsdnApr = async (chainConfig, timestampNow) => { + const timestampOneYearAgo = Math.max( + timestampNow - SECONDS_IN_A_YEAR, + chainConfig.USDN_PROTOCOL_FIRST_DEPOSIT, + ); + + const [yearAgo, now] = await Promise.all([ + fetchUSDNData(chainConfig, timestampOneYearAgo), + fetchUSDNData(chainConfig, timestampNow), + ]); + + const timePeriodInDays = + (timestampNow - timestampOneYearAgo) / SECONDS_IN_DAY; + + const totalYield = + Number( + ((now.wusdnPrice - yearAgo.wusdnPrice) * BigInt(10 ** 18)) / + yearAgo.wusdnPrice + ) / + 10 ** 18; + + return (Math.pow(1 + totalYield, 365 / timePeriodInDays) - 1) * 100; +}; + +const computeYield = async ( + chainConfig, + timestamp, +) => { + const evaluatedTimestamp = timestamp || Math.floor(Date.now() / 1000); + const [evaluatedBlock] = await utils.getBlocksByTime([evaluatedTimestamp], chainConfig.chain); + const totalSupply = + ( + await sdk.api.abi.call({ + target: chainConfig.USDN_TOKEN_ADDRESS, + abi: 'erc20:totalSupply', + chain: chainConfig.chain, + block: evaluatedBlock, + }) + ).output / 1e18; + + const apyBase = await computeUsdnApr(chainConfig, evaluatedTimestamp); + + return { + pool: chainConfig.USDN_TOKEN_ADDRESS, + symbol: 'USDN', + project: 'smardex-usdn', + chain: utils.formatChain(chainConfig.chain), + tvlUsd: totalSupply, + apyBase, + }; +} + +const main = async (timestamp = null) => { + const resultData = await Promise.allSettled( + CONFIGS.map(async (chainConfig) => { + const data = await computeYield( + chainConfig, + timestamp + ); + return data; + }) + ); + + return resultData + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter(utils.keepFinite); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://smardex.io/liquidity', +}; diff --git a/src/adaptors/smartcredit/index.js b/src/adaptors/smartcredit/index.js new file mode 100644 index 0000000000..99c8b915f5 --- /dev/null +++ b/src/adaptors/smartcredit/index.js @@ -0,0 +1,86 @@ +const utils = require('../utils'); +const { GraphQLClient, gql} = require('graphql-request') + + +const endPoint = 'https://d2c7awq32ho327.cloudfront.net/graphql' +var graphQLClient = new GraphQLClient(endPoint) +const SMART_CREDIT = '0x72e9D9038cE484EE986FEa183f8d8Df93f9aDA13'.toLowerCase() + + +const underlyingStats = gql` + query { + underlyingCurrencies { + symbol, + name, + ethAddress, + riskFreeRate, + exchangeRate, + medianExchangeRate, + isUnderlying, + isCollateral, + decimalPlaces, + totalBorrowedAmount, + totalBorrowedValueInUSD, + totalLendedAmount, + totalLendedValueInUSD, + maxAPY, + minInterestRate, + lendersAPY, + borrowersAPY + } + } +`; + +const requiredCollateralRatio = gql` + query RequiredCollateralRatio($loanAmount: Float!, $loanTerm: Int!, $loanRequestValidity: DateTime!, $collateralCurrency: String!, $underlyingCurrency: String!, $userRating: Int!) { + requiredCollateralRatio( + loanAmount: $loanAmount, + loanTerm: $loanTerm, + loanRequestValidity: $loanRequestValidity, + collateralCurrency: $collateralCurrency, + underlyingCurrency: $underlyingCurrency, + userRating: $userRating + ) { + collateralRatio + } + } +`; +async function getStats(query,variables) { + return await graphQLClient.request(query,variables) +} +const poolsFunction = async () => { + const apyData = await getStats(underlyingStats); + const variablesArr = apyData.underlyingCurrencies.map(item => ({ + loanAmount: 1, //Required param otherwise does not have any impact on the calculation + loanTerm: item.symbol === "SMARTCREDIT" ? 90 : 30, + loanRequestValidity: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000), + collateralCurrency: item.symbol, + underlyingCurrency: item.symbol, + userRating: 1, //calculating lower bound(worst credit score) + })); + const resultArr = await Promise.all(variablesArr.map(variables => getStats(requiredCollateralRatio, variables))); + return apyData.underlyingCurrencies.map((item, i) => ({ + pool: (`${item.ethAddress}-smartcredit`).toLowerCase(), + chain: utils.formatChain("Ethereum"), + project: "smartcredit", + symbol: utils.formatSymbol(item.symbol), + tvlUsd: item.totalLendedValueInUSD - item.totalBorrowedValueInUSD, + apyBase: +(item.maxAPY), + apyReward: +(item.lendersAPY), + rewardTokens: [SMART_CREDIT], + underlyingTokens: [(item.ethAddress).toLowerCase()], + poolMeta:item.symbol === "SMARTCREDIT" ? '90-180 days' : '30-90 days', + apyBaseBorrow: +(item.minInterestRate), + apyRewardBorrow: +(item.borrowersAPY), + totalSupplyUsd: item.totalLendedValueInUSD, + totalBorrowUsd: item.totalBorrowedValueInUSD, + ltv: (1 / (resultArr[i].requiredCollateralRatio.collateralRatio / 100)) + })); +}; + + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://appv2.smartcredit.io', +}; \ No newline at end of file diff --git a/src/adaptors/snowbl-capital/index.js b/src/adaptors/snowbl-capital/index.js new file mode 100644 index 0000000000..66227f6d79 --- /dev/null +++ b/src/adaptors/snowbl-capital/index.js @@ -0,0 +1,29 @@ +const utils = require('../utils'); + +const apy = async (timestamp) => { + const snowblVault = await utils.getERC4626Info( + '0xd61bfc9ca1d0d2b03a3dd74e2ab81df8e5f606e8', + 'base', + timestamp + ); + + const { tvl, ...rest } = snowblVault; + + return [ + { + ...rest, + project: 'snowbl-capital', + symbol: 'USDC', + tvlUsd: tvl / 1e6, + underlyingTokens: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'], + poolMeta: 'Snowbl Capital USDC Vault', + url: 'https://snowbl.capital', + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://snowbl.capital', +}; diff --git a/src/adaptors/solend/index.js b/src/adaptors/solend/index.js deleted file mode 100755 index 13a9ed3b6b..0000000000 --- a/src/adaptors/solend/index.js +++ /dev/null @@ -1,78 +0,0 @@ -const fetch = require('node-fetch'); - -const utils = require('../utils'); - -const baseUrl = 'https://api.solend.fi'; -const configEndpoint = `${baseUrl}/v1/config`; -const reservesEndpoint = `${baseUrl}/v1/reserves`; - -const buildPool = async (reserveConfig, reserveData) => { - const liquidity = reserveData.reserve.liquidity; - const apy = - Number(reserveData.rates.supplyInterest) + - reserveData.rewards.reduce( - (acc, reward) => - reward.side === 'supply' ? Number(reward.apy) + acc : acc, - 0 - ); - const secondaryString = - reserveConfig.marketName.charAt(0).toUpperCase() + - reserveConfig.marketName.slice(1) + - ' Pool'; - - const newObj = { - pool: reserveConfig.address, - chain: utils.formatChain('solana'), - project: 'solend', - symbol: `${reserveConfig.asset} (${secondaryString})`, - tvlUsd: - (Number(liquidity.availableAmount) / 10 ** liquidity.mintDecimals) * - (liquidity.marketPrice / 10 ** 18), - apy, - }; - - return newObj; -}; - -const topLvl = async () => { - const configResponse = await fetch(`${configEndpoint}?deployment=production`); - - const config = await configResponse.json(); - - const reservesConfigs = config.markets.flatMap((market) => - market.reserves.map((reserve) => ({ - ...reserve, - marketName: market.name, - })) - ); - - // note(slasher): seems like the solend team has made changes to the reserveEndpoint - // which now has a limit of max 5 ids, hence why i made this change to loop instead - const tokenIds = reservesConfigs.map((reserve) => reserve.address); - const reserves = []; - const maxIds = 5; - for (let i = 0; i <= tokenIds.length; i += maxIds) { - const tokens = tokenIds.slice(i, i + 5).join(','); - - const reservesResponse = await fetch(`${reservesEndpoint}?ids=${tokens}`); - const res = (await reservesResponse.json()).results; - reserves.push(res); - } - - return Promise.all( - reserves - .flat() - .map((reserve, index) => buildPool(reservesConfigs[index], reserve)) - ); -}; - -const main = async () => { - const data = await topLvl(); - - return data; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/solidly-v2/index.ts b/src/adaptors/solidly-v2/index.ts new file mode 100644 index 0000000000..5a60b3f557 --- /dev/null +++ b/src/adaptors/solidly-v2/index.ts @@ -0,0 +1,162 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL: string = 'https://api-mainnet.solidly.com/api/v1/pairs'; + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint( + sdk.graph.modifyEndpoint('4GX8RE9TzEWormbkayeGj4NQmmhYE46izVVUvXv8WPDh') +); + +const swapPairsQuery = gql` + query MyQuery { + pairs { + token0Price + reserve0 + reserve1 + token1Price + token1 { + id + symbol + name + } + token0 { + symbol + name + id + } + reserveUSD + id + } + } +`; + +type GraphPair = { + token0Price: string; + reserve0: string; + reserve1: string; + token1Price: string; + token1: { + id: string; + symbol: string; + name: string; + }; + token0: { + symbol: string; + name: string; + id: string; + }; + reserveUSD: string; + id: string; +}; + +const getPairs = async () => { + const { pairs } = await request(SUBGRAPH_URL, swapPairsQuery, {}); + return pairs; +}; + +type PoolToken = { + address: string; + symbol: string; +}; + +type AprObject = { + current: string; + projected: string; + lastWeek: string; +}; + +interface Pool { + address: string; + token0: PoolToken; + token1: PoolToken; + totalTvlUsd: string; + totalLpApr: AprObject; +} + +interface Response { + data: Array; +} + +const getApy = async () => { + // APR is retrieved using our api, tvl pairs etc trough subgraph + const { data: poolsRes }: Response = await utils.getData(API_URL); + + const apyDict: any = {}; + const alreadySeen = []; + let priceApiCoins = ''; + + for (const pool of poolsRes) { + apyDict[pool.address.toLowerCase()] = pool.totalLpApr.current; + } + + const pairs = await getPairs(); + for (const pair of pairs) { + const token0Key = 'ethereum:' + pair.token0.id.toLowerCase(); + const token1Key = 'ethereum:' + pair.token1.id.toLowerCase(); + + if (!alreadySeen.includes(token0Key)) { + alreadySeen.push(token0Key); + priceApiCoins += token0Key + ','; + } + + if (!alreadySeen.includes(token1Key)) { + alreadySeen.push(token1Key); + priceApiCoins += token1Key + ','; + } + } + + // asking price to defillama chunking requests (currently running with 1 request could be lowered if needed) + let fullCoin = {}; + const chunkSize = 60; + for (let i = 0; i < alreadySeen.length; i += chunkSize) { + const chunk = alreadySeen.slice(i, i + chunkSize); + + const { coins }: any = await utils.getData( + `https://coins.llama.fi/prices/current/${chunk.join(',')}?searchWidth=4h` + ); + fullCoin = { ...fullCoin, ...coins }; + } + + const pools = pairs.map((pair: GraphPair) => { + let tvl = 0; + + if ( + fullCoin['ethereum:' + pair.token0.id.toLowerCase()] && + fullCoin['ethereum:' + pair.token1.id.toLowerCase()] + ) { + const token0ValueInReserve = + parseFloat(pair.reserve0) * + parseFloat(fullCoin['ethereum:' + pair.token0.id.toLowerCase()].price); + const token1ValueInReserve = + parseFloat(pair.reserve1) * + parseFloat(fullCoin['ethereum:' + pair.token1.id.toLowerCase()].price); + + tvl = token0ValueInReserve + token1ValueInReserve; + } else { + // fallbacking to the one from api if defillama price are missing + tvl = parseFloat(pair.reserveUSD); + } + + return { + pool: pair.id, + chain: utils.formatChain('ethereum'), + project: 'solidly-v2', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: tvl, + apyReward: parseFloat(apyDict[pair.id.toLowerCase()]), + underlyingTokens: [pair.token0.id, pair.token1.id], + rewardTokens: [ + '0x777172D858dC1599914a1C4c6c9fC48c99a60990', // solid + ], + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://solidly.com/liquidity', +}; diff --git a/src/adaptors/solidly-v3/abi.js b/src/adaptors/solidly-v3/abi.js new file mode 100644 index 0000000000..76cb8b068a --- /dev/null +++ b/src/adaptors/solidly-v3/abi.js @@ -0,0 +1,628 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickLower', + type: 'int24', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickUpper', + type: 'int24', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickLower', + type: 'int24', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickUpper', + type: 'int24', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount0', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount1', + type: 'uint128', + }, + ], + name: 'Collect', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount0', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount1', + type: 'uint128', + }, + ], + name: 'CollectProtocol', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'paid0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'paid1', + type: 'uint256', + }, + ], + name: 'Flash', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint160', + name: 'sqrtPriceX96', + type: 'uint160', + }, + { indexed: false, internalType: 'int24', name: 'tick', type: 'int24' }, + ], + name: 'Initialize', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickLower', + type: 'int24', + }, + { + indexed: true, + internalType: 'int24', + name: 'tickUpper', + type: 'int24', + }, + { + indexed: false, + internalType: 'uint128', + name: 'amount', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint24', + name: 'feeOld', + type: 'uint24', + }, + { + indexed: false, + internalType: 'uint24', + name: 'feeNew', + type: 'uint24', + }, + ], + name: 'SetFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'int256', + name: 'amount0', + type: 'int256', + }, + { + indexed: false, + internalType: 'int256', + name: 'amount1', + type: 'int256', + }, + { + indexed: false, + internalType: 'uint160', + name: 'sqrtPriceX96', + type: 'uint160', + }, + { + indexed: false, + internalType: 'uint128', + name: 'liquidity', + type: 'uint128', + }, + { indexed: false, internalType: 'int24', name: 'tick', type: 'int24' }, + ], + name: 'Swap', + type: 'event', + }, + { + inputs: [ + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + { internalType: 'uint256', name: 'amount0Min', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Min', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + ], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amountToBurn', type: 'uint128' }, + { internalType: 'uint128', name: 'amount0ToCollect', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1ToCollect', type: 'uint128' }, + ], + name: 'burnAndCollect', + outputs: [ + { internalType: 'uint256', name: 'amount0FromBurn', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1FromBurn', type: 'uint256' }, + { internalType: 'uint128', name: 'amount0Collected', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1Collected', type: 'uint128' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amountToBurn', type: 'uint128' }, + { internalType: 'uint256', name: 'amount0FromBurnMin', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1FromBurnMin', type: 'uint256' }, + { internalType: 'uint128', name: 'amount0ToCollect', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1ToCollect', type: 'uint128' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'burnAndCollect', + outputs: [ + { internalType: 'uint256', name: 'amount0FromBurn', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1FromBurn', type: 'uint256' }, + { internalType: 'uint128', name: 'amount0Collected', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1Collected', type: 'uint128' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amount0Requested', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1Requested', type: 'uint128' }, + ], + name: 'collect', + outputs: [ + { internalType: 'uint128', name: 'amount0', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1', type: 'uint128' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint128', name: 'amount0Requested', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1Requested', type: 'uint128' }, + ], + name: 'collectProtocol', + outputs: [ + { internalType: 'uint128', name: 'amount0', type: 'uint128' }, + { internalType: 'uint128', name: 'amount1', type: 'uint128' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'flash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'liquidity', + outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxLiquidityPerTick', + outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + { internalType: 'uint256', name: 'amount0Min', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Min', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'int24', name: 'tickLower', type: 'int24' }, + { internalType: 'int24', name: 'tickUpper', type: 'int24' }, + { internalType: 'uint128', name: 'amount', type: 'uint128' }, + ], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'poolFees', + outputs: [ + { internalType: 'uint128', name: 'token0', type: 'uint128' }, + { internalType: 'uint128', name: 'token1', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'positions', + outputs: [ + { internalType: 'uint128', name: 'liquidity', type: 'uint128' }, + { internalType: 'uint128', name: 'tokensOwed0', type: 'uint128' }, + { internalType: 'uint128', name: 'tokensOwed1', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bool', name: 'zeroForOne', type: 'bool' }, + { internalType: 'int256', name: 'amountSpecified', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' }, + ], + name: 'quoteSwap', + outputs: [ + { internalType: 'int256', name: 'amount0', type: 'int256' }, + { internalType: 'int256', name: 'amount1', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceX96After', type: 'uint160' }, + { internalType: 'int24', name: 'tickAfter', type: 'int24' }, + { internalType: 'uint128', name: 'liquidityAfter', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint24', name: 'fee', type: 'uint24' }], + name: 'setFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'slot0', + outputs: [ + { internalType: 'uint160', name: 'sqrtPriceX96', type: 'uint160' }, + { internalType: 'int24', name: 'tick', type: 'int24' }, + { internalType: 'uint24', name: 'fee', type: 'uint24' }, + { internalType: 'bool', name: 'unlocked', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'bool', name: 'zeroForOne', type: 'bool' }, + { internalType: 'int256', name: 'amountSpecified', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' }, + { internalType: 'uint256', name: 'amountLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [ + { internalType: 'int256', name: 'amount0', type: 'int256' }, + { internalType: 'int256', name: 'amount1', type: 'int256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'bool', name: 'zeroForOne', type: 'bool' }, + { internalType: 'int256', name: 'amountSpecified', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [ + { internalType: 'int256', name: 'amount0', type: 'int256' }, + { internalType: 'int256', name: 'amount1', type: 'int256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'bool', name: 'zeroForOne', type: 'bool' }, + { internalType: 'int256', name: 'amountSpecified', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' }, + { internalType: 'uint256', name: 'amountLimit', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'swap', + outputs: [ + { internalType: 'int256', name: 'amount0', type: 'int256' }, + { internalType: 'int256', name: 'amount1', type: 'int256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'bool', name: 'zeroForOne', type: 'bool' }, + { internalType: 'int256', name: 'amountSpecified', type: 'int256' }, + { internalType: 'uint160', name: 'sqrtPriceLimitX96', type: 'uint160' }, + ], + name: 'swap', + outputs: [ + { internalType: 'int256', name: 'amount0', type: 'int256' }, + { internalType: 'int256', name: 'amount1', type: 'int256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'int16', name: '', type: 'int16' }], + name: 'tickBitmap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'tickSpacing', + outputs: [{ internalType: 'int24', name: '', type: 'int24' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'int24', name: '', type: 'int24' }], + name: 'ticks', + outputs: [ + { internalType: 'uint128', name: 'liquidityGross', type: 'uint128' }, + { internalType: 'int128', name: 'liquidityNet', type: 'int128' }, + { internalType: 'bool', name: 'initialized', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/solidly-v3/estimateActiveLiq.ts b/src/adaptors/solidly-v3/estimateActiveLiq.ts new file mode 100644 index 0000000000..221efa7288 --- /dev/null +++ b/src/adaptors/solidly-v3/estimateActiveLiq.ts @@ -0,0 +1,250 @@ +// forked from uniswap.fish chads (see https://github.com/chunza2542/uniswap.fish) +// modified univ3 adapter to just return the active liq fraction +const bn = require('bignumber.js'); +const axios = require('axios'); + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = (price, token0Decimal, token1Decimal) => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +const getTokensAmountFromDepositAmountUSD = ( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD +) => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = (sqrtRatioAX96, sqrtRatioBX96, amount0) => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = (sqrtRatioAX96, sqrtRatioBX96, amount1) => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = (price, token0Decimal, token1Decimal) => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P, + lowerP, + upperP, + amount0, + amount1, + token0Decimal, + token1Decimal +) => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +/// get the percentage of active liquidity from the price assumption +const liquidityPercentage = (liquidityDelta, liquidity) => { + // console.log("DELTA", liquidityDelta, "LIQ", liquidity) + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + return liquidityPercentage; +}; + +// get 'active' liquidity +const getLiquidityFromTick = (poolTicks, tick) => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price) => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n, exp) => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a, b, multiplier) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getPoolTicks = async (poolAddress, url) => { + const PAGE_SIZE = 3; + let result = []; + let page = 0; + while (true) { + const pool1 = await _getPoolTicksByPage(poolAddress, page, url); + const pool2 = await _getPoolTicksByPage(poolAddress, page + 1, url); + const pool3 = await _getPoolTicksByPage(poolAddress, page + 2, url); + + result = [...result, ...pool1, ...pool2, ...pool3]; + if (pool1.length === 0 || pool2.length === 0 || pool3.length === 0) { + break; + } + page += PAGE_SIZE; + } + return result; +}; + +const _getPoolTicksByPage = async (poolAddress, page, url) => { + let res; + try { + res = await _queryUniswap( + `{ + ticks(first: 1000, skip: ${ + page * 1000 + }, where: { poolAddress: "${poolAddress}" }, orderBy: tickIdx) { + tickIdx + liquidityNet + price0 + price1 + } + }`, + url + ); + } catch (e) { + console.log('_getPoolTicksByPage failed for', poolAddress); + return []; + } + + return res === undefined ? [] : res.ticks; +}; + +const _queryUniswap = async (query, url) => { + const { data } = await axios({ + url, + method: 'post', + data: { + query, + }, + }); + + return data.data; +}; + +module.exports.EstimateActiveLiq = async ( + poolAddress, + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + url +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + const poolTicks = await getPoolTicks(poolAddress, url); + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${poolAddress}`); + return { poolAddress, estimatedFee: 0 }; + } + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const liq_percentage = + P >= Pl && P <= Pu ? liquidityPercentage(deltaL, L) : 0; + + return liq_percentage; +}; diff --git a/src/adaptors/solidly-v3/index.js b/src/adaptors/solidly-v3/index.js new file mode 100644 index 0000000000..5682052d38 --- /dev/null +++ b/src/adaptors/solidly-v3/index.js @@ -0,0 +1,193 @@ +const utils = require('../utils'); +const { + fetch_pools, + fetch_prices, + block_24h_ago, + pool_state_changes, + get_solid, + bn_to_float, + getPoolTicks, + get_graph_url, +} = require('./queries.ts'); +// const { EstimateActiveLiq } = require('./estimateActiveLiq.ts'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); + +const ZERO = ethers.BigNumber.from(0); + +// - All pools (subgraph) [X] +// - Solid Emissions per pool (subgraph) [X] +// - lp token incentives per pool (subgraph) [X] +// - prices of tokens in usd (the defilama api call) [X] +// - Fee change events for pools (on chain call) [X] +// - Swap events for pools (on chain call) [X] +// - get fee of the pool at start of the period [X] +// - get total fee for each token for period (accounted for pool fee changes) [X] +// - get start liq of the pool for tvl [X] +// - get how much token the active liq is worth [X] -> Use uniswap v3 adapter code +// then active liq range can be inferred from swaps +// - price the token liq and fee liq [X] +// - get active token emissions [X] +// - get active solidly emissions [X] +// +// - Balances of pools (range inferred from swap events and use total liquidity indexed by tick then added) + +function pool_input(pool, x) { + let price = Math.abs( + ethers.FixedNumber.from(x.amount1.toString()) + .divUnsafe(ethers.FixedNumber.from(x.amount0.toString())) + .toUnsafeFloat() + ); + if (x.amount0 > ZERO) { + return { token: pool.token0.id.toLowerCase(), input: x.amount0, price }; + } else { + return { token: pool.token1.id.toLowerCase(), input: x.amount1, price }; + } +} + +const main = async (timestamp = null) => { + if (timestamp == null) { + timestamp = Math.floor(Date.now() / 1000.0); + } + const block_start = await block_24h_ago(timestamp); + let { pools, touched_tokens } = await fetch_pools(timestamp); + let prices = await fetch_prices(touched_tokens); + pools = pools + .map((x) => { + let t0 = x.token0.id.toLowerCase(); + let t1 = x.token1.id.toLowerCase(); + if (!(t0 in prices) || !(t1 in prices)) { + return []; + } + x.t0 = prices[t0]; + x.t1 = prices[t1]; + x[t0] = prices[t0]; + x[t1] = prices[t1]; + x.t0_usd = parseFloat(x.totalValueLockedToken0) * x.t0?.price; + x.t1_usd = parseFloat(x.totalValueLockedToken1) * x.t1?.price; + x.tvl = x.t0_usd + x.t1_usd; + return [x]; + }) + .flat(); + // console.log('pools lenght', pools.length); + + let data = ( + await Promise.all( + pools.map(async (pool) => { + let { begin_fee, state_changes, begin_liq } = await pool_state_changes( + pool.id, + block_start + ); + let current_fee = begin_fee; + let fee_per_token = {}; + + fee_per_token[pool.token0.id.toLowerCase()] = ZERO; + fee_per_token[pool.token1.id.toLowerCase()] = ZERO; + + let touched_prices = []; + for (let s of state_changes) { + // console.log(s); + if (s.event == 'Swap') { + // have to take fee from the positive amount + let pool_in = pool_input(pool, s.args); + touched_prices.push(pool_in?.price); + let swap_fee = pool_in.input + .mul(current_fee) + .div(ethers.BigNumber.from(1_000_000)); + + fee_per_token[pool_in.token] = + fee_per_token[pool_in.token].add(swap_fee); + + // console.log('got swap'); + } else if (s.event == 'SetFee') { + current_fee = ethers.BigNumber.from(s.args.feeNew); + } + } + + let delta = 0.3; + // get the more accurate delta using the prices from the swaps + // if (touched_prices.length > 2) { + // let min = Math.min(...touched_prices); + // let max = Math.max(...touched_prices); + // delta = min / max; + // // console.log('NEW DELTA', pool.id, delta); + // } + let price_assumption = pool.t1.price / pool.t0.price; + // pool.active_liq_fraction = await EstimateActiveLiq( + // pool.id, + // price_assumption, + // [price_assumption * (1 - delta), price_assumption * (1 + delta)], + // pool.t1.price, + // pool.t0.price, + // pool.tvl, + // pool.t0.decimals, + // pool.t1.decimals, + // get_graph_url() + // ); + // console.log('ACTIVE LIQ', pool.id, delta, pool.active_liq_fraction); + + // reduce token fees to total fees in window + let total_fee_usd = 0.0; + for (let [k, v] of Object.entries(fee_per_token)) { + let fee_usd = bn_to_float(v, pool[k].decimals) * pool[k]?.price; + total_fee_usd += fee_usd; + } + pool.solid_per_year_usd = + bn_to_float(pool.solid_per_year, 18) * prices[get_solid()]?.price; + pool.rewardTokens = []; + pool.apyReward = 0.0; + if (pool.tvl != 0) { + // the active tvl adjustment for apy + // to undo just don't multiply by `active_liq_fraction` + // pool.active_tvl = pool.tvl * pool.active_liq_fraction; + pool.active_tvl = pool.tvl; + // 20% goes to protocol + pool.apyBase = (total_fee_usd / pool.active_tvl) * 365 * 100 * 0.8; + pool.apySolid = (pool.solid_per_year_usd / pool.tvl) * 100; + if (pool.apySolid != 0.0) { + pool.apyReward = pool.apySolid; + pool.rewardTokens.push(get_solid()); + } + pool.apyEmissions = 0.0; + for (let emission of pool.emissions_per_year) { + if (emission.token in prices) { + let token_obj = prices[emission.token]; + let per_year_usd = + bn_to_float(emission.per_year, token_obj.decimals) * + token_obj?.price; + pool.apyEmissions += (per_year_usd / pool.tvl) * 100; + pool.rewardTokens.push(emission.token); + pool.apyReward += pool.apyEmissions; + } + } + } + pool.symbol = `${pool.t0.symbol}-${pool.t1.symbol}`; + // console.log(pool); + return pool; + }) + ) + ).map((pool) => { + return { + pool: pool.id, + chain: 'ethereum', + project: 'solidly-v3', + symbol: pool.symbol, + tvlUsd: pool.tvl, + apyBase: pool.apyBase, + apyReward: pool.apyReward, + rewardTokens: [...new Set(pool.rewardTokens)], + url: `https://solidly.com/liquidity/manage/${pool.id}/`, + underlyingTokens: [pool.token0.id, pool.token1.id], + }; + }); + // console.log(data); + + // throw ''; + // console.log(data); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/solidly-v3/queries.ts b/src/adaptors/solidly-v3/queries.ts new file mode 100644 index 0000000000..f61fc40480 --- /dev/null +++ b/src/adaptors/solidly-v3/queries.ts @@ -0,0 +1,200 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); +const axios = require('axios'); +const ethers = require('ethers'); +const ABI = require('./abi'); + +const ZERO = ethers.BigNumber.from(0); + +const GRAPH = sdk.graph.modifyEndpoint('7StqFFqbxi3jcN5C9YxhRiTxQM8HA8XEHopsynqqxw3t'); +module.exports.get_graph_url = () => GRAPH; + +const GET_POOLS = gql` + { + pools(where: { sqrtPrice_gt: "0", liquidity_gt: "0" }) { + id + tick + totalValueLockedToken0 + totalValueLockedToken1 + tickSpacing + sqrtPrice + liquidity + token0 { + id + } + token1 { + id + } + lpSolidEmissions(where: {period_lte: }) { + period + amount + } + lpTokenIncentives(where: {periodStart_lte: }) { + periodStart + periodEnd + amount + token + } + } + } +`; + +module.exports.pool_state_changes = async (pool_id, block_start) => { + let provider = new ethers.providers.JsonRpcProvider( + process.env.ALCHEMY_CONNECTION_ETHEREUM, + 1 + ); + const contract = new ethers.Contract(pool_id, ABI, provider); + const begin_fee = ( + await contract.functions.slot0({ blockTag: block_start }) + )[2]; + // const begin_liq = ( + // await contract.functions.liquidity({ blockTag: block_start }) + // )[0]; + // console.log("begin liq", begin_liq); + const swaps = await contract.queryFilter( + contract.filters.Swap(), + block_start + ); + const fee_change = await contract.queryFilter( + contract.filters.SetFee(), + block_start + ); + let state_changes = [...swaps, ...fee_change]; + // Sort the state_changes array + state_changes.sort((a, b) => { + // Compare by blockNumber first + if (a.blockNumber < b.blockNumber) return -1; + if (a.blockNumber > b.blockNumber) return 1; + // If blockNumbers are the same, compare by logIndex + if (a.logIndex < b.logIndex) return -1; + if (a.logIndex > b.logIndex) return 1; + return 0; + }); + return { + begin_fee, + // begin_liq, + state_changes, + }; +}; + +module.exports.block_24h_ago = async (now) => { + const end_24h = now; + const start_24h = end_24h - 3600 * 24; + return (await axios.get(`https://coins.llama.fi/block/ethereum/${start_24h}`)) + .data.height; +}; + +const SOLID = '0x777172d858dc1599914a1c4c6c9fc48c99a60990'.toLowerCase(); + +// wow js what a concept +function bn_to_float(v, decimals) { + v = ethers.FixedNumber.from(v.toString()); + return v + .divUnsafe( + ethers.FixedNumber.from(ethers.BigNumber.from(10.0).pow(decimals)) + ) + .toUnsafeFloat(); +} + +module.exports.bn_to_float = bn_to_float; +module.exports.get_solid = () => SOLID; + +// fetch all pools avb up to timestamp from subgraph +module.exports.fetch_pools = async (now) => { + const end_24h = now; + let week = 3600 * 24 * 7; + const one_week_before = end_24h - week; + const in_one_week = end_24h + week; + // const start_24h = end_24h - (3600 * 24); + // console.log("start_24h end_24h", start_24h, end_24h); + let holder = ''; + let res = await request( + GRAPH, + GET_POOLS.replace(holder, end_24h).replace(holder, end_24h) + ); + let touched_tokens = res.pools.flatMap((x) => [x.token0.id, x.token1.id]); + // add SOLID due to solid emissions + touched_tokens = [...touched_tokens, SOLID]; + return { + pools: res.pools.map((x) => { + // SOLID EMISSIONS + let latest = x.lpSolidEmissions + .map((x) => { + x.period = parseInt(x.period); + x.amount = ethers.BigNumber.from(x.amount); + return x; + }) + .filter((x) => x.period > one_week_before && x.period < in_one_week) + .reduce( + (max, current) => (current.period > max.period ? current : max), + { period: 0, amount: ZERO } + ); + x.solid_per_year = latest.amount.mul(ethers.BigNumber.from(52)); + + // TOKEN EMISSIONS = BRIBES + let now = end_24h; // for test: - 3600 * 24; + latest = x.lpTokenIncentives + .map((x) => { + x.periodStart = parseInt(x.periodStart); + x.periodEnd = parseInt(x.periodEnd); + x.amount = ethers.BigNumber.from(x.amount); + return x; + }) + .filter((x) => x.periodStart < x.periodEnd) + // start is smaller than now, end is bigger than now + .filter((x) => x.periodStart < now && x.periodEnd > now); + + x.emissions_per_year = []; + if (latest.length > 0) { + for (let emission of latest) { + // so that its available in prices + touched_tokens.push(emission.token); + x.emissions_per_year.push({ + ...emission, + // there is an edgecase here if emissions are for longer than year and token has little decimals + per_year: emission.amount + .mul(ethers.BigNumber.from(3600 * 24 * 365)) + .div( + ethers.BigNumber.from(emission.periodEnd - emission.periodStart) + ), + }); + } + } + + return x; + }), + touched_tokens, + }; +}; + +// fetch all prices now .. yes it is inaccurate for past queries +module.exports.fetch_prices = async (token_addr) => { + const set = new Set(token_addr.map((x) => x.toLowerCase())); + token_addr = [...set]; + // ex: https://coins.llama.fi/prices/current/ethereum:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + let idsSet = token_addr.map((x) => `ethereum:${x}`); + const maxSize = 50; + const pages = Math.ceil(idsSet.length / maxSize); + let prices = {}; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = idsSet + .slice(p * maxSize, maxSize * (p + 1)) + .join(',') + .replaceAll('/', ''); + prices = { + ...prices, + ...(await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + }; + } + let res = {}; + + Object.keys(prices).forEach((key) => { + // remove eth chain prefix + res[key.split(':')[1].toLowerCase()] = prices[key]; + }); + + return res; +}; diff --git a/src/adaptors/solv-basis-trading/index.js b/src/adaptors/solv-basis-trading/index.js new file mode 100644 index 0000000000..d0da3707a3 --- /dev/null +++ b/src/adaptors/solv-basis-trading/index.js @@ -0,0 +1,150 @@ +const { default: request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); + +const chain = { + 1: 'ethereum', + 56: 'bsc', + 137: 'polygon', + 42161: 'arbitrum', + 1313161554: 'aurora', + 25: 'cronos', + 324: 'zksync_era', + 5000: 'mantle', + 60808: 'bob', +}; + +const poolsQuery = gql` + query Pools { + pools( + filter: { + poolStatus: "Active" + auditStatus: "Approved" + isUnlisted: false + saleStatus: ["Upcoming", "Fundraising", "Active"] + } + ) { + poolsInfo { + id + productInfo { + name + chainId + contractInfo { + contractAddress + } + } + currencyInfo { + symbol + currencyAddress + decimals + } + issuerInfo { + accountInfo { + username + } + } + poolOrderInfo { + poolId + } + aum + apy + additionalRewards + } + } + } +`; + +const headers = { Authorization: 'solv' }; + +const poolsFunction = async () => { + const pools = ( + await request('https://sft-api.com/graphql', poolsQuery, null, headers) + ).pools; + const pricesArray = pools.poolsInfo.map( + (t) => `${chain[t.productInfo.chainId]}:${t.currencyInfo.currencyAddress}` + ); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + const poolConfiguration = ( + await axios.get( + `https://raw.githubusercontent.com/solv-finance/solv-protocol-defillama/refs/heads/main/pools.json` + ) + ).data; + + let ustPool = []; + for (const pool of pools.poolsInfo) { + if (poolConfiguration.filterOut.indexOf(pool.poolOrderInfo.poolId) !== -1) { + continue; + } + + const marketContractQuery = gql` + query Pools { + marketContract(chainId:${pool.productInfo.chainId}, contractAddress: "${pool.productInfo.contractInfo.contractAddress}") { + decimals + marketContractAddress + defautFeeRate + } + } + `; + + const marketContract = ( + await request( + 'https://sft-api.com/graphql', + marketContractQuery, + null, + headers + ) + ).marketContract; + + let rewardApy = 0; + let rewardTokens = []; + JSON.parse(pool.additionalRewards).map(function (item, index) { + if ( + poolConfiguration.rewardTokenAddress[pool.productInfo.chainId]?.[ + item.symbol + ] + ) { + rewardTokens.push( + poolConfiguration.rewardTokenAddress[pool.productInfo.chainId]?.[ + item.symbol + ] + ); + rewardApy += item.apy / 100; + } + }); + + ustPool.push({ + pool: `${pool.poolOrderInfo.poolId.toLowerCase()}-${ + chain[pool.productInfo.chainId] + }`, + chain: chain[pool.productInfo.chainId], + project: `solv-basis-trading`, + symbol: pool.currencyInfo.symbol, + underlyingTokens: [pool.currencyInfo.currencyAddress], + tvlUsd: Number( + pool.aum * + prices[ + `${chain[pool.productInfo.chainId]}:${ + pool.currencyInfo.currencyAddress + }` + ]?.price + ), + apyBase: Number(pool.apy / 100) - Number(marketContract.defautFeeRate), + apyReward: rewardApy, + rewardTokens, + url: `https://app.solv.finance/earn/open-fund/detail/${pool.id}`, + poolMeta: pool.productInfo.name, + }); + } + + return ustPool.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.solv.finance/', +}; diff --git a/src/adaptors/sommelier/apy-subgraph.js b/src/adaptors/sommelier/apy-subgraph.js new file mode 100644 index 0000000000..90ffc743c5 --- /dev/null +++ b/src/adaptors/sommelier/apy-subgraph.js @@ -0,0 +1,70 @@ +// deprecated v2 apy implementations using subgraph + +// Calculate daily APY given a start and end time in seconds since epoch +// APY should only be calculated with data from a full day. To calculate today's +// APY, use the complete data from the previous 2 days. +async function calcApy(cellarAddress, startEpochSecs, endEpochSecs) { + // Returns hourData in desc order, current hour is index 0 + const hrData = await queries.getHourData( + cellarAddress, + startEpochSecs, + endEpochSecs + ); + + // How many seconds have elapsed today + const remainder = endEpochSecs % dayInSec; + // Start of the 2nd day + const startOfEnd = + remainder === 0 ? endEpochSecs - dayInSec : endEpochSecs - remainder; + + // Bucket hr datas by date + const dayBefore = hrData.filter((data) => data.date >= startOfEnd); + const twoDaysBefore = hrData.filter((data) => data.date < startOfEnd); + + // Sum hourly price of the last 2 days individually + let sumPrice = dayBefore.reduce((memo, data) => { + return memo.plus(data.shareValue); + }, new BigNumber(0)); + + let sumPrevPrice = twoDaysBefore.reduce((memo, data) => { + return memo.plus(data.shareValue); + }, new BigNumber(0)); + + // Calculate yesterday's yield + const price = sumPrice.div(dayBefore.length); + const prevPrice = sumPrevPrice.div(twoDaysBefore.length); + const yieldRatio = price.minus(prevPrice).div(prevPrice); + + const result = yieldRatio.times(365).times(100).toNumber(); + + return Number.isNaN(result) ? 0 : result; +} + +// Use the change in avg daily price between the last 2 days to calculate an APR +async function getApy(cellarAddress) { + const now = Math.floor(Date.now() / 1000); + const remainder = now % dayInSec; + const end = now - remainder - 1; + const start = end - dayInSec - dayInSec + 1; + + return calcApy(cellarAddress, start, end); +} + +const windowInDays = 7; + +async function getApy7d(cellarAddress) { + // Returns dayData in desc order, today is index 0 + const dayData = await queries.getDayData(cellarAddress, windowInDays); + + // Need a minimum of 7 days to calculate yield + if (dayData.length < 7) { + return 0; + } + + const price = new BigNumber(dayData[0].shareValue); // Now price + const prevPrice = new BigNumber(dayData[dayData.length - 1].shareValue); // Comparison price + const yieldRatio = price.minus(prevPrice).div(prevPrice); + + const result = yieldRatio.times(52).times(100).toNumber(); + return Number.isNaN(result) ? 0 : result; +} diff --git a/src/adaptors/sommelier/apy.js b/src/adaptors/sommelier/apy.js new file mode 100644 index 0000000000..cbdcf4e10c --- /dev/null +++ b/src/adaptors/sommelier/apy.js @@ -0,0 +1,147 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const cellarAbi = require('./cellar-v2.json'); +const { endOfYesterday, subDays } = require('date-fns'); +const utils = require('../utils'); + +const call = sdk.api.abi.call; + +const abiDecimals = cellarAbi.find((el) => el.name === 'decimals'); +const abiConvertToAssets = cellarAbi.find( + (el) => el.name === 'convertToAssets' +); + +const getPositionAssets = cellarAbi.find( + (el) => el.name === 'getPositionAssets' +); + +async function getBlockByEpoch(epochSecs, cellarChain) { + if (!Number.isInteger) { + throw new Error('getBlockByEpoch was not passed an integer'); + } + + const data = await utils.getData( + `https://coins.llama.fi/block/${cellarChain}/${epochSecs}` + ); + + return data.height; +} + +async function getShareValueAtBlock(cellarAddress, block, cellarChain) { + const decimals = ( + await call({ + target: cellarAddress, + abi: abiDecimals, + chain: cellarChain, + }) + ).output; + + const share = new BigNumber(10).pow(decimals); + + const shareValue = ( + await call({ + target: cellarAddress, + abi: abiConvertToAssets, + params: [share.toString()], + block, + chain: cellarChain, + }) + ).output; + + return new BigNumber(shareValue); +} + +async function calcApy( + cellarAddress, + startEpochSecs, + endEpochSecs, + intervalDays, + cellarChain +) { + const startBlock = await getBlockByEpoch(startEpochSecs, cellarChain); + const endBlock = await getBlockByEpoch(endEpochSecs, cellarChain); + + // APY 7 day may error out if share price oracle was not live for 7 days, so try catch here + // Note we dont do this in the daily APY because that should always work if we're live + // End Value should always work so only do this for start value + + let startValue; + try { + startValue = await getShareValueAtBlock( + cellarAddress, + startBlock, + cellarChain + ); + } catch (e) { + console.error( + 'Unable to get start value for calcApy cellar: ', + cellarAddress, + 'startBlock: ', + startBlock, + 'intervalDays: ', + intervalDays + ); + return 0; // Return 0 for APY if we can't get start value + } + + const endValue = await getShareValueAtBlock( + cellarAddress, + endBlock, + cellarChain + ); + + const yieldRatio = endValue.minus(startValue).div(startValue); + const result = yieldRatio + .times(365 / intervalDays) + .times(100) + .toNumber(); + + return Number.isNaN(result) ? 0 : result; +} + +function utcToday() { + const dateString = new Date().toISOString().split('T')[0]; + return new Date(`${dateString}T00:00:00.000Z`); +} + +function utcEndOfYesterday() { + const today = utcToday(); + return new Date(today.getTime() - 1000); +} + +async function getApy(cellarAddress, cellarChain) { + const yesterday = utcEndOfYesterday(); + const start = subDays(yesterday, 1); + + const yesterdayEpoch = Math.floor(yesterday.getTime() / 1000); + const startEpoch = Math.floor(start.getTime() / 1000); + + return calcApy(cellarAddress, startEpoch, yesterdayEpoch, 1, cellarChain); +} + +async function getApy7d(cellarAddress, cellarChain) { + const interval = 7; // days + const yesterday = utcEndOfYesterday(); + + // Subtract 6 days because we are including yesterday + const start = subDays(yesterday, interval - 1); + + const yesterdayEpoch = Math.floor(yesterday.getTime() / 1000); + const startEpoch = Math.floor(start.getTime() / 1000); + + return calcApy( + cellarAddress, + startEpoch, + yesterdayEpoch, + interval, + cellarChain + ); +} + +module.exports = { + getBlockByEpoch, + getShareValueAtBlock, + calcApy, + getApy, + getApy7d, +}; diff --git a/src/adaptors/sommelier/backfill.js b/src/adaptors/sommelier/backfill.js new file mode 100644 index 0000000000..04428fc42a --- /dev/null +++ b/src/adaptors/sommelier/backfill.js @@ -0,0 +1,44 @@ +const { calcApy } = require('./v2.js'); +const { v2Pools } = require('./config.js'); + +const cellarAddress = v2Pools[0].pool.split('-')[0]; + +const launchDate = new Date('2023-01-27T00:00:00.000Z'); + +const dayInSec = 60 * 60 * 24; +const dayInMs = dayInSec * 1000; + +const days = []; + +// Generate days +let day = new Date(); +while (day > launchDate) { + const epochSec = day.getTime(); + const remainder = epochSec % dayInMs; + const start = new Date( + remainder === 0 ? epochSec - dayInMs : epochSec - remainder + ); + + days.push(start); + day = start; +} + +// Convert to epoch seconds +const epochs = days.map((day) => Math.floor(day.getTime() / 1000)); + +// Get apys +const promises = epochs.map((epoch) => { + // Today's APY is calculated from yesterday's gains + const end = epoch - 1; // T11:59:99.000 + const start = epoch - dayInSec - dayInSec; // T00:00:00.000 + + return calcApy(cellarAddress, start, end); +}); + +(async function () { + const apys = await Promise.all(promises); + + for (let i = days.length - 1; i >= 0; i--) { + console.log(days[i].toISOString(), apys[i]); + } +})(); diff --git a/src/adaptors/sommelier/cellar-v0-8-15.json b/src/adaptors/sommelier/cellar-v0-8-15.json new file mode 100644 index 0000000000..8c4e511c0a --- /dev/null +++ b/src/adaptors/sommelier/cellar-v0-8-15.json @@ -0,0 +1,67 @@ +{ + "asset": { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalHoldings": { + "inputs": [], + "name": "totalHoldings", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalLocked": { + "inputs": [], + "name": "totalLocked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "maxLocked": { + "inputs": [], + "name": "maxLocked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/sommelier/cellar-v0-8-16.json b/src/adaptors/sommelier/cellar-v0-8-16.json new file mode 100644 index 0000000000..431850a1fb --- /dev/null +++ b/src/adaptors/sommelier/cellar-v0-8-16.json @@ -0,0 +1,41 @@ +{ + "holdingPosition": { + "inputs": [], + "name": "holdingPosition", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getPositions": { + "inputs": [], + "name": "getPositions", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/sommelier/cellar-v2.json b/src/adaptors/sommelier/cellar-v2.json new file mode 100644 index 0000000000..056c089965 --- /dev/null +++ b/src/adaptors/sommelier/cellar-v2.json @@ -0,0 +1,1960 @@ +[ + { + "inputs": [ + { + "internalType": "contract Registry", + "name": "_registry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + } + ], + "name": "Cellar__AdaptorNotSetUp", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedAsset", + "type": "address" + } + ], + "name": "Cellar__AssetMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__CallerNotAavePool", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ContractNotShutdown", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ContractShutdown", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__DebtMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDeposit", + "type": "uint256" + } + ], + "name": "Cellar__DepositRestricted", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ExternalInitiator", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "illiquidPosition", + "type": "address" + } + ], + "name": "Cellar__IlliquidWithdraw", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assetsOwed", + "type": "uint256" + } + ], + "name": "Cellar__IncompleteWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidFee", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidFeeCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "Cellar__InvalidHoldingPosition", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Cellar__InvalidRebalanceDeviation", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidShareLockPeriod", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "depositor", + "type": "address" + } + ], + "name": "Cellar__NotApprovedToDepositOnBehalf", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__PayoutNotSet", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__PositionAlreadyUsed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxPositions", + "type": "uint256" + } + ], + "name": "Cellar__PositionArrayFull", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "sharesRemaining", + "type": "uint256" + } + ], + "name": "Cellar__PositionNotEmpty", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__PositionNotUsed", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__RemovingHoldingPosition", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timeSharesAreUnlocked", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentBlock", + "type": "uint256" + } + ], + "name": "Cellar__SharesAreLocked", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Cellar__TotalAssetDeviatedOutsideRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "Cellar__TotalSharesMustRemainConstant", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ZeroAssets", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ZeroShares", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "oldPlatformFee", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "newPlatformFee", + "type": "uint64" + } + ], + "name": "PlatformFeeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition1", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition2", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index2", + "type": "uint256" + } + ], + "name": "PositionSwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldDeviation", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDeviation", + "type": "uint256" + } + ], + "name": "RebalanceDeviationChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "feesInSharesRedeemed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "feesInAssetsSent", + "type": "uint256" + } + ], + "name": "SendFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPeriod", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPeriod", + "type": "uint256" + } + ], + "name": "ShareLockingPeriodChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isShutdown", + "type": "bool" + } + ], + "name": "ShutdownChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPayoutAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPayoutAddress", + "type": "address" + } + ], + "name": "StrategistPayoutAddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "oldPlatformCut", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "newPlatformCut", + "type": "uint64" + } + ], + "name": "StrategistPlatformCutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GRAVITY_BRIDGE_REGISTRY_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAXIMUM_SHARE_LOCK_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE_CUT", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PLATFORM_FEE", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_POSITIONS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REBALANCE_DEVIATION", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINIMUM_SHARE_LOCK_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_ROUTER_REGISTRY_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aavePool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "configurationData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "addPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allowedRebalanceDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "assetRiskTolerance", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockExternalReceiver", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callData", + "type": "bytes[]" + } + ], + "internalType": "struct Cellar.AdaptorCall[]", + "name": "data", + "type": "tuple[]" + } + ], + "name": "callOnAdaptor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "creditPositions", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "debtPositions", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "premiums", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "params", + "type": "bytes" + } + ], + "name": "executeOperation", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeData", + "outputs": [ + { + "internalType": "uint64", + "name": "strategistPlatformCut", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "platformFee", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "lastAccrual", + "type": "uint64" + }, + { + "internalType": "address", + "name": "strategistPayoutAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreditPositions", + "outputs": [ + { + "internalType": "uint32[]", + "name": "", + "type": "uint32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDebtPositions", + "outputs": [ + { + "internalType": "uint32[]", + "name": "", + "type": "uint32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPositionAssets", + "outputs": [ + { + "internalType": "contract ERC20[]", + "name": "assets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "name": "getPositionData", + "outputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDebt", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "adaptorData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "configurationData", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "holdingPosition", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "params", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initiateShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAdaptorSetup", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "isPositionUsed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liftShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "locked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolRiskTolerance", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "contract Registry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "removePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sendFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "setHoldingPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "newPlatformFee", + "type": "uint64" + } + ], + "name": "setPlatformFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newDeviation", + "type": "uint256" + } + ], + "name": "setRebalanceDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLock", + "type": "uint256" + } + ], + "name": "setShareLockPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payout", + "type": "address" + } + ], + "name": "setStrategistPayoutAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "cut", + "type": "uint64" + } + ], + "name": "setStrategistPlatformCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_adaptor", + "type": "address" + } + ], + "name": "setupAdaptor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shareLockPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index1", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "index2", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "swapPositions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssetsWithdrawable", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userShareLockStartTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/sommelier/cellar-v2p5.json b/src/adaptors/sommelier/cellar-v2p5.json new file mode 100644 index 0000000000..2c49279485 --- /dev/null +++ b/src/adaptors/sommelier/cellar-v2p5.json @@ -0,0 +1,2173 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "contract Registry", + "name": "_registry", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "_asset", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint32", + "name": "_holdingPosition", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_holdingPositionConfig", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_initialDeposit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "_strategistPlatformCut", + "type": "uint64" + }, + { + "internalType": "uint192", + "name": "_shareSupplyCap", + "type": "uint192" + }, + { + "internalType": "address", + "name": "_balancerVault", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedAsset", + "type": "address" + } + ], + "name": "Cellar__AssetMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + } + ], + "name": "Cellar__CallToAdaptorNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__CallerNotApprovedToRebalance", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__CallerNotBalancerVault", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ContractNotShutdown", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ContractShutdown", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__DebtMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ExpectedAddressDoesNotMatchActual", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ExternalInitiator", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__FailedToForceOutPosition", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "illiquidPosition", + "type": "address" + } + ], + "name": "Cellar__IlliquidWithdraw", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assetsOwed", + "type": "uint256" + } + ], + "name": "Cellar__IncompleteWithdraw", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidFee", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidFeeCut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "Cellar__InvalidHoldingPosition", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Cellar__InvalidRebalanceDeviation", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__InvalidShareSupplyCap", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__MinimumConstructorMintNotMet", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__OracleFailure", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__Paused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__PositionAlreadyUsed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxPositions", + "type": "uint256" + } + ], + "name": "Cellar__PositionArrayFull", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "sharesRemaining", + "type": "uint256" + } + ], + "name": "Cellar__PositionNotEmpty", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__PositionNotInCatalogue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "position", + "type": "uint32" + } + ], + "name": "Cellar__PositionNotUsed", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__RemovingHoldingPosition", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__SettingValueToRegistryIdZeroIsProhibited", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ShareSupplyCapExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Cellar__TotalAssetDeviatedOutsideRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "Cellar__TotalSharesMustRemainConstant", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ZeroAssets", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ZeroShares", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "AdaptorCalled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "inCatalogue", + "type": "bool" + } + ], + "name": "AdaptorCatalogueAltered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAutomationActions", + "type": "address" + } + ], + "name": "Cellar__AutomationActionsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "inCatalogue", + "type": "bool" + } + ], + "name": "PositionCatalogueAltered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition1", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition2", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index2", + "type": "uint256" + } + ], + "name": "PositionSwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldDeviation", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDeviation", + "type": "uint256" + } + ], + "name": "RebalanceDeviationChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOracle", + "type": "address" + } + ], + "name": "SharePriceOracleUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isShutdown", + "type": "bool" + } + ], + "name": "ShutdownChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPayoutAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPayoutAddress", + "type": "address" + } + ], + "name": "StrategistPayoutAddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "oldPlatformCut", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "newPlatformCut", + "type": "uint64" + } + ], + "name": "StrategistPlatformCutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GRAVITY_BRIDGE_REGISTRY_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE_CUT", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PLATFORM_FEE", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_POSITIONS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REBALANCE_DEVIATION", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ORACLE_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PRICE_ROUTER_REGISTRY_SLOT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "adaptorCatalogue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + } + ], + "name": "addAdaptorToCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "configurationData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "addPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "addPositionToCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allowedRebalanceDeviation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "automationActions", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "balancerVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockExternalReceiver", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "checkTotalAssets", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "allowableRange", + "type": "uint16" + }, + { + "internalType": "address", + "name": "expectedPriceRouter", + "type": "address" + } + ], + "name": "cachePriceRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "internalType": "bytes[]", + "name": "callData", + "type": "bytes[]" + } + ], + "internalType": "struct Cellar.AdaptorCall[]", + "name": "data", + "type": "tuple[]" + } + ], + "name": "callOnAdaptor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "creditPositions", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "debtPositions", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint192", + "name": "_newShareSupplyCap", + "type": "uint192" + } + ], + "name": "decreaseShareSupplyCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeData", + "outputs": [ + { + "internalType": "uint64", + "name": "strategistPlatformCut", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "platformFee", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "lastAccrual", + "type": "uint64" + }, + { + "internalType": "address", + "name": "strategistPayoutAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "forcePositionOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCreditPositions", + "outputs": [ + { + "internalType": "uint32[]", + "name": "", + "type": "uint32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDebtPositions", + "outputs": [ + { + "internalType": "uint32[]", + "name": "", + "type": "uint32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "name": "getPositionData", + "outputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDebt", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "adaptorData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "configurationData", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "holdingPosition", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ignorePause", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint192", + "name": "_newShareSupplyCap", + "type": "uint192" + } + ], + "name": "increaseShareSupplyCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initiateShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "isPositionUsed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liftShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "locked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "name": "positionCatalogue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceRouter", + "outputs": [ + { + "internalType": "contract PriceRouter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "feeAmounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "receiveFlashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { + "internalType": "contract Registry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adaptor", + "type": "address" + } + ], + "name": "removeAdaptorFromCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "removePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "removePositionFromCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_registryId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_expectedAutomationActions", + "type": "address" + } + ], + "name": "setAutomationActions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + } + ], + "name": "setHoldingPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newDeviation", + "type": "uint256" + } + ], + "name": "setRebalanceDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_registryId", + "type": "uint256" + }, + { + "internalType": "contract ERC4626SharePriceOracle", + "name": "_sharePriceOracle", + "type": "address" + } + ], + "name": "setSharePriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payout", + "type": "address" + } + ], + "name": "setStrategistPayoutAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "cut", + "type": "uint64" + } + ], + "name": "setStrategistPlatformCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharePriceOracle", + "outputs": [ + { + "internalType": "contract ERC4626SharePriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "shareSupplyCap", + "outputs": [ + { + "internalType": "uint192", + "name": "", + "type": "uint192" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "index1", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "index2", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "inDebtArray", + "type": "bool" + } + ], + "name": "swapPositions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "toggleIgnorePause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssetsWithdrawable", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "viewPositionBalances", + "outputs": [ + { + "internalType": "contract ERC20[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + }, + { + "internalType": "bool[]", + "name": "isDebt", + "type": "bool[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] + diff --git a/src/adaptors/sommelier/cellar-v2p6.json b/src/adaptors/sommelier/cellar-v2p6.json new file mode 100644 index 0000000000..5ae177a412 --- /dev/null +++ b/src/adaptors/sommelier/cellar-v2p6.json @@ -0,0 +1,1368 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { + "internalType": "contract Registry", + "name": "_registry", + "type": "address" + }, + { "internalType": "contract ERC20", "name": "_asset", "type": "address" }, + { "internalType": "string", "name": "_name", "type": "string" }, + { "internalType": "string", "name": "_symbol", "type": "string" }, + { + "internalType": "uint32", + "name": "_holdingPosition", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_holdingPositionConfig", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_initialDeposit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "_strategistPlatformCut", + "type": "uint64" + }, + { + "internalType": "uint192", + "name": "_shareSupplyCap", + "type": "uint192" + }, + { "internalType": "address", "name": "_balancerVault", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CellarWithMultiAssetDeposit__AlternativeAssetFeeTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "CellarWithMultiAssetDeposit__AlternativeAssetNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "CellarWithMultiAssetDeposit__CallDataLengthNotSupported", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "expectedAsset", "type": "address" } + ], + "name": "Cellar__AssetMismatch", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "adaptor", "type": "address" } + ], + "name": "Cellar__CallToAdaptorNotAllowed", + "type": "error" + }, + { "inputs": [], "name": "Cellar__CallerNotBalancerVault", "type": "error" }, + { "inputs": [], "name": "Cellar__ContractNotShutdown", "type": "error" }, + { "inputs": [], "name": "Cellar__ContractShutdown", "type": "error" }, + { + "inputs": [ + { "internalType": "uint32", "name": "position", "type": "uint32" } + ], + "name": "Cellar__DebtMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "Cellar__ExpectedAddressDoesNotMatchActual", + "type": "error" + }, + { "inputs": [], "name": "Cellar__ExternalInitiator", "type": "error" }, + { "inputs": [], "name": "Cellar__FailedToForceOutPosition", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "illiquidPosition", + "type": "address" + } + ], + "name": "Cellar__IlliquidWithdraw", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assetsOwed", "type": "uint256" } + ], + "name": "Cellar__IncompleteWithdraw", + "type": "error" + }, + { "inputs": [], "name": "Cellar__InvalidFee", "type": "error" }, + { "inputs": [], "name": "Cellar__InvalidFeeCut", "type": "error" }, + { + "inputs": [ + { "internalType": "uint32", "name": "positionId", "type": "uint32" } + ], + "name": "Cellar__InvalidHoldingPosition", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "requested", "type": "uint256" }, + { "internalType": "uint256", "name": "max", "type": "uint256" } + ], + "name": "Cellar__InvalidRebalanceDeviation", + "type": "error" + }, + { "inputs": [], "name": "Cellar__InvalidShareSupplyCap", "type": "error" }, + { + "inputs": [], + "name": "Cellar__MinimumConstructorMintNotMet", + "type": "error" + }, + { "inputs": [], "name": "Cellar__OracleFailure", "type": "error" }, + { "inputs": [], "name": "Cellar__Paused", "type": "error" }, + { + "inputs": [ + { "internalType": "uint32", "name": "position", "type": "uint32" } + ], + "name": "Cellar__PositionAlreadyUsed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "maxPositions", "type": "uint256" } + ], + "name": "Cellar__PositionArrayFull", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "position", "type": "uint32" }, + { + "internalType": "uint256", + "name": "sharesRemaining", + "type": "uint256" + } + ], + "name": "Cellar__PositionNotEmpty", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "position", "type": "uint32" } + ], + "name": "Cellar__PositionNotInCatalogue", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "position", "type": "uint32" } + ], + "name": "Cellar__PositionNotUsed", + "type": "error" + }, + { "inputs": [], "name": "Cellar__RemovingHoldingPosition", "type": "error" }, + { + "inputs": [], + "name": "Cellar__SettingValueToRegistryIdZeroIsProhibited", + "type": "error" + }, + { "inputs": [], "name": "Cellar__ShareSupplyCapExceeded", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "uint256", "name": "min", "type": "uint256" }, + { "internalType": "uint256", "name": "max", "type": "uint256" } + ], + "name": "Cellar__TotalAssetDeviatedOutsideRange", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "current", "type": "uint256" }, + { "internalType": "uint256", "name": "expected", "type": "uint256" } + ], + "name": "Cellar__TotalSharesMustRemainConstant", + "type": "error" + }, + { "inputs": [], "name": "Cellar__ZeroAssets", "type": "error" }, + { "inputs": [], "name": "Cellar__ZeroShares", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "AdaptorCalled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "adaptor", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "inCatalogue", + "type": "bool" + } + ], + "name": "AdaptorCatalogueAltered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AlternativeAssetDropped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "holdingPosition", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "depositFee", + "type": "uint32" + } + ], + "name": "AlternativeAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "depositAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "MultiAssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "positionId", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "inCatalogue", + "type": "bool" + } + ], + "name": "PositionCatalogueAltered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "position", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PositionRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition1", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newPosition2", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index2", + "type": "uint256" + } + ], + "name": "PositionSwapped", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldDeviation", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDeviation", + "type": "uint256" + } + ], + "name": "RebalanceDeviationChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOracle", + "type": "address" + } + ], + "name": "SharePriceOracleUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isShutdown", + "type": "bool" + } + ], + "name": "ShutdownChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPayoutAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPayoutAddress", + "type": "address" + } + ], + "name": "StrategistPayoutAddressChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "oldPlatformCut", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "newPlatformCut", + "type": "uint64" + } + ], + "name": "StrategistPlatformCutChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "adaptor", "type": "address" } + ], + "name": "addAdaptorToCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "index", "type": "uint32" }, + { "internalType": "uint32", "name": "positionId", "type": "uint32" }, + { "internalType": "bytes", "name": "configurationData", "type": "bytes" }, + { "internalType": "bool", "name": "inDebtArray", "type": "bool" } + ], + "name": "addPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "positionId", "type": "uint32" } + ], + "name": "addPositionToCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "name": "alternativeAssetData", + "outputs": [ + { "internalType": "bool", "name": "isSupported", "type": "bool" }, + { "internalType": "uint32", "name": "holdingPosition", "type": "uint32" }, + { "internalType": "uint32", "name": "depositFee", "type": "uint32" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { "internalType": "contract ERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockExternalReceiver", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "checkTotalAssets", "type": "bool" }, + { "internalType": "uint16", "name": "allowableRange", "type": "uint16" }, + { + "internalType": "address", + "name": "expectedPriceRouter", + "type": "address" + } + ], + "name": "cachePriceRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "adaptor", "type": "address" }, + { "internalType": "bytes[]", "name": "callData", "type": "bytes[]" } + ], + "internalType": "struct Cellar.AdaptorCall[]", + "name": "data", + "type": "tuple[]" + } + ], + "name": "callOnAdaptor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "convertToAssets", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "convertToShares", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint192", + "name": "_newShareSupplyCap", + "type": "uint192" + } + ], + "name": "decreaseShareSupplyCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_alternativeAsset", + "type": "address" + } + ], + "name": "dropAlternativeAssetData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeData", + "outputs": [ + { + "internalType": "uint64", + "name": "strategistPlatformCut", + "type": "uint64" + }, + { "internalType": "uint64", "name": "platformFee", "type": "uint64" }, + { "internalType": "uint64", "name": "lastAccrual", "type": "uint64" }, + { + "internalType": "address", + "name": "strategistPayoutAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "index", "type": "uint32" }, + { "internalType": "uint32", "name": "positionId", "type": "uint32" }, + { "internalType": "bool", "name": "inDebtArray", "type": "bool" } + ], + "name": "forcePositionOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCreditPositions", + "outputs": [{ "internalType": "uint32[]", "name": "", "type": "uint32[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDebtPositions", + "outputs": [{ "internalType": "uint32[]", "name": "", "type": "uint32[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "holdingPosition", + "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ignorePause", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint192", + "name": "_newShareSupplyCap", + "type": "uint192" + } + ], + "name": "increaseShareSupplyCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initiateShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "isPositionUsed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liftShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "locked", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDeposit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxRedeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "maxWithdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "depositAsset", + "type": "address" + }, + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "multiAssetDeposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bytes", "name": "", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewDeposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewMint", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "depositAsset", + "type": "address" + }, + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewMultiAssetDeposit", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "name": "previewRedeem", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "name": "previewWithdraw", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceRouter", + "outputs": [ + { "internalType": "contract PriceRouter", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { + "internalType": "uint256[]", + "name": "feeAmounts", + "type": "uint256[]" + }, + { "internalType": "bytes", "name": "userData", "type": "bytes" } + ], + "name": "receiveFlashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "redeem", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registry", + "outputs": [ + { "internalType": "contract Registry", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "adaptor", "type": "address" } + ], + "name": "removeAdaptorFromCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "index", "type": "uint32" }, + { "internalType": "bool", "name": "inDebtArray", "type": "bool" } + ], + "name": "removePosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "positionId", "type": "uint32" } + ], + "name": "removePositionFromCatalogue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_alternativeAsset", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_alternativeHoldingPosition", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "_alternativeAssetFee", + "type": "uint32" + } + ], + "name": "setAlternativeAssetData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "positionId", "type": "uint32" } + ], + "name": "setHoldingPosition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "newDeviation", "type": "uint256" } + ], + "name": "setRebalanceDeviation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_registryId", "type": "uint256" }, + { + "internalType": "contract ERC4626SharePriceOracle", + "name": "_sharePriceOracle", + "type": "address" + } + ], + "name": "setSharePriceOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "payout", "type": "address" } + ], + "name": "setStrategistPayoutAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint64", "name": "cut", "type": "uint64" }], + "name": "setStrategistPlatformCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharePriceOracle", + "outputs": [ + { + "internalType": "contract ERC4626SharePriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "shareSupplyCap", + "outputs": [{ "internalType": "uint192", "name": "", "type": "uint192" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint32", "name": "index1", "type": "uint32" }, + { "internalType": "uint32", "name": "index2", "type": "uint32" }, + { "internalType": "bool", "name": "inDebtArray", "type": "bool" } + ], + "name": "swapPositions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "toggleIgnorePause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssetsWithdrawable", + "outputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "assets", "type": "uint256" }, + { "internalType": "address", "name": "receiver", "type": "address" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/sommelier/config.js b/src/adaptors/sommelier/config.js new file mode 100644 index 0000000000..6edcd52315 --- /dev/null +++ b/src/adaptors/sommelier/config.js @@ -0,0 +1,555 @@ +const { arbitrum } = require('../paraspace-lending-v1/address'); + +const project = 'sommelier'; + +// Ethereum Addresses +const defiStars = '0x03df2a53cbed19b824347d6a45d09016c2d1676a'; +const realYieldUsd = '0x97e6e0a40a3d02f12d1cec30ebfbae04e37c119e'; +const realYieldEth = '0xb5b29320d2dde5ba5bafa1ebcd270052070483ec'; +const realYieldLINK = '0x4068bdd217a45f8f668ef19f1e3a1f043e4c4934'; +const realYield1INCH = '0xc7b69e15d86c5c1581dacce3cacaf5b68cd6596f'; +const realYieldUNI = '0x6a6af5393dc23d7e3db28d28ef422db7c40932b6'; +const realYieldSNX = '0xcbf2250f33c4161e18d4a2fa47464520af5216b5'; +const realYieldENS = '0x18ea937aba6053bc232d9ae2c42abe7a8a2be440'; +const fraximal = '0xdbe19d1c3f21b1bb250ca7bdae0687a97b5f77e6'; +const realYieldBtc = '0x0274a704a6d9129f90a62ddc6f6024b33ecdad36'; +const turbosweth = '0xd33dad974b938744dac81fe00ac67cb5aa13958e'; +const turbogho = '0x0c190ded9be5f512bd72827bdad4003e9cc7975c'; +const ethgrowth = '0x6c51041a91c91c86f3f08a72cb4d3f67f1208897'; +const turbosteth = '0xfd6db5011b171b05e1ea3b92f9eacaeeb055e971'; +const turbosomm = '0x5195222f69c5821f8095ec565e71e18ab6a2298f'; +const turboeeth = '0x9a7b4980C6F0FCaa50CD5f288Ad7038f434c692e'; +const turbostethstethDeposit = '0xc7372Ab5dd315606dB799246E8aA112405abAeFf'; +const morphomaximiser = '0xcf4B531b4Cde95BD35d71926e09B2b54c564F5b6'; +const turbodiveth = '0x6c1edce139291Af5b84fB1e496c9747F83E876c9'; +const turboethx = '0x19B8D8FC682fC56FbB42653F68c7d48Dd3fe597E'; +const turboeethv2 = '0xdAdC82e26b3739750E036dFd9dEfd3eD459b877A'; +const turborseth = '0x1dffb366b5c5A37A12af2C127F31e8e0ED86BDbe'; +const turboezeth = '0x27500de405a3212d57177a789e30bb88b0adbec5'; + +// Arbitrum addresses +const realYieldEth_arbitrum = '0xC47bB288178Ea40bF520a91826a3DEE9e0DbFA4C'; +const realYieldUsd_arbitrum = '0x392B1E6905bb8449d26af701Cdea6Ff47bF6e5A8'; + +// Optimism addresses +const realYieldEth_optimism = "0xC47bB288178Ea40bF520a91826a3DEE9e0DbFA4C" + +// Rewards on ethereum are paid out in EVM SOMM +const ethRewardTokens = ['0xa670d7237398238de01267472c6f13e5b8010fd1']; + + +// Rewards on arbitrum are paid out in axlSOMM +const arbitrumRewardTokens = ['0x4e914bbDCDE0f455A8aC9d59d3bF739c46287Ed2']; + + +// Rewards on optimism are paid out in axlSOMM +const optimismRewardTokens = ['0x4e914bbDCDE0f455A8aC9d59d3bF739c46287Ed2']; + +// Map of Cellars -> Staking Pool +const stakingPools = { + ethereum: { + '0x7bad5df5e11151dc5ee1a648800057c5c934c0d5': + '0x24691a00779d375A5447727E1610d327D04B3C5F', + '0x3f07a84ecdf494310d397d24c1c78b041d2fa622': + '0xae0e6024972b70601bc35405479af5cd372cc956', + '0x4986fd36b6b16f49b43282ee2e24c5cf90ed166d': + '0xd1d02c16874e0714fd825213e0c13eab6dd9c25f', + '0x6b7f87279982d919bbf85182ddeab179b366d8f2': + '0x9eeabfff5d15e8cedfd2f6c914c8826ba0a5fbbd', + '0x6e2dac3b9e9adc0cbbae2d0b9fd81952a8d33872': + '0x6ce314c39f30488b4a86b8892c81a5b7af83e337', + '0x6f069f711281618467dae7873541ecc082761b33': + '0x74a9a6fab61e128246a6a5242a3e96e56198cbdd', + '0x05641a27c82799aaf22b436f20a3110410f29652': + '0x7da7e27e4bcc6ec8bc06349e1cef6634f6df7c5c', + [realYieldUsd]: '0x8510f22bd1932afb4753b6b3edf5db00c7e7a748', + [realYieldEth]: '0x955a31153e6764fe892757ace79123ae996b0afb', + [realYieldBtc]: '0x1eff374fd9aa7266504144da861fff9bbd31828e', + [defiStars]: '0x0349b3c56adb9e39b5d75fc1df52eee313dd80d1', + [fraximal]: '0x290a42e913083edf5aefb241f8a12b306c19f8f9', + [turbosweth]: '0x69374d81fdc42add0fe1dc655705e40b51b6681b', + [turbogho]: '0x6e5bb558d6c33ca45dc9efe0746a3c80bc3e70e1', + [ethgrowth]: '0xb1D3948F4DCd7Aa5e89449080F3D88870aD0137A', + // TODO: If we add staking pool for turbo steth, add it here + // TODO: If we add staking pool for turbo somm, add it here + [turboeeth]: '0x596c3f05ba9c6c356527e47989b3ed26e2b3449d', + // TODO: If we add staking pool for turbo steth (steth deposit), add it here + [morphomaximiser]: '0xe468c1156d4b3399e4Aa1080c58fFBc6119722F9', + // TODO: If we add staking pool for turbo diveth, add it here + [turboethx]: '0x88EDf544b5d4Ba6A11D40375e4bAEf3f1Ec5aF11', + // TODO: If we add staking pool for turbo eethv2, add it here + [turborseth]: '0xC6b423E3D25e6B36ab60Fa2c91FF344877F8Ead2', + [turboezeth]: '0x4705F50b9c6CdffC6528ba6B3754106eE820997E', + }, + arbitrum: { + [realYieldEth_arbitrum]: '0xd700D39be88fB6b54311f95cCA949C3f6835e236', + [realYieldUsd_arbitrum]: '0x623987D3CC0d504782bc99BBAc7965fe54917D7D', + + + + }, + optimism: { + [realYieldEth_optimism]: '0xd700D39be88fB6b54311f95cCA949C3f6835e236', + }, +}; + +// List of v0815 Cellars +const v0815Pools = [ + { + pool: '0x7bad5df5e11151dc5ee1a648800057c5c934c0d5-ethereum', + chain: 'ethereum', + project, + symbol: 'USDC', + poolMeta: 'aave2-CLR-S', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/AAVE/manage', + }, +]; + +// List of v0816 Cellars +const v0816Pools = [ + { + pool: '0x6b7f87279982d919bbf85182ddeab179b366d8f2-ethereum', + chain: 'ethereum', + project, + symbol: 'ETH-BTC', + poolMeta: 'ETHBTCTrend', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/ETH-BTC-Trend', + }, + { + pool: '0x6e2dac3b9e9adc0cbbae2d0b9fd81952a8d33872-ethereum', + chain: 'ethereum', + project, + symbol: 'ETH-BTC', + poolMeta: 'ETHBTCMom', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/ETH-BTC-Momentum', + }, + { + pool: '0x3f07a84ecdf494310d397d24c1c78b041d2fa622-ethereum', + chain: 'ethereum', + project, + symbol: 'ETH', + poolMeta: 'SteadyETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Steady-ETH', + }, + { + pool: '0x4986fd36b6b16f49b43282ee2e24c5cf90ed166d-ethereum', + chain: 'ethereum', + project, + symbol: 'BTC', + poolMeta: 'SteadyBTC', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Steady-BTC', + }, + { + pool: '0x6f069f711281618467dae7873541ecc082761b33-ethereum', + chain: 'ethereum', + project, + symbol: 'UNI', + poolMeta: 'SteadyUNI', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Steady-UNI', + }, + { + pool: '0x05641a27c82799aaf22b436f20a3110410f29652-ethereum', + chain: 'ethereum', + project, + symbol: 'MATIC', + poolMeta: 'SteadyMATIC', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Steady-MATIC', + }, +]; + +const v2Pools = [ + { + pool: `${defiStars}-ethereum`, + chain: 'ethereum', + project, + symbol: 'USDC-CRV-AAVE-COMP-MKR-LDO', + poolMeta: 'DeFiStars', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/DeFi-Stars', + }, + { + pool: `${realYieldUsd}-ethereum`, + chain: 'ethereum', + project, + symbol: 'USDC-USDT-DAI', + poolMeta: 'RealYieldUSD', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-USD', + }, + { + pool: `${realYieldEth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-stETH-cbETH-rETH', + poolMeta: 'RealYieldETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-ETH', + }, + { + pool: `${realYieldLINK}-ethereum`, + chain: 'ethereum', + project, + symbol: 'LINK-WETH-YieldETH', + poolMeta: 'RealYieldLINK', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-LINK', + }, + { + pool: `${realYield1INCH}-ethereum`, + chain: 'ethereum', + project, + symbol: '1INCH-WETH-YieldETH', + poolMeta: 'RealYield1INCH', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-1Inch', + }, + { + pool: `${realYieldUNI}-ethereum`, + chain: 'ethereum', + project, + symbol: 'UNI-WETH-YieldETH', + poolMeta: 'RealYield1UNI', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-UNI', + }, + { + pool: `${realYieldSNX}-ethereum`, + chain: 'ethereum', + project, + symbol: 'SNX-WETH-YieldETH', + poolMeta: 'RealYieldSNX', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-SNX', + }, + { + pool: `${realYieldENS}-ethereum`, + chain: 'ethereum', + project, + symbol: 'ENS-WETH-YieldETH', + poolMeta: 'RealYieldENS', + tvlUsd: 0, + apyBase: 0, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-ENS', + }, + { + pool: `${fraximal}-ethereum`, + chain: 'ethereum', + project, + symbol: 'FRAX', + poolMeta: 'Fraximal', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Fraximal', + }, + { + pool: `${realYieldBtc}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WBTC', + poolMeta: 'RealYieldBTC', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Real-Yield-BTC', + }, +]; + +const v2p5Pools = [ + { + pool: `${turbosweth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-SWETH', + poolMeta: 'TurboSWETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-SWETH', + }, + { + pool: `${turbogho}-ethereum`, + chain: 'ethereum', + project, + symbol: 'GHO-USDC-USDT-DAI-LUSD', + poolMeta: 'TurboGHO', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-GHO', + }, + { + pool: `${turbosteth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-STETH-WSTETH', + poolMeta: 'TurboSTETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-STETH', + }, + { + pool: `${ethgrowth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'USDC-YieldUSD-YieldETH', + poolMeta: 'ETH Trend Growth', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/ETH-Trend-Growth', + }, + // { + // pool: `${turbosomm}-ethereum`, + // chain: 'ethereum', + // project, + // symbol: 'SOMM-WETH', + // poolMeta: 'TurboSOMM', + // tvlUsd: 0, + // apyBase: 0, + // apyReward: 0, + // rewardTokens: ethRewardTokens, + // underlyingTokens: [], + // url: 'https://app.sommelier.finance/strategies/Turbo-SOMM', + // }, + { + pool: `${turboeeth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-EETH', + poolMeta: 'TurboEETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-eETH', + }, + { + pool: `${turbostethstethDeposit}-ethereum`, + chain: 'ethereum', + project, + symbol: 'STETH-WSTETH-WETH', + poolMeta: 'TurboSTETH(stETHDeposit)', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-STETH-(steth-deposit)', + }, +]; + +// Minor version upgrade post v2p5, these require manually setting the underlying tokens +const v2p6Pools = [ + { + pool: `${morphomaximiser}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-STETH-WSTETH', + poolMeta: 'MorphoMaximiser', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [ + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', + '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + ], + url: 'https://app.sommelier.finance/strategies/Morpho-ETH/manage', + }, + { + pool: `${turbodiveth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'RETH_BPT-WETH-RETH', + poolMeta: 'TurboDivETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [ + '0x1E19CF2D73a72Ef1332C882F20534B6519Be0276', + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + '0xae78736Cd615f374D3085123A210448E74Fc6393', + ], + url: 'https://app.sommelier.finance/strategies/Turbo-divETH/manage', + }, + { + pool: `${turboethx}-ethereum`, + chain: 'ethereum', + project, + symbol: 'ETHx-WETH-wstETH', + poolMeta: 'TurboETHx', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [ + '0xA35b1B31Ce002FBF2058D22F30f95D405200A15b', + '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + ], + url: 'https://app.sommelier.finance/strategies/Turbo-ETHx/manage', + }, + { + pool: `${turboeethv2}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-EETH-WEETH', + poolMeta: 'TurboEETHv2', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-eETHV2/manage', + }, + { + pool: `${realYieldEth_arbitrum}-arbitrum`, + chain: 'arbitrum', + project, + symbol: 'WETH-wstETH-cbETH-rETH', + poolMeta: 'RealYieldETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: arbitrumRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/real-yield-eth-arb', + }, + { + pool: `${realYieldUsd_arbitrum}-arbitrum`, + chain: 'arbitrum', + project, + symbol: 'USDC-USDC.e-USDT-DAI', + poolMeta: 'RealYieldUSD', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: arbitrumRewardTokens, + underlyingTokens: ["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9","0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"], + url: 'https://app.sommelier.finance/strategies/real-yield-usd-arb', + }, + { + pool: `${turborseth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-RSETH', + poolMeta: 'TurborsETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-rsETH/manage', + }, + { + pool: `${turboezeth}-ethereum`, + chain: 'ethereum', + project, + symbol: 'WETH-EZETH', + poolMeta: 'TurboezETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: ethRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/Turbo-ezETH/manage', + }, + { + pool: `${realYieldEth_optimism}-optimism`, + chain: 'optimism', + project, + symbol: 'WETH-wstETH-cbETH-rETH', + poolMeta: 'RealYieldETH', + tvlUsd: 0, + apyBase: 0, + apyReward: 0, + rewardTokens: optimismRewardTokens, + underlyingTokens: [], + url: 'https://app.sommelier.finance/strategies/real-yield-eth-opt/manage', + }, +]; + +module.exports = { + project, + rewardTokens: ethRewardTokens, + stakingPools, + v0815Pools, + v0816Pools, + v2Pools, + v2p5Pools, + v2p6Pools, + realYieldEth, +}; diff --git a/src/adaptors/sommelier/index.js b/src/adaptors/sommelier/index.js new file mode 100644 index 0000000000..2ec5fe0e3f --- /dev/null +++ b/src/adaptors/sommelier/index.js @@ -0,0 +1,280 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { + stakingPools, + v0815Pools, + v0816Pools, + v2Pools, + v2p5Pools, + v2p6Pools, +} = require('./config'); +const v0815 = require('./v0-8-15'); +const v0816 = require('./v0-8-16'); +const v2 = require('./v2'); +const v2p5 = require('./v2p5'); +const v2p6 = require('./v2p6'); +const stakingAbi = require('./staking-v0-8-15.json'); + +const call = sdk.api.abi.call; + +// Get the Cellar address from pool notation +// : +function getCellarAddress(pool) { + return pool.pool.split('-')[0]; +} + +function getCellarChain(pool) { + return pool.pool.split('-')[1]; +} + +// Get a list of all Cellar holding positions +async function getHoldingPositions() { + const v1Assets = await Promise.all( + v0815Pools.map((pool) => + v0815 + .getUnderlyingTokens(getCellarAddress(pool), getCellarChain(pool)) + .then((tokens) => tokens[0]) + ) + ); + + const v15Assets = await Promise.all( + v0816Pools.map((pool) => v0816.getHoldingPosition(getCellarAddress(pool), getCellarChain(pool))) + ); + + const v2Assets = await Promise.all( + v2Pools.map((pool) => v2.getHoldingPosition(getCellarAddress(pool), getCellarChain(pool))) + ); + + const v2p5Assets = await Promise.all( + v2p5Pools.map((pool) => v2p5.getHoldingPosition(getCellarAddress(pool), getCellarChain(pool))) + ); + + const v2p6Assets = await Promise.all( + v2p6Pools.map((pool) => v2p6.getHoldingPosition(getCellarAddress(pool), getCellarChain(pool))) + ); + + const deduped = new Set([ + ...v1Assets, + ...v15Assets, + ...v2Assets, + ...v2p5Assets, + ...v2p6Assets, + ]); + + return Array.from(deduped); +} + +async function main() { + // Grab all holding positions across all cellars + const assets = await getHoldingPositions(); + + // List of holding position tokens and sommelier token + // ! Remember to add mapping for each chain + const tokens = [ + 'coingecko:sommelier', + ...assets.flatMap((a) => [`ethereum:${a}`, `arbitrum:${a}`]), + ]; + + // Fetch prices for all assets upfront + const prices = await utils.getPrices(tokens); + const sommPrice = prices.pricesBySymbol.somm; + + let promises = []; + // Calculate TVL, APRs (with rewards if applicable) for each cellar version + // V1 + promises = v0815Pools.map((pool) => handleV0815(pool, prices)); + + // V1.5 + promises = promises.concat( + v0816Pools.map((pool) => handleV0816(pool, prices)) + ); + + // V2 + promises = promises.concat(v2Pools.map((pool) => handleV2(pool, prices))); + + // V2.5 + promises = promises.concat(v2p5Pools.map((pool) => handleV2p5(pool, prices))); + + // V2.6 + promises = promises.concat(v2p6Pools.map((pool) => handleV2p6(pool, prices))); + + const pools = await Promise.all(promises); + + return pools; +} + +async function handleV0815(pool, prices) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + + const underlyingTokens = await v0815.getUnderlyingTokens( + cellarAddress, + cellarChain + ); + const asset = underlyingTokens[0]; // v0815 Cellar only holds one asset + const tvlUsd = await v0815.getTvlUsd(cellarAddress, asset, cellarChain); + const apyBase = await v0815.getApy(cellarAddress, cellarChain); + const assetPrice = prices.pricesByAddress[asset.toLowerCase()]; + const apyReward = await getRewardApy( + stakingPools[cellarChain][cellarAddress], + prices.pricesBySymbol.somm, + assetPrice, + cellarChain + ); + + return { + ...pool, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + poolMeta: + apyReward > 0 ? `${pool.poolMeta} - 3day Bonding Lock` : pool.poolMeta, + }; +} + +async function handleV0816(pool, prices) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + const underlyingTokens = await v0816.getUnderlyingTokens(cellarAddress, cellarChain); + const asset = await v0816.getHoldingPosition(cellarAddress, cellarChain); + const tvlUsd = await v0816.getTvlUsd(cellarAddress, asset, cellarChain); + const apyBase = await v0816.getApy(cellarAddress, cellarChain); + const assetPrice = prices.pricesByAddress[asset.toLowerCase()]; + const apyReward = await getRewardApy( + stakingPools[cellarChain][cellarAddress], + prices.pricesBySymbol.somm, + assetPrice, + cellarChain + ); + + return { + ...pool, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + poolMeta: + apyReward > 0 ? `${pool.poolMeta} - 3day Bonding Lock` : pool.poolMeta, + }; +} + +async function handleV2(pool, prices) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + const underlyingTokens = await v2.getUnderlyingTokens(cellarAddress, cellarChain); + + return handleV2plus(pool, prices, underlyingTokens); +} + +async function handleV2p5(pool, prices) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + const underlyingTokens = await v2p5.getUnderlyingTokens(cellarAddress, cellarChain); + + return handleV2plus(pool, prices, underlyingTokens); +} + +async function handleV2p6(pool, prices) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + + const underlyingTokens = await v2p6.getUnderlyingTokens(cellarAddress, cellarChain); + + return handleV2plus(pool, prices, underlyingTokens); +} + +async function handleV2plus(pool, prices, underlyingTokens) { + const cellarAddress = pool.pool.split('-')[0]; + const cellarChain = pool.pool.split('-')[1]; + + const asset = await v2.getHoldingPosition(cellarAddress, cellarChain); + const assetPrice = prices.pricesByAddress[asset.toLowerCase()]; + + const apyBase = await v2.getApy(cellarAddress, cellarChain); + const apyBase7d = await v2.getApy7d(cellarAddress, cellarChain); + + // getTvlUsd implementation hasn't changed since v1.5 (v0.8.16) + const tvlUsd = await v0816.getTvlUsd(cellarAddress, asset, cellarChain); + + const baseResult = { + ...pool, + tvlUsd, + apyBase, + apyBase7d, + underlyingTokens, + }; + + // return pool without apyReward if stakingPool is not configured + const stakingPool = stakingPools[cellarChain][cellarAddress]; + if (stakingPool == null) { + return baseResult; + } + + const apyReward = await getRewardApy( + stakingPools[cellarChain][cellarAddress], + prices.pricesBySymbol.somm, + assetPrice, + cellarChain + ); + + return { + ...baseResult, + apyReward, + poolMeta: + apyReward > 0 ? `${pool.poolMeta} - 3day Bonding Lock` : pool.poolMeta, + }; +} + +// Calculates Staking APY for v0815 staking contract currently used by all pools +async function getRewardApy(stakingPool, sommPrice, assetPrice, cellarChain) { + const rewardRateResult = ( + await call({ + target: stakingPool, + abi: stakingAbi.rewardRate, + chain: cellarChain, + }) + ).output; + const rewardRate = new BigNumber(rewardRateResult).div(1e6); + + const totalDepositWithBoostResult = ( + await call({ + target: stakingPool, + abi: stakingAbi.totalDepositsWithBoost, + chain: cellarChain, + }) + ).output; + let totalDepositsWithBoost = new BigNumber(totalDepositWithBoostResult).div( + 1e18 + ); + + totalDepositsWithBoost = totalDepositsWithBoost.times(assetPrice); + + const endTimestampResult = ( + await call({ + target: stakingPool, + abi: stakingAbi.endTimestamp, + chain: cellarChain, + }) + ).output; + const endTimestamp = parseInt(endTimestampResult, 10) * 1000; + const isStakingOngoing = Date.now() < endTimestamp; + if (!isStakingOngoing) { + return 0; + } + + const stakingApy = rewardRate + .times(sommPrice) + .div(totalDepositsWithBoost) + .times(365 * 24 * 60 * 60) + .times(100); + + return stakingApy.toNumber(); +} + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/sommelier/queries.js b/src/adaptors/sommelier/queries.js new file mode 100644 index 0000000000..395cac2515 --- /dev/null +++ b/src/adaptors/sommelier/queries.js @@ -0,0 +1,54 @@ +const { request, gql } = require('graphql-request'); + +const url = + 'https://subgraphs.sommelier.finance/subgraphs/name/peggyjv/cellars'; + +const dayDataQuery = gql` + { + cellarDayDatas( + where: {cellar: "" } + orderDirection: desc + orderBy: date, first: + ) { + date + shareValue + } + } +`; + +async function getDayData(cellarAddress, numDays) { + let query = dayDataQuery.replace('', cellarAddress); + query = query.replace('', numDays); + + const data = await request(url, query); + + return data.cellarDayDatas; +} + +const hourDataQuery = gql` + { + cellarHourDatas( + where: {cellar: "", date_gte: , date_lte: } + orderDirection: desc + orderBy: date + ) { + date + shareValue + } + } +`; + +async function getHourData(cellarAddress, startDate, endDate) { + let query = hourDataQuery.replace('', cellarAddress); + query = query.replace('', startDate); + query = query.replace('', endDate); + + const data = await request(url, query); + + return data.cellarHourDatas; +} + +module.exports = { + getDayData, + getHourData, +}; diff --git a/src/adaptors/sommelier/staking-v0-8-15.json b/src/adaptors/sommelier/staking-v0-8-15.json new file mode 100644 index 0000000000..c4d2d5c7e3 --- /dev/null +++ b/src/adaptors/sommelier/staking-v0-8-15.json @@ -0,0 +1,29 @@ +{ + "rewardRate": { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + "totalDepositsWithBoost": { + "inputs": [], + "name": "totalDepositsWithBoost", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + "endTimestamp": { + "inputs": [], + "name": "endTimestamp", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/sommelier/v0-8-15.js b/src/adaptors/sommelier/v0-8-15.js new file mode 100644 index 0000000000..9d410a3d10 --- /dev/null +++ b/src/adaptors/sommelier/v0-8-15.js @@ -0,0 +1,56 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const cellarAbi = require('./cellar-v0-8-15.json'); +const { getApy } = require('./apy'); + +const call = sdk.api.abi.call; + +async function getUnderlyingTokens(cellarAddress, cellarChain) { + const asset = ( + await call({ + target: cellarAddress, + abi: cellarAbi.asset, + chain: cellarChain, + }) + ).output; + + return [asset]; +} + +async function getTvlUsd(cellarAddress, assetAddress, cellarChain) { + // Total balance of asset held by the Cellar + const totalAssets = ( + await call({ + target: cellarAddress, + abi: cellarAbi.totalAssets, + chain: cellarChain, + }) + ).output; + + // Used to convert decimals + const decimals = ( + await call({ + target: assetAddress, + abi: 'erc20:decimals', + chain: cellarChain, + }) + ).output; + + const prices = (await utils.getPrices([assetAddress], cellarChain)).pricesByAddress; + const price = prices[assetAddress.toLowerCase()]; + + const total = new BigNumber(totalAssets); + + // balance * usd price converted from asset decimals + return total + .times(price) + .div(10 ** decimals) + .toNumber(); +} + +module.exports = { + getApy, + getUnderlyingTokens, + getTvlUsd, +}; diff --git a/src/adaptors/sommelier/v0-8-16.js b/src/adaptors/sommelier/v0-8-16.js new file mode 100644 index 0000000000..536fb64df9 --- /dev/null +++ b/src/adaptors/sommelier/v0-8-16.js @@ -0,0 +1,69 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const cellarAbi = require('./cellar-v0-8-16.json'); +const { getApy } = require('./apy'); + +const call = sdk.api.abi.call; + +// Call getPositions() to get a list of assets held by the Cellar +async function getUnderlyingTokens(cellarAddress, cellarChain) { + const assets = ( + await call({ + target: cellarAddress, + abi: cellarAbi.getPositions, + chain: cellarChain, + }) + ).output; + + return assets; +} + +async function getHoldingPosition(cellarAddress, cellarChain) { + const asset = ( + await call({ + target: cellarAddress, + abi: cellarAbi.holdingPosition, + chain: cellarChain, + }) + ).output; + + return asset; +} + +async function getTvlUsd(cellarAddress, assetAddress, cellarChain) { + // Represents the value of the Cellar's postitions denominated in the holding asset + const totalAssets = ( + await call({ + target: cellarAddress, + abi: cellarAbi.totalAssets, + chain: cellarChain, + }) + ).output; + + const decimals = ( + await call({ + target: assetAddress, + abi: 'erc20:decimals', + chain: cellarChain, + }) + ).output; + + const prices = (await utils.getPrices([assetAddress], cellarChain)).pricesByAddress; + const price = prices[assetAddress.toLowerCase()]; + + const total = new BigNumber(totalAssets); + + // value of cellar in holding position* usd price converted from asset decimals + return total + .times(price) + .div(10 ** decimals) + .toNumber(); +} + +module.exports = { + getApy, + getHoldingPosition, + getUnderlyingTokens, + getTvlUsd, +}; diff --git a/src/adaptors/sommelier/v2.js b/src/adaptors/sommelier/v2.js new file mode 100644 index 0000000000..e3f0fd78f5 --- /dev/null +++ b/src/adaptors/sommelier/v2.js @@ -0,0 +1,46 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const queries = require('./queries'); +const cellarAbi = require('./cellar-v2.json'); +const utils = require('../utils'); +const { getApy, getApy7d } = require('./apy'); + +const call = sdk.api.abi.call; + +const abiAsset = cellarAbi.find((el) => el.name === 'asset'); +const getPositionAssets = cellarAbi.find( + (el) => el.name === 'getPositionAssets' +); + +// Call getPositionAssets to get all the credit position's underlying assets +async function getUnderlyingTokens(cellarAddress, cellarChain) { + const assets = ( + await call({ + target: cellarAddress, + abi: getPositionAssets, + chain: cellarChain, + }) + ).output; + + // dedupe, different positions may have the same underlying + return [...new Set(assets)]; +} + +async function getHoldingPosition(cellarAddress, cellarChain) { + const asset = ( + await call({ + target: cellarAddress, + abi: abiAsset, + chain: cellarChain, + }) + ).output; + + return asset; +} + +module.exports = { + getApy, + getApy7d, + getHoldingPosition, + getUnderlyingTokens, +}; diff --git a/src/adaptors/sommelier/v2p5.js b/src/adaptors/sommelier/v2p5.js new file mode 100644 index 0000000000..af2c95a8c2 --- /dev/null +++ b/src/adaptors/sommelier/v2p5.js @@ -0,0 +1,30 @@ +const sdk = require('@defillama/sdk'); +const cellarAbi = require('./cellar-v2p5.json'); +const v2 = require('./v2'); + +const call = sdk.api.abi.call; + +const abiViewPositionBalances = cellarAbi.find( + (el) => el.name === 'viewPositionBalances' +); + +async function getUnderlyingTokens(cellarAddress, cellarChain) { + const result = ( + await call({ + target: cellarAddress, + abi: abiViewPositionBalances, + chain: cellarChain, + }) + ).output; + + // dedupe, different positions may have the same underlying + return [...new Set(result.assets)]; +} + +module.exports = { + calcApy: v2.calcApy, + getApy: v2.getApy, + getApy7d: v2.getApy7d, + getHoldingPosition: v2.getHoldingPosition, + getUnderlyingTokens, +}; diff --git a/src/adaptors/sommelier/v2p6.js b/src/adaptors/sommelier/v2p6.js new file mode 100644 index 0000000000..60ee2ab762 --- /dev/null +++ b/src/adaptors/sommelier/v2p6.js @@ -0,0 +1,21 @@ +const sdk = require('@defillama/sdk'); +const { v2p6Pools } = require('./config'); +const v2 = require('./v2'); + +const call = sdk.api.abi.call; + +async function getUnderlyingTokens(cellarAddress, cellarChain) { + // Find vault in v2p6Pools + const vault = v2p6Pools.find((pool) => pool.pool.split('-')[0].toLowerCase() === cellarAddress.toLowerCase() && pool.pool.split('-')[1].toLowerCase() === cellarChain.toLowerCase()); + + // Return the deduped underlying tokens + return [...new Set(vault.underlyingTokens)]; +} + +module.exports = { + calcApy: v2.calcApy, + getApy: v2.getApy, + getApy7d: v2.getApy7d, + getHoldingPosition: v2.getHoldingPosition, + getUnderlyingTokens, +}; diff --git a/src/adaptors/sonne-finance/abi.js b/src/adaptors/sonne-finance/abi.js new file mode 100644 index 0000000000..f596aeb517 --- /dev/null +++ b/src/adaptors/sonne-finance/abi.js @@ -0,0 +1,2948 @@ +module.exports = { + ercDelegator: [ + { inputs: [], name: 'AcceptAdminPendingAdminCheck', type: 'error' }, + { + inputs: [ + { internalType: 'uint256', name: 'actualAddAmount', type: 'uint256' }, + ], + name: 'AddReservesFactorFreshCheck', + type: 'error', + }, + { inputs: [], name: 'BorrowCashNotAvailable', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'BorrowComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'BorrowFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateAccrueBorrowInterestFailed', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateAccrueCollateralInterestFailed', + type: 'error', + }, + { inputs: [], name: 'LiquidateCloseAmountIsUintMax', type: 'error' }, + { inputs: [], name: 'LiquidateCloseAmountIsZero', type: 'error' }, + { inputs: [], name: 'LiquidateCollateralFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'LiquidateFreshnessCheck', type: 'error' }, + { inputs: [], name: 'LiquidateLiquidatorIsBorrower', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateRepayBorrowFreshFailed', + type: 'error', + }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'LiquidateSeizeComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'LiquidateSeizeLiquidatorIsBorrower', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'MintComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'MintFreshnessCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'RedeemComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'RedeemFreshnessCheck', type: 'error' }, + { inputs: [], name: 'RedeemTransferOutNotPossible', type: 'error' }, + { inputs: [], name: 'ReduceReservesAdminCheck', type: 'error' }, + { inputs: [], name: 'ReduceReservesCashNotAvailable', type: 'error' }, + { inputs: [], name: 'ReduceReservesCashValidation', type: 'error' }, + { inputs: [], name: 'ReduceReservesFreshCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'RepayBorrowComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'RepayBorrowFreshnessCheck', type: 'error' }, + { inputs: [], name: 'SetComptrollerOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetInterestRateModelFreshCheck', type: 'error' }, + { inputs: [], name: 'SetInterestRateModelOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetPendingAdminOwnerCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorAdminCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorBoundsCheck', type: 'error' }, + { inputs: [], name: 'SetReserveFactorFreshCheck', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'errorCode', type: 'uint256' }], + name: 'TransferComptrollerRejection', + type: 'error', + }, + { inputs: [], name: 'TransferNotAllowed', type: 'error' }, + { inputs: [], name: 'TransferNotEnough', type: 'error' }, + { inputs: [], name: 'TransferTooMuch', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'NO_ERROR', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'compLikeDelegatee', type: 'address' }, + ], + name: '_delegateCompLikeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isCToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract CTokenInterface', + name: 'cTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + { internalType: 'address payable', name: 'admin_', type: 'address' }, + ], + name: 'proxyInitialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], + distributorAbi: [ + { + inputs: [ + { internalType: 'address', name: '_comptroller', type: 'address' }, + { internalType: 'address', name: '_admin', type: 'address' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'lnIncentiveToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'blockNumber', + type: 'uint256', + }, + ], + name: 'LnIncentiveTokenUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'SingleAssetDynamicRainMakerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'uint256', name: 'compSupplySpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'compBorrowSpeed', type: 'uint256' }, + ], + name: '_setDynamicCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: '_cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: '_compSupplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: '_compBorrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setDynamicCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'incentiveTokenAddress', + type: 'address', + }, + ], + name: '_setLnIncentiveToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPendingAdmin', type: 'address' }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: '_supportMarket', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'baseUnits', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'market', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'connect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'contractNameHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'distributeBorrowerComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'supplier', type: 'address' }, + ], + name: 'distributeSupplierComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getLnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'isListed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isRetired', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'lnIncentiveTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'params', type: 'bytes' }], + name: 'retire', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'retireRainMaker', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'marketBorrowIndex_', + type: 'uint256', + }, + ], + name: 'updateCompBorrowIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'cToken', type: 'address' }], + name: 'updateCompSupplyIndex', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'version', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralUsage', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralUsage', + type: 'uint256', + }, + ], + name: 'ActiveCollateralUsageChange', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, + ], + name: 'LimitBorrowingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'newValue', + type: 'bool', + }, + ], + name: 'LimitMintingFlagChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newActiveCollateralCap', + type: 'uint256', + }, + ], + name: 'NewActiveCollateralCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdminBankAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdminBankAddress', + type: 'address', + }, + ], + name: 'NewAdminBankAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBouncer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBouncer', + type: 'address', + }, + ], + name: 'NewBouncer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'ctoken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldMinBorrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newMinBorrowAmount', + type: 'uint256', + }, + ], + name: 'NewMinBorrowAmount', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldRainMaker', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newRainMaker', + type: 'address', + }, + ], + name: 'NewRainMaker', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_afterNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_beforeNonReentrant', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_latestVersionSynced', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newActiveCollateralCaps', + type: 'uint256[]', + }, + ], + name: '_setActiveCollateralCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newAdminBankAddress', + type: 'address', + }, + ], + name: '_setAdminBankAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setBouncer', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitBorrowing', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'flagValue', type: 'bool' }], + name: '_setLimitMinting', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationFactorMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'minBorrowAmountUsd_', + type: 'uint256', + }, + ], + name: '_setMinBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'deployParams', type: 'bytes' }, + { internalType: 'bytes', name: 'retireParams', type: 'bytes' }, + { internalType: 'bytes', name: 'connectParams', type: 'bytes' }, + ], + name: '_setRainMaker', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying', type: 'address' }, + { internalType: 'bytes32', name: 'contractNameHash', type: 'bytes32' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + { internalType: 'address', name: 'interestRateModel', type: 'address' }, + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: '_supportNewMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'adminBankAddress', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'bouncer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'bytes32', name: '', type: 'bytes32' }, + ], + name: 'existingMarketTypes', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidityByLiquidationFactor', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getRegistry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasBouncer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'hasRainMaker', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'initializeNewComptroller', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isAccountApproved', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'limitMinting', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isComped', + type: 'bool', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'minBorrowAmountUsd', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'rainMaker', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'registry', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'cTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'unitrollerContractHash', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'bytes', + name: 'becomeImplementationData', + type: 'bytes', + }, + ], + name: 'updateDelegatedImplementations', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/sonne-finance/index.js b/src/adaptors/sonne-finance/index.js new file mode 100644 index 0000000000..938943fb7e --- /dev/null +++ b/src/adaptors/sonne-finance/index.js @@ -0,0 +1,261 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator, distributorAbi } = require('./abi'); + +const CHAINS = { + optimism: { + COMPTROLLER_ADDRESS: '0x60CF091cD3f50420d50fD7f707414d0DF4751C58', + REWARD_DISTRIBUTOR: '0x60CF091cD3f50420d50fD7f707414d0DF4751C58', + SONNE: '0x1db2466d9f5e10d7090e7152b68d62703a2245f0', + }, + base: { + COMPTROLLER_ADDRESS: '0x1DB2466d9F5e10D7090E7152B68d62703a2245F0', + REWARD_DISTRIBUTOR: '0x1DB2466d9F5e10D7090E7152B68d62703a2245F0', + SONNE: '0x22a2488fE295047Ba13BD8cCCdBC8361DBD8cf7c', + }, +}; + +const GET_ALL_MARKETS = 'getAllMarkets'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const REWARD_SPEEDS = 'compSupplySpeeds'; +const BORROW_SPEEDS = 'compBorrowSpeeds'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const SECONDS_PER_DAY = 86400; +const BLOCKS_PER_DAY = SECONDS_PER_DAY; + +const PROJECT_NAME = 'sonne-finance'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x4200000000000000000000000000000000000006'.toLowerCase(), +}; + +const getRewards = async (markets, isBorrow, chain) => { + return ( + await sdk.api.abi.multiCall({ + chain, + calls: markets.map((market) => ({ + target: CHAINS[chain].REWARD_DISTRIBUTOR, + params: [market], + })), + abi: distributorAbi.find( + ({ name }) => name === (isBorrow ? BORROW_SPEEDS : REWARD_SPEEDS) + ), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const multiCallMarkets = async (markets, method, abi, chain) => { + return ( + await sdk.api.abi.multiCall({ + chain, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const lendingApy = async (chain) => { + const COMPTROLLER_ADDRESS = CHAINS[chain].COMPTROLLER_ADDRESS; + + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + permitFailure: true, + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + if (!allMarkets.length) return []; + + const marketsInfo = ( + await sdk.api.abi.multiCall({ + chain, + calls: allMarkets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: market, + })), + abi: comptrollerAbi.find(({ name }) => name === 'markets'), + permitFailure: true, + }) + ).output.map(({ output }) => output); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator, + chain + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator, + chain + ); + + const distributeRewards = await getRewards(allMarkets, false, chain); + const distributeBorrowRewards = await getRewards(allMarkets, true, chain); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator, + chain + ); + + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator, + chain + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator, + chain + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator, + chain + ); + + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator, + chain + ); + + const SONNE = CHAINS.optimism.SONNE; + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .concat([SONNE]) + .map((token) => `${chain}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + const token = symbol === 'BNB' ? NATIVE_TOKEN.address : underlyingTokens[i]; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const apyReward = + (((distributeRewards[i] / 10 ** 18) * + SECONDS_PER_DAY * + 365 * + prices[SONNE]) / + totalSupplyUsd) * + 100; + + const apyRewardBorrow = + (((distributeBorrowRewards[i] / 10 ** 18) * + SECONDS_PER_DAY * + 365 * + prices[SONNE]) / + totalBorrowUsd) * + 100; + + return { + pool: market, + chain, + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward > 0 ? SONNE : null].filter(Boolean), + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: marketsInfo[i].collateralFactorMantissa / 10 ** 18, + }; + }); + + return pools; +}; + +const apy = async () => { + const pools = await Promise.all( + Object.keys(CHAINS).map((chain) => lendingApy(chain)) + ); + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://sonne.finance/', +}; diff --git a/src/adaptors/sovryn-dex/address.js b/src/adaptors/sovryn-dex/address.js new file mode 100644 index 0000000000..d3d67a4f66 --- /dev/null +++ b/src/adaptors/sovryn-dex/address.js @@ -0,0 +1,25 @@ +const tokensPool = { + '0xe81373285eb8cdee2e0108e98c5aa022948da9d2': "DLLR-RBTC", + '0x448c2474b255576554eed36c24430ccfac131ce3': "USDT-RBTC", + '0x26463990196b74ad5644865e4d4567e4a411e065': "BPRO-RBTC", + '0xe76ea314b32fcf641c6c57f14110c5baa1e45ff4': "SOV-RBTC", + '0xdeb0894196863dbb2f2d4c683f6d33a2197056b5': "FISH-RBTC", + '0xa57ec11497f45fe86eca50f4f1c9e75c8016a1af': "ETH-RBTC", + '0xe321442dc4793c17f41fe3fb192a856a4864ceaf': "MOC-RBTC", + '0xa9c3d9681215ef7623dc28ea6b75bf87fdf285d9': "XUSD-RBTC", + '0x1684b871ec5f93de142e79a670b541d75be07ead': "BNB-RBTC", + '0xd715192612f03d20bae53a5054af530c9bb0fa3f': "DOC-RBTC", + '0x65528e06371635a338ca804cd65958a11cb11009': "RIF-RBTC", + '0x3a18e61d9c9f1546dea013478dd653c793098f17': "MYNT-RBTC", +} + +const tokensLending = { + '0x077FCB01cAb070a30bC14b44559C96F529eE017F': "DLLR", + '0xa9DcDC63eaBb8a2b6f39D7fF9429d88340044a7A': "RBTC", + '0x8F77ecf69711a4b346f23109c40416BE3dC7f129': "XUSD", + '0xd8D25f03EBbA94E15Df2eD4d6D38276B595593c1': "DOC", + '0x849C47f9C259E9D62F289BF1b2729039698D8387': "USDT", + '0x6E2fb26a60dA535732F8149b25018C9c0823a715': "BPRO", +} + +module.exports = { tokensPool, tokensLending }; \ No newline at end of file diff --git a/src/adaptors/sovryn-dex/index.js b/src/adaptors/sovryn-dex/index.js new file mode 100755 index 0000000000..cca075d1f8 --- /dev/null +++ b/src/adaptors/sovryn-dex/index.js @@ -0,0 +1,128 @@ +// documentation: +// https://wiki.sovryn.com/en/technical-documents/amm/AMM-FAQ +// https://wiki.sovryn.com/en/sovryn-dapp/lending + +const utils = require('../utils'); +const { tokensPool, tokensLending } = require('./address'); +const { request, gql } = require('graphql-request'); +const subgraphUrl = 'https://subgraph.sovryn.app/subgraphs/name/DistributedCollective/sovryn-subgraph'; +const tokenPriceQuery = gql` + query getTokenRates { + tokens { + id + symbol + lastPriceBtc + lastPriceUsd + } + } + `; + +const getApy = async () => { + const dataPool = []; + const amm_pools_data = await utils.getData(`https://amm-apy.sovryn.app/amm`); // see https://github.com/DistributedCollective/sovryn-amm-apy + const { tvlAmm, tvlLending } = await utils.getData('https://graph-wrapper.sovryn.app/cmc/tvl'); //see https://github.com/DistributedCollective/Sovryn-graph-wrapper + const token_prices = await request(subgraphUrl, tokenPriceQuery, {}); + const data = await Promise.all( + Object.keys(tokensPool).map(async (k) => { + var symbol = String(tokensPool[k]); + var pool_id = String(k.toLowerCase()); + var tvlUsd = await getTvl(tvlAmm, 1, pool_id); + var apyData = amm_pools_data[k].data; + var apyDataArray = apyData[Object.keys(apyData)[0]]; + var apy = apyDataArray[apyDataArray.length - 1]; + dataPool.push({ + pool: pool_id, + chain: utils.formatChain('Rootstock'), + project: 'sovryn-dex', + tvlUsd: tvlUsd, + symbol: symbol, + apyBase: Number(apy.APY_rewards_pc), + apyReward: Number(apy.APY_fees_pc), + url: 'https://alpha.sovryn.app/yield-farm', + rewardTokens: ['0xefc78fc7d48b64958315949279ba181c2114abbd'], + }); + }) + ); + + const dataLend = await Promise.all( + Object.keys(tokensLending).map(async (k) => { + var symbol = String(tokensLending[k]); + var id = String(k.toLowerCase()); + var { tvlUsd, asset } = await getTvl(tvlLending, 0, id); + var asset_price = await getTokenPrice(token_prices, asset); + var apyData = await utils.getData(`https://graph-wrapper.sovryn.app/lendingApy/` + id);//see https://github.com/DistributedCollective/Sovryn-graph-wrapper + var apyDataArray = apyData[Object.keys(apyData)[0]]; + var apy = apyData[apyData.length - 1]; + var totalSupplyUsd = Number(apy.supply) * asset_price; + var totalBorrowUsd = totalSupplyUsd - tvlUsd; + dataPool.push({ + pool: id, + chain: utils.formatChain('Rootstock'), + project: 'sovryn-dex', + tvlUsd: tvlUsd, + symbol: symbol, + apyBase: Number(apy.supply_apr), + apyBaseBorrow: Number(apy.borrow_apr), + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + url: 'https://alpha.sovryn.app/lend', + }); + }) + ); + + return dataPool; +}; + +const getTokenPrice = async (object, asset) => { + const price = []; + await Promise.all( + Object.entries(object.tokens).map(async (k) => { + if (k[1].id == asset) { + price.push(k[1].lastPriceUsd); + } + }) + ); + const priceUsd = Number(price[0]); + return priceUsd; + + + +} + +const getTvl = async (tvl, type, id) => { + const tvlData = []; + const assets = []; + if (type == 1) { + await Promise.all( + Object.entries(tvl).map(async (k) => { + if (k[1].contract == id) { + tvlData.push(k[1].balanceUsd); + } + }) + ); + const tvlPoolUsd = Number(tvlData[0]) + Number(tvlData[1]); + return tvlPoolUsd; + } + else { + await Promise.all( + Object.entries(tvl).map(async (k) => { + if (k[1].contract == id) { + tvlData.push(k[1].balanceUsd); + assets.push(k[1].asset); + + } + + }) + ); + const tvlUsd = Number(tvlData[0]); + const asset = (assets[0]); + return { tvlUsd, asset }; + + } +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://alpha.sovryn.app', +}; diff --git a/src/adaptors/spark-savings/abi.js b/src/adaptors/spark-savings/abi.js new file mode 100644 index 0000000000..7ed9cd1b0f --- /dev/null +++ b/src/adaptors/spark-savings/abi.js @@ -0,0 +1,25 @@ +const sparkSavingsAbi = { + totalAssets: { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + totalSupply: { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + vsr: { + inputs: [], + name: 'vsr', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +}; + +module.exports = { sparkSavingsAbi }; diff --git a/src/adaptors/spark-savings/index.ts b/src/adaptors/spark-savings/index.ts new file mode 100644 index 0000000000..3f5606e9d1 --- /dev/null +++ b/src/adaptors/spark-savings/index.ts @@ -0,0 +1,145 @@ +const axios = require('axios') +const sdk = require('@defillama/sdk') +const BigNumber = require('bignumber.js') +const {sparkSavingsAbi} = require('./abi.js') + +import type { Pool } from '../../types/Pool' + +const sparkBaseUrl = 'https://app.spark.fi/savings' + +type Chain = 'ethereum' | 'avax' +interface VaultConfig { + assetSymbol: string + address: string + decimals: number +} + +const sparkSavings: Record = { + ethereum: [ + { + assetSymbol: 'USDC', + address: '0x28B3a8fb53B741A8Fd78c0fb9A6B2393d896a43d', + decimals: 6, + }, + { + assetSymbol: 'USDT', + address: '0xe2e7a17dFf93280dec073C995595155283e3C372', + decimals: 6, + }, + { + assetSymbol: 'PYUSD', + address: '0x80128DbB9f07b93DDE62A6daeadb69ED14a7D354', + decimals: 6, + }, + { + assetSymbol: 'ETH', + address: '0xfE6eb3b609a7C8352A241f7F3A21CEA4e9209B8f', + decimals: 18, + }, + ], + avax: [ + { + assetSymbol: 'USDC', + address: '0x28B3a8fb53B741A8Fd78c0fb9A6B2393d896a43d', + decimals: 6, + }, + ], +} + +async function getPools(): Promise { + const pools: Pool[] = [] + const chains = Object.keys(sparkSavings) as Chain[] + + for (const chain of chains) { + const vaults = sparkSavings[chain] + + const totalSupplies = toOutput( + await sdk.api.abi.multiCall({ + abi: sparkSavingsAbi.totalSupply, + chain, + calls: vaults.map((config) => ({ + target: config.address, + })), + }), + ) + + const rates = toOutput( + await sdk.api.abi.multiCall({ + abi: sparkSavingsAbi.vsr, + chain, + calls: vaults.map((config) => ({ + target: config.address, + })), + }), + ) + + const symbols = toOutput( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + chain, + calls: vaults.map((config) => ({ + target: config.address, + })), + }), + ) + + const prices = await fetchPrices(chain, vaults) + + pools.push( + ...vaults.map( + (vaultConfig, i): Pool => ({ + pool: `${vaultConfig.address}-${chain}`, + chain, + apyBase: rateToApy(rates[i]), + url: getVaultUrl(chain, symbols[i]), + project: 'spark-savings', + symbol: vaultConfig.assetSymbol, + tvlUsd: new BigNumber(totalSupplies[i]) + .div(10 ** vaultConfig.decimals) + .times(prices[`${chain}:${vaultConfig.address.toLowerCase()}`].price) + .toNumber(), + }), + ), + ) + } + + return pools +} + +function toOutput(results: { output: { output: T }[] }): T[] { + return results.output.map((result) => result.output) +} + +async function fetchPrices( + chain: Chain, + vaultConfigs: readonly VaultConfig[], +): Promise> { + const priceKeys = vaultConfigs.map((config) => `${chain}:${config.address.toLowerCase()}`).join(',') + const response = await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + return response.data.coins +} + +function getVaultUrl(chain: Chain, symbol: string): string { + return `${sparkBaseUrl}/${chainToAppChain[chain]}/${symbol.toLowerCase()}` +} + +const chainToAppChain: Record = { + ethereum: 'mainnet', + avax: 'avalanche', +} + +const yearInSeconds = 31536000 + +function rateToApy(rate: string): number { + const normalizedRate = new BigNumber(rate).div(10 ** 27) + return pow(normalizedRate, yearInSeconds).minus(1).times(100).toNumber() +} + +// high precision pow function for correct calculations +function pow(a: any, b: number): any { + return BigNumber.clone({ POW_PRECISION: 60 }).prototype.pow.apply(a, [b]) +} + +module.exports = { + apy: getPools, +} \ No newline at end of file diff --git a/src/adaptors/sparkdex-v2/index.js b/src/adaptors/sparkdex-v2/index.js new file mode 100644 index 0000000000..38fe24cdc4 --- /dev/null +++ b/src/adaptors/sparkdex-v2/index.js @@ -0,0 +1,126 @@ +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const SUBGRAPH_URL = 'https://api.goldsky.com/api/public/project_cm1tgcbwdqg8b01un9jf4a64o/subgraphs/sparkdex-v2/latest/gn'; +const FACTORY_ADDRESS = '0x16b619B04c961E8f4F06C10B42FDAbb328980A89'; +const CHAIN = 'flare'; + +const query = gql` + { + pairs(first: 1000, orderBy: liquidityUSD, orderDirection: desc, block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + liquidityUSD + feesUSD + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000, orderBy: liquidityUSD, orderDirection: desc, block: {number: }) { + id + volumeUSD + } + } +`; + +const fetchSparkDexV2Data = async (timestamp = null) => { + try { + // Get blocks for time travel + const [block, blockPrior] = await utils.getBlocks(CHAIN, timestamp, [SUBGRAPH_URL]); + const [_, blockPrior7d] = await utils.getBlocks(CHAIN, timestamp, [SUBGRAPH_URL], 604800); + + // Fetch current data + let dataNow = await request(SUBGRAPH_URL, query.replace('', block)); + dataNow = dataNow.pairs; + + // Fetch 24h offset data for volume calculation + let dataPrior = await request(SUBGRAPH_URL, queryPrior.replace('', blockPrior)); + dataPrior = dataPrior.pairs; + + // Fetch 7d offset data + const dataPrior7d = await request(SUBGRAPH_URL, queryPrior.replace('', blockPrior7d)); + const dataPrior7dPairs = dataPrior7d.pairs; + + // Process token reserves with proper decimals before TVL calculation + dataNow = dataNow.map((pair) => { + const token0Decimals = parseInt(pair.token0.decimals); + const token1Decimals = parseInt(pair.token1.decimals); + + // Convert reserves from wei to actual token amounts + const reserve0 = Number(pair.reserve0) / Math.pow(10, token0Decimals); + const reserve1 = Number(pair.reserve1) / Math.pow(10, token1Decimals); + + return { + ...pair, + reserve0: reserve0.toString(), + reserve1: reserve1.toString(), + }; + }); + + // Calculate TVL + dataNow = await utils.tvl(dataNow, CHAIN); + + // Calculate APY + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7dPairs, 'v2')); + + // Format pools + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + + return { + pool: `${p.id}-${CHAIN}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: 'sparkdex-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url: `https://sparkdex.ai/pool`, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + poolMeta: 'Uniswap V2', + }; + }); + } catch (error) { + console.error('Error fetching SparkDEX V2 data:', error); + return []; + } +}; + +const main = async (timestamp = null) => { + try { + console.log('Fetching SparkDEX V2 data for Flare chain...'); + const data = await fetchSparkDexV2Data(timestamp); + + // Filter out pools with invalid data + const validPools = data.filter((p) => utils.keepFinite(p)); + + console.log(`Found ${validPools.length} valid pools`); + return validPools; + } catch (error) { + console.error('Error in main function:', error); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://sparkdex.ai/pool', +}; diff --git a/src/adaptors/sparkdex-v3.1/index.js b/src/adaptors/sparkdex-v3.1/index.js new file mode 100644 index 0000000000..f3d761182e --- /dev/null +++ b/src/adaptors/sparkdex-v3.1/index.js @@ -0,0 +1,90 @@ +const axios = require('axios'); + +const rFLR = '0x26d460c3Cf931Fb2014FA436a49e3Af08619810e'; // Reward FLR + +const calculateApy = (_apr) => { + const APR = _apr / 100; + const n = 365; + + // APY calculation + const APY = (1 + APR / n) ** n - 1; + const APYPercentage = APY * 100; + + return APYPercentage; +}; + +const apy = async () => { + const pools = ( + await axios.get( + 'https://api.sparkdex.ai/dex/v3/pairs?chainId=14&dex=SparkDEX&version=v3_1' + ) + ).data[0].data; + + const chain = 'Flare'; + + const i = pools.map((lp) => { + if (!lp.apr) return; + + const tvlUsd = lp.tvlUSD; + const feeUsd = lp.feesUSDDay; + + const baseApy = (feeUsd / tvlUsd) * 365 * 100; + + let pool = { + pool: `${lp.id}-${chain}`.toLowerCase(), + symbol: `${lp.token0.symbol}-${lp.token1.symbol}`, + project: 'sparkdex-v3.1', + chain, + tvlUsd, + apyBase: baseApy, + underlyingTokens: [lp.token0.address, lp.token1.address], + }; + + // Extract rFLR reward APRs + const rFlrRewardAprs = lp.aprs.filter( + (apr) => apr.provider === 'rFLR Rewards' + ); + + // Extract other reward APRs + const rewardAprs = lp.aprs.filter( + (apr) => !apr.isPoolApr && apr.provider !== 'rFLR Rewards' + ); + + // Calculate total reward APY from all sources + const totalRewardApy = calculateApy( + rewardAprs.reduce((sum, apr) => sum + apr.apr, 0) + ); + const rFlrRewardApy = calculateApy( + rFlrRewardAprs.reduce((sum, apr) => sum + apr.apr, 0) + ); + + // Add remaing rewards + if (totalRewardApy > 0) { + // Rewards can be swapped instantly to wFLR + pool.apyReward = totalRewardApy; + pool.rewardTokens = [rFLR]; // rFLR + } + + // Add rFLR apr + if (rFlrRewardApy > 0) { + // rFLR can be swapped with 50% penalty instantly to wFLR or linear 12 months + // so taking care to lower bund %50 + pool.apyReward = (pool.apyReward || 0) + rFlrRewardApy / 2; + pool.rewardTokens = [rFLR]; // rFLR + } + + return pool; + }); + + const result = i.filter(Boolean); + + console.log(result); + + return result; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://sparkdex.ai/pool', +}; diff --git a/src/adaptors/sparkdex-v3/index.js b/src/adaptors/sparkdex-v3/index.js new file mode 100644 index 0000000000..c136dcaa18 --- /dev/null +++ b/src/adaptors/sparkdex-v3/index.js @@ -0,0 +1,144 @@ +const utils = require('../utils'); + +/** + * @typedef {Object} LPPage + * @property {string} address + * @property {Object} token0 + * @property {string} token0.address + * @property {string} token0.symbol + * @property {Object} token1 + * @property {string} token1.address + * @property {string} token1.symbol + * @property {Array} statistics + * @property {number} statistics.tvlUSD + * @property {number} statistics.feeUSD + * @property {string} statistics.period + * @property {Array} emissions + * @property {number} emissions.dailyEmission + * @property {string} emissions.startDate + * @property {string} emissions.endDate + */ + +/** + * @typedef {Object} Pool + * @property {string} pool + * @property {string} chain + * @property {string} project + * @property {string} symbol + * @property {number} tvlUsd + * @property {number} apyBase + * @property {number} apyReward + * @property {Array} rewardTokens + * @property {Array} underlyingTokens + * @property {string} poolMeta + * @property {string} url + * @property {number} apyBaseBorrow + * @property {number} apyRewardBorrow + * @property {number} totalSupplyUsd + * @property {number} totalBorrowUsd + * @property {number} ltv + */ + +/** + * + * @returns {Promise} + */ +function getFlrPrice() { + return utils.getData('https://api.flaremetrics.io/v2/defi/flare/price'); +} + +/** + * + * @param {number} limit + * @param {number} offset + * @returns {Promise} + */ +function getLPPage(limit, offset) { + return utils.getData( + `https://api.flaremetrics.io/v2/defi/flare/liquidity-pools?product=sparkdex-pool&tvlUSD=10000&limit=${limit}&offset=${offset}` + ); +} + +/** + * @param {number} now + * @param {number} flrPrice + * @returns {(lp: LPPage) => Pool[]} + */ +function makePoolFlatmap(now, flrPrice) { + /** + * @param {LPPage} lp + */ + return function poolFlatMap(lp) { + const chain = 'Flare'; + const address = lp.address; + const token0symbol = lp.token0.symbol; + const token1symbol = lp.token1.symbol; + const token0address = lp.token0.address; + const token1address = lp.token1.address; + const stats = lp.statistics.find((s) => s.period == '1d'); + + if (!stats) return []; + + const tvlUsd = stats.tvlUSD; + const feeUsd = stats.feeUSD; + + const apyBase = (feeUsd / tvlUsd) * 365 * 100; + /** + * @type {Pool} + */ + const pool = { + pool: `${address}-${chain}`.toLowerCase(), + chain, + project: 'sparkdex-v3', + symbol: `${token0symbol}-${token1symbol}`, + tvlUsd, + apyBase, + underlyingTokens: [token0address, token1address], + }; + + const emissions = lp.emissions || []; + const emission = emissions.find((e) => { + const startDate = Date.parse(e.startDate); + const endDate = Date.parse(e.endDate); + return now >= startDate && now < endDate; + }); + + if (!emission) { + if (apyBase == 0) return []; + + return pool; + } + + pool.apyReward = ((emission.dailyEmission * flrPrice) / tvlUsd) * 365 * 100; + pool.rewardTokens = ['0x26d460c3Cf931Fb2014FA436a49e3Af08619810e']; // rFLR + + return pool; + }; +} + +async function poolsFunction() { + const now = Date.now(); + const flrPrice = await getFlrPrice(); + /** + * @type {LPPage[]} + */ + const liquidityPools = []; + const limit = 250; + + for (let i = 0; i < 10; i += 1) { + const offset = i * limit; + const lpPage = await getLPPage(limit, offset); + + liquidityPools.push(...lpPage); + + if (lpPage.length < limit) break; + } + + return liquidityPools.flatMap(makePoolFlatmap(now, flrPrice)); +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://sparkdex.ai/apps/liquidity', +}; diff --git a/src/adaptors/sparklend/abiSKYFarm.json b/src/adaptors/sparklend/abiSKYFarm.json new file mode 100644 index 0000000000..e67f31a380 --- /dev/null +++ b/src/adaptors/sparklend/abiSKYFarm.json @@ -0,0 +1,459 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" }, + { + "internalType": "address", + "name": "_rewardsDistribution", + "type": "address" + }, + { "internalType": "address", "name": "_rewardsToken", "type": "address" }, + { "internalType": "address", "name": "_stakingToken", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerNominated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isPaused", + "type": "bool" + } + ], + "name": "PauseChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Referral", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newRewardsDistribution", + "type": "address" + } + ], + "name": "RewardsDistributionUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardForDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastPauseTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "nominateNewOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nominatedOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenAddress", "type": "address" }, + { "internalType": "uint256", "name": "tokenAmount", "type": "uint256" } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDistribution", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_paused", "type": "bool" }], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsDistribution", + "type": "address" + } + ], + "name": "setRewardsDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint16", "name": "referral", "type": "uint16" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/sparklend/index.js b/src/adaptors/sparklend/index.js new file mode 100644 index 0000000000..99f36cb799 --- /dev/null +++ b/src/adaptors/sparklend/index.js @@ -0,0 +1,240 @@ +// Copied from aave v3 +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); +const abiSKYFarm = require('./abiSKYFarm.json'); + +const sparkChains = ['ethereum', 'gnosis']; + +/** + * protocol data provider address per chain + * @type {{ethereum: string, gnosis: string}} + */ +const protocolDataProviderAddress = { + ethereum: '0xFc21d6d146E6086B8359705C8b28512a983db0cb', + gnosis: '0x2a002054A06546bB5a264D57A81347e23Af91D18', +}; + +/** + * Fetches the Spark V3 pools + * @param {('ethereum'|'gnosis')} chain + */ +async function fetchV3Pools(chain) { + const target = protocolDataProviderAddress[chain]; + + chain = chain === 'gnosis' ? 'xdai' : chain; // llamas sdk uses xdai instead of gnosis + + const reserveTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupplyEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalancesEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimalsEthereum = ( + await sdk.api.abi.multiCall({ + chain, + abi: aTokenAbi.find(({ name }) => name === 'decimals'), + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + const pricesEthereum = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + return reserveTokens + .map((pool, i) => { + const p = poolsReserveData[i]; + const price = pricesEthereum[`${chain}:${pool.tokenAddress}`]?.price; + + const supply = totalSupplyEthereum[i]; + const totalSupplyUsd = + (supply / 10 ** underlyingDecimalsEthereum[i]) * price; + + const currentSupply = underlyingBalancesEthereum[i]; + const tvlUsd = + (currentSupply / 10 ** underlyingDecimalsEthereum[i]) * price; + + return { + pool: `${aTokens[i].tokenAddress}-${chain}`.toLowerCase(), + // Captialize the first letter of the chain + chain: chain === 'xdai' ? 'Gnosis' : 'Ethereum', + project: 'sparklend', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 10 ** 27) * 100, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd: totalSupplyUsd - tvlUsd, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + }; + }) + .filter((p) => utils.keepFinite(p)); +} + +const skyFarm = async () => { + const stakingRewards = '0x0650CAF159C5A49f711e8169D4336ECB9b950275'; + const USDS = '0xdC035D45d973E3EC169d2276DDab16f1e407384F'; + const SKY = '0x56072C95FAA701256059aa122697B133aDEd9279'; + + const totalSupply = + ( + await sdk.api.abi.call({ + target: stakingRewards, + abi: 'erc20:totalSupply', + }) + ).output / 1e18; + + const stakingToken = ( + await sdk.api.abi.call({ + target: stakingRewards, + abi: abiSKYFarm.find((m) => m.name === 'stakingToken'), + }) + ).output; + + const prices = await axios.get( + `https://coins.llama.fi/prices/current/${[USDS, SKY] + .map((i) => `ethereum:${i}`) + .join(',')}` + ); + + const priceUSDS = prices.data.coins[`ethereum:${USDS}`].price; + const priceSKY = prices.data.coins[`ethereum:${SKY}`].price; + + const tvlUsd = totalSupply * priceUSDS; + + const rewardRate = + ( + await sdk.api.abi.call({ + target: stakingRewards, + abi: abiSKYFarm.find((m) => m.name === 'rewardRate'), + }) + ).output / 1e18; + + const secPerDay = 86400; + const apyReward = ((rewardRate * secPerDay * 365 * priceSKY) / tvlUsd) * 100; + + return [ + { + pool: stakingRewards, + chain: 'Ethereum', + project: 'sparklend', + symbol: 'USDS', + poolMeta: 'SKY Farming Pool', + tvlUsd: totalSupply * priceUSDS, + apyReward, + underlyingTokens: [stakingToken], + rewardTokens: [SKY], + }, + ]; +}; + +const apy = async () => { + const skyFarmPool = await skyFarm(); + + const v3Pools = [ + ...(await Promise.all(sparkChains.map(fetchV3Pools))), + ].flat(); + + const ilk = ( + await sdk.api.abi.call({ + target: '0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B', + params: [ + '0x4449524543542d535041524b2d44414900000000000000000000000000000000', + ], + abi: { + constant: true, + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'ilks', + outputs: [ + { internalType: 'uint256', name: 'Art', type: 'uint256' }, + { internalType: 'uint256', name: 'rate', type: 'uint256' }, + { internalType: 'uint256', name: 'spot', type: 'uint256' }, + { internalType: 'uint256', name: 'line', type: 'uint256' }, + { internalType: 'uint256', name: 'dust', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + }) + ).output; + + const ethereumDaiPool = v3Pools.find( + (p) => p.symbol === 'DAI' && p.chain === 'Ethereum' + ); + ethereumDaiPool.totalSupplyUsd = Number(ilk.line) / 1e45; + ethereumDaiPool.tvlUsd = + ethereumDaiPool.totalSupplyUsd - ethereumDaiPool.totalBorrowUsd; + + return [...v3Pools, ...skyFarmPool]; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.spark.fi/markets/', +}; diff --git a/src/adaptors/spectra-v2/index.js b/src/adaptors/spectra-v2/index.js new file mode 100644 index 0000000000..7c63f66154 --- /dev/null +++ b/src/adaptors/spectra-v2/index.js @@ -0,0 +1,167 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const api = (chainId) => + `https://api.spectra.finance/v1/${chains[chainId].slug}/pools?source=defillama`; +const chains = { + 1: { + name: 'ethereum', + slug: 'mainnet', + urlSlug: "eth", + SPECTRA: '0x6a89228055c7c28430692e342f149f37462b478b', + }, + 42161: { + name: 'arbitrum', + slug: 'arbitrum', + urlSlug: "arb", + SPECTRA: '0x64fcc3a02eeeba05ef701b7eed066c6ebd5d4e51', + }, + 10: { + name: 'optimism', + slug: 'optimism', + urlSlug: "op", + SPECTRA: '0x248f43b622ce2f35a14db3fc528284730b619cd5', + }, + 8453: { + name: 'base', + slug: 'base', + urlSlug: "base", + SPECTRA: '0x64fcc3a02eeeba05ef701b7eed066c6ebd5d4e51', + }, + 146: { + name: 'sonic', + slug: 'sonic', + urlSlug: "sonic", + SPECTRA: '0xb827e91c5cd4d6aca2fc0cd93a07db61896af40b', + }, + 43111: { + name: 'hemi', + slug: 'hemi', + urlSlug: "hemi", + SPECTRA: '0x392fca63e58C1870fBeC04Eb6518A75703Dd2954', + }, + 43114: { + name: 'avax', + slug: 'avalanche', + urlSlug: "avax", + SPECTRA: '0x4baB31D6c557F8285eccB5167095147a36D9BaFa', + }, + 56: { + name: 'bsc', + slug: 'bsc', + urlSlug: "bsc", + SPECTRA: "0x4baB31D6c557F8285eccB5167095147a36D9BaFa" + }, + 999: { + name: 'hyperliquid', + slug: 'hyperevm', + urlSlug: "hyperevm", + SPECTRA: "0x6bd93ee39bcc7b9baba122c2ba65246e4347bbf9" + }, + 747474: { + name: 'katana', + slug: 'katana', + urlSlug: "katana", + SPECTRA: "0xb77f1a8cb126d8567f226f990f84e2f698cc30f8" + }, + 14: { + name: 'flare', + slug: 'flare', + urlSlug: "flare", + SPECTRA: "0x5390d7c6b8139ae9d255ed9e7ae6274e18032abe" + }, + 143: { + name: 'monad', + slug: 'monad', + urlSlug: "monad", + SPECTRA: "0x1c77c5b76f02ed1538d5af95a3b1f88e55178d2f" + }, +}; + +const poolId = (address, chainId) => + `${address}-${chains[chainId].slug}`.toLowerCase(); + +const spectraApy = (pool) => { + if (pool.lpApy.details.rewards?.['SPECTRA']) { + return pool.lpApy.details.rewards['SPECTRA']; + } else if (pool.lpApy.details.boostedRewards?.['SPECTRA']) { + return pool.lpApy.details.boostedRewards['SPECTRA'].min; // take lower APY bound + } else { + return 0; + } +}; + +const formatMaturity = (maturity) => + new Date(maturity * 1000).toDateString('en-US'); // maturity is in seconds + +const formatIbt = (ibt) => + `${ibt.symbol}${ibt.protocol ? ` (${ibt.protocol})` : ''}`; + +const lpApy = (p) => { + const spectra = spectraApy(p); + const chain = chains[p.chainId]; + return { + pool: poolId(p.address, p.chainId), + chain: utils.formatChain(chain.name), + project: 'spectra-v2', + symbol: utils.formatSymbol(`${p.pt.ibt.symbol}`), + tvlUsd: p.liquidity?.usd, + apyBase: p.lpApy.total - spectra, + apyReward: spectra, + rewardTokens: spectra > 0 ? [chain.SPECTRA] : [], + underlyingTokens: [p.pt.address, p.pt.ibt.address], + poolMeta: `For LP on ${p.pt.ibt.protocol} | Maturity ${formatMaturity( + p.pt.maturity + )}`, + url: `https://app.spectra.finance/pools/${chain.urlSlug}:${p.address}?ref=defillama`, + }; +}; + +const fixedRateApy = (p) => { + const chain = chains[p.chainId]; + return { + pool: poolId(p.pt.address, p.chainId), + chain: utils.formatChain(chain.name), + project: 'spectra-v2', + symbol: utils.formatSymbol(`${p.pt.ibt.symbol}`), + tvlUsd: p.liquidity?.usd, + apyBase: p.pt.ibt.apr?.total, + underlyingTokens: [p.pt.underlying.address], + poolMeta: `For PT on ${p.pt.ibt.protocol} | Maturity ${formatMaturity( + p.pt.maturity + )}`, + url: `https://app.spectra.finance/fixed-rate/${chain.urlSlug}:${p.address}?ref=defillama`, + }; +}; + +async function apy() { + const pts = await Promise.all( + Object.keys(chains).map((chainId) => + axios + .get(api(chainId), { + headers: { + 'x-client-id': 'defillama', + }, + }) + .then((res) => res.data.flat()) + ) + ).then((res) => res.flat()); + pts.forEach((pt) => { + pt.pools.forEach((pool) => { + pool.pt = pt; // inject PT reference into pool itself + }); + }); + const pools = pts.flatMap((pt) => pt.pools); + + const apys = [...pools.map(lpApy), ...pools.map(fixedRateApy)] + .flat() + .filter((i) => utils.keepFinite(i)) // skip pools with no TVL (e.g. missing price) + .sort((a, b) => b.tvlUsd - a.tvlUsd); + + return apys; +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/spice-finance/abis.js b/src/adaptors/spice-finance/abis.js new file mode 100644 index 0000000000..3f01c3a572 --- /dev/null +++ b/src/adaptors/spice-finance/abis.js @@ -0,0 +1,20 @@ +module.exports = { + vaultABI: [ + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ], + oracleABI: [ + { + inputs: [], + name: 'latestAnswer', + outputs: [{ internalType: 'int256', name: '', type: 'int256' }], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/spice-finance/index.js b/src/adaptors/spice-finance/index.js new file mode 100644 index 0000000000..71ff46400a --- /dev/null +++ b/src/adaptors/spice-finance/index.js @@ -0,0 +1,118 @@ +const { Web3 } = require('web3'); +const axios = require('axios'); +const utils = require('../utils'); + +const { vaultABI, oracleABI } = require('./abis'); + +const RPC_URL = 'https://rpc.ankr.com/eth'; + +const PROLUGUE_VAULT_ADDRESS = '0x6110d61DD1133b0f845f1025d6678Cd22A11a2fe'; +const LEVERAGE_VAULT_ADDRESS = '0xd68871bd7D28572860b2E0Ee5c713b64445104F9'; +const FLAGSHIP_VAULT_ADDRESS = '0xAe11ae7CaD244dD1d321Ff2989543bCd8a6Db6DF'; +const BLUR_VAULT_ADDRESS = '0xfC287513E2DD58fbf952eB0ED05D511591a6215B'; +const ETHUSD_ORACLE_ADDRESS = '0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419'; + +const web3 = new Web3(RPC_URL); + +async function apr() { + const prologueVault = new web3.eth.Contract(vaultABI, PROLUGUE_VAULT_ADDRESS); + const leverageVault = new web3.eth.Contract(vaultABI, LEVERAGE_VAULT_ADDRESS); + const flagshipVault = new web3.eth.Contract(vaultABI, FLAGSHIP_VAULT_ADDRESS); + const blurVault = new web3.eth.Contract(vaultABI, BLUR_VAULT_ADDRESS); + const oracle = new web3.eth.Contract(oracleABI, ETHUSD_ORACLE_ADDRESS); + + const ethPrice = Number(await oracle.methods.latestAnswer().call()); + const totalAssetsPrologue = Number( + await prologueVault.methods.totalAssets().call() + ); + const tvlUsdPrologue = + (totalAssetsPrologue / 10 ** 18) * (ethPrice / 10 ** 8); + const { data: prologueData } = await axios.get( + `https://api.spicefi.xyz/v1/api/off-chain-vaults/${PROLUGUE_VAULT_ADDRESS}?env=prod` + ); + const actualApyPrologue = prologueData?.data?.okrs?.actual_returns; + const apyPrologue = prologueData?.data?.okrs?.expected_return * 100; + + const totalAssetsLeverage = Number( + await leverageVault.methods.totalAssets().call() + ); + const tvlUsdLeverage = + (totalAssetsLeverage / 10 ** 18) * (ethPrice / 10 ** 8); + const { data: leverageData } = await axios.get( + `https://api.spicefi.xyz/v1/api/off-chain-vaults/${LEVERAGE_VAULT_ADDRESS}?env=prod` + ); + const actualApyLeverage = leverageData?.data?.okrs?.actual_returns; + const apyLeverage = leverageData?.data?.okrs?.expected_return * 100; + + const totalAssetsFlagship = Number( + await flagshipVault.methods.totalAssets().call() + ); + const tvlUsdFlagship = + (totalAssetsFlagship / 10 ** 18) * (ethPrice / 10 ** 8); + const { data: flagshipData } = await axios.get( + `https://api.spicefi.xyz/v1/api/off-chain-vaults/${FLAGSHIP_VAULT_ADDRESS}?env=prod` + ); + const actualApyFlagship = flagshipData?.data?.okrs?.actual_returns; + const apyFlagship = flagshipData?.data?.okrs?.expected_return * 100; + + const totalAssetsBlur = Number(await blurVault.methods.totalAssets().call()); + const tvlUsdBlur = (totalAssetsBlur / 10 ** 18) * (ethPrice / 10 ** 8); + const { data: blurData } = await axios.get( + `https://api.spicefi.xyz/v2/api/vaults/${BLUR_VAULT_ADDRESS}` + ); + const actualApyBlur = blurData?.data?.okrs?.actual_returns; + const apyBlur = blurData?.data?.okrs?.expected_return * 100; + + return [ + { + pool: `Spice-Prologue-Vault`, + poolMeta: 'Prologue Vault', + chain: 'Ethereum', + project: 'spice-finance', + symbol: 'WETH', + tvlUsd: tvlUsdPrologue, + apyBase: apyPrologue, + apyBaseInception: actualApyPrologue, + }, + { + pool: `Spice-Leverage-Vault`, + poolMeta: 'Leverage Vault', + chain: 'Ethereum', + project: 'spice-finance', + symbol: 'WETH', + tvlUsd: tvlUsdLeverage, + apyBase: apyLeverage, + apyBaseInception: actualApyLeverage, + }, + { + pool: `Spice-Flagship-Vault`, + poolMeta: 'Flagship Vault', + chain: 'Ethereum', + project: 'spice-finance', + symbol: 'WETH', + tvlUsd: tvlUsdFlagship, + apyBase: apyFlagship, + apyBaseInception: actualApyFlagship, + }, + { + pool: `Spice-Blur-Vault`, + poolMeta: 'Blur Vault', + chain: 'Ethereum', + project: 'spice-finance', + symbol: 'WETH', + tvlUsd: tvlUsdBlur, + apyBase: apyBlur, + apyBaseInception: actualApyBlur, + }, + ]; +} + +const main = async () => { + return await apr(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.spicefi.xyz/', +}; diff --git a/src/adaptors/spookyswap-v2/abis.js b/src/adaptors/spookyswap-v2/abis.js new file mode 100644 index 0000000000..ba749d447b --- /dev/null +++ b/src/adaptors/spookyswap-v2/abis.js @@ -0,0 +1,974 @@ +module.exports = { + lpTokenABI: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + masterChefABI: [ + { + inputs: [ + { + internalType: 'contract IMasterChef', + name: '_MASTER_CHEF', + type: 'address', + }, + { internalType: 'contract IERC20', name: '_boo', type: 'address' }, + { internalType: 'uint256', name: '_MASTER_PID', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'LogInit', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: 'update', type: 'bool' }, + ], + name: 'LogPoolAddition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'overwrite', + type: 'bool', + }, + { indexed: false, internalType: 'bool', name: 'update', type: 'bool' }, + ], + name: 'LogSetPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accBooPerShare', + type: 'uint256', + }, + ], + name: 'LogUpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'BOO', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_CHEF', + outputs: [ + { internalType: 'contract IMasterChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_PID', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'V1_HARVEST_QUERY_TIME', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: 'update', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'booPerSecond', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'getFarmData', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accBooPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MasterChefV2.PoolInfo', + name: '', + type: 'tuple', + }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'harvestAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'harvestFromMasterChef', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'harvestMultiple', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'dummyToken', + type: 'address', + }, + ], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'isLpToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastV1HarvestTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdateAllPools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingBOO', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint128', name: 'accBooPerShare', type: 'uint128' }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolInfoAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'queryHarvestFromMasterChef', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewarder', + outputs: [ + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint64', name: '_allocPoint', type: 'uint64' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: 'overwrite', type: 'bool' }, + { internalType: 'bool', name: 'update', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: '_pid', type: 'uint256[]' }, + { internalType: 'uint64[]', name: '_allocPoint', type: 'uint64[]' }, + { + internalType: 'contract IRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + { internalType: 'bool[]', name: 'overwrite', type: 'bool[]' }, + { internalType: 'bool', name: 'update', type: 'bool' }, + ], + name: 'setBatch', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newTime', type: 'uint256' }, + { internalType: 'bool', name: 'inDays', type: 'bool' }, + ], + name: 'setV1HarvestQueryTime', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accBooPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MasterChefV2.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/spookyswap-v2/index.js b/src/adaptors/spookyswap-v2/index.js new file mode 100644 index 0000000000..a443fd8d8a --- /dev/null +++ b/src/adaptors/spookyswap-v2/index.js @@ -0,0 +1,282 @@ +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const { masterChefABI, lpTokenABI } = require('./abis'); +const utils = require('../utils'); + +const API_URL = sdk.graph.modifyEndpoint( + 'HyhMfT7gehNHMBmFiExqeg3pDtop9UikjvBPfAXT3b21' +); + +const MASTERCHEF_ADDRESS = '0x18b4f774fdC7BF685daeeF66c2990b1dDd9ea6aD'; +const BOO_TOKEN = '0x841FAD6EAe12c286d1Fd18d1d525DFfA75C7EFFE'.toLowerCase(); + +const FTM_BLOCK_TIME = 1; +const BLOCKS_PER_YEAR = Math.floor((60 / FTM_BLOCK_TIME) * 60 * 24 * 365); +const WEEKS_PER_YEAR = 52; +const FEE_RATE = 0.0017; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + bswPerBlock, + bswPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + const vvsPerYear = BLOCKS_PER_YEAR * bswPerBlock; + + return ((poolWeight * vvsPerYear * bswPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + decimals0, + decimals1, + tokenPrices +) => { + const token0Price = tokenPrices[token0.toLowerCase()]; + const token1Price = tokenPrices[token1.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - decimals0)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - decimals1)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getPrices = async (addresses) => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${addresses + .map((address) => `fantom:${address}`) + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const apy = async () => { + const poolsCount = ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + abi: masterChefABI.find((m) => m.name === 'poolLength'), + chain: 'fantom', + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + abi: masterChefABI.find((m) => m.name === 'totalAllocPoint'), + chain: 'fantom', + }) + ).output; + + const bswPerBlock = + ( + await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + abi: masterChefABI.find((m) => m.name === 'booPerSecond'), + chain: 'fantom', + }) + ).output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'fantom', + }); + + const pools = poolsRes.output.map(({ output }, i) => ({ ...output, i })); + + const lpTokens = ( + await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'lpToken')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'fantom', + }) + ).output.map(({ output }) => output); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'fantom', + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'fantom', + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + + const symbols0 = ( + await sdk.api.abi.multiCall({ + calls: tokens0.map((i) => ({ target: i })), + chain: 'fantom', + abi: 'erc20:symbol', + }) + ).output.map((o) => o.output); + const symbols1 = ( + await sdk.api.abi.multiCall({ + calls: tokens1.map((i) => ({ target: i })), + chain: 'fantom', + abi: 'erc20:symbol', + }) + ).output.map((o) => o.output); + + const decimals0 = ( + await sdk.api.abi.multiCall({ + calls: tokens0.map((i) => ({ target: i })), + chain: 'fantom', + abi: 'erc20:decimals', + }) + ).output.map((o) => o.output); + const decimals1 = ( + await sdk.api.abi.multiCall({ + calls: tokens1.map((i) => ({ target: i })), + chain: 'fantom', + abi: 'erc20:decimals', + }) + ).output.map((o) => o.output); + + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + + const queries = gql` + query volumesQuery { + ${lpTokens + .map( + (token, i) => `token_${token.toLowerCase()}:pairDayDatas( + orderBy: date + orderDirection: desc + first: 7 + where: { pairAddress: "${token.toLowerCase()}" } + ) { + dailyVolumeUSD + }` + ) + .join('\n')} + + } + `; + + const volumesMap = await request(API_URL, queries); + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + tokens0[i], + tokens1[i], + decimals0[i], + decimals1[i], + tokensPrices + ) + ?.div(1e18) + .toString(); + + const lpReservesUsd = calculateReservesUSD( + reserves, + 1, + tokens0[i], + tokens1[i], + decimals0[i], + decimals1[i], + tokensPrices + ) + ?.div(1e18) + .toString(); + + const lpFees7D = + (volumesMap[`token_${lpTokens[i].toLowerCase()}`] || []).reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * FEE_RATE; + + const apyBase = ((lpFees7D * WEEKS_PER_YEAR) / lpReservesUsd) * 100; + + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + bswPerBlock, + tokensPrices[BOO_TOKEN], + masterChefReservesUsd + ); + + return { + pool: lpTokens[i], + chain: utils.formatChain('fantom'), + project: 'spookyswap-v2', + symbol: `${symbols0[i]}-${symbols1[i]}`, + tvlUsd: + lpTokens[i]?.toLowerCase() === + '0xaf918ef5b9f33231764a5557881e6d3e5277d456' + ? Number(lpReservesUsd) + : Number(masterChefReservesUsd), + apyBase, + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [BOO_TOKEN], + }; + }); + + return res.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, + url: 'https://spooky.fi/#/farms', +}; diff --git a/src/adaptors/sprinter/index.ts b/src/adaptors/sprinter/index.ts new file mode 100644 index 0000000000..2c4d8fe68f --- /dev/null +++ b/src/adaptors/sprinter/index.ts @@ -0,0 +1,76 @@ +const sdk = require('@defillama/sdk'); +const { gql, request } = require('graphql-request'); +const { + BigNumber, + utils: { formatUnits }, +} = require('ethers'); + +const utils = require('../utils'); + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint("https://api.studio.thegraph.com/query/117634/sprinter-stash/v0.0.2"); +const HUB_CONTRACT_ADDRESS = "0xa593A9bBBc65be342FF610a01e96da2EB8539FF2"; +const DAY_IN_MS = 24 * 60 * 60 * 1000; +const INITIAL_DATE = '2025-06-17T00:00:00'; +const USDC_DECIMALS = 6; + +const DataQuery = gql` + query DataQuery($from: BigInt = "", $to: BigInt = "") { + depositProfits(where: {blockTimestamp_gte: $from, blockTimestamp_lte: $to}) { + assets + totalAssets + blockTimestamp + } + } +`; + +const startDate = new Date(INITIAL_DATE); +async function apy() { + const currentYear = new Date( + Date.UTC(new Date().getUTCFullYear(), 0, 1, 0, 0, 0), + ); + + const startTimestamp = + startDate.getUTCFullYear() === currentYear.getUTCFullYear() + ? startDate.getTime() + : currentYear.getTime(); + + let endTimestamp = Date.now(); + const { depositProfits } = await request(SUBGRAPH_URL, DataQuery, { + from: Math.floor(startTimestamp / 1000), + to: Math.floor(endTimestamp / 1000), + }); + + const totalProfit = depositProfits.reduce((sum, deposit) => { + return sum.add(BigNumber.from(deposit.assets)); + }, BigNumber.from(0)); + + const averageSupply = + depositProfits.reduce((sum, deposit) => { + return sum.add(BigNumber.from(deposit.totalAssets)); + }, BigNumber.from(0)).div(depositProfits.length); + + const lastDepositProfit = depositProfits[0]; + + const timeDiff = + new Date(parseInt(lastDepositProfit.blockTimestamp) * 1000).getTime() - startTimestamp; + const daysInPeriod = Math.max(1, Math.floor(timeDiff / DAY_IN_MS)); + + const ratio = + Number(formatUnits(totalProfit, USDC_DECIMALS)) / + Number(formatUnits(averageSupply, USDC_DECIMALS)); + const rate = Math.pow(1 + ratio, 365 / daysInPeriod) - 1; + + return [{ + project: "sprinter", + pool: HUB_CONTRACT_ADDRESS, + chain: utils.formatChain("base"), + symbol: utils.formatSymbol("USDC"), + tvlUsd: Number(formatUnits(lastDepositProfit.totalAssets, USDC_DECIMALS)), + apy: rate * 100, + }]; +} + +module.exports = { + apy: apy, + url: 'https://app.sprinter.tech/', +} diff --git a/src/adaptors/stable-jack-v1/abiAUSD.js b/src/adaptors/stable-jack-v1/abiAUSD.js new file mode 100644 index 0000000000..c310438d37 --- /dev/null +++ b/src/adaptors/stable-jack-v1/abiAUSD.js @@ -0,0 +1,357 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_from', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'subtractedValue', + type: 'uint256', + }, + ], + name: 'decreaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'addedValue', + type: 'uint256', + }, + ], + name: 'increaseAllowance', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + { + internalType: 'string', + name: '_name', + type: 'string', + }, + { + internalType: 'string', + name: '_symbol', + type: 'string', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_to', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nav', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'treasury', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/stable-jack-v1/abirebalancePool.js b/src/adaptors/stable-jack-v1/abirebalancePool.js new file mode 100644 index 0000000000..a772f1b2c9 --- /dev/null +++ b/src/adaptors/stable-jack-v1/abirebalancePool.js @@ -0,0 +1,1174 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newDeposit', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newUnlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'epoch', + type: 'uint256', + }, + ], + name: 'AccountSnapshotTaken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'manager', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'periodLength', + type: 'uint256', + }, + ], + name: 'AddRewardToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Claim', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'reciever', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'DepositReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'liquidated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseGained', + type: 'uint256', + }, + ], + name: 'Liquidate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'loss', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseOut', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assetLossPerUnitStaked', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'epoch', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scale', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newProductFactor', + type: 'uint256', + }, + ], + name: 'LossNotified', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'RemoveRewardToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pending', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardsPerUnitStaked', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'epoch', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scale', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newRewardSum', + type: 'uint256', + }, + ], + name: 'RewardsAccumulated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'duration', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pending', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'accumulated', + type: 'bool', + }, + ], + name: 'RewardsDistributed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'unlockAt', + type: 'uint256', + }, + ], + name: 'Unlock', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'liquidatableCollateralRatio', + type: 'uint256', + }, + ], + name: 'UpdateLiquidatableCollateralRatio', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + ], + name: 'UpdateLiquidator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'manager', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'periodLength', + type: 'uint256', + }, + ], + name: 'UpdateRewardToken', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'unlockDuration', + type: 'uint256', + }, + ], + name: 'UpdateUnlockDuration', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'wrapper', + type: 'address', + }, + ], + name: 'UpdateWrapper', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newDeposit', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'loss', + type: 'uint256', + }, + ], + name: 'UserDepositChange', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newUnlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'loss', + type: 'uint256', + }, + ], + name: 'UserUnlockChange', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawUnlocked', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'address', + name: '_manager', + type: 'address', + }, + { + internalType: 'uint32', + name: '_periodLength', + type: 'uint32', + }, + ], + name: 'addReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseRewardToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_tokens', + type: 'address[]', + }, + { + internalType: 'bool', + name: '_unwrap', + type: 'bool', + }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'bool', + name: '_unwrap', + type: 'bool', + }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + { + internalType: 'address', + name: '_token', + type: 'address', + }, + ], + name: 'claimable', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + { + internalType: 'address', + name: '_recipient', + type: 'address', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'depositReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'epochState', + outputs: [ + { + internalType: 'uint64', + name: 'epoch', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'scale', + type: 'uint64', + }, + { + internalType: 'uint128', + name: 'prod', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'epochToScaleToBaseRewardSum', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'epochToScaleToExtraRewardSum', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'extraRewardState', + outputs: [ + { + internalType: 'uint256', + name: 'rate', + type: 'uint256', + }, + { + internalType: 'uint32', + name: 'periodLength', + type: 'uint32', + }, + { + internalType: 'uint48', + name: 'lastUpdate', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'finishAt', + type: 'uint48', + }, + { + internalType: 'uint256', + name: 'queued', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'extraRewards', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'extraRewardsLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_treasury', + type: 'address', + }, + { + internalType: 'address', + name: '_market', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lastAssetLossError', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'liquidatableCollateralRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_maxAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_minBaseOut', + type: 'uint256', + }, + ], + name: 'liquidate', + outputs: [ + { + internalType: 'uint256', + name: '_liquidated', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_baseOut', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'liquidator', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'market', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256', + }, + ], + name: 'removeReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'rewardManager', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalUnlocking', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'treasury', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'unlock', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unlockDuration', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'unlockedBalanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'unlockingBalanceOf', + outputs: [ + { + internalType: 'uint256', + name: '_balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_unlockAt', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + ], + name: 'updateAccountSnapshot', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_liquidatableCollateralRatio', + type: 'uint256', + }, + ], + name: 'updateLiquidatableCollateralRatio', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_liquidator', + type: 'address', + }, + ], + name: 'updateLiquidator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_token', + type: 'address', + }, + { + internalType: 'address', + name: '_manager', + type: 'address', + }, + { + internalType: 'uint32', + name: '_periodLength', + type: 'uint32', + }, + ], + name: 'updateReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_unlockDuration', + type: 'uint256', + }, + ], + name: 'updateUnlockDuration', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bool', + name: '_doClaim', + type: 'bool', + }, + { + internalType: 'bool', + name: '_unwrap', + type: 'bool', + }, + ], + name: 'withdrawUnlocked', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'wrapper', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/stable-jack-v1/abisAVAXOracle.js b/src/adaptors/stable-jack-v1/abisAVAXOracle.js new file mode 100644 index 0000000000..293c610acc --- /dev/null +++ b/src/adaptors/stable-jack-v1/abisAVAXOracle.js @@ -0,0 +1,70 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IStakedAvax', + name: 'savax_', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'PRICE_DECIMALS', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getData', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'priceDecimals', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'savax', + outputs: [ + { + internalType: 'contract IStakedAvax', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/stable-jack-v1/abisAVAXTreasury.js b/src/adaptors/stable-jack-v1/abisAVAXTreasury.js new file mode 100644 index 0000000000..c2807910ff --- /dev/null +++ b/src/adaptors/stable-jack-v1/abisAVAXTreasury.js @@ -0,0 +1,1044 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'uint256', + name: '_initialMintRatio', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalRewards', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rebalancePoolRewards', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestBounty', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'price', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'aNav', + type: 'uint256', + }, + ], + name: 'ProtocolSettle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'baseTokenCap', + type: 'uint256', + }, + ], + name: 'UpdateBaseTokenCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'beta', + type: 'uint256', + }, + ], + name: 'UpdateBeta', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint24', + name: 'sampleInterval', + type: 'uint24', + }, + ], + name: 'UpdateEMASampleInterval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'platform', + type: 'address', + }, + ], + name: 'UpdatePlatform', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'priceOracle', + type: 'address', + }, + ], + name: 'UpdatePriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'rateProvider', + type: 'address', + }, + ], + name: 'UpdateRateProvider', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'rebalancePool', + type: 'address', + }, + ], + name: 'UpdateRebalancePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rebalancePoolRatio', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestBountyRatio', + type: 'uint256', + }, + ], + name: 'UpdateRewardRatio', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'status', + type: 'bool', + }, + ], + name: 'UpdateSettleWhitelist', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint24', + name: 'sampleInterval', + type: 'uint24', + }, + ], + name: 'V2Initialized', + type: 'event', + }, + { + inputs: [], + name: 'aToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'baseTokenCap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'beta', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'collateralRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'convertToUnwrapped', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_amount', + type: 'uint256', + }, + ], + name: 'convertToWrapped', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'currentBaseTokenPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emaLeverageRatio', + outputs: [ + { + internalType: 'uint40', + name: 'lastTime', + type: 'uint40', + }, + { + internalType: 'uint24', + name: 'sampleInterval', + type: 'uint24', + }, + { + internalType: 'uint96', + name: 'lastValue', + type: 'uint96', + }, + { + internalType: 'uint96', + name: 'lastEmaValue', + type: 'uint96', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getCurrentNav', + outputs: [ + { + internalType: 'uint256', + name: '_baseNav', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_aNav', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_xNav', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'harvestBountyRatio', + outputs: [ + { + internalType: 'uint128', + name: '', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_market', + type: 'address', + }, + { + internalType: 'address', + name: '_baseToken', + type: 'address', + }, + { + internalType: 'address', + name: '_aToken', + type: 'address', + }, + { + internalType: 'address', + name: '_xToken', + type: 'address', + }, + { + internalType: 'address', + name: '_priceOracle', + type: 'address', + }, + { + internalType: 'uint256', + name: '_beta', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_baseTokenCap', + type: 'uint256', + }, + { + internalType: 'address', + name: '_rateProvider', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'initializePrice', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint24', + name: 'sampleInterval', + type: 'uint24', + }, + ], + name: 'initializeV2', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isBaseTokenPriceValid', + outputs: [ + { + internalType: 'bool', + name: '_isValid', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isUnderCollateral', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastPermissionedPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'leverageRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'market', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_incentiveRatio', + type: 'uint256', + }, + ], + name: 'maxLiquidatable', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseOut', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxaTokenLiquidatable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + ], + name: 'maxMintableXToken', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseIn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxXTokenMintable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_incentiveRatio', + type: 'uint256', + }, + ], + name: 'maxMintableXTokenWithIncentive', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseIn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxXTokenMintable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + ], + name: 'maxMintableaToken', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseIn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxaTokenMintable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + ], + name: 'maxRedeemableXToken', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseOut', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxXTokenRedeemable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newCollateralRatio', + type: 'uint256', + }, + ], + name: 'maxRedeemableaToken', + outputs: [ + { + internalType: 'uint256', + name: '_maxBaseOut', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_maxaTokenRedeemable', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_baseIn', + type: 'uint256', + }, + { + internalType: 'address', + name: '_recipient', + type: 'address', + }, + { + internalType: 'enum IJackTreasury.MintOption', + name: '_option', + type: 'uint8', + }, + ], + name: 'mint', + outputs: [ + { + internalType: 'uint256', + name: '_aTokenOut', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_xTokenOut', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'platform', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'priceOracle', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rateProvider', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rebalancePool', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rebalancePoolRatio', + outputs: [ + { + internalType: 'uint128', + name: '', + type: 'uint128', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_aTokenIn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '_xTokenIn', + type: 'uint256', + }, + { + internalType: 'address', + name: '_owner', + type: 'address', + }, + ], + name: 'redeem', + outputs: [ + { + internalType: 'uint256', + name: '_baseOut', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'settleWhitelist', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalBaseToken', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_baseTokenCap', + type: 'uint256', + }, + ], + name: 'updateBaseTokenCap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_beta', + type: 'uint256', + }, + ], + name: 'updateBeta', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint24', + name: '_sampleInterval', + type: 'uint24', + }, + ], + name: 'updateEMASampleInterval', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_platform', + type: 'address', + }, + ], + name: 'updatePlatform', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_priceOracle', + type: 'address', + }, + ], + name: 'updatePriceOracle', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rateProvider', + type: 'address', + }, + ], + name: 'updateRateProvider', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_rebalancePool', + type: 'address', + }, + ], + name: 'updateRebalancePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint128', + name: '_rebalancePoolRatio', + type: 'uint128', + }, + { + internalType: 'uint128', + name: '_harvestBountyRatio', + type: 'uint128', + }, + ], + name: 'updateRewardRatio', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_account', + type: 'address', + }, + { + internalType: 'bool', + name: '_status', + type: 'bool', + }, + ], + name: 'updateSettleWhitelist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'xAVAXLeverageRatio', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'xToken', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/stable-jack-v1/index.js b/src/adaptors/stable-jack-v1/index.js new file mode 100644 index 0000000000..699ba4bec9 --- /dev/null +++ b/src/adaptors/stable-jack-v1/index.js @@ -0,0 +1,106 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abisAVAXOracle = require('./abisAVAXOracle'); +const abisAVAXTreasury = require('./abisAVAXTreasury'); +const abiRebalancePool = require('./abirebalancePool.js'); +const abiAUSD = require('./abiAUSD'); +const { apyBase } = require('../barnbridge/numbers'); +const { rewardTokens } = require('../sommelier/config'); + +const sAVAX = 'avax:0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be'; +const sAVAXTreasury = '0xDC325ad34C762C19FaAB37d439fbf219715f9D58'; +const sAVAXOracle = '0x600466c3c707A75129C7B7BC280e5A00C219fEF0'; +const aUSD = '0xaBe7a9dFDA35230ff60D1590a929aE0644c47DC1'; +const rebalancePool = '0x0363a3deBe776de575C36F524b7877dB7dd461Db'; + +const getAPR = async () => { + return (await axios.get('https://api.benqi.fi/liquidstaking/apr')).data.apr; +}; + +const getTreasuryTotalwsAVAX = async () => { + return ( + ( + await sdk.api.abi.call({ + target: sAVAXTreasury, + abi: abisAVAXTreasury.find((m) => m.name === 'totalBaseToken'), + chain: 'avax', + params: [], + }) + ).output / 1e18 + ); +}; + +// this returns the ratio of sAVAX to wsAVAX +const getWSAVAXtoSAVAXRatio = async () => { + const wsAVAXPrice = await sdk.api.abi.call({ + target: sAVAXOracle, + abi: abisAVAXOracle.find((m) => m.name === 'getData'), + chain: 'avax', + params: [], + }); + + return wsAVAXPrice.output[0] / 1e18; +}; + +const getSAVAXPrice = async () => { + return (await axios.get(`https://coins.llama.fi/prices/current/${sAVAX}`)) + .data.coins[sAVAX].price; +}; + +const getaUSDPrice = async () => { + return ( + ( + await sdk.api.abi.call({ + target: aUSD, + abi: abiAUSD.find((m) => m.name == 'nav'), + chain: 'avax', + params: [], + }) + ).output / 1e18 + ); +}; + +const getRPoolTotalSupply = async () => { + return ( + ( + await sdk.api.abi.call({ + target: rebalancePool, + abi: abiRebalancePool.find((m) => m.name === 'totalSupply'), + chain: 'avax', + }) + ).output / 1e18 + ); +}; + +const pool = '0x0363a3deBe776de575C36F524b7877dB7dd461Db-avax'.toLowerCase(); +async function main() { + const totalwsAVAX = await getTreasuryTotalwsAVAX(); + const wsAVAXPrice = await getWSAVAXtoSAVAXRatio(); + const sAVAXPrice = await getSAVAXPrice(); + const APR = await getAPR(); + const rPoolSupply = await getRPoolTotalSupply(); + const aUSDPrice = await getaUSDPrice(); + + const sAVAXTVL = (totalwsAVAX / wsAVAXPrice) * sAVAXPrice; + const rPoolTVL = rPoolSupply * aUSDPrice; + const protocolAPR = (sAVAXTVL / rPoolTVL) * APR; + const rPoolAPR = protocolAPR * 0.9 * 100; + + return [ + { + pool: pool, + chain: 'avax', + project: 'stable-jack-v1', + symbol: 'aUSD', + tvlUsd: rPoolTVL, + apyBase: rPoolAPR, + rewardTokens: [sAVAX], + }, + ]; +} + +module.exports = { + apy: main, + url: 'https://app.stablejack.xyz/rebalancepool', +}; diff --git a/src/adaptors/stablebase/abis.js b/src/adaptors/stablebase/abis.js new file mode 100644 index 0000000000..e73383cff9 --- /dev/null +++ b/src/adaptors/stablebase/abis.js @@ -0,0 +1,1660 @@ +module.exports = { + lpABI: [ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + masterChefABI: [ + { + "inputs": [ + { + "internalType": "contract IBoringERC20", + "name": "_sBaseToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_sBasePerSec", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_treasuryAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IBoringERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IComplexRewarder[]", + "name": "rewarders", + "type": "address[]" + } + ], + "name": "Add", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newAmount", + "type": "uint256" + } + ], + "name": "AllocPointsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "EmissionRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountLockedUp", + "type": "uint256" + } + ], + "name": "RewardLockedUp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IComplexRewarder[]", + "name": "rewarders", + "type": "address[]" + } + ], + "name": "Set", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAddress", + "type": "address" + } + ], + "name": "SetTreasuryAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accSBasePerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MAXIMUM_DEPOSIT_FEE_RATE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAXIMUM_HARVEST_INTERVAL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SBASE", + "outputs": [ + { + "internalType": "contract IBoringERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBoringERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_harvestInterval", + "type": "uint256" + }, + { + "internalType": "contract IComplexRewarder[]", + "name": "_rewarders", + "type": "address[]" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "canHarvest", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "depositWithPermit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + } + ], + "name": "harvestMany", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "symbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "decimals", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBoringERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accSBasePerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "harvestInterval", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalLp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "poolRewarders", + "outputs": [ + { + "internalType": "address[]", + "name": "rewarders", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "poolRewardsPerSec", + "outputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "symbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "decimals", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsPerSec", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "poolTotalLp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sBasePerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_harvestInterval", + "type": "uint256" + }, + { + "internalType": "contract IComplexRewarder[]", + "name": "_rewarders", + "type": "address[]" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasuryAddress", + "type": "address" + } + ], + "name": "setTreasuryAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startFarming", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalLockedUpRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSBaseInPools", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + } + ], + "name": "updateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_sBasePerSec", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardLockedUp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nextHarvestUntil", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +}; diff --git a/src/adaptors/stablebase/index.js b/src/adaptors/stablebase/index.js new file mode 100644 index 0000000000..c96c66a1ac --- /dev/null +++ b/src/adaptors/stablebase/index.js @@ -0,0 +1,113 @@ +const sdk = require('@defillama/sdk'); +const { Web3 } = require('web3'); +const superagent = require('superagent'); +const { masterChefABI, lpABI } = require('./abis'); +const utils = require('../utils'); + +const MASTERCHEF_ADDRESS = '0x8eE78D4836B44944D393941A736b6DC23e33bc69'; +const sBASE = '0x616F5b97C22Fa42C3cA7376F7a25F0d0F598b7Bb'; +const WETH = '0x4200000000000000000000000000000000000006'; +const sBASE_WETH_LP = '0xd072a63c2d54b49229a4557b3aeb1cbe04eb6b2e'; + +const RPC_URL = 'https://mainnet.base.org'; +const web3 = new Web3(RPC_URL); + +const poolStaticData = { + '0x5626f9217e774eabebb86821f5fbe6e8ed0770dc': { + tokens: 'USDC-DAI-axlUSD', + }, + [sBASE_WETH_LP]: { + tokens: 'sBASE-WETH', + }, + '0x890cff90ee1c24b0a2264e5d3618bfdec05b077c': { + tokens: 'USDC-USDbC', + }, +}; + +const getPrice = async () => { + const lpContract = new web3.eth.Contract(lpABI, sBASE_WETH_LP); + const sBASEreserves = await lpContract.methods.getReserves().call(); + const totalSupply = await lpContract.methods.totalSupply().call(); + + // WETH Price + const ethPriceRes = ( + await superagent.get( + `https://coins.llama.fi/prices/current/base:${WETH.toLowerCase()}` + ) + ).body.coins; + const ethPrice = ethPriceRes[`base:${WETH}`]?.price; + + // sBASE Price + const reserve1 = sBASEreserves[0]; + const reserve0 = sBASEreserves[1]; + const sBASE_IN_ETH = Number(reserve1) / Number(reserve0); + const sBasePrice = sBASE_IN_ETH * ethPrice; + + // sBASE-WETH LP Price + const token0total = Number( + Number(sBasePrice * (Number(reserve0) / 10 ** 18)).toString() + ); + const token1total = Number( + Number(ethPrice * (Number(reserve1) / 10 ** 18)).toString() + ); + const lpTotalPrice = Number(token0total + token1total); + const lpPrice = lpTotalPrice / (Number(totalSupply) / 10 ** 18); + + return { sBasePrice, ethPrice, lpPrice }; +}; + +const main = async () => { + const { sBasePrice, ethPrice, lpPrice } = await getPrice(); + const masterChef = new web3.eth.Contract(masterChefABI, MASTERCHEF_ADDRESS); + + const poolsCount = await masterChef.methods.poolLength().call(); + const totalAllocPoint = Number( + await masterChef.methods.totalAllocPoint().call() + ); + const perSec = Number(await masterChef.methods.sBasePerSec().call()) / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'base', + }); + + const pools = poolsRes.output.map(({ output }, i) => ({ ...output, i })); + + const response = pools.map((pool, index) => { + const allocPoint = pool[1]; + const _tvl = pool[6]; + const numerator = allocPoint * perSec * 86400; + const denominator = totalAllocPoint; + const rewardPerDay = numerator / denominator; + const rewardPerYear = rewardPerDay * 365 * 100; + let apy = 0; + let tvl = _tvl / 1e18; + if (index === 1) { + tvl = (_tvl / 1e18) * lpPrice; + apy = (rewardPerYear * sBasePrice) / tvl; + } else { + apy = (rewardPerYear * sBasePrice) / tvl; + } + return { + pool: pool[0], + chain: utils.formatChain('base'), + project: 'stablebase', + symbol: poolStaticData[pool[0].toLowerCase()].tokens, + tvlUsd: tvl, + apyReward: apy, + rewardTokens: [sBASE], + }; + }); + + return response; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://stablebase.fi/farm', +}; diff --git a/src/adaptors/stables-labs-usdx/index.js b/src/adaptors/stables-labs-usdx/index.js new file mode 100644 index 0000000000..c864a7faaa --- /dev/null +++ b/src/adaptors/stables-labs-usdx/index.js @@ -0,0 +1,78 @@ +const { gql } = require('graphql-request'); +const utils = require('../utils'); +const fetch = require('node-fetch'); + +const USDX = '0xf3527ef8dE265eAa3716FB312c12847bFBA66Cef'; + +const poolsFunction = async (chainString, subgraphUrl, token) => { + const query = ` + query { + rewardAccumulations(first: 1) { + id + totalAmount + totalAssets + lastRewardTime + apy + } + } + `; + + let apyData = { + tvl: 0, + deposit_apy: 0, + }; + + try { + const response = await fetch(subgraphUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query }), + }); + const { data } = await response.json(); + const { rewardAccumulations } = data; + apyData.deposit_apy = rewardAccumulations[0].apy; + apyData.tvl = rewardAccumulations[0].totalAssets; + } catch (err) { + console.log('Error fetching token prices:', err); + return {}; + } + + const usdxPool = { + pool: `${token}-${chainString.toLowerCase()}`, + symbol: 'USDX', + project: 'stables-labs-usdx', + chain: chainString, + tvlUsd: Number(apyData.tvl) / 1e18, + apyBase: Number(apyData.deposit_apy) * 100, + poolMeta: '7 days unstaking', + underlyingTokens: [token], + }; + + return usdxPool; +}; + +const main = async () => { + const data = await Promise.all([ + poolsFunction( + 'Ethereum', + 'https://api.studio.thegraph.com/query/96429/usdx-subgraph-ethereum/version/latest', + '0xf3527ef8dE265eAa3716FB312c12847bFBA66Cef' + ), + poolsFunction( + 'Arbitrum', + 'https://api.studio.thegraph.com/query/96429/usdx-subgraph-arbitrum/version/latest', + '0xf3527ef8dE265eAa3716FB312c12847bFBA66Cef' + ), + poolsFunction( + 'Bsc', + 'https://api.studio.thegraph.com/query/96429/usdx-subgraph-bsc/version/latest', + '0xf3527ef8dE265eAa3716FB312c12847bFBA66Cef' + ), + ]); + return data; +}; + +module.exports = { + apy: main, + url: 'https://app.usdx.money/', +}; diff --git a/src/adaptors/stack/abi/FeeSplitter.json b/src/adaptors/stack/abi/FeeSplitter.json new file mode 100644 index 0000000000..e7a792d8a8 --- /dev/null +++ b/src/adaptors/stack/abi/FeeSplitter.json @@ -0,0 +1,535 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_token", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + }, + { + "name": "split", + "type": "uint96", + "internalType": "uint96" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "allReceivers", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct FeeSplitter.FeeReceiver[]", + "components": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + }, + { + "name": "split", + "type": "uint96", + "internalType": "uint96" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "checkpoint", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct FeeSplitter.Checkpoint", + "components": [ + { + "name": "timestamp", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "totalDistributed", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "distribute", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "distributionRate", + "inputs": [], + "outputs": [ + { + "name": "tokensPerSecond", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "distributionRateFor", + "inputs": [ + { + "name": "feeReceiver", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "tokensPerSecond", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "distributor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setDistributor", + "inputs": [ + { + "name": "_distributor", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setReceivers", + "inputs": [ + { + "name": "receivers", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "splits", + "type": "uint96[]", + "internalType": "uint96[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "token", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + }, + { + "name": "split", + "type": "uint96", + "internalType": "uint96" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967InvalidImplementation", + "inputs": [ + { + "name": "implementation", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967NonPayable", + "inputs": [] + }, + { + "type": "error", + "name": "FailedInnerCall", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidFee", + "inputs": [ + { + "name": "min", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "actual", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidShare", + "inputs": [ + { + "name": "min", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "max", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "actual", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidSplitValue", + "inputs": [ + { + "name": "value", + "type": "uint96", + "internalType": "uint96" + } + ] + }, + { + "type": "error", + "name": "InvalidZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ReceiverAlreadyAdded", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ReceiverNotFound", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "UUPSUnauthorizedCallContext", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnsupportedProxiableUUID", + "inputs": [ + { + "name": "slot", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "UnauthorizedCaller", + "inputs": [] + }, + { + "type": "error", + "name": "ValueUnchanged", + "inputs": [] + } +] diff --git a/src/adaptors/stack/constants.js b/src/adaptors/stack/constants.js new file mode 100644 index 0000000000..df70c2b01f --- /dev/null +++ b/src/adaptors/stack/constants.js @@ -0,0 +1,18 @@ +const FeeSplitterContractAbi = require('./abi/FeeSplitter.json'); + +const contracts = { + FeeSplitter: { + address: "0x02473349D9e2AbbFcF5b82F171b55Cd694f9Fc7A", + abi: FeeSplitterContractAbi, + }, +}; + +const tokens = { + MORE: "0x25ea98ac87A38142561eA70143fd44c4772A16b6", + sMORE: "0xD1e39288520f9f3619714B525e1fD5F8c023dbA1", +}; + +module.exports = { + contracts, + tokens, +}; diff --git a/src/adaptors/stack/index.js b/src/adaptors/stack/index.js new file mode 100644 index 0000000000..e9e47d5764 --- /dev/null +++ b/src/adaptors/stack/index.js @@ -0,0 +1,68 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { ethers } = require('ethers'); + +const utils = require('../utils'); +const { contracts, tokens } = require('./constants'); + +const apy = async () => { + const underlying = tokens.MORE; + const tokenPrices = ( + await axios.get(`https://coins.llama.fi/prices/current/real:${underlying}`) + ).data.coins; + + const underlyingPrice = tokenPrices[`real:${underlying}`]?.price; + + const [tvlRes, decimalsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals'].map( + async (method) => + await sdk.api.abi.multiCall({ + abi: method, + calls: [ + { + target: tokens.MORE, + params: method === 'erc20:balanceOf' ? tokens.sMORE : null, + }, + ], + chain: 'real', + }) + ) + ); + + const [tvl] = tvlRes.output.map((o) => o.output); + const [decimals] = decimalsRes.output.map((o) => o.output); + + const tvlUsd = (underlyingPrice * tvl) / 10 ** decimals; + + const tokensPerSecond = await sdk.api.abi.call({ + abi: contracts.FeeSplitter.abi.find( + (m) => m.name === 'distributionRateFor' + ), + target: contracts.FeeSplitter.address, + params: tokens.sMORE, + chain: 'real', + }); + + const tokensPerYear = tokensPerSecond.output * 60 * 60 * 24 * 365; + const apr = tokensPerYear / tvl; + + return [ + { + pool: tokens.sMORE, + chain: 'real', + project: 'stack', + symbol: utils.formatSymbol('sMORE'), + tvlUsd, + underlyingTokens: [tokens.MORE], + apyBase: apr * 100, + apyReward: 0, + rewardTokens: null, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://www.stackmore.xyz/stake', +}; diff --git a/src/adaptors/stader/ PermissionlessNodeRegistryAbi.json b/src/adaptors/stader/ PermissionlessNodeRegistryAbi.json new file mode 100644 index 0000000000..93ed282118 --- /dev/null +++ b/src/adaptors/stader/ PermissionlessNodeRegistryAbi.json @@ -0,0 +1,1143 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "CallerNotManager", "type": "error" }, + { "inputs": [], "name": "CallerNotOperator", "type": "error" }, + { "inputs": [], "name": "CallerNotStaderContract", "type": "error" }, + { "inputs": [], "name": "CooldownNotComplete", "type": "error" }, + { "inputs": [], "name": "DuplicatePoolIDOrPoolNotAdded", "type": "error" }, + { "inputs": [], "name": "InSufficientBalance", "type": "error" }, + { "inputs": [], "name": "InvalidBondEthValue", "type": "error" }, + { "inputs": [], "name": "InvalidKeyCount", "type": "error" }, + { "inputs": [], "name": "InvalidStartAndEndIndex", "type": "error" }, + { "inputs": [], "name": "MisMatchingInputKeysSize", "type": "error" }, + { "inputs": [], "name": "NoChangeInState", "type": "error" }, + { "inputs": [], "name": "NotEnoughSDCollateral", "type": "error" }, + { + "inputs": [], + "name": "OperatorAlreadyOnBoardedInProtocol", + "type": "error" + }, + { "inputs": [], "name": "OperatorIsDeactivate", "type": "error" }, + { "inputs": [], "name": "OperatorNotOnBoarded", "type": "error" }, + { "inputs": [], "name": "PageNumberIsZero", "type": "error" }, + { "inputs": [], "name": "PubkeyAlreadyExist", "type": "error" }, + { "inputs": [], "name": "TooManyVerifiedKeysReported", "type": "error" }, + { "inputs": [], "name": "TooManyWithdrawnKeysReported", "type": "error" }, + { "inputs": [], "name": "TransferFailed", "type": "error" }, + { "inputs": [], "name": "UNEXPECTED_STATUS", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { "inputs": [], "name": "maxKeyLimitReached", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "nodeOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + } + ], + "name": "AddedValidatorKey", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalActiveValidatorCount", + "type": "uint256" + } + ], + "name": "DecreasedTotalActiveValidatorCount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalActiveValidatorCount", + "type": "uint256" + } + ], + "name": "IncreasedTotalActiveValidatorCount", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "nodeOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "nodeRewardAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "optInForSocializingPool", + "type": "bool" + } + ], + "name": "OnboardedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredCollateralToPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "batchKeyDepositLimit", + "type": "uint256" + } + ], + "name": "UpdatedInputKeyCountLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "maxNonTerminalKeyPerOperator", + "type": "uint64" + } + ], + "name": "UpdatedMaxNonTerminalKeyPerOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "nextQueuedValidatorIndex", + "type": "uint256" + } + ], + "name": "UpdatedNextQueuedValidatorIndex", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "nodeOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "operatorName", + "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardAddress", + "type": "address" + } + ], + "name": "UpdatedOperatorDetails", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "operatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "optedForSocializingPool", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "block", + "type": "uint256" + } + ], + "name": "UpdatedSocializingPoolState", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "staderConfig", + "type": "address" + } + ], + "name": "UpdatedStaderConfig", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "depositBlock", + "type": "uint256" + } + ], + "name": "UpdatedValidatorDepositBlock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "verifiedKeysBatchSize", + "type": "uint256" + } + ], + "name": "UpdatedVerifiedKeyBatchSize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawnKeysBatchSize", + "type": "uint256" + } + ], + "name": "UpdatedWithdrawnKeyBatchSize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + } + ], + "name": "ValidatorMarkedAsFrontRunned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + } + ], + "name": "ValidatorMarkedReadyToDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + } + ], + "name": "ValidatorStatusMarkedAsInvalidSignature", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "pubkey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorId", + "type": "uint256" + } + ], + "name": "ValidatorWithdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "COLLATERAL_ETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FRONT_RUN_PENALTY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POOL_ID", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "_pubkey", "type": "bytes[]" }, + { + "internalType": "bytes[]", + "name": "_preDepositSignature", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "_depositSignature", + "type": "bytes[]" + } + ], + "name": "addValidatorKeys", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_optInForSocializingPool", + "type": "bool" + } + ], + "name": "changeSocializingPoolState", + "outputs": [ + { + "internalType": "address", + "name": "feeRecipientAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pageNumber", "type": "uint256" }, + { "internalType": "uint256", "name": "_pageSize", "type": "uint256" } + ], + "name": "getAllActiveValidators", + "outputs": [ + { + "components": [ + { + "internalType": "enum ValidatorStatus", + "name": "status", + "type": "uint8" + }, + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { + "internalType": "bytes", + "name": "preDepositSignature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "depositSignature", + "type": "bytes" + }, + { + "internalType": "address", + "name": "withdrawVaultAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "operatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawnBlock", + "type": "uint256" + } + ], + "internalType": "struct Validator[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pageNumber", "type": "uint256" }, + { "internalType": "uint256", "name": "_pageSize", "type": "uint256" } + ], + "name": "getAllNodeELVaultAddress", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCollateralETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "getOperatorRewardAddress", + "outputs": [ + { "internalType": "address payable", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "getOperatorTotalKeys", + "outputs": [ + { "internalType": "uint256", "name": "_totalKeys", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_nodeOperator", "type": "address" }, + { "internalType": "uint256", "name": "_startIndex", "type": "uint256" }, + { "internalType": "uint256", "name": "_endIndex", "type": "uint256" } + ], + "name": "getOperatorTotalNonTerminalKeys", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_operatorId", "type": "uint256" } + ], + "name": "getSocializingPoolStateChangeBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalActiveValidatorCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalQueuedValidatorCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_operator", "type": "address" }, + { "internalType": "uint256", "name": "_pageNumber", "type": "uint256" }, + { "internalType": "uint256", "name": "_pageSize", "type": "uint256" } + ], + "name": "getValidatorsByOperator", + "outputs": [ + { + "components": [ + { + "internalType": "enum ValidatorStatus", + "name": "status", + "type": "uint8" + }, + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { + "internalType": "bytes", + "name": "preDepositSignature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "depositSignature", + "type": "bytes" + }, + { + "internalType": "address", + "name": "withdrawVaultAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "operatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawnBlock", + "type": "uint256" + } + ], + "internalType": "struct Validator[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_count", "type": "uint256" } + ], + "name": "increaseTotalActiveValidatorCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_admin", "type": "address" }, + { "internalType": "address", "name": "_staderConfig", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "inputKeyCountLimit", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_operAddr", "type": "address" } + ], + "name": "isExistingOperator", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "_pubkey", "type": "bytes" }], + "name": "isExistingPubkey", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "_readyToDepositPubkey", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "_frontRunPubkey", + "type": "bytes[]" + }, + { + "internalType": "bytes[]", + "name": "_invalidSignaturePubkey", + "type": "bytes[]" + } + ], + "name": "markValidatorReadyToDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxNonTerminalKeyPerOperator", + "outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextOperatorId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextQueuedValidatorIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextValidatorId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "nodeELRewardVaultByOperatorId", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_optInForSocializingPool", + "type": "bool" + }, + { "internalType": "string", "name": "_operatorName", "type": "string" }, + { + "internalType": "address payable", + "name": "_operatorRewardAddress", + "type": "address" + } + ], + "name": "onboardNodeOperator", + "outputs": [ + { + "internalType": "address", + "name": "feeRecipientAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "operatorIDByAddress", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "operatorStructById", + "outputs": [ + { "internalType": "bool", "name": "active", "type": "bool" }, + { + "internalType": "bool", + "name": "optedForSocializingPool", + "type": "bool" + }, + { "internalType": "string", "name": "operatorName", "type": "string" }, + { + "internalType": "address payable", + "name": "operatorRewardAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "operatorAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "queuedValidators", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "socializingPoolStateChangeBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "staderConfig", + "outputs": [ + { + "internalType": "contract IStaderConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalActiveValidatorCount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "transferCollateralToPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_validatorId", "type": "uint256" } + ], + "name": "updateDepositStatusAndBlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_inputKeyCountLimit", + "type": "uint16" + } + ], + "name": "updateInputKeyCountLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_maxNonTerminalKeyPerOperator", + "type": "uint64" + } + ], + "name": "updateMaxNonTerminalKeyPerOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nextQueuedValidatorIndex", + "type": "uint256" + } + ], + "name": "updateNextQueuedValidatorIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "_operatorName", "type": "string" }, + { + "internalType": "address payable", + "name": "_rewardAddress", + "type": "address" + } + ], + "name": "updateOperatorDetails", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_staderConfig", "type": "address" } + ], + "name": "updateStaderConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_verifiedKeysBatchSize", + "type": "uint256" + } + ], + "name": "updateVerifiedKeysBatchSize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "name": "validatorIdByPubkey", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "validatorIdsByOperatorId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validatorQueueSize", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "validatorRegistry", + "outputs": [ + { + "internalType": "enum ValidatorStatus", + "name": "status", + "type": "uint8" + }, + { "internalType": "bytes", "name": "pubkey", "type": "bytes" }, + { + "internalType": "bytes", + "name": "preDepositSignature", + "type": "bytes" + }, + { "internalType": "bytes", "name": "depositSignature", "type": "bytes" }, + { + "internalType": "address", + "name": "withdrawVaultAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "operatorId", "type": "uint256" }, + { "internalType": "uint256", "name": "depositBlock", "type": "uint256" }, + { "internalType": "uint256", "name": "withdrawnBlock", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "verifiedKeyBatchSize", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "_pubkeys", "type": "bytes[]" } + ], + "name": "withdrawnValidators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stader/abi.js b/src/adaptors/stader/abi.js new file mode 100644 index 0000000000..d2c3766820 --- /dev/null +++ b/src/adaptors/stader/abi.js @@ -0,0 +1,536 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { inputs: [], name: 'CallerNotManager', type: 'error' }, + { inputs: [], name: 'CallerNotStaderContract', type: 'error' }, + { inputs: [], name: 'CooldownNotComplete', type: 'error' }, + { inputs: [], name: 'InsufficientBalance', type: 'error' }, + { inputs: [], name: 'InvalidDepositAmount', type: 'error' }, + { inputs: [], name: 'PoolIdDoesNotExit', type: 'error' }, + { inputs: [], name: 'TransferFailed', type: 'error' }, + { inputs: [], name: 'UnsupportedOperation', type: 'error' }, + { inputs: [], name: 'UnsupportedOperationInSafeMode', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'AuctionedEthReceived', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'poolId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'poolAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'validatorCount', + type: 'uint256', + }, + ], + name: 'ETHTransferredToPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ExecutionLayerRewardsReceived', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint8', + name: 'poolId', + type: 'uint8', + }, + ], + name: 'ReceivedExcessEthFromPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, + ], + name: 'RoleAdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleRevoked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'TransferredETHToUserWithdrawManager', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'excessETHDepositCoolDown', + type: 'uint256', + }, + ], + name: 'UpdatedExcessETHDepositCoolDown', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'staderConfig', + type: 'address', + }, + ], + name: 'UpdatedStaderConfig', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'WithdrawVaultUserShareReceived', + type: 'event', + }, + { stateMutability: 'payable', type: 'fallback' }, + { + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_receiver', type: 'address' }], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'depositETHOverTargetWeight', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'excessETHDepositCoolDown', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getExchangeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_admin', type: 'address' }, + { internalType: 'address', name: '_staderConfig', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isVaultHealthy', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastExcessETHDepositBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'minDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'receiveEthFromAuction', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: '_poolId', type: 'uint8' }], + name: 'receiveExcessEthFromPool', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'receiveExecutionLayerRewards', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'receiveWithdrawVaultUserShare', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'staderConfig', + outputs: [ + { + internalType: 'contract IStaderConfig', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'transferETHToUserWithdrawManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_excessETHDepositCoolDown', + type: 'uint256', + }, + ], + name: 'updateExcessETHDepositCoolDown', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_staderConfig', type: 'address' }, + ], + name: 'updateStaderConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: '_poolId', type: 'uint8' }], + name: 'validatorBatchDeposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, +]; diff --git a/src/adaptors/stader/abiPolygon.json b/src/adaptors/stader/abiPolygon.json new file mode 100644 index 0000000000..f7a3d2e610 --- /dev/null +++ b/src/adaptors/stader/abiPolygon.json @@ -0,0 +1,1008 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_idx", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountClaimed", + "type": "uint256" + } + ], + "name": "ClaimWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_validatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountDelegated", + "type": "uint256" + } + ], + "name": "Delegate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "DistributeFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_fromValidatorId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_toValidatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "MigrateDelegation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "MintFromPolygon", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountMaticX", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountMatic", + "type": "uint256" + } + ], + "name": "RequestWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "_feePercent", + "type": "uint8" + } + ], + "name": "SetFeePercent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "SetFxStateRootTunnel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "SetInstantPoolOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "SetTreasury", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "SetValidatorRegistry", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "_version", + "type": "string" + } + ], + "name": "SetVersion", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_validatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amountStaked", + "type": "uint256" + } + ], + "name": "StakeRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Submit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_validatorId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "WithdrawRewards", + "type": "event" + }, + { + "inputs": [], + "name": "BOT", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INSTANT_POOL_OWNER", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PREDICATE_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_idx", "type": "uint256" } + ], + "name": "claimWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_balance", "type": "uint256" } + ], + "name": "convertMaticToMaticX", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_balance", "type": "uint256" } + ], + "name": "convertMaticXToMatic", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feePercent", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fxStateRootTunnel", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getContracts", + "outputs": [ + { "internalType": "address", "name": "_stakeManager", "type": "address" }, + { "internalType": "address", "name": "_polygonERC20", "type": "address" }, + { + "internalType": "address", + "name": "_validatorRegistry", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" } + ], + "name": "getRoleAdmin", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" }, + { "internalType": "uint256", "name": "_idx", "type": "uint256" } + ], + "name": "getSharesAmountOfUserWithdrawalRequest", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalPooledMatic", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IValidatorShare", + "name": "_validatorShare", + "type": "address" + } + ], + "name": "getTotalStake", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalStakeAcrossAllValidators", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "getUserWithdrawalRequests", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "validatorNonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestEpoch", + "type": "uint256" + }, + { + "internalType": "address", + "name": "validatorAddress", + "type": "address" + } + ], + "internalType": "struct IMaticX.WithdrawalRequest[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validatorRegistry", + "type": "address" + }, + { "internalType": "address", "name": "_stakeManager", "type": "address" }, + { "internalType": "address", "name": "_polygonERC20", "type": "address" }, + { "internalType": "address", "name": "_manager", "type": "address" }, + { + "internalType": "address", + "name": "_instantPoolOwner", + "type": "address" + }, + { "internalType": "address", "name": "_treasury", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "instantPoolMatic", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "instantPoolMaticX", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "instantPoolOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fromValidatorId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_toValidatorId", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "migrateDelegation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintMaticXToInstantPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "provideInstantPoolMatic", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "provideInstantPoolMaticX", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "requestWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "role", "type": "bytes32" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint8", "name": "_feePercent", "type": "uint8" } + ], + "name": "setFeePercent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "setFxStateRootTunnel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "setInstantPoolOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "setValidatorRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "_version", "type": "string" } + ], + "name": "setVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setupBotAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_validatorId", "type": "uint256" } + ], + "name": "stakeRewardsAndDistributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "submit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "interfaceId", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "swapMaticForMaticXViaInstantPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "togglePause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawInstantPoolMatic", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawInstantPoolMaticX", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_validatorId", "type": "uint256" } + ], + "name": "withdrawRewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_validatorIds", + "type": "uint256[]" + } + ], + "name": "withdrawValidatorsReward", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stader/index.js b/src/adaptors/stader/index.js new file mode 100644 index 0000000000..f6fcf41f91 --- /dev/null +++ b/src/adaptors/stader/index.js @@ -0,0 +1,124 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abi = require('./abi.js'); +const PermissionlessNodeRegistryAbi = require('./ PermissionlessNodeRegistryAbi.json'); +const abiPolygon = require('./abiPolygon'); + +const token = '0xa35b1b31ce002fbf2058d22f30f95d405200a15b'; +const stakingContract = '0xcf5EA1b38380f6aF39068375516Daf40Ed70D299'; +const nodeOperatorRegistry = '0x4f4bfa0861f62309934a5551e0b2541ee82fdcf1'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + let tvl = (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const nodeOperatorCount = ( + await sdk.api.abi.call({ + abi: PermissionlessNodeRegistryAbi.find( + (m) => m.name === 'totalActiveValidatorCount' + ), + target: nodeOperatorRegistry, + }) + ).output; + + // +4 ETH per node operator + tvl += nodeOperatorCount * 4; + + const now = Math.floor(Date.now() / 1000); + const timestamp7dayAgo = now - 86400 * 7; + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: stakingContract, + abi: abi.find((m) => m.name === 'getExchangeRate'), + chain: 'ethereum', + }), + sdk.api.abi.call({ + target: stakingContract, + abi: abi.find((m) => m.name === 'getExchangeRate'), + chain: 'ethereum', + block: block7dayAgo, + }), + ]); + + const apyBase7d = + ((exchangeRates[0].output - exchangeRates[1].output) / 1e18 / 7) * + 365 * + 100; + + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + // maticx contract on ethereum + const stakeManagerContract = '0xf03A7Eb46d01d9EcAA104558C732Cf82f6B6B645'; + const exchangeRatesPolygon = await Promise.all([ + sdk.api.abi.call({ + target: stakeManagerContract, + chain: 'ethereum', + abi: abiPolygon.find((m) => m.name === 'convertMaticXToMatic'), + params: [1000000000000000000n], + }), + sdk.api.abi.call({ + target: stakeManagerContract, + chain: 'ethereum', + abi: abiPolygon.find((m) => m.name === 'convertMaticXToMatic'), + params: [1000000000000000000n], + block: block7dayAgo, + }), + ]); + + const apyBase7dPolygon = + ((exchangeRatesPolygon[0].output[0] - exchangeRatesPolygon[1].output[0]) / + 1e18 / + 7) * + 365 * + 100; + + const priceKeyPolygon = `ethereum:${stakeManagerContract}`; + const maticxPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeyPolygon}`) + ).data.coins[priceKeyPolygon]?.price; + + const tvlPolygon = + ( + await sdk.api.abi.call({ + target: stakeManagerContract, + abi: 'erc20:totalSupply', + chain: 'ethereum', + }) + ).output / 1e18; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'stader', + symbol: 'ethx', + tvlUsd: tvl * ethPrice, + apyBase: apyBase7d, + apyBase7d, + underlyingTokens: [weth], + }, + { + pool: stakeManagerContract, + chain: 'polygon', + project: 'stader', + symbol: 'maticx', + tvlUsd: tvlPolygon * maticxPrice, + apyBase: apyBase7dPolygon, + apyBase7d: apyBase7dPolygon, + underlyingTokens: ['0x0000000000000000000000000000000000001010'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.staderlabs.com/eth/stake/', +}; diff --git a/src/adaptors/stafi/index.js b/src/adaptors/stafi/index.js new file mode 100644 index 0000000000..e0c3a77d2b --- /dev/null +++ b/src/adaptors/stafi/index.js @@ -0,0 +1,36 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const token = '0x9559aaa82d9649c7a7b220e7c461d2e74c9a3593'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const getApy = async () => { + const tvl = + (await sdk.api.erc20.totalSupply({ target: token })).output / 1e18; + + const apyData = ( + await axios.get('https://drop-api.stafi.io/reth/v1/poolData') + ).data; + const priceKey = `ethereum:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: token, + chain: 'ethereum', + project: 'stafi', + symbol: 'reth', + tvlUsd: tvl * ethPrice, + apyBase: apyData.data.stakeApr, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://bifrost.app/vstaking', +}; diff --git a/src/adaptors/stake-dao/index.js b/src/adaptors/stake-dao/index.js new file mode 100644 index 0000000000..39ea7296bd --- /dev/null +++ b/src/adaptors/stake-dao/index.js @@ -0,0 +1,116 @@ +const utils = require('../utils'); + +const API_ENDPOINT = 'https://api.stakedao.org/api/'; +const SDT_ADDRESS = '0x73968b9a57c6e53d41345fd57a6e6ae27d6cdb2f'; + +const CHAINS = { + 1: 'ethereum', + 42161: 'arbitrum', + 56: 'bsc', + 252: 'fraxtal', + 10: 'optimism', + 8453: 'base', + 146: 'sonic', + 42793: 'etherlink', +}; + +const poolsFunction = async () => { + const resp = await Promise.all([ + // Strategies v1 + utils.getData(`${API_ENDPOINT}strategies/pendle`), + utils.getData(`${API_ENDPOINT}strategies/balancer`), + utils.getData(`${API_ENDPOINT}strategies/yearn`), + // Strategies v2 + utils.getData(`${API_ENDPOINT}strategies/v2/curve`), + // Lockers + utils.getData(`${API_ENDPOINT}lockers`), + ]); + + const pendleStrategies = resp[0].deployed; + const balancerStrategies = resp[1].deployed; + const yearnStrategies = resp[2].deployed; + + const v2CurveStrategies = resp[3]; + + const strats = v2CurveStrategies + .concat(pendleStrategies) + .concat(balancerStrategies) + .concat(yearnStrategies) + .reduce((acc, strat) => { + const rewardTokens = strat?.rewards + ?.filter((t) => { + if (t.token.address === SDT_ADDRESS) { + return parseFloat(strat.sdtApr.sdtFuturMinApr) > 0; + } + + return t.apr > 0; + }) + .map((t) => t.token.address); + + // strategies APR + const apyBase = + strat.tradingApy + + (strat.underlyingReward?.reduce( + (acc, underlyingReward) => acc + underlyingReward.apy, + 0 + ) || 0); + const apyReward = strat.apr.current.total - apyBase; + + let symbol = strat.name?.replace('/', '-') ?? ['placeholder']; + + const underlyingTokens = strat?.coins?.map((t) => + t?.symbol === 'ETH' + ? '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + : t?.address + ); + + return acc.concat([ + { + pool: `sd-${strat.key}-${CHAINS[strat.chainId]}`, + chain: utils.formatChain(CHAINS[strat.chainId]), + project: 'stake-dao', + symbol: symbol ? utils.formatSymbol(symbol) : null, + poolMeta: strat.protocol ? utils.formatChain(strat.protocol) : null, + tvlUsd: strat.tvl, + apyReward, + apyBase, + rewardTokens, + underlyingTokens, + }, + ]); + }, []); + + const lockers = resp[4].parsed + .map((locker) => { + const rewardTokens = locker?.rewards + ?.filter((t) => t.apr > 0) + .map((t) => t.token.address); + + if (!CHAINS[locker.chainId]) return []; + + return { + pool: locker.sdToken.symbol, + chain: utils.formatChain(CHAINS[locker.chainId]), + project: 'stake-dao', + symbol: utils.formatSymbol(locker.sdToken.symbol), + poolMeta: locker.protocol ? utils.formatChain(locker.protocol) : null, + tvlUsd: locker.tvl, + // Select lower bounds of rewards, without veSDT boost + apyReward: locker.streaming ? locker.apr[0] : 0, + apyBase: 0, + rewardTokens, + underlyingTokens: [locker.token.address], + }; + }) + .flat(); + + return utils.removeDuplicates( + strats.concat(lockers).filter((i) => utils.keepFinite(i)) + ); +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://stakedao.org', +}; diff --git a/src/adaptors/stake.link-index/index.js b/src/adaptors/stake.link-index/index.js new file mode 100644 index 0000000000..45600f746e --- /dev/null +++ b/src/adaptors/stake.link-index/index.js @@ -0,0 +1,107 @@ +const utils = require('../utils'); +const superagent = require('superagent'); + +const SUBGRAPH_URL = + 'https://graph-readonly.linkpool.pro/subgraphs/name/stakedotlink-ethereum-production'; +const CHAIN_NAME = 'Ethereum'; + +const getData = async (url, query = null) => { + let res; + if (query !== null) { + res = await superagent + .post(url) + .send(query) + .set('Content-Type', 'application/json'); + } else { + res = await superagent.get(url); + } + return res.body; +}; + +const wsdQuery = ` + { + wsdstakingPools { + id + reward_rate_stpol_9x + reward_rate_stlink_9x + tvl + } + } +`; + +const pools = [ + { + symbol: 'SDL', // Stake.link token + address: '0xa95c5ebb86e0de73b4fb8c47a45b792cfea28c23', // SDL token contract address + priceId: 'stake-link', // CoinGecko ID for SDL token + }, +]; + +const fetchPrice = async (tokenId) => { + const priceKey = `coingecko:${tokenId}`; + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + return data.coins[priceKey].price; +}; + +const fetchPool = async (pool) => { + try { + const { symbol, address, priceId } = pool; + + const price = await fetchPrice(priceId); + + const response = await getData( + SUBGRAPH_URL, + JSON.stringify({ query: wsdQuery }) + ); + + if ( + !response || + !response.data || + !response.data.wsdstakingPools || + !response.data.wsdstakingPools[0] + ) { + throw new Error('Invalid data structure received from subgraph'); + } + + const poolData = response.data.wsdstakingPools[0]; + + // Combine both stPOL and stLINK 9x reward rates + const stpolRewardRate = parseFloat(poolData.reward_rate_stpol_9x); + const stlinkRewardRate = parseFloat(poolData.reward_rate_stlink_9x); + const combinedRewardRate = stpolRewardRate + stlinkRewardRate; + + // Rates are already in percentage form, no need to multiply by 100 + const apy = combinedRewardRate; + + // Use TVL from the subgraph + const tvl = parseFloat(poolData.tvl); + + return { + pool: `${address}-${CHAIN_NAME}`.toLowerCase(), + chain: CHAIN_NAME, + project: 'stake.link-index', + symbol, + tvlUsd: tvl, + apyBase: apy, + }; + } catch (error) { + console.error( + `Error fetching pool data for ${pool.symbol}:`, + error.message + ); + return null; + } +}; + +const fetchPools = async () => { + const poolsData = await Promise.all(pools.map(fetchPool)); + return poolsData.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: fetchPools, + url: 'https://stake.link/sdl', +}; diff --git a/src/adaptors/stake.link-liquid/index.js b/src/adaptors/stake.link-liquid/index.js new file mode 100644 index 0000000000..e3615189e1 --- /dev/null +++ b/src/adaptors/stake.link-liquid/index.js @@ -0,0 +1,159 @@ +const { ethers } = require('ethers'); +const superagent = require('superagent'); + +const getData = async (url, query = null) => { + let res; + if (query !== null) { + res = await superagent + .post(url) + .send(query) + .set('Content-Type', 'application/json'); + } else { + res = await superagent.get(url); + } + return res.body; +}; + +const SUBGRAPH_URL = + 'https://graph-readonly.linkpool.pro/subgraphs/name/stakedotlink-ethereum-production'; + +const linkQuery = ` + { + totalRewardAmounts { + totalRewardSTLINK + __typename + } + totalCounts { + linkStakingDistributionCount + __typename + } + linkStakingDistributions( + first: 1 + skip: 0 + orderBy: ts + orderDirection: desc + ) { + reward_rate + reward_amount + total_staked + fees + fee_percentage + tx_hash + ts + __typename + } + } + `; + +const polQuery = ` + { + totalRewardAmounts { + totalRewardSTPOL + __typename + } + totalCounts { + polStakingDistributionCount + __typename + } + polStakingDistributions( + first: 1 + skip: 0 + orderBy: ts + orderDirection: desc + where: {isUpdatedWithBurnAmount: true} + ) { + reward_rate + reward_amount + total_staked + fees + fee_percentage + tx_hash + ts + __typename + } + } + `; + +const API_URL = 'https://stake.link/v1/metrics/staking'; + +const pools = [ + { + symbol: 'stLINK', + address: '0xb8b295df2cd735b15BE5Eb419517Aa626fc43cD5', + priceId: 'chainlink', + chain: 'Ethereum', + }, + { + symbol: 'stPOL', + address: '0x2ff4390dB61F282Ef4E6D4612c776b809a541753', + priceId: 'polygon-ecosystem-token', + chain: 'Ethereum', + }, +]; + +const fetchPrice = async (tokenId) => { + const priceKey = `coingecko:${tokenId}`; + const data = await getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + return data.coins[priceKey].price; +}; + +const fetchPool = async (pool) => { + try { + const { symbol, address, priceId, chain } = pool; + const price = await fetchPrice(priceId); + + // Use appropriate query and field names based on the token + const query = symbol === 'stPOL' ? polQuery : linkQuery; + const distributionField = + symbol === 'stPOL' + ? 'polStakingDistributions' + : 'linkStakingDistributions'; + + const response = await getData(SUBGRAPH_URL, JSON.stringify({ query })); + + if ( + !response || + !response.data || + !response.data[distributionField] || + !response.data[distributionField][0] + ) { + throw new Error( + `Invalid data structure received from subgraph for ${symbol}` + ); + } + + const distribution = response.data[distributionField][0]; + const apy = parseFloat(distribution.reward_rate); + const totalStakedInWei = distribution.total_staked; + const totalStaked = parseFloat(ethers.utils.formatEther(totalStakedInWei)); + const tvl = totalStaked * price; + + return { + pool: `${address}-${chain}`.toLowerCase(), + chain: chain, + project: 'stake.link-liquid', + symbol, + tvlUsd: tvl, + apyBase: apy, + }; + } catch (error) { + console.error( + `Error fetching pool data for ${pool.symbol}:`, + error.message + ); + return null; + } +}; + +const fetchPools = async () => { + const poolsData = await Promise.all(pools.map(fetchPool)); + return poolsData.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: fetchPools, + url: 'https://stake.link/', +}; diff --git a/src/adaptors/stakehouse/index.js b/src/adaptors/stakehouse/index.js new file mode 100644 index 0000000000..afddf097cc --- /dev/null +++ b/src/adaptors/stakehouse/index.js @@ -0,0 +1,157 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const axios = require('axios'); + +const { ethers } = require('ethers'); +const { request, gql } = require('graphql-request'); + +const getTvlPerLSD = async (response, ticker) => { + let savETHPool = response[ticker][0].savETHPool, + tvl = ethers.BigNumber.from('0'); + + const protectedDeposits = response[`${ticker}_protectedDeposits`]; + const feesAndMevDeposits = response[`${ticker}_feesAndMevDeposits`]; + const nodeRunners = response[`${ticker}_nodeRunners`]; + + if (protectedDeposits.length != 0 || feesAndMevDeposits.length != 0) { + for (let i = 0; i < protectedDeposits.length; ++i) { + tvl = tvl.add(ethers.BigNumber.from(protectedDeposits[i].totalDeposit)); + } + for (let i = 0; i < feesAndMevDeposits.length; ++i) { + tvl = tvl.add(ethers.BigNumber.from(feesAndMevDeposits[i].totalDeposit)); + } + let nodeOperatorDeposit = ethers.BigNumber.from('0'); + for (let i = 0; i < nodeRunners.length; ++i) { + for (let j = 0; j < nodeRunners[i].validators.length; ++j) { + nodeOperatorDeposit = nodeOperatorDeposit.add( + ethers.BigNumber.from('4000000000000000000') + ); + } + } + tvl = tvl.add(nodeOperatorDeposit); + } + + return { savETHPool, tvl }; +}; + +const topLvl = async (chainString, url, underlying) => { + const aprData = (await axios.get(url)).data; + const tickers = Object.keys(aprData).map((index) => aprData[index].Ticker); + + const query = gql` + query getDepositAmounts { + ${tickers + .map( + (ticker) => ` + ${ticker}: liquidStakingNetworks(where: { ticker: "${ticker}" }) { + savETHPool + id + } + ${ticker}_protectedDeposits: protectedDeposits( + where: { + liquidStakingNetwork_: { ticker: "${ticker}" } + validator_: { status_not_in: ["BANNED", "WITHDRAWN"] } + } + ) { + totalDeposit + liquidStakingNetwork { + savETHPool + } + } + ${ticker}_feesAndMevDeposits: feesAndMevDeposits( + where: { + liquidStakingNetwork_: { ticker: "${ticker}" } + validator_: { status_not_in: ["BANNED", "WITHDRAWN"] } + } + ) { + totalDeposit + liquidStakingNetwork { + savETHPool + } + } + ${ticker}_nodeRunners: nodeRunners( + where: { + liquidStakingNetworks_: { ticker: "${ticker}" } + validators_: { status_not_in: ["BANNED", "WITHDRAWN"] } + } + ) { + validators(where: { status_not: "BANNED" }) { + id + } + } + ` + ) + .join('\n')} + } + `; + + const response = await request( + sdk.graph.modifyEndpoint('8hFX42Mcd6JMXLz7gnP5zenpoWkr6bye89n1zCWKBXoz'), + query + ); + + const priceKey = 'ethereum:0x0000000000000000000000000000000000000000'; + const ethUSDPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + let apyList = [], + tvlUsd; + let totalApy = 0, + noOfActiveLSDs = 0; + let totalTvl = 0; + + for (let i = 0; i < tickers.length; ++i) { + const ticker = tickers[i]; + const result = await getTvlPerLSD(response, ticker); + tvlUsd = ethers.utils.formatEther(result.tvl.toString()) * ethUSDPrice; + + if (tvlUsd > 0) { + apyList.push({ + pool: `${result.savETHPool}-${chainString}`.toLowerCase(), + chain: utils.formatChain(chainString), + project: 'stakehouse', + symbol: utils.formatSymbol(Object.values(aprData)[i].Ticker), + tvlUsd: tvlUsd, + apyBase: Number(Object.values(aprData)[i].APR), + underlyingTokens: [underlying], + }); + + totalTvl += tvlUsd; + if (Number(Object.values(aprData)[i].APR) > 0) { + totalApy += Number(Object.values(aprData)[i].APR); + noOfActiveLSDs += 1; + } + } + } + + // The average APY for all LSDs + apyList.push({ + pool: `0x3d1E5Cf16077F349e999d6b21A4f646e83Cd90c5-${chainString}`.toLowerCase(), + chain: utils.formatChain(chainString), + project: 'stakehouse', + symbol: 'dETH', + tvlUsd: totalTvl, + apyBase: totalApy / noOfActiveLSDs, + underlyingTokens: [underlying], + }); + + return apyList; +}; + +const main = async () => { + const data = await topLvl( + 'ethereum', + 'https://etl.joinstakehouse.com/lsdWisePerformance', + '0x0000000000000000000000000000000000000000' + ); + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://joinstakehouse.com/', +}; diff --git a/src/adaptors/stakewise-v2/index.js b/src/adaptors/stakewise-v2/index.js new file mode 100644 index 0000000000..f2b3ca6e9d --- /dev/null +++ b/src/adaptors/stakewise-v2/index.js @@ -0,0 +1,81 @@ +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const BigNumber = require('bignumber.js'); +const axios = require('axios'); +const utils = require('../utils'); + +const secondsInYear = 31536000; +const secondsInWeek = 7 * 60 * 60 * 24; +const maxPercent = 10000; // 100.00 % +const wad = 1e18; + +const osTokenAddress = '0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38'; +const osTokenCtrlAddress = '0x2A261e60FB14586B474C208b1B7AC6D0f5000306'; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const topic = + '0x575b153fd68e97b63239f63ca929196a4e398b8157c14ddb6bfc54dad71071cb'; +const chain = 'ethereum'; +const osTokenCtrlInterface = new ethers.utils.Interface([ + 'event AvgRewardPerSecondUpdated(uint256 avgRewardPerSecond)', +]); + +const getApy = async () => { + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + const timestampWeekAgo = currentBlock.timestamp - secondsInWeek; + const [fromBlock] = await utils.getBlocksByTime([timestampWeekAgo], chain); + + const logs = ( + await sdk.api.util.getLogs({ + target: osTokenCtrlAddress, + topic: '', + toBlock: toBlock, + fromBlock: fromBlock, + keys: [], + topics: [topic], + chain, + }) + ).output; + + // get last 14 events (1-week average) + const lastWeekLogs = logs.slice(-14); + const osEthRewardPerSecondSum = lastWeekLogs + .map((log) => { + const value = osTokenCtrlInterface.parseLog(log); + return new BigNumber(value.args.avgRewardPerSecond._hex); + }) + .reduce((a, b) => a.plus(b), new BigNumber('0')); + + // calculate APY + const apyBN = osEthRewardPerSecondSum + .times(new BigNumber(secondsInYear.toString())) + .times(new BigNumber(maxPercent.toString())) + .dividedBy(new BigNumber(lastWeekLogs.length.toString())) + .dividedBy(new BigNumber(wad.toString())); + const tvl = + (await sdk.api.erc20.totalSupply({ target: osTokenAddress })).output / 1e18; + + // fetch ETH price + const priceKey = `${chain}:${weth}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + return [ + { + pool: osTokenAddress, + chain, + project: 'stakewise-v2', + symbol: 'osETH', + tvlUsd: tvl * ethPrice, + apy: Number(apyBN) / 100, + underlyingTokens: [weth], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.stakewise.io/', +}; diff --git a/src/adaptors/staking-rewards-sreth/index.js b/src/adaptors/staking-rewards-sreth/index.js new file mode 100644 index 0000000000..a3dc9e4e58 --- /dev/null +++ b/src/adaptors/staking-rewards-sreth/index.js @@ -0,0 +1,102 @@ +const { BigNumber, constants, utils } = require('ethers'); +const { request, gql } = require('graphql-request'); +const { api } = require("@defillama/sdk"); + +// endpoints +const subgraphUrl = "https://api.studio.thegraph.com/query/41372/spool-v2_mainnet/version/latest"; + +// queries +const q = gql` + query MyQuery($smartVault: ID) { + smartVaultStrategies(where: {smartVault: $smartVault}) { + strategy { apy } + allocation + } + }` + +// abis +const abi = { + "getSmartVaultAssetBalances": "function getSmartVaultAssetBalances(address, bool) external returns (uint256[] memory)", + "getAmountsOut": "function getAmountsOut(uint256, address[] memory) external view returns (uint256[] memory)", + "rewardConfiguration": "function rewardConfiguration(address, address) public view returns(uint32,uint32,uint192,uint32)", + "assetToUsd": "function assetToUsd(address, uint256) public view returns(uint256)" +} + +// contracts +const dai = "0x6b175474e89094c44da98b954eedeac495271d0f"; +const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const spool = '0x40803cea2b2a32bda1be61d3604af6a814e70976'; +const vault = '0x5d6ac99835b0dd42ed9ffc606170e59f75a88fde'; // srETH vault +const spoolLens = "0x8aa6174333f75421903b2b5c70ddf8da5d84f74f"; +const rewardManager = "0xd8d2c1c3c7982272e3e12dec5af681433fdcf003"; +const uniswapRouterV2 = "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"; +const usdPriceFeedManager = "0x38f1a78ad8956b45b48837657bd0884ba7ab485a"; + +// constants +const SECONDS_PER_YEAR = 31536000; +const url = `https://app.spool.fi/` +const urlVault = `${url}smart-vaults/${vault}/` + +// helpers +const call = async(target, abi, params) => (await api.abi.call({target: target, abi: abi, params: params, chain: "ethereum"})).output; + +// functions +const getTvlUsdRaw = async() => { + const tvlETH = await call(spoolLens, abi["getSmartVaultAssetBalances"], [vault, false]); + const ethPrice = await call(usdPriceFeedManager, abi["assetToUsd"], [weth, constants.WeiPerEther.toString()]); + return BigNumber.from(tvlETH[0]).mul(ethPrice).div(constants.WeiPerEther); +} + +const getApyBase = async() => { + const apyBase = (await request(subgraphUrl, q, { smartVault: vault })) + .smartVaultStrategies + .reduce((a, b) => a + ((b.strategy.apy * b.allocation) / 100), 0); + return apyBase; +} + +const getApyReward = async (tvlUsdRaw) => { + const [rewardsDuration, periodFinish, rewardRate, tokenAdded] = + await call(rewardManager, abi["rewardConfiguration"], [vault, spool]); + + const timestampNow = Math.floor(Date.now() / 1_000); + if(Number(periodFinish) < timestampNow) return 0; + + // get reward token distributed yearly in USD + const spoolPrice = await call(uniswapRouterV2, abi["getAmountsOut"], [constants.WeiPerEther.toString(), [spool, dai]]); + const spoolYearlyDistributionUsdRaw = BigNumber.from(rewardRate).mul(SECONDS_PER_YEAR).mul(spoolPrice[1]); + + let apyReward = Number(utils.formatUnits( + spoolYearlyDistributionUsdRaw.div(tvlUsdRaw.mul(constants.WeiPerEther)) + )) * 100; + + return apyReward; + +} + +const getApy = async () => { + const tvlUsdRaw = await getTvlUsdRaw(); + const tvlUsd = Number(utils.formatUnits(tvlUsdRaw)); + const apyBase = await getApyBase(); + const apyReward = await getApyReward(tvlUsdRaw); + + return [ + { + pool: vault, + chain: 'ethereum', + project: 'staking-rewards-sreth', + symbol: 'srETH', + tvlUsd: tvlUsd, + apyBase: apyBase, + apyReward: apyReward, + rewardTokens: [spool], + underlyingTokens: [weth], + url: urlVault, + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: url, +}; diff --git a/src/adaptors/stargate-v1/abis.json b/src/adaptors/stargate-v1/abis.json new file mode 100644 index 0000000000..65e86784e9 --- /dev/null +++ b/src/adaptors/stargate-v1/abis.json @@ -0,0 +1,146 @@ +{ + "poolLength": { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolInfo": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accStargatePerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAllocPoint": { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "stargatePerBlock": { + "inputs": [], + "name": "stargatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "lpBalances": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "token": { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "eTokenPerSecond": { + "inputs": [], + "name": "eTokenPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/stargate-v1/index.js b/src/adaptors/stargate-v1/index.js new file mode 100644 index 0000000000..81c2b8b478 --- /dev/null +++ b/src/adaptors/stargate-v1/index.js @@ -0,0 +1,335 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const utils = require('../utils'); +const abi = require('./abis.json'); + +//optimism uses (OP) token for rewards and kava uses (WKAVA), all else use (STG) token +const CONFIG = { + ethereum: { + LP_STAKING: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b', + REWARD_TOKEN: '0xaf5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + LLAMA_NAME: 'Ethereum', + }, + bsc: { + LP_STAKING: '0x3052A0F6ab15b4AE1df39962d5DdEFacA86DaB47', + REWARD_TOKEN: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b', + LLAMA_NAME: 'Binance', + }, + avax: { + LP_STAKING: '0x8731d54E9D02c286767d56ac03e8037C07e01e98', + REWARD_TOKEN: '0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590', + LLAMA_NAME: 'Avalanche', + }, + base: { + LP_STAKING: '0x06Eb48763f117c7Be887296CDcdfad2E4092739C', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + REWARD_TOKEN: '0xE3B53AF74a4BF62Ae5511055290838050bf764Df', + LLAMA_NAME: 'Base', + }, + polygon: { + LP_STAKING: '0x8731d54E9D02c286767d56ac03e8037C07e01e98', + REWARD_TOKEN: '0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590', + LLAMA_NAME: 'Polygon', + }, + arbitrum: { + LP_STAKING: '0xeA8DfEE1898a7e0a59f7527F076106d7e44c2176', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + REWARD_TOKEN: '0x6694340fc020c5e6b96567843da2df01b2ce1eb6', + LLAMA_NAME: 'Arbitrum', + }, + optimism: { + LP_STAKING: '0x4DeA9e918c6289a52cd469cAC652727B7b412Cd2', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + REWARD_TOKEN: '0x4200000000000000000000000000000000000042', + LLAMA_NAME: 'Optimism', + }, + fantom: { + LP_STAKING: '0x224D8Fd7aB6AD4c6eb4611Ce56EF35Dec2277F03', + REWARD_TOKEN: '0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590', + LLAMA_NAME: 'Fantom', + }, + kava: { + LP_STAKING: '0x35F78Adf283Fe87732AbC9747d9f6630dF33276C', + REWARD_TOKEN: '0xc86c7c0efbd6a49b35e8714c5f59d99de09a225b', + LLAMA_NAME: 'Kava', + }, + linea: { + LP_STAKING: '0x4a364f8c717cAAD9A442737Eb7b8A55cc6cf18D8', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + REWARD_TOKEN: '0x808d7c71ad2ba3FA531b068a2417C63106BC0949', + LLAMA_NAME: 'Linea', + }, + mantle: { + LP_STAKING: '0x352d8275AAE3e0c2404d9f68f6cEE084B5bEB3DD', + ETHER_TOKEN: '0x0000000000000000000000000000000000000000', + REWARD_TOKEN: '0x8731d54E9D02c286767d56ac03e8037C07e01e98', + LLAMA_NAME: 'Mantle', + }, +}; + +const CHAIN_MAP = { + fantom: 'ftm', + polygon: 'matic', + arbitrum: 'arbitrum', + base: 'base', + optimism: 'optimism', + ethereum: 'eth', + bsc: 'bnb', + avax: 'avax', + kava: 'kava', + linea: 'linea', + mantle: 'mantle', +}; + +const pools = async (poolIndex, chain) => { + // info for tvl / apy calculations + const poolInfo = ( + await sdk.api.abi.call({ + abi: abi.poolInfo, + target: CONFIG[chain].LP_STAKING, + chain: chain, + params: poolIndex, + }) + ).output; + const lpToken = poolInfo.lpToken; + const lpTokenSymbol = ( + await sdk.api.abi.call({ abi: abi.symbol, target: lpToken, chain: chain }) + ).output; + const underlyingLpToken = ( + await sdk.api.abi.call({ abi: abi.token, target: lpToken, chain: chain }) + ).output; + const lpTokenDecimals = ( + await sdk.api.abi.call({ abi: abi.decimals, target: lpToken, chain: chain }) + ).output; + const allocPoint = await poolInfo.allocPoint; + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abi.totalAllocPoint, + target: CONFIG[chain].LP_STAKING, + chain: chain, + }) + ).output; + const reserve = + ( + await sdk.api.abi.call({ + abi: abi.lpBalances, + target: CONFIG[chain].LP_STAKING, + chain: chain, + params: [poolIndex], + }) + ).output / + (1 * 10 ** lpTokenDecimals); + + let rewardPerBlock; + // reward (STG) per block + if (!['optimism', 'base', 'kava', 'linea', 'mantle'].includes(chain)) { + const STGPerBlock = ( + await sdk.api.abi.call({ + abi: abi.stargatePerBlock, + target: CONFIG[chain].LP_STAKING, + chain: chain, + }) + ).output; + rewardPerBlock = STGPerBlock; + } else { + const eTokenPerBlock = ( + await sdk.api.abi.call({ + abi: abi.eTokenPerSecond, + target: CONFIG[chain].LP_STAKING, + chain: chain, + }) + ).output; + rewardPerBlock = eTokenPerBlock; + } + + return { + lpToken, + lpTokenSymbol, + underlyingLpToken, + allocPoint, + totalAllocPoint, + reserve, + rewardPerBlock, + }; +}; + +const getPrices = async (chain, addresses) => { + const uri = `${addresses.map((address) => `${chain}:${address}`)}`; + const prices = ( + await superagent.get('https://coins.llama.fi/prices/current/' + uri) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const tvl = async (chain, symbol, underlyingLpToken, reserve) => { + // total number of coins in pool * coin price + let token = underlyingLpToken; + if (symbol === 'S*SGETH') { + token = CONFIG[chain].ETHER_TOKEN; + } + const price = (await getPrices(chain, [token]))[token.toLowerCase()]; + const reserveUSD = reserve * price; + + return reserveUSD; +}; + +const calcApy = async ( + chain, + allocPoint, + totalAllocPoint, + reward, + rewardPrice, + reserve +) => { + // pool rewards per year in usd + // blocks per year * reward * wieght * price + + // BLOCK_TIME is number of seconds for 1 block to settle + let BLOCK_TIME; + switch (chain) { + // these have dynamic block times, but reward = rewardPerSecond (so can just use BLOCK_TIME =1) + case 'optimism': + case 'base': + case 'kava': + case 'linea': + case 'mantle': + BLOCK_TIME = 1; + break; + // the others have rewardPerBlock + case 'polygon': + BLOCK_TIME = 2.11; + break; + case 'avax': + BLOCK_TIME = 2.03; + break; + case 'bsc': + BLOCK_TIME = 3; + break; + // dynamic blocks for fantom + // we calculate BLOCK_TIME based on nb of blocks in offset period + case 'fantom': + // 1 week + const offset = 7; + const dateNow = Math.floor(Date.now() / 1000); + const date7daysPrior = dateNow - 86400 * offset; + + const blocks = ( + await Promise.all( + [dateNow, date7daysPrior].map((d) => + superagent.get(`https://coins.llama.fi/block/${chain}/${d}`) + ) + ) + ) + .flat() + .map((i) => i.body?.height); + + const nbBlocksInOffset = blocks[0] - blocks[1]; + const secondsPerOffset = 86400 * offset; + BLOCK_TIME = secondsPerOffset / nbBlocksInOffset; + break; + default: + BLOCK_TIME = 12; + break; + } + + const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; + const BLOCKS_PER_YEAR = SECONDS_PER_YEAR / BLOCK_TIME; + + const weight = allocPoint / totalAllocPoint; + const rewardPerBlock = reward * weight; + + const rewardPerYear = (rewardPerBlock / 1e18) * BLOCKS_PER_YEAR; + + const rewardUSD = rewardPerYear * rewardPrice; + const apr = (rewardUSD / reserve) * 100; + + return apr; +}; + +const getApy = async (chain) => { + let poolsApy = []; + + const poolLength = parseInt( + ( + await sdk.api.abi.call({ + abi: abi.poolLength, + target: CONFIG[chain].LP_STAKING, + chain, + }) + ).output + ); + // use ETH pricing for STG since its most liquid, use OPT pricing for OP, and kava price for WKAVA + const rewardPrice = ['optimism', 'kava', 'linea'].includes(chain) + ? (await getPrices(chain, [CONFIG[chain].REWARD_TOKEN]))[ + CONFIG[chain].REWARD_TOKEN.toLowerCase() + ] + : (await getPrices('ethereum', [CONFIG.ethereum.REWARD_TOKEN]))[ + CONFIG.ethereum.REWARD_TOKEN.toLowerCase() + ]; + for (index = 0; index < poolLength; index++) { + const pool = await pools(index, chain); + const reserveUSD = await tvl( + chain, + pool.lpTokenSymbol, + pool.underlyingLpToken, + pool.reserve + ); + const apy = await calcApy( + chain, + pool.allocPoint, + pool.totalAllocPoint, + pool.rewardPerBlock, + rewardPrice, + reserveUSD + ); + + poolsApy.push({ + pool: `${pool.lpToken}-${CONFIG[chain].LLAMA_NAME}`.toLowerCase(), + chain: CONFIG[chain].LLAMA_NAME, + project: 'stargate-v1', + symbol: `${pool.lpTokenSymbol}`, + tvlUsd: reserveUSD, + apyReward: apy, + underlyingTokens: [`${pool.underlyingLpToken}`], + rewardTokens: [`${CONFIG[chain].REWARD_TOKEN}`], + url: `https://stargate.finance/pool/${pool.lpTokenSymbol.replace( + 'S*', + '' + )}-${CHAIN_MAP[chain]}/add`, + }); + } + + return poolsApy; +}; + +const main = async () => { + const pools = []; + for (const chain of Object.keys(CONFIG)) { + console.log(chain); + try { + pools.push(await getApy(chain, CONFIG[chain].LP_STAKING)); + } catch (err) { + console.log(`${chain} failed`); + } + } + + return pools + .flat() + .filter((p) => utils.keepFinite(p)) + .map((p) => ({ ...p, symbol: p.symbol.replace('S*', '') })); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/starlay-finance/abi.json b/src/adaptors/starlay-finance/abi.json new file mode 100644 index 0000000000..fa6b892dd7 --- /dev/null +++ b/src/adaptors/starlay-finance/abi.json @@ -0,0 +1,167 @@ +{ + "Lendingpool.getReservesList": { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "Lendingpool.getReserveData": { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "lTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "id", + "type": "uint8" + } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + "ProtocolProvider.getReserveConfigurationData": { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ltv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactor", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowingEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isFrozen", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/starlay-finance/index.js b/src/adaptors/starlay-finance/index.js new file mode 100644 index 0000000000..b9f86e1369 --- /dev/null +++ b/src/adaptors/starlay-finance/index.js @@ -0,0 +1,118 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const abi = require('./abi.json'); + +const ADDRESSES = { + LendingPool: '0x90384334333f3356eFDD5b20016350843b90f182', + ProtocolDataProvider: '0x5BF9B2644E273D92ff1C31A83476314c95953133', +}; + +const getApy = async () => { + const chain = 'astar'; + + const reservesList = ( + await sdk.api.abi.call({ + target: ADDRESSES.LendingPool, + abi: abi['Lendingpool.getReservesList'], + chain: chain, + }) + ).output; + + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((i) => ({ + target: ADDRESSES.LendingPool, + params: [i], + })), + abi: abi['Lendingpool.getReserveData'], + chain: chain, + }) + ).output.map((o) => o.output); + + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' ? reserveData[i].lTokenAddress : null, + })), + chain: chain, + }) + ) + ); + + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ + target: p.variableDebtTokenAddress, + })), + chain: chain, + }) + ).output.map((o) => o.output); + + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: ADDRESSES.ProtocolDataProvider, + params: t, + })), + chain: chain, + abi: abi['ProtocolProvider.getReserveConfigurationData'], + }) + ).output.map((o) => o.output); + + const pricesArray = reservesList.map((t) => `${chain}:${t}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).data.coins; + + return reservesList + .map((t, i) => { + const config = reserveConfigurationData[i]; + if (!config.isActive) return null; + + const price = prices[`${chain}:${t}`]?.price; + + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + const apyBase = Number(reserveData[i].currentLiquidityRate) / 1e25; + const apyBaseBorrow = + Number(reserveData[i].currentVariableBorrowRate) / 1e25; + + const ltv = Number(config.ltv) / 1e4; + const borrowable = config.borrowingEnabled; + const frozen = config.isFrozen; + + return { + pool: `${reserveData[i].lTokenAddress}-${chain}`.toLowerCase(), + symbol: symbols[i], + project: 'starlay-finance', + chain, + tvlUsd, + apyBase, + underlyingTokens: [t], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + ltv, + borrowable, + poolMeta: frozen ? 'frozen' : null, + }; + }) + .filter((p) => p && utils.keepFinite(p)); +}; + +module.exports = { + apy: getApy, + url: 'https://starlay.finance/app/markets', +}; diff --git a/src/adaptors/steadefi/abi.json b/src/adaptors/steadefi/abi.json new file mode 100644 index 0000000000..170dc868e1 --- /dev/null +++ b/src/adaptors/steadefi/abi.json @@ -0,0 +1,60 @@ +{ + "LENDING_POOL": [ + { + "inputs": [], + "name": "totalValue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lendingAPR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "assetDecimals", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } + ], + "VAULT": [ + { + "inputs": [], + "name": "reader", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "VAULT_READER": [ + { + "inputs": [], + "name": "equityValue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } + ], + "CHAINLINK_ORACLE": [ + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "consultIn18Decimals", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/src/adaptors/steadefi/index.js b/src/adaptors/steadefi/index.js new file mode 100644 index 0000000000..906d40ecaa --- /dev/null +++ b/src/adaptors/steadefi/index.js @@ -0,0 +1,154 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const ethers = require('ethers'); +const abi = require('./abi.json'); +const utils = require('../utils'); + +const project = 'steadefi'; + +const CONSTANT = { + 43114: { + name: 'avax', + chainLinkOracle: '0xd8D520903DF0cAfEe9b989922173D636290572c2', + }, + 42161: { + name: 'arbitrum', + chainLinkOracle: '0x43697612E11e5C53F1DE1c0AeddCEEC0a0Bff9b6', + }, +}; + +async function apy() { + const vaultResponse = ( + await axios.get(`https://api.steadefi.com/vaults`) + ).data.filter((v) => v.status !== 'Hidden'); + + const lendingPoolResponse = ( + await axios.get(`https://api.steadefi.com/lending-pools`) + ).data.filter((v) => v.status !== 'Hidden'); + + const vaults = await Promise.all( + vaultResponse.map(async (p) => { + const chain = CONSTANT[p.chainId].name; + const chainString = utils.formatChain(chain); + + let equityValue; + try { + const readerAddress = ( + await sdk.api.abi.call({ + target: p.address, + abi: abi.VAULT.find(({ name }) => name === 'reader'), + chain, + }) + ).output; + + equityValue = ( + await sdk.api.abi.call({ + target: readerAddress, + abi: abi.VAULT_READER.find(({ name }) => name === 'equityValue'), + chain, + }) + ).output; + } catch (err) { + console.log(p.address, chain); + return {}; + } + + const lp = `${p.tokens.map((t) => t.symbol).join('')}`; + const strategy = `${p.strategy[0]}`; + const symbol = `${p.leverage}${strategy}-${lp}`; + + return { + pool: `${p.address}-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol, + poolMeta: p.protocol, + tvlUsd: Number(ethers.utils.formatUnits(equityValue)), + apy: utils.aprToApy(Number(p.data.apr.totalApr * 100)), + }; + }) + ); + + const lendingPools = await Promise.all( + lendingPoolResponse.map(async (p) => { + const chain = CONSTANT[p.chainId].name; + const chainString = utils.formatChain(chain); + + let lendingAPR, totalValue, assetDecimals, assetPrice; + try { + lendingAPR = ( + await sdk.api.abi.call({ + target: p.address, + abi: abi.LENDING_POOL.find(({ name }) => name === 'lendingAPR'), + chain, + }) + ).output; + + totalValue = ( + await sdk.api.abi.call({ + target: p.address, + abi: abi.LENDING_POOL.find(({ name }) => name === 'totalValue'), + chain, + }) + ).output; + + assetDecimals = ( + await sdk.api.abi.call({ + target: p.address, + abi: abi.LENDING_POOL.find(({ name }) => name === 'assetDecimals'), + chain, + }) + ).output; + + assetPrice = ( + await sdk.api.abi.call({ + target: CONSTANT[p.chainId].chainLinkOracle, + abi: abi.CHAINLINK_ORACLE.find( + ({ name }) => name === 'consultIn18Decimals' + ), + params: p.baseToken.address, + chain, + }) + ).output; + } catch (err) { + console.log(p.address, chain); + return {}; + } + + const lendingTo = p.name.split(' ')[2]; + + const symbol = p.baseToken.symbol; + + const poolMeta = + p.lendingTo === 'Perpetual DEX' + ? p.protocol + : `${p.protocol} - ${lendingTo}`; + + return { + pool: `${p.address}-${chainString}`.toLowerCase(), + chain: chainString, + project, + symbol, + poolMeta, + tvlUsd: + Number(ethers.utils.formatUnits(totalValue, Number(assetDecimals))) * + Number(ethers.utils.formatUnits(assetPrice)), + apy: utils.aprToApy(Number(ethers.utils.formatUnits(lendingAPR)) * 100), + }; + }) + ); + + return [...vaults, ...lendingPools].filter((p) => p.pool); +} + +const main = async () => { + const data = await apy(); + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://steadefi.com/vaults', +}; diff --git a/src/adaptors/steer-protocol/index.js b/src/adaptors/steer-protocol/index.js new file mode 100644 index 0000000000..d0e657d4a5 --- /dev/null +++ b/src/adaptors/steer-protocol/index.js @@ -0,0 +1,111 @@ +const { request } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); + +// add chain deployments and subgraph endpoints here +const supportedChains = [ + { + name: 'Polygon', + subgraphEndpoint: sdk.graph.modifyEndpoint( + 'uQxLz6EarmJcr2ymRRmTnrRPi8cCqas4XcPQb71HBvw' + ), + }, + { + name: 'Arbitrum', + subgraphEndpoint: sdk.graph.modifyEndpoint( + 'HVC4Br5yprs3iK6wF8YVJXy4QZWBNXTCFp8LPe3UpcD4' + ), + }, + { + name: 'Optimism', + subgraphEndpoint: sdk.graph.modifyEndpoint( + 'GgW1EwNARL3dyo3acQ3VhraQQ66MHT7QnYuGcQc5geDG' + ), + }, +]; + +// Fetch active vaults and associated data @todo limited to 1000 per chain +const query = ` +{ + vaults(first: 1000, where: {totalLPTokensIssued_not: "0"}) { + weeklyFeeAPR + beaconName + feeTier + id + pool + token0 + token0Symbol + token0Decimals + token1 + token1Symbol + token1Decimals + totalLPTokensIssued + totalAmount1 + totalAmount0 + strategyToken { + id + } + } + }`; + +const getPools = async () => { + const pools = []; + for (const chainInfo of supportedChains) { + try { + const data = await request(chainInfo.subgraphEndpoint, query); + // get tokens + const tokenList = new Set(); + data.vaults.forEach((vaultInfo) => { + tokenList.add((chainInfo.name + ':' + vaultInfo.token0).toLowerCase()); + tokenList.add((chainInfo.name + ':' + vaultInfo.token1).toLowerCase()); + }); + + // get prices + const tokenPrices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${[...tokenList]}` + ) + ).data.coins; + + const chainPools = data.vaults.map((vault) => { + // calculate tvl + const totalUSD0 = + (Number(vault.totalAmount0) * + tokenPrices[`${chainInfo.name.toLowerCase()}:${vault.token0}`] + ?.price) / + 10 ** Number(vault.token0Decimals); + const totalUSD1 = + (Number(vault.totalAmount1) * + tokenPrices[`${chainInfo.name.toLowerCase()}:${vault.token1}`] + ?.price) / + 10 ** Number(vault.token1Decimals); + const poolTvl = totalUSD0 + totalUSD1; + return { + pool: (vault.id + '-' + chainInfo.name).toLowerCase(), + chain: chainInfo.name, // chain where the pool is (needs to match the `name` field in here https://api.llama.fi/chains) + project: 'steer-protocol', // protocol (using the slug again) + symbol: vault.token0Symbol + '-' + vault.token1Symbol, // symbol of the tokens in pool, can be a single symbol if pool is single-sided or multiple symbols (eg: USDT-ETH) if it's an LP + tvlUsd: poolTvl, // number representing current USD TVL in pool + apyBase: parseFloat(vault.weeklyFeeAPR), // APY from pool fees/supplying in % + underlyingTokens: [vault.token0, vault.token1], // Array of underlying token addresses from a pool, eg here USDT address on ethereum + poolMeta: vault.beaconName.replace('MultiPosition', ''), + url: + 'https://app.steer.finance/app/' + + vault.strategyToken.id + + '/vault/' + + vault.id, + }; + }); + pools.push(...chainPools); + } catch (err) { + console.log(err.message); + } + } + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: getPools, +}; diff --git a/src/adaptors/stella/abi/IBaseLendingPool.json b/src/adaptors/stella/abi/IBaseLendingPool.json new file mode 100644 index 0000000000..e06423fde3 --- /dev/null +++ b/src/adaptors/stella/abi/IBaseLendingPool.json @@ -0,0 +1,28 @@ +[ + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDebts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/stella/abi/IRewardVault.json b/src/adaptors/stella/abi/IRewardVault.json new file mode 100644 index 0000000000..118243806b --- /dev/null +++ b/src/adaptors/stella/abi/IRewardVault.json @@ -0,0 +1,20 @@ +[ + { + "inputs": [], + "name": "rewardDistribution", + "outputs": [ + { + "internalType": "uint128", + "name": "dailyRewardDistributionRateE18", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxRewardDistributionFactorE18", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/stella/index.js b/src/adaptors/stella/index.js new file mode 100644 index 0000000000..b10761a7c3 --- /dev/null +++ b/src/adaptors/stella/index.js @@ -0,0 +1,15 @@ +const getLendApy = require('./lend'); +const getStrategyApy = require('./strategy'); + +const apy = async () => { + const lendApyRes = await getLendApy(); + const strategyApyRes = await getStrategyApy(); + + return [...lendApyRes, ...strategyApyRes]; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.stellaxyz.io', +}; diff --git a/src/adaptors/stella/lend.js b/src/adaptors/stella/lend.js new file mode 100644 index 0000000000..2c7572b500 --- /dev/null +++ b/src/adaptors/stella/lend.js @@ -0,0 +1,135 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); + +const IRewardVaultABI = require('./abi/IRewardVault.json'); +const IBaseLendingPoolABI = require('./abi/IBaseLendingPool.json'); + +const poolListEndpoint = 'https://graph.stellaxyz.io/api/rest/lending-pools'; +const rewardRateEndpoint = + 'https://blocks.alphainnovationslab.io/lm-lender/reward_rates'; +const priceEndpoint = 'https://coins.llama.fi/prices/current/'; + +const rewardVaultAddress = '0xa67CF61b0b9BC39c6df04095A118e53BFb9303c7'; +const alphaTokenAddressARB = '0xc9cbf102c73fb77ec14f8b4c8bd88e050a6b2646'; +const alphaTokenAddressETH = '0xa1faa113cbe53436df28ff0aee54275c13b40975'; +const alphaTokenPriceKey = `ethereum:${alphaTokenAddressETH}`; + +const SEC_IN_YEAR = 365 * 24 * 60 * 60; + +const apy = async () => { + const result = []; + + const { pools } = await utils.getData(poolListEndpoint); + const { data: rewardRate } = await utils.getData(rewardRateEndpoint); + const priceData = await utils.getData( + priceEndpoint + + pools + .map((p) => `arbitrum:${p.underlyingToken}`) + .concat(alphaTokenPriceKey) + .join(',') + + '?searchWidth=4h' + ); + + const { output: rewardDistribution } = await sdk.api.abi.call({ + target: rewardVaultAddress, + abi: IRewardVaultABI.find((m) => m.name === 'rewardDistribution'), + chain: 'arbitrum', + }); + + const dailyRewardVaultRate = new BigNumber( + rewardDistribution.dailyRewardDistributionRateE18 + ); + + for (const pool of pools) { + const { output: rewardVaultBalance } = await sdk.api.erc20.balanceOf({ + target: pool.underlyingToken, + owner: rewardVaultAddress, + chain: 'arbitrum', + }); + + const { output: totalAssets } = await sdk.api.abi.call({ + target: pool.poolAddress, + abi: IBaseLendingPoolABI.find((m) => m.name === 'totalAssets'), + chain: 'arbitrum', + }); + + const { output: totalDebts } = await sdk.api.abi.call({ + target: pool.poolAddress, + abi: IBaseLendingPoolABI.find((m) => m.name === 'totalDebts'), + chain: 'arbitrum', + }); + + const { output: decimals } = await sdk.api.erc20.decimals( + pool.underlyingToken, + 'arbitrum' + ); + + const baseApy = dailyRewardVaultRate + .div('1e18') + .times(rewardVaultBalance) + .div(totalAssets) + .plus(1) + .pow(365) + .minus(1); + + const underlyingTokenPrice = + priceData?.coins[`arbitrum:${pool.underlyingToken.toLowerCase()}`].price; + + const tvlUsd = new BigNumber(totalAssets) + .minus(totalDebts) + .times(underlyingTokenPrice) + .div(`1e${decimals}`); + + const rewardRatePerSecE18 = + rewardRate.reward_rate_per_sec_e18[pool.poolAddress.toLowerCase()]; + const alphaPrice = + priceData?.coins['ethereum:0xa1faa113cbe53436df28ff0aee54275c13b40975'] + .price; + + let res = { + pool: `${pool.poolAddress}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'stella', + symbol: pool.poolName, + tvlUsd: tvlUsd.toNumber(), + totalSupplyUsd: new BigNumber(totalAssets) + .times(underlyingTokenPrice) + .div(`1e${decimals}`) + .toNumber(), + totalBorrowUsd: new BigNumber(totalDebts) + .times(underlyingTokenPrice) + .div(`1e${decimals}`) + .toNumber(), + apyBase: baseApy.times(100).toNumber(), + underlyingTokens: [pool.underlyingToken], + url: `https://app.stellaxyz.io/lending/${pool.poolAddress}?action=deposit`, + }; + + if (rewardRatePerSecE18 && alphaPrice && underlyingTokenPrice) { + const totalRewardValue = new BigNumber(rewardRatePerSecE18) + .times(alphaPrice) + .times(SEC_IN_YEAR); + + const rewardApy = totalRewardValue + .div(totalAssets) + .times(`1e${decimals}`) + .div('1e18') + .div(underlyingTokenPrice); + + const rewardTokens = [alphaTokenAddressARB]; + + res = { + ...res, + apyReward: rewardApy.times(100).toNumber(), + rewardTokens, + }; + } + + result.push(res); + } + + return result; +}; + +module.exports = apy; diff --git a/src/adaptors/stella/strategy.js b/src/adaptors/stella/strategy.js new file mode 100644 index 0000000000..3e65397a02 --- /dev/null +++ b/src/adaptors/stella/strategy.js @@ -0,0 +1,70 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); + +const strategyInfoEndpoint = + 'https://graph.stellaxyz.io/api/rest/defillama/strategy_info'; + +const apy = async () => { + const result = []; + + const { strategy: strategies } = await utils.getData(strategyInfoEndpoint); + + for (const strategy of strategies) { + const maxLeverage = + strategy.strategy_info.yield_info['Default'].maxLeverage; + + let baseApy = 0; + + if (strategy.exchange.name === 'Trader Joe V2') { + try { + baseApy = + strategy?.strategy_info?.additional_data?.priceRangeInfos['Uniform'][ + 'Wide' + ]?.apr ?? 0; + } catch (err) { + console.log(err); + } + } else { + try { + baseApy = + strategy?.strategy_info?.additional_data?.priceRangeInfos?.find( + (x) => x.priceRangeType === 'Wide' + )?.apr ?? 0; + } catch (err) { + console.log(err); + } + } + + const feeBps = strategy?.additional_info.feeBps; + let poolMeta; + if (feeBps) { + poolMeta = `${( + (strategy?.additional_info.feeBps / 10000) * + 100 + ).toLocaleString()}% (${ + strategy.exchange.name + }) Lev Up to ${maxLeverage.toFixed(0)}x`; + } else { + poolMeta = `(${strategy.exchange.name}) Lev Up to ${maxLeverage.toFixed( + 0 + )}x`; + } + + result.push({ + pool: `${strategy.strategy_address}-arbitrum`, + chain: utils.formatChain('arbitrum'), + project: 'stella', + symbol: strategy.name.split('/').join('-'), + poolMeta: poolMeta, + tvlUsd: strategy.strategy_info.strategy_tvl, + apyBase: baseApy * 100, + underlyingTokens: strategy.underlying_tokens, + url: `https://app.stellaxyz.io/strategies/${strategy.strategy_address}`, + }); + } + + return result; +}; + +module.exports = apy; diff --git a/src/adaptors/stellaswap-v2/abiLpToken.js b/src/adaptors/stellaswap-v2/abiLpToken.js new file mode 100644 index 0000000000..3b5d453bdc --- /dev/null +++ b/src/adaptors/stellaswap-v2/abiLpToken.js @@ -0,0 +1,404 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'devFee', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint32', name: '_devFee', type: 'uint32' }], + name: 'setDevFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint32', name: '_swapFee', type: 'uint32' }], + name: 'setSwapFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'swapFee', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/stellaswap-v2/abiMasterchef.js b/src/adaptors/stellaswap-v2/abiMasterchef.js new file mode 100644 index 0000000000..c9e27a94ab --- /dev/null +++ b/src/adaptors/stellaswap-v2/abiMasterchef.js @@ -0,0 +1,754 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IBoringERC20', + name: '_stella', + type: 'address', + }, + { internalType: 'uint256', name: '_stellaPerSec', type: 'uint256' }, + { internalType: 'address', name: '_teamAddress', type: 'address' }, + { internalType: 'address', name: '_treasuryAddress', type: 'address' }, + { internalType: 'address', name: '_investorAddress', type: 'address' }, + { internalType: 'uint256', name: '_teamPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_treasuryPercent', type: 'uint256' }, + { internalType: 'uint256', name: '_investorPercent', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IComplexRewarder[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Add', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newAmount', + type: 'uint256', + }, + ], + name: 'AllocPointsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newValue', + type: 'uint256', + }, + ], + name: 'EmissionRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amountLockedUp', + type: 'uint256', + }, + ], + name: 'RewardLockedUp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IComplexRewarder[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Set', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetInvestorAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetInvestorPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetTeamAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetTeamPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetTreasuryAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetTreasuryPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accStellaPerShare', + type: 'uint256', + }, + ], + name: 'UpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'MAXIMUM_DEPOSIT_FEE_RATE', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAXIMUM_HARVEST_INTERVAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IBoringERC20', + name: '_lpToken', + type: 'address', + }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IComplexRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'canHarvest', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: '_pids', type: 'uint256[]' }], + name: 'harvestMany', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'investorAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'investorPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTimestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'accStellaPerShare', type: 'uint256' }, + { internalType: 'uint16', name: 'depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: 'harvestInterval', type: 'uint256' }, + { internalType: 'uint256', name: 'totalLp', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewarders', + outputs: [ + { internalType: 'address[]', name: 'rewarders', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewardsPerSec', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'rewardsPerSec', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'poolTotalLp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IComplexRewarder[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_investorAddress', type: 'address' }, + ], + name: 'setInvestorAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newInvestorPercent', type: 'uint256' }, + ], + name: 'setInvestorPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_teamAddress', type: 'address' }, + ], + name: 'setTeamAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newTeamPercent', type: 'uint256' }, + ], + name: 'setTeamPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_treasuryAddress', type: 'address' }, + ], + name: 'setTreasuryAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newTreasuryPercent', type: 'uint256' }, + ], + name: 'setTreasuryPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stella', + outputs: [ + { internalType: 'contract IBoringERC20', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stellaPerSec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLockedUpRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalStellaInPools', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'treasuryAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'treasuryPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'updateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_stellaPerSec', type: 'uint256' }, + ], + name: 'updateEmissionRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardLockedUp', type: 'uint256' }, + { internalType: 'uint256', name: 'nextHarvestUntil', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/stellaswap-v2/abiStableSwap.js b/src/adaptors/stellaswap-v2/abiStableSwap.js new file mode 100644 index 0000000000..3400e85c41 --- /dev/null +++ b/src/adaptors/stellaswap-v2/abiStableSwap.js @@ -0,0 +1,712 @@ +module.exports = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'fees', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'invariant', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'AddLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: false, + internalType: 'uint8', + name: 'tokenIndex', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountFee', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'protocolFee', + type: 'uint256', + }, + ], + name: 'FlashLoan', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newAdminFee', + type: 'uint256', + }, + ], + name: 'NewAdminFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newSwapFee', + type: 'uint256', + }, + ], + name: 'NewSwapFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'initialTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'futureTime', + type: 'uint256', + }, + ], + name: 'RampA', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'RemoveLiquidity', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'tokenAmounts', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256[]', + name: 'fees', + type: 'uint256[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'invariant', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + ], + name: 'RemoveLiquidityImbalance', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpTokenSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'boughtId', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensBought', + type: 'uint256', + }, + ], + name: 'RemoveLiquidityOne', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'currentA', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'time', + type: 'uint256', + }, + ], + name: 'StopRampA', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'buyer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensSold', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokensBought', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint128', + name: 'soldId', + type: 'uint128', + }, + { + indexed: false, + internalType: 'uint128', + name: 'boughtId', + type: 'uint128', + }, + ], + name: 'TokenSwap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + inputs: [], + name: 'MAX_BPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'minToMint', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'addLiquidity', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'calculateRemoveLiquidity', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + { internalType: 'uint8', name: 'tokenIndex', type: 'uint8' }, + ], + name: 'calculateRemoveLiquidityOneToken', + outputs: [ + { + internalType: 'uint256', + name: 'availableTokenAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'tokenIndexFrom', type: 'uint8' }, + { internalType: 'uint8', name: 'tokenIndexTo', type: 'uint8' }, + { internalType: 'uint256', name: 'dx', type: 'uint256' }, + ], + name: 'calculateSwap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'bool', name: 'deposit', type: 'bool' }, + ], + name: 'calculateTokenAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'contract IERC20', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'bytes', name: 'params', type: 'bytes' }, + ], + name: 'flashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'flashLoanFeeBPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getA', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAPrecise', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'getAdminBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAdminBalances', + outputs: [ + { internalType: 'uint256[]', name: 'adminBalances', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getLpToken', + outputs: [{ internalType: 'contract LPToken', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getNumberOfTokens', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: 'index', type: 'uint8' }], + name: 'getToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint8', name: 'index', type: 'uint8' }], + name: 'getTokenBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTokenBalances', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + name: 'getTokenIndex', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTokenPrecisionMultipliers', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getTokens', + outputs: [ + { internalType: 'contract IERC20[]', name: '', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVirtualPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: '_pooledTokens', + type: 'address[]', + }, + { internalType: 'uint8[]', name: 'decimals', type: 'uint8[]' }, + { internalType: 'string', name: 'lpTokenName', type: 'string' }, + { internalType: 'string', name: 'lpTokenSymbol', type: 'string' }, + { internalType: 'uint256', name: '_a', type: 'uint256' }, + { internalType: 'uint256', name: '_fee', type: 'uint256' }, + { internalType: 'uint256', name: '_adminFee', type: 'uint256' }, + { + internalType: 'address', + name: 'lpTokenTargetAddress', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'isFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolFeeShareBPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'futureA', type: 'uint256' }, + { internalType: 'uint256', name: 'futureTime', type: 'uint256' }, + ], + name: 'rampA', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256[]', name: 'minAmounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidity', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + { internalType: 'uint256', name: 'maxBurnAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidityImbalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + { internalType: 'uint8', name: 'tokenIndex', type: 'uint8' }, + { internalType: 'uint256', name: 'minAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'removeLiquidityOneToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newAdminFee', type: 'uint256' }], + name: 'setAdminFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newFlashLoanFeeBPS', type: 'uint256' }, + { + internalType: 'uint256', + name: 'newProtocolFeeShareBPS', + type: 'uint256', + }, + ], + name: 'setFlashLoanFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'newSwapFee', type: 'uint256' }], + name: 'setSwapFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stopRampA', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: 'tokenIndexFrom', type: 'uint8' }, + { internalType: 'uint8', name: 'tokenIndexTo', type: 'uint8' }, + { internalType: 'uint256', name: 'dx', type: 'uint256' }, + { internalType: 'uint256', name: 'minDy', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + name: 'swap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'swapStorage', + outputs: [ + { internalType: 'uint256', name: 'initialA', type: 'uint256' }, + { internalType: 'uint256', name: 'futureA', type: 'uint256' }, + { internalType: 'uint256', name: 'initialATime', type: 'uint256' }, + { internalType: 'uint256', name: 'futureATime', type: 'uint256' }, + { internalType: 'uint256', name: 'swapFee', type: 'uint256' }, + { internalType: 'uint256', name: 'adminFee', type: 'uint256' }, + { internalType: 'contract LPToken', name: 'lpToken', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: 'enableFlashLoan', type: 'bool' }], + name: 'toggleFlashLoan', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawAdminFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/stellaswap-v2/index.js b/src/adaptors/stellaswap-v2/index.js new file mode 100644 index 0000000000..9816836d4b --- /dev/null +++ b/src/adaptors/stellaswap-v2/index.js @@ -0,0 +1,360 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiMasterchef = require('./abiMasterchef.js'); +const abiLpToken = require('./abiLpToken.js'); +const abiStableSwap = require('./abiStableSwap.js'); +const pools = require('../concentrator/pools'); + +const project = 'stellaswap-v2'; + +const url = sdk.graph.modifyEndpoint('HgSAfZvHEDbAVuZciPUYEqFzhAUnjJWmyix5C1R2tmTp'); +const urlStable = sdk.graph.modifyEndpoint('bqFx2yiB2VBH8LAJMGZ37Zj3NtBrY7gArFFciLaA3nE'); +const masterchef = '0xF3a5454496E26ac57da879bf3285Fa85DEBF0388'; +const STELLA = '0x0e358838ce72d5e61e0018a2ffac4bec5f4c88d2'; +const STELLA_DEC = 18; + +// most tokens aren't available on our price api +const rewardTokenMapping = { + '0xAcc15dC74880C9944775448304B263D191c6077F': 'moonbeam', + '0x511aB53F793683763E5a8829738301368a2411E3': 'moonwell-artemis', + '0xCBABEe0658725b5B21e1512244734A5D5C6B51D6': 'athos-finance', + '0x9Fda7cEeC4c18008096C2fE2B85F05dc300F94d0': 'lido-dao', +}; + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const queryStablePools = gql` + query swapData($id: String!) { + swap(id: $id) { + id + lpToken + tokens { + decimals + symbol + address + } + weeklyVolumes(first: 1) { + volume + } + dailyVolumes(first: 1) { + volume + } + swapFee + } + } +`; + +const stablePools = [ + '0xb1bc9f56103175193519ae1540a0a4572b1566f6', + '0xa1ffdc79f998e7fa91ba3a6f098b84c9275b0483', + '0xf0a2ae65342f143fc09c83e5f19b706abb37414d', +]; + +const apyBase = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let dataNow = (await request(url, query.replace('', block))) + .pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((p) => utils.apy(p, dataPrior, dataPrior7d, version)); + + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = 'moonbeam'; + + return { + pool: p.id.toLowerCase(), + chain: utils.formatChain(chainString), + project, + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + // stable pools + const stablePoolUnderlyingTokens = ( + await sdk.api.abi.multiCall({ + calls: stablePools.map((p) => ({ target: p })), + chain: 'moonbeam', + abi: abiStableSwap.find((m) => m.name === 'getTokens'), + }) + ).output.map((o) => o.output); + + const stablePoolBalances = ( + await sdk.api.abi.multiCall({ + calls: stablePools.map((p) => ({ target: p })), + chain: 'moonbeam', + abi: abiStableSwap.find((m) => m.name === 'getTokenBalances'), + }) + ).output.map((o) => o.output); + + let dataStables = await Promise.all( + stablePools.map((p) => { + return request(urlStable, queryStablePools, { + id: p.toLowerCase(), + }); + }) + ); + + dataStables = dataStables.map((p, i) => { + const pool = p.swap; + if (pool === null) return null; + + const tvlUsd = stablePoolBalances[i] + .map((balance, j) => { + const decimal = pool.tokens.find( + (x) => + x.address.toLowerCase() === + stablePoolUnderlyingTokens[i][j].toLowerCase() + ).decimals; + + return balance / 10 ** decimal; + }) + .reduce((a, b) => a + b); + + const apyBase = + ((pool.dailyVolumes[0].volume * pool.swapFee) / 1e8 / tvlUsd) * 100; + const apyBase7d = + ((pool.weeklyVolumes[0].volume * pool.swapFee) / 1e8 / tvlUsd) * 100; + const symbol = utils.formatSymbol( + pool.tokens.map((t) => t.symbol).join('-') + ); + const underlyingTokens = pool.tokens.map((t) => t.address); + + return { + pool: pool.lpToken.toLowerCase(), + chain: utils.formatChain(chainString), + project, + symbol, + tvlUsd, + apyBase, + apyBase7d, + underlyingTokens, + }; + }); + + return [...dataNow, ...dataStables].filter((p) => p !== null); +}; + +const getApy = async (timestamp = null) => { + // ------------ fee apr for all pools + const dataFee = ( + await apyBase('moonbeam', url, query, queryPrior, 'stellaswap', timestamp) + ).filter((p) => utils.keepFinite(p)); + + // ------------ add reward apr only for pools in farms + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: abiMasterchef.find((m) => m.name === 'poolLength'), + chain: 'moonbeam', + }) + ).output; + + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + chain: 'moonbeam', + abi: abiMasterchef.find((m) => m.name === 'poolInfo'), + }) + ).output.map((o) => o.output); + + // contains all rewards (including stella though those seem off; going to use this only for + // other rewards aka extraRewards + const poolRewardsPerSec = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + chain: 'moonbeam', + abi: abiMasterchef.find((m) => m.name === 'poolRewardsPerSec'), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const stellaPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: abiMasterchef.find((m) => m.name === 'stellaPerSec'), + chain: 'moonbeam', + }) + ).output / + 10 ** STELLA_DEC; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: abiMasterchef.find((m) => m.name === 'totalAllocPoint'), + chain: 'moonbeam', + }) + ).output; + + const stellaPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/moonbeam:${STELLA}`) + ).data.coins[`moonbeam:${STELLA}`].price; + + const [supplyRes, masterChefBalancesRes] = await Promise.all( + ['totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: abiLpToken.filter(({ name }) => name === method)[0], + calls: poolInfo.map((p) => ({ + target: p.lpToken, + params: method === 'balanceOf' ? [masterchef] : null, + })), + chain: 'moonbeam', + permitFailure: true, + }) + ) + ); + const totalSupply = supplyRes.output.map((o) => o.output); + const masterChefBalances = masterChefBalancesRes.output.map((o) => o.output); + + const tokenKeys = Object.values(rewardTokenMapping) + .map((t) => `coingecko:${t}`) + .join(','); + const extrRewardTokenPrices = ( + await axios.get(`https://coins.llama.fi/prices/current/${tokenKeys}`) + ).data.coins; + + const dataRewards = poolInfo.map((p, i) => { + const pool = dataFee.find((d) => d.pool === p.lpToken.toLowerCase()); + if (pool === undefined) return { ...p }; + + const poolShare = Number(p.allocPoint) / Number(totalAllocPoint); + const stellaPerDay = stellaPerSec * poolShare * 86400; + + const reserveRatio = masterChefBalances[i] / totalSupply[i]; + const farmTvlUsd = reserveRatio * pool.tvlUsd; + const stellaAPR = ((stellaPrice * stellaPerDay * 365) / farmTvlUsd) * 100; + + const extraRewardAddresses = poolRewardsPerSec[i]?.addresses; + if (!extraRewardAddresses) + return { + ...p, + stellaAPR, + extraAPR: 0, + rewardTokens: stellaAPR > 0 ? [STELLA] : [], + farmTvlUsd, + }; + + const extraRewardDecimals = poolRewardsPerSec[i].decimals; + const rewardsPerSec = poolRewardsPerSec[i].rewardsPerSec; + + const rewardTokens = new Set(); + let extraAPR = 0; + for (const [j, a] of extraRewardAddresses.entries()) { + if (a === STELLA) continue; + const rewardsPerDay = + (rewardsPerSec[j] / 10 ** extraRewardDecimals[j]) * 86400; + + const price = + extrRewardTokenPrices[`coingecko:${rewardTokenMapping[a]}`]?.price ?? 0; + extraAPR += ((price * rewardsPerDay * 365) / farmTvlUsd) * 100; + rewardTokens.add(a); + } + + return { + ...p, + stellaAPR, + extraAPR, + rewardTokens: + stellaAPR > 0 ? [STELLA, ...rewardTokens] : [...rewardTokens], + farmTvlUsd, + }; + }); + + const dataRewardsObj = {}; + for (const p of dataRewards) { + dataRewardsObj[p.lpToken.toLowerCase()] = p; + } + + return dataFee.map((p) => { + const pool = dataRewardsObj[p.pool.toLowerCase()]; + if (pool === undefined) return { ...p }; + + return { + ...p, + apyReward: pool.stellaAPR + pool.extraAPR, + rewardTokens: pool.rewardTokens, + tvlUsd: pool.farmTvlUsd, + }; + }); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.stellaswap.com/farm', +}; diff --git a/src/adaptors/stellaswap/index.js b/src/adaptors/stellaswap/index.js deleted file mode 100644 index c72f2e7af7..0000000000 --- a/src/adaptors/stellaswap/index.js +++ /dev/null @@ -1,35 +0,0 @@ -const utils = require('../utils'); - -const buildPool = (entry) => { - const newObj = { - pool: entry.id, - chain: utils.formatChain(entry.chain), - project: 'stellaswap', - symbol: entry.tokens, - tvlUsd: entry.tvl, - apy: ( entry.reward + entry.base ) * 100, - }; - - return newObj; -}; - -const farmsList = async () => { - let data = await utils.getData( - 'https://api.stellaswap.com/api/v1/coindix' - ); - - const nonActivefarms = data.result.filter(f => f.active); - data = nonActivefarms.map((el) => buildPool(el)); - - return data; -}; - -const main = async () => { - const data = await farmsList(); - return data; -}; - -module.exports = { - timetravel: false, - apy: main, -}; diff --git a/src/adaptors/stfil/abiStakingPool.js b/src/adaptors/stfil/abiStakingPool.js new file mode 100644 index 0000000000..06c4b8dc74 --- /dev/null +++ b/src/adaptors/stfil/abiStakingPool.js @@ -0,0 +1,831 @@ +module.exports = [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "award", + "type": "uint256" + } + ], + "name": "Liquidation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "role", + "type": "uint256" + } + ], + "name": "NodeDelegate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "NodeUndelegateBeneficiary", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "NodeUndelegateOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "OperatorChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Unstake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_FIL_BORROW_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_STAKE_FIL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RISK_RESERVE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "approveOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "delegateBeneficiary", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "delegateOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract IStakingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "getNodeData", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.NodeConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "safetyBuffer", + "type": "uint256" + }, + { + "internalType": "enum DataTypes.NodeRole", + "name": "role", + "type": "uint8" + } + ], + "internalType": "struct DataTypes.NodeData", + "name": "", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "data", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.PoolConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "stFILAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "internalType": "struct DataTypes.PoolReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserveNormalizedIncome", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserveNormalizedVariableDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initStakingPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IStakingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + } + ], + "name": "liquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "configuration", + "type": "uint256" + } + ], + "name": "setNodeConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "val", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "configuration", + "type": "uint256" + } + ], + "name": "setPoolConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "undelegateBeneficiary", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + } + ], + "name": "undelegateOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "unstake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "actorId", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/stfil/index.js b/src/adaptors/stfil/index.js new file mode 100644 index 0000000000..3089e75015 --- /dev/null +++ b/src/adaptors/stfil/index.js @@ -0,0 +1,72 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const abiStakingPool = require('./abiStakingPool'); + +const stakingPool = '0xC8E4EF1148D11F8C557f677eE3C73901CD796Bf6'; +const variableDebtTokenAddress = '0x0B24190702018C93E09A55F958D6485Ae31b62A1'; +const sdkChain = 'filecoin'; +const url = 'https://app.stfil.io/#/stake'; + +const getApy = async () => { + const priceKey = `coingecko:filecoin`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const reserveData = ( + await sdk.api.abi.call({ + target: stakingPool, + abi: abiStakingPool.find((m) => m.name === 'getReserveData'), + chain: sdkChain, + }) + ).output; + const apyBase = reserveData.currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData.currentVariableBorrowRate / 1e25; + + const totalBorrow = ( + await sdk.api.abi.call({ + target: variableDebtTokenAddress, + abi: 'erc20:totalSupply', + chain: sdkChain, + }) + ).output; + + const decimal = ( + await sdk.api.abi.call({ + target: variableDebtTokenAddress, + abi: 'erc20:decimals', + chain: sdkChain, + }) + ).output; + + const tvlUsd = + ( + await sdk.api.eth.getBalance({ + target: stakingPool, + decimals: 18, + chain: sdkChain, + }) + ).output * price; + const totalBorrowUsd = (totalBorrow / 10 ** decimal) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + return [ + { + pool: `${stakingPool}-${sdkChain}`.toLowerCase(), + symbol: 'stFIL', + project: 'stfil', + chain: sdkChain, + tvlUsd, + apyBase, + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + }, + ]; +}; + +module.exports = { + apy: getApy, +}; diff --git a/src/adaptors/stlos-liquid-staking/index.js b/src/adaptors/stlos-liquid-staking/index.js new file mode 100644 index 0000000000..99643b93d2 --- /dev/null +++ b/src/adaptors/stlos-liquid-staking/index.js @@ -0,0 +1,42 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const sTlosAbi = require('./sTlos.json'); +const axios = require('axios'); + +const sTLOS = '0xb4b01216a5bc8f1c8a33cd990a1239030e60c905'; + +async function poolsFunction(timestamp, block, chainBlocks) { + const pooledTLOS = + ( + await sdk.api.abi.call({ + target: sTLOS, + abi: sTlosAbi.totalAssets, + chain: 'telos', + }) + ).output / 1e18; + + const priceKey = 'coingecko:telos'; + const telosPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const apyPercentage = (await axios.get('https://api.telos.net/v1/apy/evm')) + .data; + + return [ + { + pool: sTLOS, + chain: utils.formatChain('telos'), + project: 'stlos-liquid-staking', + symbol: utils.formatSymbol('sTLOS'), + tvlUsd: pooledTLOS * telosPrice, + apyBase: apyPercentage, + }, + ]; +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://www.teloscan.io/staking', +}; diff --git a/src/adaptors/stlos-liquid-staking/sTlos.json b/src/adaptors/stlos-liquid-staking/sTlos.json new file mode 100644 index 0000000000..69b6adba53 --- /dev/null +++ b/src/adaptors/stlos-liquid-staking/sTlos.json @@ -0,0 +1,15 @@ +{ + "totalAssets": { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/ston.fi/index.js b/src/adaptors/ston.fi/index.js new file mode 100644 index 0000000000..37060c5a12 --- /dev/null +++ b/src/adaptors/ston.fi/index.js @@ -0,0 +1,76 @@ +const utils = require('../utils'); + +// ignore pools with TVL below the threshold +const MIN_TVL_USD = 100000; + +const getApy = async () => { + console.log("Requesting pools list") + const pool_list = (await utils.getData('https://api.ston.fi/v1/pools')).pool_list; + console.log("Requesting farms list") + const farm_list = (await utils.getData('https://api.ston.fi/v1/farms')).farm_list; + console.log("Requesting assets list") + const asset_list = (await utils.getData('https://api.ston.fi/v1/assets')).asset_list; + console.log("Well done, preparing output list") + const asset2symbol = {}; + for (const asset of asset_list) { + if (asset.community || asset.blacklisted) { + continue; + } + asset2symbol[asset.contract_address] = asset.symbol; + } + const pool2tvl = {}; + for (const pool of pool_list) { + // ignore pools with low liquidity + if (pool['lp_total_supply_usd'] < MIN_TVL_USD) { + continue + } + pool2tvl[pool['address']] = { + tvl: pool['lp_total_supply_usd'], + tokens: [pool['token0_address'], pool['token1_address']], + base_apy: pool['apy_1d'] + } + } + + const pools = Object.keys(pool2tvl) + .map((pool_address) => { + const farm = farm_list.find((f) => f.pool_address == pool_address && f.status == 'operational') + const pool_info = pool2tvl[pool_address]; + if (!(pool_info.tokens[0] in asset2symbol && pool_info.tokens[1] in asset2symbol)) { + console.error("Can't find symbol", pool_info); + return null; + } + const s1 = asset2symbol[pool_info.tokens[0]] + const s2 = asset2symbol[pool_info.tokens[1]]; + // use apropriate base-quote order + let symbol = ''; + if (s1 == 'USD₮') { + symbol = `${s2}-${s1}` + } else if (s2 == 'USD₮') { + symbol = `${s1}-${s2}` + } else if (s1 == 'TON') { + symbol = `${s2}-${s1}` + } else { + symbol = `${s1}-${s2}` + } + + return { + pool: `${pool_address}-ton`.toLowerCase(), + chain: 'Ton', + project: 'ston.fi', + symbol: symbol, + tvlUsd: Number(pool_info.tvl), + apyBase: Number(pool_info.base_apy) * 100, + apyReward: farm ? Number(farm.apy) * 100 : 0, + rewardTokens: farm ? [farm.reward_token_address] : undefined, + underlyingTokens: pool_info.tokens, + url: `https://app.ston.fi/pools/${pool_address}` + }; + }).filter((pool) => pool != null); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://ston.fi/', +}; diff --git a/src/adaptors/storm-trade/index.js b/src/adaptors/storm-trade/index.js new file mode 100644 index 0000000000..b9e0d7f2de --- /dev/null +++ b/src/adaptors/storm-trade/index.js @@ -0,0 +1,60 @@ +const utils = require('../utils'); + +const GRAPHQL_ENDPOINT = 'https://api5.storm.tg/graphql'; + + +const getVault = async (address, price, symbol, token) => { + console.log("Requesting vault " + address) + const vault = (await utils.getData(GRAPHQL_ENDPOINT, { + query: ` + query { + getVault(address: "${address}") { + freeBalance + config { + asset { + name + decimals + } + } + APR { + rateAPR + } + } +}` + })).data.getVault; + console.log(vault); + return { + pool: `${address}-ton`.toLowerCase(), + chain: 'Ton', + project: 'storm-trade', + symbol: symbol, + tvlUsd: vault.freeBalance / 1e9 * price, + apyBase: Number(vault.APR.rateAPR), + underlyingTokens: [token], + url: `https://app.storm.tg/vault/${symbol}` + } +} + + +const getApr = async () => { + console.log("Requesting vaults list") + const TON = 'ton:EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c'; + const NOT = 'ton:EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT'; + const price = async (token) => (await utils.getData(`https://coins.llama.fi/prices/current/${token}`)).coins[token].price; + const ton_price = await price(TON); + + return [ + await getVault('0:33e9e84d7cbefff0d23b395875420e3a1ecb82e241692be89c7ea2bd27716b77', 1, + 'USDT', 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'), + await getVault('0:e926764ff3d272c73ddeb836975c5521c025ad68e7919a25094e2de3198805f1', await price(TON), + 'TON', 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c'), + await getVault('0:06f3f073c255a49aa6fdcc89abf512638e065908b30e4173fd3d1d01d4f607bd', await price(NOT), + 'NOT', 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT') + ]; +}; + +module.exports = { + timetravel: false, + apy: getApr, + url: 'https://storm.tg/', +}; diff --git a/src/adaptors/strata-tranches/index.js b/src/adaptors/strata-tranches/index.js new file mode 100644 index 0000000000..c3bc6e9f1d --- /dev/null +++ b/src/adaptors/strata-tranches/index.js @@ -0,0 +1,98 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const ethers = require('ethers'); + +const Addresses = { + lens: '0xeA62e3a2D5FE8D5b66dc8E1bd2405AD23C851f4e', + ethena: { + cdo: '0x908B3921aaE4fC17191D382BB61020f2Ee6C0e20', + srUSDe: '0x3d7d6fdf07EE548B939A80edbc9B2256d0cdc003', + jrUSDe: '0xC58D044404d8B14e953C115E67823784dEA53d8F', + }, +}; + +const getTotalSupply = async (tokenAddress, chain = 'ethereum') => { + try { + const { output } = await sdk.api.abi.call({ + target: tokenAddress, + abi: 'erc20:totalSupply', + chain, + }); + return output / 1e18; + } catch (error) { + console.error(`Error fetching total supply for ${tokenAddress}:`, error); + throw error; + } +}; + +const getTokenPrice = async (tokenAddress) => { + try { + const priceKey = `ethereum:${tokenAddress}`; + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + return data.coins[priceKey].price; + } catch (error) { + console.error(`Error fetching price for ${tokenAddress}:`, error); + throw error; + } +}; + +const getAprs = async (cdoAddress, chain = 'ethereum') => { + try { + const { output } = await sdk.api.abi.call({ + target: Addresses.lens, + abi: 'function getAPRs(address cdo) external view returns (int64 base, int64 target, int64 jrt, int64 srt)', + params: [cdoAddress], + chain, + block: 'latest', + }); + let [base, target, jrt, srt] = output; + return { + jrt: Number(jrt) / 1e10, + srt: Number(srt) / 1e10, + }; + } catch (error) { + console.error(`Error fetching total supply for ${cdoAddress}:`, error); + throw error; + } +}; + +async function loadPool(tranche, symbol) { + const cdo = Addresses[tranche].cdo; + const vault = Addresses[tranche][symbol]; + + const [totalSupply, price, aprs] = await Promise.all([ + getTotalSupply(vault), + getTokenPrice(vault), + getAprs(cdo), + ]); + + const apy = utils.aprToApy(symbol.startsWith('sr') ? aprs.srt : aprs.jrt); + return { + pool: vault, + symbol: symbol, + chain: 'ethereum', + project: 'strata-tranches', + tvlUsd: totalSupply * price, + apyBase: apy, + }; +} + +const apy = async () => { + try { + return await Promise.all([ + loadPool('ethena', 'srUSDe'), + loadPool('ethena', 'jrUSDe'), + ]); + } catch (error) { + console.error('Error fetching APYs:', error); + throw error; + } +}; + +module.exports = { + apy, + url: 'https://strata.money/', +}; diff --git a/src/adaptors/stratum-exchange/abiGauge.json b/src/adaptors/stratum-exchange/abiGauge.json new file mode 100644 index 0000000000..c4c9983126 --- /dev/null +++ b/src/adaptors/stratum-exchange/abiGauge.json @@ -0,0 +1,1086 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_stake", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_forPair", + "type": "bool" + }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "claimed", + "type": "uint256[]" + } + ], + "name": "ClaimFees3Pool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "SECONDS_PER_EPOCH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxRuns", + "type": "uint256" + } + ], + "name": "batchRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxRuns", + "type": "uint256" + } + ], + "name": "batchUpdateRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "checkpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOf", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_swapAddress", + "type": "address" + } + ], + "name": "claimFeesFor3Pool", + "outputs": [ + { + "internalType": "uint256[]", + "name": "claimed", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "derivedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "derivedBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "derivedSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorBalanceIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorRewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorSupplyIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "is3pool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastEarn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_is3pool", + "type": "bool" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardPerTokenCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardPerTokenNumCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "supplyCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyNumCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "i", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldToken", + "type": "address" + }, + { + "internalType": "address", + "name": "newToken", + "type": "address" + } + ], + "name": "swapOutRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stratum-exchange/abiMultipoolSwap.json b/src/adaptors/stratum-exchange/abiMultipoolSwap.json new file mode 100644 index 0000000000..f879b8014a --- /dev/null +++ b/src/adaptors/stratum-exchange/abiMultipoolSwap.json @@ -0,0 +1,953 @@ +[ + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "_pooledTokens", + "type": "address[]" + }, + { + "internalType": "uint8[]", + "name": "decimals", + "type": "uint8[]" + }, + { + "internalType": "string", + "name": "lpTokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "lpTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_adminFee", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "fees", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "invariant", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "AddLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newAdminFee", + "type": "uint256" + } + ], + "name": "NewAdminFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newSwapFee", + "type": "uint256" + } + ], + "name": "NewSwapFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newWithdrawFee", + "type": "uint256" + } + ], + "name": "NewWithdrawFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "initialTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "futureTime", + "type": "uint256" + } + ], + "name": "RampA", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "RemoveLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "fees", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "invariant", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + } + ], + "name": "RemoveLiquidityImbalance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpTokenSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boughtId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensBought", + "type": "uint256" + } + ], + "name": "RemoveLiquidityOne", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "currentA", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "StopRampA", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensSold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokensBought", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "soldId", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "boughtId", + "type": "uint128" + } + ], + "name": "TokenSwap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minToMint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "calculateRemoveLiquidity", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "tokenIndex", + "type": "uint8" + } + ], + "name": "calculateRemoveLiquidityOneToken", + "outputs": [ + { + "internalType": "uint256", + "name": "availableTokenAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tokenIndexFrom", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "tokenIndexTo", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "dx", + "type": "uint256" + } + ], + "name": "calculateSwap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bool", + "name": "deposit", + "type": "bool" + } + ], + "name": "calculateTokenAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAPrecise", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getAdminBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAdminFees", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "index", + "type": "uint8" + } + ], + "name": "getToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tokenIndex", + "type": "uint8" + } + ], + "name": "getTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "index", + "type": "uint8" + } + ], + "name": "getTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "name": "getTokenIndex", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTokensArray", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVirtualPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "futureA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "futureTime", + "type": "uint256" + } + ], + "name": "rampA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseHandler", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "minAmounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "maxBurnAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityImbalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "tokenIndex", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "minAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityOneToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rebaseHandler", + "type": "address" + } + ], + "name": "setRebaseHandler", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newSwapFee", + "type": "uint256" + } + ], + "name": "setSwapFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stopRampA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tokenIndexFrom", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "tokenIndexTo", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "dx", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minDy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "swapStorage", + "outputs": [ + { + "internalType": "uint256", + "name": "initialA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "futureA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialATime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "futureATime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "adminFee", + "type": "uint256" + }, + { + "internalType": "contract LPToken", + "name": "lpToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAdminFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stratum-exchange/abiPair.json b/src/adaptors/stratum-exchange/abiPair.json new file mode 100644 index 0000000000..379cc37e73 --- /dev/null +++ b/src/adaptors/stratum-exchange/abiPair.json @@ -0,0 +1,1102 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stratum-exchange/abiPairFactory.json b/src/adaptors/stratum-exchange/abiPairFactory.json new file mode 100644 index 0000000000..f0fce6c610 --- /dev/null +++ b/src/adaptors/stratum-exchange/abiPairFactory.json @@ -0,0 +1,508 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ZERO_FEE_INDICATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "acceptPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_3pool", + "type": "address" + } + ], + "name": "create3Pool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "customFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idx", + "type": "uint256" + } + ], + "name": "getPairByIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "is3pool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingPauser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setCustomFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_state", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pauser", + "type": "address" + } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/stratum-exchange/abiVoter.json b/src/adaptors/stratum-exchange/abiVoter.json new file mode 100644 index 0000000000..6667f28252 --- /dev/null +++ b/src/adaptors/stratum-exchange/abiVoter.json @@ -0,0 +1,1287 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauges", + "type": "address" + }, + { + "internalType": "address", + "name": "_bribes", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "internal_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "external_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "SECONDS_PER_EPOCH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_LPToken", + "type": "address" + } + ], + "name": "_LPTokenTo3Pool", + "outputs": [ + { + "internalType": "address", + "name": "swap", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_bribes", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_fees", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_wxBribeFactory", + "type": "address" + } + ], + "name": "createGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_3pool", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_token", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_wxBribeFactory", + "type": "address" + } + ], + "name": "createGauge3pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "finish", + "type": "uint256" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_swapAddress", + "type": "address[]" + } + ], + "name": "distributeFeesFor3Pool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distro", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "external_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gauges", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "internal_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "is3poolGauge", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAlive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isGauge", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lastVoted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "poolByIndex", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolForGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolVote", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_council", + "type": "address" + } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usedWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_poolVote", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_weights", + "type": "uint256[]" + } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "votesByNFTAndPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "weights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/stratum-exchange/index.js b/src/adaptors/stratum-exchange/index.js new file mode 100644 index 0000000000..73bded58e7 --- /dev/null +++ b/src/adaptors/stratum-exchange/index.js @@ -0,0 +1,364 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const abiPairFactory = require('./abiPairFactory.json'); + +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); +const abiMultipoolSwap = require('./abiMultipoolSwap.json'); + +const pairFactory = '0x061FFE84B0F9E1669A6bf24548E5390DBf1e03b2'; +const voter = '0xd14884b51Ff6cDa4F6f92f0fe7ac198C6c63BC7a'; +const STRAT = '0x5a093a9c4f440c6b105F0AF7f7C4f1fBE45567f9'; + +const DEBUG = false; + +const getApy = async () => { + let chain = 'mantle'; + const poolsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain, + }) + ).output; + + const pools = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain, + }) + ).output.map((o) => o.output); + + const poolIsMultipool = ( + await sdk.api.abi.multiCall({ + calls: pools.map((p) => ({ + target: pairFactory, + params: [p], + })), + abi: abiPairFactory.find((m) => m.name === 'is3pool'), + chain, + }) + ).output.map((o) => o.output); + + const poolFee = ( + await sdk.api.abi.multiCall({ + calls: pools.map((p) => ({ + target: pairFactory, + params: [p], + })), + abi: abiPairFactory.find((m) => m.name === 'getFee' && m.inputs.length === 1), + chain, + }) + ).output.map((o) => o.output); + + // + // Pairs + // + + const pairs = pools.filter((_, i) => !poolIsMultipool[i]); + + const pairMetaData = ( + await sdk.api.abi.multiCall({ + calls: pairs.map((pair) => ({ + target: pair, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain, + }) + ).output.map((o) => o.output); + + + // + // Multipools + // + + const multipools = pools.filter((_, i) => poolIsMultipool[i]); + + const mpLpToken = ( + await sdk.api.abi.multiCall({ + calls: multipools.map((multipool) => ({ + target: multipool, + })), + abi: abiMultipoolSwap.find((m) => m.name === 'swapStorage'), + chain, + }) + ).output.map((o) => o.output[6]); // lpToken + + const mpPooledTokens = ( + await sdk.api.abi.multiCall({ + calls: multipools.map((multipool) => ({ + target: multipool, + })), + abi: abiMultipoolSwap.find((m) => m.name === 'getTokensArray'), + chain, + }) + ).output.map((o) => o.output); + + const mpTokenPermutation = mpPooledTokens.map((tokenArr, i) => + tokenArr.map((_, j) => + ({multipoolIndex: i, tokenIndex: j}) + ) + ).flat(); + const mpReserves = mpPooledTokens.map(tokenAddr => tokenAddr.map(_ => 0)); + ( + await sdk.api.abi.multiCall({ + calls: mpTokenPermutation.map(permutation => ({ + target: multipools[permutation.multipoolIndex], + params: [permutation.tokenIndex] + })), + abi: abiMultipoolSwap.find((m) => m.name === 'getTokenBalance'), + chain, + }) + ).output.map((o) => o.output).forEach((balance, i) => { + mpReserves[mpTokenPermutation[i].multipoolIndex][mpTokenPermutation[i].tokenIndex] = balance; + }); + + const mpUnderlyingTokenAddr = [...new Set(mpPooledTokens.flat())]; + const mpUnderlyingTokenAddrToSymbol = {}; + ( + await sdk.api.abi.multiCall({ + calls: mpUnderlyingTokenAddr.map(tokenAddr => ({ + target: tokenAddr + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain, + }) + ).output.map((o) => o.output).forEach((symbol, i) => { + mpUnderlyingTokenAddrToSymbol[mpUnderlyingTokenAddr[i]] = symbol; + }); + + + // + // Common (Pairs & Multipools) + // + + const poolLpToken = pools.map((pool, i) => !poolIsMultipool[i] ? pool : mpLpToken[multipools.indexOf(pool)]); + + const poolSymbol = ( + await sdk.api.abi.multiCall({ + calls: poolLpToken.map(lpToken => ({ + target: lpToken, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain, + }) + ).output.map((o) => o.output); + + const poolLpTotalSupply = ( + await sdk.api.abi.multiCall({ + calls: poolLpToken.map(lpToken => ({ + target: lpToken, + })), + abi: abiPair.find((m) => m.name === 'totalSupply'), + chain, + }) + ).output.map((o) => o.output); + + const poolGauge = ( + await sdk.api.abi.multiCall({ + calls: poolLpToken.map(lpToken => ({ + target: voter, + params: [lpToken], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain, + }) + ).output.map((o) => o.output); + + const poolLpInGaugeBalance = ( + await sdk.api.abi.multiCall({ + calls: poolGauge.map((gauge, i) => ({ + target: poolLpToken[i], + params: [gauge], + })), + abi: abiPair.find((m) => m.name === 'balanceOf'), + chain, + }) + ).output.map((o) => o.output); + + const poolGaugeStakingRatio = poolLpInGaugeBalance.map((balance, i) => balance / poolLpTotalSupply[i]); + + const poolRewardRate = ( + await sdk.api.abi.multiCall({ + calls: poolGauge.map(gauge => ({ + target: gauge, + params: [STRAT], + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + pairMetaData + .map((m) => [m.t0, m.t1]).flat() + .concat(mpPooledTokens.flat()) + .concat(STRAT) + ), + ]; + + const decimalsOf = {}; + ( + await sdk.api.abi.multiCall({ + calls: tokens.map(token => ({ + target: token, + })), + abi: abiPair.find((m) => m.name === 'decimals'), + chain, + permitFailure: true, + }) + ).output.map((o) => o.output).forEach((decimal, i) => { + decimalsOf[tokens[i]] = decimal; + }); + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `mantle:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA.flat()) { + prices = {...prices, ...p}; + } + + + // + // Generate resulting SDK Pool objects + // + + const rewardTokenPriceUsd = prices[`mantle:${STRAT}`]?.price; + + const poolDescriptorsOfPairs = pairs.map((pair, i) => { + + const poolIndex = pools.indexOf(pair); + + const pairMeta = pairMetaData[i]; + const r0 = pairMeta.r0 / pairMeta.dec0; + const r1 = pairMeta.r1 / pairMeta.dec1; + + const p0 = prices[`mantle:${pairMeta.t0}`]?.price; + const p1 = prices[`mantle:${pairMeta.t1}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const rewardRate = poolRewardRate[poolIndex]; // STRAT per second + const apyReward = poolGaugeStakingRatio[poolIndex] > 0 && tvlUsd > 0 + ? (rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd + / tvlUsd / poolGaugeStakingRatio[poolIndex] * 100) + : Number.POSITIVE_INFINITY; + + let pool = { + pool: pair, + chain: utils.formatChain(chain), + project: 'stratum-exchange', + symbol: utils.formatSymbol(poolSymbol[poolIndex].split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [STRAT] : [], + underlyingTokens: [pairMeta.t0, pairMeta.t1], + poolMeta: pairMeta.st + ? `sAMM: stable V2 pair ${poolFee[poolIndex] / 100}%` + : `vAMM: volatile V2 pair ${poolFee[poolIndex] / 100}%`, + url: `https://app.stratumexchange.com/liquidity/${pair}`, + }; + if (DEBUG) { + pool = { + ...pool, + type: pairMeta.st ? 'sAMM' : 'vAMM', + gauge: poolGauge[poolIndex], + gaugeStakingRatio: poolGaugeStakingRatio[poolIndex], + locked0_USD: r0 * p0, + locked1_USD: r1 * p1, + rewardTokenPriceUsd, + rewardRate, + rewardRatePerSec: rewardRate / 1e18, + rewardRatePerYear: rewardRate / 1e18 * 86400 * 365, + rewardPerYearUsd: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd, + rewardPerYearUsdToTvlRatioPercent: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd / tvlUsd * 100, + rewardPerYearUsdToStakedTvlRatioPercent: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd / tvlUsd / poolGaugeStakingRatio[poolIndex] * 100, + }; + } + return pool; + }); + + const poolDescriptorsOfMultipools = multipools.map((multipool, i) => { + + const poolIndex = pools.indexOf(multipool); + + let tvlUsd = 0; + mpPooledTokens[i].forEach((tokenAddr, j) => + tvlUsd += (mpReserves[i][j] / (10 ** decimalsOf[tokenAddr])) + * prices[`mantle:${tokenAddr}`]?.price + ); + + const rewardRate = poolRewardRate[poolIndex]; // STRAT per second + const apyReward = poolGaugeStakingRatio[poolIndex] > 0 && tvlUsd > 0 + ? (rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd / + tvlUsd / poolGaugeStakingRatio[poolIndex] * 100) + : Number.POSITIVE_INFINITY; + + const customSymbol = mpPooledTokens[i].map(tokenAddr => mpUnderlyingTokenAddrToSymbol[tokenAddr]).join('-'); + + let pool = { + pool: multipool, + chain: utils.formatChain(chain), + project: 'stratum-exchange', + symbol: utils.formatSymbol(customSymbol), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [STRAT] : [], + underlyingTokens: mpPooledTokens[i], + poolMeta: `multipool (curve style) ${poolFee[poolIndex] / 100}%`, + url: `https://app.stratumexchange.com/liquidity/${multipool}`, + }; + if (DEBUG) { + pool = { + ...pool, + type: 'multipool', + lpToken: mpLpToken[i], + tokens: mpPooledTokens[i], + reserves: mpReserves[i], + gauge: poolGauge[poolIndex], + gaugeStakingRatio: poolGaugeStakingRatio[poolIndex], + rewardTokenPriceUsd, + rewardRate, + rewardRatePerSec: rewardRate / 1e18, + rewardRatePerYear: rewardRate / 1e18 * 86400 * 365, + rewardPerYearUsd: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd, + rewardPerYearUsdToTvlRatioPercent: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd / tvlUsd * 100, + rewardPerYearUsdToStakedTvlRatioPercent: rewardRate / 1e18 * 86400 * 365 * rewardTokenPriceUsd / tvlUsd / poolGaugeStakingRatio[poolIndex] * 100, + }; + } + return pool; + }); + + return [...poolDescriptorsOfPairs, ...poolDescriptorsOfMultipools] + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: getApy, + url: 'https://app.stratumexchange.com/liquidity', +}; diff --git a/src/adaptors/stream-finance/abiVault.json b/src/adaptors/stream-finance/abiVault.json new file mode 100644 index 0000000000..000e9bb912 --- /dev/null +++ b/src/adaptors/stream-finance/abiVault.json @@ -0,0 +1 @@ +[{"type":"constructor","inputs":[{"name":"_tokenName","type":"string","internalType":"string"},{"name":"_tokenSymbol","type":"string","internalType":"string"},{"name":"_stableWrapper","type":"address","internalType":"address"},{"name":"_lzEndpoint","type":"address","internalType":"address"},{"name":"_delegate","type":"address","internalType":"address"},{"name":"_vaultParams","type":"tuple","internalType":"struct Vault.VaultParams","components":[{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"minimumSupply","type":"uint56","internalType":"uint56"},{"name":"cap","type":"uint104","internalType":"uint104"}]}],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"},{"type":"function","name":"SEND","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"SEND_AND_CALL","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"type":"function","name":"accountVaultBalance","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"allowIndependence","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"allowInitializePath","inputs":[{"name":"origin","type":"tuple","internalType":"struct Origin","components":[{"name":"srcEid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"allowance","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"approvalRequired","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"type":"function","name":"approve","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"bridgeWithRedeem","inputs":[{"name":"sendParam","type":"tuple","internalType":"struct SendParam","components":[{"name":"dstEid","type":"uint32","internalType":"uint32"},{"name":"to","type":"bytes32","internalType":"bytes32"},{"name":"amountLD","type":"uint256","internalType":"uint256"},{"name":"minAmountLD","type":"uint256","internalType":"uint256"},{"name":"extraOptions","type":"bytes","internalType":"bytes"},{"name":"composeMsg","type":"bytes","internalType":"bytes"},{"name":"oftCmd","type":"bytes","internalType":"bytes"}]},{"name":"fee","type":"tuple","internalType":"struct MessagingFee","components":[{"name":"nativeFee","type":"uint256","internalType":"uint256"},{"name":"lzTokenFee","type":"uint256","internalType":"uint256"}]},{"name":"refundAddress","type":"address","internalType":"address payable"}],"outputs":[{"name":"","type":"tuple","internalType":"struct MessagingReceipt","components":[{"name":"guid","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"},{"name":"fee","type":"tuple","internalType":"struct MessagingFee","components":[{"name":"nativeFee","type":"uint256","internalType":"uint256"},{"name":"lzTokenFee","type":"uint256","internalType":"uint256"}]}]},{"name":"","type":"tuple","internalType":"struct OFTReceipt","components":[{"name":"amountSentLD","type":"uint256","internalType":"uint256"},{"name":"amountReceivedLD","type":"uint256","internalType":"uint256"}]}],"stateMutability":"payable"},{"type":"function","name":"cap","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"combineOptions","inputs":[{"name":"_eid","type":"uint32","internalType":"uint32"},{"name":"_msgType","type":"uint16","internalType":"uint16"},{"name":"_extraOptions","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"decimalConversionRate","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"depositAndStake","inputs":[{"name":"amount","type":"uint104","internalType":"uint104"},{"name":"creditor","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositETHAndStake","inputs":[{"name":"creditor","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"endpoint","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ILayerZeroEndpointV2"}],"stateMutability":"view"},{"type":"function","name":"enforcedOptions","inputs":[{"name":"eid","type":"uint32","internalType":"uint32"},{"name":"msgType","type":"uint16","internalType":"uint16"}],"outputs":[{"name":"enforcedOption","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"instantUnstake","inputs":[{"name":"amount","type":"uint104","internalType":"uint104"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"instantUnstakeAndWithdraw","inputs":[{"name":"amount","type":"uint104","internalType":"uint104"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isComposeMsgSender","inputs":[{"name":"","type":"tuple","internalType":"struct Origin","components":[{"name":"srcEid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"}]},{"name":"","type":"bytes","internalType":"bytes"},{"name":"_sender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"isPeer","inputs":[{"name":"_eid","type":"uint32","internalType":"uint32"},{"name":"_peer","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"lzReceive","inputs":[{"name":"_origin","type":"tuple","internalType":"struct Origin","components":[{"name":"srcEid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"}]},{"name":"_guid","type":"bytes32","internalType":"bytes32"},{"name":"_message","type":"bytes","internalType":"bytes"},{"name":"_executor","type":"address","internalType":"address"},{"name":"_extraData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"lzReceiveAndRevert","inputs":[{"name":"_packets","type":"tuple[]","internalType":"struct InboundPacket[]","components":[{"name":"origin","type":"tuple","internalType":"struct Origin","components":[{"name":"srcEid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"}]},{"name":"dstEid","type":"uint32","internalType":"uint32"},{"name":"receiver","type":"address","internalType":"address"},{"name":"guid","type":"bytes32","internalType":"bytes32"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"executor","type":"address","internalType":"address"},{"name":"message","type":"bytes","internalType":"bytes"},{"name":"extraData","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"lzReceiveSimulate","inputs":[{"name":"_origin","type":"tuple","internalType":"struct Origin","components":[{"name":"srcEid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"}]},{"name":"_guid","type":"bytes32","internalType":"bytes32"},{"name":"_message","type":"bytes","internalType":"bytes"},{"name":"_executor","type":"address","internalType":"address"},{"name":"_extraData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"maxRedeem","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"msgInspector","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"nextNonce","inputs":[{"name":"","type":"uint32","internalType":"uint32"},{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"nonce","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"oApp","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"oAppVersion","inputs":[],"outputs":[{"name":"senderVersion","type":"uint64","internalType":"uint64"},{"name":"receiverVersion","type":"uint64","internalType":"uint64"}],"stateMutability":"pure"},{"type":"function","name":"oftVersion","inputs":[],"outputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"},{"name":"version","type":"uint64","internalType":"uint64"}],"stateMutability":"pure"},{"type":"function","name":"omniTotalSupply","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"peers","inputs":[{"name":"eid","type":"uint32","internalType":"uint32"}],"outputs":[{"name":"peer","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"preCrime","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"quoteOFT","inputs":[{"name":"_sendParam","type":"tuple","internalType":"struct SendParam","components":[{"name":"dstEid","type":"uint32","internalType":"uint32"},{"name":"to","type":"bytes32","internalType":"bytes32"},{"name":"amountLD","type":"uint256","internalType":"uint256"},{"name":"minAmountLD","type":"uint256","internalType":"uint256"},{"name":"extraOptions","type":"bytes","internalType":"bytes"},{"name":"composeMsg","type":"bytes","internalType":"bytes"},{"name":"oftCmd","type":"bytes","internalType":"bytes"}]}],"outputs":[{"name":"oftLimit","type":"tuple","internalType":"struct OFTLimit","components":[{"name":"minAmountLD","type":"uint256","internalType":"uint256"},{"name":"maxAmountLD","type":"uint256","internalType":"uint256"}]},{"name":"oftFeeDetails","type":"tuple[]","internalType":"struct OFTFeeDetail[]","components":[{"name":"feeAmountLD","type":"int256","internalType":"int256"},{"name":"description","type":"string","internalType":"string"}]},{"name":"oftReceipt","type":"tuple","internalType":"struct OFTReceipt","components":[{"name":"amountSentLD","type":"uint256","internalType":"uint256"},{"name":"amountReceivedLD","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"},{"type":"function","name":"quoteSend","inputs":[{"name":"_sendParam","type":"tuple","internalType":"struct SendParam","components":[{"name":"dstEid","type":"uint32","internalType":"uint32"},{"name":"to","type":"bytes32","internalType":"bytes32"},{"name":"amountLD","type":"uint256","internalType":"uint256"},{"name":"minAmountLD","type":"uint256","internalType":"uint256"},{"name":"extraOptions","type":"bytes","internalType":"bytes"},{"name":"composeMsg","type":"bytes","internalType":"bytes"},{"name":"oftCmd","type":"bytes","internalType":"bytes"}]},{"name":"_payInLzToken","type":"bool","internalType":"bool"}],"outputs":[{"name":"msgFee","type":"tuple","internalType":"struct MessagingFee","components":[{"name":"nativeFee","type":"uint256","internalType":"uint256"},{"name":"lzTokenFee","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"},{"type":"function","name":"redeem","inputs":[{"name":"numShares","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceOwnership","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"rescueETH","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"rescueTokens","inputs":[{"name":"_token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"rollToNextRound","inputs":[{"name":"yield","type":"uint256","internalType":"uint256"},{"name":"isYieldPositive","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"round","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"roundPricePerShare","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"send","inputs":[{"name":"_sendParam","type":"tuple","internalType":"struct SendParam","components":[{"name":"dstEid","type":"uint32","internalType":"uint32"},{"name":"to","type":"bytes32","internalType":"bytes32"},{"name":"amountLD","type":"uint256","internalType":"uint256"},{"name":"minAmountLD","type":"uint256","internalType":"uint256"},{"name":"extraOptions","type":"bytes","internalType":"bytes"},{"name":"composeMsg","type":"bytes","internalType":"bytes"},{"name":"oftCmd","type":"bytes","internalType":"bytes"}]},{"name":"_fee","type":"tuple","internalType":"struct MessagingFee","components":[{"name":"nativeFee","type":"uint256","internalType":"uint256"},{"name":"lzTokenFee","type":"uint256","internalType":"uint256"}]},{"name":"_refundAddress","type":"address","internalType":"address"}],"outputs":[{"name":"msgReceipt","type":"tuple","internalType":"struct MessagingReceipt","components":[{"name":"guid","type":"bytes32","internalType":"bytes32"},{"name":"nonce","type":"uint64","internalType":"uint64"},{"name":"fee","type":"tuple","internalType":"struct MessagingFee","components":[{"name":"nativeFee","type":"uint256","internalType":"uint256"},{"name":"lzTokenFee","type":"uint256","internalType":"uint256"}]}]},{"name":"oftReceipt","type":"tuple","internalType":"struct OFTReceipt","components":[{"name":"amountSentLD","type":"uint256","internalType":"uint256"},{"name":"amountReceivedLD","type":"uint256","internalType":"uint256"}]}],"stateMutability":"payable"},{"type":"function","name":"setAllowIndependence","inputs":[{"name":"_allowIndependence","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setDelegate","inputs":[{"name":"_delegate","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setEnforcedOptions","inputs":[{"name":"_enforcedOptions","type":"tuple[]","internalType":"struct EnforcedOptionParam[]","components":[{"name":"eid","type":"uint32","internalType":"uint32"},{"name":"msgType","type":"uint16","internalType":"uint16"},{"name":"options","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setMsgInspector","inputs":[{"name":"_msgInspector","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setPeer","inputs":[{"name":"_eid","type":"uint32","internalType":"uint32"},{"name":"_peer","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setPreCrime","inputs":[{"name":"_preCrime","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setStableWrapper","inputs":[{"name":"newStableWrapper","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setVaultParams","inputs":[{"name":"newVaultParams","type":"tuple","internalType":"struct Vault.VaultParams","components":[{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"minimumSupply","type":"uint56","internalType":"uint56"},{"name":"cap","type":"uint104","internalType":"uint104"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"shareBalancesHeldByAccount","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"shareBalancesHeldByVault","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"sharedDecimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"shares","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"stableWrapper","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"stake","inputs":[{"name":"amount","type":"uint104","internalType":"uint104"},{"name":"creditor","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"stakeReceipts","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"round","type":"uint16","internalType":"uint16"},{"name":"amount","type":"uint104","internalType":"uint104"},{"name":"unredeemedShares","type":"uint128","internalType":"uint128"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"token","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"totalPending","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"totalStaked","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"transfer","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"transferOwnership","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"unstake","inputs":[{"name":"numShares","type":"uint256","internalType":"uint256"},{"name":"minAmountOut","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"unstakeAndWithdraw","inputs":[{"name":"numShares","type":"uint256","internalType":"uint256"},{"name":"minAmountOut","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"vaultParams","inputs":[],"outputs":[{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"minimumSupply","type":"uint56","internalType":"uint56"},{"name":"cap","type":"uint104","internalType":"uint104"}],"stateMutability":"view"},{"type":"function","name":"vaultState","inputs":[],"outputs":[{"name":"round","type":"uint16","internalType":"uint16"},{"name":"totalPending","type":"uint128","internalType":"uint128"}],"stateMutability":"view"},{"type":"event","name":"AllowIndependenceSet","inputs":[{"name":"allowIndependence","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"CapSet","inputs":[{"name":"oldCap","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newCap","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"EnforcedOptionSet","inputs":[{"name":"_enforcedOptions","type":"tuple[]","indexed":false,"internalType":"struct EnforcedOptionParam[]","components":[{"name":"eid","type":"uint32","internalType":"uint32"},{"name":"msgType","type":"uint16","internalType":"uint16"},{"name":"options","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"event","name":"InstantUnstake","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"round","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"MsgInspectorSet","inputs":[{"name":"inspector","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"OFTReceived","inputs":[{"name":"guid","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"srcEid","type":"uint32","indexed":false,"internalType":"uint32"},{"name":"toAddress","type":"address","indexed":true,"internalType":"address"},{"name":"amountReceivedLD","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OFTSent","inputs":[{"name":"guid","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"dstEid","type":"uint32","indexed":false,"internalType":"uint32"},{"name":"fromAddress","type":"address","indexed":true,"internalType":"address"},{"name":"amountSentLD","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amountReceivedLD","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"PeerSet","inputs":[{"name":"eid","type":"uint32","indexed":false,"internalType":"uint32"},{"name":"peer","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"PreCrimeSet","inputs":[{"name":"preCrimeAddress","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Redeem","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"share","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"round","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"RoundRolled","inputs":[{"name":"round","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"pricePerShare","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"sharesMinted","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"wrappedTokensMinted","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"wrappedTokensBurned","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"yield","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"isYieldPositive","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"Stake","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"round","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Unstake","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"round","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"AddressMustBeNonZero","inputs":[]},{"type":"error","name":"AmountExceedsReceipt","inputs":[]},{"type":"error","name":"AmountMustBeGreaterThanZero","inputs":[]},{"type":"error","name":"CapExceeded","inputs":[]},{"type":"error","name":"CapMustBeGreaterThanZero","inputs":[]},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"allowance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"name":"spender","type":"address","internalType":"address"}]},{"type":"error","name":"IndependenceNotAllowed","inputs":[]},{"type":"error","name":"InsufficientUnredeemedShares","inputs":[]},{"type":"error","name":"InsufficientWithdrawal","inputs":[]},{"type":"error","name":"InvalidDelegate","inputs":[]},{"type":"error","name":"InvalidEndpointCall","inputs":[]},{"type":"error","name":"InvalidLocalDecimals","inputs":[]},{"type":"error","name":"InvalidOptions","inputs":[{"name":"options","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"LzTokenUnavailable","inputs":[]},{"type":"error","name":"MinimumSupplyNotMet","inputs":[]},{"type":"error","name":"NoPeer","inputs":[{"name":"eid","type":"uint32","internalType":"uint32"}]},{"type":"error","name":"NotEnoughNative","inputs":[{"name":"msgValue","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"OnlyEndpoint","inputs":[{"name":"addr","type":"address","internalType":"address"}]},{"type":"error","name":"OnlyPeer","inputs":[{"name":"eid","type":"uint32","internalType":"uint32"},{"name":"sender","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"OnlySelf","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"RoundMismatch","inputs":[]},{"type":"error","name":"RoundMustBeGreaterThanOne","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"SimulationResult","inputs":[{"name":"result","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"SlippageExceeded","inputs":[{"name":"amountLD","type":"uint256","internalType":"uint256"},{"name":"minAmountLD","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"TransferFailed","inputs":[]}] \ No newline at end of file diff --git a/src/adaptors/stream-finance/index.js b/src/adaptors/stream-finance/index.js new file mode 100644 index 0000000000..0e406d9489 --- /dev/null +++ b/src/adaptors/stream-finance/index.js @@ -0,0 +1,194 @@ +const utils = require('../utils'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const vaultABI = require('./abiVault.json'); + +// Configuration constants +const SECONDS_PER_YEAR = 31536000; +const WEEKS_PER_YEAR = 52; + +// Contract addresses +const ADDRESSES = { + ethereum: { + vaults: { + xUSD: '0xE2Fc85BfB48C4cF147921fBE110cf92Ef9f26F94', + xBTC: '0x12fd502e2052CaFB41eccC5B596023d9978057d6', + xETH: '0x7E586fBaF3084C0be7aB5C82C04FfD7592723153', + xEUR: '0xc15697f61170Fc3Bb4e99Eb7913b4C7893F64F13', + }, + wrappers: { + xUSD: '0x6eAf19b2FC24552925dB245F9Ff613157a7dbb4C', + xBTC: '0x12fd502e2052CaFB41eccC5B596023d9978057d6', + xETH: '0xF70f54cEFdCd3C8f011865685FF49FB80A386a34', + xEUR: '0xDCFd98A5681722DF0d93fc11b9205f757576a427', + }, + underlyingTokens: { + xUSD: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC + xBTC: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', // WBTC + xETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH + xEUR: '0x1abaea1f7c830bd89acc67ec4af516284b1bc33c', // EURC + } + } +}; + +const VAULT_DECIMALS = { + '0xE2Fc85BfB48C4cF147921fBE110cf92Ef9f26F94': 6, + '0x12fd502e2052CaFB41eccC5B596023d9978057d6': 8, + '0x7E586fBaF3084C0be7aB5C82C04FfD7592723153': 18, + '0xc15697f61170Fc3Bb4e99Eb7913b4C7893F64F13': 6, +} + + +const UNDERLYING_SYMBOL_MAP = { + XUSD: 'USDC', + XBTC: 'wBTC', + XETH: 'wETH' +}; + + +const mapToUnderlying = (vault) => UNDERLYING_SYMBOL_MAP[vault] || vault; + +const getContractData = async (target, abi, chain, params = []) => { + try { + sdk.api.config.setProvider( + 'ethereum', + new ethers.providers.JsonRpcProvider( + 'https://eth.llamarpc.com' + ) + ); + const result = await sdk.api.abi.call({ + target, + abi: vaultABI.find((m) => m.name === abi), + chain, + params + }); + return result.output; + } catch (error) { + console.error(`Error fetching ${abi} for ${target}:`, error.message); + throw error; + } +}; + +const getTokenPrice = async (priceKey, amount, decimals) => { + try { + const response = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`); + if (!response.data?.coins?.[priceKey]?.price) { + console.warn(`No price found for ${priceKey}`); + return 0; + } + return (response.data.coins[priceKey].price * amount) / 10 ** decimals; + } catch (error) { + console.error(`Error fetching price for ${priceKey}:`, error.message); + return 0; + } +}; + + +const getVaultAPY = async (vaultAddress, chain) => { + const vaultState = await getContractData(vaultAddress, 'vaultState', chain); + const currRound = vaultState.round; + + // Look at last 7 rounds to get a weekly average + const numRoundsToAnalyze = 7; + const startRound = Math.max(1, currRound - numRoundsToAnalyze); + + let pricePerShareValues = []; + + // Collect price per share for each round + for (let round = startRound; round < currRound; round++) { + try { + const pricePerShare = await getContractData( + vaultAddress, + 'roundPricePerShare', + chain, + [round] + ); + pricePerShareValues.push(pricePerShare); + } catch (error) { + console.error(`Error fetching price per share for round ${round}:`, error.message); + } + } + + if (pricePerShareValues.length < 2) { + console.warn('Not enough price data to calculate APY'); + return 0; + } + + // Calculate daily yield rates + const dailyYields = []; + for (let i = 1; i < pricePerShareValues.length; i++) { + const prevPrice = pricePerShareValues[i - 1]; + const currPrice = pricePerShareValues[i]; + if (prevPrice && prevPrice > 0) { + const dailyYield = (currPrice - prevPrice) / prevPrice; + dailyYields.push(dailyYield); + } + } + + if (dailyYields.length === 0) { + console.warn('No valid yield rates calculated'); + return 0; + } + + // Calculate average daily yield + const avgDailyYield = dailyYields.reduce((sum, yieldRate) => sum + yieldRate, 0) / dailyYields.length; + + // Convert to APY using compound interest formula + // APY = (1 + r)^n - 1, where r is the periodic rate and n is number of periods + const periodsPerYear = 365; // Daily compounding + const apy = (Math.pow(1 + avgDailyYield, periodsPerYear) - 1) * 100; + + return Number.isFinite(apy) ? Number(apy.toFixed(2)) : 0; +}; + +const getVaultTVL = async (chain, vaultType, vaultDecimals) => { + const wrapperAddress = ADDRESSES[chain].wrappers[vaultType]; + const underlyingAddress = ADDRESSES[chain].underlyingTokens[vaultType]; + const priceKey = `${chain}:${underlyingAddress}`; + + const totalSupply = await getContractData(wrapperAddress, 'totalSupply', chain); + + return getTokenPrice(priceKey, Number(totalSupply), vaultDecimals); +}; + + +const main = async () => { + const pools = []; + + for (const chain of Object.keys(ADDRESSES)) { + for (const [vaultType, vaultAddress] of Object.entries(ADDRESSES[chain].vaults)) { + try { + const vaultDecimals = VAULT_DECIMALS[vaultAddress]; + const underlyingTicker = mapToUnderlying(utils.formatSymbol(vaultType)); + const tvlUSD = await getVaultTVL(chain, vaultType, vaultDecimals); + const apy = await getVaultAPY(vaultAddress, chain); + + if (tvlUSD !== undefined && apy !== undefined) { + pools.push({ + pool: `${vaultAddress}-${chain}`, + chain: utils.formatChain(chain), + project: 'stream-finance', + symbol: underlyingTicker, + tvlUsd: Number(tvlUSD.toFixed(2)), + apyBase: Number(apy.toFixed(2)), + underlyingTokens: [ADDRESSES[chain].underlyingTokens[vaultType]], + poolMeta: utils.formatSymbol(vaultType) + }); + } + + } catch (error) { + console.error(`Error processing vault ${vaultType} on ${chain}:`, error.message); + } + } + } + + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.streamprotocol.money' +}; diff --git a/src/adaptors/stride/index.js b/src/adaptors/stride/index.js new file mode 100644 index 0000000000..313eaab417 --- /dev/null +++ b/src/adaptors/stride/index.js @@ -0,0 +1,39 @@ +const utils = require('../utils'); + +const getPoolSymbol = (entry) => { + // stATOM/ATOM -> stATOM-ATOM + return entry.poolName.split('/').join('-'); +}; + +const main = async () => { + const data = await utils.getData('https://app.stride.zone/api/pool-gauges'); + + const pools = []; + let uniqueIds = []; + for (const entry of data) { + if (!entry.poolId) continue; + if (uniqueIds.includes(entry.poolId)) continue; + uniqueIds.push(entry.poolId); + const symbol = getPoolSymbol(entry); + + pools.push({ + pool: `${entry.poolId}-${entry.gaugeId}-${entry.token}`, + chain: utils.formatChain('Stride'), + project: 'stride', + symbol: utils.formatSymbol(symbol), + poolMeta: `${entry.lockupDuration} day(s)`, + tvlUsd: entry.tvl, + apy: entry.apr, + }); + } + + return pools.filter((pool) => { + return utils.keepFinite(pool); + }); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.stride.zone', +}; // npm run test --adapter=stride diff --git a/src/adaptors/strike/abi.js b/src/adaptors/strike/abi.js new file mode 100644 index 0000000000..cceeff87c9 --- /dev/null +++ b/src/adaptors/strike/abi.js @@ -0,0 +1,3851 @@ +module.exports = { + ercDelegator: [ + { + inputs: [], + payable: false, + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "cashPrior", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "interestAccumulated", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "borrowIndex", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "totalBorrows", + type: "uint256" + } + ], + name: "AccrueInterest", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Approval", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "borrower", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "borrowAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "accountBorrows", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "totalBorrows", + type: "uint256" + } + ], + name: "Borrow", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "error", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "info", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "detail", + type: "uint256" + } + ], + name: "Failure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "liquidator", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "borrower", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "repayAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "seizeTokens", + type: "uint256" + } + ], + name: "LiquidateBorrow", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "minter", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "mintAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "mintTokens", + type: "uint256" + } + ], + name: "Mint", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldAdmin", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newAdmin", + type: "address" + } + ], + name: "NewAdmin", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract ComptrollerInterface", + name: "oldComptroller", + type: "address" + }, + { + indexed: false, + internalType: "contract ComptrollerInterface", + name: "newComptroller", + type: "address" + } + ], + name: "NewComptroller", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract InterestRateModel", + name: "oldInterestRateModel", + type: "address" + }, + { + indexed: false, + internalType: "contract InterestRateModel", + name: "newInterestRateModel", + type: "address" + } + ], + name: "NewMarketInterestRateModel", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldPendingAdmin", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newPendingAdmin", + type: "address" + } + ], + name: "NewPendingAdmin", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldReserveFactorMantissa", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newReserveFactorMantissa", + type: "uint256" + } + ], + name: "NewReserveFactor", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "redeemer", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "redeemAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "redeemTokens", + type: "uint256" + } + ], + name: "Redeem", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "payer", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "borrower", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "repayAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "accountBorrows", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "totalBorrows", + type: "uint256" + } + ], + name: "RepayBorrow", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "benefactor", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "addAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newTotalReserves", + type: "uint256" + } + ], + name: "ReservesAdded", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "admin", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "reduceAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newTotalReserves", + type: "uint256" + } + ], + name: "ReservesReduced", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Transfer", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "guardian", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "reserveAddress", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "reduceAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newTotalReserves", + type: "uint256" + } + ], + name: "TransferReserves", + type: "event" + }, + { + constant: false, + inputs: [], + name: "_acceptAdmin", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "addAmount", + type: "uint256" + } + ], + name: "_addReserves", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "bytes", + name: "data", + type: "bytes" + } + ], + name: "_becomeImplementation", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "reduceAmount", + type: "uint256" + } + ], + name: "_reduceReserves", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [], + name: "_resignImplementation", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract ComptrollerInterface", + name: "newComptroller", + type: "address" + } + ], + name: "_setComptroller", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract InterestRateModel", + name: "newInterestRateModel", + type: "address" + } + ], + name: "_setInterestRateModel", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address payable", + name: "newPendingAdmin", + type: "address" + } + ], + name: "_setPendingAdmin", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "newReserveFactorMantissa", + type: "uint256" + } + ], + name: "_setReserveFactor", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "reduceAmount", + type: "uint256" + } + ], + name: "_transferReserves", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "accrualBlockNumber", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "accrueInterest", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "admin", + outputs: [ + { + internalType: "address payable", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "owner", + type: "address" + }, + { + internalType: "address", + name: "spender", + type: "address" + } + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "spender", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "owner", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "owner", + type: "address" + } + ], + name: "balanceOfUnderlying", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "borrowAmount", + type: "uint256" + } + ], + name: "borrow", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "borrowBalanceCurrent", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "borrowBalanceStored", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "borrowIndex", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "borrowRatePerBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "comptroller", + outputs: [ + { + internalType: "contract ComptrollerInterface", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "exchangeRateCurrent", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "exchangeRateStored", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getAccountSnapshot", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "getCash", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "implementation", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "underlying_", + type: "address" + }, + { + internalType: "contract ComptrollerInterface", + name: "comptroller_", + type: "address" + }, + { + internalType: "contract InterestRateModel", + name: "interestRateModel_", + type: "address" + }, + { + internalType: "uint256", + name: "initialExchangeRateMantissa_", + type: "uint256" + }, + { + internalType: "string", + name: "name_", + type: "string" + }, + { + internalType: "string", + name: "symbol_", + type: "string" + }, + { + internalType: "uint8", + name: "decimals_", + type: "uint8" + } + ], + name: "initialize", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract ComptrollerInterface", + name: "comptroller_", + type: "address" + }, + { + internalType: "contract InterestRateModel", + name: "interestRateModel_", + type: "address" + }, + { + internalType: "uint256", + name: "initialExchangeRateMantissa_", + type: "uint256" + }, + { + internalType: "string", + name: "name_", + type: "string" + }, + { + internalType: "string", + name: "symbol_", + type: "string" + }, + { + internalType: "uint8", + name: "decimals_", + type: "uint8" + } + ], + name: "initialize", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "interestRateModel", + outputs: [ + { + internalType: "contract InterestRateModel", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "isSToken", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "repayAmount", + type: "uint256" + }, + { + internalType: "contract STokenInterface", + name: "sTokenCollateral", + type: "address" + } + ], + name: "liquidateBorrow", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "mintAmount", + type: "uint256" + } + ], + name: "mint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingAdmin", + outputs: [ + { + internalType: "address payable", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "protocolSeizeShareMantissa", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "redeemTokens", + type: "uint256" + } + ], + name: "redeem", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "redeemAmount", + type: "uint256" + } + ], + name: "redeemUnderlying", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "repayAmount", + type: "uint256" + } + ], + name: "repayBorrow", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "repayAmount", + type: "uint256" + } + ], + name: "repayBorrowBehalf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "reserveFactorMantissa", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "liquidator", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "seizeTokens", + type: "uint256" + } + ], + name: "seize", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "supplyRatePerBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalBorrows", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [], + name: "totalBorrowsCurrent", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalReserves", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "dst", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "src", + type: "address" + }, + { + internalType: "address", + name: "dst", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "underlying", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + } + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "action", + type: "string" + }, + { + indexed: false, + internalType: "bool", + name: "pauseState", + type: "bool" + } + ], + name: "ActionPaused", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "string", + name: "action", + type: "string" + }, + { + indexed: false, + internalType: "bool", + name: "pauseState", + type: "bool" + } + ], + name: "ActionPaused", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "contributor", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "newStrikeSpeed", + type: "uint256" + } + ], + name: "ContributorStrikeSpeedUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "borrower", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "strikeDelta", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "strikeBorrowIndex", + type: "uint256" + } + ], + name: "DistributedBorrowerStrike", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "supplier", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "strikeDelta", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "strikeSupplyIndex", + type: "uint256" + } + ], + name: "DistributedSupplierStrike", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "error", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "info", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "detail", + type: "uint256" + } + ], + name: "Failure", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "account", + type: "address" + } + ], + name: "MarketEntered", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "account", + type: "address" + } + ], + name: "MarketExited", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + } + ], + name: "MarketListed", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "bool", + name: "isStriked", + type: "bool" + } + ], + name: "MarketStriked", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldCloseFactorMantissa", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newCloseFactorMantissa", + type: "uint256" + } + ], + name: "NewCloseFactor", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "oldCollateralFactorMantissa", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newCollateralFactorMantissa", + type: "uint256" + } + ], + name: "NewCollateralFactor", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldLiquidationIncentiveMantissa", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newLiquidationIncentiveMantissa", + type: "uint256" + } + ], + name: "NewLiquidationIncentive", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldMaxAssets", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newMaxAssets", + type: "uint256" + } + ], + name: "NewMaxAssets", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldPauseGuardian", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newPauseGuardian", + type: "address" + } + ], + name: "NewPauseGuardian", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "contract PriceOracle", + name: "oldPriceOracle", + type: "address" + }, + { + indexed: false, + internalType: "contract PriceOracle", + name: "newPriceOracle", + type: "address" + } + ], + name: "NewPriceOracle", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldReserveGuardian", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newReserveGuardian", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "oldReserveAddress", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newReserveAddress", + type: "address" + } + ], + name: "NewReserveGuardian", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldStrikeRate", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newStrikeRate", + type: "uint256" + } + ], + name: "NewStrikeRate", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldStrkStaking", + type: "address" + }, + { + indexed: false, + internalType: "address", + name: "newStrkStaking", + type: "address" + } + ], + name: "NewStrkStakingInfo", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "newSpeed", + type: "uint256" + } + ], + name: "StrikeBorrowSpeedUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "recipient", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "StrikeGranted", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "newSpeed", + type: "uint256" + } + ], + name: "StrikeSpeedUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "newSpeed", + type: "uint256" + } + ], + name: "StrikeSupplySpeedUpdated", + type: "event" + }, + { + constant: false, + inputs: [ + { + internalType: "contract Unitroller", + name: "unitroller", + type: "address" + } + ], + name: "_become", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "_borrowGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + } + ], + name: "_dropStrikeMarket", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "recipient", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "_grantSTRK", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "_mintGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + internalType: "bool", + name: "state", + type: "bool" + } + ], + name: "_setBorrowPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "newCloseFactorMantissa", + type: "uint256" + } + ], + name: "_setCloseFactor", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + internalType: "uint256", + name: "newCollateralFactorMantissa", + type: "uint256" + } + ], + name: "_setCollateralFactor", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "contributor", + type: "address" + }, + { + internalType: "uint256", + name: "strikeSpeed", + type: "uint256" + } + ], + name: "_setContributorStrikeSpeed", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "newLiquidationIncentiveMantissa", + type: "uint256" + } + ], + name: "_setLiquidationIncentive", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "uint256", + name: "newMaxAssets", + type: "uint256" + } + ], + name: "_setMaxAssets", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract SToken", + name: "sToken", + type: "address" + }, + { + internalType: "bool", + name: "state", + type: "bool" + } + ], + name: "_setMintPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "newPauseGuardian", + type: "address" + } + ], + name: "_setPauseGuardian", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract PriceOracle", + name: "newOracle", + type: "address" + } + ], + name: "_setPriceOracle", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address payable", + name: "newReserveGuardian", + type: "address" + }, + { + internalType: "address payable", + name: "newReserveAddress", + type: "address" + } + ], + name: "_setReserveInfo", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "bool", + name: "state", + type: "bool" + } + ], + name: "_setSeizePaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract SToken[]", + name: "sToken", + type: "address[]" + }, + { + internalType: "uint256[]", + name: "supplySpeeds", + type: "uint256[]" + }, + { + internalType: "uint256[]", + name: "borrowSpeeds", + type: "uint256[]" + } + ], + name: "_setStrikeSpeeds", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "newStrkStaking", + type: "address" + } + ], + name: "_setStrkStakingInfo", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "bool", + name: "state", + type: "bool" + } + ], + name: "_setTransferPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "contract SToken", + name: "sToken", + type: "address" + } + ], + name: "_supportMarket", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "accountAssets", + outputs: [ + { + internalType: "contract SToken", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "admin", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "allMarkets", + outputs: [ + { + internalType: "contract SToken", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "borrowAmount", + type: "uint256" + } + ], + name: "borrowAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "borrowGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "borrowAmount", + type: "uint256" + } + ], + name: "borrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "user", + type: "address" + } + ], + name: "canClaimStrikeBySuppling", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + }, + { + internalType: "contract SToken", + name: "sToken", + type: "address" + } + ], + name: "checkMembership", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address[]", + name: "holders", + type: "address[]" + }, + { + internalType: "contract SToken[]", + name: "sTokens", + type: "address[]" + }, + { + internalType: "bool", + name: "borrowers", + type: "bool" + }, + { + internalType: "bool", + name: "suppliers", + type: "bool" + } + ], + name: "claimStrike", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "holder", + type: "address" + } + ], + name: "claimStrike", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "holder", + type: "address" + }, + { + internalType: "contract SToken[]", + name: "sTokens", + type: "address[]" + } + ], + name: "claimStrike", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "closeFactorMantissa", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "comptrollerImplementation", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address[]", + name: "sTokens", + type: "address[]" + } + ], + name: "enterMarkets", + outputs: [ + { + internalType: "uint256[]", + name: "", + type: "uint256[]" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sTokenAddress", + type: "address" + } + ], + name: "exitMarket", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getAccountLiquidity", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "getAllMarkets", + outputs: [ + { + internalType: "contract SToken[]", + name: "", + type: "address[]" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getAssetsIn", + outputs: [ + { + internalType: "contract SToken[]", + name: "", + type: "address[]" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "getBlockNumber", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + }, + { + internalType: "address", + name: "sTokenModify", + type: "address" + }, + { + internalType: "uint256", + name: "redeemTokens", + type: "uint256" + }, + { + internalType: "uint256", + name: "borrowAmount", + type: "uint256" + } + ], + name: "getHypotheticalAccountLiquidity", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "getSTRKAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "isComptroller", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "lastContributorBlock", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sTokenBorrowed", + type: "address" + }, + { + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + internalType: "address", + name: "liquidator", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "repayAmount", + type: "uint256" + } + ], + name: "liquidateBorrowAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sTokenBorrowed", + type: "address" + }, + { + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + internalType: "address", + name: "liquidator", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "actualRepayAmount", + type: "uint256" + }, + { + internalType: "uint256", + name: "seizeTokens", + type: "uint256" + } + ], + name: "liquidateBorrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "sTokenBorrowed", + type: "address" + }, + { + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + internalType: "uint256", + name: "actualRepayAmount", + type: "uint256" + } + ], + name: "liquidateCalculateSeizeTokens", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "liquidationIncentiveMantissa", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "markets", + outputs: [ + { + internalType: "bool", + name: "isListed", + type: "bool" + }, + { + internalType: "uint256", + name: "collateralFactorMantissa", + type: "uint256" + }, + { + internalType: "bool", + name: "isStriked", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "maxAssets", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "minter", + type: "address" + }, + { + internalType: "uint256", + name: "mintAmount", + type: "uint256" + } + ], + name: "mintAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "mintGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "minter", + type: "address" + }, + { + internalType: "uint256", + name: "actualMintAmount", + type: "uint256" + }, + { + internalType: "uint256", + name: "mintTokens", + type: "uint256" + } + ], + name: "mintVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "oracle", + outputs: [ + { + internalType: "contract PriceOracle", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pauseGuardian", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingAdmin", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "pendingComptrollerImplementation", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "redeemer", + type: "address" + }, + { + internalType: "uint256", + name: "redeemTokens", + type: "uint256" + } + ], + name: "redeemAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "redeemer", + type: "address" + }, + { + internalType: "uint256", + name: "redeemAmount", + type: "uint256" + }, + { + internalType: "uint256", + name: "redeemTokens", + type: "uint256" + } + ], + name: "redeemVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "payer", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "repayAmount", + type: "uint256" + } + ], + name: "repayBorrowAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "payer", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "actualRepayAmount", + type: "uint256" + }, + { + internalType: "uint256", + name: "borrowerIndex", + type: "uint256" + } + ], + name: "repayBorrowVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "reserveAddress", + outputs: [ + { + internalType: "address payable", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "reserveGuardian", + outputs: [ + { + internalType: "address payable", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + internalType: "address", + name: "sTokenBorrowed", + type: "address" + }, + { + internalType: "address", + name: "liquidator", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "seizeTokens", + type: "uint256" + } + ], + name: "seizeAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "seizeGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sTokenCollateral", + type: "address" + }, + { + internalType: "address", + name: "sTokenBorrowed", + type: "address" + }, + { + internalType: "address", + name: "liquidator", + type: "address" + }, + { + internalType: "address", + name: "borrower", + type: "address" + }, + { + internalType: "uint256", + name: "seizeTokens", + type: "uint256" + } + ], + name: "seizeVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeAccrued", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeBorrowSpeeds", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeBorrowState", + outputs: [ + { + internalType: "uint224", + name: "index", + type: "uint224" + }, + { + internalType: "uint32", + name: "block", + type: "uint32" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + }, + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeBorrowerIndex", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "strikeClaimThreshold", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeContributorSpeeds", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "strikeInitialIndex", + outputs: [ + { + internalType: "uint224", + name: "", + type: "uint224" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "strikeRate", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeSpeeds", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + }, + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeSupplierIndex", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeSupplySpeeds", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "strikeSupplyState", + outputs: [ + { + internalType: "uint224", + name: "index", + type: "uint224" + }, + { + internalType: "uint32", + name: "block", + type: "uint32" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: true, + inputs: [], + name: "strkStaking", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "src", + type: "address" + }, + { + internalType: "address", + name: "dst", + type: "address" + }, + { + internalType: "uint256", + name: "transferTokens", + type: "uint256" + } + ], + name: "transferAllowed", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: true, + inputs: [], + name: "transferGuardianPaused", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + payable: false, + stateMutability: "view", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "sToken", + type: "address" + }, + { + internalType: "address", + name: "src", + type: "address" + }, + { + internalType: "address", + name: "dst", + type: "address" + }, + { + internalType: "uint256", + name: "transferTokens", + type: "uint256" + } + ], + name: "transferVerify", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + }, + { + constant: false, + inputs: [ + { + internalType: "address", + name: "contributor", + type: "address" + } + ], + name: "updateContributorRewards", + outputs: [], + payable: false, + stateMutability: "nonpayable", + type: "function" + } + ], +}; diff --git a/src/adaptors/strike/index.js b/src/adaptors/strike/index.js new file mode 100755 index 0000000000..9911c67a24 --- /dev/null +++ b/src/adaptors/strike/index.js @@ -0,0 +1,235 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('../strike/abi'); + +const COMPTROLLER_ADDRESS = '0xe2e17b2CBbf48211FA7eB8A875360e5e39bA2602'; +const CHAIN = 'ethereum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'strikeSupplySpeeds'; +const REWARD_SPEED_BORROW = 'strikeBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'strike'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'STRK', + address: '0x74232704659ef37c08995e386A2E26cc27a8d7B1'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = + // for maker + underlyingTokens[i]?.toLowerCase() === + '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2' + ? 'MKR' + : underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + } + return poolReturned; + }); + + return pools.filter((p) => ![].includes(p.pool)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.strike.org/', +}; diff --git a/src/adaptors/struct-finance/index.js b/src/adaptors/struct-finance/index.js new file mode 100644 index 0000000000..2f01835feb --- /dev/null +++ b/src/adaptors/struct-finance/index.js @@ -0,0 +1,173 @@ +const axios = require('axios'); +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); +const { apy: gmxApy } = require('../gmx-v1-perps/index.js'); + +const USDC_TOKEN_ADDRESS = '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e'; +const BTCB_TOKEN_ADDRESS = '0x152b9d0FdC40C096757F570A51E494bd4b943E50'; +const FSGLP_TOKEN_ADDRESS = '0x9e295B5B976a184B14aD8cd72413aD846C299660'; + +const structSubgraphUrl = + 'https://subgraph.satsuma-prod.com/0598bbca8a6d/structfinance/struct-finance-factory/api'; + +const tokens = { + [USDC_TOKEN_ADDRESS]: { + project: 'struct-finance', + symbol: 'USDC', + chain: utils.formatChain('avax'), + underlyingTokens: [FSGLP_TOKEN_ADDRESS], + }, + [BTCB_TOKEN_ADDRESS]: { + project: 'struct-finance', + symbol: 'BTC.b', + chain: utils.formatChain('avax'), + underlyingTokens: [FSGLP_TOKEN_ADDRESS], + }, +}; + +// percentages are scaled by 10 ** 4 +const scalingFactor = 10 ** 4; + +// returns tranches sorted by the highest hurdle (senior) rate available for a given token +const qGetHighestSeniorRateForOpenTrancheToken = gql` + query GetHighestSeniorRateForOpenTrancheToken($tokenAddress: Bytes) { + trancheCreateds( + orderDirection: desc + orderBy: product__hurdleRate + where: { + and: [ + { trancheType: "0" } + { tokenAddress: $tokenAddress } + { product_: { status: 0 } } + ] + } + ) { + id + trancheType + tokenAddress + product { + id + hurdleRate + tranches { + senior { + totalDeposited + } + } + } + } + } +`; + +// returns tranches sorted by the highest junior rate (lowest hurdle rate) available for a given token +const qGetHighestJuniorRateForOpenTrancheToken = gql` + query GetHighestJuniorRateForOpenTrancheToken($tokenAddress: Bytes) { + trancheCreateds( + orderDirection: asc + orderBy: product__hurdleRate + where: { + and: [ + { trancheType: "1" } + { tokenAddress: $tokenAddress } + { product_: { status: 0 } } + ] + } + ) { + id + trancheType + tokenAddress + product { + id + hurdleRate + tranches { + junior { + totalDeposited + } + } + } + } + } +`; + +async function getTrancheTokenInfo(tokenAddress, glpApy, tokenInfo) { + const { trancheCreateds: seniorTranches } = await request( + structSubgraphUrl, + qGetHighestSeniorRateForOpenTrancheToken, + { + tokenAddress, + } + ); + + const { trancheCreateds: juniorTranches } = await request( + structSubgraphUrl, + qGetHighestJuniorRateForOpenTrancheToken, + { + tokenAddress, + } + ); + + let tokenDeposits = 0; + let highestJuniorRate = 0; + let highestSeniorRate = 0; + if (seniorTranches.length !== 0) { + highestSeniorRate = Number(seniorTranches[0].product.hurdleRate); + tokenDeposits += seniorTranches.reduce(tabulateTokenDeposits, 0); + } + if (juniorTranches.length !== 0) { + // junior tranche rate is 2x the glp rate minus the senior tranche rate + highestJuniorRate = + glpApy * 2 - Number(juniorTranches[0].product.hurdleRate); + tokenDeposits += juniorTranches.reduce(tabulateTokenDeposits, 0); + } + + let highestApr = + highestSeniorRate > highestJuniorRate + ? highestSeniorRate + : highestJuniorRate; + + const highestAprHuman = highestApr / scalingFactor; + const tokenDepositsHuman = tokenDeposits / 10 ** 18; + const tvlUsd = tokenDepositsHuman * tokenInfo.price; + + const tokenData = tokens[tokenAddress]; + Object.assign(tokenData, { + apy: highestAprHuman, + pool: `${tokenAddress}-avalanche`.toLowerCase(), + tvlUsd, + }); + return tokenData; +} + +function tabulateTokenDeposits(acc, tranche) { + return ( + acc + Number(Object.values(tranche.product.tranches)[0].totalDeposited) + ); +} + +async function getTokenPrices() { + const priceKeys = Object.keys(tokens) + .map((i) => `avax:${i}`) + .join(','); + + return (await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`)) + .data.coins; +} + +async function getTrancheTokenAprs() { + const [, , , glpAvax] = await gmxApy(); + const tokenPrices = await getTokenPrices(); + const glpApyBaseScaled = Math.floor(glpAvax.apyBase * scalingFactor); + const trancheTokenPromises = Object.entries(tokens).map( + async ([tokenAddress, token]) => { + const tokenInfo = tokenPrices[`avax:${tokenAddress}`]; + return getTrancheTokenInfo(tokenAddress, glpApyBaseScaled, tokenInfo); + } + ); + const tokenAprs = await Promise.all(trancheTokenPromises); + return tokenAprs; +} + +module.exports = { + timetravel: false, + apy: getTrancheTokenAprs, + url: 'https://app.struct.fi', +}; diff --git a/src/adaptors/strx-finance/index.js b/src/adaptors/strx-finance/index.js new file mode 100644 index 0000000000..e8d47044a1 --- /dev/null +++ b/src/adaptors/strx-finance/index.js @@ -0,0 +1,57 @@ +const utils = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const STAKING_ADDRESS = 'TGrdCu9fu8csFmQptVE25fDzFmPU9epamH'; +const REVENUE_ADDRESS = 'TWisShDfhZGXLy1s5uoWjyyucSKwfkohu7'; + +const getCurrentStake = async () => { + const postdata = { + "contract_address": "414b8a2c619bccb710206b3d11e28dce62d8d72a8b", + "owner_address": "4128fb7be6c95a27217e0e0bff42ca50cd9461cc9f", + "function_selector": "reservedTRX()", + "parameter": "", + "call_value": 0 + }; + const result = await utils.getData('https://api.trongrid.io/wallet/triggerconstantcontract', postdata); + return parseInt(result.constant_result[0], 16); +}; + +const getRevenueToday = async () => { + const startTimestamp = Date.now() - 86400000; // 24 hours ago + const url = `https://apilist.tronscan.org/api/transfer?sort=-timestamp&limit=20&start_timestamp=${startTimestamp}&token=_&address=${REVENUE_ADDRESS}`; + let totalRevenue = 0; + let startFrom = 0; + while (true) { + const { data } = await fetchURL(`${url}&start=${startFrom}`); + const transfers = data.data; + if (transfers.length === 0) { + break; + } + totalRevenue += transfers.reduce((sum, transfer) => sum + transfer.amount, 0); + startFrom += 20; // start from next 20th element + } + return totalRevenue; +}; + +const poolsFunction = async () => { + const [revenue, totalStake, dataTvl] = await Promise.all([ + getRevenueToday(), + getCurrentStake(), + utils.getData('https://api.llama.fi/tvl/strx-finance') + ]); + const dailyAPY = ((revenue / totalStake) * 365) * 100; + return [{ + pool: STAKING_ADDRESS, + chain: utils.formatChain('tron'), + project: 'strx-finance', + symbol: utils.formatSymbol('TRX'), + tvlUsd: dataTvl, + apyBase: dailyAPY > 0 ? Number(dailyAPY) : 0 + }]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: "https://app.strx.finance", +}; diff --git a/src/adaptors/sturdy-v2/abi.js b/src/adaptors/sturdy-v2/abi.js new file mode 100644 index 0000000000..631bbbb2fb --- /dev/null +++ b/src/adaptors/sturdy-v2/abi.js @@ -0,0 +1,287 @@ +module.exports = { + DataProviderAbi: [ + { + inputs: [], + name: 'getStrategies', + outputs: [ + { + components: [ + { internalType: 'address', name: 'deployedAt', type: 'address' }, + { internalType: 'address', name: 'pair', type: 'address' }, + { + components: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'string', name: 'assetSymbol', type: 'string' }, + { + internalType: 'uint256', + name: 'assetDecimals', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'string', + name: 'collateralSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'collateralDecimals', + type: 'uint256', + }, + { + internalType: 'address', + name: 'rateContract', + type: 'address', + }, + { internalType: 'address', name: 'oracle', type: 'address' }, + { + internalType: 'uint256', + name: 'depositLimit', + type: 'uint256', + }, + { internalType: 'uint64', name: 'ratePerSec', type: 'uint64' }, + { + internalType: 'uint64', + name: 'fullUtilizationRate', + type: 'uint64', + }, + { + internalType: 'uint32', + name: 'feeToProtocolRate', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'maxOacleDeviation', + type: 'uint32', + }, + { + internalType: 'uint256', + name: 'lowExchangeRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'highExchangeRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'maxLTV', type: 'uint256' }, + { + internalType: 'uint256', + name: 'protocolLiquidationFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalAsset', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { internalType: 'uint256', name: 'version', type: 'uint256' }, + ], + internalType: 'struct IAggregatorDataProvider.StrategyPairData', + name: 'pairData', + type: 'tuple', + }, + ], + internalType: 'struct IAggregatorDataProvider.StrategyData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVaults', + outputs: [ + { + components: [ + { internalType: 'address', name: 'deployedAt', type: 'address' }, + { internalType: 'bool', name: 'isShutdown', type: 'bool' }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'string', name: 'assetSymbol', type: 'string' }, + { internalType: 'uint256', name: 'assetDecimals', type: 'uint256' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'uint256', name: 'totalAssets', type: 'uint256' }, + { internalType: 'uint256', name: 'totalDebt', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'maxDebt', type: 'uint256' }, + { + internalType: 'uint256', + name: 'currentDebt', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'string', + name: 'collateralSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'collateralDecimals', + type: 'uint256', + }, + { + components: [ + { + internalType: 'address', + name: 'deployedAt', + type: 'address', + }, + { internalType: 'address', name: 'pair', type: 'address' }, + { + components: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + { + internalType: 'string', + name: 'assetSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'assetDecimals', + type: 'uint256', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'string', + name: 'collateralSymbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'collateralDecimals', + type: 'uint256', + }, + { + internalType: 'address', + name: 'rateContract', + type: 'address', + }, + { + internalType: 'address', + name: 'oracle', + type: 'address', + }, + { + internalType: 'uint256', + name: 'depositLimit', + type: 'uint256', + }, + { + internalType: 'uint64', + name: 'ratePerSec', + type: 'uint64', + }, + { + internalType: 'uint64', + name: 'fullUtilizationRate', + type: 'uint64', + }, + { + internalType: 'uint32', + name: 'feeToProtocolRate', + type: 'uint32', + }, + { + internalType: 'uint32', + name: 'maxOacleDeviation', + type: 'uint32', + }, + { + internalType: 'uint256', + name: 'lowExchangeRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'highExchangeRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'maxLTV', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolLiquidationFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalAsset', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrow', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'version', + type: 'uint256', + }, + ], + internalType: + 'struct IAggregatorDataProvider.StrategyPairData', + name: 'pairData', + type: 'tuple', + }, + ], + internalType: 'struct IAggregatorDataProvider.StrategyData', + name: 'strategyData', + type: 'tuple', + }, + ], + internalType: + 'struct IAggregatorDataProvider.VaultStrategyData[]', + name: 'vaultStrategyData', + type: 'tuple[]', + }, + ], + internalType: 'struct IAggregatorDataProvider.AggregatedVaultData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/sturdy-v2/index.js b/src/adaptors/sturdy-v2/index.js new file mode 100644 index 0000000000..fe458008e4 --- /dev/null +++ b/src/adaptors/sturdy-v2/index.js @@ -0,0 +1,81 @@ +const sdk = require('@defillama/sdk'); +const { BigNumber } = require('bignumber.js'); +const { DataProviderAbi } = require('./abi'); +const utils = require('../utils'); + +const BIG_10 = new BigNumber('10'); + +// DataProvider Addresses +const config = { + ethereum: '0x69764E3e0671747A7768A1C1AfB7C0C39868CC9e', + mode: '0xF0382A9Eca5276d7B4BbcC503e4159C046c120ec', +}; + +const aggregators = async () => { + const apiData = await utils.getData( + `https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/v2Aggregators` + ); + + // const subgraphData = await request(sturdy_v2_subgraph, query); + // const aggregators = subgraphData.aggregators as V2AggregatorSubgraphData[]; + + const aggregators = (await Promise.all( + Object.keys(config) + .map(async (chain) => { + const chainAggregators = ( + await sdk.api.abi.call({ + target: config[chain], + abi: DataProviderAbi.find((m) => m.name === 'getVaults'), + chain, + }) + ).output; + + return chainAggregators.map((e) => { + return { + ...e, + chainName: chain, + }; + }); + }) + )).flat(); + + // fetch token prices + const assetContracts = aggregators.map((a) => a.asset); + const coins = aggregators.map((a) => `${a.chainName}:${a.asset}`); + const prices = (await utils.getPrices(coins)).pricesByAddress; + + return aggregators.map((a, index) => { + const { chainName, deployedAt: address, name, totalAssets, asset, assetDecimals, assetSymbol } = a; + + const tvl = new BigNumber(totalAssets) + .dividedBy(BIG_10.pow(assetDecimals)) + .times(prices[assetContracts[index].toLowerCase()]); + + const apy = apiData.find( + (e) => e.address.toLowerCase() === address.toLowerCase() + ); + const apyBase = apy?.baseAPY * 100 || 0; + const apyReward = apy?.rewardsAPY * 100 || 0; + const rewardTokens = apy?.rewardTokens || []; + + return { + pool: address, + chain: chainName, + project: 'sturdy-v2', + symbol: utils.formatSymbol(assetSymbol), + tvlUsd: tvl.toNumber(), + apyBase, + apyReward, + rewardTokens, + url: `https://v2.sturdy.finance/aggregators/${chainName}/${address}`, + underlyingTokens: [asset], + poolMeta: name, // aggregator name + }; + }).filter((a) => a.tvlUsd > 0).map(i => ({...i, pool: i.pool.toLowerCase()})); +}; + +module.exports = { + timetravel: false, + apy: aggregators, + url: 'https://v2.sturdy.finance/aggregators', +}; diff --git a/src/adaptors/sturdy/index.js b/src/adaptors/sturdy/index.js index bf6ea84014..a13de0d870 100644 --- a/src/adaptors/sturdy/index.js +++ b/src/adaptors/sturdy/index.js @@ -1,31 +1,46 @@ const utils = require('../utils'); const poolsFunction = async () => { - const ftmVaultData = await utils.getData('https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring'); - const ftmData = ftmVaultData.map(item => ({ - pool: item.address, - chain: utils.formatChain('fantom'), - project: 'sturdy', - symbol: utils.formatSymbol(item.tokens), - tvlUsd: item.tvl, - apy: item.base * 100, - }) + const ftmVaultData = await utils.getData( + 'https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring' ); + const ftmData = ftmVaultData.map((item) => ({ + pool: item.address, + chain: utils.formatChain('fantom'), + project: 'sturdy', + symbol: utils.formatSymbol(item.tokens), + tvlUsd: item.tvl, + apyBase: item.base * 100, + // borrow fields + apyBaseBorrow: item.borrowAPY * 100, + totalSupplyUsd: item.tvl, + totalBorrowUsd: item.totalBorrowUsd, + ltv: item.ltv, + })); - const ethVaultData = await utils.getData('https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring?chain=ethereum'); - const ethData = ethVaultData.map(item => ({ - pool: item.address, - chain: utils.formatChain('ethereum'), - project: 'sturdy', - symbol: utils.formatSymbol(item.tokens), - tvlUsd: item.tvl, - apy: item.base * 100, - }) + const ethVaultData = await utils.getData( + 'https://us-central1-stu-dashboard-a0ba2.cloudfunctions.net/getVaultMonitoring?chain=ethereum' ); + const ethData = ethVaultData.map((item) => ({ + pool: item.address, + chain: utils.formatChain('ethereum'), + project: 'sturdy', + symbol: utils.formatSymbol(item.tokens), + tvlUsd: item.tvl, + apyBase: item.base * 100, + apyReward: item.reward * 100, + rewardTokens: item.rewardTokens || [], + // borrow fields + apyBaseBorrow: item.borrowAPY * 100, + totalSupplyUsd: item.tvl, + totalBorrowUsd: item.totalBorrowUsd, + ltv: item.ltv, + })); return [...ftmData, ...ethData]; }; module.exports = { timetravel: false, apy: poolsFunction, -}; \ No newline at end of file + url: 'https://app.sturdy.finance/deposit', +}; diff --git a/src/adaptors/stusdt/index.js b/src/adaptors/stusdt/index.js new file mode 100644 index 0000000000..faa6a09a8b --- /dev/null +++ b/src/adaptors/stusdt/index.js @@ -0,0 +1,57 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const stUSDT = 'TThzxNRLrW2Brp9DcTQU8i4Wd9udCWEdZ3'; +const stUSDTEthereum = '0x25ec98773d7b4ced4cafab96a2a1c0945f145e10'; + +const apy = async () => { + const balanceTron = ( + await sdk.api.abi.call({ + chain: 'tron', + abi: 'erc20:totalSupply', + target: stUSDT, + }) + ).output; + + const balanceEthereum = ( + await sdk.api.abi.call({ + chain: 'ethereum', + abi: 'erc20:totalSupply', + target: stUSDTEthereum, + }) + ).output; + + const apys = await Promise.all( + ['stusdt/dashboard', 'ethereum/stusdt/dashboard'].map((i) => + axios.get(`https://api.stusdt.org/${i}`) + ) + ); + + return [ + { + pool: stUSDT, + chain: 'tron', + project: 'stusdt', + symbol: 'stusdt', + apy: apys[0].data.data.apy * 100, + tvlUsd: balanceTron / 1e18, + underlyingTokens: ['TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'], + url: 'https://stusdt.io/tron/?lang=en-US#/stake', + }, + { + pool: stUSDTEthereum, + chain: 'ethereum', + project: 'stusdt', + symbol: 'stusdt', + apy: apys[1].data.data.apy * 100, + tvlUsd: balanceEthereum / 1e18, + underlyingTokens: ['0xdAC17F958D2ee523a2206206994597C13D831ec7'], + url: 'https://stusdt.io/?lang=en-US#/stake', + }, + ]; +}; + +module.exports = { + apy, + url: 'test', +}; diff --git a/src/adaptors/superfund/constants.js b/src/adaptors/superfund/constants.js new file mode 100644 index 0000000000..5249a66548 --- /dev/null +++ b/src/adaptors/superfund/constants.js @@ -0,0 +1,1238 @@ +const CHAIN = 'base'; +const CHAIN_ID = 8453; +const VAULT = '0x10076ed296571cE4Fde5b1FDF0eB9014a880e47B'; +const USDC_TOKEN = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; + +const VAULT_ABI = [ + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'evc', type: 'address' }, + { internalType: 'address', name: 'balanceTracker', type: 'address' }, + { internalType: 'address', name: 'permit2', type: 'address' }, + { + internalType: 'bool', + name: 'isHarvestCoolDownCheckOn', + type: 'bool', + }, + ], + internalType: 'struct Shared.IntegrationsParams', + name: '_integrationsParams', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'eulerEarnVaultModule', + type: 'address', + }, + { internalType: 'address', name: 'rewardsModule', type: 'address' }, + { internalType: 'address', name: 'hooksModule', type: 'address' }, + { internalType: 'address', name: 'feeModule', type: 'address' }, + { internalType: 'address', name: 'strategyModule', type: 'address' }, + { + internalType: 'address', + name: 'withdrawalQueueModule', + type: 'address', + }, + ], + internalType: 'struct IEulerEarn.DeploymentParams', + name: '_deploymentParams', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AccessControlBadConfirmation', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'bytes32', name: 'neededRole', type: 'bytes32' }, + ], + name: 'AccessControlUnauthorizedAccount', + type: 'error', + }, + { inputs: [], name: 'CheckpointUnorderedInsertion', type: 'error' }, + { inputs: [], name: 'ControllerDisabled', type: 'error' }, + { inputs: [], name: 'ECDSAInvalidSignature', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'length', type: 'uint256' }], + name: 'ECDSAInvalidSignatureLength', + type: 'error', + }, + { + inputs: [{ internalType: 'bytes32', name: 's', type: 'bytes32' }], + name: 'ECDSAInvalidSignatureS', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'increasedSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'cap', type: 'uint256' }, + ], + name: 'ERC20ExceededSafeSupply', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'increasedSupply', type: 'uint256' }, + { internalType: 'uint256', name: 'cap', type: 'uint256' }, + ], + name: 'ERC20ExceededSafeSupply', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'approver', type: 'address' }], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'spender', type: 'address' }], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxDeposit', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxMint', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxRedeem', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxWithdraw', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'timepoint', type: 'uint256' }, + { internalType: 'uint48', name: 'clock', type: 'uint48' }, + ], + name: 'ERC5805FutureLookup', + type: 'error', + }, + { inputs: [], name: 'ERC6372InconsistentClock', type: 'error' }, + { inputs: [], name: 'EVC_InvalidAddress', type: 'error' }, + { inputs: [], name: 'InitialAllocationPointsZero', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'currentNonce', type: 'uint256' }, + ], + name: 'InvalidAccountNonce', + type: 'error', + }, + { inputs: [], name: 'InvalidAssetAddress', type: 'error' }, + { inputs: [], name: 'InvalidInitialization', type: 'error' }, + { inputs: [], name: 'InvalidSmearingPeriod', type: 'error' }, + { inputs: [], name: 'NotAuthorized', type: 'error' }, + { inputs: [], name: 'NotInitializing', type: 'error' }, + { + inputs: [ + { internalType: 'uint8', name: 'bits', type: 'uint8' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'SafeCastOverflowedUintDowncast', + type: 'error', + }, + { inputs: [], name: 'ViewReentrancy', type: 'error' }, + { + inputs: [{ internalType: 'uint256', name: 'expiry', type: 'uint256' }], + name: 'VotesExpiredSignature', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'delegator', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'fromDelegate', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'toDelegate', + type: 'address', + }, + ], + name: 'DelegateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'delegate', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousVotes', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newVotes', + type: 'uint256', + }, + ], + name: 'DelegateVotesChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'EIP712DomainChanged', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'version', + type: 'uint64', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, + ], + name: 'RoleAdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleRevoked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'EVC', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'uint256', name: '_allocationPoints', type: 'uint256' }, + ], + name: 'addStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'uint256', name: '_newPoints', type: 'uint256' }, + ], + name: 'adjustAllocationPoints', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_owner', type: 'address' }, + { internalType: 'address', name: '_spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_spender', type: 'address' }, + { internalType: 'uint256', name: '_value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'balanceForwarderEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'balanceTrackerAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_account', type: 'address' }, + { internalType: 'uint32', name: '_pos', type: 'uint32' }, + ], + name: 'checkpoints', + outputs: [ + { + components: [ + { internalType: 'uint48', name: '_key', type: 'uint48' }, + { internalType: 'uint208', name: '_value', type: 'uint208' }, + ], + internalType: 'struct Checkpoints.Checkpoint208', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'address', name: '_reward', type: 'address' }, + { internalType: 'address', name: '_recipient', type: 'address' }, + { internalType: 'bool', name: '_forfeitRecentReward', type: 'bool' }, + ], + name: 'claimStrategyReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'clock', + outputs: [{ internalType: 'uint48', name: '', type: 'uint48' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_delegatee', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_delegatee', type: 'address' }, + { internalType: 'uint256', name: '_nonce', type: 'uint256' }, + { internalType: 'uint256', name: '_expiry', type: 'uint256' }, + { internalType: 'uint8', name: '_v', type: 'uint8' }, + { internalType: 'bytes32', name: '_r', type: 'bytes32' }, + { internalType: 'bytes32', name: '_s', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'delegates', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assets', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'disableBalanceForwarder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'address', name: '_reward', type: 'address' }, + { internalType: 'bool', name: '_forfeitRecentReward', type: 'bool' }, + ], + name: 'disableRewardForStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'eip712Domain', + outputs: [ + { internalType: 'bytes1', name: 'fields', type: 'bytes1' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'version', type: 'string' }, + { internalType: 'uint256', name: 'chainId', type: 'uint256' }, + { internalType: 'address', name: 'verifyingContract', type: 'address' }, + { internalType: 'bytes32', name: 'salt', type: 'bytes32' }, + { internalType: 'uint256[]', name: 'extensions', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'enableBalanceForwarder', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'address', name: '_reward', type: 'address' }, + ], + name: 'enableRewardForStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'eulerEarnVaultModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'feeModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getEulerEarnSavingRate', + outputs: [ + { internalType: 'uint40', name: '', type: 'uint40' }, + { internalType: 'uint40', name: '', type: 'uint40' }, + { internalType: 'uint168', name: '', type: 'uint168' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getHooksConfig', + outputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint32', name: '', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_timepoint', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_account', type: 'address' }, + { internalType: 'uint256', name: '_timepoint', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'getRoleMember', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleMemberCount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleMembers', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_strategy', type: 'address' }], + name: 'getStrategy', + outputs: [ + { + components: [ + { internalType: 'uint120', name: 'allocated', type: 'uint120' }, + { internalType: 'uint96', name: 'allocationPoints', type: 'uint96' }, + { internalType: 'AmountCap', name: 'cap', type: 'uint16' }, + { + internalType: 'enum IEulerEarn.StrategyStatus', + name: 'status', + type: 'uint8', + }, + ], + internalType: 'struct IEulerEarn.Strategy', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'getVotes', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: '_role', type: 'bytes32' }, + { internalType: 'address', name: '_account', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'gulp', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'hooksModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'eulerEarnVaultOwner', + type: 'address', + }, + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'symbol', type: 'string' }, + { + internalType: 'uint256', + name: 'initialCashAllocationPoints', + type: 'uint256', + }, + { internalType: 'uint24', name: 'smearingPeriod', type: 'uint24' }, + ], + internalType: 'struct IEulerEarn.InitParams', + name: '_initParams', + type: 'tuple', + }, + ], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'interestAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'interestSmearingPeriod', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isCheckingHarvestCoolDown', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lastHarvestTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_account', type: 'address' }], + name: 'numCheckpoints', + outputs: [{ internalType: 'uint32', name: '', type: 'uint32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_strategy', type: 'address' }], + name: 'optInStrategyRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_strategy', type: 'address' }], + name: 'optOutStrategyRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'performanceFeeConfig', + outputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint96', name: '', type: 'uint96' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'permit2Address', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: '_strategies', type: 'address[]' }, + ], + name: 'rebalance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_shares', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_strategy', type: 'address' }], + name: 'removeStrategy', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: '_role', type: 'bytes32' }, + { internalType: 'address', name: '_callerConfirmation', type: 'address' }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '_index1', type: 'uint8' }, + { internalType: 'uint8', name: '_index2', type: 'uint8' }, + ], + name: 'reorderWithdrawalQueue', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: '_role', type: 'bytes32' }, + { internalType: 'address', name: '_account', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardsModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newFeeRecipient', type: 'address' }, + ], + name: 'setFeeRecipient', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_hooksTarget', type: 'address' }, + { internalType: 'uint32', name: '_hookedFns', type: 'uint32' }, + ], + name: 'setHooksConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint96', name: '_newFee', type: 'uint96' }], + name: 'setPerformanceFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_strategy', type: 'address' }, + { internalType: 'uint16', name: '_cap', type: 'uint16' }, + ], + name: 'setStrategyCap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token', type: 'address' }, + { internalType: 'address', name: '_recipient', type: 'address' }, + ], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'strategyModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_strategy', type: 'address' }], + name: 'toggleStrategyEmergencyStatus', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocated', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocationPoints', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssetsAllocatable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssetsDeposited', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_from', type: 'address' }, + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'updateInterestAccrued', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assets', type: 'uint256' }, + { internalType: 'address', name: '_receiver', type: 'address' }, + { internalType: 'address', name: '_owner', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawalQueue', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'withdrawalQueueModule', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { + CHAIN, + CHAIN_ID, + VAULT, + VAULT_ABI, + USDC_TOKEN +}; diff --git a/src/adaptors/superfund/index.js b/src/adaptors/superfund/index.js new file mode 100644 index 0000000000..26f655d2d8 --- /dev/null +++ b/src/adaptors/superfund/index.js @@ -0,0 +1,50 @@ +const sdk = require('@defillama/sdk'); +const { + CHAIN_ID, + VAULT, + VAULT_ABI, + CHAIN, + USDC_TOKEN, +} = require('./constants'); +const utils = require('../utils'); + +const SUPERFUND_API_URL = `https://api.funds.superlend.xyz/vaults/rate/${VAULT}/${CHAIN_ID}`; +const URL = 'https://funds.superlend.xyz/super-fund/base'; +const getApy = async () => { + const data = (await utils.getData(SUPERFUND_API_URL))?.data; + + const base_rate = data.base_apy; + const reward_rate = data.rewards_apy; + + const tvl = ( + await sdk.api.abi.call({ + target: VAULT, + abi: VAULT_ABI.find((m) => m.name === 'totalAssets'), + chain: CHAIN, + }) + ).output; + const tvlUsd = tvl / 10 ** 6; + + return [ + { + pool: `${VAULT}-${CHAIN}`, + chain: CHAIN, + project: 'superfund', + symbol: 'USDC', + tvlUsd, + apyBase: base_rate, + apyReward: reward_rate, + underlyingTokens: [USDC_TOKEN], + rewardTokens: reward_rate > 0 ? [USDC_TOKEN] : [], + url: URL, + }, + ]; +}; + +const apy = async () => { + return await getApy(); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/superlend/constants.js b/src/adaptors/superlend/constants.js new file mode 100644 index 0000000000..8f431d8802 --- /dev/null +++ b/src/adaptors/superlend/constants.js @@ -0,0 +1,1016 @@ +const poolAbi = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +const uiPoolDataProviderAbi = [ + { + inputs: [ + { + internalType: 'contract IEACAggregatorProxy', + name: '_networkBaseTokenPriceInUsdProxyAggregator', + type: 'address', + }, + { + internalType: 'contract IEACAggregatorProxy', + name: '_marketReferenceCurrencyPriceInUsdProxyAggregator', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ETH_CURRENCY_UNIT', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MKR_ADDRESS', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_bytes32', + type: 'bytes32', + }, + ], + name: 'bytes32ToString', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'getReservesData', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'underlyingAsset', + type: 'address', + }, + { + internalType: 'string', + name: 'name', + type: 'string', + }, + { + internalType: 'string', + name: 'symbol', + type: 'string', + }, + { + internalType: 'uint256', + name: 'decimals', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseLTVasCollateral', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationThreshold', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveLiquidationBonus', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'reserveFactor', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'borrowingEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'stableBorrowRateEnabled', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isActive', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + { + internalType: 'uint128', + name: 'liquidityIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowIndex', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'liquidityRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'variableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'stableBorrowRate', + type: 'uint128', + }, + { + internalType: 'uint40', + name: 'lastUpdateTimestamp', + type: 'uint40', + }, + { + internalType: 'address', + name: 'aTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'interestRateStrategyAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'availableLiquidity', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalPrincipalStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'averageStableRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableDebtLastUpdateTimestamp', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalScaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'priceInMarketReferenceCurrency', + type: 'uint256', + }, + { + internalType: 'address', + name: 'priceOracle', + type: 'address', + }, + { + internalType: 'uint256', + name: 'variableRateSlope1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'variableRateSlope2', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableRateSlope1', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableRateSlope2', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseStableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'baseVariableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'optimalUsageRatio', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'isPaused', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isSiloedBorrowing', + type: 'bool', + }, + { + internalType: 'uint128', + name: 'accruedToTreasury', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'unbacked', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'isolationModeTotalDebt', + type: 'uint128', + }, + { + internalType: 'bool', + name: 'flashLoanEnabled', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'debtCeiling', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'debtCeilingDecimals', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'eModeCategoryId', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'borrowCap', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'supplyCap', + type: 'uint256', + }, + { + internalType: 'uint16', + name: 'eModeLtv', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'eModeLiquidationThreshold', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'eModeLiquidationBonus', + type: 'uint16', + }, + { + internalType: 'address', + name: 'eModePriceSource', + type: 'address', + }, + { + internalType: 'string', + name: 'eModeLabel', + type: 'string', + }, + { + internalType: 'bool', + name: 'borrowableInIsolation', + type: 'bool', + }, + ], + internalType: 'struct IUiPoolDataProviderV3.AggregatedReserveData[]', + name: '', + type: 'tuple[]', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketReferenceCurrencyUnit', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'marketReferenceCurrencyPriceInUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'networkBaseTokenPriceInUsd', + type: 'int256', + }, + { + internalType: 'uint8', + name: 'networkBaseTokenPriceDecimals', + type: 'uint8', + }, + ], + internalType: 'struct IUiPoolDataProviderV3.BaseCurrencyInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + ], + name: 'getReservesList', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'provider', + type: 'address', + }, + { + internalType: 'address', + name: 'user', + type: 'address', + }, + ], + name: 'getUserReservesData', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'underlyingAsset', + type: 'address', + }, + { + internalType: 'uint256', + name: 'scaledATokenBalance', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'usageAsCollateralEnabledOnUser', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'stableBorrowRate', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'scaledVariableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'principalStableDebt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'stableBorrowLastUpdateTimestamp', + type: 'uint256', + }, + ], + internalType: 'struct IUiPoolDataProviderV3.UserReserveData[]', + name: '', + type: 'tuple[]', + }, + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'marketReferenceCurrencyPriceInUsdProxyAggregator', + outputs: [ + { + internalType: 'contract IEACAggregatorProxy', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'networkBaseTokenPriceInUsdProxyAggregator', + outputs: [ + { + internalType: 'contract IEACAggregatorProxy', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +const oracleAbi = [ + { + inputs: [ + { + internalType: 'address', + name: '_pyth', + type: 'address', + }, + { + internalType: 'bytes32', + name: '_priceId', + type: 'bytes32', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'description', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'getAnswer', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint80', + name: '_roundId', + type: 'uint80', + }, + ], + name: 'getRoundData', + outputs: [ + { + internalType: 'uint80', + name: 'roundId', + type: 'uint80', + }, + { + internalType: 'int256', + name: 'answer', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'startedAt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAt', + type: 'uint256', + }, + { + internalType: 'uint80', + name: 'answeredInRound', + type: 'uint80', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'getTimestamp', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestAnswer', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestRound', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestRoundData', + outputs: [ + { + internalType: 'uint80', + name: 'roundId', + type: 'uint80', + }, + { + internalType: 'int256', + name: 'answer', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'startedAt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAt', + type: 'uint256', + }, + { + internalType: 'uint80', + name: 'answeredInRound', + type: 'uint80', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'latestTimestamp', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'priceId', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pyth', + outputs: [ + { + internalType: 'contract IPyth', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes[]', + name: 'priceUpdateData', + type: 'bytes[]', + }, + ], + name: 'updateFeeds', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, +]; + +const CHAIN = 'etlk'; +const CHAIN_ID = 42793; +const PROTOCOL_DATA_PROVIDER = '0x99e8269dDD5c7Af0F1B3973A591b47E8E001BCac'; +const UI_POOL_DATA_PROVIDER = '0x9F9384Ef6a1A76AE1a95dF483be4b0214fda0Ef9'; +const PROVIDER_ADDRESS = '0x5ccF60c7E10547c5389E9cBFf543E5D0Db9F4feC'; + +const CAMPAIGN_ID_MAP = { + LBTC: '0x193d899fa6755af844f1760530adf99b66f731541edac24f07f175eccb2310d8', + WXTZ: '0xd4efe420526ee7d819398b324e35cace9aa79f9c3aadf93295cdf746b4d251be', + USDC: '0x49c6ed3ca10db9b36515da2052085dfb8b4863d30407d80705670fb2666150a9', + USDT: '0xe5282245f3abf855492ed9843bb25cd72899348872792fdb2698897f9781579e', + WBTC: '0x4d4d4fd27367894a1fa91e19576db99826267ecfa5be8181d2d6b2b128fe23ad', + MTBILL: '0x9b8132c65008c300f60fb4b91ebb5bd710c0c8a45546a871418bf246d78eea4b', + MBASIS: '0xd5cca8591d67180b9031f521d1858161918102f4d0c7cabd45907c65105bb16c', +}; + +const MERKLE_BASE_URL = + 'https://api.merkl.xyz/v4/campaigns/?chainId=CHAIN_ID&campaignId=CAMPAIGN_ID&withOpportunity=true'; + +const APPLE_REWARD_TOKEN = '0x6E9C1F88a960fE63387eb4b71BC525a9313d8461'; + +module.exports = { + poolAbi, + uiPoolDataProviderAbi, + oracleAbi, + CHAIN, + PROTOCOL_DATA_PROVIDER, + UI_POOL_DATA_PROVIDER, + PROVIDER_ADDRESS, + CHAIN_ID, + MERKLE_BASE_URL, + CAMPAIGN_ID_MAP, + APPLE_REWARD_TOKEN, +}; diff --git a/src/adaptors/superlend/index.js b/src/adaptors/superlend/index.js new file mode 100644 index 0000000000..f628d2198b --- /dev/null +++ b/src/adaptors/superlend/index.js @@ -0,0 +1,190 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const { + poolAbi, + uiPoolDataProviderAbi, + oracleAbi, + CHAIN: chain, + PROTOCOL_DATA_PROVIDER, + UI_POOL_DATA_PROVIDER, + PROVIDER_ADDRESS, + CHAIN_ID, + MERKLE_BASE_URL, + CAMPAIGN_ID_MAP, + APPLE_REWARD_TOKEN, +} = require('./constants'); + +const getApy = async () => { + const reserveTokens = ( + await sdk.api.abi.call({ + target: PROTOCOL_DATA_PROVIDER, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + const aTokens = ( + await sdk.api.abi.call({ + target: PROTOCOL_DATA_PROVIDER, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: PROTOCOL_DATA_PROVIDER, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: PROTOCOL_DATA_PROVIDER, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: aTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: aTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + const oracleAddresses = ( + await sdk.api.abi.call({ + target: UI_POOL_DATA_PROVIDER, + abi: uiPoolDataProviderAbi.find((m) => m.name === 'getReservesData'), + params: PROVIDER_ADDRESS, + chain, + }) + ).output[0]?.reduce((acc, current) => { + acc[current?.underlyingAsset.toLowerCase()] = current?.priceOracle; + return acc; + }, {}); + + const oraclePrices = {}; + for (const key of Object.keys(oracleAddresses)) { + oraclePrices[key] = + Number( + ( + await sdk.api.abi.call({ + target: oracleAddresses[key], + abi: oracleAbi.find((m) => m.name === 'latestAnswer'), + chain, + }) + ).output + ) / 1e8; + } + + // reward data + const rewardData = {}; + for (const pool of reserveTokens) { + const campaignId = CAMPAIGN_ID_MAP[pool.symbol.toUpperCase()]; + const url = MERKLE_BASE_URL.replace('CHAIN_ID', CHAIN_ID).replace( + 'CAMPAIGN_ID', + campaignId + ); + const campaign = await utils.getData(url); + rewardData[pool.symbol.toUpperCase()] = campaign[0]?.Opportunity?.apr ?? 0; + } + + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = oraclePrices[pool.tokenAddress.toLowerCase()]; + + const supply = totalSupply[i]; + let totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + let tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + totalBorrowUsd = totalSupplyUsd - tvlUsd; + + const url = `https://markets.superlend.xyz/reserve-overview/?underlyingAsset=${pool.tokenAddress.toLowerCase()}&marketName=etherlink`; + + const apyBase = (p.liquidityRate / 10 ** 27) * 100; + const apyReward = rewardData[pool.symbol.toUpperCase()] ?? 0; + + return { + pool: `${aTokens[i].tokenAddress}-etlk`.toLowerCase(), + chain: 'Etherlink', + project: 'superlend', + symbol: pool.symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [pool.tokenAddress], + rewardTokens: apyReward > 0 ? [APPLE_REWARD_TOKEN] : [], + totalSupplyUsd, + totalBorrowUsd, + debtCeilingUsd: null, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + url, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + mintedCoin: null, + poolMeta: null, + }; + }) + .filter((i) => Boolean(i)); +}; + +const keepFinite = (p) => { + if ( + !['apyBase', 'apyReward', 'apy'] + .map((f) => Number.isFinite(p[f])) + .includes(true) + ) + return false; + + return Number.isFinite(p['tvlUsd']); +}; + +const apy = async () => { + const pools = await getApy(); + + return pools.filter((p) => keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/superstate-uscc/index.js b/src/adaptors/superstate-uscc/index.js new file mode 100644 index 0000000000..114209a615 --- /dev/null +++ b/src/adaptors/superstate-uscc/index.js @@ -0,0 +1,82 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { getTotalSupply } = require('../utils'); + +const USCC = { + ethereum: '0x14d60e7fdc0d71d8611742720e4c50e7a974020c', + plume_mainnet: '0x4c21b7577c8fe8b0b0669165ee7c8f67fa1454cf', + solana: 'BTRR3sj1Bn2ZjuemgbeQ6SCtf84iXS81CS7UDTSxUCaK', +}; +const USCC_ORACLE = '0xAfFd8F5578E8590665de561bdE9E7BAdb99300d9'; +const project = 'superstate-uscc'; +const symbol = 'USCC'; + +const apy = async () => { + let tvlEth = + (await sdk.api.erc20.totalSupply({ target: USCC['ethereum'], chain: 'ethereum' })); + let tvlPlume = + (await sdk.api.erc20.totalSupply({ target: USCC['plume_mainnet'], chain: 'plume_mainnet' })); + const tvlSol = await getTotalSupply(USCC['solana']); + tvlEth = tvlEth.output / 1e6; + tvlPlume = tvlPlume.output / 1e6; + + const timestampNow = Math.floor(Date.now() / 1000); + const timestampYesterday = timestampNow - 86400; + + const blockNow = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestampNow}`) + ).data.height; + + const blockYesterday = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestampYesterday}`) + ).data.height; + + let exchangeRateYesterday = await sdk.api.abi.call({ + target: USCC_ORACLE, + chain: 'ethereum', + abi: 'uint256:latestAnswer', + block: blockYesterday, + }); + + let exchangeRateToday = await sdk.api.abi.call({ + target: USCC_ORACLE, + chain: 'ethereum', + abi: 'uint256:latestAnswer', + block: blockNow, + }); + + exchangeRateToday = exchangeRateToday.output / 1e6; + exchangeRateYesterday = exchangeRateYesterday.output / 1e6; + + const apr = ((exchangeRateToday - exchangeRateYesterday) / exchangeRateYesterday) * + 365 * 100; + + return [ + { + pool: `${USCC['ethereum']}`, + chain: 'ethereum', + project, + symbol, + apyBase: apr, + tvlUsd: tvlEth * exchangeRateToday, + }, + { + pool: `${USCC['plume_mainnet']}`, + chain: 'plume_mainnet', + project, + symbol, + apyBase: apr, + tvlUsd: tvlPlume * exchangeRateToday, + }, + { + pool: `${USCC['solana']}`, + chain: 'solana', + project, + symbol, + apyBase: apr, + tvlUsd: tvlSol * exchangeRateToday, + }, + ]; +}; + +module.exports = { apy, url: 'https://superstate.com/uscc' }; diff --git a/src/adaptors/supervaults/index.js b/src/adaptors/supervaults/index.js new file mode 100644 index 0000000000..c565f440c6 --- /dev/null +++ b/src/adaptors/supervaults/index.js @@ -0,0 +1,136 @@ +const axios = require('axios'); + +const INDEXER = 'https://app.neutron.org/api/indexer/v2/vaults'; + +// Browser-like headers to pass WAF checks +const HDRS = { + Origin: 'https://app.neutron.org', + Referer: 'https://app.neutron.org/earn', + Accept: 'application/json, text/plain, */*', + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', +}; + +// Bitcoin LST Denominations (for proper symbol display) +// Maps IBC denoms to actual token symbols +const BTC_LST_DENOMS = { + 'ibc/2EB30350120BBAFC168F55D0E65551A27A724175E8FBCC7B37F9A71618FE136B': 'FBTC', + 'ibc/B7BF60BB54433071B49D586F54BD4DED5E20BEFBBA91958E87488A761115106B': 'LBTC', + 'ibc/C0F284F165E6152F6DDDA900537C1BC8DA1EA00F03B9C9EC1841FA7E004EF7A3': 'solvBTC', + 'ibc/E2A000FD3EDD91C9429B473995CE2C7C555BCC8CFC1D0A3D02F514392B7A80E8': 'eBTC', + 'ibc/1075520501498E008B02FD414CD8079C0A2BAF9657278F8FB8F7D37A857ED668': 'pumpBTC', + 'ibc/3F1D988D9EEA19EB0F3950B4C19664218031D8BCE68CE7DE30F187D5ACEA0463': 'uniBTC', + // Base assets + 'ibc/0E293A7622DC9A6439DB60E6D234B5AF446962E27CA3AB44D0590603DFF6968E': 'wBTC', + 'ibc/694A6B26A43A2FBECCFFEAC022DEACB39578E54207FDD32005CD976B57B98004': 'ETH', + 'ibc/A585C2D15DCD3B010849B453A2CFCB5E213208A5AB665691792684C26274304D': 'ETH', + // maxBTC factory denom + 'factory/neutron17sp75wng9vl2hu3sf4ky86d7smmk3wle9gkts2gmedn9x4ut3xcqa5xp34/maxbtc': 'maxBTC', +}; + +/** + * Fetch vaults data with retry logic to handle transient WAF/CDN issues + * @returns {Array} - Array of vault objects + */ +async function fetchVaults() { + let lastErr; + for (let i = 0; i < 3; i++) { + try { + const res = await axios.get(INDEXER, { headers: HDRS }); + const rows = Array.isArray(res?.data?.data) ? res.data.data : []; + if (rows.length) return rows; + } catch (e) { + lastErr = e; + // Exponential backoff: 500ms, 1000ms, 1500ms + await new Promise((r) => setTimeout(r, 500 * (i + 1))); + } + } + throw lastErr || new Error('Indexer fetch failed after retries'); +} + +/** + * Main APY calculation function + * Methodology: Uses indexer-calculated vault performance over 30d window + * - apy_vault_over_hold_30d accounts for fees earned vs. impermanent loss + * - Already calculated by the indexer (complex CL position management) + * - Can be negative if IL > fees earned + * - Omits points, boosts, and locked rewards per DefiLlama guidelines + */ +async function apy() { + const vaults = await fetchVaults(); + const pools = []; + + for (const vault of vaults) { + if (!vault) continue; + + // Skip paused vaults + if (vault.paused) continue; + + // Skip test/inactive vaults (deposit_cap = 0 indicates test vault) + if ( + !vault.deposit_cap || + vault.deposit_cap === '0' || + vault.deposit_cap === 0 + ) { + continue; + } + + // Extract TVL data (already in USD from indexer) + const tvl0 = Number(vault.tvl_0) || 0; + const tvl1 = Number(vault.tvl_1) || 0; + const tvlUsd = tvl0 + tvl1; + + // Skip if no meaningful TVL + if (tvlUsd === 0) continue; + + // Use indexer-calculated APY (vault performance vs. holding over 30d) + // This accounts for: + // - Trading fees earned + // - Impermanent loss from concentrated liquidity position + // - Position rebalancing effects + // Note: Can be negative if IL > fees + const apyVaultOverHold = vault.apy_vault_over_hold_30d; + + // Convert from decimal to percentage (e.g., 0.05 -> 5%) + // Set to null if not available (indexer needs time to calculate) + let apyBase = null; + if (apyVaultOverHold !== null && apyVaultOverHold !== undefined) { + apyBase = Number(apyVaultOverHold) * 100; + } + + // Extract token information with proper symbol mapping + const token0Denom = vault.token_0_denom; + const token1Denom = vault.token_1_denom; + + // Use mapping for BTC LSTs and known tokens, fallback to indexer symbol + const token0Symbol = BTC_LST_DENOMS[token0Denom] || vault.token_0_symbol || '?'; + const token1Symbol = BTC_LST_DENOMS[token1Denom] || vault.token_1_symbol || '?'; + + // Build underlying tokens array (filter out nullish values) + const underlyingTokens = [token0Denom, token1Denom].filter(Boolean); + + // Construct pool URL (use vault-specific link if available, otherwise campaign page) + const poolUrl = vault.contract_address + ? `https://app.neutron.org/bitcoin-summer?vault=${vault.contract_address}` + : 'https://app.neutron.org/bitcoin-summer'; + + pools.push({ + pool: `${vault.contract_address}-neutron`.toLowerCase(), + chain: 'Neutron', + project: 'supervaults', + symbol: `${token0Symbol}-${token1Symbol}`, + tvlUsd, + apyBase, + underlyingTokens, + url: poolUrl, + }); + } + + return pools; +} + +module.exports = { + timetravel: false, + apy, + url: 'https://app.neutron.org/bitcoin-summer', +}; diff --git a/src/adaptors/sushiswap-v3/estimateFee.ts b/src/adaptors/sushiswap-v3/estimateFee.ts new file mode 100644 index 0000000000..86e458b11c --- /dev/null +++ b/src/adaptors/sushiswap-v3/estimateFee.ts @@ -0,0 +1,230 @@ +// forked from https://github.com/chunza2542/uniswap.fish + +const bn = require('bignumber.js'); + +interface Tick { + tickIdx: string; + liquidityNet: string; + price0: string; + price1: string; +} + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = ( + price: number, + token0Decimal: string, + token1Decimal: string +): number => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 1) +interface TokensAmount { + amount0: number; + amount1: number; +} +const getTokensAmountFromDepositAmountUSD = ( + P: number, + Pl: number, + Pu: number, + priceUSDX: number, + priceUSDY: number, + depositAmountUSD: number +): TokensAmount => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount0: bn +): bn => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount1: bn +): bn => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = ( + price: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P: number, + lowerP: number, + upperP: number, + amount0: number, + amount1: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity: bn; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +const estimateFee = ( + liquidityDelta: bn, + liquidity: bn, + volume24H: number, + feeTier: string +): number => { + const feeTierPercentage = getFeeTierPercentage(feeTier); + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + + return feeTierPercentage * volume24H * liquidityPercentage; +}; + +const getLiquidityFromTick = (poolTicks: Tick[], tick: number): bn => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity: bn = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price: number | string | bn): bn => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n: number | string | bn, exp: number): bn => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a: bn, b: bn, multiplier: bn) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getFeeTierPercentage = (tier: string): number => { + if (tier === '100') return 0.01 / 100; + if (tier === '500') return 0.05 / 100; + if (tier === '3000') return 0.3 / 100; + if (tier === '10000') return 1 / 100; + return 0; +}; + +module.exports.EstimatedFees = ( + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + feeTier, + volume, + poolTicks +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const estimatedFee = + P >= Pl && P <= Pu ? estimateFee(deltaL, L, volume, feeTier) : 0; + + return estimatedFee; +}; diff --git a/src/adaptors/sushiswap-v3/index.js b/src/adaptors/sushiswap-v3/index.js new file mode 100644 index 0000000000..9e0991bf82 --- /dev/null +++ b/src/adaptors/sushiswap-v3/index.js @@ -0,0 +1,329 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); +const env = require('../../../env'); + +const utils = require('../utils'); +const { EstimatedFees } = require('./estimateFee.ts'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); +const { addMerklRewardApy } = require('../merkl/merkl-additional-reward'); + +const PROJECT = 'sushiswap-v3'; + +const chains = { + ethereum: sdk.graph.modifyEndpoint('5nnoU1nUFeWqtXgbpC54L9PWdpgo7Y9HYinR3uTMsfzs'), + arbitrum: sdk.graph.modifyEndpoint('96EYD64NqmnFxMELu2QLWB95gqCmA9N96ssYsZfFiYHg'), + bsc: sdk.graph.modifyEndpoint('FiJDXMFCBv88GP17g2TtPh8BcA8jZozn5WRW7hCN7cUT'), + base: sdk.graph.modifyEndpoint('Cz4Snpih41NNNPZcbj1gd3fYXPwFr5q92iWMoZjCarEb'), + hemi: 'https://api.goldsky.com/api/public/project_clslspm3c0knv01wvgfb2fqyq/subgraphs/sushiswap/v3-hemi/gn' +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + dataNow = dataNow.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + // balance calls not working on the uni v3 avax contracts + if (chainString === 'avax') { + dataNow = dataNow.map((p) => ({ + ...p, + reserve0: Number(p.totalValueLockedToken0), + reserve1: Number(p.totalValueLockedToken1), + })); + } + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = true; + if (enableV3Apy && chainString !== 'arbitrum') { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // batching the tick query into 3 chunks to prevent it from breaking + const nbBatches = 3; + const chunkSize = Math.ceil(dataNow.length / nbBatches); + const chunks = [ + dataNow.slice(0, chunkSize).map((i) => i.id), + dataNow.slice(chunkSize, chunkSize * 2).map((i) => i.id), + dataNow.slice(chunkSize * 2, dataNow.length).map((i) => i.id), + ]; + + const tickData = {}; + // we fetch 3 pages for each pool + for (const page of [0, 1, 2]) { + // console.log(`page nb: ${page}`); + let pageResults = {}; + for (const chunk of chunks) { + // console.log(chunk.length); + const tickQuery = ` + query { + ${chunk + .map( + (poolAddress, index) => ` + pool_${poolAddress}: ticks( + first: 1000, + skip: ${page * 1000}, + where: { poolAddress: "${poolAddress}" }, + orderBy: tickIdx + ) { + tickIdx + liquidityNet + price0 + price1 + } + ` + ) + .join('\n')} + } + `; + + try { + const response = await request(url, tickQuery); + pageResults = { ...pageResults, ...response }; + } catch (err) { + console.log(err); + } + } + tickData[`page_${page}`] = pageResults; + } + + // reformat tickData + const ticks = {}; + Object.values(tickData).forEach((page) => { + Object.entries(page).forEach(([pool, values]) => { + if (!ticks[pool]) { + ticks[pool] = []; + } + ticks[pool] = ticks[pool].concat(values); + }); + }); + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + dataNow = dataNow.map((p) => { + const poolTicks = ticks[`pool_${p.id}`] ?? []; + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${p.id}`); + return { ...p, estimatedFee: null, apy7d: null }; + } + + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + const estimatedFee = EstimatedFees( + priceAssumption, + [p.token1_in_token0 * (1 - delta), p.token1_in_token0 * (1 + delta)], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + p.volumeUSD7d, + poolTicks + ); + + const apy7d = ((estimatedFee * 52) / investmentAmount) * 100; + + return { ...p, estimatedFee, apy7d }; + }); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://www.sushi.com/${chainString}/pool/v3/${p.id}`; + + let symbol = p.symbol; + if ( + chainString === 'arbitrum' && + underlyingTokens + .map((t) => t.toLowerCase()) + .includes('0xff970a61a04b1ca14834a43f5de4533ebddb5cc8') + ) { + symbol = p.symbol.replace('USDC', 'USDC.e'); + } + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: PROJECT, + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + console.log(chainString, e); + return []; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await axios.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).data.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + + return addMerklRewardApy(data.flat().filter( + (p) => + utils.keepFinite(p)), 'sushi-swap'); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/sushiswap/abiMinichefV2.js b/src/adaptors/sushiswap/abiMinichefV2.js new file mode 100644 index 0000000000..451afcaf71 --- /dev/null +++ b/src/adaptors/sushiswap/abiMinichefV2.js @@ -0,0 +1,529 @@ +module.exports = { + minichefV2: [ + { + inputs: [ + { internalType: 'contract IERC20', name: '_sushi', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'LogPoolAddition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'overwrite', + type: 'bool', + }, + ], + name: 'LogSetPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'sushiPerSecond', + type: 'uint256', + }, + ], + name: 'LogSushiPerSecond', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint64', + name: 'lastRewardTime', + type: 'uint64', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accSushiPerShare', + type: 'uint256', + }, + ], + name: 'LogUpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'SUSHI', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes[]', name: 'calls', type: 'bytes[]' }, + { internalType: 'bool', name: 'revertOnFail', type: 'bool' }, + ], + name: 'batch', + outputs: [ + { internalType: 'bool[]', name: 'successes', type: 'bool[]' }, + { internalType: 'bytes[]', name: 'results', type: 'bytes[]' }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'claimOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingSushi', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: 'token', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permitToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint128', name: 'accSushiPerShare', type: 'uint128' }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewarder', + outputs: [ + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: 'overwrite', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_sushiPerSecond', type: 'uint256' }, + ], + name: 'setSushiPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sushiPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newOwner', type: 'address' }, + { internalType: 'bool', name: 'direct', type: 'bool' }, + { internalType: 'bool', name: 'renounce', type: 'bool' }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accSushiPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MiniChefV2.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'int256', name: 'rewardDebt', type: 'int256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdrawAndHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/sushiswap/abiRewarder.js b/src/adaptors/sushiswap/abiRewarder.js new file mode 100644 index 0000000000..0c08029de0 --- /dev/null +++ b/src/adaptors/sushiswap/abiRewarder.js @@ -0,0 +1,311 @@ +module.exports = { + rewarderABI: [ + { + inputs: [ + { internalType: 'address', name: '_MASTERCHEF_V2', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'rewardToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerSecond', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'masterLpToken', + type: 'address', + }, + ], + name: 'LogInit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'LogOnReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerSecond', + type: 'uint256', + }, + ], + name: 'LogRewardPerSecond', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint64', + name: 'lastRewardTime', + type: 'uint64', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accToken1PerShare', + type: 'uint256', + }, + ], + name: 'LogUpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [], + name: 'MASTERCHEF_V2', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'claimOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: 'init', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'masterLpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: 'lpTokenAmount', type: 'uint256' }, + ], + name: 'onSushiReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingToken', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'pendingTokens', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'rewardTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'rewardAmounts', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint128', name: 'accToken1PerShare', type: 'uint128' }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address payable', name: 'to', type: 'address' }, + ], + name: 'reclaimTokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardRates', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_rewardPerSecond', type: 'uint256' }, + ], + name: 'setRewardPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newOwner', type: 'address' }, + { internalType: 'bool', name: 'direct', type: 'bool' }, + { internalType: 'bool', name: 'renounce', type: 'bool' }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accToken1PerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardTime', type: 'uint64' }, + ], + internalType: 'struct TreasureRewarder.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'unpaidRewards', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/sushiswap/abisEthereum.js b/src/adaptors/sushiswap/abisEthereum.js new file mode 100644 index 0000000000..10cc212067 --- /dev/null +++ b/src/adaptors/sushiswap/abisEthereum.js @@ -0,0 +1,1267 @@ +module.exports = { + lpTokenABI: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sync', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + masterchefABI: [ + { + inputs: [ + { + internalType: 'contract SushiToken', + name: '_sushi', + type: 'address', + }, + { internalType: 'address', name: '_devaddr', type: 'address' }, + { internalType: 'uint256', name: '_sushiPerBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_startBlock', type: 'uint256' }, + { internalType: 'uint256', name: '_bonusEndBlock', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'BONUS_MULTIPLIER', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bonusEndBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_devaddr', type: 'address' }], + name: 'dev', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'devaddr', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_from', type: 'uint256' }, + { internalType: 'uint256', name: '_to', type: 'uint256' }, + ], + name: 'getMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingSushi', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'accSushiPerShare', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sushi', + outputs: [ + { internalType: 'contract SushiToken', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sushiPerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + masterchefV2ABI: [ + { + inputs: [ + { + internalType: 'contract IMasterChef', + name: '_MASTER_CHEF', + type: 'address', + }, + { internalType: 'contract IERC20', name: '_sushi', type: 'address' }, + { internalType: 'uint256', name: '_MASTER_PID', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'LogInit', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'LogPoolAddition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'overwrite', + type: 'bool', + }, + ], + name: 'LogSetPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint64', + name: 'lastRewardBlock', + type: 'uint64', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accSushiPerShare', + type: 'uint256', + }, + ], + name: 'LogUpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'MASTER_CHEF', + outputs: [ + { internalType: 'contract IMasterChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MASTER_PID', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'SUSHI', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes[]', name: 'calls', type: 'bytes[]' }, + { internalType: 'bool', name: 'revertOnFail', type: 'bool' }, + ], + name: 'batch', + outputs: [ + { internalType: 'bool[]', name: 'successes', type: 'bool[]' }, + { internalType: 'bytes[]', name: 'results', type: 'bytes[]' }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'claimOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'harvestFromMasterChef', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'dummyToken', + type: 'address', + }, + ], + name: 'init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingSushi', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IERC20', name: 'token', type: 'address' }, + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permitToken', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'uint128', name: 'accSushiPerShare', type: 'uint128' }, + { internalType: 'uint64', name: 'lastRewardBlock', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewarder', + outputs: [ + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: 'overwrite', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sushiPerBlock', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newOwner', type: 'address' }, + { internalType: 'bool', name: 'direct', type: 'bool' }, + { internalType: 'bool', name: 'renounce', type: 'bool' }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint128', + name: 'accSushiPerShare', + type: 'uint128', + }, + { internalType: 'uint64', name: 'lastRewardBlock', type: 'uint64' }, + { internalType: 'uint64', name: 'allocPoint', type: 'uint64' }, + ], + internalType: 'struct MasterChefV2.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'int256', name: 'rewardDebt', type: 'int256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdrawAndHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/sushiswap/index.js b/src/adaptors/sushiswap/index.js index c94c7a4708..d7c890ac8d 100644 --- a/src/adaptors/sushiswap/index.js +++ b/src/adaptors/sushiswap/index.js @@ -1,50 +1,95 @@ +const superagent = require('superagent'); const { request, gql } = require('graphql-request'); -const dateFunc = require('date-fns'); +const sdk = require('@defillama/sdk'); +const env = require('../../../env'); const utils = require('../utils'); +const { + lpTokenABI, + masterchefABI, + masterchefV2ABI, +} = require('./abisEthereum'); +const { minichefV2 } = require('./abiMinichefV2'); +const { rewarderABI } = require('./abiRewarder'); + +// exchange urls +const urlEthereum = sdk.graph.modifyEndpoint( + '6NUtT5mGjZ1tSshKLf5Q3uEEJtjBZJo1TpL5MXsUBqrT' +); +const urlArbitrum = `https://gateway-arbitrum.network.thegraph.com/api/${env.GRAPH_API_KEY}/deployments/id/QmfN96hDXYtgeLsBv5WjQY8FAwqBfBFoiq8gzsn9oApcoU`; + +const urlPolygon = sdk.graph.modifyEndpoint( + '8NiXkxLRT3R22vpwLB4DXttpEf3X1LrKhe4T1tQ3jjbP' +); +const urlAvalanche = sdk.graph.modifyEndpoint( + '6VAhbtW5u2sPYkJKAcMsxgqTBu4a1rqmbiVQWgtNjrvT' +); +const urlBase = `https://gateway-arbitrum.network.thegraph.com/api/${env.GRAPH_API_KEY}/deployments/id/QmQfYe5Ygg9A3mAiuBZYj5a64bDKLF4gF6sezfhgxKvb9y`; + +// LM reward urls +const urlMc2 = sdk.graph.modifyEndpoint( + 'FAa1YU79pPDUKj8vtkUPZGzCcPVS6Edg1md5LsRHSKWb' +); +const urlMcArbitrum = sdk.graph.modifyEndpoint('sushiswap/arbitrum-minichef'); +const urlMcPolygon = sdk.graph.modifyEndpoint('sushiswap/matic-minichef'); + +// sushi token +const SUSHI = { + ethereum: '0x6b3595068778dd592e39a122f4f5a5cf09c90fe2', + arbitrum: '0xd4d42F0b6DEF4CE0383636770eF773390d85c61A', + polygon: '0x0b3F868E0BE5597D5DB7fEB59E1CADBb0fdDa50a', +}; -// base apy -const baseUrl = 'https://api.thegraph.com/subgraphs/name/sushiswap'; -const urlEthereum = `${baseUrl}/exchange`; -const urlPolygon = `${baseUrl}/matic-exchange`; -const urlArbitrum = `${baseUrl}/arbitrum-exchange`; -const urlAvalanche = `${baseUrl}/avalanche-exchange`; - -// reward apy -const baseUrlLm = 'https://api.thegraph.com/subgraphs/name'; -const urlMc1 = `${baseUrlLm}/sushiswap/master-chef`; -const urlMc2 = `${baseUrlLm}/sushiswap/master-chefv2`; -const urlMcPolygon = `${baseUrlLm}/sushiswap/matic-minichef`; -const urlMcArbitrum = `${baseUrlLm}/matthewlilley/arbitrum-minichef`; - -const queryMasterChef = gql` - { - masterChefs(block: {number: }) { - totalAllocPoint - sushiPerBlock - } - } -`; +// masterchef/minichef for arbitrum/polygon +const CHEF = { + ethereum: { + // masterchef and masterchefv2 + mc1: '0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd', + mc2: '0xef0881ec094552b2e128cf945ef17a6752b4ec5d', + }, + arbitrum: { + // minichefv2 + mc2: '0xF4d73326C13a4Fc5FD7A064217e12780e9Bd62c3', + }, + polygon: { + // minichefv2 + mc2: '0x0769fd68dFb93167989C6f7254cd0D766Fb2841F', + }, +}; -const queryMiniChef = gql` +const secondsPerDay = 60 * 60 * 24; +const secondsPerBlock = 12; +const blocksPerDay = secondsPerDay / secondsPerBlock; + +const query = gql` { - miniChefs(block: {number: }) { - totalAllocPoint - sushiPerSecond + pairs(first: 1000, orderBy: reserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } } } `; -const querySushiAllocation = gql` +const queryPrior = gql` { - pools(first: 1000, orderBy: allocPoint, orderDirection: desc block: {number: }) { - pair - allocPoint + pairs (first: 1000 orderBy: reserveETH orderDirection: desc block: {number: }) { + id + volumeUSD } } `; -const queryExtraAllocation = gql` +const queryMc = gql` { pools( first: 1000 @@ -57,10 +102,6 @@ const queryExtraAllocation = gql` id pair allocPoint - masterChef { - id - totalAllocPoint - } rewarder { id rewardToken @@ -70,397 +111,375 @@ const queryExtraAllocation = gql` } `; -const queryExtraAllocationEVM = gql` - { - pools(first: 1000, skip: 0, orderBy: id, orderDirection: desc block: {number: }) { - id - pair - rewarder { - id - rewardToken - rewardPerSecond - } - allocPoint - miniChef { - id - sushiPerSecond - totalAllocPoint - } - } - } -`; +const topLvl = async (chainString, urlExchange, urlRewards, chainId) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, null, [ + urlExchange, + urlRewards, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + null, + [urlExchange, urlRewards], + 604800 + ); -const query = gql` - { - pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { - id - reserve0 - reserve1 - volumeUSD - token0 { - symbol - id - } - token1 { - symbol - id - } - } - } -`; + // calc base apy + let data = ( + await request(urlExchange, query.replace('', block)) + ).pairs; + const dataPrior = ( + await request( + urlExchange, + queryPrior.replace('', blockPrior) + ) + ).pairs; -const queryPrior = gql` - { - pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { - id - volumeUSD + // 7d offset + const dataPrior7d = ( + await request( + urlExchange, + queryPrior.replace('', blockPrior7d) + ) + ).pairs; + + data = await utils.tvl(data, chainString); + data = data.map((p) => utils.apy(p, dataPrior, dataPrior7d, 'v2')); + data = data.map((p) => ({ + ...p, + totalValueLockedUSDlp: p.totalValueLockedUSD, + })); + + if (chainString === 'avalanche' || chainString === 'base') { + return data.map((p) => ({ + pool: p.id, + chain: utils.formatChain(chainString), + project: 'sushiswap', + symbol: utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`), + tvlUsd: p.totalValueLockedUSDlp, + apyBase: Number(p.apy1d), + apyBase7d: Number(p.apy7d), + underlyingTokens: [p.token0.id, p.token1.id], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + url: `https://www.sushi.com/${chainString}/pool/v2/${p.id}`, + })); } - } -`; -const blockFieldsQuery = gql` - fragment blockFields on Block { - id - number - timestamp - } -`; - -const blocksQuery = gql` - query blocksQuery( - $first: Int! = 1000 - $skip: Int! = 0 - $start: Int! - $end: Int! - ) { - blocks( - first: $first - skip: $skip - orderBy: number - orderDirection: desc - where: { timestamp_gt: $start, timestamp_lt: $end } - ) { - ...blockFields + let sushiPerSecond; + + let poolsLengthMC1; + let totalAllocPointMC1; + let sushiPerBlockMC1; + + let poolsLengthMC2; + let totalAllocPointMC2; + let sushiPerBlockMC2; + + let poolsInfoMC1; + let poolsInfoMC2; + let lpTokensMC2; + + let rewarderMC2; + let rewardTokenMC2; + let rewardPerSecondMC2; + + if (chainString === 'arbitrum' || chainString === 'polygon') { + [poolsLengthMC2, totalAllocPointMC2, sushiPerSecond] = ( + await Promise.all( + ['poolLength', 'totalAllocPoint', 'sushiPerSecond'].map((method) => + sdk.api.abi.call({ + target: CHEF[chainString].mc2, + abi: minichefV2.find(({ name }) => name === method), + chain: chainString, + permitFailure: true, + }) + ) + ) + ).map((res) => res.output); + sushiPerSecond /= 1e18; + + [poolsInfoMC2, lpTokensMC2, rewarderMC2] = await Promise.all( + ['poolInfo', 'lpToken', 'rewarder'].map((method) => + sdk.api.abi.multiCall({ + calls: [...Array(Number(poolsLengthMC2 - 1)).keys()].map((i) => ({ + target: CHEF[chainString].mc2, + params: i, + })), + abi: minichefV2.find(({ name }) => name === method), + chain: chainString, + permitFailure: true, + }) + ) + ); + poolsInfoMC2 = poolsInfoMC2.output.map((res) => res.output); + lpTokensMC2 = lpTokensMC2.output.map((res) => res.output); + rewarderMC2 = rewarderMC2.output.map((res) => res.output); + + [rewardPerSecondMC2, rewardTokenMC2] = await Promise.all( + ['rewardPerSecond', 'rewardToken'].map((method) => + sdk.api.abi.multiCall({ + abi: rewarderABI.find(({ name }) => name === method), + calls: [...Array(Number(poolsLengthMC2 - 1)).keys()].map((i) => ({ + target: rewarderMC2[i], + })), + chain: chainString, + permitFailure: true, + }) + ) + ); + rewardPerSecondMC2 = rewardPerSecondMC2.output.map((res) => res.output); + rewardTokenMC2 = rewardTokenMC2.output.map((res) => res.output); + + poolsInfoMC2.forEach((p, i) => { + p['lpToken'] = lpTokensMC2[i]; + p['rewardToken'] = rewardTokenMC2[i]?.toLowerCase(); + p['rewardPerSecond'] = rewardPerSecondMC2[i]; + }); + } else if (chainString === 'ethereum') { + //////////////////// MC1 (pools with sushi rewards) + [poolsLengthMC1, totalAllocPointMC1, sushiPerBlockMC1] = ( + await Promise.all( + ['poolLength', 'totalAllocPoint', 'sushiPerBlock'].map((method) => + sdk.api.abi.call({ + target: CHEF[chainString].mc1, + abi: masterchefABI.find(({ name }) => name === method), + chain: chainString, + permitFailure: true, + }) + ) + ) + ).map((res) => res.output); + sushiPerBlockMC1 /= 1e18; + + poolsInfoMC1 = await sdk.api.abi.multiCall({ + abi: masterchefABI.find(({ name }) => name === 'poolInfo'), + calls: [...Array(Number(poolsLengthMC1 - 1)).keys()].map((i) => ({ + target: CHEF[chainString].mc1, + params: i, + })), + chain: chainString, + permitFailure: true, + }); + poolsInfoMC1 = poolsInfoMC1.output.map((res) => res.output); + + //////////////////// MC2 (pools with sushi and extra rewards) + [poolsLengthMC2, totalAllocPointMC2, sushiPerBlockMC2] = ( + await Promise.all( + ['poolLength', 'totalAllocPoint', 'sushiPerBlock'].map((method) => + sdk.api.abi.call({ + target: CHEF[chainString].mc2, + abi: masterchefV2ABI.find(({ name }) => name === method), + chain: chainString, + permitFailure: true, + }) + ) + ) + ).map((res) => res.output); + sushiPerBlockMC2 /= 1e18; + + [poolsInfoMC2, lpTokensMC2] = await Promise.all( + ['poolInfo', 'lpToken'].map((method) => + sdk.api.abi.multiCall({ + abi: masterchefV2ABI.find(({ name }) => name === method), + calls: [...Array(Number(poolsLengthMC2 - 1)).keys()].map((i) => ({ + target: CHEF[chainString].mc2, + params: i, + })), + chain: chainString, + permitFailure: true, + }) + ) + ); + poolsInfoMC2 = poolsInfoMC2.output.map((res) => res.output); + lpTokensMC2 = lpTokensMC2.output.map((res) => res.output); + poolsInfoMC2.forEach((p, i) => { + p['lpToken'] = lpTokensMC2[i]; + }); } - } - ${blockFieldsQuery} -`; -// Grabs the last 1000 blocks and averages -// the time difference between them -const getAverageBlockTime = async () => { - const now = dateFunc.startOfHour(Date.now()); - const start = dateFunc.getUnixTime(dateFunc.subHours(now, 6)); - const end = dateFunc.getUnixTime(now); - let blocks = await request( - 'https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks', - blocksQuery, - { start, end } - ); - blocks = blocks.blocks; - - const averageBlockTime = blocks?.reduce( - (previousValue, currentValue, currentIndex) => { - if (previousValue.timestamp) { - const difference = previousValue.timestamp - currentValue.timestamp; - - previousValue.averageBlockTime = - previousValue.averageBlockTime + difference; + // scale tvl by reservesRatio + // need to loop over them separately and call mc1 for sushiAllocation and mc2 for extraAlloctaion + const Z = + chainString === 'ethereum' + ? { mc1: poolsInfoMC1, mc2: poolsInfoMC2 } + : { mc2: poolsInfoMC2 }; + + for (const [k, alloc] of Object.entries(Z)) { + const lpTokens = alloc.map((p) => p.lpToken); + let [supplyData, masterChefBalData] = await Promise.all( + ['totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [CHEF[chainString][k]] : null, + })), + abi: lpTokenABI.find(({ name }) => name === method), + chain: chainString, + permitFailure: true, + }) + ) + ); + supplyData = supplyData.output.map((res) => res.output); + masterChefBalData = masterChefBalData.output.map((res) => res.output); + + const reserveRatios = {}; + lpTokens.forEach((lp, i) => { + reserveRatios[lp?.toLowerCase()] = masterChefBalData[i] / supplyData[i]; + }); + for (const p of data) { + const rr = reserveRatios[p.id?.toLowerCase()]; + if (rr === undefined) continue; + p['totalValueLockedUSD'] *= rr; } + } - previousValue.timestamp = currentValue.timestamp; - - if (currentIndex === blocks.length - 1) { - return previousValue.averageBlockTime / blocks.length; + // calculate sushi and extra token reward apy for ethereum + // note: wanted to pull via contracts, but a large variety of different reward token related abis + // and function names (eg `rewardPerSecond`, `tokenPerBlock`, `rewardPerToken`) + // using the subgraph to pull rewards instead + if (chainString === 'ethereum') { + const poolsRewardMC2 = ( + await request(urlRewards, queryMc.replace('', block)) + ).pools; + for (const p of poolsInfoMC2) { + const x = poolsRewardMC2.find( + (x) => x.pair?.toLowerCase() === p.lpToken?.toLowerCase() + ); + const rewarder = x?.rewarder; + p['rewardPerSecond'] = + // ALCX reward token returns tokenPerBlock but subgraph doesn't distinguish + // see: (https://etherscan.io/address/0x7519C93fC5073E15d89131fD38118D73A72370F8#readContract) + p.lpToken?.toLowerCase() === + '0xc3f279090a47e80990fe3a9c30d24cb117ef91a8' + ? Number(rewarder?.rewardPerSecond / secondsPerBlock) + : // CVX rewards are 0 + p.lpToken?.toLowerCase() === + '0x05767d9ef41dc40689678ffca0608878fb3de906' + ? 0 + : Number(rewarder?.rewardPerSecond); + p['rewardToken'] = + rewarder !== undefined + ? rewarder.rewardToken?.toLowerCase() + : rewarder; } + } - return previousValue; - }, - { timestamp: null, averageBlockTime: 0 } - ); - return averageBlockTime; -}; - -const buildRewardFields = ( - el, - totalAllocPoint, - sushiUsd, - sushiPerBlock = null, - sushiPerSecond = null, - blocksPerDay = null -) => { - el = { ...el }; - const decimals = 1e18; - const relPoolShare = Number(el.allocPoint) / Number(totalAllocPoint); - - if (sushiPerBlock !== null) { - rewardPerBlock = (relPoolShare * Number(sushiPerBlock)) / decimals; - rewardPerDay = rewardPerBlock * blocksPerDay; - } else { - rewardPerSecond = (relPoolShare * Number(sushiPerSecond)) / decimals; - rewardPerDay = rewardPerSecond * 86400; - } - - el['sushiPerDay'] = rewardPerDay; - el['sushiPerYear'] = rewardPerDay * 365; - el['sushiPerYearUsd'] = rewardPerDay * 365 * sushiUsd.sushi.usd; - - return el; -}; - -const prepareLMData = async ( - urlMc1, - urlMc2, - querySushiAllocation, - queryExtraAllocation, - queryChef, - block -) => { - const secondsPerDay = 60 * 60 * 24; - const secondsPerBlock = await getAverageBlockTime(); - const blocksPerDay = secondsPerDay / secondsPerBlock; - const sushiUsd = await utils.getCGpriceData('sushi', true); - - // pull sushi allocation data (sushi rewards) - let sushiAllocation = await request( - urlMc1, - querySushiAllocation.replace('', block) - ); - // pull extra allocation data (extra token rewards) - let extraAllocation = await request( - urlMc2, - queryExtraAllocation.replace('', block) - ); - // pull total allocation points (so we can calc the pct share of a pool) - const sushiMc1 = await request( - urlMc1, - queryChef.replace('', block) - ); - - // //////////////////////////////////////// ETH - if (queryChef.includes('master')) { - details = sushiMc1.masterChefs[0]; - // 1. calc sushi rewards - sushiAllocation = sushiAllocation.pools.map((el) => - buildRewardFields( - el, - details.totalAllocPoint, - sushiUsd, - details.sushiPerBlock, - null, - blocksPerDay - ) - ); - // 2. calc extra token rewards - extraAllocation = extraAllocation.pools.map((el) => - buildRewardFields( - el, - details.totalAllocPoint, - sushiUsd, - details.sushiPerBlock, - null, - blocksPerDay + // get reward token prices + let coins = [ + ...new Set(poolsInfoMC2.map((p) => p.rewardToken).filter((p) => p)), + ].map((t) => `${chainString}:${t}`); + const sushi = `${chainString}:${SUSHI[chainString]?.toLowerCase()}`; + coins = [...coins, sushi]; + const tokensUsd = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${coins.join(',').toLowerCase()}` ) - ); - } else { - // //////////////////////////////////////// OTHER EVM CHAINS - // arbitrum, polygon etc have different fields - details = sushiMc1.miniChefs[0]; - // 1. calc sushi rewards - sushiAllocation = sushiAllocation.pools.map((el) => - buildRewardFields( - el, - details.totalAllocPoint, - sushiUsd, - null, - details.sushiPerSecond, - null - ) - ); - extraAllocation = extraAllocation.pools.map((el) => - buildRewardFields( - el, - details.totalAllocPoint, - sushiUsd, - null, - details.sushiPerSecond, - null - ) - ); - } - - // for the extra allocation pools, we'll need to pull price data - // and calculate the rewardPerYearUsd - let tokenList = extraAllocation.map((el) => el.rewarder.rewardToken); - tokenList = [...new Set(tokenList)]; - let prices = await utils.getCGpriceData(tokenList.join(), false); - const maticPrice = await utils.getCGpriceData( - '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270', - false, - 'polygon-pos' - ); - prices = { ...prices, ...maticPrice }; - - extraAllocation = extraAllocation.map((el) => { - let decimals = 18; - if ( - el.rewarder.rewardToken === '0x4c19596f5aaff459fa38b0f7ed92f11ae6543784' - ) { - decimals = 8; + ).body.coins; + + // for mc1: calc sushi per year in usd + if (chainString === 'ethereum') { + for (const p of poolsInfoMC1) { + p['sushiPerYearUsd'] = + (Number(p.allocPoint) / Number(totalAllocPointMC1)) * + sushiPerBlockMC1 * + blocksPerDay * + 365 * + tokensUsd[sushi].price; + } } - let timeUnit = secondsPerDay; - if ( - el.rewarder.rewardToken !== '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270' - ) { - timeUnit = blocksPerDay; + // for mc2: calc sushi and extra reward per year in usd + for (const p of poolsInfoMC2) { + priceUnit = + chainString === 'ethereum' + ? sushiPerBlockMC2 * blocksPerDay + : sushiPerSecond * secondsPerDay; + + p['sushiPerYearUsd'] = + (Number(p.allocPoint) / Number(totalAllocPointMC2)) * + priceUnit * + 365 * + tokensUsd[sushi].price; + + const coin = tokensUsd[`${chainString}:${p.rewardToken}`]; + p['rewardPerYearUsd'] = + (Number(p.rewardPerSecond) / 10 ** coin?.decimals) * + secondsPerDay * + 365 * + coin?.price; } - el['rewardPerYear'] = - (Number(el.rewarder.rewardPerSecond) / 10 ** decimals) * timeUnit * 365; - el['rewardPerYearUsd'] = el.rewardPerYear * prices[el.rewardToken]?.usd; - - return el; - }); - - // concat and return - const data = [...sushiAllocation, ...extraAllocation]; - - return data; -}; - -const addRewardApy = (el, dataLm) => { - el = { ...el }; - el['sushiPerYearUsd'] = dataLm.find((x) => x.pair === el.id)?.sushiPerYearUsd; - - el['rewardPerYearUsd'] = dataLm.find( - (x) => x.pair === el.id - )?.rewardPerYearUsd; - - el['apySushi'] = (el.sushiPerYearUsd / Number(el.totalValueLockedUSD)) * 100; - - el['apyReward'] = - (el.rewardPerYearUsd / Number(el.totalValueLockedUSD)) * 100; - return el; -}; - -const buildPool = (entry, chainString) => { - const apyFee = Number(entry.apy); - const apySushi = isNaN(entry.apySushi) ? 0 : entry.apySushi; - const apyReward = isNaN(entry.apyReward) ? 0 : entry.apyReward; - const apy = apyFee + apySushi + apyReward; - const symbol = utils.formatSymbol( - `${entry.token0.symbol}-${entry.token1.symbol}` - ); - - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'sushiswap', - symbol, - tvlUsd: entry.totalValueLockedUSD, - apy: apy === null ? 0 : apy, - }; - - return newObj; -}; - -const topLvl = async ( - chainString, - url, - urlMc1, - urlMc2, - querySushiAllocation, - queryExtraAllocation, - queryChef, - timestamp -) => { - const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ - url, - urlMc1, - urlMc2, - ]); - - // pull data - let dataNow = await request(url, query.replace('', block)); - - let queryPriorC = queryPrior; - queryPriorC = queryPriorC.replace('', blockPrior); - let dataPrior = await request(url, queryPriorC); - - // calculate tvl - dataNow = await utils.tvl(dataNow.pairs, chainString); - - // calculate base apy - let data = dataNow.map((el) => utils.apy(el, dataPrior.pairs, 'v2')); - - // get LM reward (no avalanche minichef, exlcuding from lm rewards) - if (chainString !== 'avalanche') { - dataLm = await prepareLMData( - urlMc1, - urlMc2, - querySushiAllocation, - queryExtraAllocation, - queryChef, - block - ); - } else { - dataLm = []; + const dataLM = + chainString === 'ethereum' + ? [...poolsInfoMC1, poolsInfoMC2].flat() + : poolsInfoMC2; + + data = data.map((p) => { + const lm = dataLM.find( + (x) => x.lpToken?.toLowerCase() === p.id?.toLowerCase() + ); + + let apySushi = + (lm?.sushiPerYearUsd / Number(p.totalValueLockedUSD)) * 100; + let apyExtra = + (lm?.rewardPerYearUsd / Number(p.totalValueLockedUSD)) * 100; + let rewardToken = lm?.rewardToken ?? []; + + apySushi = isNaN(apySushi) ? 0 : apySushi; + const apyExtraRewards = isNaN(apyExtra) ? 0 : apyExtra; + const apyReward = apySushi + apyExtraRewards; + + const rewardTokens = + apySushi > 0 && apyExtraRewards > 0 + ? [SUSHI[chainString], rewardToken] + : apySushi > 0 + ? [SUSHI[chainString]] + : apyExtraRewards > 0 + ? [rewardToken] + : []; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'sushiswap', + symbol: utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`), + tvlUsd: p.totalValueLockedUSDlp, + apyBase: Number(p.apy1d), + apyBase7d: Number(p.apy7d), + apyReward, + rewardTokens, + underlyingTokens: [p.token0.id, p.token1.id], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + url: `https://www.sushi.com/${chainString}/pool/v2/${p.id}`, + }; + }); + + return data; + } catch (e) { + if (e.message.includes('Stale subgraph')) return []; + else throw e; } - - // we add the reward apy - data = data.map((el) => addRewardApy(el, dataLm)); - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; }; -const main = async (timestamp = null) => { - // 3 "types" of pools re apy: - // feebased only, - // feebased + sushi incentives, - // feebased + sushi incentives + extra allocation - // the final output contains the sum of these individual values - - let data = await Promise.all([ - topLvl( - 'ethereum', - urlEthereum, - urlMc1, - urlMc2, - querySushiAllocation, - queryExtraAllocation, - queryMasterChef, - timestamp - ), - topLvl( - 'polygon', - urlPolygon, - urlMcPolygon, - urlMcPolygon, - querySushiAllocation, - queryExtraAllocationEVM, - queryMiniChef, - timestamp - ), - topLvl( - 'arbitrum', - urlArbitrum, - urlMcArbitrum, - urlMcArbitrum, - querySushiAllocation, - queryExtraAllocationEVM, - queryMiniChef, - timestamp - ), - topLvl('avalanche', urlAvalanche, null, null, null, null, null, timestamp), +const main = async () => { + let data = await Promise.allSettled([ + topLvl('ethereum', urlEthereum, urlMc2, 1), + topLvl('arbitrum', urlArbitrum, null, 42161), + topLvl('polygon', urlPolygon, null, 137), + topLvl('avalanche', urlAvalanche, null, 43114), + topLvl('base', urlBase, null, 8453), ]); - return data.flat(); + return data + .filter((i) => i.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((p) => utils.keepFinite(p)); }; module.exports = { - timetravel: true, + timetravel: false, apy: main, }; diff --git a/src/adaptors/swap.coffee/index.js b/src/adaptors/swap.coffee/index.js new file mode 100644 index 0000000000..3f22a7fd4f --- /dev/null +++ b/src/adaptors/swap.coffee/index.js @@ -0,0 +1,94 @@ +const utils = require('../utils'); + +const MIN_TVL_USD = 10000 +const TON_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c" + +function extractPoolSymbol(tokens) { + const parts = [] + + for (let asset of tokens) { + parts.push(asset["address"]["address"] === "native" ? "TON" : asset["metadata"]["symbol"]) + } + + return parts.join("-") +} + +function normalizeAddress(address) { + return address === "native" ? TON_ADDRESS : address +} + +const poolsFunction = async () => { + let allPools = [] + + for (let trusted of ["true", "false"]) { + let size = 0 + for (let page = 1; ;page++) { + const response = (await utils.getData(`https://backend.swap.coffee/v1/yield/pools?blockchains=ton&providers=coffee&trusted=${trusted}&size=100&page=${page}`))[0] + const pools = response["pools"] + if (pools.length === 0) { + break + } + + allPools.push(...pools) + size += pools.length + if (size >= response["total_count"]) { + break + } + } + } + + // No reason to load pools with TVL < 10k USD. + // DefiLlama only displays pools with >10k TVL, + // so pools with less TVL than that will appear on the adapter but not on defillama + allPools = allPools.filter((pool) => pool["pool_statistics"]["tvl_usd"] >= MIN_TVL_USD) + + let poolRewards = {} + for (let pool of allPools) { + const statisticsBoostApr = pool["pool_statistics"]["boost_apr"] + if (statisticsBoostApr === 0) { + continue + } + const address = pool["address"] + + const detailed = await utils.getData(`https://backend.swap.coffee/v1/yield/pool/${address}`) + const boosts = detailed["pool"]["boosts"] + + const rewards = [] + let boostAprSum = 0 + for (let boost of boosts) { + rewards.push(normalizeAddress(boost["reward_token"]["address"]["address"])) + boostAprSum += boost["apr"] + } + if (boostAprSum < statisticsBoostApr && !rewards.includes(TON_ADDRESS)) { + rewards.push(TON_ADDRESS) + } + poolRewards[address] = rewards + } + + return allPools.map((pool) => { + const poolAddress = pool["address"] + const statistics = pool["pool_statistics"] + const tokens = pool["tokens"] + const boostApr = statistics["boost_apr"] + + return { + pool: `${pool["address"]}-ton`.toLowerCase(), + chain: "TON", + project: "swap.coffee", + symbol: extractPoolSymbol(tokens), + tvlUsd: statistics["tvl_usd"], + apyBase: statistics["lp_apr"], + apyReward: boostApr > 0 ? boostApr : undefined, + rewardTokens: boostApr > 0 ? poolRewards[poolAddress] : undefined, + underlyingTokens: tokens.map((token) => normalizeAddress(token["address"]["address"])), + poolMeta: `AMM: ${pool["pool"]["amm_type"]}`, + url: `https://swap.coffee/earn/pool/${poolAddress}` + }; + }) +} + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://swap.coffee/earn', +}; \ No newline at end of file diff --git a/src/adaptors/swapfish/abis/lp.json b/src/adaptors/swapfish/abis/lp.json new file mode 100644 index 0000000000..53582c1ed6 --- /dev/null +++ b/src/adaptors/swapfish/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/swapfish/abis/masterchef.json b/src/adaptors/swapfish/abis/masterchef.json new file mode 100644 index 0000000000..4254887556 --- /dev/null +++ b/src/adaptors/swapfish/abis/masterchef.json @@ -0,0 +1,572 @@ +[ + { + "inputs": [ + { + "internalType": "contract FishToken", + "name": "_cake", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_cakePerSecond", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IBEP20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allocRatio", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cake", + "outputs": [ + { + "internalType": "contract FishToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cakePerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "enterStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "leaveStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lpTokenAdded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ownerFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingCake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IBEP20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accCakePerShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_mintAmt", + "type": "uint256" + } + ], + "name": "reduceEmissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_allocRatio", + "type": "uint8" + } + ], + "name": "setAllocRatio", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + } + ], + "name": "setStartTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "multiplierNumber", + "type": "uint256" + } + ], + "name": "updateMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/swapfish/index.js b/src/adaptors/swapfish/index.js new file mode 100644 index 0000000000..da6dd79317 --- /dev/null +++ b/src/adaptors/swapfish/index.js @@ -0,0 +1,240 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); + +const FISH_TOKEN = '0xb348B87b23D5977E2948E6f36ca07E1EC94d7328'; +const CHAINS = { + arbitrum: { + masterchef: '0x33141e87ad2DFae5FBd12Ed6e61Fa2374aAeD029', + }, + bsc: { + masterchef: '0x671eFBa3F6874485cC39535fa7b525fe764985e9', + }, +}; + +const getPairInfo = async (pair, tokenAddress, chain) => { + const [tokenSymbol, tokenDecimals] = await Promise.all( + ['erc20:symbol', 'erc20:decimals'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: tokenAddress.map((address) => ({ + target: address, + })), + chain: chain, + requery: true, + }) + ) + ); + + return { + lpToken: pair.toLowerCase(), + pairName: tokenSymbol.output.map((e) => e.output).join('-'), + token0: { + address: tokenAddress[0], + symbol: tokenSymbol.output[0].output, + decimals: tokenDecimals.output[0].output, + }, + token1: { + address: tokenAddress[1], + symbol: tokenSymbol.output[1].output, + decimals: tokenDecimals.output[1].output, + }, + }; +}; + +const getPrices = async (addresses, chain) => { + const coins = addresses + .map((address) => { + // FISH is bridgeable, take price from the main chain + const priceChain = address == FISH_TOKEN ? 'arbitrum' : chain; + return `${priceChain}:${address}`; + }) + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + FishPerSecond, + FishPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const FishPerYear = FishPerSecond * 365 * 24 * 60 * 60; + return ((poolWeight * FishPerYear * FishPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, address: token0Address } = token0; + const { decimals: token1Decimals, address: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolsApy = []; + + for (chain in CHAINS) { + masterchefAddress = CHAINS[chain]['masterchef']; + + const poolLength = await sdk.api.abi.call({ + target: masterchefAddress, + chain: chain, + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: masterchefAddress, + chain: chain, + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const FishPerSecond = await sdk.api.abi.call({ + target: masterchefAddress, + chain: chain, + abi: masterChefABI.find((e) => e.name === 'cakePerSecond'), + }); + const normalizedFishPerSecond = FishPerSecond.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: masterchefAddress, + params: i, + })), + chain: chain, + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter( + (k) => + ![ + '0xb348B87b23D5977E2948E6f36ca07E1EC94d7328', + '0x666F4429681BeAfE36208FF9D0d16665755f488a', + '0x089a4b6E7EF16e401C24DAE1e736dc33Ab8aDE52', + '0x4CD8Ba83b30f3a39a5D63E086D31509399415b49', + ].includes(k.lpToken) + ); + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [masterchefAddress] : null, + })), + chain: chain, + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: chain, + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1], chain); + const pairInfos = await Promise.all( + pools.map((_, index) => + getPairInfo(lpTokens[index], [tokens0[index], tokens1[index]], chain) + ) + ); + + for (const [i, pool] of pools.entries()) { + const pairInfo = pairInfos[i]; + const poolInfo = pool; + const reserves = reservesData[i]; + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const apy = calculateApy( + poolInfo, + totalAllocPoint, + normalizedFishPerSecond, + tokensPrices[FISH_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + poolsApy.push({ + pool: pool.lpToken, + chain: utils.formatChain(chain), + project: 'swapfish', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyReward: apy, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [FISH_TOKEN], + }); + } + } + + return poolsApy; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://swapfish.fi/', +}; diff --git a/src/adaptors/swapr/api.js b/src/adaptors/swapr-v2/api.js similarity index 100% rename from src/adaptors/swapr/api.js rename to src/adaptors/swapr-v2/api.js diff --git a/src/adaptors/swapr-v2/constants.js b/src/adaptors/swapr-v2/constants.js new file mode 100644 index 0000000000..1a9417c8e6 --- /dev/null +++ b/src/adaptors/swapr-v2/constants.js @@ -0,0 +1,12 @@ +const sdk = require('@defillama/sdk'); +exports.constants = { + PROJECT_NAME: 'swapr-v2', + XDAI_CHAIN: 'xdai', + ARBITRUM_CHAIN: 'arbitrum', + KPI_ENDPOINT: 'https://api.thegraph.com/subgraphs/name/luzzif/carrot-xdai', + XDAI_ENDPOINT: + 'https://api.thegraph.com/subgraphs/name/dxgraphs/swapr-xdai-v2', + ARBITRUM_ENDPOINT: sdk.graph.modifyEndpoint( + '8CtcD8EzHq6YyQrnb4XFz2pnwXVx3nHruj4pcDjHRKpt' + ), +}; diff --git a/src/adaptors/swapr-v2/index.js b/src/adaptors/swapr-v2/index.js new file mode 100644 index 0000000000..a5ce2427b2 --- /dev/null +++ b/src/adaptors/swapr-v2/index.js @@ -0,0 +1,197 @@ +const utils = require('../utils'); +const { request } = require('graphql-request'); + +const { + queries: { + QUERY_PAIRS, + QUERY_LIQUIDITY_MINING_CAMPAIGNS, + QUERY_KPI_TOKENS, + QUERY_TOKEN, + QUERY_NATIVE_CURRENCY_USD, + }, +} = require('./api'); +const { + constants: { + PROJECT_NAME, + XDAI_CHAIN, + ARBITRUM_CHAIN, + XDAI_ENDPOINT, + ARBITRUM_ENDPOINT, + KPI_ENDPOINT, + }, +} = require('./constants'); + +const rewardsAPR = {}; + +const createPool = (pair, chainString) => { + const { id, token0, token1, totalValueLockedUSD: tvlUsd } = pair; + + const symbol = utils.formatSymbol(`${token0.symbol}-${token1.symbol}`); + + const apyReward = rewardsAPR[id.toLowerCase()]; + + let chain = utils.formatChain(chainString); + + if (chain === 'Xdai') chain = 'xDai'; + + return { + pool: id, + chain, + project: PROJECT_NAME, + symbol, + tvlUsd, + apyReward, + rewardTokens: ['0x6cacdb97e3fc8136805a9e7c342d866ab77d0957'], + }; +}; + +const calculateRewardsApy = async ( + endpoint, + pair, + liquidityMiningCampaigns, + kpiTokens, + nativeCurrencyPrice +) => { + const normalizedPairId = pair.id.toLowerCase(); + + // filter by id and active + const activeCampaigns = liquidityMiningCampaigns.filter( + (campaign) => + campaign.stakablePair.id.toLowerCase() === normalizedPairId && + campaign.endsAt * 1000 >= Date.now() + ); + + if (!activeCampaigns.length) { + rewardsAPR[normalizedPairId] = 0; + return; + } + + for (const campaign of activeCampaigns) { + // duration in days + const duration = campaign.duration / 24 / 3600; + + let totalValueUSD = 0; + + for (const reward of campaign.rewards) { + const { token, amount } = reward; + + const kpiToken = kpiTokens?.find( + ({ id }) => id.toLowerCase() === token.id.toLowerCase() + ); + + let tokenAddress; + + if (kpiToken) { + tokenAddress = kpiToken.collateral.token.id; + } else { + tokenAddress = token.id; + } + + const { + token: { derivedNativeCurrency }, + } = await request( + endpoint, + QUERY_TOKEN.replace('', `"${tokenAddress.toLowerCase()}"`) + ); + + const tokenPrice = derivedNativeCurrency * nativeCurrencyPrice; + + totalValueUSD += tokenPrice * amount; + } + + const [token0, token1] = await Promise.all([ + request( + endpoint, + QUERY_TOKEN.replace( + '', + `"${pair.token0.id.toLowerCase()}"` + ) + ), + request( + endpoint, + QUERY_TOKEN.replace( + '', + `"${pair.token1.id.toLowerCase()}"` + ) + ), + ]); + + const token0Price = + token0.token.derivedNativeCurrency * nativeCurrencyPrice; + const token1Price = + token1.token.derivedNativeCurrency * nativeCurrencyPrice; + + const lpTokenPrice = + (2 * + (Math.sqrt(pair.reserve0 * pair.reserve1) * + Math.sqrt(token0Price * token1Price))) / + pair.totalSupply; + + const tvlCampaign = campaign.stakedAmount * lpTokenPrice; + + const apr = ((totalValueUSD / duration) * 365 * 100) / tvlCampaign; + + if (rewardsAPR[normalizedPairId]) { + rewardsAPR[normalizedPairId] += apr; + } else { + rewardsAPR[normalizedPairId] = apr; + } + } +}; + +const topLvl = async (chainString, endpoint, timestamp) => { + const [block] = await utils.getBlocks(chainString, timestamp, [endpoint]); + + const { liquidityMiningCampaigns } = await request( + endpoint, + QUERY_LIQUIDITY_MINING_CAMPAIGNS + ); + + let pairs = await request( + endpoint, + QUERY_PAIRS.replace('', block) + ); + + const { + bundle: { nativeCurrencyPrice }, + } = await request(endpoint, QUERY_NATIVE_CURRENCY_USD); + + //currently carrot is only on xdai chain + let kpiTokens; + + if (chainString === XDAI_CHAIN) { + const response = await request(KPI_ENDPOINT, QUERY_KPI_TOKENS); + kpiTokens = response.kpiTokens; + } + + pairs = await utils.tvl(pairs.pairs, chainString); + + for (const pair of pairs) { + await calculateRewardsApy( + endpoint, + pair, + liquidityMiningCampaigns, + kpiTokens, + nativeCurrencyPrice + ); + } + + return pairs.map((pair) => createPool(pair, chainString)); +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([ + topLvl(XDAI_CHAIN, XDAI_ENDPOINT, timestamp), + topLvl(ARBITRUM_CHAIN, ARBITRUM_ENDPOINT, timestamp), + ]); + + return data + .flat() + .filter((pool) => isFinite(pool.apyReward) && !isNaN(pool.apyReward)); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://swapr.eth.link/#/pools?chainId=1', +}; diff --git a/src/adaptors/swapr/constants.js b/src/adaptors/swapr/constants.js deleted file mode 100644 index cd14d3eb52..0000000000 --- a/src/adaptors/swapr/constants.js +++ /dev/null @@ -1,8 +0,0 @@ -exports.constants = { - PROJECT_NAME: "swapr", - XDAI_CHAIN: "xdai", - ARBITRUM_CHAIN: "arbitrum", - KPI_ENDPOINT: "https://api.thegraph.com/subgraphs/name/luzzif/carrot-xdai", - XDAI_ENDPOINT: "https://api.thegraph.com/subgraphs/name/dxgraphs/swapr-xdai-v2", - ARBITRUM_ENDPOINT: "https://api.thegraph.com/subgraphs/name/dxgraphs/swapr-arbitrum-one-v3", -} diff --git a/src/adaptors/swapr/index.js b/src/adaptors/swapr/index.js deleted file mode 100644 index 8bee4a7d1d..0000000000 --- a/src/adaptors/swapr/index.js +++ /dev/null @@ -1,132 +0,0 @@ -const utils = require('../utils') -const { request } = require('graphql-request') - -const {queries: { QUERY_PAIRS, QUERY_LIQUIDITY_MINING_CAMPAIGNS, QUERY_KPI_TOKENS, QUERY_TOKEN, QUERY_NATIVE_CURRENCY_USD }} = require("./api") -const {constants: { PROJECT_NAME, XDAI_CHAIN, ARBITRUM_CHAIN, XDAI_ENDPOINT, ARBITRUM_ENDPOINT, KPI_ENDPOINT }} = require("./constants") - -const rewardsAPR = {} - -const createPool = (pair, chainString) => { - const { id, token0, token1, totalValueLockedUSD: tvlUsd } = pair - - const symbol = utils.formatSymbol( - `${token0.symbol}-${token1.symbol}` - ); - - const apy = rewardsAPR[id.toLowerCase()] - - let chain = utils.formatChain(chainString) - - if(chain === "Xdai") chain = "xDai" - - return { - pool: id, - chain, - project: PROJECT_NAME, - symbol, - tvlUsd, - apy, - } -} - -const calculateRewardsApy = async (endpoint, pair, liquidityMiningCampaigns, kpiTokens, nativeCurrencyPrice) => { - const normalizedPairId = pair.id.toLowerCase() - - // filter by id and active - const activeCampaigns = liquidityMiningCampaigns.filter(campaign => campaign.stakablePair.id.toLowerCase() === normalizedPairId && campaign.endsAt * 1000 >= Date.now()) - - if(!activeCampaigns.length){ - rewardsAPR[normalizedPairId] = 0 - return - } - - for(const campaign of activeCampaigns){ - // duration in days - const duration = campaign.duration / 24 / 3600 - - let totalValueUSD = 0 - - for(const reward of campaign.rewards) { - const { token, amount } = reward - - const kpiToken = kpiTokens?.find(({ id }) => id.toLowerCase() === token.id.toLowerCase()) - - let tokenAddress; - - if (kpiToken) { - tokenAddress = kpiToken.collateral.token.id - } else { - tokenAddress = token.id - } - - const {token: { derivedNativeCurrency }} = await request(endpoint, QUERY_TOKEN.replace('',`"${tokenAddress.toLowerCase()}"`)) - - const tokenPrice = derivedNativeCurrency * nativeCurrencyPrice - - totalValueUSD += tokenPrice * amount - } - - const [token0, token1] = await Promise.all([ - request(endpoint, QUERY_TOKEN.replace('',`"${pair.token0.id.toLowerCase()}"`)), - request(endpoint, QUERY_TOKEN.replace('',`"${pair.token1.id.toLowerCase()}"`)) - ]) - - const token0Price = token0.token.derivedNativeCurrency * nativeCurrencyPrice - const token1Price = token1.token.derivedNativeCurrency * nativeCurrencyPrice - - const lpTokenPrice = (2 * (Math.sqrt(pair.reserve0 * pair.reserve1) * Math.sqrt(token0Price * token1Price))) / pair.totalSupply - - const tvlCampaign = campaign.stakedAmount * lpTokenPrice - - const apr = (totalValueUSD / duration) * 365 * 100 / tvlCampaign - - if (rewardsAPR[normalizedPairId]){ - rewardsAPR[normalizedPairId] += apr - } else { - rewardsAPR[normalizedPairId] = apr - } - } - -} - -const topLvl = async (chainString, endpoint, timestamp) => { - const [block] = await utils.getBlocks(chainString, timestamp, [ - endpoint, - ]) - - const { liquidityMiningCampaigns } = await request(endpoint, QUERY_LIQUIDITY_MINING_CAMPAIGNS) - - let pairs = await request(endpoint, QUERY_PAIRS.replace('', block)) - - const {bundle: { nativeCurrencyPrice }} = await request(endpoint, QUERY_NATIVE_CURRENCY_USD) - - //currently carrot is only on xdai chain - let kpiTokens; - - if(chainString === XDAI_CHAIN) { - const response = await request(KPI_ENDPOINT, QUERY_KPI_TOKENS) - kpiTokens = response.kpiTokens - } - - pairs = await utils.tvl(pairs.pairs, chainString) - - for (const pair of pairs){ - await calculateRewardsApy(endpoint, pair, liquidityMiningCampaigns, kpiTokens, nativeCurrencyPrice) - } - - return pairs.map(pair => createPool(pair, chainString)) -} - -const main = async (timestamp = null) => { - const data = await Promise.all([ - topLvl(XDAI_CHAIN, XDAI_ENDPOINT, timestamp), - topLvl(ARBITRUM_CHAIN, ARBITRUM_ENDPOINT, timestamp) - ]); - - return data.flat().filter(pool => isFinite(pool.apy) && !isNaN(pool.apy)) -} - -module.exports = { - timetravel: true, - apy: main, -} diff --git a/src/adaptors/swell-earn/Accountant.json b/src/adaptors/swell-earn/Accountant.json new file mode 100644 index 0000000000..b0ec287e63 --- /dev/null +++ b/src/adaptors/swell-earn/Accountant.json @@ -0,0 +1,667 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + }, + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + }, + { + "internalType": "uint96", + "name": "startingExchangeRate", + "type": "uint96" + }, + { + "internalType": "address", + "name": "_base", + "type": "address" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__LowerBoundTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__ManagementFeeTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__OnlyCallableByBoringVault", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__Paused", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__UpdateDelayTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__UpperBoundTooSmall", + "type": "error" + }, + { + "inputs": [], + "name": "AccountantWithRateProviders__ZeroFeesOwed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "oldDelay", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newDelay", + "type": "uint32" + } + ], + "name": "DelayInSecondsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint96", + "name": "oldRate", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "newRate", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "currentTime", + "type": "uint64" + } + ], + "name": "ExchangeRateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FeesClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldBound", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newBound", + "type": "uint16" + } + ], + "name": "LowerBoundUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldFee", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newFee", + "type": "uint16" + } + ], + "name": "ManagementFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPayout", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPayout", + "type": "address" + } + ], + "name": "PayoutAddressUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isPegged", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateProvider", + "type": "address" + } + ], + "name": "RateProviderUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "oldBound", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "newBound", + "type": "uint16" + } + ], + "name": "UpperBoundUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "accountantState", + "outputs": [ + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + }, + { + "internalType": "uint128", + "name": "feesOwedInBase", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "totalSharesLastUpdate", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "exchangeRate", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "lastUpdateTimestamp", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "isPaused", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + }, + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "base", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "feeAsset", + "type": "address" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRate", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "quote", + "type": "address" + } + ], + "name": "getRateInQuote", + "outputs": [ + { + "internalType": "uint256", + "name": "rateInQuote", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "quote", + "type": "address" + } + ], + "name": "getRateInQuoteSafe", + "outputs": [ + { + "internalType": "uint256", + "name": "rateInQuote", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRateSafe", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "name": "rateProviderData", + "outputs": [ + { + "internalType": "bool", + "name": "isPeggedToBase", + "type": "bool" + }, + { + "internalType": "contract IRateProvider", + "name": "rateProvider", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "isPeggedToBase", + "type": "bool" + }, + { + "internalType": "address", + "name": "rateProvider", + "type": "address" + } + ], + "name": "setRateProviderData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "minimumUpdateDelayInSeconds", + "type": "uint32" + } + ], + "name": "updateDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "newExchangeRate", + "type": "uint96" + } + ], + "name": "updateExchangeRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeLower", + "type": "uint16" + } + ], + "name": "updateLower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "managementFee", + "type": "uint16" + } + ], + "name": "updateManagementFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payoutAddress", + "type": "address" + } + ], + "name": "updatePayoutAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "allowedExchangeRateChangeUpper", + "type": "uint16" + } + ], + "name": "updateUpper", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract BoringVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/swell-earn/EarnVault.json b/src/adaptors/swell-earn/EarnVault.json new file mode 100644 index 0000000000..18b0f9b217 --- /dev/null +++ b/src/adaptors/swell-earn/EarnVault.json @@ -0,0 +1,806 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "InsufficientBalance", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "AuthorityUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Enter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Exit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "authority", + "outputs": [ + { + "internalType": "contract Authority", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "enter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "contract ERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "hook", + "outputs": [ + { + "internalType": "contract BeforeTransferHook", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "targets", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "manage", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Authority", + "name": "newAuthority", + "type": "address" + } + ], + "name": "setAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_hook", + "type": "address" + } + ], + "name": "setBeforeTransferHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/swell-earn/index.ts b/src/adaptors/swell-earn/index.ts new file mode 100644 index 0000000000..d221a5ece7 --- /dev/null +++ b/src/adaptors/swell-earn/index.ts @@ -0,0 +1,81 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const EarnVault = require('./EarnVault.json'); +const Accountant = require('./Accountant.json'); + +const earnETH = '0x9Ed15383940CC380fAEF0a75edacE507cC775f22'; +const accountant = '0x411c78BC8c36c3c66784514f28c56209e1DF2755'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const apy = async () => { + // TVL calculation + const totalSupply = + ( + await sdk.api.abi.call({ + target: earnETH, + abi: EarnVault.find((m) => m.name === 'totalSupply'), + }) + ).output / 1e18; + + const priceKey = `ethereum:${WETH}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const currentRate = ( + await sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === 'getRate'), + }) + ).output; + const tvlUsd = totalSupply * (currentRate / 1e18) * ethPrice; + + // APY calculations + const now = Math.floor(Date.now() / 1000); + + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + + const block1dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp1dayAgo}`) + ).data.height; + const block7dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp7dayAgo}`) + ).data.height; + + const exchangeRates = await Promise.all([ + sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === 'getRate'), + block: block1dayAgo, + }), + sdk.api.abi.call({ + target: accountant, + abi: Accountant.find((m) => m.name === 'getRate'), + block: block7dayAgo, + }), + ]); + const apr1d = ((currentRate - exchangeRates[0].output) / 1e18) * 365 * 100; + + const apr7d = + ((currentRate - exchangeRates[1].output) / 1e18 / 7) * 365 * 100; + + return [ + { + pool: earnETH, + project: 'swell-earn', + chain: 'Ethereum', + symbol: 'earnETH', + tvlUsd: tvlUsd, + apyBase: apr1d, + apyBase7d: apr7d, + underlyingTokens: [WETH], + }, + ]; +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.swellnetwork.io/earn/vaults', +}; diff --git a/src/adaptors/swell-liquid-restaking/abi.json b/src/adaptors/swell-liquid-restaking/abi.json new file mode 100644 index 0000000000..0a4c0a9c88 --- /dev/null +++ b/src/adaptors/swell-liquid-restaking/abi.json @@ -0,0 +1,1163 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "AddressAlreadyInWhitelist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "AddressMissingFromWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "CannotBeZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "CannotBurnZeroRswETH", + "type": "error" + }, + { + "inputs": [], + "name": "CannotReferSelf", + "type": "error" + }, + { + "inputs": [], + "name": "CannotRepriceWithZeroRswETHSupply", + "type": "error" + }, + { + "inputs": [], + "name": "CoreMethodsPaused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "rswETHAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minRswETH", + "type": "uint256" + } + ], + "name": "InsufficientRswETHReceived", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidETHDeposit", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMethodCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidPreRewardETHReserves", + "type": "error" + }, + { + "inputs": [], + "name": "NoTokensToWithdraw", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "remainingTime", + "type": "uint256" + } + ], + "name": "NotEnoughTimeElapsedForReprice", + "type": "error" + }, + { + "inputs": [], + "name": "NotInWhitelist", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDepositManager", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "name": "PRBMath_MulDiv18_Overflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "denominator", + "type": "uint256" + } + ], + "name": "PRBMath_MulDiv_Overflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repriceDiff", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumRepriceDiff", + "type": "uint256" + } + ], + "name": "RepriceDifferenceTooLarge", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repriceRswETHDiff", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumRswETHRepriceDiff", + "type": "uint256" + } + ], + "name": "RepriceRswETHDifferenceTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "RewardPercentageTotalOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "WhitelistAlreadyDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "WhitelistAlreadyEnabled", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "AddedToWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_ethSpent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_rswETHReceived", + "type": "uint256" + } + ], + "name": "DepoistManagerDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rswETHMinted", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalETHDeposited", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "referral", + "type": "address" + } + ], + "name": "ETHDepositReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rswETHBurned", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethReturned", + "type": "uint256" + } + ], + "name": "ETHWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMaximumRepriceDifferencePercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMaximumRepriceDifferencePercentage", + "type": "uint256" + } + ], + "name": "MaximumRepriceDifferencePercentageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMaximumRepriceRswETHDifferencePercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMaximumRepriceRswETHDifferencePercentage", + "type": "uint256" + } + ], + "name": "MaximumRepriceRswETHDifferencePercentageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMinimumRepriceTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMinimumRepriceTime", + "type": "uint256" + } + ], + "name": "MinimumRepriceTimeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercentage", + "type": "uint256" + } + ], + "name": "NodeOperatorRewardPercentageUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "RemovedFromWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newEthReserves", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRswETHToETHRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nodeOperatorRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "swellTreasuryRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalETHDeposited", + "type": "uint256" + } + ], + "name": "Reprice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercentage", + "type": "uint256" + } + ], + "name": "SwellTreasuryRewardPercentageUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "WhitelistDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "WhitelistEnabled", + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, + { + "inputs": [], + "name": "AccessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "addToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_addresses", + "type": "address[]" + } + ], + "name": "batchAddToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_addresses", + "type": "address[]" + } + ], + "name": "batchRemoveFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minRswETH", + "type": "uint256" + } + ], + "name": "depositViaDepositManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "referral", + "type": "address" + } + ], + "name": "depositWithReferral", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "disableWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ethToRswETHRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IAccessControlManager", + "name": "_accessControlManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRepriceETHReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRepriceUNIX", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumRepriceDifferencePercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumRepriceRswETHDifferencePercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumRepriceTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nodeOperatorRewardPercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_preRewardETHReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newETHRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_rswETHTotalSupply", + "type": "uint256" + } + ], + "name": "reprice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rswETHToETHRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maximumRepriceDifferencePercentage", + "type": "uint256" + } + ], + "name": "setMaximumRepriceDifferencePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maximumRepriceRswETHDifferencePercentage", + "type": "uint256" + } + ], + "name": "setMaximumRepriceRswETHDifferencePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumRepriceTime", + "type": "uint256" + } + ], + "name": "setMinimumRepriceTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newNodeOperatorRewardPercentage", + "type": "uint256" + } + ], + "name": "setNodeOperatorRewardPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newSwellTreasuryRewardPercentage", + "type": "uint256" + } + ], + "name": "setSwellTreasuryRewardPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "swellTreasuryRewardPercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalETHDeposited", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedAddresses", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_token", + "type": "address" + } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/swell-liquid-restaking/index.js b/src/adaptors/swell-liquid-restaking/index.js new file mode 100644 index 0000000000..b4f60ef410 --- /dev/null +++ b/src/adaptors/swell-liquid-restaking/index.js @@ -0,0 +1,165 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const { BigNumber } = require('ethers'); + +const abi = require('./abi.json'); + +const rswETH = '0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: rswETH, + abi: abi.find((m) => m.name === 'totalSupply'), + }) + ).output / 1e18; + + const repriceEvents = await get7dRepriceEvents() + // sort by blockNumber descending + repriceEvents.sort((a,b) => (b.blockNumber - a.blockNumber)); + + const eventNow = repriceEvents[0]; + const eventPrev = repriceEvents[1]; + const { closestBefore, closestAfter, timestamp7DaysAgo } = await getCloseestTo7dAgo(repriceEvents); + + const interpolatedRate = await interpolate7d(closestBefore, closestAfter, timestamp7DaysAgo); + const startTime = await sdk.api.util.getTimestamp(eventPrev.blockNumber, "ethereum"); + const endTime = await sdk.api.util.getTimestamp(eventNow.blockNumber, "ethereum"); + + const apr1d = await calcRate(eventNow, eventPrev); + + // Calculate 7-day APR using BigNumber operations + const currentRate = BigNumber.from(eventNow.decoded.newRswETHToETHRate.toString()); + const sevenDayRateChange = currentRate.mul(BigNumber.from(10).pow(18)).div(interpolatedRate).sub(BigNumber.from(10).pow(18)); + const timeElapsed = BigNumber.from(endTime - timestamp7DaysAgo); + const apr7d = sevenDayRateChange.mul(365 * 86400).div(timeElapsed).mul(100).toString() / 1e18; + + const priceKey = `ethereum:${rswETH}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const rate = (await sdk.api.abi.call({ + target: rswETH, + abi: abi.find((m) => m.name === 'getRate'), + })).output / 1e18; + const tvlUsd = totalSupply * rate * ethPrice; + + return [ + { + pool: rswETH, + project: 'swell-liquid-restaking', + chain: 'Ethereum', + symbol: 'rswETH', + tvlUsd: tvlUsd, + apyBase: apr1d, + apyBase7d: apr7d, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], + }, + ]; +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.swellnetwork.io/stake/rsweth', +}; + +async function get7dRepriceEvents() { + + const timestampNow = Math.floor(Date.now() / 1000); + // going with 14 days to allow buffer + const timestamp14dayAgo = timestampNow - 86400 * 14; + + const blockNow = await sdk.api.util.getLatestBlock("ethereum") + const block14dayAgo = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestamp14dayAgo}`) + ).data.height; + + const iface = new ethers.utils.Interface([ + 'event Reprice (uint256 newEthReserves, uint256 newRswETHToETHRate, uint256 nodeOperatorRewards, uint256 swellTreasuryRewards, uint256 totalETHDeposited)', + ]); + + const repriceEvents = ( + await sdk.api2.util.getLogs({ + target: rswETH, + topic: '', + fromBlock: block14dayAgo, + toBlock: blockNow.number, + keys: [], + topics: [iface.getEventTopic('Reprice')], + chain: "ethereum", + entireLog: true, + }) + ).output + .filter((ev) => !ev.removed) + .map((ev) => { + ev.decoded = iface.parseLog(ev).args + return ev + } + ); + + return repriceEvents; +} + +async function calcRate( + eventNow, + eventPrev +) { + const rateDelta = (eventNow.decoded[1]/eventPrev.decoded[1]) - 1; + const blockDelta = (eventNow.blockNumber - eventPrev.blockNumber); + const timeDeltaSeconds = blockDelta*12; // assuming 12 seconds per block + const apr1d = (rateDelta*365*100)/(timeDeltaSeconds/86400); + + return apr1d; +} + + +async function getCloseestTo7dAgo(repriceEvents) { + const timestampNow = Math.floor(Date.now() / 1000); + const timestamp7DaysAgo = timestampNow - 86400 * 7; + + let closestBefore = null; + let closestAfter = null; + let minDiffBefore = Infinity; + let minDiffAfter = Infinity; + + for (const repriceEvent of repriceEvents) { + const eventTimestamp = await sdk.api.util.getTimestamp(repriceEvent.blockNumber, "ethereum"); + const timeDiff = eventTimestamp - timestamp7DaysAgo; + + if (timeDiff <= 0 && Math.abs(timeDiff) < minDiffBefore) { + minDiffBefore = Math.abs(timeDiff); + closestBefore = repriceEvent; + } else if (timeDiff > 0 && timeDiff < minDiffAfter) { + minDiffAfter = timeDiff; + closestAfter = repriceEvent; + } + } + + //console.log("Closest event before 7 days ago:", closestBefore); + //console.log("Closest event after 7 days ago:", closestAfter); + + return { closestBefore, closestAfter, timestamp7DaysAgo }; +} + +async function interpolate7d(closestBefore, closestAfter, timestamp7DaysAgo) { + const beforeTimestamp = await sdk.api.util.getTimestamp(closestBefore.blockNumber, "ethereum"); + const afterTimestamp = await sdk.api.util.getTimestamp(closestAfter.blockNumber, "ethereum"); + + const timeDiff = afterTimestamp - beforeTimestamp; + const rateBefore = BigNumber.from(closestBefore.decoded.newRswETHToETHRate.toString()); + const rateAfter = BigNumber.from(closestAfter.decoded.newRswETHToETHRate.toString()); + + const rateDiff = rateAfter.sub(rateBefore); + const timeRatio = BigNumber.from(Math.floor((timestamp7DaysAgo - beforeTimestamp) / timeDiff * 1e18).toString()); + + const interpolatedRateBN = rateBefore.add( + rateDiff.mul(timeRatio).div(BigNumber.from(10).pow(18)) + ); + + //console.log("Interpolated rate:", interpolatedRateBN.toString()); + return interpolatedRateBN; +} \ No newline at end of file diff --git a/src/adaptors/swell-liquid-staking/abi.json b/src/adaptors/swell-liquid-staking/abi.json new file mode 100644 index 0000000000..70c737f444 --- /dev/null +++ b/src/adaptors/swell-liquid-staking/abi.json @@ -0,0 +1,745 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "AddressAlreadyInWhitelist", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "AddressMissingFromWhitelist", + "type": "error" + }, + { "inputs": [], "name": "BotMethodsPaused", "type": "error" }, + { "inputs": [], "name": "CannotBeZeroAddress", "type": "error" }, + { "inputs": [], "name": "CannotRepriceWithZeroSwETHSupply", "type": "error" }, + { "inputs": [], "name": "CoreMethodsPaused", "type": "error" }, + { "inputs": [], "name": "InvalidETHDeposit", "type": "error" }, + { "inputs": [], "name": "InvalidMethodCall", "type": "error" }, + { "inputs": [], "name": "InvalidPreRewardETHReserves", "type": "error" }, + { "inputs": [], "name": "NoActiveValidators", "type": "error" }, + { "inputs": [], "name": "NoTokensToWithdraw", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "remainingTime", "type": "uint256" } + ], + "name": "NotEnoughTimeElapsedForReprice", + "type": "error" + }, + { "inputs": [], "name": "NotInWhitelist", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "x", "type": "uint256" }, + { "internalType": "uint256", "name": "y", "type": "uint256" } + ], + "name": "PRBMath_MulDiv18_Overflow", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "x", "type": "uint256" }, + { "internalType": "uint256", "name": "y", "type": "uint256" }, + { "internalType": "uint256", "name": "denominator", "type": "uint256" } + ], + "name": "PRBMath_MulDiv_Overflow", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "repriceDiff", "type": "uint256" }, + { + "internalType": "uint256", + "name": "maximumRepriceDiff", + "type": "uint256" + } + ], + "name": "RepriceDifferenceTooLarge", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repriceswETHDiff", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximumswETHRepriceDiff", + "type": "uint256" + } + ], + "name": "RepriceswETHDifferenceTooLarge", + "type": "error" + }, + { "inputs": [], "name": "RewardPercentageTotalOverflow", "type": "error" }, + { "inputs": [], "name": "WhitelistAlreadyDisabled", "type": "error" }, + { "inputs": [], "name": "WhitelistAlreadyEnabled", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "AddedToWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "swETHMinted", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalETHDeposited", + "type": "uint256" + } + ], + "name": "ETHDepositReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "swETHBurned", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ethReturned", + "type": "uint256" + } + ], + "name": "ETHWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMaximumRepriceDifferencePercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMaximumRepriceDifferencePercentage", + "type": "uint256" + } + ], + "name": "MaximumRepriceDifferencePercentageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMaximumRepriceswETHDifferencePercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMaximumRepriceswETHDifferencePercentage", + "type": "uint256" + } + ], + "name": "MaximumRepriceswETHDifferencePercentageUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMinimumRepriceTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMinimumRepriceTime", + "type": "uint256" + } + ], + "name": "MinimumRepriceTimeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercentage", + "type": "uint256" + } + ], + "name": "NodeOperatorRewardPercentageUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "RemovedFromWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newEthReserves", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSwETHToETHRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nodeOperatorRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "swellTreasuryRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalETHDeposited", + "type": "uint256" + } + ], + "name": "Reprice", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPercentage", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPercentage", + "type": "uint256" + } + ], + "name": "SwellTreasuryRewardPercentageUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "WhitelistDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "WhitelistEnabled", + "type": "event" + }, + { "stateMutability": "nonpayable", "type": "fallback" }, + { + "inputs": [], + "name": "AccessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "addToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_addresses", "type": "address[]" } + ], + "name": "batchAddToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_addresses", "type": "address[]" } + ], + "name": "batchRemoveFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "disableWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enableWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ethToSwETHRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IAccessControlManager", + "name": "_accessControlManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRepriceETHReserves", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRepriceUNIX", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumRepriceDifferencePercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maximumRepriceswETHDifferencePercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minimumRepriceTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nodeOperatorRewardPercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_address", "type": "address" } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_preRewardETHReserves", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newETHRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_swETHTotalSupply", + "type": "uint256" + } + ], + "name": "reprice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maximumRepriceDifferencePercentage", + "type": "uint256" + } + ], + "name": "setMaximumRepriceDifferencePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maximumRepriceswETHDifferencePercentage", + "type": "uint256" + } + ], + "name": "setMaximumRepriceswETHDifferencePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumRepriceTime", + "type": "uint256" + } + ], + "name": "setMinimumRepriceTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newNodeOperatorRewardPercentage", + "type": "uint256" + } + ], + "name": "setNodeOperatorRewardPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newSwellTreasuryRewardPercentage", + "type": "uint256" + } + ], + "name": "setSwellTreasuryRewardPercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "swETHToETHRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "swellTreasuryRewardPercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalETHDeposited", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistEnabled", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "whitelistedAddresses", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract IERC20", "name": "_token", "type": "address" } + ], + "name": "withdrawERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/swell-liquid-staking/index.js b/src/adaptors/swell-liquid-staking/index.js new file mode 100644 index 0000000000..f3506f8e27 --- /dev/null +++ b/src/adaptors/swell-liquid-staking/index.js @@ -0,0 +1,55 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const abi = require('./abi.json'); + +const apr = 'https://v3.svc.swellnetwork.io/swell.v3.StatsService/All'; +const apr7d = 'https://v3-public.svc.swellnetwork.io/api/tokens/sweth/apr'; +const swETH = '0xf951E335afb289353dc249e82926178EaC7DEd78'; + +const apy = async () => { + const totalSupply = + ( + await sdk.api.abi.call({ + target: swETH, + abi: abi.find((m) => m.name === 'totalSupply'), + }) + ).output / 1e18; + + const rate = + ( + await sdk.api.abi.call({ + target: swETH, + abi: abi.find((m) => m.name === 'getRate'), + }) + ).output / 1e18; + + const priceKey = `ethereum:${swETH}`; + const ethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey].price; + + const tvlUsd = totalSupply * rate * ethPrice; + + // const apyBase = (await axios.post(apr, {})).data.stakingAprPercent; + const apyBase7d = (await axios.get(apr7d)).data; + + return [ + { + pool: swETH, + project: 'swell-liquid-staking', + chain: 'Ethereum', + symbol: 'swETH', + tvlUsd, + apyBase: apyBase7d, + apyBase7d, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.swellnetwork.io/', +}; diff --git a/src/adaptors/swop/index.js b/src/adaptors/swop/index.js new file mode 100644 index 0000000000..f2507d7666 --- /dev/null +++ b/src/adaptors/swop/index.js @@ -0,0 +1,129 @@ +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL = 'https://backend.swop.fi/pools'; +const UNIT0_GRAPH_URL = 'http://graphql-node-htz-fsn1-1.wvservices.com:8000/subgraphs/name/swopfi/swopfi-units' + +const queryUnit0 = gql` + { + pairs(first: 1000, orderBy: trackedReserveUNIT0, orderDirection: desc block: {number: }, where: {reserve1_gt: "0.0000001", reserve0_gt: "0.0000001"}) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPriorUnit0 = gql` + { + pairs (first: 1000 orderBy: trackedReserveUNIT0 orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const getWavesPools = async () => { + const SWOP_TOKEN_ID = "Ehie5xYpeN8op1Cctc6aGUrqx8jq3jtf1DSjXDbfm7aT"; + const CHAIN = "waves" + const BASE_POOL_URL = "https://swop.fi/pool?address=" + const data = await utils.getData(API_URL); + + const pools = data.pools.filter((pool) => { return !pool.isDeprecated}) + .map((pool) => { + return { + pool: `${pool.id}-${CHAIN}`.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: 'swop', + symbol: pool.name.replace(' / ', '-'), + tvlUsd: Number(pool.liquidity), + apyBase: Number(pool.day.liquidityApy), + apyReward: Number(pool.current.swopApr.min), + rewardTokens: [SWOP_TOKEN_ID], + underlyingTokens: pool.assets.map(a => a.id), + url: `${BASE_POOL_URL}${pool.id}` + }; + }); + return pools; +} + +const getUnit0Pools = async (timestamp = null) => { + chainString = 'unit0' + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + UNIT0_GRAPH_URL, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [UNIT0_GRAPH_URL], + 604800 + ); + // pull data + let queryC = queryUnit0; + let dataNow = await request(UNIT0_GRAPH_URL, queryC.replace('', block)); + dataNow = dataNow.pairs; + + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPriorUnit0; + let dataPrior = await request( + UNIT0_GRAPH_URL, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(UNIT0_GRAPH_URL, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'v2')); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const url = `https://units.swop.fi/#/add/${token0}/${token1}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'swop', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +} + +const main = async (timestamp = null) => { + const data = []; + data.push(...await getWavesPools()); // get pools from waves chain + data.push(...await getUnit0Pools(timestamp)); // get pools from waves chain + return data.filter((p) => utils.keepFinite(p)); +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://swop.fi/', +}; diff --git a/src/adaptors/symbiosis/config.js b/src/adaptors/symbiosis/config.js new file mode 100644 index 0000000000..d177d4bd3c --- /dev/null +++ b/src/adaptors/symbiosis/config.js @@ -0,0 +1,64 @@ +module.exports = { + pool: { + chainId: 56288, + address: '0x6148FD6C649866596C3d8a971fC313E5eCE84882', + }, + chains: [ + { + id: 1, + name: 'ethereum', + stable: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + sStable: '0x7d6EC42b5d9566931560411a8652Cea00b90d982' + }, + { + id: 56, + name: 'bsc', + stable: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + symbol: 'BUSD', + sStable: '0x1a25BEB8E75626ADDb983d46fbDfcE5fdC29Ae58' + }, + { + id: 43114, + name: 'avalanche', + stable: '0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664', + symbol: 'USDC.e', + sStable: '0x6dF9C221F52537DFD63d70721EEAA0C4d4472C18' + }, + { + id: 137, + name: 'polygon', + stable: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', + symbol: 'USDC', + sStable: '0x59AA2e5F628659918A4890A2a732E6C8bD334E7A' + }, + { + id: 40, + name: 'telos', + stable: '0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b', + symbol: 'USDC', + sStable: '0x7Af28c655F1EF73E1Fb15204f025A25D686A3Ca7' + }, + { + id: 288, + name: 'boba', + stable: '0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc', + symbol: 'USDC', + sStable: '0x1a3d48492Cd334AD140587091AC382E5695a4934', + }, + { + id: 43288, + name: 'boba_avax', + stable: '0x126969743a6d300bab08F303f104f0f7DBAfbe20', + symbol: 'USDC.e', + sStable: '0xa9441f2995763e38d18A725646b00D90938d2FBf' + }, + { + id: 56288, + name: 'boba_bnb', + stable: '0x9F98f9F312D23d078061962837042b8918e6aff2', + symbol: 'USDC', + sStable: '0x9F98f9F312D23d078061962837042b8918e6aff2', + }, + ] +} \ No newline at end of file diff --git a/src/adaptors/symbiosis/index.js b/src/adaptors/symbiosis/index.js new file mode 100644 index 0000000000..89dc2379d4 --- /dev/null +++ b/src/adaptors/symbiosis/index.js @@ -0,0 +1,96 @@ +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const config = require('./config'); + +const erc20ABI = { + decimals: 'function decimals() external pure returns (uint8)', + balanceOf: + 'function balanceOf(address owner) external view returns (uint256 balance)', +}; + +const urlApy = 'https://api-v2.symbiosis.finance/farming/v1/apr'; + +const formatApy = (value) => { + return new BigNumber(value).multipliedBy(100).toNumber(); +}; + +const loadApyData = async () => { + const apy = await utils.getData(urlApy); + + const apyData = {}; + apy.forEach((i) => { + const pool = i['pools'][0]; + apyData[pool['chainId']] = { + apr: formatApy(pool['apr']), + boostedApr: formatApy(pool['boostedApr']), + }; + }); + return apyData; +}; + +const loadTvlData = async () => { + const balanceCalls = config.chains.map((i) => { + return { + target: i.sStable, + params: config.pool.address, + }; + }); + const balanceOutput = await sdk.api.abi.multiCall({ + chain: 'boba_bnb', + abi: erc20ABI.balanceOf, + calls: balanceCalls, + }); + + const decimalsCalls = config.chains.map((i) => { + return { + target: i.sStable, + params: [], + }; + }); + const decimalsOutput = await sdk.api.abi.multiCall({ + chain: 'boba_bnb', + abi: erc20ABI.decimals, + calls: decimalsCalls, + }); + + const tvl = {}; + config.chains.map((chainInfo, i) => { + const decimals = parseInt(decimalsOutput.output[i].output); + const balance = parseInt(balanceOutput.output[i].output); + const delimiter = new BigNumber(10).pow(decimals); + const usd = new BigNumber(balance).div(delimiter); + tvl[chainInfo.stable] = usd.toNumber(); + }); + + return tvl; +}; + +const main = async () => { + const apyData = await loadApyData(); + const tvl = await loadTvlData(); + + let data = []; + config.chains.forEach((chainInfo) => { + const { id, name: chain, stable, symbol } = chainInfo; + + data.push({ + pool: `symbiosis-finance-${stable}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'symbiosis', + symbol, + tvlUsd: tvl[stable], + apyReward: apyData[id].apr, + rewardTokens: ['0xd38bb40815d2b0c2d2c866e0c72c5728ffc76dd9'], + underlyingTokens: [stable], + }); + }); + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app-v2.symbiosis.finance/liquidity-v2/pools', +}; diff --git a/src/adaptors/synapse/abis.json b/src/adaptors/synapse/abis.json new file mode 100644 index 0000000000..b1fb3b1055 --- /dev/null +++ b/src/adaptors/synapse/abis.json @@ -0,0 +1,302 @@ +{ + "allPools": { + "inputs": [], + "name": "allPools", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isWeth", + "type": "bool" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "internalType": "struct PoolToken[]", + "name": "tokens", + "type": "tuple[]" + } + ], + "internalType": "struct Pool[]", + "name": "pools", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + "balanceOf": { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "lpToken": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolLength": { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "poolInfo": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "accSynapsePerShare", + "type": "uint128" + }, + { + "internalType": "uint64", + "name": "lastRewardTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "allocPoint", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + "totalAllocPoint": { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "synapsePerBlock": { + "inputs": [], + "name": "synapsePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "lpBalances": { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "symbol": { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + "token": { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "decimals": { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "synapsePerSecond": { + "inputs": [], + "name": "synapsePerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "swapStorage": { + "inputs":[], + "name":"swapStorage", + "outputs":[ + { + "internalType":"uint256", + "name":"initialA", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"futureA", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"initialATime", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"futureATime", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"swapFee", + "type":"uint256" + }, + { + "internalType":"uint256", + "name":"adminFee", + "type":"uint256" + }, + { + "internalType":"contract LPToken", + "name":"lpToken", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + "getToken": { + "inputs":[ + { + "internalType":"uint8", + "name":"index", + "type":"uint8" + } + ], + "name":"getToken", + "outputs":[ + { + "internalType":"contract IERC20", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + "getTokenBalance": { + "inputs":[ + { + "internalType":"uint8", + "name":"index", + "type":"uint8" + } + ], + "name":"getTokenBalance", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + } + +} diff --git a/src/adaptors/synapse/index.js b/src/adaptors/synapse/index.js new file mode 100644 index 0000000000..b62d7401db --- /dev/null +++ b/src/adaptors/synapse/index.js @@ -0,0 +1,308 @@ +const sdk = require('@defillama/sdk'); +const abi = require('./abis.json'); +const { formatChain, getData } = require('../utils'); +const _ = require('lodash'); + +// Pools are the treasurys that hold the underlying assets +const config = { + Arbitrum: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x080F6AEd32Fc474DD5717105Dba5ea57268F46eb', + LP_STAKING_ADDRESS: '0x73186f2Cf2493f20836b17b21ae79fc12934E207', + }, + Avax: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x1f1E7c893855525b303f99bDF5c3c05Be09ca251', + LP_STAKING_ADDRESS: '0x3a01521F8E7F012eB37eAAf1cb9490a5d9e18249', + formattedChainName: 'Avalanche', + }, + Base: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x432036208d2717394d2614d6697c46DF3Ed69540', + LP_STAKING_ADDRESS: '0xfFC2d603fde1F99ad94026c00B6204Bb9b8c36E9', + }, + Ethereum: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x0f2D719407FdBeFF09D87557AbB7232601FD9F29', + LP_STAKING_ADDRESS: '0xd10eF2A513cEE0Db54E959eF16cAc711470B62cF', + }, + Optimism: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x5A5fFf6F753d7C11A56A52FE47a177a87e431655', + LP_STAKING_ADDRESS: '0xe8c610fcb63A4974F02Da52f0B4523937012Aaa0', + }, + Polygon: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0xf8F9efC0db77d8881500bb06FF5D6ABc3070E695', + LP_STAKING_ADDRESS: '0x7875Af1a6878bdA1C129a4e2356A3fD040418Be5', + }, + Blast: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x9592f08387134e218327E6E8423400eb845EdE0E', + LP_STAKING_ADDRESS: '0x3100dC8464A8523306c3C5034de24a8927d6E590', + }, + Bsc: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0xa4080f1778e69467e905b8d6f72f6e441f9e9484', + LP_STAKING_ADDRESS: '0x8F5BBB2BB8c2Ee94639E55d5F41de9b4839C1280', + }, + Metis: { + ROUTER: '0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a', + SYN_TOKEN_ADDRESS: '0x67C10C397dD0Ba417329543c1a40eb48AAa7cd00', + LP_STAKING_ADDRESS: '0xaB0D8Fc46249DaAcd5cB36c5F0bC4f0DAF34EBf5', + }, +}; + +const chainNames = Object.keys(config); + +const calcApy = ( + priceOfSyn, + tvl, + synapsePerSecond, + totalAllocPoint, + poolAllocPoint +) => { + // # Calculate the annualized rewards for this pool + pool_rewards = + synapsePerSecond * (poolAllocPoint / totalAllocPoint) * 60 * 60 * 24 * 365; + + // # Calculate the APY + apy = (pool_rewards * priceOfSyn) / tvl; + + return apy * 100; +}; + +const getPrices = async (chain, addresses) => { + const prices = ( + await getData( + `https://coins.llama.fi/prices/current/${addresses.map( + (address) => `${chain}:${address}` + )}` + ) + ).coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const relevantPoolInfo = async (poolIndex, chain, LP_STAKING_ADDRESS) => { + // info for tvl / apy calculations + const poolInfo = ( + await sdk.api.abi.call({ + abi: abi.poolInfo, + target: LP_STAKING_ADDRESS, + chain: chain, + params: poolIndex, + }) + ).output; + const lpToken = ( + await sdk.api.abi.call({ + abi: abi.lpToken, + target: LP_STAKING_ADDRESS, + chain: chain, + params: poolIndex, + }) + ).output; + const allocPoint = await poolInfo.allocPoint; + + return { + lpToken, + allocPoint, + }; +}; + +const getTvl = async ( + chain, + underlyingAssetsTreasury, + lpToken, + underlyingTokenCount +) => { + const allUnderlyingTokenAddresses = // get all the tokens underlying the LP + ( + await sdk.api.abi.multiCall({ + calls: _.map(_.range(0, underlyingTokenCount), (index) => ({ + target: underlyingAssetsTreasury, + params: [index], + })), + abi: abi.getToken, + chain: chain, + }) + ).output.map(({ output }) => output); + + const tokenPrices = await getPrices(chain, allUnderlyingTokenAddresses); + + // get all the token balances underlying the LP + const allUnderlyingTokenBalances = ( + await sdk.api.abi.multiCall({ + calls: _.map(_.range(0, underlyingTokenCount), (index) => ({ + target: underlyingAssetsTreasury, + params: [index], + })), + abi: abi.getTokenBalance, + chain: chain, + }) + ).output.map(({ output }) => output); + + // get decimals to correct the returned balances + const allUnderlyingTokenDecimals = ( + await sdk.api.abi.multiCall({ + calls: allUnderlyingTokenAddresses.map((tokenAddress) => ({ + target: tokenAddress, + })), + abi: abi.decimals, + chain: chain, + }) + ).output.map(({ output }) => output); + + // get decimals to correct the returned balances + const allUnderlyingTokenSymbols = ( + await sdk.api.abi.multiCall({ + calls: allUnderlyingTokenAddresses.map((tokenAddress) => ({ + target: tokenAddress, + })), + abi: abi.symbol, + chain: chain, + }) + ).output.map(({ output }) => output); + + let tvl = 0; + for (let i = 0; i < allUnderlyingTokenAddresses.length; i++) { + const tokenAddress = allUnderlyingTokenAddresses[i]; + const balance = + parseFloat(allUnderlyingTokenBalances[i]) / + (1 * 10 ** parseInt(allUnderlyingTokenDecimals[i])); + let price = tokenPrices[tokenAddress.toLowerCase()]; + if (!price) { + // hETH or hUSD will not be found in tokenPrices so we use the average price to dictate its price + price = + Object.values(tokenPrices).reduce((acc, curr) => acc + curr, 0) / + Object.values(tokenPrices).length; + } + const value = balance * price; + tvl += value; + } + + return { + tvlUsd: tvl, + underlyingTokens: allUnderlyingTokenAddresses, + allUnderlyingTokenSymbols, + }; +}; + +const main = async () => { + let allPools = []; + const synPrice = Object.values( + await getPrices('Ethereum', [config.Ethereum.SYN_TOKEN_ADDRESS]) + )[0]; + + for (let x = 0; x < chainNames.length; x++) { + const chainKey = chainNames[x].toLowerCase(); + const configPerChain = config[chainNames[x]]; + + const LP_STAKING_ADDRESS = configPerChain.LP_STAKING_ADDRESS; + const SYN_TOKEN_ADDRESS = configPerChain.SYN_TOKEN_ADDRESS; + const ROUTER = configPerChain.ROUTER; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abi.totalAllocPoint, + target: LP_STAKING_ADDRESS, + chain: chainKey, + }) + ).output; + const synapsePerSecond = ( + await sdk.api.abi.call({ + abi: abi.synapsePerSecond, + target: LP_STAKING_ADDRESS, + chain: chainKey, + }) + ).output; + const poolLength = parseInt( + ( + await sdk.api.abi.call({ + abi: abi.poolLength, + target: LP_STAKING_ADDRESS, + chain: chainKey, + }) + ).output + ); + + const allLpTokens = ( + await sdk.api.abi.call({ + abi: abi.allPools, + target: ROUTER, + chain: chainKey, + }) + ).output.map((data) => ({ + lpToken: data.lpToken, + poolAddress: data.pool, + tokens: data.tokens.map((tokenData) => tokenData.token), + underlyingTokenCount: data.tokens.length, + })); + + for (let y = 0; y < poolLength; y++) { + // For each pool index, we have to see if we have info about it. + // if so, we can get the tvl for the chain and move from there + // if not, keep going + + const relevantInfo = await relevantPoolInfo( + y, + chainKey, + LP_STAKING_ADDRESS + ); + const underlyingAssetsTreasury = allLpTokens.find( + (x) => x.lpToken === relevantInfo.lpToken + ); + + // We are excluding some of the low tvl pools that are onchain but not shown on web app + // If you want to include these, add it to the config var + if (!underlyingAssetsTreasury) { + continue; + } + + const { tvlUsd, underlyingTokens, allUnderlyingTokenSymbols } = + await getTvl( + chainKey, + underlyingAssetsTreasury.poolAddress, + underlyingAssetsTreasury.lpToken, + underlyingAssetsTreasury.underlyingTokenCount, + synPrice + ); + const apy = calcApy( + synPrice, + tvlUsd, + synapsePerSecond / (1 * 10 ** 18), + totalAllocPoint, + relevantInfo.allocPoint + ); + + allPools.push({ + pool: `${relevantInfo.lpToken}-${formatChain(chainKey)}`.toLowerCase(), + chain: configPerChain.formattedChainName + ? configPerChain.formattedChainName + : formatChain(chainKey), + symbol: allUnderlyingTokenSymbols.join('-'), + project: 'synapse', + underlyingTokens, + rewardTokens: [SYN_TOKEN_ADDRESS], + tvlUsd, + apy, + }); + } + } + + return allPools; +}; + +module.exports = { + url: 'https://synapseprotocol.com/pools', + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/synthetix-v3/index.js b/src/adaptors/synthetix-v3/index.js new file mode 100644 index 0000000000..76e7ceabfa --- /dev/null +++ b/src/adaptors/synthetix-v3/index.js @@ -0,0 +1,44 @@ +const axios = require('axios'); + +const sdk = require('@defillama/sdk'); + +const USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; +const SNX = '0x22e6966B799c4D5B13BE962E1D117b56327FDa66'; +const USDC_POOL = '0x32C222A9A159782aFD7529c87FA34b96CA72C696'; + +const apy = async () => { + const apr = (await axios.get('https://api.synthetix.io/v3/base/sc-pool-apy')) + .data; + + const deposits = + ( + await sdk.api.abi.call({ + target: USDC, + abi: 'erc20:balanceOf', + chain: 'base', + params: [USDC_POOL], + }) + ).output / 1e6; + + const key = `base:${USDC}`; + const price = ( + await axios.get(`https://coins.llama.fi/prices/current/${key}`) + ).data.coins[key].price; + + return [ + { + pool: USDC_POOL, + symbol: 'USDC', + project: 'synthetix-v3', + chain: 'Base', + tvlUsd: deposits * price, + apy: apr.apr28d * 100, + underlyingTokens: [USDC], + }, + ]; +}; + +module.exports = { + apy, + url: 'https://liquidity.synthetix.eth.limo/', +}; diff --git a/src/adaptors/taiga-acala/index.js b/src/adaptors/taiga-acala/index.js new file mode 100644 index 0000000000..3331647b3f --- /dev/null +++ b/src/adaptors/taiga-acala/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils'); + +const getPools = async () => { + const tdotApr = await utils.getData( + 'https://api.taigaprotocol.io/rewards/apr?network=acala&pool=0' + ); + const tdotStats = await utils.getData( + 'https://api.taigaprotocol.io/tokens/tdot/stats' + ); + + const priceKey = 'coingecko:polkadot'; + + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const dotUsd = prices[priceKey].price; + + const tdot = { + pool: 'acala-sa0-taiga', + chain: utils.formatChain('acala'), + project: 'taiga-acala', + symbol: 'tDOT', + tvlUsd: tdotStats.total * dotUsd, + apyBase: Number(tdotApr['sa://0']) * 100, + }; + + return [tdot]; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.taigaprotocol.io/', +}; diff --git a/src/adaptors/taiga-karura/index.js b/src/adaptors/taiga-karura/index.js new file mode 100644 index 0000000000..e0941a1059 --- /dev/null +++ b/src/adaptors/taiga-karura/index.js @@ -0,0 +1,51 @@ +const utils = require('../utils'); + +const getPools = async () => { + const taiKsmApr = await utils.getData( + 'https://api.taigaprotocol.io/rewards/apr?network=karura&pool=0' + ); + const taiKsmStats = await utils.getData( + 'https://api.taigaprotocol.io/tokens/taiksm/stats' + ); + const threeUsdApr = await utils.getData( + 'https://api.taigaprotocol.io/rewards/apr?network=karura&pool=1' + ); + const threeUsdStats = await utils.getData( + 'https://api.taigaprotocol.io/tokens/3usd/stats' + ); + + const taiKsm = { + pool: 'karura-sa0-taiga', + chain: utils.formatChain('karura'), + project: 'taiga-karura', + symbol: 'tKSM', + tvlUsd: taiKsmStats.data.tvl, + apyBase: taiKsmApr['sa://0'] * 100, + apyReward: taiKsmApr['TAI'] * 100, + rewardTokens: ['TAI'], + }; + + const threeUsd = { + pool: 'karura-sa1-taiga', + chain: utils.formatChain('karura'), + project: 'taiga-karura', + symbol: '3USD', + tvlUsd: threeUsdStats.data.tvl, + apyBase: threeUsdApr['sa://1'] * 100, + rewardTokens: ['TAI', 'sa://0', 'LKSM', 'KAR'], + apyReward: + (threeUsdApr['TAI'] + + threeUsdApr['sa://0'] + + threeUsdApr['LKSM'] + + threeUsdApr['KAR']) * + 100, + }; + + return [taiKsm, threeUsd]; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://app.taigaprotocol.io/', +}; diff --git a/src/adaptors/takara-lend/index.js b/src/adaptors/takara-lend/index.js new file mode 100644 index 0000000000..3ce29f6c0a --- /dev/null +++ b/src/adaptors/takara-lend/index.js @@ -0,0 +1,202 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abis = require('./takara-lend.json'); +const ethers = require('ethers'); + +const markets_state = '0x4fFD2B969f883679c008838329d249E295aafC3C'; +const chain = utils.formatChain('Sei'); +const project = 'takara-lend'; + +function multiplyWithPrecision(a, aDecimals, b, bDecimals, resultDecimals = 18) { + const scaleA = 10n ** BigInt(aDecimals); + const scaleB = 10n ** BigInt(bDecimals); + const scaleResult = 10n ** BigInt(resultDecimals); + + return (a * b * scaleResult) / (scaleA * scaleB); +} + +function calculateApy(ratePerSecond, compoundingsPerYear) { + ratePerSecond = BigInt(ratePerSecond); + compoundingsPerYear = BigInt(compoundingsPerYear); + + if (ratePerSecond === 0n) return 0; + + const SCALE = BigInt(1e18); + + function pow(base, exponent) { + let result = SCALE; + let basePow = base; + + while (exponent > 0n) { + if (exponent % 2n === 1n) { + result = (result * basePow) / SCALE; + } + basePow = (basePow * basePow) / SCALE; + exponent /= 2n; + } + + return result; + } + const compounded = pow(SCALE + ratePerSecond, compoundingsPerYear); + const rawData = (compounded - SCALE) * 100n; + + const data = ethers.utils.formatEther(rawData); + return Number(data); +} + +function yearly(emissionPerSec) { + return emissionPerSec * 86400n * 365n; // BigInt +} + +function calcSubsidyPct(configs, supplyUsdFixed18, supplyTokenDec, oracleMap) { + const bySymbol = new Map(); + configs + .filter((n) => BigInt(n.endTime) > BigInt(Math.floor(Date.now() / 1000))) + .map((cfg) => { + const oracle = oracleMap.get(cfg.emissionToken.toLowerCase()); + if (!oracle || cfg.supplyEmissionsPerSec === '0') return; + + const yearlyAmt = yearly(BigInt(cfg.supplyEmissionsPerSec)); + + const yearlyUsd18 = multiplyWithPrecision(yearlyAmt, Number(oracle.decimals), BigInt(oracle.price), 18, 18n); + + const pct18 = (yearlyUsd18 * 100n * 10n ** 18n) / supplyUsdFixed18; + + const prev = bySymbol.get(oracle.symbol) || 0n; + bySymbol.set(oracle.symbol, prev + pct18); + }); + + return Array.from(bySymbol.entries()).map(([name, pct18]) => ({ + name, + value: Number(ethers.utils.formatEther(pct18, 18)), + })); +} + +const apy = async () => { + const {output:allMarketsMetadata} = ( + await sdk.api.abi.call({ + target: markets_state, + abi: abis.find((m) => m.name === 'getActiveMarketsInfo'), + chain: 'sei', + }) + ); + const oracleMap = new Map(); + const rTokens = allMarketsMetadata.map((m)=> { + oracleMap.set(m.underlying.toLowerCase(), { + price: BigInt(m.price), // 18 位 + decimals: Number(m.decimals), + symbol: m.underlyingSymbol, + }); + return m.token; + }); + + const { output: partnerRaw } = await sdk.api.abi.multiCall({ + chain: 'sei', + abi: abis.find(m => m.name === 'getPartnerRewardsAllMarketConfigs'), + target: markets_state, + calls: rTokens.map(t => ({ params: [t] })), + }); + + const { output: rewardsRaw } = await sdk.api.abi.multiCall({ + chain: 'sei', + abi: abis.find(m => m.name === 'getRewardsAllMarketConfigs'), + target: markets_state, + calls: rTokens.map(t => ({ params: [t] })), + }); + + + const pools = allMarketsMetadata.map((marketInfo, i) => { + const pool = `${marketInfo.token}-${chain}`.toLowerCase(); + const underlyingSymbol = marketInfo.underlyingSymbol; + + const poolMeta = `Takara Lend ${underlyingSymbol} Market`; + const tvlUsd = Number(ethers.utils.formatEther(marketInfo.tvl)); + const ltv = Number(ethers.utils.formatEther(marketInfo.ltv)); + const totalSupplyUsd = Number( + ethers.utils.formatEther(marketInfo.totalSupply) + ); + const totalBorrowUsd = Number( + ethers.utils.formatEther(marketInfo.totalBorrows) + ); + const borrowRatePerBlock = marketInfo.borrowRatePerBlock; + const supplyRatePerBlock = marketInfo.supplyRatePerBlock; + const timestampsPerYear = marketInfo.timestampsPerYear; + + const apyBase = calculateApy(supplyRatePerBlock, timestampsPerYear); + const apyBaseBorrow = calculateApy(borrowRatePerBlock, timestampsPerYear); + + const url = `https://app.takaralend.com/market/${underlyingSymbol}`; + + + const underlyingTot = multiplyWithPrecision( + BigInt(marketInfo.orginTotalSupply), + Number(marketInfo.decimals), + BigInt(marketInfo.exchangeRateStored), + 18, + Number(marketInfo.decimals) + ); + + const supplyUsdFixed = multiplyWithPrecision( + underlyingTot, + Number(marketInfo.decimals), + BigInt(marketInfo.price), + 18, + 18 + ); + const rewards = rewardsRaw[i].output ||[]; + const partnerRewards = partnerRaw[i].output||[]; + + let apyReward = 0; + const SubsidyList = []; + const rewardTokens = []; + + if(underlyingTot !== 0n || supplyUsdFixed !== 0n) { + const rewardList = calcSubsidyPct( + rewards, + supplyUsdFixed, + Number(marketInfo.decimals), + oracleMap, + ); + const partnerList = calcSubsidyPct( + partnerRewards, + supplyUsdFixed, + Number(marketInfo.decimals), + oracleMap, + ); + const allSubsidy = [...partnerList, ...rewardList]; + apyReward = Number(allSubsidy.reduce((acc, item) => acc + item.value, 0).toFixed(2)); + const tokens = [...new Set([ ...partnerList, ...rewardList ].map(o => o.name))]; + allMarketsMetadata.forEach(item=>{ + if(tokens.includes(item.underlyingSymbol)){ + rewardTokens.push(item.underlying) + } + }) + } + + return { + pool, + chain, + project, + poolMeta, + ltv, + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + apyBase, + apyBaseBorrow, + apyReward: apyReward, + rewardTokens: rewardTokens, + symbol: underlyingSymbol, + underlyingTokens: [marketInfo.underlying], + url, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://app.takaralend.com', +}; diff --git a/src/adaptors/takara-lend/takara-lend.json b/src/adaptors/takara-lend/takara-lend.json new file mode 100644 index 0000000000..ac170ce382 --- /dev/null +++ b/src/adaptors/takara-lend/takara-lend.json @@ -0,0 +1,302 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "_partnerMultiRewardDistributor", + "type": "address" + }, + { + "internalType": "address", + "name": "_multiRewardDistributor", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract Comptroller", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getActiveMarketsInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ltv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowRatePerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestampsPerYear", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "underlyingSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRateStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "orginTotalSupply", + "type": "uint256" + } + ], + "internalType": "struct MarketState.MarketsInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TErc20", + "name": "rToken", + "type": "address" + } + ], + "name": "getPartnerRewardsAllMarketConfigs", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "emissionToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint224", + "name": "supplyGlobalIndex", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "supplyGlobalTimestamp", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "borrowGlobalIndex", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "borrowGlobalTimestamp", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "supplyEmissionsPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowEmissionsPerSec", + "type": "uint256" + } + ], + "internalType": "struct MultiRewardDistributorCommon.MarketConfig[]", + "name": "rewardsConfigs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TErc20", + "name": "rToken", + "type": "address" + } + ], + "name": "getRewardsAllMarketConfigs", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "emissionToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint224", + "name": "supplyGlobalIndex", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "supplyGlobalTimestamp", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "borrowGlobalIndex", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "borrowGlobalTimestamp", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "supplyEmissionsPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowEmissionsPerSec", + "type": "uint256" + } + ], + "internalType": "struct MultiRewardDistributorCommon.MarketConfig[]", + "name": "rewardsConfigs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract CompositeOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "partner", + "outputs": [ + { + "internalType": "contract PartnerMultiRewardDistributor", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewards", + "outputs": [ + { + "internalType": "contract MultiRewardDistributorV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/tangible-arcana/abis/PointsBoostingVault.json b/src/adaptors/tangible-arcana/abis/PointsBoostingVault.json new file mode 100644 index 0000000000..743109834b --- /dev/null +++ b/src/adaptors/tangible-arcana/abis/PointsBoostingVault.json @@ -0,0 +1,4 @@ +{ + "address": "0xeAcFaA73D34343FcD57a1B3eB5B0D949df727712", + "abi": [] +} \ No newline at end of file diff --git a/src/adaptors/tangible-arcana/abis/RebaseManager.json b/src/adaptors/tangible-arcana/abis/RebaseManager.json new file mode 100644 index 0000000000..6410745863 --- /dev/null +++ b/src/adaptors/tangible-arcana/abis/RebaseManager.json @@ -0,0 +1,359 @@ +{ + "address": "0x1FB57aF994a03c49f9B1b7Eef938519463CdF996", + "abi": [ + { + "type": "constructor", + "inputs": [ + { + "name": "initialOwner", + "type": "address", + "internalType": "address" + }, + { + "name": "rebaseController_", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "RATE_HISTORY_LENGTH", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "apr", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "_apr", + "type": "int256", + "internalType": "int256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "execute", + "inputs": [ + { + "name": "calls", + "type": "tuple[]", + "internalType": "struct RebaseManager.Call[]", + "components": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getCurrentInterestRate", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "currentRate", + "type": "int256", + "internalType": "int256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "interestRatesHistory", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "currentIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "ema", + "type": "int256", + "internalType": "int256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lastRebaseTimestamp", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "rebase", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "rebaseCallData", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "preparations", + "type": "tuple[]", + "internalType": "struct RebaseManager.Call[]", + "components": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "cleanups", + "type": "tuple[]", + "internalType": "struct RebaseManager.Call[]", + "components": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rebaseController", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "InternalCallFailed", + "inputs": [ + { + "name": "target", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "result", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RebaseInterestRateUpdated", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newRate", + "type": "int256", + "indexed": false, + "internalType": "int256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "RebaseFailed", + "inputs": [] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "SafeCastOverflowedUintToInt", + "inputs": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "TotalSupplyUnchanged", + "inputs": [] + }, + { + "type": "error", + "name": "Unauthorized", + "inputs": [] + }, + { + "type": "error", + "name": "Unchanged", + "inputs": [] + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-arcana/abis/USTB.json b/src/adaptors/tangible-arcana/abis/USTB.json new file mode 100644 index 0000000000..3167fa1e07 --- /dev/null +++ b/src/adaptors/tangible-arcana/abis/USTB.json @@ -0,0 +1,1743 @@ +{ + "address": "0x83feDBc0B85c6e29B589aA6BdefB1Cc581935ECD", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mainChainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "endpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AmountExceedsBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "CannotBridgeWhenOptedOut", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "NotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "RebaseOverflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [], + "name": "SupplyOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "UnsupportedChain", + "type": "error" + }, + { + "inputs": [], + "name": "ValueUnchanged", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "RebaseDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "RebaseEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "RebaseIndexManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "updatedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupplyBefore", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupplyAfter", + "type": "uint256" + } + ], + "name": "RebaseIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "SetUseCustomAdapterParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "disable", + "type": "bool" + } + ], + "name": "disableRebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "indexManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isMainChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "optedOut", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseIndexManager", + "outputs": [ + { + "internalType": "address", + "name": "_rebaseIndexManager", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refreshRebaseIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "setRebaseIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setRebaseIndexManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "useCustomAdapterParams", + "type": "bool" + } + ], + "name": "setUseCustomAdapterParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expectedBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "withdrawExcessAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] +} \ No newline at end of file diff --git a/src/adaptors/tangible-arcana/abis/arcUSD.json b/src/adaptors/tangible-arcana/abis/arcUSD.json new file mode 100644 index 0000000000..2ec7c5449a --- /dev/null +++ b/src/adaptors/tangible-arcana/abis/arcUSD.json @@ -0,0 +1,1836 @@ +{ + "address": "0xAEC9e50e3397f9ddC635C6c429C8C7eca418a143", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "mainChainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "endpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AmountExceedsBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "CannotBridgeWhenOptedOut", + "type": "error" + }, + { + "inputs": [], + "name": "CantRenounceOwnership", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRebaseIndex", + "type": "error" + }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyMinter", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "RebaseOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "SupplyLimitExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "SupplyOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressException", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroRebaseIndex", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newMinter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oldMinter", + "type": "address" + } + ], + "name": "MinterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "RebaseDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "RebaseEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "RebaseIndexManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "updatedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupplyBefore", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupplyAfter", + "type": "uint256" + } + ], + "name": "RebaseIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "SetUseCustomAdapterParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "newSupplyLimit", + "type": "uint256" + } + ], + "name": "SupplyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTaxManager", + "type": "address" + } + ], + "name": "TaxManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDisabled", + "type": "bool" + } + ], + "name": "disableRebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "payloadHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_rebaseManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isMainChain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "optedOut", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "optedOutTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "setRebaseIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRebaseManager", + "type": "address" + } + ], + "name": "setRebaseManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setSupplyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTaxManager", + "type": "address" + } + ], + "name": "setTaxManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "useCustomAdapterParams", + "type": "bool" + } + ], + "name": "setUseCustomAdapterParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supplyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taxManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "remoteChainId", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] + } \ No newline at end of file diff --git a/src/adaptors/tangible-arcana/index.js b/src/adaptors/tangible-arcana/index.js new file mode 100644 index 0000000000..859c273af4 --- /dev/null +++ b/src/adaptors/tangible-arcana/index.js @@ -0,0 +1,61 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); + +const RebaseManager = require('./abis/RebaseManager.json'); +const PointsVault = require('./abis/PointsBoostingVault.json'); +const arcUSD = require('./abis/arcUSD.json'); +const USTB = require('./abis/USTB.json'); + +const CHAIN_NAME = 'real'; + +const poolsFunction = async () => { + const totalSupply = await sdk.api.abi + .call({ + target: arcUSD.address, + abi: arcUSD.abi.find((m) => m.name === 'totalSupply'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const amountStaked = await sdk.api.abi + .call({ + target: arcUSD.address, + abi: arcUSD.abi.find((m) => m.name === 'balanceOf'), + params: [PointsVault.address], + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const apr = await sdk.api.abi + .call({ + target: RebaseManager.address, + abi: RebaseManager.abi.find((m) => m.name === 'getCurrentInterestRate'), + params: [arcUSD.address], + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const apy = (Math.pow(1 + (apr/1e18) / 365, 365) - 1); + const ratio = (totalSupply-amountStaked)/totalSupply; + const apy_given_staked = (apy/ratio)*1e2; + + const arcUSDPool = { + pool: arcUSD.address, + chain: utils.formatChain('real'), + project: 'tangible-arcana', + symbol: utils.formatSymbol('arcUSD'), + tvlUsd: Number(totalSupply) / 1e18, + apyBase: apy_given_staked, + apyReward: 0, + rewardTokens: [arcUSD.address], + underlyingTokens: [USTB.address], + url: 'https://arcana.finance', + }; + + return [arcUSDPool] +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/tangible-rwa/abis/Caviar.json b/src/adaptors/tangible-rwa/abis/Caviar.json new file mode 100644 index 0000000000..41a59d7aae --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/Caviar.json @@ -0,0 +1,540 @@ +{ + "address": "0x6AE96Cc93331c19148541D4D2f31363684917092", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-rwa/abis/CaviarRebaseChef.json b/src/adaptors/tangible-rwa/abis/CaviarRebaseChef.json new file mode 100644 index 0000000000..84a460d824 --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/CaviarRebaseChef.json @@ -0,0 +1,643 @@ +{ + "address": "0xf5374d452697d9A5fa2D97Ffd05155C853F6c1c6", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rewardPerSecond", + "type": "uint256" + } + ], + "name": "LogRewardPerSecond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accRewardPerShare", + "type": "uint256" + } + ], + "name": "LogUpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "__NAME__", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accRewardPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributionPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "harvestRebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_distributionPeriod", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastDistributedTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingReward", + "outputs": [ + { + "internalType": "uint256", + "name": "pending", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "seedRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_distributionPeriod", + "type": "uint256" + } + ], + "name": "setDistributionPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPerSecond", + "type": "uint256" + } + ], + "name": "setRewardPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingChef", + "type": "address" + } + ], + "name": "setStakingChef", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "smartWalletChecker", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingChef", + "outputs": [ + { + "internalType": "contract ICaviarChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "update", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardDebt", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-rwa/abis/CaviarStakingChef.json b/src/adaptors/tangible-rwa/abis/CaviarStakingChef.json new file mode 100644 index 0000000000..b3efff3a50 --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/CaviarStakingChef.json @@ -0,0 +1,749 @@ +{ + "address": "0x83C5022745B2511Bd199687a42D27BEFd025A9A9", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rewardPerSecond", + "type": "uint256" + } + ], + "name": "LogRewardPerSecond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlyingSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accRewardPerShare", + "type": "uint256" + } + ], + "name": "LogUpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "__NAME__", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accRewardPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributionPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeForLP", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_underlying", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_distributionPeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_smartWalletChecker", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastDistributedTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingReward", + "outputs": [ + { + "internalType": "uint256", + "name": "pending", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebaseChef", + "outputs": [ + { + "internalType": "contract ICaviarChef", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "seedRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_distributionPeriod", + "type": "uint256" + } + ], + "name": "setDistributionPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeForLP", + "type": "address" + } + ], + "name": "setGaugeForLP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rebaseChef", + "type": "address" + } + ], + "name": "setRebaseChef", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPerSecond", + "type": "uint256" + } + ], + "name": "setRewardPerSecond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_checker", + "type": "address" + } + ], + "name": "setSmartWalletChecker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlying", + "type": "address" + } + ], + "name": "setUnderlyingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "smartWalletChecker", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "rewardDebt", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-rwa/abis/Pair.json b/src/adaptors/tangible-rwa/abis/Pair.json new file mode 100644 index 0000000000..2f6c5a829e --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/Pair.json @@ -0,0 +1,1152 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "migratePairFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/src/adaptors/tangible-rwa/abis/PairFactory.json b/src/adaptors/tangible-rwa/abis/PairFactory.json new file mode 100644 index 0000000000..37418336e1 --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/PairFactory.json @@ -0,0 +1,587 @@ +{ + "address": "0xEaF188cdd22fEEBCb345DCb529Aa18CA9FcB4FBd", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_added", + "type": "bool" + } + ], + "name": "PrivilegedAccountStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getFeeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pairImplementation", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "isPrivileged", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pairImplementation", + "type": "address" + } + ], + "name": "setPairImplementationAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pairManager", + "type": "address" + } + ], + "name": "setPairManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updatePairFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "name": "updatePairFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_addToPrivileged", + "type": "bool" + } + ], + "name": "updatePrivilegedAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/src/adaptors/tangible-rwa/abis/Pearl.json b/src/adaptors/tangible-rwa/abis/Pearl.json new file mode 100644 index 0000000000..006a644e46 --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/Pearl.json @@ -0,0 +1,428 @@ +{ + "address": "0x7238390d5f6F64e67c3211C343A410E2A3DEc142", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "V1_MINTER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "migrator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "reinitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_migrator", + "type": "address" + } + ], + "name": "setMigrator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/src/adaptors/tangible-rwa/abis/USDR.json b/src/adaptors/tangible-rwa/abis/USDR.json new file mode 100644 index 0000000000..3a6600ba1e --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/USDR.json @@ -0,0 +1,1886 @@ +{ + "address": "0x40379a439D4F6795B6fc9aa5687dB461677A2dBa", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supplyDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "Rebase", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "SetUseCustomAdapterParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + } + ], + "name": "SyncFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + } + ], + "name": "SyncToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MULTICHAIN_VAULT", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PREVIOUS_WUSDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SYNC", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "addressProvider", + "outputs": [ + { + "internalType": "contract AddressProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_previousImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "_lzEndpoint", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isMainChain", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isMain", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidityIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpointUpgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "previousImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "supplyDelta", + "type": "uint256" + } + ], + "name": "rebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reinitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resetInitialLiquidityIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AddressProvider", + "name": "_addressProvider", + "type": "address" + } + ], + "name": "setAddressProvider", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "setUseCustomAdapterParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "address payable", + "name": "_refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "sync", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferAllFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useCustomAdapterParams", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-rwa/abis/WrappedUSDR.json b/src/adaptors/tangible-rwa/abis/WrappedUSDR.json new file mode 100644 index 0000000000..a9e7d22131 --- /dev/null +++ b/src/adaptors/tangible-rwa/abis/WrappedUSDR.json @@ -0,0 +1,1780 @@ +{ + "address": "0x00e8c0E92eB3Ad88189E7125Ec8825eDc03Ab265", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "SetUseCustomAdapterParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "usdr", + "type": "address" + }, + { + "internalType": "address", + "name": "lzEndpoint", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpointUpgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reinitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_toAddress", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_useCustomAdapterParams", + "type": "bool" + } + ], + "name": "setUseCustomAdapterParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "useCustomAdapterParams", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] +} \ No newline at end of file diff --git a/src/adaptors/tangible-rwa/caviar.js b/src/adaptors/tangible-rwa/caviar.js new file mode 100644 index 0000000000..e12e52fdf4 --- /dev/null +++ b/src/adaptors/tangible-rwa/caviar.js @@ -0,0 +1,82 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); +const { getPairs, getPrice } = require('./pearl'); + +const caviar = require('./abis/Caviar.json'); +const caviarStakingChef = require('./abis/CaviarStakingChef.json'); +const caviarRebaseChef = require('./abis/CaviarRebaseChef.json'); +const pearl = require('./abis/Pearl.json'); +const usdr = require('./abis/USDR.json'); +const wusdr = require('./abis/WrappedUSDR.json'); + +const CHAIN_NAME = 'polygon'; + +exports.pool = async () => { + const [pearlCaviarPair, pearlUsdrPair] = await getPairs([ + [pearl.address, caviar.address, false], + [pearl.address, usdr.address, false], + ]); + + return await Promise.all([ + sdk.api.abi + .multiCall({ + calls: [ + { + target: caviarRebaseChef.address, + }, + { + target: caviarStakingChef.address, + }, + ], + abi: caviarRebaseChef.abi.find((m) => m.name === 'rewardPerSecond'), + chain: CHAIN_NAME, + }) + .then((result) => result.output), + sdk.api.abi.call({ + target: usdr.address, + abi: usdr.abi.find((m) => m.name === 'liquidityIndex'), + chain: CHAIN_NAME, + }), + sdk.api.abi.call({ + target: caviar.address, + params: caviarStakingChef.address, + abi: 'erc20:balanceOf', + chain: CHAIN_NAME, + }), + ]).then(async (result) => { + [ + caviarRewardPerSecond, + wusdrRewardPerSecond, + liquidityIndex, + caviarBalance, + ] = result.flat().map((res) => res.output); + const [caviarPrice, pearlPrice] = await Promise.all([ + getPrice(pearlCaviarPair, pearl.address), + getPrice(pearlUsdrPair, usdr.address), + ]); + const usdrPrice = await utils + .getPrices([usdr.address], 'polygon') + .then((result) => result.pricesByAddress[usdr.address.toLowerCase()]); + const caviarBalanceInUSDR = new BigNumber(caviarBalance) + .multipliedBy(caviarPrice) + .multipliedBy(pearlPrice); + const tvl = new BigNumber(caviarBalanceInUSDR) + .div(1e18) + .multipliedBy(usdrPrice); + const aprBase = new BigNumber(caviarRewardPerSecond) + .multipliedBy(60 * 60 * 24 * 365) + .multipliedBy(caviarPrice) + .multipliedBy(pearlPrice) + .multipliedBy(usdrPrice) + .dividedBy(tvl) + .dividedBy(1e16); + const aprReward = new BigNumber(wusdrRewardPerSecond) + .multipliedBy(60 * 60 * 24 * 365) + .multipliedBy(liquidityIndex) + .multipliedBy(usdrPrice) + .dividedBy(tvl) + .dividedBy(1e34); + return [tvl, aprBase, aprReward]; + }); +}; diff --git a/src/adaptors/tangible-rwa/index.js b/src/adaptors/tangible-rwa/index.js new file mode 100644 index 0000000000..bc393b8c40 --- /dev/null +++ b/src/adaptors/tangible-rwa/index.js @@ -0,0 +1,61 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const cvr = require('./caviar'); + +const caviar = require('./abis/Caviar.json'); +const caviarStakingChef = require('./abis/CaviarStakingChef.json'); +const usdr = require('./abis/USDR.json'); + +const CHAIN_NAME = 'polygon'; +const TNGBL_ADDRESS = '0x49e6A20f1BBdfEeC2a8222E052000BbB14EE6007'; +const project = 'tangible-rwa'; + +const poolsFunction = async () => { + const apyData = await utils.getData( + 'http://usdr-api.us-east-1.elasticbeanstalk.com/usdr/apy' + ); + + const totalSupply = await sdk.api.abi + .call({ + target: usdr.address, + abi: usdr.abi.find((m) => m.name === 'totalSupply'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const usdrPool = { + pool: usdr.address, + chain: utils.formatChain('polygon'), + project, + symbol: utils.formatSymbol('USDR'), + tvlUsd: Number(totalSupply) / 1e9, + apyBase: Number(apyData.usdr), + apyReward: Number(apyData.tngbl), + rewardTokens: [TNGBL_ADDRESS], + underlyingTokens: [usdr.address], + url: 'https://www.tangible.store/realusd', + }; + + const [tvl, aprBase, aprReward] = await cvr.pool(); + + const caviarPool = { + pool: caviarStakingChef.address, + chain: utils.formatChain('polygon'), + project, + symbol: utils.formatSymbol('CVR'), + tvlUsd: Number(tvl), + apyBase: Number(utils.aprToApy(aprBase, 52)), + apyReward: Number(utils.aprToApy(aprReward, 52)), + rewardTokens: [usdr.address], + underlyingTokens: [caviar.address], + poolMeta: 'Caviar Staking Pool', + url: 'https://www.tangible.store/caviar', + }; + + return [usdrPool, caviarPool]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, +}; diff --git a/src/adaptors/tangible-rwa/pearl.js b/src/adaptors/tangible-rwa/pearl.js new file mode 100644 index 0000000000..ca0ce3b84d --- /dev/null +++ b/src/adaptors/tangible-rwa/pearl.js @@ -0,0 +1,94 @@ +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); + +const pearlPair = require('./abis/Pair.json'); +const pearlPairFactory = require('./abis/PairFactory.json'); + +const CHAIN_NAME = 'polygon'; + +exports.getPrice = async (pair, quoteToken) => { + let { _reserve0, _reserve1 } = await sdk.api.abi + .call({ + target: pair, + abi: pearlPair.abi.find((m) => m.name === 'getReserves'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + let [token0, token1] = await sdk.api.abi + .call({ + target: pair, + abi: pearlPair.abi.find((m) => m.name === 'tokens'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + const stable = await sdk.api.abi + .call({ + target: pair, + abi: pearlPair.abi.find((m) => m.name === 'stable'), + chain: CHAIN_NAME, + }) + .then((result) => result.output); + + if (quoteToken !== token0) { + [_reserve0, _reserve1] = [_reserve1, _reserve0]; + [token0, token1] = [token1, token0]; + } + + const [reserve0, reserve1] = [_reserve0, _reserve1].map( + (n) => new BigNumber(n) + ); + + const [decimals0, decimals1] = await sdk.api.abi + .multiCall({ + calls: [ + { + target: token0, + }, + { + target: token1, + }, + ], + abi: 'erc20:decimals', + chain: CHAIN_NAME, + }) + .then((result) => result.output.map((o) => o.output)); + + const factor0 = new BigNumber(10).pow(decimals0); + const factor1 = new BigNumber(10).pow(decimals1); + + if (stable) { + // Formula: (3 * reserve1 ** 2 * reserve0 + reserve0 ** 3) / (3 * reserve0 ** 2 * reserve1 + reserve1 ** 3) + let numerator = ethers.BigNumber.from(3) + .mul(reserve1.mul(reserve1).mul(reserve0)) + .add(reserve0.mul(reserve0).mul(reserve0)) + .mul(factor1.pow(3)); + let denominator = ethers.BigNumber.from(3) + .mul(reserve0.mul(reserve0).mul(reserve1)) + .add(reserve1.mul(reserve1).mul(reserve1)) + .mul(factor0.pow(3)); + + return numerator.div(denominator); + } else { + // Formula: reserve0 / reserve1 + return reserve0 + .multipliedBy(factor1) + .dividedBy(reserve1.multipliedBy(factor0)); + } +}; + +exports.getPairs = async (pairs) => { + return await sdk.api.abi + .multiCall({ + calls: pairs.map((p) => { + return { + target: pearlPairFactory.address, + params: p, + }; + }), + abi: pearlPairFactory.abi.find((m) => m.name === 'getPair'), + chain: CHAIN_NAME, + }) + .then((result) => result.output.map((o) => o.output)); +}; diff --git a/src/adaptors/tapp-exchange/index.js b/src/adaptors/tapp-exchange/index.js new file mode 100644 index 0000000000..cc273f25f7 --- /dev/null +++ b/src/adaptors/tapp-exchange/index.js @@ -0,0 +1,54 @@ +const utils = require('../utils'); + +const TAPP_EXCHANGE_API_URL = 'https://api.tapp.exchange/api/v1'; +const randomId = Math.floor(Math.random() * 1000000); + +async function main() { + const pools = await utils.getData(`${TAPP_EXCHANGE_API_URL}`, { + method: 'public/pool', + jsonrpc: '2.0', + id: randomId, + params: { + query: { + page: 1, + pageSize: 100, + interval: '7d', + sortBy: 'tvl', + sortOrder: 'desc', + }, + }, + }); + + const poolsData = pools.result.data; + + // filter only showing tvl > 10k + const filteredPools = poolsData.filter((pool) => Number(pool.tvl) > 10000); + + const tvlArr = []; + + for (const pool of filteredPools) { + const tokenPairs = pool.tokens.map((token) => token.symbol); + tvlArr.push({ + pool: `${pool.poolId}::${pool.poolType}::${tokenPairs.join('-')}`, + chain: utils.formatChain('aptos'), + project: 'tapp-exchange', + apyBase: pool.apr.feeAprPercentage, + apyReward: pool.apr.boostedAprPercentage, + rewardTokens: pool.apr.campaignAprs.map( + (campaign) => campaign.token.addr + ), + symbol: tokenPairs.join('-'), + tvlUsd: Number(pool.tvl), + underlyingTokens: pool.tokens.map((token) => token.addr), + url: `https://tapp.exchange/pool/${pool.poolId}`, + }); + } + + return tvlArr; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://tapp.exchange', +}; diff --git a/src/adaptors/tarot/abi.js b/src/adaptors/tarot/abi.js new file mode 100644 index 0000000000..1b4755733e --- /dev/null +++ b/src/adaptors/tarot/abi.js @@ -0,0 +1,184 @@ +module.exports = { + allLendingPools: { + constant: true, + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'allLendingPools', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + allLendingPoolsLength: { + constant: true, + inputs: [], + name: 'allLendingPoolsLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + getLendingPool: { + constant: true, + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'getLendingPool', + outputs: [ + { + internalType: 'bool', + name: 'initialized', + type: 'bool', + }, + { + internalType: 'uint24', + name: 'lendingPoolId', + type: 'uint24', + }, + { + internalType: 'address', + name: 'collateral', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable0', + type: 'address', + }, + { + internalType: 'address', + name: 'borrowable1', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + totalBorrows: { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint112', name: '', type: 'uint112' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + underlying: { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + symbol: { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + getReserves: { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: 'reserve0', type: 'uint112' }, + { internalType: 'uint112', name: 'reserve1', type: 'uint112' }, + { internalType: 'uint32', name: 'blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token0: { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token1: { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + decimals: { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + reserveFactor: { + constant: true, + inputs: [], + name: 'reserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + borrowRate: { + constant: true, + inputs: [], + name: 'borrowRate', + outputs: [{ internalType: 'uint48', name: '', type: 'uint48' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + factory: { + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +}; diff --git a/src/adaptors/tarot/config/lending-pools.js b/src/adaptors/tarot/config/lending-pools.js new file mode 100644 index 0000000000..36ea01e218 --- /dev/null +++ b/src/adaptors/tarot/config/lending-pools.js @@ -0,0 +1,8739 @@ +const LENDING_POOL_DETAILS_MAP = { + '0xa48869049e36f8bfe0cc5cf655632626988c0140': { + lendingPoolAddress: '0xa48869049e36f8bfe0cc5cf655632626988c0140', + isTarotVault: false, + dex: DEX.SUSHI, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xa48869049e36f8bfe0cc5cf655632626988c0140', + collateralAddress: '0xfb505abd709c3ab7b62aa21f639be3840163be05', + borrowableAddress0: '0x65a4810e68ab2b011140b940f8edf8ee84bc141d', + borrowableAddress1: '0x74e657267d3588d6330cf719368627f8b6f13303', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x12b42fab7821f8141a24589640c4d056946ecac6': { + lendingPoolAddress: '0x12b42fab7821f8141a24589640c4d056946ecac6', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 0, + symbol0: 'WFTM', + symbol1: 'BOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + uniswapV2PairAddress: '0xec7178f4c41f346b2721907f5cf7628e388a7a58', + collateralAddress: '0xbfd68879c32bc0341e9ddd90c7eec85d794b7363', + borrowableAddress0: '0xd05f23002f6d09cf7b643b69f171cc2a3eacd0b3', + borrowableAddress1: '0x9514d6c3f62bba5cba2565fbecd437fe3a218fbb', + farmingPoolAddress0: '0x5f0a89d57017f947f2cfef6cbacbe60a7eefd208', + farmingPoolAddress1: '0x56d4099438a5e1a80689a78cc39cfcf4f84c8d78', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x72f6a9adcafdc150ce69bd69e3455ee0ed7d2242': { + lendingPoolAddress: '0x72f6a9adcafdc150ce69bd69e3455ee0ed7d2242', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 1, + symbol0: 'WFTM', + symbol1: 'SPIRIT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x5cc61a78f164885776aa610fb0fe1257df78e59b', + uniswapV2PairAddress: '0x30748322b6e34545dbe0788c421886aeb5297789', + collateralAddress: '0x22886046e637a1e77d5d100280c838217d85cdc1', + borrowableAddress0: '0x93a97db4fea1d053c31f0b658b0b87f4b38e105d', + borrowableAddress1: '0x8d45f1496bf8a5f291dde3b40ac83a950a27a055', + farmingPoolAddress0: '0x14de3e43674852e09091c0ae4ad38583c869aa8f', + farmingPoolAddress1: '0xdb433573e93b4b4c717d64e93dbc7677dbc3f1f7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xde203f137ef23aff18f051addc36624b5a0ef0c2': { + lendingPoolAddress: '0xde203f137ef23aff18f051addc36624b5a0ef0c2', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 4, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xe7e90f5a767406eff87fdad7eb07ef407922ec1d', + collateralAddress: '0x70d3efe42f8934fa670652d0052a9e7b1eee7cd1', + borrowableAddress0: '0x710675a9c8509d3df254792c548555d3d0a69494', + borrowableAddress1: '0x6e11aad63d11234024efb6f7be345d1d5b8a8f38', + farmingPoolAddress0: '0x0ec8d2cbddf9d17b4d7c770637d739e48035251a', + farmingPoolAddress1: '0x08ddd4b74c5692f0b07cda177ba33962db21c761', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x5642b215b15d36194e90bbf217e6b7014a8965ce': { + lendingPoolAddress: '0x5642b215b15d36194e90bbf217e6b7014a8965ce', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 2, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x2b4c76d0dc16be1c31d4c1dc53bf9b45987fc75c', + collateralAddress: '0x64c3f581849068beb54fdebe3e05288b309ef447', + borrowableAddress0: '0xb7fa3710a69487f37ae91d74be55578d1353f9df', + borrowableAddress1: '0xff0bc3c7df0c247e5ce1ea220c7095ce1b6dc745', + farmingPoolAddress0: '0xd64913a182571ccc7f836060bb0b5f8e9eb4ba1b', + farmingPoolAddress1: '0xfaa719314b0dd7595656e0f7358406f7d11bd9bb', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x3e0c11024e364026046d0072f95ff898fbd7da3e': { + lendingPoolAddress: '0x3e0c11024e364026046d0072f95ff898fbd7da3e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 5, + symbol0: 'WFTM', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xf0702249f4d3a25cd3ded7859a165693685ab577', + collateralAddress: '0xc8b2935b6d078a9118d24166a0ec1d200922ee8d', + borrowableAddress0: '0x845b1619eb0c7c0f9bc7d5494a0b332f6d8fd4f6', + borrowableAddress1: '0xcda31b40671229776a5f9aedb6bbfc7e7a62eae6', + farmingPoolAddress0: '0xf3e24e2a927f12a26b8fe52f7f5d3f86afced789', + farmingPoolAddress1: '0x4d604b3eb4bbce50efea0432cb3f5b3490153be8', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xcf9f94adcf137e7398e65a0c8a3b6caf127f760e': { + lendingPoolAddress: '0xcf9f94adcf137e7398e65a0c8a3b6caf127f760e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 4, + symbol0: 'WFTM', + symbol1: 'BTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x321162cd933e2be498cd2267a90534a804051b11', + uniswapV2PairAddress: '0xfdb9ab8b9513ad9e419cf19530fee49d412c3ee3', + collateralAddress: '0x603f668931ea70db8e44210c6a22d805103fc56d', + borrowableAddress0: '0x7a7dd36bcca42952cc1e67bca1be44097ff5b644', + borrowableAddress1: '0x9800ac596e345e6a7179b33deeae2efaf7c9b8e7', + farmingPoolAddress0: '0xa3907e0b229d4abd14818c4f798ab84f3e400c8b', + farmingPoolAddress1: '0x508d4bbf34584a5bebeed04bb8121f94a5d12945', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd4ca5899c042545d602363b6dcf0aeaa42f85158': { + lendingPoolAddress: '0xd4ca5899c042545d602363b6dcf0aeaa42f85158', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 2, + symbol0: 'WFTM', + symbol1: 'BTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x321162cd933e2be498cd2267a90534a804051b11', + uniswapV2PairAddress: '0x279b2c897737a50405ed2091694f225d83f2d3ba', + collateralAddress: '0xbfae93ced8824c1e62040dc85715a6edeedabb96', + borrowableAddress0: '0xe4eb3bd58c6021de054505e85179bbd2ebc03566', + borrowableAddress1: '0xe02a4886718da7ec9e66eb75b1f22d5d3753a715', + farmingPoolAddress0: '0xad98e4a5ebcc4ae94e1d2ae55b8e1ca69811a087', + farmingPoolAddress1: '0x06426e1c851c34991e79f5caea6e802866b1c50f', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x7c8b3ba13c5bb891d765871d830e9b6f159ace13': { + lendingPoolAddress: '0x7c8b3ba13c5bb891d765871d830e9b6f159ace13', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 3, + symbol0: 'WFTM', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x613bf4e46b4817015c01c6bb31c7ae9edaadc26e', + collateralAddress: '0x753fc37744e640119de02ed03b4f8ced6baad1e6', + borrowableAddress0: '0x8254086911e2a08bf0a179e87a1d45fb6b0f64e9', + borrowableAddress1: '0x6eedde8005d974f004f9ff1e50f6cd2aeff9d407', + farmingPoolAddress0: '0xf75ef6ba5a704609a31d3f4e2af0b78b29935112', + farmingPoolAddress1: '0x6b3c5c875237a5be0774034277c2fbbe180b6aca', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x84311ecc54d7553378c067282940b0fdfb913675': { + lendingPoolAddress: '0x84311ecc54d7553378c067282940b0fdfb913675', + isTarotVault: false, + dex: DEX.SUSHI, + symbol0: 'WFTM', + symbol1: 'ICE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf16e81dce15b08f326220742020379b855b87df9', + uniswapV2PairAddress: '0x84311ecc54d7553378c067282940b0fdfb913675', + collateralAddress: '0x692ba088feebcd9f57017e573174d8d14f6a9089', + borrowableAddress0: '0x8958aa800ea1baa1c47a76ce441b9ff95548fb6a', + borrowableAddress1: '0x49fdee95ac2fdfabb9bded9db9ede35e4213c5a4', + farmingPoolAddress0: '0xc66a06991937b770ae35de273543bd9b377f7956', + farmingPoolAddress1: '0xb717ce85d2a1357285e9c4b32a6ebb1548e8598d', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xb9eef82528fe73f32deab5918af431972c24f552': { + lendingPoolAddress: '0xb9eef82528fe73f32deab5918af431972c24f552', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 7, + symbol0: 'WFTM', + symbol1: 'ICE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf16e81dce15b08f326220742020379b855b87df9', + uniswapV2PairAddress: '0x936d23c83c2469f6a14b9f5beaec13879598a5ac', + collateralAddress: '0x3de2ba8aa129ac4e23f62d55f61ac699960a7133', + borrowableAddress0: '0x60d5ef2b19078773fc7ea61599d7e5219218bf8e', + borrowableAddress1: '0x3b893dbe7d79b63f9f7357837248fff00b318e97', + farmingPoolAddress0: '0x8046ba0ccd220b318d17368bbc1b0e401930d526', + farmingPoolAddress1: '0xf3133ed63875f515112159a85f38e074765454f7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x29652f57e18c502f342eba20ebf4d42128b222ee': { + lendingPoolAddress: '0x29652f57e18c502f342eba20ebf4d42128b222ee', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 17, + symbol0: 'WFTM', + symbol1: 'ICE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf16e81dce15b08f326220742020379b855b87df9', + uniswapV2PairAddress: '0x623ee4a7f290d11c11315994db70fb148b13021d', + collateralAddress: '0xae7401ffde555a69240f1348b31d3cfa784e0f5e', + borrowableAddress0: '0x7d0eb2b3edec482c86e0d588a0f1b3a36b99d336', + borrowableAddress1: '0x09663b211c559cc5430ee1f4680d6de2888631dd', + farmingPoolAddress0: '0xd3be88da8d7549501423271d08850f4b15cc8620', + farmingPoolAddress1: '0xd81f3e702fbdd115ff6dd254c85cb20e0c4ccc1d', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x081e5c833f8b66d8f5ca96574a3a6729143d077a': { + lendingPoolAddress: '0x081e5c833f8b66d8f5ca96574a3a6729143d077a', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 24, + symbol0: 'WFTM', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0x6f86e65b255c9111109d2d2325ca2dfc82456efc', + collateralAddress: '0x949d6299d76b68719fd33b2bcec49ea176455a8d', + borrowableAddress0: '0x4e4a8ae836cbe9576113706e166ae1194a7113e6', + borrowableAddress1: '0xf13ac080bb77ad70fecc2da4107faf5d8d3c4e46', + farmingPoolAddress0: '0xadb6432003aa5e37671d8a2be5286bfce92c9abd', + farmingPoolAddress1: '0xb8cf3aba7f002820ab1a801cfe7a44c22908b836', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x9e93c992eedcad949e11e30898a4c58e378aedaa': { + lendingPoolAddress: '0x9e93c992eedcad949e11e30898a4c58e378aedaa', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 30, + symbol0: 'WFTM', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xb32b31dfafbd53e310390f641c7119b5b9ea0488', + collateralAddress: '0x2fc8ca465415985f169f67b33be058fd5c3ba738', + borrowableAddress0: '0xb566727f4edf30ba13939e304d828e30d4063c59', + borrowableAddress1: '0x2c4107f7de56f1e0f99f31fadb69284207d5fda6', + farmingPoolAddress0: '0x8464f75b81be31e94b7e1d93f3d0629d9e86596d', + farmingPoolAddress1: '0x8a6796d146a2d65f462ba83018a8812b4a3acf17', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x5e2982b55d79327887b297cdca76a7562393408b': { + lendingPoolAddress: '0x5e2982b55d79327887b297cdca76a7562393408b', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 10, + symbol0: 'CRV', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x374c8acb146407ef0ae8f82baafcf8f4ec1708cf', + collateralAddress: '0x41837b6304a94426ad3c59d882d0104238d5ad6b', + borrowableAddress0: '0x054ec0cb1798f609cb08f0848ce6cc1982acd1fe', + borrowableAddress1: '0xeaab0eb61326499a4bc79ecdbc6f3bb17b323dd6', + farmingPoolAddress0: '0x535055b0363e412b61b2fc39729673e50cb705f9', + farmingPoolAddress1: '0x2b9ca2b3bb31b8375bddc1512fe095a46dd379c1', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x9652e127c69a59ee723882fb69d7fa59cd866f50': { + lendingPoolAddress: '0x9652e127c69a59ee723882fb69d7fa59cd866f50', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 17, + symbol0: 'fUSDT', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xd14dd3c56d9bc306322d4cea0e1c49e9ddf045d4', + collateralAddress: '0xcea9c816dae9d96e7d563c8def6549948a179d8f', + borrowableAddress0: '0x83016ff687944613c2f79eb8ab3d85fd55e8e39f', + borrowableAddress1: '0x1cee4fd447d7ce967fddae4b7da872a3a1d04f4b', + farmingPoolAddress0: '0xfc9dbfc7d081fe15b198af0634104e440992e631', + farmingPoolAddress1: '0xef92c2ca392df6d351aa7d82c6d688648437bf4f', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x35d5c753563f10a7b3fad397c13ca0de785b8cb2': { + lendingPoolAddress: '0x35d5c753563f10a7b3fad397c13ca0de785b8cb2', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 21, + symbol0: 'WFTM', + symbol1: 'BNB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454', + uniswapV2PairAddress: '0x74fe5ddc4c27f91a1898ccd5ac62dfeb2d3df726', + collateralAddress: '0x7e6347ce254d4661346f59f265d93356a228b552', + borrowableAddress0: '0xd875860d6c7386e296c21374ea789c5ce574c6df', + borrowableAddress1: '0x319d788931129f36ca1c6632bb8f536705523fba', + farmingPoolAddress0: '0x5d7a9e6aa96af8fbaa9a40af13f8a23018705796', + farmingPoolAddress1: '0x3b7a555a00ee4db2670fa0cc528582c76514626e', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x5021e2f1fb0040af695d45b17f32e2cf04555770': { + lendingPoolAddress: '0x5021e2f1fb0040af695d45b17f32e2cf04555770', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 25, + symbol0: 'SPIRIT', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x5cc61a78f164885776aa610fb0fe1257df78e59b', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0xffbfc0446ca725b21256461e214e9d472f9be390', + collateralAddress: '0xf092a0c7ce5b5859890d2dad14c75a557207243d', + borrowableAddress0: '0xd4f7cd723c01c2f38388ca85aadd920c3df5c76e', + borrowableAddress1: '0xc8c57213af8241b3762ca330cf4f7cf7d7157bfc', + farmingPoolAddress0: '0x859cf2158c9263e54014f4204244a91b11adf34b', + farmingPoolAddress1: '0x75408ad366920cf800aa46403f88d4c6f2b76d22', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x59ca0775b04fbe64793af430748e6c4239644a86': { + lendingPoolAddress: '0x59ca0775b04fbe64793af430748e6c4239644a86', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 1, + symbol0: 'fUSDT', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x5965e53aa80a0bcf1cd6dbdd72e6a9b2aa047410', + collateralAddress: '0x53409182cfe736c7bc54130cfa1d1ce74662123c', + borrowableAddress0: '0x98682a6a8aa07902b71e2dc7a5e5073ed282ff42', + borrowableAddress1: '0xbeb8c1266b6a561f2f10b2d242628d7ed4ba458e', + farmingPoolAddress0: '0x92ce34dbdbe1718b77a0019a80ad30c6920c994d', + farmingPoolAddress1: '0xf208c107183095edd52c2a5e33f96fd2d2be3c49', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd29acf6899b8e19c052ab36a981880d090bace67': { + lendingPoolAddress: '0xd29acf6899b8e19c052ab36a981880d090bace67', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 3, + symbol0: 'WFTM', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0xe120ffbda0d14f3bb6d6053e90e63c572a66a428', + collateralAddress: '0x932dc1ce6833a9a0270a689eb0c92326386ef5c3', + borrowableAddress0: '0x604ea00f00c25747d369d9d114590a483e23ff48', + borrowableAddress1: '0x31c43ab4827c4ec0e5377db6a22fe83d3c415da1', + farmingPoolAddress0: '0xbf9b246add25763744daccf2c4efe701d58ba741', + farmingPoolAddress1: '0xeb78bb29a33506389e8f68e5d9348f469f76866a', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd2f9933140492a7407136707a21425a2df69c2c9': { + lendingPoolAddress: '0xd2f9933140492a7407136707a21425a2df69c2c9', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 14, + symbol0: 'CRV', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xb471ac6ef617e952b84c6a9ff5de65a9da96c93b', + collateralAddress: '0x48cb984f81335114630c5372a87b16f5c9ada07d', + borrowableAddress0: '0xcd473b8cf083a362414cf86fbda72ab2a49750be', + borrowableAddress1: '0x5b80b6e16147bc339e22296184f151262657a327', + farmingPoolAddress0: '0xc327003f1fd0ec16b9d54e2139a798217057df78', + farmingPoolAddress1: '0x3eee106ceec87cb1c2278a8626972a42a1275ead', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xe9cf8996424136634f58b48edb868287d5203e9a': { + lendingPoolAddress: '0xe9cf8996424136634f58b48edb868287d5203e9a', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 19, + symbol0: 'WFTM', + symbol1: 'BNB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454', + uniswapV2PairAddress: '0x956de13ea0fa5b577e4097be837bf4ac80005820', + collateralAddress: '0x8c9c672223a93739fa8a8bc5a2933f0ea7fb6751', + borrowableAddress0: '0xf63d4894c605c246fbe238514355e3cd9680cff0', + borrowableAddress1: '0xe69c2c761931c4bf719cf5931af37c6a09889d06', + farmingPoolAddress0: '0xc0ad7ecc6980dd62368d64a31cf1dbdb4fdef8f7', + farmingPoolAddress1: '0xd4ffaebcda66717c6022a5e5d40e2bd1ac58f02a', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xafb56de46fba7bdcbc569eec0e6bb62b6e41f5f7': { + lendingPoolAddress: '0xafb56de46fba7bdcbc569eec0e6bb62b6e41f5f7', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 40, + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0xf050133847bb537c7476d054b8be6e30253fbd05', + collateralAddress: '0x970d1cb2f261de3b956ef1c51ca89eacab0126f8', + borrowableAddress0: '0x8c97dcb6a6b08e8beece3d75e918fbc076c094ab', + borrowableAddress1: '0x63218cf07df7c177bc96573d645decf155760290', + farmingPoolAddress0: '0x8fe009e17f5906d3300910a75254f9592ca5242c', + farmingPoolAddress1: '0x508025775244a09efcfcf2c300ff18e8df223c01', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xdffae68e2b7fb1f5438df5c771fd8ae73a9b4067': { + lendingPoolAddress: '0xdffae68e2b7fb1f5438df5c771fd8ae73a9b4067', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 27, + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x11d90ea9d16e1ee5879b299a819f6d618816d70f', + collateralAddress: '0x1dc63864950831bd6335b2e89560a74be4b70006', + borrowableAddress0: '0x5dd76071f7b5f4599d4f2b7c08641843b746ace9', + borrowableAddress1: '0xe0d10cefc6cdfbbde41a12c8bbe9548587568329', + farmingPoolAddress0: '0x2ccac9f9439383516b0aea82d333c1af1d16e6f8', + farmingPoolAddress1: '0x54cb7f772461759c383fe4677e2da3c4b0db33db', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xe86382644014c9507e7adc6250193516ebf8ccc0': { + lendingPoolAddress: '0xe86382644014c9507e7adc6250193516ebf8ccc0', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 28, + symbol0: 'WFTM', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0x30872e4fc4edbfd7a352bfc2463eb4fae9c09086', + collateralAddress: '0x27cd3f8f18eae08485834fda12b42e813e49fd0d', + borrowableAddress0: '0x037d3b5213c53a54c5de243aade6e7bbd8858c70', + borrowableAddress1: '0x557ffb85a5ffb0bf878636b748487c3ec4abb8a9', + farmingPoolAddress0: '0x5024de556ec5518c7df4d8cced991827761bbb7d', + farmingPoolAddress1: '0x599da730b9a26a682095cf12fe1a0d638411410e', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x01233eb846f1ed6137448c2d64b3d9c69ade5a9d': { + lendingPoolAddress: '0x01233eb846f1ed6137448c2d64b3d9c69ade5a9d', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 23, + symbol0: 'YFI', + symbol1: 'WOOFY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 12, + tokenAddress0: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + tokenAddress1: '0xd0660cd418a64a1d44e9214ad8e459324d8157f1', + uniswapV2PairAddress: '0x287ebf376c59a037b8d8e0e987461b2fd8550d8c', + collateralAddress: '0x7ce2f84e452cac413b04f4e8ca948ca0158b94de', + borrowableAddress0: '0x24b1c4e292abe72a6764d380cfaadbabd14d80de', + borrowableAddress1: '0xa11d823eb85d23c7a12e46cb3c250df50df98277', + farmingPoolAddress0: '0x223cdaa1fed53c7272d3cb54df72fa8f973b1d2c', + farmingPoolAddress1: '0xbab1815cae6a3d85afca554c6f91786a9ec74392', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xfdef392adc84607135c24ca45de5452d77aa10de': { + lendingPoolAddress: '0xfdef392adc84607135c24ca45de5452d77aa10de', + isTarotVault: false, + dex: DEX.SPOOKY, + symbol0: 'USDC', + symbol1: 'fUSDT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 6, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + uniswapV2PairAddress: '0xfdef392adc84607135c24ca45de5452d77aa10de', + collateralAddress: '0xacb8eaeb3182ca5f312ecc37f7f8115cbc295456', + borrowableAddress0: '0x7623abcb2a3da6bb14bbb713b58c9b11fc9713b1', + borrowableAddress1: '0x9b5eb381e66170b60a7737414db3624509f03460', + farmingPoolAddress0: '0x6ee3a657b884ee15488b4e3ada36165ff4082ac2', + farmingPoolAddress1: '0x5692a1d2be132cbe0ec76346292c01f677830bb7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd837e86c951dd98b80195deb39e4166c485efff3': { + lendingPoolAddress: '0xd837e86c951dd98b80195deb39e4166c485efff3', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 27, + symbol0: 'fUSDT', + symbol1: 'BUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0xc931f61b1534eb21d8c11b24f3f5ab2471d4ab50', + uniswapV2PairAddress: '0x1ac51904cfaad15679b3500f0fc41d2971657f80', + collateralAddress: '0x402365800291dd4fbdd183b96b8d96606fb96123', + borrowableAddress0: '0x69026594c52b47fb26716d4cc1934e1f2d4f84ee', + borrowableAddress1: '0xdca2b13c3e796a2a476516ebb2731356bd4bf293', + farmingPoolAddress0: '0x8717aa8c3f0655968e474ea6427038955ef22615', + farmingPoolAddress1: '0x7c897328bf874de6d2962a64f5af2ad7a2dba916', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xc10eab109a9f4a696d60321b426bc86c272429eb': { + lendingPoolAddress: '0xc10eab109a9f4a696d60321b426bc86c272429eb', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 52, + symbol0: 'fUSDT', + symbol1: 'SPELL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x468003b688943977e6130f4f68f23aad939a1040', + uniswapV2PairAddress: '0x31c0385dde956f95d43dac80bd74fee149961f4c', + collateralAddress: '0x415f1b65cc25b40e432cb56042f99868b40dffd1', + borrowableAddress0: '0x6051a30c995a69800056ff17bf932d67cf353339', + borrowableAddress1: '0xa1b006dcaae5264dbde224cb1df875ab754c4511', + farmingPoolAddress0: '0x20f2008a1fcc7046fac87b27dac8db55617f5351', + farmingPoolAddress1: '0xac0e9a536aa8bdaf9d0b722293ac50f7e4643a37', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x50644123ee3fd57226fbbebeb79c9e7f61b2be7e': { + lendingPoolAddress: '0x50644123ee3fd57226fbbebeb79c9e7f61b2be7e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 6, + symbol0: 'WFTM', + symbol1: 'LINK', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8', + uniswapV2PairAddress: '0x89d9bc2f2d091cfbfc31e333d6dc555ddbc2fd29', + collateralAddress: '0x1b08a8776f964baf5b80626da5950ab86e3a58bd', + borrowableAddress0: '0xdf79ea5d777f28cab9fd42acda6208a228c71b59', + borrowableAddress1: '0x98ad887d54593e9f514a4b5b4791dc0a9a62145d', + farmingPoolAddress0: '0x07f19e9b4bed8f6abeb2ebe739db5cdc830a2479', + farmingPoolAddress1: '0x6a714b5789bea3f24d6e91a3a6dfbd3298e124c5', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xe556317f66f0c4f44ccd7fef20e17fa3cde2cbd9': { + lendingPoolAddress: '0xe556317f66f0c4f44ccd7fef20e17fa3cde2cbd9', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 32, + symbol0: 'WFTM', + symbol1: 'SHADE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x3a3841f5fa9f2c283ea567d5aeea3af022dd2262', + uniswapV2PairAddress: '0x20aa395f3bcc4dc44a94215d129650533b3da0b3', + collateralAddress: '0x7c00f62156d8f201bc129ceebe48109220836b81', + borrowableAddress0: '0x10a1ba0f63d71e83dc74f05c878223b2ae828300', + borrowableAddress1: '0xbd300fe1298ba08fa22527bf9f89410cca1617ae', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xcaf9f25ea321ab2675f8adb13c5df58e8918d0dd': { + lendingPoolAddress: '0xcaf9f25ea321ab2675f8adb13c5df58e8918d0dd', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 26, + symbol0: 'YFI', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x0845c0bfe75691b1e21b24351aac581a7fb6b7df', + collateralAddress: '0x7036601839bee58c64476815d03d5c8bb388f539', + borrowableAddress0: '0x024d7143c04487757dfb4c55526df32173592395', + borrowableAddress1: '0x6bb913d4b277ab2b8dadff079e244f6e61d08d6c', + farmingPoolAddress0: '0x7cc111e4e514f629ff773a7eadd30fda94c4fdf8', + farmingPoolAddress1: '0x6903f1c3494bcfae28e58693dad39ed0872bb41c', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xc0c9e66bf0f5cc40bfeb76ade0e650e8f15b7eae': { + lendingPoolAddress: '0xc0c9e66bf0f5cc40bfeb76ade0e650e8f15b7eae', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 11, + symbol0: 'WFTM', + symbol1: 'LINK', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8', + uniswapV2PairAddress: '0xd061c6586670792331e14a80f3b3bb267189c681', + collateralAddress: '0xd65cc1a261c371bd0cdab755c311726e4c4b50fc', + borrowableAddress0: '0xf2d3ae45f8775ba0a729df47210164f921edc306', + borrowableAddress1: '0x356073f1f372463bda048891795e4f1d98463d46', + farmingPoolAddress0: '0xf32ce5fa449a3391d7f79634b0a66586faffb33a', + farmingPoolAddress1: '0x0ac3307cea3d14966f5a5a98fc00f3ca565bc9ac', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x77f6199a44ac3f83db953bd30896f22be0d72551': { + lendingPoolAddress: '0x77f6199a44ac3f83db953bd30896f22be0d72551', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 8, + symbol0: 'WFTM', + symbol1: 'SUSHI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc', + uniswapV2PairAddress: '0x9fe4c0ce5f533e96c2b72d852f190961ad5a7bb3', + collateralAddress: '0x4b06d5ae9ec8e9445fee73daadfae96ab40481af', + borrowableAddress0: '0x00fb23c7169e0378a63d9cfe50ef40f944653c69', + borrowableAddress1: '0xcd0af9e83216255c3a4e48e9fc36f64d92bbfc72', + farmingPoolAddress0: '0x248b585042b3f4b1279d380ed3ce1d688539dffb', + farmingPoolAddress1: '0x24047f0af874005b9c182d801c7df2fa57640ef0', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xec5dd1fad6c4cbd57ef57a8b90bee37c3aa674f2': { + lendingPoolAddress: '0xec5dd1fad6c4cbd57ef57a8b90bee37c3aa674f2', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 13, + symbol0: 'WFTM', + symbol1: 'YFI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + uniswapV2PairAddress: '0x4fc38a2735c7da1d71ccabf6dec235a7da4ec52c', + collateralAddress: '0x9020aaa8c2c1f7f6a2fef837444be2e480e3af02', + borrowableAddress0: '0x9cded654472788a143c2285a6b2a580392510688', + borrowableAddress1: '0x0a41a6e2597a67f43069be63f312af6dbbbda037', + farmingPoolAddress0: '0x9fc4df542239611a2eb41ab583623994b69c1267', + farmingPoolAddress1: '0x405af7fd2c856fecb0a4deae18ad3e6a8aaeb744', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x1157d21ee6b01f51596df537e92f07634d826864': { + lendingPoolAddress: '0x1157d21ee6b01f51596df537e92f07634d826864', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 20, + symbol0: 'WFTM', + symbol1: 'WOOFY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 12, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd0660cd418a64a1d44e9214ad8e459324d8157f1', + uniswapV2PairAddress: '0xfd0ab56b83130ce8f2b7a4f4d4532dee495c0794', + collateralAddress: '0x5c7efa2149d337ce8a46076973001c78ff6ba2b4', + borrowableAddress0: '0x0c60dbd5b78d1488f9f71163e598d90f8ede55e7', + borrowableAddress1: '0xcb7c335d19d48571884840bab53897ce99b7ae83', + farmingPoolAddress0: '0xbe1efe0a905bf7f1977570913342bd30b623b459', + farmingPoolAddress1: '0xc63e735370ca1bc10f37ac3ea60ef7dc58c46541', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x45c0a8ace2d71e08c7e56850766e7fe8da584039': { + lendingPoolAddress: '0x45c0a8ace2d71e08c7e56850766e7fe8da584039', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 10, + symbol0: 'WFTM', + symbol1: 'SUSHI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc', + uniswapV2PairAddress: '0xf84e313b36e86315af7a06ff26c8b20e9eb443c3', + collateralAddress: '0xc668b6f42c7d13591e5bea46b19ac48209229b3f', + borrowableAddress0: '0x37f6cf24ba9e781344ae4ac8923d9a0a3910bc64', + borrowableAddress1: '0x41392cf20f12ddadcc8a0ad2040cb6b376678e38', + farmingPoolAddress0: '0xb95cbe6fdef0e8509b2d19efa30a782c2995c0f3', + farmingPoolAddress1: '0xfdf86a79846343157923c1c0d5d1931d36a647e3', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xe9f0146be89aa82a4827425240e755be01b78c82': { + lendingPoolAddress: '0xe9f0146be89aa82a4827425240e755be01b78c82', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 35, + symbol0: 'BTC', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 8, + decimals1: 18, + tokenAddress0: '0x321162cd933e2be498cd2267a90534a804051b11', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xec454eda10accdd66209c57af8c12924556f3abd', + collateralAddress: '0x214812a0e2ad2f05ae9707c7680e079124e34cc5', + borrowableAddress0: '0x967a31b5ad8d194cef342397658b1f8a7e40bcaa', + borrowableAddress1: '0x9430cfd7cae4182b87ff8b21554ceb813f50da38', + farmingPoolAddress0: '0x96546777246e774ef0113a155092238a5232bb16', + farmingPoolAddress1: '0xe2e1e0b7f0ff1dce467b8e8ef1848ce588965a9c', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x0e5736c76229e8bd4bcbc355a216d79de9caa844': { + lendingPoolAddress: '0x0e5736c76229e8bd4bcbc355a216d79de9caa844', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 38, + symbol0: 'WFTM', + symbol1: 'SPELL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x468003b688943977e6130f4f68f23aad939a1040', + uniswapV2PairAddress: '0x78f82c16992932efdd18d93f889141ccf326dbc2', + collateralAddress: '0xc8166fe1da4ad873b4c70fe8ab103a86ea73e79d', + borrowableAddress0: '0xb2aae88836b08a0df09625a74a6d830561c4c904', + borrowableAddress1: '0x702e6ca4972496572c407efcf841a1496b1cfc04', + farmingPoolAddress0: '0x2de42765ab8a7d94681eaebe72d4e52b1fcc5dcc', + farmingPoolAddress1: '0xe942dcdd2e9f340f49128589867fce4c66935fd7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x0cda2b4cd087461010dadfa6718c680cfdafaada': { + lendingPoolAddress: '0x0cda2b4cd087461010dadfa6718c680cfdafaada', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 57, + symbol0: 'MIM', + symbol1: 'wMEMO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x82f0b8b456c1a451378467398982d4834b6829c1', + tokenAddress1: '0xddc0385169797937066bbd8ef409b5b3c0dfeb52', + uniswapV2PairAddress: '0xc9b98e4a4e306dfc24bc5b5f66e271e19fd74c5a', + collateralAddress: '0xaf8cdbd1a5ea3e51b35b3425d932b1c0942e58b6', + borrowableAddress0: '0xc6caf3e4ab97f37ae78cfe6a3cc84bd75400cee9', + borrowableAddress1: '0xf062999692a9934c5832aa627c58fd9f6db4d998', + farmingPoolAddress0: '0x6aab91f35700672d0ea69951cf159af1c4668eef', + farmingPoolAddress1: '0x8991aa5a934f0ebaefba249d4c765d225ec31b69', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x0360e5a5195cfa681262a7612e655a81dd08b1a9': { + lendingPoolAddress: '0x0360e5a5195cfa681262a7612e655a81dd08b1a9', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 60, + symbol0: 'SPELL', + symbol1: 'sSPELL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x468003b688943977e6130f4f68f23aad939a1040', + tokenAddress1: '0xbb29d2a58d880af8aa5859e30470134deaf84f2b', + uniswapV2PairAddress: '0x4f41d03631ea4dc14016ccf90690d6d22b24c12d', + collateralAddress: '0x19d6ccbac61860dd74610c24ef23c7c874b183fc', + borrowableAddress0: '0x6e7dbf4c14f28db91a8c468031b7ce6a7eec675e', + borrowableAddress1: '0x5ad2aab6fc1d5064690076e84e73763169a65cf7', + farmingPoolAddress0: '0x05599b76d0c8843abc3fab9749744942b4c3ddf9', + farmingPoolAddress1: '0x7cabdff2550c08748888f965468efb547260b8c9', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x197244b7212a309a26d8f4ed21f6aa7a8634be00': { + lendingPoolAddress: '0x197244b7212a309a26d8f4ed21f6aa7a8634be00', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 18, + symbol0: 'WFTM', + symbol1: 'ANY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xddcb3ffd12750b45d32e084887fdf1aabab34239', + uniswapV2PairAddress: '0x26d583028989378cc1b7cbc023f4ae049d5e5899', + collateralAddress: '0x05e16b501c68ac6d5a7240c4a5fad48fdc3fb452', + borrowableAddress0: '0xca578d5753dc419cfa14e7711208003043b6e5b6', + borrowableAddress1: '0x8cd512af981c66bee0c3997807cbfda281553dd8', + farmingPoolAddress0: '0x8a44fa968df97d22134dcf57760adeb5ba72e10e', + farmingPoolAddress1: '0xb79bbe39892737433a43d7016118fdff978439e2', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x0f1e427036478968cb707cb903bab75af0f075ff': { + lendingPoolAddress: '0x0f1e427036478968cb707cb903bab75af0f075ff', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 22, + symbol0: 'WFTM', + symbol1: 'ANY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xddcb3ffd12750b45d32e084887fdf1aabab34239', + uniswapV2PairAddress: '0x5c021d9cfad40aafc57786b409a9ce571de375b4', + collateralAddress: '0x2fc4141e8f9ee0e482ba2d03c65b9793512b43eb', + borrowableAddress0: '0x114fb353ad085d1a4044f41988d0c212b859fbe2', + borrowableAddress1: '0x873e78c836f94b04a50014ce616b6ce319a1912a', + farmingPoolAddress0: '0xb7428982d46b3b2459ccbca152e6b934fecc9873', + farmingPoolAddress1: '0x5d5df119fa6a13f126c2c1440bcdabb10ecbacfd', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xaaafc7d4fc6d9b6b216d4dc5a87f1236c958ac7f': { + lendingPoolAddress: '0xaaafc7d4fc6d9b6b216d4dc5a87f1236c958ac7f', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 42, + symbol0: 'USDC', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x4de9f0ed95de2461b6db1660f908348c42893b1a', + collateralAddress: '0x6cd5bfae1feb317c6d978299c375d723dacd91c1', + borrowableAddress0: '0xd8339e66eeb1762e699b3f0ef694269658e2421f', + borrowableAddress1: '0x03289938cd5496e1dc7a4285457f712eb5e63a18', + farmingPoolAddress0: '0xc27f8e00c28d9dc5f24873f8001af60ae0a79db4', + farmingPoolAddress1: '0x2daad37a5186e3af14651edae227ff14e337a0d1', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x33ab4fb570509fb102bc51433c3d78226c2c7440': { + lendingPoolAddress: '0x33ab4fb570509fb102bc51433c3d78226c2c7440', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 44, + symbol0: 'WFTM', + symbol1: 'JOE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x9f47f313acfd4bdc52f4373b493eae7d5ac5b765', + uniswapV2PairAddress: '0xd518737ff601c2a7c67f55ebbeb0a4e3ff5c0c35', + collateralAddress: '0x828a69f6cbcf9b0049b539fd6e52b09735698695', + borrowableAddress0: '0x5a88f89fcc6827a1572d0efa32b82c69700aa7a0', + borrowableAddress1: '0xe5214c9f166245c3b5b01f711ef25dcb23f0a893', + farmingPoolAddress0: '0x9f1289d363aca2a65a37973aae68ff1b55b4b6d9', + farmingPoolAddress1: '0x5e2b5709fe814e9c0037dd0f1f5842aa2df5c582', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xc439220b52abf7641348896950d5a69511c18243': { + lendingPoolAddress: '0xc439220b52abf7641348896950d5a69511c18243', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.TOMB, + pid: 0, + symbol0: 'WFTM', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0x2a651563c9d3af67ae0388a5c8f89b867038089e', + collateralAddress: '0x8e4c0929606540985aa55dddbe20729eea595d1c', + borrowableAddress0: '0x3da659961cfb2b3e7b167b6d0761d6ecb5926422', + borrowableAddress1: '0xdbd846a0fc27e1f7749140f945fe7b28b9ac6a48', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x9cf1fc04e64df6691f40c00a187049b8320323bc': { + lendingPoolAddress: '0x9cf1fc04e64df6691f40c00a187049b8320323bc', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.TOMB, + pid: 1, + symbol0: 'WFTM', + symbol1: 'TSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + uniswapV2PairAddress: '0x4733bc45ef91cf7ccecaeedb794727075fb209f2', + collateralAddress: '0x40435ead2b5da9980f0511af454c7f73bddf9108', + borrowableAddress0: '0x7b501aa0ffb85171c94366db113119cdfaf7b5f5', + borrowableAddress1: '0xdb8b0449fe89cf8251c9029827fda3f11ed7150e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x2f7b62ec34019956061b06c7c14966dcad425718': { + lendingPoolAddress: '0x2f7b62ec34019956061b06c7c14966dcad425718', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 0, + gaugeAddress: '0xefe02cb895b6e061fa227de683c04f3ce19f3a62', + symbol0: 'WFTM', + symbol1: 'SPIRIT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x5cc61a78f164885776aa610fb0fe1257df78e59b', + uniswapV2PairAddress: '0x30748322b6e34545dbe0788c421886aeb5297789', + collateralAddress: '0xabccf1bf4b58d8dc55a6104971694c30ad6b0204', + borrowableAddress0: '0x09961762eee83644f0a36eb937246382f100cd4e', + borrowableAddress1: '0xc5eb7db755a870b91d18adcbbf60549a294b4130', + farmingPoolAddress0: '0x224fb7073d6c8c2abe04a326f7ebe20742695eb0', + farmingPoolAddress1: '0x0a98d9c789acf590c448eff1705d892f936c5c8f', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x9550cd12e14c7675ed0c8573fbbaaaf9b08a2ffb': { + lendingPoolAddress: '0x9550cd12e14c7675ed0c8573fbbaaaf9b08a2ffb', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 1, + gaugeAddress: '0xe86cee843a5ce2f40575544b1ffc43cb1701d9ae', + symbol0: 'WFTM', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x613bf4e46b4817015c01c6bb31c7ae9edaadc26e', + collateralAddress: '0xa3a479e8961fc5a7476f4684cc0ab14cf1a91b47', + borrowableAddress0: '0x93b2cd2f0e3d5a1f5f9955a84b8e1223bac614aa', + borrowableAddress1: '0x84097529a78121549a75e7b4136d7680aa50502a', + farmingPoolAddress0: '0xc816b56cf688e44a2da23b3d6b431e919eca774e', + farmingPoolAddress1: '0xecc1e5b307739723a561d2b0ba32afbf246310c6', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x2edc3b58646b5183ccfea216e97fa4973817d74c': { + lendingPoolAddress: '0x2edc3b58646b5183ccfea216e97fa4973817d74c', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 2, + gaugeAddress: '0xdccafce93e6e57f0464b4639d4afd7b9ad006f61', + symbol0: 'WFTM', + symbol1: 'BTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x321162cd933e2be498cd2267a90534a804051b11', + uniswapV2PairAddress: '0x279b2c897737a50405ed2091694f225d83f2d3ba', + collateralAddress: '0xaffd63137a17e9fd7b6644c48b36f565125814c4', + borrowableAddress0: '0x577bccf20972fd13bf4749df12a7616be9c8b249', + borrowableAddress1: '0x1a932bbad60d390dbdb7596e4fed9c215830d9d1', + farmingPoolAddress0: '0x6110f55d3cc4b9e3d9f13a375f7626da967e872a', + farmingPoolAddress1: '0x76ffd462954cf46cffae8a0633f540527e0f59d7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xba4181d1b6574305a803ab7fd88c4a05073b0d69': { + lendingPoolAddress: '0xba4181d1b6574305a803ab7fd88c4a05073b0d69', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 6, + gaugeAddress: '0x0b905475bea057060d066f3d1f85e6902ae62557', + symbol0: 'WFTM', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xb32b31dfafbd53e310390f641c7119b5b9ea0488', + collateralAddress: '0xc5f8bce448b5b90e48d9458c1228d04d4c472485', + borrowableAddress0: '0x44de772e41e7ec1d20f47d0c293b5c895d973b51', + borrowableAddress1: '0xbc1d2c9426c7ec8a0efc825725608fb1e9bc3704', + farmingPoolAddress0: '0xd5fa760a650b2bcb62399dbca86c4bd42824c086', + farmingPoolAddress1: '0x11f116e2a2efcecf8fe097d1c9b97b81e4779a82', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x576628396526c8ef7dd84d3a8d4e50bb15db1c86': { + lendingPoolAddress: '0x576628396526c8ef7dd84d3a8d4e50bb15db1c86', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 7, + gaugeAddress: '0x27dc7cc7175f8ac26dc7421a3a92dacdc1a9ef0d', + symbol0: 'WFTM', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x51eb93ecfeffbb2f6fe6106c4491b5a0b944e8bd', + collateralAddress: '0x077f05a81e00636fb246c71011e79262b4e4f045', + borrowableAddress0: '0x56d62514f2598fcff97c64caa236f9eaeb536f0f', + borrowableAddress1: '0xb5dd3f64b8b00d81aa2110b681d72ae43c150c61', + farmingPoolAddress0: '0x8310b224728c2a65ace36cbbcf236d6e6348b33a', + farmingPoolAddress1: '0x0f2d229a4360da33901a051912092e2c3522d8cc', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x76615a1a91f425a96e73d1d2a178e01f74026a48': { + lendingPoolAddress: '0x76615a1a91f425a96e73d1d2a178e01f74026a48', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 9, + gaugeAddress: '0xa6a6f26426fb5fe15b33fae65d1335b02dc54372', + symbol0: 'WFTM', + symbol1: 'ICE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf16e81dce15b08f326220742020379b855b87df9', + uniswapV2PairAddress: '0x936d23c83c2469f6a14b9f5beaec13879598a5ac', + collateralAddress: '0x4b7685045ea9720637f8e2e7d628b6106970539a', + borrowableAddress0: '0x48b931fbcddccfab67fe718fe567b1f67f49ccf2', + borrowableAddress1: '0x2536dcb0dbd745cc9c8ca3bbd7825448b0e4e1e8', + farmingPoolAddress0: '0xd3670e37b8a66e8ad809e27cf62b386934ed59e9', + farmingPoolAddress1: '0xc1282abb02afb856b3facf24aeb2c38a6c13d612', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xde2c8022982acba527080bb863384b8f9bcd9117': { + lendingPoolAddress: '0xde2c8022982acba527080bb863384b8f9bcd9117', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 11, + gaugeAddress: '0xa3c6d55397dcddaf9f600b082f7a6a918f2f4a5c', + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xe7e90f5a767406eff87fdad7eb07ef407922ec1d', + collateralAddress: '0xdd044e921ab56e4f1c14cc62c49f54c63e69aaa6', + borrowableAddress0: '0xb91e78e239ddf33de24e32424decffa036e770e4', + borrowableAddress1: '0x7078183318adb7088f97d5884f35b1321a34224b', + farmingPoolAddress0: '0x70b4df260d8f68127099c514526e9da90e44400a', + farmingPoolAddress1: '0x596dcc230df117d19772183a03ee4329363c0533', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x5790c009a59daa9b5b859803188a8d1877ca56cc': { + lendingPoolAddress: '0x5790c009a59daa9b5b859803188a8d1877ca56cc', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 12, + gaugeAddress: '0xed912897138f8af455b8f95f75850b11979806d8', + symbol0: 'fUSDT', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xd14dd3c56d9bc306322d4cea0e1c49e9ddf045d4', + collateralAddress: '0xd92fd5558706fe12137cd8499081672f0aec9f74', + borrowableAddress0: '0x1891069c9ca5cebca29ba34d626a4aa766e9370f', + borrowableAddress1: '0x2e5d02fb402670d76c3f31fb23e8f396e73d5252', + farmingPoolAddress0: '0xcc40461271545e9c613aeb1e9488102cc5bc16ea', + farmingPoolAddress1: '0xa066454937de53de952aea9a951e050a1d99a5a9', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xb779ea18b24abf78ae8c1689d9b9c02eb1a2a15d': { + lendingPoolAddress: '0xb779ea18b24abf78ae8c1689d9b9c02eb1a2a15d', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 13, + gaugeAddress: '0x1b6ca59bf8a911ee56e58eb5e5a97f69356ec6c3', + symbol0: 'WFTM', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0xdbc490b47508d31c9ec44afb6e132ad01c61a02c', + collateralAddress: '0xc688eabdfd698fe3796806b98d2f85b0da5a067a', + borrowableAddress0: '0x2d8c65844018e0b46f58ce8c70e01f1f21a8eac5', + borrowableAddress1: '0xc0c9316d611dd939033aa3f1e3e9d79b2a8bf58d', + farmingPoolAddress0: '0xee0e9bed2c744064ef051bad4cb66afb05a6aa5e', + farmingPoolAddress1: '0x89511ed81bbd4a3a06176ec544747a107320ad97', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x6a0c5792e58e4af845f273d4f6dd52c0987e11cf': { + lendingPoolAddress: '0x6a0c5792e58e4af845f273d4f6dd52c0987e11cf', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 14, + gaugeAddress: '0x02adc9b582e39dc4cb727a64d8584830cf1bb9bc', + symbol0: 'WFTM', + symbol1: 'SPELL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x468003b688943977e6130f4f68f23aad939a1040', + uniswapV2PairAddress: '0x19d4092635740699b6e4735701742740e235165a', + collateralAddress: '0xb014f8d403eae7d311b07cf5ec14b119f6444314', + borrowableAddress0: '0xda6225b507c9f43314396e9d27e4cb3c1f5be106', + borrowableAddress1: '0xf83d6bb90c85a0ed42c64f78fc89612756a5fef6', + farmingPoolAddress0: '0x7c2eb547e7378a6587d4dd8dfee325cb22faf6c4', + farmingPoolAddress1: '0x5e349d24b17be79d0378a8cd1a2fe68c4d927dc5', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xacf6f1f1e92109baf25ee220c4ddc6464741704e': { + lendingPoolAddress: '0xacf6f1f1e92109baf25ee220c4ddc6464741704e', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 15, + gaugeAddress: '0x237e7e20bf10a61c8ded780398aa0d5e69ddff9c', + symbol0: 'WFTM', + symbol1: 'YFI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + uniswapV2PairAddress: '0x4fc38a2735c7da1d71ccabf6dec235a7da4ec52c', + collateralAddress: '0x401ece057bd310bccf071712a08e2224afac5956', + borrowableAddress0: '0x96e33d1ecf87d27a4aee5331f452f0213914ebdc', + borrowableAddress1: '0xbb085b957ba2f0250a2c7a89e5deaebf0974bf5b', + farmingPoolAddress0: '0x9c7634242e0d28619877e3f07a39852c39eb0362', + farmingPoolAddress1: '0x6d86a1bca19917ff5a7a7ba565daca6d543bcb13', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x0cbabbbb050088fcc7162b5d4fa962c74c8fc24e': { + lendingPoolAddress: '0x0cbabbbb050088fcc7162b5d4fa962c74c8fc24e', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 16, + gaugeAddress: '0x3fd04eeb74204f8faa5ea539cd5275ec1a3aa70c', + symbol0: 'WFTM', + symbol1: 'SUSHI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc', + uniswapV2PairAddress: '0x9fe4c0ce5f533e96c2b72d852f190961ad5a7bb3', + collateralAddress: '0x7812e99fb1a2a5b313b0968608ad690e71d0c29b', + borrowableAddress0: '0xcddc0d347ca41b88742489ef778354b35c5139f5', + borrowableAddress1: '0xfec280602e428db567903174becb66ac703a8585', + farmingPoolAddress0: '0xc8333347b30b5431aff0a3b7dc36eac77744ac84', + farmingPoolAddress1: '0xdebb0e8807255cfe49e0bed42011c424848bc73b', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x6332c721c1420e2376a5236ae94bc05a62f0babc': { + lendingPoolAddress: '0x6332c721c1420e2376a5236ae94bc05a62f0babc', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 17, + gaugeAddress: '0x1360e082c01c897339b82ef098ab4e8b271252c8', + symbol0: 'WFTM', + symbol1: 'LINK', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8', + uniswapV2PairAddress: '0xd061c6586670792331e14a80f3b3bb267189c681', + collateralAddress: '0xb34afc2ce99bf7017f875fc12d55350b3397ef9e', + borrowableAddress0: '0x5b31487dad21d780d62d87d5568961c59f47948b', + borrowableAddress1: '0x8d137de87a92c613405aca40cebfcd7b8afd5eff', + farmingPoolAddress0: '0x3bc6797853e945c839ab91b8930ed6c29cb648a6', + farmingPoolAddress1: '0xd98d3c429e8e29985c97a0d369b086fecf10bd1d', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xc0662300c35226a284d65ca3616f9555586d475f': { + lendingPoolAddress: '0xc0662300c35226a284d65ca3616f9555586d475f', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 18, + gaugeAddress: '0x73ecaad4fff43619f31d47d66d841de41a933488', + symbol0: 'CRV', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x374c8acb146407ef0ae8f82baafcf8f4ec1708cf', + collateralAddress: '0xb5ef813b7dfa8d96dbe2de1e9a5e3228b0a58c21', + borrowableAddress0: '0x29d68861fd8cdb9f6c64b3b3384a12b1d1e80e09', + borrowableAddress1: '0xad760cd61f06c44b3c10dc067ded0d6621a68526', + farmingPoolAddress0: '0xd8a6db2ed6f9e5acdbe2f81ae18ffc3b245b418f', + farmingPoolAddress1: '0xe32ec4cfee5da58666d1c8fcf5db62a2fb59ee6e', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xc7186b46c0a6e9930950fd113336fb45972dcd91': { + lendingPoolAddress: '0xc7186b46c0a6e9930950fd113336fb45972dcd91', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 26, + gaugeAddress: '0xf7d3de134c9d09998f94a3de5e0d7f3317dd97be', + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0xf050133847bb537c7476d054b8be6e30253fbd05', + collateralAddress: '0xca5235d3b9dbcac46f0c8455cd83d5edaac0acd9', + borrowableAddress0: '0x21f5007180057a354dff1713aa7e3ccb8b6144a8', + borrowableAddress1: '0xda803d259204a2189a4e7448b1874e0f68b52206', + farmingPoolAddress0: '0xe2c6c65ea63ce3eca9331bcd2816f5fc017b33dc', + farmingPoolAddress1: '0x89d08d1ac4c327be63e8c84e30c677326ad979b6', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x92518ebe1ecc052815d1dda817396dd762eb1e64': { + lendingPoolAddress: '0x92518ebe1ecc052815d1dda817396dd762eb1e64', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 27, + gaugeAddress: '0x86762289ffb97f8db441a4faf5ecd335165e8e08', + symbol0: 'MIM', + symbol1: 'wMEMO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x82f0b8b456c1a451378467398982d4834b6829c1', + tokenAddress1: '0xddc0385169797937066bbd8ef409b5b3c0dfeb52', + uniswapV2PairAddress: '0xc9b98e4a4e306dfc24bc5b5f66e271e19fd74c5a', + collateralAddress: '0xcb0919ca2e7d2354f775bb532014e640b150c246', + borrowableAddress0: '0x31d9cac933c928f8647288b25fc84e8d2f29af67', + borrowableAddress1: '0x931708e4971a1690c8f7dab764405dd6811f61a5', + farmingPoolAddress0: '0x20d678690510c1f0c1af006376f08bf12a476129', + farmingPoolAddress1: '0x35007e7acb28f147c444c5de85679cb85dcc7d60', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xca7743efb8a9c9986fb88d9f47aa6072d8faf3da': { + lendingPoolAddress: '0xca7743efb8a9c9986fb88d9f47aa6072d8faf3da', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.OXD_V1, + pid: 0, + symbol0: 'USDC', + symbol1: 'OXD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xc165d941481e68696f43ee6e99bfb2b23e0e3114', + uniswapV2PairAddress: '0xd5fa400a24eb2ea55bc5bd29c989e70fbc626fff', + collateralAddress: '0x5673b1ee6e5550b53bee81f5782da6128a3895ef', + borrowableAddress0: '0xd8c8dab764a03e1df3162b560402498a4d4361c4', + borrowableAddress1: '0xeb3723d9f817368fa7bfcdbfe2d9d2870dbc1259', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xa3695a0c2424c60fba36aaccf52957c446c17dab': { + lendingPoolAddress: '0xa3695a0c2424c60fba36aaccf52957c446c17dab', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 59, + symbol0: 'USDC', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0x484237bc35ca671302d19694c66d617142fbc235', + collateralAddress: '0xdae9e6a740c2f3d2d56917169064cd2c22fbf18c', + borrowableAddress0: '0x07642848c3564e8e1566f8e55317b43375a66382', + borrowableAddress1: '0x36baa3db4d14f062c879fa41af556b6f42db6b48', + farmingPoolAddress0: '0x3a726457c84d28c8c2f396f0af41e9eb5393d272', + farmingPoolAddress1: '0xd986709c5e10942d32c4412fec9c7fbdd5abe51a', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xe4f0a4ff687fd567eb9075c543935e706a49b96f': { + lendingPoolAddress: '0xe4f0a4ff687fd567eb9075c543935e706a49b96f', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 3, + gaugeAddress: '0xb3afa9cb6c53d061bc2263ce15357a691d0d60d4', + symbol0: 'WFTM', + symbol1: 'gOHM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x91fa20244fb509e8289ca630e5db3e9166233fdc', + uniswapV2PairAddress: '0xae9bba22e87866e48ccacff0689afaa41eb94995', + collateralAddress: '0x47b3c2375b846d0e13b19673c7658bfb99eedb3d', + borrowableAddress0: '0x5516fe3b0f0d620496b784c43877de6d0d722c28', + borrowableAddress1: '0x3d9219e8089ac7cde166ab533e19792b985c8f9c', + farmingPoolAddress0: '0x7b579bb44fdb8338452daef3441bb3383049ceb2', + farmingPoolAddress1: '0x8907b461c46c5305076a55df4775a05736aae2d9', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xf59a41477a7e54274156f32f935b8b1632b3dc92': { + lendingPoolAddress: '0xf59a41477a7e54274156f32f935b8b1632b3dc92', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 4, + gaugeAddress: '0x805f756d7b2592637725a1b797088c29c9d6a1f8', + symbol0: 'WFTM', + symbol1: 'FRAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355', + uniswapV2PairAddress: '0x7ed0cddb9bb6c6dfea6fb63e117c8305479b8d7d', + collateralAddress: '0xa0005f8d7581a30a48960278b10d6fcbbf04d742', + borrowableAddress0: '0x26f10d9627cc177c6b7d774c1fbc79f18a86d426', + borrowableAddress1: '0xfca7ae9316637588dccc687117f6b40c2b96f402', + farmingPoolAddress0: '0x95c5fe6b843e7dd7d846aa38f3caeb289586f2e7', + farmingPoolAddress1: '0x420427f4cf2b878ae4d39eb66cadea5b94f986bb', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x488f1f90ab0ab463ceb3534612a051858c22a5a6': { + lendingPoolAddress: '0x488f1f90ab0ab463ceb3534612a051858c22a5a6', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 10, + gaugeAddress: '0x717bde1aa46a0fcd937af339f95361331412c74c', + symbol0: 'LQDR', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x4fe6f19031239f105f753d1df8a0d24857d0caa2', + collateralAddress: '0x694a273fe35d11e182a9de90ad25e9a99d1c90e4', + borrowableAddress0: '0x7a5a79b287a527f234d6e2c5454de2fc38f1f12d', + borrowableAddress1: '0x725e21976b57cfc22ecdcec306d2c353313c7998', + farmingPoolAddress0: '0xe028a3016221e37a2ee70eecbea00157aa6ad4cc', + farmingPoolAddress1: '0xef52c47254255582477b5c5cbe66ca7340efb35e', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x1fe1ea0d4d8f0df19c5c088b20af8f8977769096': { + lendingPoolAddress: '0x1fe1ea0d4d8f0df19c5c088b20af8f8977769096', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 62, + symbol0: 'USDC', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0x9606d683d03f012dda296ef0ae9261207c4a5847', + collateralAddress: '0xad9788d18e5cce209442126201ed64ba3b374c7b', + borrowableAddress0: '0xb564899ba911c4f6a25a7aecc4b8808a487dc8c2', + borrowableAddress1: '0xa8f3eba35c95a56cbcf506204bf47523c290936e', + farmingPoolAddress0: '0xd3f1c4b71d29bd7af9e63bace25be74f9336a17c', + farmingPoolAddress1: '0xaeacf08bcec0776f80b32a735439d8214d9b63d0', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x9bb4f82b821b63c5d912578b7f93548f5f25e749': { + lendingPoolAddress: '0x9bb4f82b821b63c5d912578b7f93548f5f25e749', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 65, + symbol0: 'USDC', + symbol1: 'fUSDT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 6, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + uniswapV2PairAddress: '0xe7f86cef8fef60ce5050899d1f8e465c00d04a79', + collateralAddress: '0x0b9a5ec57875c7ebea2094d8dc8b9f0b65f3f96f', + borrowableAddress0: '0x74aa611d3b13c13574327733862146858d80c6fe', + borrowableAddress1: '0xc805a375369ed22fa9d0a77ee66151efc8c7763a', + farmingPoolAddress0: '0x0eca1934a22be3262387c71af2b1e841f7fd9d3e', + farmingPoolAddress1: '0x3bd27485dfe0b15e4784105eebbb23d1957eb82a', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xff85dc4afe552a3475f04ae260b9575f586d7225': { + lendingPoolAddress: '0xff85dc4afe552a3475f04ae260b9575f586d7225', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 66, + symbol0: 'USDC', + symbol1: 'FRAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355', + uniswapV2PairAddress: '0x1478aec7896e40ae5fb858c77d389f0b3e6cbc5d', + collateralAddress: '0x33cbbee97742cab1ad2ef03560ef030ce9441835', + borrowableAddress0: '0xafee6d51c75704bc38e40778ae99e546d5562881', + borrowableAddress1: '0x6e243b412f91a4b8808e267fdfdaf2bdee500654', + farmingPoolAddress0: '0x05ae47f4f69c4e6f6aca84a2f9f8866e888b3b53', + farmingPoolAddress1: '0x38c7e7b245d6f54cbd458631d441de2f699894c7', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x909eb9d5d00c810bb2a1c93ebba3d9dada4ad50e': { + lendingPoolAddress: '0x909eb9d5d00c810bb2a1c93ebba3d9dada4ad50e', + isTarotVault: true, + dex: DEX.SPIRIT, + pid: 67, + symbol0: 'USDC', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xc19c7615237f770179ed93d89126478c60742664', + collateralAddress: '0x8793f2d5862aaf4ba94634a7ada3c365fa7d7b9e', + borrowableAddress0: '0x93d3701ffa4dcb5d30bcaf5cf897b08e0deca6dd', + borrowableAddress1: '0x1fa3f3f1397ef9af4195841687b4341ac0105d95', + farmingPoolAddress0: '0xc03be6d548131f3f0bb719f30a300780d8fd41ae', + farmingPoolAddress1: '0x157eb62560d5c636094a08215ba525a89b19f049', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x553ae9592cd4d73d4fb67ce4c891e7043d6fc19b': { + lendingPoolAddress: '0x553ae9592cd4d73d4fb67ce4c891e7043d6fc19b', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 37, + symbol0: 'LQDR', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x506ddcc751c7d500f983ffda6ddefbe458ba2c33', + collateralAddress: '0x76a40408550421b275df554b08b9aae3100e0954', + borrowableAddress0: '0x741c96fcf88aacc2788f921ac4a62b2a0627f21c', + borrowableAddress1: '0x7e9a1c333cab2081583b74964ff82696706bba8b', + farmingPoolAddress0: '0xb2d80109f98079d1d82d19bfb98287c84325d68a', + farmingPoolAddress1: '0x01b1107d15a1bebab1fedd2f577bfc468de6058a', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x41560b5ea2924190506cbdbdba767f848a395c9e': { + lendingPoolAddress: '0x41560b5ea2924190506cbdbdba767f848a395c9e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 57, + symbol0: 'WFTM', + symbol1: 'BRUSH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x85dec8c4b2680793661bca91a8f129607571863d', + uniswapV2PairAddress: '0x4ee115137ac73a3e5f99598564905465c101b11f', + collateralAddress: '0x89c17164cb8f9c1e556fa960303e6a158073290e', + borrowableAddress0: '0xeeb34feb8dca9a17be17da3184851fafadba62b0', + borrowableAddress1: '0xafbf06ebbeea01b229d58017ab9afd37d36c9b7a', + farmingPoolAddress0: '0xaa7685ce9f5897b99d8b68ebe892733c194f1f01', + farmingPoolAddress1: '0x79728d2de5c752433f7965f567defc8f31f8af1c', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x7c9c8834f8e8a51a15243af2fedb0b91b45cd648': { + lendingPoolAddress: '0x7c9c8834f8e8a51a15243af2fedb0b91b45cd648', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 45, + symbol0: 'USDC', + symbol1: 'TUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x9879abdea01a879644185341f7af7d8343556b7a', + uniswapV2PairAddress: '0x12692b3bf8dd9aa1d2e721d1a79efd0c244d7d96', + collateralAddress: '0xcc908a1f512dee9677b79a2e5cbb20a6e06f76ed', + borrowableAddress0: '0x3536f53757679c8f31aa2dfb2534fbcc51650e25', + borrowableAddress1: '0xc939ba5fcb0f1c03cb138197d86458cf8b3e19aa', + farmingPoolAddress0: '0x285dc9aa8344e92556ba2662255cf28e210c5402', + farmingPoolAddress1: '0x5f057a79c0cb794b5b0de6a827d305c8753c811b', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xfa7092af55474ec37bfde6947170792083fdf40f': { + lendingPoolAddress: '0xfa7092af55474ec37bfde6947170792083fdf40f', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 54, + symbol0: 'WFTM', + symbol1: 'MATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x40df1ae6074c35047bff66675488aa2f9f6384f3', + uniswapV2PairAddress: '0x7051c6f0c1f1437498505521a3bd949654923fe1', + collateralAddress: '0x048d8948fb326754b177cc5f6f9c873402f66e05', + borrowableAddress0: '0x4f04f1d467de9172a88c67f845f08d6961f39e6c', + borrowableAddress1: '0x61b4ba643e952464e7b3b0b6a44973e2a342508e', + farmingPoolAddress0: '0xeb238a070141232e108d839273fdd019c66a065e', + farmingPoolAddress1: '0x68bad952978b2adc8f6b95942b943269cf48364b', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xf8a2f66a4dd770cb3ee7ba810992eb478964b96f': { + lendingPoolAddress: '0xf8a2f66a4dd770cb3ee7ba810992eb478964b96f', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 52, + symbol0: 'WFTM', + symbol1: 'AVAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x511d35c52a3c244e7b8bd92c0c297755fbd89212', + uniswapV2PairAddress: '0x5df809e410d9cc577f0d01b4e623c567c7ad56c1', + collateralAddress: '0xf9cb063fbca0b8f3ae855b5f4fd104ee471f1d2a', + borrowableAddress0: '0xa7e140cadd68aeed5874b3417741c0176f85ace4', + borrowableAddress1: '0xf8a8965044027812572969e98ddafb1a29ab705c', + farmingPoolAddress0: '0xcd2ff1ce9558f551502d0383218c9c5b2c879eac', + farmingPoolAddress1: '0x81a35a3544dc27f1aa206023e327b215e98c6ecf', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x2e0b129d3dd14fcd676695c0a7ddef9fcc13e74e': { + lendingPoolAddress: '0x2e0b129d3dd14fcd676695c0a7ddef9fcc13e74e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 58, + symbol0: 'WFTM', + symbol1: 'BEETS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e', + uniswapV2PairAddress: '0x648a7452da25b4fb4bdb79badf374a8f8a5ea2b5', + collateralAddress: '0xc50ec5f995f76aee07ebf0f66c0e73c39d0ce79b', + borrowableAddress0: '0x0bcc954cfb4dbbcd808e84529aae1e1834a0c2c2', + borrowableAddress1: '0xdf0148de898f3a229ecd7ef414eeef54fb8fe841', + farmingPoolAddress0: '0xc9e87920b46117a5f6735e5d0415a85fc43891e4', + farmingPoolAddress1: '0x249b8042d536d8e74f00d41979e845065e0877df', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xa60b150392509636346eeb76d828ec765eff8e27': { + lendingPoolAddress: '0xa60b150392509636346eeb76d828ec765eff8e27', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 56, + symbol0: 'HND', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10010078a54396f62c96df8532dc2b4847d47ed3', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x16b6deee778bbcf427e40ffa3c14c4840be10e6a', + collateralAddress: '0x384c28410c766a009358e56532e74d495b9e6512', + borrowableAddress0: '0x5501a370fd23615575aa03a2dc4ea606d3ada88c', + borrowableAddress1: '0xeb0908108ff291c8b4e51dfd90af0d7ab9884b1f', + farmingPoolAddress0: '0xfa7d3ff16f478618aa8b332c657308f27ace3067', + farmingPoolAddress1: '0xa52a96198462a6b593c8b4fe0016de3273c284c9', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x4e890227a33fdd230de6b369aac0b397cc60a0e6': { + lendingPoolAddress: '0x4e890227a33fdd230de6b369aac0b397cc60a0e6', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.VEDAO, + pid: 9, + symbol0: 'USDC', + symbol1: 'WeVE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x911da02c1232a3c3e1418b834a311921143b04d7', + uniswapV2PairAddress: '0xff85fc809e760a09e5940546ce66dde579144a37', + collateralAddress: '0x29607b783011abdda5eaf393151465322902104c', + borrowableAddress0: '0xffaaad83e45a6ae6b6ae52a5159ebe083dcdcaf0', + borrowableAddress1: '0xd30c1342248a5a08edfdc22d6d096584f59a22b2', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x2d4f1bdf1b2fd05aa879d9cd3228f0e80a0bf20f': { + lendingPoolAddress: '0x2d4f1bdf1b2fd05aa879d9cd3228f0e80a0bf20f', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T2OMB, + pid: 0, + symbol0: 'WFTM', + symbol1: '2OMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x7a6e4e3cc2ac9924605dca4ba31d1831c84b44ae', + uniswapV2PairAddress: '0xbdc7dfb7b88183e87f003ca6b5a2f81202343478', + collateralAddress: '0xa9fa893fe8eef3d011c3bcf15c8b36588e673383', + borrowableAddress0: '0x612fe8cbf116141bb34eef8efee0bc17d3a82d86', + borrowableAddress1: '0x8d1103706c98d8abafb3030cb0877a3d78dabad3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x3c3e863f2e956ba14ff7fb5ec9e4d6d3ea868927': { + lendingPoolAddress: '0x3c3e863f2e956ba14ff7fb5ec9e4d6d3ea868927', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T2OMB, + pid: 1, + symbol0: 'WFTM', + symbol1: '2SHARES', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc54a1684fd1bef1f077a336e6be4bd9a3096a6ca', + uniswapV2PairAddress: '0x6398acbbab2561553a9e458ab67dcfbd58944e52', + collateralAddress: '0x51084b9e086ffce96189ceaa817c1d094fa5c89c', + borrowableAddress0: '0xbb2c39bfc2764ed8600eda0db56ea67a7b249477', + borrowableAddress1: '0x1fcbaed61092d5df8416eaff1f9b968a47fed505', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xaa21293e9734569fe8264a9a789240a4ba4716bf': { + lendingPoolAddress: '0xaa21293e9734569fe8264a9a789240a4ba4716bf', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T2OMB, + pid: 2, + symbol0: '2OMB', + symbol1: '2SHARES', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x7a6e4e3cc2ac9924605dca4ba31d1831c84b44ae', + tokenAddress1: '0xc54a1684fd1bef1f077a336e6be4bd9a3096a6ca', + uniswapV2PairAddress: '0xd9b5f00d183df52d717046521152303129f088dd', + collateralAddress: '0x78a92bebef6d06fb3cf0f66bf9e16307c8d2c08a', + borrowableAddress0: '0x850c404597673d81b1e7d4644be628accb976cc7', + borrowableAddress1: '0xa906bb21d5f11f502e93080ab1b4642b8b80931f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xb7a079e3e2a6b44983a7206dcf4f392acd55a70e': { + lendingPoolAddress: '0xb7a079e3e2a6b44983a7206dcf4f392acd55a70e', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T3OMB, + pid: 0, + symbol0: '3OMB', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x14def7584a6c52f470ca4f4b9671056b22f4ffde', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x83a52eff2e9d112e9b022399a9fd22a9db7d33ae', + collateralAddress: '0x8b927c1007807afd5bdb01751b1aba7fc845b62b', + borrowableAddress0: '0x92130b1676c3864d15d382b4a406923f617fd484', + borrowableAddress1: '0xa3b3ffdb3a7ec27c4b9d93d388edb94ce42095f2', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x99e4b37aacdd79347406528dd3994243b39c5709': { + lendingPoolAddress: '0x99e4b37aacdd79347406528dd3994243b39c5709', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T3OMB, + pid: 1, + symbol0: 'WFTM', + symbol1: '3SHARES', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6437adac543583c4b31bf0323a0870430f5cc2e7', + uniswapV2PairAddress: '0xd352dac95a91afefb112dbbb3463ccfa5ec15b65', + collateralAddress: '0xbcbe87db961ee6e7ab974f4a37a1da64855fcd2c', + borrowableAddress0: '0xcde8e796038373ff030b56c9717757d293b703eb', + borrowableAddress1: '0x9061c8471e208e8205a40eecb86040d7730e58f2', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd7badb2621b3741b645a35675abf176dfe4957bb': { + lendingPoolAddress: '0xd7badb2621b3741b645a35675abf176dfe4957bb', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T3OMB, + pid: 2, + symbol0: 'WFTM', + symbol1: '2SHARES', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc54a1684fd1bef1f077a336e6be4bd9a3096a6ca', + uniswapV2PairAddress: '0x6398acbbab2561553a9e458ab67dcfbd58944e52', + collateralAddress: '0x1ae697ce7854390c6ced5de8d006e899d2820c8a', + borrowableAddress0: '0xecebba2f1df5b4d39c9fac123cc60bc8bf735f1d', + borrowableAddress1: '0xd5cceaa44627f7a7ae63345744877bb656d9ccbb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xf609fcbbe80ddc8df4a0312ce8c4c1dd95e0868f': { + lendingPoolAddress: '0xf609fcbbe80ddc8df4a0312ce8c4c1dd95e0868f', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.T3OMB, + pid: 3, + symbol0: 'WFTM', + symbol1: '2OMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x7a6e4e3cc2ac9924605dca4ba31d1831c84b44ae', + uniswapV2PairAddress: '0xbdc7dfb7b88183e87f003ca6b5a2f81202343478', + collateralAddress: '0x64db48a35a5d906f1a52ae1fb84e982c91a3e6b2', + borrowableAddress0: '0x35893e3907c82663688b4965ed2458f9f01ccc6e', + borrowableAddress1: '0x9ec85bc28c781c6f7eb79a5ee7229d7c3b7a02c6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x7e2ad210fa1d69f799fe45b45d92ec43ba5ef33e': { + lendingPoolAddress: '0x7e2ad210fa1d69f799fe45b45d92ec43ba5ef33e', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 61, + symbol0: 'WFTM', + symbol1: 'MULTI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '2000000000000', + adjustSpeed1: '2000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + uniswapV2PairAddress: '0x297c8990134bf1ee08ae5d8805042fbac8781201', + collateralAddress: '0x81aac2a04bd238874882bc5ab3ff53215f32280d', + borrowableAddress0: '0x133e827dfcd415213584363f95b1c686be5dc27e', + borrowableAddress1: '0xc1a13a6eef5876fbe8fdf0c0b12dac5130a29999', + farmingPoolAddress0: '0xa373c7e1f82493addbc3dbe8e5359b824ecd9d6e', + farmingPoolAddress1: '0x7e1978b9001b17f79fca8549d8d122606df023d3', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0x7b05d4f56f617b4ee75886c770cc4277811a34d0': { + lendingPoolAddress: '0x7b05d4f56f617b4ee75886c770cc4277811a34d0', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 65, + symbol0: 'WFTM', + symbol1: 'SOLID', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '5000000000000', + adjustSpeed1: '5000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x888ef71766ca594ded1f0fa3ae64ed2941740a20', + uniswapV2PairAddress: '0xc8cc1b89820791665b6f26b00b3111b00e021f19', + collateralAddress: '0x17f3b2a2ebe6676744fa34387df4517140adc9c2', + borrowableAddress0: '0x84069262f02a95f5fe8f9f2889003f256c3c5849', + borrowableAddress1: '0xfbc27b5797667ed94fc381a74c226d444f25ec66', + farmingPoolAddress0: '0x9ee6db7f952823ed47d4e3f51aa93d95595b5633', + farmingPoolAddress1: '0xdba325315ec241734feadf4ad44d165f0512a07f', + poolDisabled: false, + tarotFactoryAddress: '0x35c052bbf8338b06351782a565aa9aad173432ea', + tarotRouterAddress: '0x283e62cfe14b352db8e30a9575481dcbf589ad98', + }, + '0xd0ad79e5acc51afdf4693d8304f40a1a221abe9e': { + lendingPoolAddress: '0xd0ad79e5acc51afdf4693d8304f40a1a221abe9e', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.BASED, + pid: 0, + symbol0: 'TOMB', + symbol1: 'BASED', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0x8d7d3409881b51466b483b11ea1b8a03cded89ae', + uniswapV2PairAddress: '0xab2ddcbb346327bbdf97120b0dd5ee172a9c8f9e', + collateralAddress: '0x3aa7e4128f84a605ac136ba56289d50b8e3cfa09', + borrowableAddress0: '0x62fad47ed7cf0d88806c4985863b706584350e05', + borrowableAddress1: '0xe9108e10723cbe6e64f3f55159e45974b4029859', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x2a42314f7b4b43ec588f709580350288a64a5c71': { + lendingPoolAddress: '0x2a42314f7b4b43ec588f709580350288a64a5c71', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.BASED, + pid: 1, + symbol0: 'WFTM', + symbol1: 'BSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x49c290ff692149a4e16611c694fded42c954ab7a', + uniswapV2PairAddress: '0x6f607443dc307dcbe570d0ecff79d65838630b56', + collateralAddress: '0x32f502d7273cde0c877de08782cfc8d221478655', + borrowableAddress0: '0x923d731f0a75e4af9000646da301b78fe33d71e9', + borrowableAddress1: '0xb0b71b193b0f1a86c813738567c4448713e23ca9', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x09b8bb15e7706c4df8a1a9a3e02659f37b07542b': { + lendingPoolAddress: '0x09b8bb15e7706c4df8a1a9a3e02659f37b07542b', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 2, + symbol0: 'TOMB', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x45f4682b560d4e3b8ff1f1b3a38fdbe775c7177b', + collateralAddress: '0xa745b8365c34b9631a3151f8657d1600f82b7e60', + borrowableAddress0: '0xba36f108d499804d0d434a2f302aec4b0ab6f40b', + borrowableAddress1: '0xcdbd99ce5b6b8caa87ab7332e59eed2a5cdf99f0', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xdadb090017ba6d5d320872d96b823531f6b80a44': { + lendingPoolAddress: '0xdadb090017ba6d5d320872d96b823531f6b80a44', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 23, + symbol0: 'WFTM', + symbol1: 'BIFI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd6070ae98b8069de6b494332d1a1a81b6179d960', + uniswapV2PairAddress: '0x1656728af3a14e1319f030dc147fabf6f627059e', + collateralAddress: '0x9a3221a8bbd6c2bc318a6410a0e96f428aee9522', + borrowableAddress0: '0x02abd28ac6c7161aa556a2e5dc9bea54896695c9', + borrowableAddress1: '0xd0ea500a1219ef9339058748a82cf625f31b586b', + farmingPoolAddress0: '0xbf70ba3299a2b1d4426a9079e800136616179cf0', + farmingPoolAddress1: '0x263199057f1a606a2c05a1ee4fbeeff4908f3ed0', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xffa854ab1aec94c39494e20dc0b326e1fe81aec0': { + lendingPoolAddress: '0xffa854ab1aec94c39494e20dc0b326e1fe81aec0', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 69, + symbol0: 'USDC', + symbol1: 'BOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + uniswapV2PairAddress: '0xf8cb2980120469d79958151daa45eb937c6e1ed6', + collateralAddress: '0x4938681cc05ba234947c2353db4a47ddf89b3752', + borrowableAddress0: '0xfea97187c7d46a1e29d4f35e7314d37859902a2c', + borrowableAddress1: '0x0af723efb0c4fd494054bf58e1cd757c26028735', + farmingPoolAddress0: '0x137ffffb1a2b79adc4137f1495c9d10b755b2bfb', + farmingPoolAddress1: '0xdb8cd3f464a4eaa13e3c624391aca94252ef6dcb', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x0e4e825977e168f97148fe5656fb4c774ca2ff9a': { + lendingPoolAddress: '0x0e4e825977e168f97148fe5656fb4c774ca2ff9a', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 70, + symbol0: 'WFTM', + symbol1: 'APE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x2d72a97a31dc920db03330780d30074626e39c8a', + uniswapV2PairAddress: '0xc9fb686f14bda7e2653cf8f605dc8551b6a53fd3', + collateralAddress: '0xa98cb22784d80316281867d35b80e3b5dc2621aa', + borrowableAddress0: '0xbc05b4834fedb1c74df54777c4439023c0df4534', + borrowableAddress1: '0xf57271445f1a2fd0061fb2e9a91243ef71385561', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf0fdd57186359208aa2ba0175436c86372208f18': { + lendingPoolAddress: '0xf0fdd57186359208aa2ba0175436c86372208f18', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 29, + gaugeAddress: '0x7a91957097e85bb933828d4cc7db287f573d0b2f', + symbol0: 'WFTM', + symbol1: 'DEUS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xde5ed76e7c05ec5e4572cfc88d1acea165109e44', + uniswapV2PairAddress: '0x2599eba5fd1e49f294c76d034557948034d6c96e', + collateralAddress: '0x0f72d6d19c87555af68dffb71f83c3910af90761', + borrowableAddress0: '0xa7f40a6cbc2626bcc097f179b4d23e4525e4bf1b', + borrowableAddress1: '0x7585fe31fb3521a352f88db90c6ab142a1221f2a', + farmingPoolAddress0: '0xa860f48176fce7bde1dc298706a95b8752c0a104', + farmingPoolAddress1: '0x37ab40ef5dbe7ccf3beab3117bf49a7d1eae1ae6', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x98220747eef09c849fda1961c018a6c949464010': { + lendingPoolAddress: '0x98220747eef09c849fda1961c018a6c949464010', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 30, + gaugeAddress: '0x6cb0ca6635027623684ebd3387a6f5188fe90ea2', + symbol0: 'USDC', + symbol1: 'DEI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + uniswapV2PairAddress: '0x8efd36aa4afa9f4e157bec759f1744a7febaea0e', + collateralAddress: '0x3f37739646b3eefbd8b1769b78b96e3fdde3de88', + borrowableAddress0: '0x23013fd32b980ce78acebdaa9dfd8e79390b175a', + borrowableAddress1: '0x2945ac0fc468bcb91950eea2372c1253c704ba23', + farmingPoolAddress0: '0xcdd5b7941b4138eb62b604604656ba1e7b4e8798', + farmingPoolAddress1: '0x8ec877da515b7aa5ad7d5d6a0624ca4022ff4e7f', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x300295c6ef497ba622a869b847f2b40ee379452f': { + lendingPoolAddress: '0x300295c6ef497ba622a869b847f2b40ee379452f', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 32, + gaugeAddress: '0xdcd990038d9cbe98b84a6ad9dbc880e3d4b06599', + symbol0: 'WFTM', + symbol1: 'CRE8R', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x2ad402655243203fcfa7dcb62f8a08cc2ba88ae0', + uniswapV2PairAddress: '0x459e7c947e04d73687e786e4a48815005dfbd49a', + collateralAddress: '0x69edbca1cb658f056523a1efa23a1beaf8bdbe61', + borrowableAddress0: '0x2a697a95219ff80315510d351dc1985401ce3de2', + borrowableAddress1: '0x6cc71989cf3440c11f7aab4ec25aaaba16d81943', + farmingPoolAddress0: '0xa975f642167fe18cd0d864405c71f91577a28f93', + farmingPoolAddress1: '0x910caf033b3bc457bcb706b528268c1944de71e4', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x7c630afa6255a80915932f9921ba12576db54a63': { + lendingPoolAddress: '0x7c630afa6255a80915932f9921ba12576db54a63', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 41, + gaugeAddress: '0x356169bea8c58c3b59e83c650a1608fc54d0c44a', + symbol0: 'WFTM', + symbol1: 'BIFI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd6070ae98b8069de6b494332d1a1a81b6179d960', + uniswapV2PairAddress: '0xc28cf9aebfe1a07a27b3a4d722c841310e504fe3', + collateralAddress: '0xe9c4b53c4ea943398080ba6680baad71e6355dab', + borrowableAddress0: '0xfa0c5884aa1c98d27c10b34488fe840438be3190', + borrowableAddress1: '0x5500781137e7dd0f18bf13fdc42f53bef707ddd3', + farmingPoolAddress0: '0x7b669ed4806fab903680c2fb2bbbd746e2416ea3', + farmingPoolAddress1: '0xd4f8795b28c73f52384124dd6d6564381aff81bd', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc0d477f3429d629208a390cbf123aecb534cc8eb': { + lendingPoolAddress: '0xc0d477f3429d629208a390cbf123aecb534cc8eb', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 47, + gaugeAddress: '0xab9f86efd519eb9b110542faf984780e3d99e697', + symbol0: 'WFTM', + symbol1: 'beFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x7381ed41f6de418dde5e84b55590422a57917886', + uniswapV2PairAddress: '0xe3d4c22d0543e050a8b3f713899854ed792fc1bd', + collateralAddress: '0x459f52b2f79824dc606caa639e44ce18a2009611', + borrowableAddress0: '0xcea57ecccd53a96054b1b03573cf87c7788d48ed', + borrowableAddress1: '0x1696c05acdf942a4d60ee85c7808d90695f8a166', + farmingPoolAddress0: '0x459662b66f944c902f228b6bbdcff1ed4b5710f0', + farmingPoolAddress1: '0xb1d474a181146618f18ca9aba52a3e3a37c9e78a', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x016ddef7abbe7f9e8da8c2bd655922a9b8986d5b': { + lendingPoolAddress: '0x016ddef7abbe7f9e8da8c2bd655922a9b8986d5b', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 52, + gaugeAddress: '0xb1bc9455db839655b1a3c1c128e6ab094190b724', + symbol0: 'WFTM', + symbol1: 'UST', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x846e4d51d7e2043c1a87e0ab7490b93fb940357b', + uniswapV2PairAddress: '0xfa84ced3dc4bffaf93d21b9e3a4750f5c2a42886', + collateralAddress: '0x250bcc829fa1908cea5e74ca07d3a75fde2bb3b4', + borrowableAddress0: '0x47bd57dae9d57d3de292b236bc0c748335488327', + borrowableAddress1: '0xa059cca4f26a14a79a67435571733e08df9b4afe', + farmingPoolAddress0: '0x63b22461e2eb8bcf5230d32e4309aa8ebbecd613', + farmingPoolAddress1: '0x246abef96e6102aff8eed8c39829e53613a199e1', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x04804e6f84e0c7e4660b7323127871030b87687a': { + lendingPoolAddress: '0x04804e6f84e0c7e4660b7323127871030b87687a', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 3, + symbol0: 'WFTM', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0xfca12a13ac324c09e9f43b5e5cfc9262f3ab3223', + collateralAddress: '0x89e2edd65bb05351f5b8d3e5d245bfb38747e991', + borrowableAddress0: '0xcb61e66a8a6a62afb14858965d887952984587b9', + borrowableAddress1: '0xbdea9419f069001907c13808b4f68282e013e118', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe6d31ab5607eb7618a16b5923b67314d16bd350f': { + lendingPoolAddress: '0xe6d31ab5607eb7618a16b5923b67314d16bd350f', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 4, + symbol0: 'TSHARE', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x67b2faf48c1710ff1d2a9ac429b726b8f63ee83c', + collateralAddress: '0x73151cca9e1fb165ab4e527a3ebc4d22a66e8980', + borrowableAddress0: '0xc14f09b04c99f73a6c7ef5513763dabf54a1cc58', + borrowableAddress1: '0x280dc734aa2592a2f0d4582200cfd6d8067b72a8', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x4601ad6ffd55f15dadc639b8704b19dc4b7dfc91': { + lendingPoolAddress: '0x4601ad6ffd55f15dadc639b8704b19dc4b7dfc91', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.BASED, + pid: 6, + symbol0: 'BASED', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x8d7d3409881b51466b483b11ea1b8a03cded89ae', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x7b5b3751550be4ff87ac6bda89533f7a0c9825b3', + collateralAddress: '0x975fae1e67390a2a40b333808a65faf468880607', + borrowableAddress0: '0x6dd61797dabf84985c1ca3941c5abc0fe254aa5f', + borrowableAddress1: '0x4fba508ce473ac808ca742e37c60ef9a9e3531ad', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: true, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x6d368f3f94601cce3f9806381a6132feb0dd6272': { + lendingPoolAddress: '0x6d368f3f94601cce3f9806381a6132feb0dd6272', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.BASED, + pid: 7, + symbol0: 'TOMB', + symbol1: 'BASED', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0x8d7d3409881b51466b483b11ea1b8a03cded89ae', + uniswapV2PairAddress: '0x172bfaa8991a54abd0b3ee3d4f8cbdab7046ff79', + collateralAddress: '0x6f192c6c441c06200ae26060fb22f8a42e92b954', + borrowableAddress0: '0xe5f57902b2a6f2607855f1707fd3bec9b74796c4', + borrowableAddress1: '0x38425f311aa93241f5f0d606b8967c2900af0173', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: true, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe841cd70e83ddee17f5432e06b12b77914fff4b8': { + lendingPoolAddress: '0xe841cd70e83ddee17f5432e06b12b77914fff4b8', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.BASED, + pid: 6, + symbol0: 'BASED', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x8d7d3409881b51466b483b11ea1b8a03cded89ae', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x7b5b3751550be4ff87ac6bda89533f7a0c9825b3', + collateralAddress: '0x8bdfd042ce29fb43b0b0b7dbceeab99169964700', + borrowableAddress0: '0x78d8336f9046e45a374fff00278794d615987213', + borrowableAddress1: '0xc1ae31030b419920e8b14376830082bda0c967f2', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc69552bf7cd99aa3faf2bbbd5b4aa5b2857513b5': { + lendingPoolAddress: '0xc69552bf7cd99aa3faf2bbbd5b4aa5b2857513b5', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.BASED, + pid: 7, + symbol0: 'TOMB', + symbol1: 'BASED', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0x8d7d3409881b51466b483b11ea1b8a03cded89ae', + uniswapV2PairAddress: '0x172bfaa8991a54abd0b3ee3d4f8cbdab7046ff79', + collateralAddress: '0x2f0b5e091cc1e36636cb077d623c87a770e12511', + borrowableAddress0: '0x445f69a4a1e6a5f15980a560bf9deb444ee51ac1', + borrowableAddress1: '0x44e0f499176ad70bde076d209a5ff3b7acd6fc0d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf96e636366c672447d40585b076459412f0fadb2': { + lendingPoolAddress: '0xf96e636366c672447d40585b076459412f0fadb2', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 75, + symbol0: 'WFTM', + symbol1: 'LUNA', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x593ae1d34c8bd7587c11d539e4f42bff242c82af', + uniswapV2PairAddress: '0xd8934c58de27e7b6342924b185da0b3ab009f959', + collateralAddress: '0x95f3c7edfbd3da7f2cd75f04e0cea6186bf6fd55', + borrowableAddress0: '0x5990ddc40b63d90d3b783207069f5b9a8b661c1c', + borrowableAddress1: '0xae352a9a76ca357563f6d59d892551c207da41f0', + farmingPoolAddress0: '0xe6b49bb5968c51726d949f5f544ce9532b648ed2', + farmingPoolAddress1: '0xe973b3684e382d03d73e88f8ede79daff0978a63', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x675c8dacc134b28c5cb256ff26bbde10f5f27586': { + lendingPoolAddress: '0x675c8dacc134b28c5cb256ff26bbde10f5f27586', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 76, + symbol0: 'WFTM', + symbol1: 'UST', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x846e4d51d7e2043c1a87e0ab7490b93fb940357b', + uniswapV2PairAddress: '0x656b3264695690322acbad95f994b51c5a8c8edf', + collateralAddress: '0xce73d9fa32494103dee3dd9d56da939d84f58c8d', + borrowableAddress0: '0x6bc4c41b4c38c28f36d0b6a650fa93569a69bc5c', + borrowableAddress1: '0x89bead6ae53c37a2341aaffaab1cacf94c4ba2e6', + farmingPoolAddress0: '0x6ad1256310b885140d48a7d4632dee1883b71c0c', + farmingPoolAddress1: '0x5452fccfdd16df26c2ca79ba27723ca3b39e9ff9', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x18fc05a12ce30d7514e8c59c035b7b5cc68a98e0': { + lendingPoolAddress: '0x18fc05a12ce30d7514e8c59c035b7b5cc68a98e0', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 1, + symbol0: 'USDC', + symbol1: 'DEI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + uniswapV2PairAddress: '0xd343b8361ce32a9e570c1fc8d4244d32848df88b', + collateralAddress: '0xe9353160cad51ef2ae83f71e56283b62c61ed2ad', + borrowableAddress0: '0x893beb893baf18d18050ec2de71ad4d70f9998f4', + borrowableAddress1: '0x00ca688f69870a68bd80cb11adf8237a8c594aad', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x86fbecb2e655102e97019358855d0aad9adff26b': { + lendingPoolAddress: '0x86fbecb2e655102e97019358855d0aad9adff26b', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 2, + symbol0: 'WFTM', + symbol1: 'DEUS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xde5ed76e7c05ec5e4572cfc88d1acea165109e44', + uniswapV2PairAddress: '0xaf918ef5b9f33231764a5557881e6d3e5277d456', + collateralAddress: '0xa583e23e1d6219d6570a71197471432ac006368b', + borrowableAddress0: '0x7b0d24741d85c6733d10ed59b22335fbb3ada32e', + borrowableAddress1: '0xf7c9f2e8df56d3898deaaabe8e35bb98aaf8f749', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x92eb021eda4c3c841d48475a3fa0310d9d5c307e': { + lendingPoolAddress: '0x92eb021eda4c3c841d48475a3fa0310d9d5c307e', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 4, + symbol0: 'WFTM', + symbol1: 'sFTMX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd7028092c830b5c8fce061af2e593413ebbc1fc1', + uniswapV2PairAddress: '0xe67980fc955fecfda8a92bbbfbcc9f0c4be60a9a', + collateralAddress: '0xb50f9faea66539d845094627f1acae09ee314e88', + borrowableAddress0: '0xbc96dd6347c261ffe54bb3f0b2504b1be4410e38', + borrowableAddress1: '0x297ebf6b7179d3fceb69cc0d02ed60c322dfcaf0', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x18829eb4d371e2bf93b6d7cb807122cab4577dd7': { + lendingPoolAddress: '0x18829eb4d371e2bf93b6d7cb807122cab4577dd7', + isTarotVault: true, + dex: DEX.SPIRIT, + vaultType: VaultType.SPIRIT_BOOSTED, + pid: 55, + gaugeAddress: '0x3a3c0449fdd642dd9bb714b5b8f90d7f198a0024', + symbol0: 'WFTM', + symbol1: 'sFTMX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd7028092c830b5c8fce061af2e593413ebbc1fc1', + uniswapV2PairAddress: '0x72133bbff5072616e165237e69b3f4c87c1a94e8', + collateralAddress: '0x456c1086acdbb567a6cbc917ab91e1c2290aaea1', + borrowableAddress0: '0x661fc67b5c00dfff84646e80de9efc0312d7e18b', + borrowableAddress1: '0x18392d7112f533540b18bae28af46aa2acef09e6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x22b20d4c5ea37f9227915e57cdeebf75e40eebf4': { + lendingPoolAddress: '0x22b20d4c5ea37f9227915e57cdeebf75e40eebf4', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 6, + symbol0: 'BTC', + symbol1: 'TSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 8, + decimals1: 18, + tokenAddress0: '0x321162cd933e2be498cd2267a90534a804051b11', + tokenAddress1: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + uniswapV2PairAddress: '0xa1f4a9ee0d06115376dff357d34c3f5eb4107398', + collateralAddress: '0xbd9f91ca626b230d0c95fc4a12237c0ce0a8ebf6', + borrowableAddress0: '0xf0763274fd6578077ce687f2c0abe92a1cfa3b1d', + borrowableAddress1: '0x6fd968c8a09f3653524f746a99ccb6da7bd46b12', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xff31d4850943291033de5d531f1844bf21e923d3': { + lendingPoolAddress: '0xff31d4850943291033de5d531f1844bf21e923d3', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 7, + symbol0: 'TSHARE', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xd702d7495b010936ebc53a1efee42d97996ca5ee', + collateralAddress: '0x4a3d8d1fc8b01f0c8216cb4a73b0b34255253419', + borrowableAddress0: '0x9487ce2f8e6c0cae2cdc272c097da0dcfbb24f2c', + borrowableAddress1: '0xa7861cb21e3181864760e247ce23d33d5dc72ae2', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x3fa4226faa9cc45c9b1317377ec450c58e54d2c1': { + lendingPoolAddress: '0x3fa4226faa9cc45c9b1317377ec450c58e54d2c1', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 8, + symbol0: 'USDC', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0xedf6595e2ae78a4e5c8725d7ed2a28ad974f1b8e', + collateralAddress: '0x85caf116d763eff267e8ff21d2a865bbbb37bd4e', + borrowableAddress0: '0xdb1afbc52eaacde3b5d4964fe344a6a5b9ce1338', + borrowableAddress1: '0x165993286dd83ea4e366735116b0316d6a7f026d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc27f2bc83b5e82a89810f368363f021b2fc056fc': { + lendingPoolAddress: '0xc27f2bc83b5e82a89810f368363f021b2fc056fc', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 9, + symbol0: 'USDC', + symbol1: 'fUSDT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 6, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + uniswapV2PairAddress: '0x3486011e2e18ccf4558c4c84d5cbbccfdbf16c03', + collateralAddress: '0x9ab2a4c5a5d3e7f170885a0ad367713141537b23', + borrowableAddress0: '0xa04e4bb66b686afc4750fc0e0ce4db3b9664e3b2', + borrowableAddress1: '0xe75370b44075a2c441d04c4cc0c85443974908a3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe41451cf4f75cefda4a9d78f9a6ace46a5115897': { + lendingPoolAddress: '0xe41451cf4f75cefda4a9d78f9a6ace46a5115897', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 10, + symbol0: 'USDC', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xd840af68b35469ec3478c9b0cbcddc6dc80dd98c', + collateralAddress: '0xa287ddd1f60297990e56a4fcf82b265eb71d5aa8', + borrowableAddress0: '0x18d40342042aa36eb4a2c03744d7c9114ec2a281', + borrowableAddress1: '0x38131fce386d6fe5acba4d7fdac84737b036a41b', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x28fea858ec73548c0308f7b9356a4e6911a589c5': { + lendingPoolAddress: '0x28fea858ec73548c0308f7b9356a4e6911a589c5', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 11, + symbol0: 'USDC', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0xaa9be68d990d5e56870b2e0544f96ffb0b1da8f7', + collateralAddress: '0x5565b216c112ac69f21193da9d2eac1a583ab10e', + borrowableAddress0: '0xd5e0c06535c3a698278e7736c3d4179dbf631b44', + borrowableAddress1: '0x6f266ead5389a2f2febde3e6fac95abd3da4e65d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x30aac38a9527d82e0cc7105b4be7871c36daabe3': { + lendingPoolAddress: '0x30aac38a9527d82e0cc7105b4be7871c36daabe3', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 12, + symbol0: 'USDC', + symbol1: 'TSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + uniswapV2PairAddress: '0xdec1259188e6c5273acd1e84d5b4b58897ca013e', + collateralAddress: '0x553728d83d89924d10c09c400d8f9be325e70443', + borrowableAddress0: '0x0acb77118cd570a95068f7dea9c9ce59d88bbc25', + borrowableAddress1: '0x1f615aa66bff3384d28f67a1db6527f95c4e2cf0', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x45de440a365209a14f252734b77d9be58c96c510': { + lendingPoolAddress: '0x45de440a365209a14f252734b77d9be58c96c510', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 13, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x8c853ce1561a2c2cd2e857670e3ccd04ba4cb27b', + collateralAddress: '0x8aa5937dcf5162a51c273145ddf209270b396b4c', + borrowableAddress0: '0x3ca8e0675a4436acc6a29b9f28ed2fbe94cab5ce', + borrowableAddress1: '0x98c0d6fbf237afe3691808e356b2e0adfd52ced1', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xd06214f62d4624c0c531c8c27bf3263e72d868d4': { + lendingPoolAddress: '0xd06214f62d4624c0c531c8c27bf3263e72d868d4', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 78, + symbol0: 'USDC', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x35a60b8c750b4d834a27443f35269a84d06de391', + collateralAddress: '0xb47b46b0464b363e45ba62773bccbff80accf387', + borrowableAddress0: '0xc81b902d10a6de1bf150c9261ba931e734ae7bb5', + borrowableAddress1: '0x9bb784e77b69a36ce7a4f16cb16d25bbe56925a5', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc9624a1f71592eed1df7169562e73af50cd49c43': { + lendingPoolAddress: '0xc9624a1f71592eed1df7169562e73af50cd49c43', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 14, + symbol0: 'USDC', + symbol1: 'FUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xad84341756bf337f5a0164515b1f6f993d194e1f', + uniswapV2PairAddress: '0x38ff5377a42d0a45c829de45801481869087d22c', + collateralAddress: '0x56940874608bcb219a0c69af440ea36b9be5aae2', + borrowableAddress0: '0x44b79e8483db8699400f3849725ba9c0f9ae3bd7', + borrowableAddress1: '0xb9c6bdaf41ef4a04f0f6874eb64035ff8de361e4', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf0843e749ac88ba7d20660c61a81101280798b0e': { + lendingPoolAddress: '0xf0843e749ac88ba7d20660c61a81101280798b0e', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 16, + symbol0: 'ZOO', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 0, + decimals1: 18, + tokenAddress0: '0x09e145a1d53c0045f41aeef25d8ff982ae74dd56', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0x67019e7b4a233cc2e875e5c713042333d879aace', + collateralAddress: '0x3c80ec3112bcc46846e4d81021fb22a7da589d2c', + borrowableAddress0: '0x15481370ba9abae14c5d853a27644bdf6d38cd11', + borrowableAddress1: '0x7e41321788ed396d1756c0770dfb03c59cb81e28', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x9f5ff4c6c040c9e39f50ba92cae2de28f67fbc1e': { + lendingPoolAddress: '0x9f5ff4c6c040c9e39f50ba92cae2de28f67fbc1e', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.TOMB, + pid: 17, + symbol0: 'TOMB', + symbol1: 'TREEB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xc60d7067dfbc6f2caf30523a064f416a5af52963', + uniswapV2PairAddress: '0x801d17c21d0808bc00d46e2f081214c9d82f4fbf', + collateralAddress: '0x4a07fdc332254bdd36075d622ad75a2033976608', + borrowableAddress0: '0x1a34e3be20a966d046ff43ab3b6f5d8f5c7978d4', + borrowableAddress1: '0x0d2d6208ae09a68628d1f1ba0ff8b5d4a6c11e26', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe8087d14c53ea14c860973d2c64c69c011925a1c': { + lendingPoolAddress: '0xe8087d14c53ea14c860973d2c64c69c011925a1c', + isTarotVault: true, + dex: DEX.SPOOKY, + pid: 74, + symbol0: 'WFTM', + symbol1: 'beFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x7381ed41f6de418dde5e84b55590422a57917886', + uniswapV2PairAddress: '0xb5512e3fa8304d33cdae4a40c21f1d3f70eba45a', + collateralAddress: '0x4b14daea4b33deacc68ef92077fa17e0fff814a1', + borrowableAddress0: '0xd60d8e6a0cdb12357bb3fcd332cf97135a21f38b', + borrowableAddress1: '0x47d5f54f6274299e2a569e7f5e7642d6967aa9ea', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xcc675d69563774feb559834d90064bbff8acd787': { + lendingPoolAddress: '0xcc675d69563774feb559834d90064bbff8acd787', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 0, + symbol0: 'WFTM', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0xfca12a13ac324c09e9f43b5e5cfc9262f3ab3223', + collateralAddress: '0xc383465564864565ca1741d08192cde9c5beb74a', + borrowableAddress0: '0xf5099a10ca1b80757777507c784c49688c1f560a', + borrowableAddress1: '0xdbf394be52302987d65ed591e00c12791a6e66f6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc6879cc07960d9862d3a3d942ab8c5ee4fc9e430': { + lendingPoolAddress: '0xc6879cc07960d9862d3a3d942ab8c5ee4fc9e430', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 1, + symbol0: 'USDC', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0xaa9be68d990d5e56870b2e0544f96ffb0b1da8f7', + collateralAddress: '0x89fc27dacb92e4f149c32762fbb69e39f8a52ba5', + borrowableAddress0: '0x7c66609513b5189d76c0cd34dc695311ad05873f', + borrowableAddress1: '0xeb4dedb9a9eed1d87e2bb4c0ec31a77af865b20a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xd8d4a4738e285c33a2890fb2e225c692b84c55ca': { + lendingPoolAddress: '0xd8d4a4738e285c33a2890fb2e225c692b84c55ca', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 2, + symbol0: 'ZOO', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 0, + decimals1: 18, + tokenAddress0: '0x09e145a1d53c0045f41aeef25d8ff982ae74dd56', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0x67019e7b4a233cc2e875e5c713042333d879aace', + collateralAddress: '0x84bbff4bf4eb3bab3095eae43d871789054cf884', + borrowableAddress0: '0x602a1fe1dfdc645831952cf29bef8676b80b3349', + borrowableAddress1: '0x826ac6017c7c9003e54c78ad33bb71624a9b6d9b', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe9ee1370f81439e522ffd244e5ee1cc3ad7a7f01': { + lendingPoolAddress: '0xe9ee1370f81439e522ffd244e5ee1cc3ad7a7f01', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 3, + symbol0: 'TOMB', + symbol1: 'TREEB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xc60d7067dfbc6f2caf30523a064f416a5af52963', + uniswapV2PairAddress: '0x801d17c21d0808bc00d46e2f081214c9d82f4fbf', + collateralAddress: '0x5f5d4300bc335b85febcb2968878e5a6b44b1a47', + borrowableAddress0: '0x3867f13f9dd4492bebc32e0dd429eb739b79c6b1', + borrowableAddress1: '0xdc5bfd89b1521556701bbf8c2e50114a3f472238', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x8bc3fa22095fff2461321475031c231ae76c42dc': { + lendingPoolAddress: '0x8bc3fa22095fff2461321475031c231ae76c42dc', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 4, + symbol0: 'BTC', + symbol1: 'TSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 8, + decimals1: 18, + tokenAddress0: '0x321162cd933e2be498cd2267a90534a804051b11', + tokenAddress1: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + uniswapV2PairAddress: '0xa1f4a9ee0d06115376dff357d34c3f5eb4107398', + collateralAddress: '0xe918c1714e5460922742914c6ede1285c28119ba', + borrowableAddress0: '0x6c998cbc0d5d2869883a4c58bc8da39e1f5a19f4', + borrowableAddress1: '0xd5f59774c061fa9d395c58a89951e7d8315c598b', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf85fe698a3368a565149a26bd262690b5c428472': { + lendingPoolAddress: '0xf85fe698a3368a565149a26bd262690b5c428472', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 5, + symbol0: 'TSHARE', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xd702d7495b010936ebc53a1efee42d97996ca5ee', + collateralAddress: '0x90a51e88004524feb89e546b34d787bfe3cb81a8', + borrowableAddress0: '0x0c49e21768f4ad0f7090f8dd24eeb6e0f868ef57', + borrowableAddress1: '0x1bf9556d0a7e0c52f413afd788cad34508ab51f5', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x5e24cb79d406668994397f5b5f5c554f1a347c4a': { + lendingPoolAddress: '0x5e24cb79d406668994397f5b5f5c554f1a347c4a', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 6, + symbol0: 'USDC', + symbol1: 'TSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + uniswapV2PairAddress: '0xdec1259188e6c5273acd1e84d5b4b58897ca013e', + collateralAddress: '0x6330297993b1a36cf16e1c5d5c6842c677640991', + borrowableAddress0: '0x56f8e038e226531b67b1e249555c3e2433493ca1', + borrowableAddress1: '0x0eebdb3f18f6360beb7a98cd6635f1fe33b0f6cb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xd67b9d3a6fc711fb8b7ab4b6d64cb7949d47deb4': { + lendingPoolAddress: '0xd67b9d3a6fc711fb8b7ab4b6d64cb7949d47deb4', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 7, + symbol0: 'USDC', + symbol1: 'fUSDT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 6, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + uniswapV2PairAddress: '0x3486011e2e18ccf4558c4c84d5cbbccfdbf16c03', + collateralAddress: '0xf8090c8a88ead97676ffe5430009db2f0bc4dc5c', + borrowableAddress0: '0xd275cba9cd0d5157734984de340cb8d26822e8ec', + borrowableAddress1: '0x0d5ff347c1d80d1f1a40dfa5a86826fa180e0fcf', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe51bb9fe17b66a7944fda7a6690b4c4694baea57': { + lendingPoolAddress: '0xe51bb9fe17b66a7944fda7a6690b4c4694baea57', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 8, + symbol0: 'USDC', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xd840af68b35469ec3478c9b0cbcddc6dc80dd98c', + collateralAddress: '0x7df381a7eb8aa26d61a0eb45c0fa86e0301b2806', + borrowableAddress0: '0xf67cc1cebd0673b0b4879de19297c4e5cf8e5ff6', + borrowableAddress1: '0x7b2a39c89514ce12c132f5fb3fae0be657b33a9a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x6e18bbc32a0d67955d28ec7113679cfb541e0159': { + lendingPoolAddress: '0x6e18bbc32a0d67955d28ec7113679cfb541e0159', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 9, + symbol0: 'USDC', + symbol1: 'FUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xad84341756bf337f5a0164515b1f6f993d194e1f', + uniswapV2PairAddress: '0x38ff5377a42d0a45c829de45801481869087d22c', + collateralAddress: '0xbe57417861ca29b5d022c1076251e88c82ab800d', + borrowableAddress0: '0x33a4d51a88e3e7f844e87da8c1ead314befa284b', + borrowableAddress1: '0x4e4c8374fd171e6c4280528ee80b1c0c609329f9', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xcfbb62bb8777709966f81f7d58aedd6b8d0747fd': { + lendingPoolAddress: '0xcfbb62bb8777709966f81f7d58aedd6b8d0747fd', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 10, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x8c853ce1561a2c2cd2e857670e3ccd04ba4cb27b', + collateralAddress: '0xfb8a78682fa0714547f1b9fe145bf0a6f415fd24', + borrowableAddress0: '0xd8ca234c9b7c6843070ac477b48e48c8af1d2184', + borrowableAddress1: '0xca9e494a2ad0c15fef58b3cf21e2617d8a5efb31', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x4d3b315994b5fd2bbd93506ea5db8f4b59561e9e': { + lendingPoolAddress: '0x4d3b315994b5fd2bbd93506ea5db8f4b59561e9e', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 11, + symbol0: 'WFTM', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0xb89486a030075b42d589008da7877dd783af968f', + collateralAddress: '0x2210597b655bad7968fa33f43e87ea105f57a051', + borrowableAddress0: '0x968624225ad173d984286393b37c2b93b9e5e54c', + borrowableAddress1: '0xf1b4293b9928ac10dfb1ada86c368121cbf3a27a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xfdcaf82160e4f06a6b011ad3ed4b6e61c653ed4a': { + lendingPoolAddress: '0xfdcaf82160e4f06a6b011ad3ed4b6e61c653ed4a', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 12, + symbol0: 'WFTM', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x8e49c8fbf6128356019d8a7d34e9b92f03bc2803', + collateralAddress: '0xdf6f280d2cb74d7280be82b457223a159d12046b', + borrowableAddress0: '0x270790722be3acdcd392cdc2022700bed6d390f2', + borrowableAddress1: '0xcedd29d2df5e65109be434820319fb140de71b24', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xd78d3cc53ab902a210734bfc11565d7be96230c0': { + lendingPoolAddress: '0xd78d3cc53ab902a210734bfc11565d7be96230c0', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 13, + symbol0: 'fUSDT', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x681d32c8b374c2dd83064775dbb48ea97db2c506', + collateralAddress: '0xee1e2f879b754fb07ac28c4568b7c02bfb98377c', + borrowableAddress0: '0x115cba4efaa7415933b1a9e85d6ba8b649404485', + borrowableAddress1: '0xd63fb7ef6258924004128496fed26097dc214162', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x5f3f4b1f08fcd9f35872b71a71f2170a2ad3b8d6': { + lendingPoolAddress: '0x5f3f4b1f08fcd9f35872b71a71f2170a2ad3b8d6', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 14, + symbol0: 'WFTM', + symbol1: 'BTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x321162cd933e2be498cd2267a90534a804051b11', + uniswapV2PairAddress: '0x5063c79e377332fb98cb6c8db414d752dc7c478e', + collateralAddress: '0xf56a7ea5c422f9a07780a96f47e2d0d354f46503', + borrowableAddress0: '0x7fa3dac37374acc101aaee0468b8e14ad183e02b', + borrowableAddress1: '0xf01b8da1a6110a399370e767b55bb6548489664a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xfd5c2ac90b12b9014b9a6c826687689384842593': { + lendingPoolAddress: '0xfd5c2ac90b12b9014b9a6c826687689384842593', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 15, + symbol0: 'WFTM', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0xa7c86fc1b87830b8abfa623571405e03560a8326', + collateralAddress: '0xfd1267c004b65ba58e5c440abcf4c079bdd9effd', + borrowableAddress0: '0xe364547482e0a3eaff1164f636ba6835fcc9cdc4', + borrowableAddress1: '0x5b8a3de3031aa0d0441bdc88ad2bee9713f4e979', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xc155a158cd66c030d87007870bf144ec05d3ffb9': { + lendingPoolAddress: '0xc155a158cd66c030d87007870bf144ec05d3ffb9', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 16, + symbol0: 'WFTM', + symbol1: 'BNB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454', + uniswapV2PairAddress: '0xb5f1b98693c4894880dd90c1d3e7a517b9c16ae3', + collateralAddress: '0x89026c5f1d104a126e6501cdea364f9f61615da6', + borrowableAddress0: '0x96903b187d60675d5738f1471f06efed1d16cad5', + borrowableAddress1: '0x7cca03b86b125b63fc7ca0029ea271e66419d78c', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xfd97ad406bc7743d10a745ffcde11b1242a38f7d': { + lendingPoolAddress: '0xfd97ad406bc7743d10a745ffcde11b1242a38f7d', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 17, + symbol0: 'WFTM', + symbol1: 'AVAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x511d35c52a3c244e7b8bd92c0c297755fbd89212', + uniswapV2PairAddress: '0xc753d5aa76f90b7057cc2b6766fe67faf68bf6e3', + collateralAddress: '0xe2e9696222e12484638819c6195d1f0351e9c42e', + borrowableAddress0: '0xdef4f5cf53b18a18265380279ec274e306fce1cd', + borrowableAddress1: '0xd227e55848a9f24c0fa1d8f8d6996a98d0989087', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe5d699f95d6a2e3e7129f2e03a5faf5f35cb34da': { + lendingPoolAddress: '0xe5d699f95d6a2e3e7129f2e03a5faf5f35cb34da', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 18, + symbol0: 'WFTM', + symbol1: 'LINK', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8', + uniswapV2PairAddress: '0x51e1b9b1ec411a2258f674c26a0a0ac78cd81478', + collateralAddress: '0x833930c08fc627550a5490f91fd81628887494ad', + borrowableAddress0: '0xf560f93ef320134bb5a532fdbee61ece0f41ab1f', + borrowableAddress1: '0x0c3fe1c8de98cc3d683efa7547b54e9fa8475e6f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf727e8d6512c1bf9b0553f114158da913f9bdcfd': { + lendingPoolAddress: '0xf727e8d6512c1bf9b0553f114158da913f9bdcfd', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 19, + symbol0: 'CRV', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xff17e19feeaf403e8ed9d79a5b78b8f4ded38df3', + collateralAddress: '0x62a5042c439bde8983581ead0103b4f493f16bda', + borrowableAddress0: '0xec93a592fe0b216626a7c3fe1d146b9894031455', + borrowableAddress1: '0xb77327d9b81b576735b507821b5aa7d2245986ec', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x1f2bff0e37c592c7de6393c9dd3c0f7933408228': { + lendingPoolAddress: '0x1f2bff0e37c592c7de6393c9dd3c0f7933408228', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 20, + symbol0: 'BTC', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 8, + decimals1: 18, + tokenAddress0: '0x321162cd933e2be498cd2267a90534a804051b11', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x3f468804d133894a73b54cfc07d5886e5195255f', + collateralAddress: '0xfd0bd84efe63dcf7aeabd1f9f644536fdb269137', + borrowableAddress0: '0x9b2e19859bbbb0e916ab25da1eb9d86a9ba6ae0f', + borrowableAddress1: '0x29e43ac0d45aff4fa1ab15af9f77d429e5a45f08', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x16904332af97a2e28ce2284e4c0c5078049b958c': { + lendingPoolAddress: '0x16904332af97a2e28ce2284e4c0c5078049b958c', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 21, + symbol0: 'TOMB', + symbol1: 'LIF3', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xbf60e7414ef09026733c1e7de72e7393888c64da', + uniswapV2PairAddress: '0xcc3d9921302dbbc72171eed1b10fd45f9e83ad8c', + collateralAddress: '0x36ac0effea7fda41ec7280dbb35663131bb7ac99', + borrowableAddress0: '0xa171da288495da742df32b6164d95a9835ceeba9', + borrowableAddress1: '0x0fc5188f44f53ee902f5ef49789d28c3bf9fb00d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xd916ab627631ba859029eaaaf2729af987a011f4': { + lendingPoolAddress: '0xd916ab627631ba859029eaaaf2729af987a011f4', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 22, + symbol0: 'TSHARE', + symbol1: 'LSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4cdf39285d7ca8eb3f090fda0c069ba5f4145b37', + tokenAddress1: '0xcbe0ca46399af916784cadf5bcc3aed2052d6c45', + uniswapV2PairAddress: '0x9fc1cfb778864d319ebe35afd475f869ed8e34a9', + collateralAddress: '0xde30fa651c3511963c51d779e79b89d765ecdc93', + borrowableAddress0: '0x5da4525595249558458dfe8e1070bec943afd742', + borrowableAddress1: '0x3988735cc7f8e21a3bdeebaa85218bd4fbbb677e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x6d1bec43f50eacf00bd81335a4e61f67f09d95c1': { + lendingPoolAddress: '0x6d1bec43f50eacf00bd81335a4e61f67f09d95c1', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 23, + symbol0: 'USDC', + symbol1: 'LIF3', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xbf60e7414ef09026733c1e7de72e7393888c64da', + uniswapV2PairAddress: '0x502eeeb06c2e01fd151cfc6624f0b98420bd1291', + collateralAddress: '0x312189368d8db0edc74ee9237b09fdd0e7695ce7', + borrowableAddress0: '0x171bf5558f83d1a96ca3513f5676f41b8d9cd08c', + borrowableAddress1: '0xec2f3ed6b87fe58b35938a06f2e4269b33a697e6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xa811752e01b691f4de336f6db49ddc7232b9527f': { + lendingPoolAddress: '0xa811752e01b691f4de336f6db49ddc7232b9527f', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 24, + symbol0: 'USDC', + symbol1: 'LSHARE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xcbe0ca46399af916784cadf5bcc3aed2052d6c45', + uniswapV2PairAddress: '0x0621d9c22fad25bf5b88735defb419fa60f118f7', + collateralAddress: '0xf2d1fb89c7fb964f46efc3d8f97e3584098a3e51', + borrowableAddress0: '0x4a7fe4da206df8be0419098cefa0e011db3d1741', + borrowableAddress1: '0xaa566d6fd0a2d7b45fecf543d24d4cf91dbc9c16', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x0a1fd2286f38bb75950fa90fb9b56c824648f7d6': { + lendingPoolAddress: '0x0a1fd2286f38bb75950fa90fb9b56c824648f7d6', + isTarotVault: true, + dex: DEX.TOMB, + vaultType: VaultType.LIF3, + pid: 25, + symbol0: 'WFTM', + symbol1: 'LIF3', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xbf60e7414ef09026733c1e7de72e7393888c64da', + uniswapV2PairAddress: '0xd62cacdb69000fed31bb348e9c0e073bb8ad7caf', + collateralAddress: '0x3a03b9ce0a4d2ffef33e77f9fd30150b3050ff06', + borrowableAddress0: '0x0be3fcfd8b1a5e878daf0d07784725b3cfab9883', + borrowableAddress1: '0x0eea78976675dd05c56744847f289b08f730de16', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x1af3c714928fe9cb8e997d59dfa2594fe4cf4ddc': { + lendingPoolAddress: '0x1af3c714928fe9cb8e997d59dfa2594fe4cf4ddc', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 0, + symbol0: 'WFTM', + symbol1: 'BOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + uniswapV2PairAddress: '0xec7178f4c41f346b2721907f5cf7628e388a7a58', + collateralAddress: '0x274de5dd8824009006410ab034e157d349d908d5', + borrowableAddress0: '0x3d216d1086deadd6bf361f270584711859a64102', + borrowableAddress1: '0x8d5fe826e222df813e68f0aa4626f3e5d5b1e007', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x939dff08be101d86d91048c7f56ccbc713ea5a95': { + lendingPoolAddress: '0x939dff08be101d86d91048c7f56ccbc713ea5a95', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 9, + symbol0: 'fUSDT', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x5965e53aa80a0bcf1cd6dbdd72e6a9b2aa047410', + collateralAddress: '0xea8f4d3aa4c7d0b4b8c4dae27a724440f3b48914', + borrowableAddress0: '0x01b61b3d1fdfb46d6093d8c102bc424cb4befd8d', + borrowableAddress1: '0x06e37d44d85f72fcab3fe743a129c704d21bad6f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x01a621fe05fe5aab97c3a9841383230a96d8392b': { + lendingPoolAddress: '0x01a621fe05fe5aab97c3a9841383230a96d8392b', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 10, + symbol0: 'USDC', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x2b4c76d0dc16be1c31d4c1dc53bf9b45987fc75c', + collateralAddress: '0xc7c091ad588afde099f17e0e225585f289ff51a2', + borrowableAddress0: '0xee234eb2919a1dc4b597de618240ec0c14ef11ce', + borrowableAddress1: '0xed0e1b57eebdf538434b521e47fb3df0a94f2343', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xfee40d4f2c8526ae02b654b7f348fb82aa9531c4': { + lendingPoolAddress: '0xfee40d4f2c8526ae02b654b7f348fb82aa9531c4', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 11, + symbol0: 'WFTM', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + uniswapV2PairAddress: '0xe120ffbda0d14f3bb6d6053e90e63c572a66a428', + collateralAddress: '0x0f3b7b10ec9263fe389d732b52efe9f4442eed5a', + borrowableAddress0: '0x3221c43a4e354cece2fc8e0fdda2a663e052022d', + borrowableAddress1: '0xd24772601db6d3387a404e41468f839d1485c2ea', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x0fc03567c78b43211fff2c17f792c8b2f41811a2': { + lendingPoolAddress: '0x0fc03567c78b43211fff2c17f792c8b2f41811a2', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 12, + symbol0: 'WFTM', + symbol1: 'BTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x321162cd933e2be498cd2267a90534a804051b11', + uniswapV2PairAddress: '0xfdb9ab8b9513ad9e419cf19530fee49d412c3ee3', + collateralAddress: '0x07bfb45a86d202a77d6e60a82b343164d9beb5b0', + borrowableAddress0: '0x5eae455dd945a743f6c17faef55126eebf4b0308', + borrowableAddress1: '0x7c934bb5363a4a160ac4bd8fdb260f6070527c96', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x82a4ef6d28f390e3eb0348d18d1bd71927c185e0': { + lendingPoolAddress: '0x82a4ef6d28f390e3eb0348d18d1bd71927c185e0', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 13, + symbol0: 'WFTM', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xf0702249f4d3a25cd3ded7859a165693685ab577', + collateralAddress: '0x4b0d1ce6159b1e36498ffe89424ec5933268fd64', + borrowableAddress0: '0xf5b6992019cdb92b8cdcb5a17022e852e4cdec02', + borrowableAddress1: '0x0fb2ff53721418f668f93fcaadb3b73d699e41df', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x49d5df1766120daace799f4aa384c52909131d30': { + lendingPoolAddress: '0x49d5df1766120daace799f4aa384c52909131d30', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 14, + symbol0: 'WFTM', + symbol1: 'LINK', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8', + uniswapV2PairAddress: '0x89d9bc2f2d091cfbfc31e333d6dc555ddbc2fd29', + collateralAddress: '0x3d1cc4f52696da9d65a15edb5ff161f4c3eb6eff', + borrowableAddress0: '0x555ed3c399d0ca6e05028e601e37456cdce9a29b', + borrowableAddress1: '0x301ebf81ca3f77bc29e705fc889f4ead2de5f43e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xacfea2a2441bc9d8087c958028d97be588bf3c33': { + lendingPoolAddress: '0xacfea2a2441bc9d8087c958028d97be588bf3c33', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 15, + symbol0: 'WFTM', + symbol1: 'SUSHI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc', + uniswapV2PairAddress: '0xf84e313b36e86315af7a06ff26c8b20e9eb443c3', + collateralAddress: '0x4eca3ca3f0d00adfd1f51de8fdc0c091b2f64e34', + borrowableAddress0: '0x307ea46e4e6cf7b3bd94be61c46ef7c517ef6201', + borrowableAddress1: '0x36e8830e8480e4efb277d769e6290ab17df167aa', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xddb870e27469e842e18182101bd1c59e746ec9b4': { + lendingPoolAddress: '0xddb870e27469e842e18182101bd1c59e746ec9b4', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 16, + symbol0: 'CRV', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0xb471ac6ef617e952b84c6a9ff5de65a9da96c93b', + collateralAddress: '0x2e2c1d6507d722c7fedb7ef4d5514069beb741b2', + borrowableAddress0: '0x7f0f0361e5c2b062793f525efb407451edaed850', + borrowableAddress1: '0xaa00256c599b23b1f7d5b3a132200cd329075f56', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x0f4998fe47ad783329714612b083681f4901f339': { + lendingPoolAddress: '0x0f4998fe47ad783329714612b083681f4901f339', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 17, + symbol0: 'WFTM', + symbol1: 'BNB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454', + uniswapV2PairAddress: '0x956de13ea0fa5b577e4097be837bf4ac80005820', + collateralAddress: '0xc11d3f68b89ce53deafefbc8a5d77683546ad220', + borrowableAddress0: '0x9b02d0d6643646ef13416530e2f67f32d9c26080', + borrowableAddress1: '0x1a563a2f35b67e95cdd57e3ad1d783b750703d23', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x0fd2947895fcd9fd4fe5c66d255998c2d7e56ce6': { + lendingPoolAddress: '0x0fd2947895fcd9fd4fe5c66d255998c2d7e56ce6', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 18, + symbol0: 'WFTM', + symbol1: 'BIFI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd6070ae98b8069de6b494332d1a1a81b6179d960', + uniswapV2PairAddress: '0x1656728af3a14e1319f030dc147fabf6f627059e', + collateralAddress: '0xb9e70e8524a6df697b9dd93d644a9d3b8e0f149b', + borrowableAddress0: '0x1bcfb40f6c8372d3526c2f2b36081332c9c659ce', + borrowableAddress1: '0xd7da80ee161b1c04fffb401b7318de1347c305eb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x1616e02f66ddd35e6cf4c7818e452227215b37fe': { + lendingPoolAddress: '0x1616e02f66ddd35e6cf4c7818e452227215b37fe', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 19, + symbol0: 'WFTM', + symbol1: 'MIM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x82f0b8b456c1a451378467398982d4834b6829c1', + uniswapV2PairAddress: '0x6f86e65b255c9111109d2d2325ca2dfc82456efc', + collateralAddress: '0xdb7eb67c4d1ff380bc677abdb207e692f6f7c3bb', + borrowableAddress0: '0x416b8d5a3dd8bb1426dbe6f86317e22951a6d124', + borrowableAddress1: '0xdeb93bbac39b84df99cd4ed6051f99e1683e6c21', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe786dc3efa7f4338dcf20331f64f41763ce3d735': { + lendingPoolAddress: '0xe786dc3efa7f4338dcf20331f64f41763ce3d735', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 21, + symbol0: 'YFI', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0x0845c0bfe75691b1e21b24351aac581a7fb6b7df', + collateralAddress: '0x274534ad3aa3b3fdce328cec520a2084f18f7212', + borrowableAddress0: '0x5d8960078d745e2987a5a02078a4028489b5b4a6', + borrowableAddress1: '0xe8685152922edea8f6dbfcc7886f13b09e0b9dd8', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x1d1b8da1826cc7624b91c4c616ecd3fd1ca04b71': { + lendingPoolAddress: '0x1d1b8da1826cc7624b91c4c616ecd3fd1ca04b71', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 22, + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x11d90ea9d16e1ee5879b299a819f6d618816d70f', + collateralAddress: '0xd206277d475bc882c6a7496525739ab5fefc2b89', + borrowableAddress0: '0xffb9260808e327432350fc9c06d639f7ee9c90f6', + borrowableAddress1: '0x1f8b52ed3cd22f5e4275aaf68301566bb6739f22', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x3a1a62b2736ebb210f0c7574d227352087b19791': { + lendingPoolAddress: '0x3a1a62b2736ebb210f0c7574d227352087b19791', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 23, + symbol0: 'WFTM', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0x30872e4fc4edbfd7a352bfc2463eb4fae9c09086', + collateralAddress: '0x39760abfb8d1e8b441d9ca822b76eebc2ffaf9c5', + borrowableAddress0: '0x23691ab8c86370926748f5f405838749514fbaf2', + borrowableAddress1: '0x629a6e543749c49ff09de99ee2a087f4560cae8f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xdcc2de17d86b66a39f1da54e7a6afe1053cafc52': { + lendingPoolAddress: '0xdcc2de17d86b66a39f1da54e7a6afe1053cafc52', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 25, + symbol0: 'BTC', + symbol1: 'ETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 8, + decimals1: 18, + tokenAddress0: '0x321162cd933e2be498cd2267a90534a804051b11', + tokenAddress1: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + uniswapV2PairAddress: '0xec454eda10accdd66209c57af8c12924556f3abd', + collateralAddress: '0x3421c585b8b1b7e92f214ae516d1c1237201d912', + borrowableAddress0: '0xe9d7575f900592cef8a6583196763953d9bed9f2', + borrowableAddress1: '0x5b09669c26301033be4d418aefe753d085a4c8b1', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xb0fc78e37ced369ed57a07677f80e6dd35084f3a': { + lendingPoolAddress: '0xb0fc78e37ced369ed57a07677f80e6dd35084f3a', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 26, + symbol0: 'LQDR', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x506ddcc751c7d500f983ffda6ddefbe458ba2c33', + collateralAddress: '0x90403c69d8a4b81152d4a3c816cfa7731805c4b7', + borrowableAddress0: '0xe10210cf9da2fd2ba5ac91ca25895bdace011500', + borrowableAddress1: '0x0fa8f0c3bc60251a6cca65d610e19b29d445c6d3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xabd5c48b5342c47d78625006f67d70d911f8601d': { + lendingPoolAddress: '0xabd5c48b5342c47d78625006f67d70d911f8601d', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 27, + symbol0: 'WFTM', + symbol1: 'SPELL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x468003b688943977e6130f4f68f23aad939a1040', + uniswapV2PairAddress: '0x78f82c16992932efdd18d93f889141ccf326dbc2', + collateralAddress: '0x893d356b79047b9fa8a95a839f13c7417ec35242', + borrowableAddress0: '0x1e979bb99f37a3533b12093038977092ac527a62', + borrowableAddress1: '0xf4ef1814044286dfb84af8654cdf149c3d864fc3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x66e14d95f9f16557fdd44891306114a3e23fd5a1': { + lendingPoolAddress: '0x66e14d95f9f16557fdd44891306114a3e23fd5a1', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 28, + symbol0: 'USDC', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x4de9f0ed95de2461b6db1660f908348c42893b1a', + collateralAddress: '0x9df0c9a8912ff769f579d3b75a9d92d27e015211', + borrowableAddress0: '0xc2b71db3e843dbe0615bc8fcefc8b28d34f265c6', + borrowableAddress1: '0xb320fa815a18bf186c8894930aa787b381f30b8a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xf11d495bbaea1e37bc2220604d83fc9a7ca38de9': { + lendingPoolAddress: '0xf11d495bbaea1e37bc2220604d83fc9a7ca38de9', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 29, + symbol0: 'USDC', + symbol1: 'TUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x9879abdea01a879644185341f7af7d8343556b7a', + uniswapV2PairAddress: '0x12692b3bf8dd9aa1d2e721d1a79efd0c244d7d96', + collateralAddress: '0x14431c8b513128188a43e2726502fcb6f683219b', + borrowableAddress0: '0xadf5c4115fba294d208dc708c1dd20025d07ea9e', + borrowableAddress1: '0xe5e9253c867ac7bb2e54bb57eb55e150bc3fff60', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x3a1e79415cd46f2a508c8dc160d68d7f9009e1d2': { + lendingPoolAddress: '0x3a1e79415cd46f2a508c8dc160d68d7f9009e1d2', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 32, + symbol0: 'WFTM', + symbol1: 'AVAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x511d35c52a3c244e7b8bd92c0c297755fbd89212', + uniswapV2PairAddress: '0x5df809e410d9cc577f0d01b4e623c567c7ad56c1', + collateralAddress: '0xd9d4c6c9cf0c78eeee45a88607a12587651040e1', + borrowableAddress0: '0x807d781a1f2fe3ed67ec2edd5d945e1666282ff2', + borrowableAddress1: '0x0bee491043289eff7bb65ad529fc64e5aa5fcaac', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x17ff855bf4f301f502298f30720b6604b861d27e': { + lendingPoolAddress: '0x17ff855bf4f301f502298f30720b6604b861d27e', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 34, + symbol0: 'WFTM', + symbol1: 'MATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x40df1ae6074c35047bff66675488aa2f9f6384f3', + uniswapV2PairAddress: '0x7051c6f0c1f1437498505521a3bd949654923fe1', + collateralAddress: '0x65c97e95042608865aacb57b70dcbac7a8ef9fb7', + borrowableAddress0: '0xdaf86a099ff129857dff818ffb07aa65512a83ce', + borrowableAddress1: '0xae7f25fcca11564b0016e1f7787259294b4e18ba', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x847e8f3b438540acb8146c12bd84a97efff4fd2d': { + lendingPoolAddress: '0x847e8f3b438540acb8146c12bd84a97efff4fd2d', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 35, + symbol0: 'WFTM', + symbol1: 'BRUSH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x85dec8c4b2680793661bca91a8f129607571863d', + uniswapV2PairAddress: '0x4ee115137ac73a3e5f99598564905465c101b11f', + collateralAddress: '0x5a8377eba9b964659fa0b1d8946e52a48e3e1bf3', + borrowableAddress0: '0x0a9617cf6d3debcf65633eebca25bcac5daad9c4', + borrowableAddress1: '0x66fafe368d8f5b3e7eb2d56602a282c0660acf1f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe4b58eda17f7261c6e2bf8bee87f68a18eff5739': { + lendingPoolAddress: '0xe4b58eda17f7261c6e2bf8bee87f68a18eff5739', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 36, + symbol0: 'WFTM', + symbol1: 'BEETS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e', + uniswapV2PairAddress: '0x648a7452da25b4fb4bdb79badf374a8f8a5ea2b5', + collateralAddress: '0xdf741d5ff44a3e354fbc30547c2719c10ec9c4b0', + borrowableAddress0: '0x1b0ba9f68ceaf9455206e4ea6066eb6333bf7d5a', + borrowableAddress1: '0xe3f201d4676d1aec0baa8c70f8f07f14b73b3aec', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x7ab024addf7095cca03172e1df16dfacafbb88bc': { + lendingPoolAddress: '0x7ab024addf7095cca03172e1df16dfacafbb88bc', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 37, + symbol0: 'WFTM', + symbol1: 'MULTI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + uniswapV2PairAddress: '0x297c8990134bf1ee08ae5d8805042fbac8781201', + collateralAddress: '0x98db9e233c77782ca029d413efa3d0559bcb07c9', + borrowableAddress0: '0x9242169d580e09f41b8d37bc344d6bdcfe9f2ced', + borrowableAddress1: '0x5c3947689acc68c3ab5c9b80f8ec43e24c724ef6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xe95b744444d019dfee6a98969b82b061a574194a': { + lendingPoolAddress: '0xe95b744444d019dfee6a98969b82b061a574194a', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 39, + symbol0: 'USDC', + symbol1: 'BOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + uniswapV2PairAddress: '0xf8cb2980120469d79958151daa45eb937c6e1ed6', + collateralAddress: '0x5b136e32867bb564c608daa7c21ef92b2ec45edb', + borrowableAddress0: '0x9f2f80ea74f44c923910781d858eccbcc3a14e5d', + borrowableAddress1: '0x4f533dc378e3d5dc769bd1f7c0a1e55c771dd7f0', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xb6b8c26915c7f812edf82fcd68db4a7d0f8e4986': { + lendingPoolAddress: '0xb6b8c26915c7f812edf82fcd68db4a7d0f8e4986', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 40, + symbol0: 'WFTM', + symbol1: 'APE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x2d72a97a31dc920db03330780d30074626e39c8a', + uniswapV2PairAddress: '0xc9fb686f14bda7e2653cf8f605dc8551b6a53fd3', + collateralAddress: '0xaf94d802195996a80af2307ad7b9fd7fd0cfac80', + borrowableAddress0: '0x6e1091bc2eca3236eb79c9d21061e9e319f1c759', + borrowableAddress1: '0xe43767e6ac0f91e7d4497f7e2d07e08f50ecbf88', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xa3f6fa09aa7f959e7a917d0677a7be9ae7446c09': { + lendingPoolAddress: '0xa3f6fa09aa7f959e7a917d0677a7be9ae7446c09', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 41, + symbol0: 'WFTM', + symbol1: 'beFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '800000000000000000', + kinkUtilizationRate1: '800000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1224744870000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x7381ed41f6de418dde5e84b55590422a57917886', + uniswapV2PairAddress: '0xb5512e3fa8304d33cdae4a40c21f1d3f70eba45a', + collateralAddress: '0xbcffa579ba5d2301fbfd54fe9d78c1046c3cf7e5', + borrowableAddress0: '0x43ea7c17f3232a3308fb5675433c8355a3595f20', + borrowableAddress1: '0xb0a87f3368a448cf61ff7f1dc370792428bdddd5', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0xec51a9f0dc97563147fb89176047283b9ae4cca9': { + lendingPoolAddress: '0xec51a9f0dc97563147fb89176047283b9ae4cca9', + isTarotVault: true, + dex: DEX.SPOOKY, + vaultType: VaultType.SPOOKY_V2, + pid: 42, + symbol0: 'USDC', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x35a60b8c750b4d834a27443f35269a84d06de391', + collateralAddress: '0xf454df5ff5b89b9d469bed1b0584d926ef5d5ef9', + borrowableAddress0: '0x6ed9d143a5a2d87796441915410a6617b02d7935', + borrowableAddress1: '0x61e8ee0bde02cad88010e3a2d4e7821d60d39bc7', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xf6d943c8904195d0f69ba03d97c0baf5bbdcd01b', + tarotRouterAddress: '0x3f7e61c5dd29f9380b270551e438b65c29183a7c', + }, + '0x6f694a3dc87a739e0fd84620eb2bebe2fca5af7d': { + lendingPoolAddress: '0x6f694a3dc87a739e0fd84620eb2bebe2fca5af7d', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x04f12d5eb29edc7241de831e582c3b7814844fcb', + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x783f1edbe336981dfcb74bd0b803655f55aadf48', + collateralAddress: '0xb49e1ca89f4619051cc67aad23e41bacd11f11c2', + borrowableAddress0: '0x86637914fcf928c665eb61cdd500bafec35e5bd6', + borrowableAddress1: '0x3e8e748ad4b302e4f9d2d207ac268f21f2663a6d', + farmingPoolAddress0: '0xd4119e06214b9d38598c45b9ae16a905631a1939', + farmingPoolAddress1: '0xb193b09493f89454ee7677d2961f442bcdf845a4', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xb54cda66e287ff85e2de2433154969a1afcc7208': { + lendingPoolAddress: '0xb54cda66e287ff85e2de2433154969a1afcc7208', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x1d1a1871d1830d4b5087212c820e5f1252379c2c', + symbol0: 'WFTM', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0x60a861cd30778678e3d613db96139440bd333143', + collateralAddress: '0x544f13effc5d23180e8c7d9831f67ec7a8421abc', + borrowableAddress0: '0x70dd33ad26ea769dc65a96425741c667c2bce123', + borrowableAddress1: '0x474e8204fb41dbfa18a7c96edec725a358ffc438', + farmingPoolAddress0: '0xc900dc5ad63751b913ac70c305782aa99380c37a', + farmingPoolAddress1: '0xc4016771f87dd6de4f0a6dd64cf6646740aa1075', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xf1234dbdce04c8f26e53e33d53010862dd775d28': { + lendingPoolAddress: '0xf1234dbdce04c8f26e53e33d53010862dd775d28', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xa0813bccc899589b4e7d9ac42193136d0313f4eb', + symbol0: 'xTAROT', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x74d1d2a851e339b8cb953716445be7e8abdf92f4', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x4fe782133af0f7604b9b89bf95893adde265fefd', + collateralAddress: '0xb98b00ed7c4f68c0d6218298748b78296b03945f', + borrowableAddress0: '0x0a25c2f5b958a92a96fbb57b2f3bdc45cd2fe464', + borrowableAddress1: '0x272263ecafbbf852910efe1043b9c8cf3c9f7fea', + farmingPoolAddress0: '0x13bbbd25b7a7a8ff19a23a834c10be30b500bf02', + farmingPoolAddress1: '0xe6345830b5ec891e9d82896b47bc67b19332a770', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x3469099c7fc07be112f6c9e7516beac1266a4871': { + lendingPoolAddress: '0x3469099c7fc07be112f6c9e7516beac1266a4871', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xa0ce41c44c2108947e7a5291fe3181042affdae7', + symbol0: 'USDC', + symbol1: 'WeVE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x911da02c1232a3c3e1418b834a311921143b04d7', + uniswapV2PairAddress: '0xd9a4108cbb40a12de16dffdc54ae5065878816d7', + collateralAddress: '0xf598d1ab0cd1ecbd77ae3601341537be7864497a', + borrowableAddress0: '0x5341cdea1f6783d1aec016d86a79f30874b509c0', + borrowableAddress1: '0x622156a1829ce0cf0c7736d29e9c92dd8046f5d9', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x38c52f8bc14331bfde62ea3cfc35cde71f7cb3d7': { + lendingPoolAddress: '0x38c52f8bc14331bfde62ea3cfc35cde71f7cb3d7', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x8e81ec0d9c184e73746446dfb83f86c1156744d5', + symbol0: 'USDC', + symbol1: 'OXD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xc165d941481e68696f43ee6e99bfb2b23e0e3114', + uniswapV2PairAddress: '0xeafb5ae6eea34954ee5e5a27b068b8705ce926a6', + collateralAddress: '0x199a0be8096c523a5e329818a099a546eecfe1ab', + borrowableAddress0: '0x9fa828c5f9b09a8ccbc2608578c2d3947ecc6a22', + borrowableAddress1: '0xe54fe59d4ad6122d21e41bc1b69253c3e349382b', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xafc4d6c798c5bfe7acb987ca546dc1f1b8aa3aab': { + lendingPoolAddress: '0xafc4d6c798c5bfe7acb987ca546dc1f1b8aa3aab', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x51b6b39816cbe47a74ec3154208f86199f9225a4', + symbol0: 'OATH', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21ada0d2ac28c3a5fa3cd2ee30882da8812279b6', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x6b987e02ca5eae26d8b2bcac724d4e03b3b0c295', + collateralAddress: '0x18b972b6a4f2ab3fcdb7a2ae5703c533c8c49759', + borrowableAddress0: '0xef6f72d4f053c2d6af6bbd92f2247f3864b33389', + borrowableAddress1: '0x0afdcfa51e42dbc84d679e9dc5678a40afc665a6', + farmingPoolAddress0: '0x3093f7042f10b0c241e1d0abc4f1c6052e9a6cea', + farmingPoolAddress1: '0xf6fe5762b34af0a3590e8a8ad3a7d3678b2347ad', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x25e37b2f78c78ba9123f5c48578706bf0d8329ad': { + lendingPoolAddress: '0x25e37b2f78c78ba9123f5c48578706bf0d8329ad', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x5990734584bf21c76cbc721858843e9574c8446f', + symbol0: 'WFTM', + symbol1: 'SOLID', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x888ef71766ca594ded1f0fa3ae64ed2941740a20', + uniswapV2PairAddress: '0xe4bc39fdd4618a76f6472079c329bdfa820afa75', + collateralAddress: '0x79adbb6b4c028ef8b9be11fe4e5fd9a4556063dc', + borrowableAddress0: '0x90f38a3f144912726e09f5be7d30d094c49a8850', + borrowableAddress1: '0xc0155d822a89d9029cd577f566c374be97019af6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xcacf5b0958fb5e989646a64081c9f56bdabd0ce3': { + lendingPoolAddress: '0xcacf5b0958fb5e989646a64081c9f56bdabd0ce3', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x3cbd867cf1d37d9b5c3cedf28b8a41d71f6807d6', + symbol0: 'WFTM', + symbol1: 'SEX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd31fcd1f7ba190dbc75354046f6024a9b86014d7', + uniswapV2PairAddress: '0xfcec86af8774d69e2e4412b8de3f4abf1f671ecc', + collateralAddress: '0x6cc6ffabade9139ae73411e8ee81ff326bac72c1', + borrowableAddress0: '0x28be2d9cc5b8a1b0a21c4fcd1941ff7cc882c797', + borrowableAddress1: '0xf77238fc06af35a72be8c0be006c9301fe4d8332', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x19560566d9db6fd6925e1ea0defbd857985e8d1e': { + lendingPoolAddress: '0x19560566d9db6fd6925e1ea0defbd857985e8d1e', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x8015c2ca86f9833486f31782f43d7a8991c4c895', + symbol0: 'WFTM', + symbol1: 'SOLIDsex', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x41adac6c1ff52c5e27568f27998d747f7b69795b', + uniswapV2PairAddress: '0xa66901d1965f5410deeb4d0bb43f7c1b628cb20b', + collateralAddress: '0x66339a6a884056e1fea887dda7ecb23596117c82', + borrowableAddress0: '0xe3f9df9479085eb8b4835dfd2ccd391898c817b7', + borrowableAddress1: '0x4ffec8f8d4c40fb25efbaef48e1ca62ef4d5527c', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x30b39cc2067d204d975f7ef34014d04c3aa8370e': { + lendingPoolAddress: '0x30b39cc2067d204d975f7ef34014d04c3aa8370e', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x1d1a1871d1830d4b5087212c820e5f1252379c2c', + oxUserProxyAddress: '0xb94dbdbd456579c8fb617661b2eacbd40ef49e6c', + oxStakingAddress: '0x69a693329ac7a2c416b18fed8fe85f276a3da82d', + symbol0: 'WFTM', + symbol1: 'TOMB', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + uniswapV2PairAddress: '0x60a861cd30778678e3d613db96139440bd333143', + collateralAddress: '0x73b24f01ce92546b00555192332c67a5bf50e3ad', + borrowableAddress0: '0xdffb193d3242ea5f6d23261e61823b240f44e1a1', + borrowableAddress1: '0x2343258a2781ca9494256178e251919b162d1de0', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x969a0057a06e36e3d4d2603c6d4e938ca79de36e': { + lendingPoolAddress: '0x969a0057a06e36e3d4d2603c6d4e938ca79de36e', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xa0ce41c44c2108947e7a5291fe3181042affdae7', + oxUserProxyAddress: '0x1c9a0d3b2f4c7e83806b660750f6a88b90f09553', + oxStakingAddress: '0x234f69918f43b30ef2adf5f743cd729e40e14ecd', + symbol0: 'USDC', + symbol1: 'WeVE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0x911da02c1232a3c3e1418b834a311921143b04d7', + uniswapV2PairAddress: '0xd9a4108cbb40a12de16dffdc54ae5065878816d7', + collateralAddress: '0x97a8a8cec00409d97d3cdd1129a1d9bb36fb2837', + borrowableAddress0: '0x78e44df86327e79cb431e7e8bf17e0601e3f3ad1', + borrowableAddress1: '0xc1eb875e33fa3a846beafb3c5d0492d67683db2d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x0d1562f1041062b47929be6768fd0af08a816ca0': { + lendingPoolAddress: '0x0d1562f1041062b47929be6768fd0af08a816ca0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x8e81ec0d9c184e73746446dfb83f86c1156744d5', + oxUserProxyAddress: '0x958af968e10a345fb8d00fe47bcb6f7a5e2d8483', + oxStakingAddress: '0xf09d4a95ce6ece4b01d7ed9e585db3721ba44052', + symbol0: 'USDC', + symbol1: 'OXD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xc165d941481e68696f43ee6e99bfb2b23e0e3114', + uniswapV2PairAddress: '0xeafb5ae6eea34954ee5e5a27b068b8705ce926a6', + collateralAddress: '0x5604e6050c94593db93441ed190c037b2d3846f5', + borrowableAddress0: '0x74891bf20912f056a97e418b83f6a46bf751b45c', + borrowableAddress1: '0xe4f323d1fd118245f49fa2182b6fecd3fba872e4', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xd6b9ffe84a1aac669d55b12f983f78028445c7aa': { + lendingPoolAddress: '0xd6b9ffe84a1aac669d55b12f983f78028445c7aa', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x51b6b39816cbe47a74ec3154208f86199f9225a4', + oxUserProxyAddress: '0xd0d202199897bea721754bec5df8cd994eda735d', + oxStakingAddress: '0x7ab6f7848658363a2d771ae67e5bf31cf4c55655', + symbol0: 'OATH', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21ada0d2ac28c3a5fa3cd2ee30882da8812279b6', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x6b987e02ca5eae26d8b2bcac724d4e03b3b0c295', + collateralAddress: '0x11ba6291af2a90d72eb50b07dd1ee8e19d0c0d2f', + borrowableAddress0: '0x6a38ee4f5f07ffd21ce6deb5e82167c41dca0166', + borrowableAddress1: '0xb8b2f156368b09b3c5cdce1057e20deb75a4778d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x7bc34e4aae7842637b4815f90bd50ce32cfaa58a': { + lendingPoolAddress: '0x7bc34e4aae7842637b4815f90bd50ce32cfaa58a', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x04f12d5eb29edc7241de831e582c3b7814844fcb', + oxUserProxyAddress: '0x25eaa5f2b6ce371fc50f03f0a0b3cf55b3e33883', + oxStakingAddress: '0x7b44fec85895b138255e7490c62c323e458386fb', + symbol0: 'WFTM', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x783f1edbe336981dfcb74bd0b803655f55aadf48', + collateralAddress: '0x998e45fd73d0ee358bc93e548f5eb26be2eb2cc2', + borrowableAddress0: '0x4dfa40824f7493a17f9bad352425d4c066314378', + borrowableAddress1: '0x262665aa97632b4b39be282750888d6b69ab63dd', + farmingPoolAddress0: '0xb2c19e8a519090d1d56959ceca4dee370a6b99a6', + farmingPoolAddress1: '0x2ceff293f95ee813f55725608f991b4a555d096e', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x7a2edc2041e130d61e18eb93a32bb13c331067a0': { + lendingPoolAddress: '0x7a2edc2041e130d61e18eb93a32bb13c331067a0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xa0813bccc899589b4e7d9ac42193136d0313f4eb', + oxUserProxyAddress: '0xaf73d1afb44ea75db5124748d17a41deb1523c4d', + oxStakingAddress: '0xe28ad06576546c1d5953ab2871f22cc6c13285fb', + symbol0: 'xTAROT', + symbol1: 'TAROT', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x74d1d2a851e339b8cb953716445be7e8abdf92f4', + tokenAddress1: '0xc5e2b037d30a390e62180970b3aa4e91868764cd', + uniswapV2PairAddress: '0x4fe782133af0f7604b9b89bf95893adde265fefd', + collateralAddress: '0x6f488a8743b390c893345edcdfbd670d4527841e', + borrowableAddress0: '0x89bf74aa60a2f3b530004a4a9e3404bd4ca444c7', + borrowableAddress1: '0xd7736b59614d5fdcb35cf910d7302b3e51650380', + farmingPoolAddress0: '0x7e3b7cb22ea21393edd51b928e182e2bb1e9dbde', + farmingPoolAddress1: '0x85ba4ddfa4d434b436a95d3e468556511510a61c', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x48c7f3aa92fd340077d890706bfa93c644bd6828': { + lendingPoolAddress: '0x48c7f3aa92fd340077d890706bfa93c644bd6828', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x5990734584bf21c76cbc721858843e9574c8446f', + oxUserProxyAddress: '0xd7ff56920169e989282522836f1237925299c080', + oxStakingAddress: '0x3f6696b06f9479c9e538351f260e0dee109f4490', + symbol0: 'WFTM', + symbol1: 'SOLID', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x888ef71766ca594ded1f0fa3ae64ed2941740a20', + uniswapV2PairAddress: '0xe4bc39fdd4618a76f6472079c329bdfa820afa75', + collateralAddress: '0xa83581ba4f18ebbfb71f9f6fb1d8f9c8dffd09f1', + borrowableAddress0: '0x2387a9ec987f58a7298fd21af9eb2dbfc3c37b8c', + borrowableAddress1: '0x184dbba12dd8800300254ab6ee6b460e15ab34bb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x234c0af6f049a40fdc983b16b375c9d4fba4fe54': { + lendingPoolAddress: '0x234c0af6f049a40fdc983b16b375c9d4fba4fe54', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x3cbd867cf1d37d9b5c3cedf28b8a41d71f6807d6', + oxUserProxyAddress: '0x12f6b315ae0c8d42b288d5687b9bbe00a6cc20b8', + oxStakingAddress: '0x9c056d8c85a185c1ef469a3e09f65021a5052c6d', + symbol0: 'WFTM', + symbol1: 'SEX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xd31fcd1f7ba190dbc75354046f6024a9b86014d7', + uniswapV2PairAddress: '0xfcec86af8774d69e2e4412b8de3f4abf1f671ecc', + collateralAddress: '0xdadb23786315cde79c27665f4af97850cb574f2d', + borrowableAddress0: '0x56e8f6791cd75361a158f76fe3346049675a1d3f', + borrowableAddress1: '0x8700344aadad62c46bff3dd3839571dd1893a694', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xb5e6b68139aab9776d2cf40cc8ca7a178f97eda0': { + lendingPoolAddress: '0xb5e6b68139aab9776d2cf40cc8ca7a178f97eda0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x8015c2ca86f9833486f31782f43d7a8991c4c895', + oxUserProxyAddress: '0x9aaae5341427a8076bcfea494f9d9e19b57efa69', + oxStakingAddress: '0x8a88732ca17db0eb549f80fa716af53885960f18', + symbol0: 'WFTM', + symbol1: 'SOLIDsex', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x41adac6c1ff52c5e27568f27998d747f7b69795b', + uniswapV2PairAddress: '0xa66901d1965f5410deeb4d0bb43f7c1b628cb20b', + collateralAddress: '0x7919d965c11cf32c7e90ebdfaeeba3bd234cfe8b', + borrowableAddress0: '0x6ee25d3314053ffb12451fd82fb10667f3b40261', + borrowableAddress1: '0x1cde1cfb43bb77e0d7383e7ce118d04c78fbdb1d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x7e21f5aa96cc2ac329d94422094317d294220aa0': { + lendingPoolAddress: '0x7e21f5aa96cc2ac329d94422094317d294220aa0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x4905b9574d391c4c09bf73d0ebbd5cf71b015e2f', + oxUserProxyAddress: '0x443d1ac026b3c0db65b2dd631317b18f25c5005d', + oxStakingAddress: '0xadf51699539a3f37a7fcd213a4fbb1817d3d2a13', + symbol0: 'WFTM', + symbol1: 'MULTI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + uniswapV2PairAddress: '0x94be7e51efe2a0c06c2281b6b385fcd12c84d6f9', + collateralAddress: '0x38ca08a1561e91d3c6859b11a008b3c1db9fdc2b', + borrowableAddress0: '0x71f2d43d1ed7c6873fd49f8ec44d731a07283e83', + borrowableAddress1: '0x6cfe618214584d09ba393099f177d4754e2cc985', + farmingPoolAddress0: '0x1e83fd2f9c05a747b7c1ff8444a4d008a70c9a76', + farmingPoolAddress1: '0xaf113ad0489a5458724431dcbe6f21def1b37bb0', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x01bfde9576cc9410d917246a8496fc9115d5ad91': { + lendingPoolAddress: '0x01bfde9576cc9410d917246a8496fc9115d5ad91', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x9a1f8adae1a0b79ed1263640ee78421e9a5c9b68', + oxUserProxyAddress: '0xf420284921a4220895930a5f9da2630588c3fd28', + oxStakingAddress: '0x77831ced767f0e24cc69ecfc137ba45305ebc415', + symbol0: 'BOO', + symbol1: 'xBOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + tokenAddress1: '0xa48d959ae2e88f1daa7d5f611e01908106de7598', + uniswapV2PairAddress: '0x5804f6c40f44cf7593f73cf3aa16f7037213a623', + collateralAddress: '0xb057af778294d3bc28143e931b5adff0346a7512', + borrowableAddress0: '0x18b4f21fa8d8fbd1a81a987cdb6509eaa8aaea97', + borrowableAddress1: '0xd8fd5113a29309281e9b560d87016a36c3a9cef6', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x96f76751ea2669e6bb013d244164a0728368d6fb': { + lendingPoolAddress: '0x96f76751ea2669e6bb013d244164a0728368d6fb', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x6642c79bd7729ec7c56954b7fdd453991342f3d8', + oxUserProxyAddress: '0xfb804b47ebebe28470f03ec6f77feda28a978c91', + oxStakingAddress: '0x44c1c6292eba47fc73e44ad586dbe7925970c82c', + symbol0: 'WFTM', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0x86dd79265814756713e631dde7e162bdd538b7b1', + collateralAddress: '0xbb39b9ef9853165c9b1070f24b7b8e6be530f4c4', + borrowableAddress0: '0x334017a61d850abc9fff3e5d2e91f7d22a220c8d', + borrowableAddress1: '0xf887f61d08bb6b40139cf68258b7d72f85114586', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x96563f866bf30c64e6273706ac795ffc608b9de7': { + lendingPoolAddress: '0x96563f866bf30c64e6273706ac795ffc608b9de7', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xd0aa0c876cf4a223845dd8e26af1f9894d4b0d66', + oxUserProxyAddress: '0xcc1a362a23c856c2696b8d0441337874a660f834', + oxStakingAddress: '0x6b854eed02eb5a2dfc6bea6f63738107af5d2214', + symbol0: 'LQDR', + symbol1: 'DEI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + uniswapV2PairAddress: '0xd7c590a05c9bf78a51e5171613f83e6a88a6851a', + collateralAddress: '0x5e68df898c372a5fd7e97e88bdb4455dbad974bd', + borrowableAddress0: '0xe10daad8d16a5a016ac305cc600c66e2e73610d3', + borrowableAddress1: '0x37c3b503a315fc4a6de437a6276aa0df111f4e85', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xeb172c44b914638aed21743623da7a0ae431a8d0': { + lendingPoolAddress: '0xeb172c44b914638aed21743623da7a0ae431a8d0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x4b356eb8992eccd97b276187141bc2305a163599', + oxUserProxyAddress: '0xc792c62a6d78cea8799d4f14ce79884a9adbdde8', + oxStakingAddress: '0xb454d836a391cd2857a07735e5bfaa9226ed9077', + symbol0: 'DEI', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0xd11e940c42e03d927cfd7426718bb4ca21d6015f', + collateralAddress: '0x026bcd207f63bdf75849acd672becd51a72af56b', + borrowableAddress0: '0x8e364310f091dd0e56c40ea802b16bbd7476ba39', + borrowableAddress1: '0x74d241befc633d0e0c3e6ab805fe7f690133cd41', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x3a3d87c216d7401fde2c53ee4f8f33de333ff1b4': { + lendingPoolAddress: '0x3a3d87c216d7401fde2c53ee4f8f33de333ff1b4', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x3de4c9648d97834b3e67bd1a63102814c2b8282f', + oxUserProxyAddress: '0xd94355f7a44dd4ac4e9e10534352278cc695e000', + oxStakingAddress: '0x413e8bcb492474f66a816a4f5fb6413a3ef18c56', + symbol0: 'DEI', + symbol1: 'DEUS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + tokenAddress1: '0xde5ed76e7c05ec5e4572cfc88d1acea165109e44', + uniswapV2PairAddress: '0xf42dbcf004a93ae6d5922282b304e2aefdd50058', + collateralAddress: '0x9f93abd08990eaa680108b06d9d21d1dd68c049a', + borrowableAddress0: '0x38cb3f7c4f1de341d777654bf3ca4207ead76755', + borrowableAddress1: '0x210347a8a55efcbe99de070b3d33bb2acfa197d9', + farmingPoolAddress0: '0xc3d18268f2bc3a1d4c3104504c725ca27d654902', + farmingPoolAddress1: '0xf37fb8fbd9f96c45ef8a409a006967ac4b78390c', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x5aee40f89d84ce767f1df112d61d487268299987': { + lendingPoolAddress: '0x5aee40f89d84ce767f1df112d61d487268299987', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x2a6931b75ee4e062baabee7f297166871ee55837', + oxUserProxyAddress: '0x7628878704854b2b5d7da6fe3f088123619d3b39', + oxStakingAddress: '0xd6e666ec745990ec678342936446265198d5df62', + symbol0: 'WFTM', + symbol1: 'OXD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5a9848b9d145965d821aaec8fa32aaee026492d', + uniswapV2PairAddress: '0xcb6eab779780c7fd6d014ab90d8b10e97a1227e2', + collateralAddress: '0xb2b5d3326c6c74bc0f55eed80f0fd85724985899', + borrowableAddress0: '0x88f7412aca3fa7c93ba5a4f2d9fcffc0a7b71030', + borrowableAddress1: '0x44d87b59ce5a69968bfffd22e72d0a42bac83c48', + farmingPoolAddress0: '0xedb47fe9a9448707835d7e23ddf12b55d369e4fc', + farmingPoolAddress1: '0x5d594b469958b6f9017a84cbec012fdf08aec769', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xbc7dc91b8c1f2da435b8913d2b266ae96b2e5ec5': { + lendingPoolAddress: '0xbc7dc91b8c1f2da435b8913d2b266ae96b2e5ec5', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x7b69eb796fa7d8ee40ecfb92c71788b679a3c560', + oxUserProxyAddress: '0xe7f4756cf2f8783d7d1662651901d88c852dd5dd', + oxStakingAddress: '0xd78da94ab7cca8b083c7c59e0ed81ec4e86a0d99', + symbol0: 'SOLID', + symbol1: 'oxSOLID', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x888ef71766ca594ded1f0fa3ae64ed2941740a20', + tokenAddress1: '0xda0053f0befcbcac208a3f867bb243716734d809', + uniswapV2PairAddress: '0xa3bf7336fdbce054c4b5bad4ff8d79539db2a2b3', + collateralAddress: '0x6873dd094f4efe0df2f6afe549b0a4a9f55275ff', + borrowableAddress0: '0xbe9965a8ff26f61dfd5b71c62759b5ccc5d07b7d', + borrowableAddress1: '0xa4366c29811c5c045186b9beba0991b90600341f', + farmingPoolAddress0: '0xef64ed62dc029294682c1d0f0e9dbd8cb3088232', + farmingPoolAddress1: '0x670bbd4d35fd6ac76db7f78a7492a3cf8a9edc1e', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xb3dc4accfe37bd8b3c2744e9e687d252c9661bc7': { + lendingPoolAddress: '0xb3dc4accfe37bd8b3c2744e9e687d252c9661bc7', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xbb6c3a2eda2edf495d695d4105f48d16c2da5d70', + oxUserProxyAddress: '0x46341fc48c9463b35926bcedae2671b6135e376e', + oxStakingAddress: '0x63378ed6d07091ec18bb80b450241a09851cc559', + symbol0: 'USDC', + symbol1: 'SYN', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xe55e19fb4f2d85af758950957714292dac1e25b2', + uniswapV2PairAddress: '0xb1b3b96cf35435b2518093acd50e02fe03a0131f', + collateralAddress: '0xa82d53c7c6ef2a7282424a868faa057c848ea2d7', + borrowableAddress0: '0xd053007fa1b12b8d740477c587a7a2a2321a40ad', + borrowableAddress1: '0x25f889ca6c226da747ecaed30f115b3beb75f0e4', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x6707a811c7eb2582171ffebb33bc3b34247242f8': { + lendingPoolAddress: '0x6707a811c7eb2582171ffebb33bc3b34247242f8', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x13782c5c1b3b53095c7894c39b76ab0430099e02', + oxUserProxyAddress: '0x520307d4eba30197b5789ec95b4679424ff0a759', + oxStakingAddress: '0xa26da4bf51741e4bc18223bbc247cc461c232a0d', + symbol0: 'WFTM', + symbol1: 'SYN', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe55e19fb4f2d85af758950957714292dac1e25b2', + uniswapV2PairAddress: '0x8aa410d8b0cc3de48aac8eb5d928646a00e6ff04', + collateralAddress: '0xf5cc5d2934e32c773bcb984807c722ad90aa1582', + borrowableAddress0: '0x9ad764acd611ad8b70ca114a86c0c92f35412cc9', + borrowableAddress1: '0x611706e94a690549aebcbe541670a5db148d114f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x430a123b4b359fc46cdad932327684466b50b32e': { + lendingPoolAddress: '0x430a123b4b359fc46cdad932327684466b50b32e', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x6479352f9086474307b3fa465efc6fb550231f12', + oxUserProxyAddress: '0x0d9985983f9fd4784e1414c0a2f89332a3ed2a5e', + oxStakingAddress: '0x4c6e554c37c8a15095fa407bd83ee7d0497aaee5', + symbol0: 'HND', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10010078a54396f62c96df8532dc2b4847d47ed3', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x6aae93f2915b899e87b49a9254434d36ac9570d8', + collateralAddress: '0xd985702ecf985654b535a7fbd17d1ab01d99657f', + borrowableAddress0: '0xa4514d0830bcd78ad3097ea77a987bd6f5caafa1', + borrowableAddress1: '0xe343016794bdf44de8004dabe15dce4a351b7020', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x1a69a8d382a1b5b8e12a56e9e92b7f6e51180324': { + lendingPoolAddress: '0x1a69a8d382a1b5b8e12a56e9e92b7f6e51180324', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xdf6f82eb0b596c720135c9a85960f54dd495ea8c', + oxUserProxyAddress: '0x684a0087077b11d63c7604567d5591216c0d1371', + oxStakingAddress: '0xa8b093d1b878646dd2b6f957bf4b0b6eee46a4e6', + symbol0: 'LQDR', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x9861b8a9acc9b4f249981164bfe7f84202068bfe', + collateralAddress: '0xe91c0ee3cc1477f427adbe9a15be255ee24961dd', + borrowableAddress0: '0x79ccf06f6bbef48bb22d29a35ddbf5db039d838e', + borrowableAddress1: '0x31d6f048aeac0485a53213e8f9fa2a72e2276707', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xefb573eba712d8b03ab60fea31626c0ca46a30a0': { + lendingPoolAddress: '0xefb573eba712d8b03ab60fea31626c0ca46a30a0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x6228f815d433293a4429d6ff055264fba60c6fb8', + oxUserProxyAddress: '0xd846a8d69f367edf9bea058f027b273207736796', + oxStakingAddress: '0x16c03f86fc4127ac8753470c526e0f0e0be74e6a', + symbol0: 'BEETS', + symbol1: 'fBEETS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e', + tokenAddress1: '0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1', + uniswapV2PairAddress: '0x5a3aa3284ee642152d4a2b55be1160051c5eb932', + collateralAddress: '0x26f516b34bf72d9972385a7ff33efca7a83d12ad', + borrowableAddress0: '0xf7a734c3738bb3a44de504fb1d017b1e904fbce4', + borrowableAddress1: '0xe62f2142dfdd4151abd3118ca50465e08441798e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x2e4be477fd58a8409a671d15c7a91c2f98b81b39': { + lendingPoolAddress: '0x2e4be477fd58a8409a671d15c7a91c2f98b81b39', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x4905b9574d391c4c09bf73d0ebbd5cf71b015e2f', + symbol0: 'WFTM', + symbol1: 'MULTI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + uniswapV2PairAddress: '0x94be7e51efe2a0c06c2281b6b385fcd12c84d6f9', + collateralAddress: '0x82ae22ad352d90113b820a94838d594c67fbbfe0', + borrowableAddress0: '0xf20dd9117f2257b9f6baaee183c012f4bfce8bdf', + borrowableAddress1: '0xb54d34ea4c0433172bd4270f10cbcd7fb7d3181b', + farmingPoolAddress0: '0xcab448daecbd7cd753595499319f7775b7057fad', + farmingPoolAddress1: '0xd200e3951d66d88ade3dca286ebe4ee1e1621598', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xa96703fa415acbfce853fb16841f8d1e8032569b': { + lendingPoolAddress: '0xa96703fa415acbfce853fb16841f8d1e8032569b', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x9a1f8adae1a0b79ed1263640ee78421e9a5c9b68', + symbol0: 'BOO', + symbol1: 'xBOO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x841fad6eae12c286d1fd18d1d525dffa75c7effe', + tokenAddress1: '0xa48d959ae2e88f1daa7d5f611e01908106de7598', + uniswapV2PairAddress: '0x5804f6c40f44cf7593f73cf3aa16f7037213a623', + collateralAddress: '0x5be0af57b3dfb760b967966bf98a155782c211fe', + borrowableAddress0: '0xe216f239da2b4b9ca86f112c10c7e99b32d549e3', + borrowableAddress1: '0x04e8bd819398d93df9231067236a1598a71ec747', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x951dd713ba26dc922c00cdfa8ce2da97551f99d6': { + lendingPoolAddress: '0x951dd713ba26dc922c00cdfa8ce2da97551f99d6', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x6642c79bd7729ec7c56954b7fdd453991342f3d8', + symbol0: 'WFTM', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0x86dd79265814756713e631dde7e162bdd538b7b1', + collateralAddress: '0x864186a616db214979589959666f280ca9b06076', + borrowableAddress0: '0x71e83383ac325dfaac560b1b33be07978a25b319', + borrowableAddress1: '0x5a6c4d053faa2044c493daecf034e25493172338', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x2e99df1ea51260589dc7cc5bde84ba6b48bddd89': { + lendingPoolAddress: '0x2e99df1ea51260589dc7cc5bde84ba6b48bddd89', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xd0aa0c876cf4a223845dd8e26af1f9894d4b0d66', + symbol0: 'LQDR', + symbol1: 'DEI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + uniswapV2PairAddress: '0xd7c590a05c9bf78a51e5171613f83e6a88a6851a', + collateralAddress: '0x8256f092efecfee05ee2b5c8a3b27cb545b0f1eb', + borrowableAddress0: '0x7884692c97457935b393fe946c962e2377164785', + borrowableAddress1: '0xd5843632c5cc8ba08d2c2a3b58383e9088e0b37e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x7295faaeded70745063f1b31af6e21baccc2f915': { + lendingPoolAddress: '0x7295faaeded70745063f1b31af6e21baccc2f915', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x4b356eb8992eccd97b276187141bc2305a163599', + symbol0: 'DEI', + symbol1: 'SCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + tokenAddress1: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + uniswapV2PairAddress: '0xd11e940c42e03d927cfd7426718bb4ca21d6015f', + collateralAddress: '0x91b527cbc341ea82cebc553386cf780d97224f41', + borrowableAddress0: '0xbf3e99cfae35ba8419b12a4b8dedd66c8964ccda', + borrowableAddress1: '0x9fdb08128382110a7b28b4d29ce225ef7cabd658', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xe6e91ab350418a3223d035af5ab74ce599fbd614': { + lendingPoolAddress: '0xe6e91ab350418a3223d035af5ab74ce599fbd614', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x3de4c9648d97834b3e67bd1a63102814c2b8282f', + symbol0: 'DEI', + symbol1: 'DEUS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xde12c7959e1a72bbe8a5f7a1dc8f8eef9ab011b3', + tokenAddress1: '0xde5ed76e7c05ec5e4572cfc88d1acea165109e44', + uniswapV2PairAddress: '0xf42dbcf004a93ae6d5922282b304e2aefdd50058', + collateralAddress: '0x55d29cfc8635127f19ed6c645bfdc9c16f180ead', + borrowableAddress0: '0xeab2b2a1049b6e08520db65db08f2fd78d164d39', + borrowableAddress1: '0x014c4bf6b842ada889cf629ca156964ce8d3be30', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x2c6ce73df1bd4a2b1a57895033068f3e8c413158': { + lendingPoolAddress: '0x2c6ce73df1bd4a2b1a57895033068f3e8c413158', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x2a6931b75ee4e062baabee7f297166871ee55837', + symbol0: 'WFTM', + symbol1: 'OXD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xc5a9848b9d145965d821aaec8fa32aaee026492d', + uniswapV2PairAddress: '0xcb6eab779780c7fd6d014ab90d8b10e97a1227e2', + collateralAddress: '0x0babddfc39dbd6db4d059be43969c1b5d0def1da', + borrowableAddress0: '0x21f90523c7c4c607c9e05bb089cc7ef5b5b94392', + borrowableAddress1: '0x6bc4cbc23130cfe62ea3049f24313ed9cc4c26f3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xa5a877fc9d4c61b39443e8899fbb0277e02845d2': { + lendingPoolAddress: '0xa5a877fc9d4c61b39443e8899fbb0277e02845d2', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x7b69eb796fa7d8ee40ecfb92c71788b679a3c560', + symbol0: 'SOLID', + symbol1: 'oxSOLID', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x888ef71766ca594ded1f0fa3ae64ed2941740a20', + tokenAddress1: '0xda0053f0befcbcac208a3f867bb243716734d809', + uniswapV2PairAddress: '0xa3bf7336fdbce054c4b5bad4ff8d79539db2a2b3', + collateralAddress: '0x4082cd81cee247cc0e99283e5a7658200c239340', + borrowableAddress0: '0xef036d4baf03c36c7c2337ff10c8cdbe2bd33331', + borrowableAddress1: '0x05f277e74e8bc1f0fd38ab8c621eb7bbeb4a3212', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x38af189e2fc6fdfb0763904d9a19b272d2b352b1': { + lendingPoolAddress: '0x38af189e2fc6fdfb0763904d9a19b272d2b352b1', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xbb6c3a2eda2edf495d695d4105f48d16c2da5d70', + symbol0: 'USDC', + symbol1: 'SYN', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + tokenAddress1: '0xe55e19fb4f2d85af758950957714292dac1e25b2', + uniswapV2PairAddress: '0xb1b3b96cf35435b2518093acd50e02fe03a0131f', + collateralAddress: '0xa773ea05976146f272af577602a11ff5eb92c23b', + borrowableAddress0: '0xddded636cdd2cf25b93aaa615c1ec8cdf3222e51', + borrowableAddress1: '0x86beb793552b6459ae588439cf4b28978b4294bb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xf57e2173cc253c0466530943f4b099b1d27a3a9c': { + lendingPoolAddress: '0xf57e2173cc253c0466530943f4b099b1d27a3a9c', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x13782c5c1b3b53095c7894c39b76ab0430099e02', + symbol0: 'WFTM', + symbol1: 'SYN', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0xe55e19fb4f2d85af758950957714292dac1e25b2', + uniswapV2PairAddress: '0x8aa410d8b0cc3de48aac8eb5d928646a00e6ff04', + collateralAddress: '0x5eba46c2c8051f5788ea696e7849e0d03c1f69cb', + borrowableAddress0: '0x26d102b170c383a5e87a91a6a8d4e5754256ae00', + borrowableAddress1: '0xb430f6aaddeda089830c1e0714e0b4556ec01f1f', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x19d56953bbf4e4336bb90fe38ebccc99534a522b': { + lendingPoolAddress: '0x19d56953bbf4e4336bb90fe38ebccc99534a522b', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x6479352f9086474307b3fa465efc6fb550231f12', + symbol0: 'HND', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10010078a54396f62c96df8532dc2b4847d47ed3', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x6aae93f2915b899e87b49a9254434d36ac9570d8', + collateralAddress: '0x693e10b79634484abb7c0f493d325ee378445986', + borrowableAddress0: '0xa98d5d59c6f46a2a5e75e5d93e6368a7af7c8649', + borrowableAddress1: '0x25a699e2cb9a94a82fab16e2e648d8b728132918', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x609918b85712ef0448f6a4dc8d7f5986afd0ebf3': { + lendingPoolAddress: '0x609918b85712ef0448f6a4dc8d7f5986afd0ebf3', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xdf6f82eb0b596c720135c9a85960f54dd495ea8c', + symbol0: 'LQDR', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x10b620b2dbac4faa7d7ffd71da486f5d44cd86f9', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x9861b8a9acc9b4f249981164bfe7f84202068bfe', + collateralAddress: '0xc0d79f43c88b925da4b1a020b48423cc08505d65', + borrowableAddress0: '0xa587d96bc77501a2c133b886644c4f238d4b6009', + borrowableAddress1: '0x237c961037d5795f8a0508de72a57303e77f8989', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xa860d4c99dc21582b1c4431a5a067ca97706c5a0': { + lendingPoolAddress: '0xa860d4c99dc21582b1c4431a5a067ca97706c5a0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x6228f815d433293a4429d6ff055264fba60c6fb8', + symbol0: 'BEETS', + symbol1: 'fBEETS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e', + tokenAddress1: '0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1', + uniswapV2PairAddress: '0x5a3aa3284ee642152d4a2b55be1160051c5eb932', + collateralAddress: '0x7eb93604ff06860f3e568acc222df2867ad1305e', + borrowableAddress0: '0xa957422d3103189e6fd0d7ae187bea0e1e0a2d02', + borrowableAddress1: '0x149dd3a2aa9574d27042e7a05599f5ffdb366c95', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xd2916e1fdf0cbbf919a025003a8059d5e50f6686': { + lendingPoolAddress: '0xd2916e1fdf0cbbf919a025003a8059d5e50f6686', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xabf0eaf72086dca7226ba44adf85091cea238789', + oxUserProxyAddress: '0x1625a30c04d4f71af2ccc47c350354f228b70e08', + oxStakingAddress: '0x88fc52d698294997fc35bdbce4b809d57f342f94', + symbol0: 'SCREAM', + symbol1: 'xSCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + tokenAddress1: '0xe3d17c7e840ec140a7a51aca351a482231760824', + uniswapV2PairAddress: '0x74b61f876fb49c7e73dbdd3b2185390bfdc11ff5', + collateralAddress: '0x87c8dc9082cf28e5da001a12de88344e46ed03ad', + borrowableAddress0: '0x25fbd8f0e63477bb8a38f6c4b26cc8634a07dd8e', + borrowableAddress1: '0xfc35532900ab01de750f5871d82a41b1d2b82015', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x45933032bca4f793bf185d02ba6a154bdbdf93a7': { + lendingPoolAddress: '0x45933032bca4f793bf185d02ba6a154bdbdf93a7', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xdafacf5182437311c1f88cd6b42f881b062e2888', + oxUserProxyAddress: '0x29723918607309a73e71e38cf18d64d69e3b38d9', + oxStakingAddress: '0x06e19eab30c1e0c3fe8c6f8c8bce401d26ed60b0', + symbol0: 'IB', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x00a35fd824c717879bf370e70ac6868b95870dfb', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x304b61f3481c977ffbe630b55f2abeee74792664', + collateralAddress: '0xb0717a749613f04bfe73f2d19d709e235bf8445f', + borrowableAddress0: '0xf2488a11e74fe4869a46554a186e0e1e74bace69', + borrowableAddress1: '0x5b39ee4e653f7162425dbbc1d2035a94e1c2f808', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x328caceb07022f910eb0eef7b1bcce19d54eaca0': { + lendingPoolAddress: '0x328caceb07022f910eb0eef7b1bcce19d54eaca0', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xeb569abd7f3dd906461fcf74d4e4495871f02d32', + oxUserProxyAddress: '0x0ca3511d056b8eda2b9aefc81ec049fc15fed778', + oxStakingAddress: '0xb4fc94e6420b6e421a023eb30c46d2dfa3304942', + symbol0: 'FXS', + symbol1: 'FRAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x7d016eec9c25232b01f23ef992d98ca97fc2af5a', + tokenAddress1: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355', + uniswapV2PairAddress: '0x4bbd8467ccd49d5360648ce14830f43a7feb6e45', + collateralAddress: '0xd0be590064fbf6ab791033eebb1cbdd9356aeec0', + borrowableAddress0: '0x347f7be6d88ae2755ac945453a992784937851ab', + borrowableAddress1: '0xc779d63809b0b9f5bbfe01b846adbbf3bbd058f3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xc64cdbc64060196a3e0f663cac484d2a5270634c': { + lendingPoolAddress: '0xc64cdbc64060196a3e0f663cac484d2a5270634c', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x9d1a7eb2cfb99a9a1806d14366514bfb43d4f254', + oxUserProxyAddress: '0x7e6e88757651e544bdc90cecbfb6bd2703710c9a', + oxStakingAddress: '0xe0a25297fd593877207c918a541158591b7fb6c2', + symbol0: 'WFTM', + symbol1: 'RDL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x79360af49edd44f3000303ae212671ac94bb8ba7', + uniswapV2PairAddress: '0x5ef8f0bd4f071b0199603a28ec9343f3651999c0', + collateralAddress: '0xdb03d8e47117d75cdc17029734baea76c317be56', + borrowableAddress0: '0xe7628ff9380a7722acd3b2a1017d21de741faef3', + borrowableAddress1: '0xec495088ceb26a141837996508327358f77c2d56', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xbdecb0def3795214f3a1cc119cb4d711e42bd181': { + lendingPoolAddress: '0xbdecb0def3795214f3a1cc119cb4d711e42bd181', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x46e0f8acb83bdc5fd6cb6d888d285ccf17aacbf4', + oxUserProxyAddress: '0x7691eb2d90b28835dd63d5a014c530c8a409479c', + oxStakingAddress: '0x2799e089550979d5e268559bebca3990dcbed18b', + symbol0: 'YFI', + symbol1: 'WOOFY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 12, + tokenAddress0: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + tokenAddress1: '0xd0660cd418a64a1d44e9214ad8e459324d8157f1', + uniswapV2PairAddress: '0x4b3a172283ecb7d07ab881a9443d38cb1c98f4d0', + collateralAddress: '0xd05ef44c8c1a47d31a82b36dcca0ef45e53f44b9', + borrowableAddress0: '0xadb016b3650d01c69292cba63daa999d89667462', + borrowableAddress1: '0xda10a0d871f52d6c455e189ec3d4e8182812231d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xc45ba1007e00c47055ae8c9619442e91ff7168ba': { + lendingPoolAddress: '0xc45ba1007e00c47055ae8c9619442e91ff7168ba', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0xf66eaea3f1f90eecae3c865686136b3e8ffbaabc', + oxUserProxyAddress: '0x69f9a9f4f4e4efe57bb36c71e7e7cb9aff99eb0e', + oxStakingAddress: '0x107b45bc35b7ae0fa56bf39ef91787a3a66f9be1', + symbol0: 'TOMB', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x29a1780be39c1911e55179f3ead358767203cecc', + collateralAddress: '0x43196d55d6d7bdfb4bc72393cb0627ef386bcf55', + borrowableAddress0: '0x83faf1f8a7e6e516cf0349c1eaf16dad727e2e72', + borrowableAddress1: '0x2eb0af61964011b8e792880f0910af032c88cda1', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x6aa1d3223a0571e63b8a5d4a5671024c4cdbac30': { + lendingPoolAddress: '0x6aa1d3223a0571e63b8a5d4a5671024c4cdbac30', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xabf0eaf72086dca7226ba44adf85091cea238789', + symbol0: 'SCREAM', + symbol1: 'xSCREAM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0xe0654c8e6fd4d733349ac7e09f6f23da256bf475', + tokenAddress1: '0xe3d17c7e840ec140a7a51aca351a482231760824', + uniswapV2PairAddress: '0x74b61f876fb49c7e73dbdd3b2185390bfdc11ff5', + collateralAddress: '0x3cdad887459247e0068014402b2bf629df948933', + borrowableAddress0: '0x04b8c8920a0b27f7ead647bb31f23bf55e8c1246', + borrowableAddress1: '0x56dc6dd26c409aaa74f42e2dc9457e0641fccd32', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x11402425f12285c89bb16524a953c2de37f1268c': { + lendingPoolAddress: '0x11402425f12285c89bb16524a953c2de37f1268c', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xdafacf5182437311c1f88cd6b42f881b062e2888', + symbol0: 'IB', + symbol1: 'WFTM', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x00a35fd824c717879bf370e70ac6868b95870dfb', + tokenAddress1: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + uniswapV2PairAddress: '0x304b61f3481c977ffbe630b55f2abeee74792664', + collateralAddress: '0x069b99fcb55da376ac70333f8c46921bf94dfad0', + borrowableAddress0: '0x706521742fe064457c878df380ae435cf68fb372', + borrowableAddress1: '0x7be27ec00239ca28ceb3fd71fcc52152028826d5', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xadb8d29ecb0224d1113a5d2223f7c513d7666985': { + lendingPoolAddress: '0xadb8d29ecb0224d1113a5d2223f7c513d7666985', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xeb569abd7f3dd906461fcf74d4e4495871f02d32', + symbol0: 'FXS', + symbol1: 'FRAX', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x7d016eec9c25232b01f23ef992d98ca97fc2af5a', + tokenAddress1: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355', + uniswapV2PairAddress: '0x4bbd8467ccd49d5360648ce14830f43a7feb6e45', + collateralAddress: '0x2c275c1e57654cf6715d59659cf8742695ab918e', + borrowableAddress0: '0xa1d7f9517cb8c0da2d17b5b76600f712d16b2755', + borrowableAddress1: '0x6a59dec247056ab9b1be0b061ac1465b285d6bb8', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x008e5bfb67d6cf1ae5bcc39feceb6b49cd4714ab': { + lendingPoolAddress: '0x008e5bfb67d6cf1ae5bcc39feceb6b49cd4714ab', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x9d1a7eb2cfb99a9a1806d14366514bfb43d4f254', + symbol0: 'WFTM', + symbol1: 'RDL', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + tokenAddress1: '0x79360af49edd44f3000303ae212671ac94bb8ba7', + uniswapV2PairAddress: '0x5ef8f0bd4f071b0199603a28ec9343f3651999c0', + collateralAddress: '0xc8438653199186e5c693942567d999ed870fcdf3', + borrowableAddress0: '0x75235d63bac661d77fd3d834ea49624c15c04d19', + borrowableAddress1: '0x68bbc08abe51f2c7470fc473ecf03178156668dd', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x4f1cbeb5cff89e24a31dbc046fd7f59d25a2843d': { + lendingPoolAddress: '0x4f1cbeb5cff89e24a31dbc046fd7f59d25a2843d', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x46e0f8acb83bdc5fd6cb6d888d285ccf17aacbf4', + symbol0: 'YFI', + symbol1: 'WOOFY', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1322875650000000000', + decimals0: 18, + decimals1: 12, + tokenAddress0: '0x29b0da86e484e1c0029b56e817912d778ac0ec69', + tokenAddress1: '0xd0660cd418a64a1d44e9214ad8e459324d8157f1', + uniswapV2PairAddress: '0x4b3a172283ecb7d07ab881a9443d38cb1c98f4d0', + collateralAddress: '0xe9f4726b9c3f68fa7b58b666ea910156125cda61', + borrowableAddress0: '0x02742fba9c84847517b8f7996d128d11be5e04dd', + borrowableAddress1: '0x77601b5d64962f25d054412d86cb0d61018d0d79', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xc799ce73ede5c2fd58df7432c7028f82ac3f0de7': { + lendingPoolAddress: '0xc799ce73ede5c2fd58df7432c7028f82ac3f0de7', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0xf66eaea3f1f90eecae3c865686136b3e8ffbaabc', + symbol0: 'TOMB', + symbol1: 'miMATIC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x6c021ae822bea943b2e66552bde1d2696a53fbb7', + tokenAddress1: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + uniswapV2PairAddress: '0x29a1780be39c1911e55179f3ead358767203cecc', + collateralAddress: '0x29e4498ad756b9302bff579ba864c41c11242c05', + borrowableAddress0: '0x4e49d9d2b967445af1c131b90668c7d83995c90d', + borrowableAddress1: '0x15eca3f722bade7053f0989f8f1e2c970ce47770', + farmingPoolAddress0: '0x0181f09b9803bb11817afcdd884b1ca400a74d67', + farmingPoolAddress1: '0x26d6f09c253ffede5f40c8e6e35640cb7f3d9a51', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0xa65709aece302ed478b7d3171cfd577bbe4706a4': { + lendingPoolAddress: '0xa65709aece302ed478b7d3171cfd577bbe4706a4', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.OXD, + pid: undefined, + gaugeAddress: '0x3e21a9254070730935c27a07b8a85eb262d0ec4e', + oxUserProxyAddress: '0xedfd66f1749350fe4ef35ecbbeba4bff8f4b55ed', + oxStakingAddress: '0x106e126f7b26aad7d0f3c7edd1da2ddeab056d07', + symbol0: 'wpc', + symbol1: 'WeVE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x0589073b62217f8196fa668a3fdf81df45726236', + tokenAddress1: '0x911da02c1232a3c3e1418b834a311921143b04d7', + uniswapV2PairAddress: '0x759d12bef107e51a711a502cb81f3dbd2748ebf1', + collateralAddress: '0xc4dd56e0e111253a64114a6a924a67c14a0b20f8', + borrowableAddress0: '0xc23cf7426cc5a8d8911173dfa46aee2544d6bf82', + borrowableAddress1: '0xf04463a43235793dcecf72df93770505a4919af3', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + '0x543bdf468abe8f367b42646ea24177569d25985d': { + lendingPoolAddress: '0x543bdf468abe8f367b42646ea24177569d25985d', + isTarotVault: true, + dex: DEX.SOLIDLY, + vaultType: VaultType.SOLIDEX, + pid: undefined, + gaugeAddress: '0x3e21a9254070730935c27a07b8a85eb262d0ec4e', + symbol0: 'wpc', + symbol1: 'WeVE', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x0589073b62217f8196fa668a3fdf81df45726236', + tokenAddress1: '0x911da02c1232a3c3e1418b834a311921143b04d7', + uniswapV2PairAddress: '0x759d12bef107e51a711a502cb81f3dbd2748ebf1', + collateralAddress: '0xf4f399fdb7aa04c0a3fdc60a90c5a692e5666397', + borrowableAddress0: '0x30e5c36fb34e6d869eb8790b769e1fc7e368b0c9', + borrowableAddress1: '0xd0fee07f490772f8ceb0ce318b9f33e309d2eb25', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xbf76f858b42bb9b196a87e43235c2f0058cf7322', + tarotRouterAddress: '0x26b21e8cd033ec68e4180dc5fc14446905e94572', + }, + + // Optimism Pools + '0xaaa7ce97cf8f8487354824d0df41f2ac864a4790': { + chainId: 10, + lendingPoolAddress: '0xaaa7ce97cf8f8487354824d0df41f2ac864a4790', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 0, + symbol0: 'WETH', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x1a981daa7967c66c3356ad044979bc82e4a478b9', + collateralAddress: '0x1db39b72721e1c4f8532346d861c273af00db443', + borrowableAddress0: '0xd1e303e68ad59d067c775ee5f307191af7f9a696', + borrowableAddress1: '0x7e101818f24bb084cf55f343a7c6a7c92e405b60', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0xe8181e911f62c4ddfffa7c02de8824aee42461e5': { + chainId: 10, + lendingPoolAddress: '0xe8181e911f62c4ddfffa7c02de8824aee42461e5', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 1, + symbol0: 'WETH', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + uniswapV2PairAddress: '0x53790b6c7023786659d11ed82ee03079f3bd6976', + collateralAddress: '0x9de331d1b50cfb25a1c863b3300bf68f17f6d44c', + borrowableAddress0: '0xe25c6ce3f2ded8c57e33628c9241ce2cb96e4b9b', + borrowableAddress1: '0x40e3c5b417bf016672a6ed86e4f12dd0782104ba', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0xd839b87aff846daef263190086b82896af5038e2': { + chainId: 10, + lendingPoolAddress: '0xd839b87aff846daef263190086b82896af5038e2', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 2, + symbol0: 'WETH', + symbol1: 'WBTC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 8, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x68f180fcce6836688e9084f035309e29bf0a2095', + uniswapV2PairAddress: '0x251de0f0368c472bba2e1c8f5db5ac7582b5f847', + collateralAddress: '0xaa04c5ff42e87b440e4900ee8e3e2c6cd88b04c6', + borrowableAddress0: '0x3c335a34fcf13777691535017d47d1da07a20e89', + borrowableAddress1: '0xe3516f617ae4be7670f40cb1488a934a6addac39', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0x7eac79383c42bc16e33cd100008ee6d5e491680f': { + chainId: 10, + lendingPoolAddress: '0x7eac79383c42bc16e33cd100008ee6d5e491680f', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 3, + symbol0: 'WETH', + symbol1: 'ZIP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0xfa436399d0458dbe8ab890c3441256e3e09022a8', + uniswapV2PairAddress: '0xd7f6ecf4371eddbd60c1080bfaec3d1d60d415d0', + collateralAddress: '0x317dd3a4d48b41d0ad4c9af0d720f7fc97090315', + borrowableAddress0: '0x14f8570c3d7e739a304c9ae3f29a1f3732bf7b0a', + borrowableAddress1: '0x7ddee8c66f838380e2cbd89c814e5f25ccacf185', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0x01b62c75f10eab716612d358226db4d25bb262d6': { + chainId: 10, + lendingPoolAddress: '0x01b62c75f10eab716612d358226db4d25bb262d6', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 5, + symbol0: 'gOHM', + symbol1: 'WETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x0b5740c6b4a97f90ef2f0220651cca420b868ffb', + tokenAddress1: '0x4200000000000000000000000000000000000006', + uniswapV2PairAddress: '0x3f6da9334142477718be2ecc3577d1a28dceaae1', + collateralAddress: '0xc4923d1b6110a233870f67cbbe85d156c19bb04b', + borrowableAddress0: '0x6f4f0168e3be337c4821f6b04abc37a4daa0009d', + borrowableAddress1: '0x7ce6ca0b512280c442f33d9fc824d5d425495642', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0x164426c091e0d5801ce86404cb49e9435dba4569': { + chainId: 10, + lendingPoolAddress: '0x164426c091e0d5801ce86404cb49e9435dba4569', + isTarotVault: true, + dex: DEX.ZIP, + vaultType: VaultType.ZIP, + pid: 7, + symbol0: 'WETH', + symbol1: 'OP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x4200000000000000000000000000000000000042', + uniswapV2PairAddress: '0x167dc49c498729223d1565df3207771b4ee19853', + collateralAddress: '0x38585c27c99dfff859cc33f19dcd03f897f5156f', + borrowableAddress0: '0x6cfca68b32bdb5b02039ccd03784cdc96de7fb87', + borrowableAddress1: '0x53a5267d2ddd35fe80651e038d5f82cad2df9751', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0x1d90fdac4dd30c3ba38d53f52a884f6e75d0989e', + tarotRouterAddress: '0xd4a6a05081fd270dc111332845a778a49fe01741', + }, + '0x287f9681af590354d6722ac51e6935beef631941': { + chainId: 10, + lendingPoolAddress: '0x287f9681af590354d6722ac51e6935beef631941', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x6b8edc43de878fd5cd5113c42747d32500db3873', + symbol0: 'VELO', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x3c8b650257cfb5f272f799f5e2b4e65093a11a05', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0xe8537b6ff1039cb9ed0b71713f697ddbadbb717d', + collateralAddress: '0x1b7b202d44193f6af293bad8ef773791cfd24ee1', + borrowableAddress0: '0xcc538d478369336fe18311bec9edddca8587967b', + borrowableAddress1: '0x1635353098ffb668e049c41e4d1546af682bc798', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xb4a2520be6c12d06f56959b90578fb57c25fd54b': { + chainId: 10, + lendingPoolAddress: '0xb4a2520be6c12d06f56959b90578fb57c25fd54b', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x1f36f95a02c744f2b3cd196b5e44e749c153d3b9', + symbol0: 'VELO', + symbol1: 'OP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x3c8b650257cfb5f272f799f5e2b4e65093a11a05', + tokenAddress1: '0x4200000000000000000000000000000000000042', + uniswapV2PairAddress: '0xffd74ef185989bff8752c818a53a47fc45388f08', + collateralAddress: '0xe7dad0fbb8c865791dda8d098581bc0f55fbfd3b', + borrowableAddress0: '0xe9e2be7f7538300d9bcffb5f208dc0ab78ace6d5', + borrowableAddress1: '0x720de187caea20a39befcf1803d1f4d99e23464a', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x6cfe820ec919a4accd651ac336197ce8a19539c7': { + chainId: 10, + lendingPoolAddress: '0x6cfe820ec919a4accd651ac336197ce8a19539c7', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xe2cec8ab811b648ba7b1691ce08d5e800dd0a60a', + symbol0: 'WETH', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x79c912fef520be002c2b6e57ec4324e260f38e50', + collateralAddress: '0x28fa49da55a54f02bc4ff103adbd843b50b556f4', + borrowableAddress0: '0xabcc0531d4cf0b4d6a92f1e5668696033a96f6d2', + borrowableAddress1: '0xebe70ea3ff5fe44a22185870f46a9d092958db69', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x2585d58367c9faccddecc7df05006cf7f0f3d18e': { + chainId: 10, + lendingPoolAddress: '0x2585d58367c9faccddecc7df05006cf7f0f3d18e', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x0299d40e99f2a5a1390261f5a71d13c3932e214c', + symbol0: 'OP', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x4200000000000000000000000000000000000042', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x47029bc8f5cbe3b464004e87ef9c9419a48018cd', + collateralAddress: '0x2f707cfb7b6c1ef2fe01b13f13379ab0d6961189', + borrowableAddress0: '0x0af2fdfde652310677ddf3b0bb6cd903476c4342', + borrowableAddress1: '0xdb37a76ffc5aaf97a40c0d542ff7a4eca33380ab', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x0d7ba80188b908e110757338da125b28fa4c2a6b': { + chainId: 10, + lendingPoolAddress: '0x0d7ba80188b908e110757338da125b28fa4c2a6b', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xb62814b9ec209959dffd36d6130349c2fbae9050', + symbol0: 'FRAX', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x2e3d870790dc77a83dd1d18184acc7439a53f475', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x587233ce63d7c1e081ce9d94d9940544758f6d01', + collateralAddress: '0x732ed35a0ee78992ed33e12c72eb106c49047db0', + borrowableAddress0: '0xcf722e010bebbb375f72f9f8aba3242aa379a22c', + borrowableAddress1: '0xf36049b664157b9369c8bf68f98c9254c85c8a8d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xeef5cfe8b9bda6ff4f37f30af93079209825b863': { + chainId: 10, + lendingPoolAddress: '0xeef5cfe8b9bda6ff4f37f30af93079209825b863', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x461ba7fa5c2e94eb93e881b7c7e3a7dc4c1cd6b4', + symbol0: 'LYRA', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x50c5725949a6f0c72e6c4a641f24049a917db0cb', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0xdee1856d7b75abf4c1bdf986da4e1c6c7864d640', + collateralAddress: '0xfca2208f3a2aca17aba88e9461916f9456e3fd16', + borrowableAddress0: '0x5b374b3b9e2706303201a336a59cc4b4fa9961fb', + borrowableAddress1: '0x2ec051e30abb7123d4919b37b73194baf8dcf450', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xecbdddf4358c530df890bf1973700780dd8fb5b3': { + chainId: 10, + lendingPoolAddress: '0xecbdddf4358c530df890bf1973700780dd8fb5b3', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x05ef41da0b0c76b6e17be79bdaacf66306cbebb5', + symbol0: 'OP', + symbol1: 'DAI', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000042', + tokenAddress1: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + uniswapV2PairAddress: '0x43c3f2d0aa0ebc433d654bb6ebf67f0c03f8d8d9', + collateralAddress: '0x6aed49274d4cd3ea10ed3d4121e2b3f2881bd350', + borrowableAddress0: '0xe0264679ebb55d9438cf40d612ff88b1ae4e88f8', + borrowableAddress1: '0xb37dcdfa3b6e4994cef2a2887c710e4a3263a953', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xaff67afde8fc7910a04e8461ebeaaee6aea851ac': { + chainId: 10, + lendingPoolAddress: '0xaff67afde8fc7910a04e8461ebeaaee6aea851ac', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x0aaf1de71910d9f2be10e6c75b3eb6eca377cbf2', + symbol0: 'VELO', + symbol1: 'WETH', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x3c8b650257cfb5f272f799f5e2b4e65093a11a05', + tokenAddress1: '0x4200000000000000000000000000000000000006', + uniswapV2PairAddress: '0x06141423dcf1a5a4c137039063ac873cdc1e363a', + collateralAddress: '0x978d6913feec200bac83e5568dfc2ff1c12641b0', + borrowableAddress0: '0x4e4c12bf1b6e74767edb9a9ba9de03c8c20eca24', + borrowableAddress1: '0x7629411bd395e197fbc51ba11909cd0ff8986dda', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xc5aacc98ec32b86da4f30eff732d702623d0b5cf': { + chainId: 10, + lendingPoolAddress: '0xc5aacc98ec32b86da4f30eff732d702623d0b5cf', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x055ee7ddc298dca46172a7a9a43e28b76c17ad26', + symbol0: 'THALES', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x217d47011b23bb961eb6d93ca9945b7501a5bb11', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x9355292f66552ea5717b274d27eefc8254011d83', + collateralAddress: '0xbb478ac34bc2869b263bc1ee0579614e629a0881', + borrowableAddress0: '0x40585d56682a2e77caab7e3c4ef0f79484b411f9', + borrowableAddress1: '0x8b811cc824f527985dfdea869eb044e6c10dad88', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x1b59389ab4d77eb51048fc8ee5b0cda59a561de1': { + chainId: 10, + lendingPoolAddress: '0x1b59389ab4d77eb51048fc8ee5b0cda59a561de1', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x6af999d0cb99773398ddb265adf0243fbf5125df', + symbol0: 'USDC', + symbol1: 'PERP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + tokenAddress1: '0x9e1028f5f1d5ede59748ffcee5532509976840e0', + uniswapV2PairAddress: '0x9c8a59934fba9af82674eff5d13a24e7c7e7a1f1', + collateralAddress: '0x4e5acc5d171faa9e376089afbf6caedd2c2416eb', + borrowableAddress0: '0xad4c0cd0a8c220e9a55593966177be33f741e69d', + borrowableAddress1: '0xa514558c9ed596e69d7a42b8bc5e3c0a03ccc980', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xffba812d4b41f0bfadae9dc55b8319bb786e9a67': { + chainId: 10, + lendingPoolAddress: '0xffba812d4b41f0bfadae9dc55b8319bb786e9a67', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x2f733b00127449fcf8b5a195bc51abb73b7f7a75', + symbol0: 'WETH', + symbol1: 'OP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x4200000000000000000000000000000000000042', + uniswapV2PairAddress: '0xcdd41009e74bd1ae4f7b2eecf892e4bc718b9302', + collateralAddress: '0x64c6309e65358ff14efa378b6812d881cb7c1f5d', + borrowableAddress0: '0x2b0e6675365e6070a7012dbd19e49c5f9248f77f', + borrowableAddress1: '0xb34c6d7b14e3e835b1b75896d4526040314f68ef', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x07e7f9ea38256f808d86471ac0c6b3097c84182f': { + chainId: 10, + lendingPoolAddress: '0x07e7f9ea38256f808d86471ac0c6b3097c84182f', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x77b9a432b23ff5fc798c92a1435b0e51772bc538', + symbol0: 'FRAX', + symbol1: 'OP', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x2e3d870790dc77a83dd1d18184acc7439a53f475', + tokenAddress1: '0x4200000000000000000000000000000000000042', + uniswapV2PairAddress: '0x986d353a3700530be4e75794830f57e657bc68cb', + collateralAddress: '0x1a7452fe7787516d9f0dd36022d50be4ba898582', + borrowableAddress0: '0x48fb8f137a2a55a5d28dda478cfdb375de53cb02', + borrowableAddress1: '0x0e8e9a109d1b25f5e772d658c06312134337c09e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x0d1c6da0eb5539f9f790ad106b8f74eababf46d9': { + chainId: 10, + lendingPoolAddress: '0x0d1c6da0eb5539f9f790ad106b8f74eababf46d9', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x3a8883381e4416488db94a8e0469394ecfa8a024', + symbol0: 'FRAX', + symbol1: 'FXS', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x2e3d870790dc77a83dd1d18184acc7439a53f475', + tokenAddress1: '0x67ccea5bb16181e7b4109c9c2143c24a1c2205be', + uniswapV2PairAddress: '0xe2ea57fdf87624f4384ef6da5f3844e8e9e5d878', + collateralAddress: '0xb548bb4c852ca44f6f28a878e93c13213621da37', + borrowableAddress0: '0xea1ecb4fb0ac93ab9d0eb4e740cfaa01c562ad3b', + borrowableAddress1: '0xdc47970ab04da3da18b5e808c42f7dfd58a7cd26', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x78c46b737003055327cd36f311b125eeacb1a7ea': { + chainId: 10, + lendingPoolAddress: '0x78c46b737003055327cd36f311b125eeacb1a7ea', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x49ab32dc8c870ab033ca87df2b954c4c24405e64', + symbol0: 'WETH', + symbol1: 'DOLA', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x8ae125e8653821e851f12a49f7765db9a9ce7384', + uniswapV2PairAddress: '0x43ce87a1ad20277b78cae52c7bcd5fc82a297551', + collateralAddress: '0x0fb14ec4a5980d5c74cf95e34f408d7ce352033b', + borrowableAddress0: '0xe56cae2c06e986099e5dd6459f3aa2c17df11710', + borrowableAddress1: '0x8d7fea26e61027d33d2cd479114446a1c453defb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x632a464393eaede5d1242017afeef266e2c3256e': { + chainId: 10, + lendingPoolAddress: '0x632a464393eaede5d1242017afeef266e2c3256e', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xb4d9036b81b9b6a7de1c70887c29938ec8df6048', + symbol0: 'OP', + symbol1: 'L2DAO', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000042', + tokenAddress1: '0xd52f94df742a6f4b4c8b033369fe13a41782bf44', + uniswapV2PairAddress: '0xfc77e39de40e54f820e313039207dc850e4c9e60', + collateralAddress: '0xc122a9fde60b01888fb9b56a365ce72e29dc67fd', + borrowableAddress0: '0xbd378fb15daf7a1f3eb3cd797ab3f93a7b703f4f', + borrowableAddress1: '0xecd4c02ae701996be2d5611c1edc7199e97253cb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x6d94ef6aaa28a01a52387cb51253e3b903fa8278': { + chainId: 10, + lendingPoolAddress: '0x6d94ef6aaa28a01a52387cb51253e3b903fa8278', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xaf307d86b08c54bb840ab17ef66abbba87c6aabe', + symbol0: 'WETH', + symbol1: 'AELIN', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x61baadcf22d2565b0f471b291c475db5555e0b76', + uniswapV2PairAddress: '0x3eec44e94ee86ce79f34bb26dc3cdbbee18d6d17', + collateralAddress: '0xce7495b40afdfe2b7e15db8229d9bdf4f6100ab0', + borrowableAddress0: '0xffaecdfb9ab0b9dd8a029f34fda06dd04c09c0cc', + borrowableAddress1: '0x30845cddb42ad6234964b0108f02564b22776a28', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x6cce00972bff06ec4fed6602bd22f65214e14d1f': { + chainId: 10, + lendingPoolAddress: '0x6cce00972bff06ec4fed6602bd22f65214e14d1f', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x97f7884c1e57ca991b949b9ac2c6a04599e8f988', + symbol0: 'USDC', + symbol1: 'agEUR', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 6, + decimals1: 18, + tokenAddress0: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + tokenAddress1: '0x9485aca5bbbe1667ad97c7fe7c4531a624c8b1ed', + uniswapV2PairAddress: '0x7866c6072b09539fc0fde82963846b80203d7beb', + collateralAddress: '0xc5ca00fb11dcda882109fc520aebf723930b2db2', + borrowableAddress0: '0x9d29a054496fcdaed2b87e887a4e05f583c6e556', + borrowableAddress1: '0xfa29ffdcfaa1c82de7b59253ac0dae9f7ddadb42', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xc5820f74d6bcaf3a2e44ed1bc6661cadee29734d': { + chainId: 10, + lendingPoolAddress: '0xc5820f74d6bcaf3a2e44ed1bc6661cadee29734d', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x883c6d437d45b7ce61c07606fb390e6c28be27b8', + symbol0: 'HND', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x10010078a54396f62c96df8532dc2b4847d47ed3', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x588443c932b45f47e936b969eb5aa6b5fd4f3369', + collateralAddress: '0x94fcfa90f21810d332e2eccaf405508d0617fbfa', + borrowableAddress0: '0x9e254991db95404737ab4ce7f60b71f8f80af916', + borrowableAddress1: '0xcb22df226cc34b2a282d02c7f77b9ca2afe07c1e', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x1f3cd67eed9da261646e4687526ac5e22b69c994': { + chainId: 10, + lendingPoolAddress: '0x1f3cd67eed9da261646e4687526ac5e22b69c994', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x2414d571e490981b4dd8f554d0e719aed114525b', + symbol0: 'WETH', + symbol1: 'sUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000006', + tokenAddress1: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', + uniswapV2PairAddress: '0x58f98be02c4ffb675af8857013a9c0dfa5750d04', + collateralAddress: '0xc40c037ae545aa5ace049b1c5e5eecec29070749', + borrowableAddress0: '0xda59161d3fc389dd054fbb9396e0759ba6649482', + borrowableAddress1: '0x1d6af2d7b8f81fe928d4474ce750bc2677587cdb', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xad9800f58c61c3dc6b3aa55e24645c67ba542183': { + chainId: 10, + lendingPoolAddress: '0xad9800f58c61c3dc6b3aa55e24645c67ba542183', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xfc4b6dea9276d906ad36828dc2e7dbacfc01b47f', + symbol0: 'SNX', + symbol1: 'sUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x8700daec35af8ff88c16bdf0418774cb3d7599b4', + tokenAddress1: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', + uniswapV2PairAddress: '0x85ff5b70de43fee34f3fa632addd9f76a0f6baa9', + collateralAddress: '0xa5258e1208574a6884629e76b0d55821007fe7c0', + borrowableAddress0: '0x91ae00b11cd72b8c25e128b0bae5fdab4f3de7a0', + borrowableAddress1: '0xa7db9f0602d28941dd2690bae56d1a7f79007ccf', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x2c174d9408710c1ab5594ba54c0fbb0f2f6f29cb': { + chainId: 10, + lendingPoolAddress: '0x2c174d9408710c1ab5594ba54c0fbb0f2f6f29cb', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0xc8f650131f160da1f362777e3d5d7162ae3ac077', + symbol0: 'WBTC', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 8, + decimals1: 6, + tokenAddress0: '0x68f180fcce6836688e9084f035309e29bf0a2095', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x4c8b195d33c6f95a8262d56ede793611ee7b5aad', + collateralAddress: '0x7df1cdafecfe3e2fc94c3a7d8724e2cb0fca62fd', + borrowableAddress0: '0xf011fb6811642dcae7424b5c3a24c42d1d35486d', + borrowableAddress1: '0x5b4afcbc6cd40127c5a015774c7ccaba9c418188', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x9bf904e1ee73583490fab76bfae8ae0ad80c8762': { + chainId: 10, + lendingPoolAddress: '0x9bf904e1ee73583490fab76bfae8ae0ad80c8762', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x3dac764b79acdbc9fc4d3f6a58c15260ed3db230', + symbol0: 'OP', + symbol1: 'sUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x4200000000000000000000000000000000000042', + tokenAddress1: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', + uniswapV2PairAddress: '0x53bea2d15efe344b054e73209455d2b6aa1c9462', + collateralAddress: '0x8783489e280ef69f3b3dcf4db8080fe116383cbe', + borrowableAddress0: '0x75caed68833475d888582d2dc7fdbb1cd8b7ca5e', + borrowableAddress1: '0x26828c8dd4c0ae785dc42ec2209406839d88105d', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0x8a06163824f29d54807773b91f15259e528c9450': { + chainId: 10, + lendingPoolAddress: '0x8a06163824f29d54807773b91f15259e528c9450', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x8b57098ee6eafbe85fc3977cb974b5ab929e63f2', + symbol0: 'VELO', + symbol1: 'sUSD', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 18, + tokenAddress0: '0x3c8b650257cfb5f272f799f5e2b4e65093a11a05', + tokenAddress1: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', + uniswapV2PairAddress: '0x46b8a98d72820e28465a172687af920cc167e587', + collateralAddress: '0xd3237b2e5c6a20617f4f428b52c311654974f209', + borrowableAddress0: '0xa8bdf098cb52e2e386a17cb1bcf8fc190b1bbe70', + borrowableAddress1: '0xee760c93ba108f8e13af6f5d3c8b31b263773863', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, + '0xc73adf1da8847f0d8a4d1c17d2d2b3861ea577ae': { + chainId: 10, + lendingPoolAddress: '0xc73adf1da8847f0d8a4d1c17d2d2b3861ea577ae', + isTarotVault: true, + dex: DEX.VELODROME, + vaultType: VaultType.VELODROME, + pid: undefined, + gaugeAddress: '0x99f5d706218a95b4d20d222e8b184b30084fdcfb', + symbol0: 'TAROT', + symbol1: 'USDC', + shares0: '0', + shares1: '0', + reserveFactor0: '100000000000000000', + reserveFactor1: '100000000000000000', + adjustSpeed0: '50000000000000', + adjustSpeed1: '50000000000000', + kinkUtilizationRate0: '750000000000000000', + kinkUtilizationRate1: '750000000000000000', + liquidationIncentive: '1020000000000000000', + safetyMarginSqrt: '1414213560000000000', + decimals0: 18, + decimals1: 6, + tokenAddress0: '0x375488f097176507e39b9653b88fdc52cde736bf', + tokenAddress1: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + uniswapV2PairAddress: '0x3bbde95b1ed19f8d76252d0b48854d9eaaec3cef', + collateralAddress: '0xb5639e9efa70b6d70a5f1fed3c850b14d3cc66d3', + borrowableAddress0: '0xce38d8514b234bab4df7ec682ec3419f6c228d8c', + borrowableAddress1: '0x75ddb769e76f7d30340357f4810300eb3a4d9a87', + farmingPoolAddress0: '0x0000000000000000000000000000000000000000', + farmingPoolAddress1: '0x0000000000000000000000000000000000000000', + poolDisabled: false, + tarotFactoryAddress: '0xd7cabef2c1fd77a31c5ba97c724b82d3e25fc83c', + tarotRouterAddress: '0xa516b9c7378799799e6dfadbdabf45d5b584405f', + }, +}; diff --git a/src/adaptors/tarot/index.js b/src/adaptors/tarot/index.js new file mode 100644 index 0000000000..6ea885c7bd --- /dev/null +++ b/src/adaptors/tarot/index.js @@ -0,0 +1,701 @@ +/* + used g1nt0ki's code as a base from DefiLlama-Adapters ./projects/tarot/index.js + General setup + 1. Loop through each factory in each chain under const config + 2. Get the lending pools which are the vaults that tarot lets you borrow/lend tokens with the liquidity pool of the tokens as collateral. + 2a. If only lending, you don't need to supply collateral (which gets counted as excess supply) + 3. Prefetch the prices of the tokens (looking at the token0 and token1 fields in the lendingPools) from https://coins.llama.fi/prices + + To calculate TVL + 1. For each lending pool follow the below for each borrowable tokens (underlying are token0 and token1) + 2. Get the reserves of the tokens from the lending pool contract. Use the respective token's reserve and get the USD amount. + In USD term both tokens should be equal (or close) since they are a 50/50 weighted LP. (const lpTvlUsd) + 3. Get the excess supply of the borrowable token by getting the balanceOf the underlying token and get the USD amount (const excessSupplyUsd) + 4. Add the reserve in USD from step 2 and excess supply in USD in step 3 above to get the totalTvl for that token (const totalTvl) + + To calculate APY (for the supplied token) + 1. For each lending pool follow the below for each borrowable token (underlying are token0 and token1) + 2. Get the following values from the borrowable contract + 2a. reserveFactor + 2b. totalBorrows + 2c. borrowRate + 2d. decimals + 3. Calculate the total supply of the borrowable contract: totalBorrows + excessSupply. (const totalSupply) + 4. Calculate the utilization rate: totalBorrows/totalSupply. (const utilization) + 5. Calculate the supply rate with the formula below: + (borrowRate *utilization*(10 ** borrowableDecimal - reserveFactor) * SECONDS_IN_YEAR) / (10 **borrowableDecimal * 10 ** borrowableDecimal); + (const supplyRateAPY) + + Notes: + 1. There are some disabled tarot lending pools which are ignored (defined in const DISABLED_LENDING_POOLS. copy of the lending pool lists is in ./config/lending-pools.js) + 2. There are few tokens where prices were not available so they are skipped. + 3. There are some lending pools where the abis were not published yet so they are skipped. +*/ +const axios = require('axios'); +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); +const { tryUntilSucceed } = require('../../helper/utils'); +const abi = require('./abi'); +const SECONDS_IN_YEAR = BigNumber(365).times(24).times(3600); +const protocolSlug = 'tarot'; +const sdk = require('@defillama/sdk'); +const { getProvider } = require('@defillama/sdk/build/general'); +const config = { + // fantom: { + // factories: [ + // '0x35C052bBf8338b06351782A565aa9AaD173432eA', // Tarot Classic + // '0xF6D943c8904195d0f69Ba03D97c0BAF5bbdCd01B', // Tarot Requiem + // '0xbF76F858b42bb9B196A87E43235C2f0058CF7322', // Tarot Carcosa + // ], + // }, + optimism: { + factories: [ + '0x1D90fDAc4DD30c3ba38d53f52A884F6e75d0989e', // Tarot Opaline + '0xD7cABeF2c1fD77a31c5ba97C724B82d3e25fC83C', // Tarot Velours + ], + }, +}; +// pools that are disabled by tarot.co (included in their lending-pool.ts) +const DISABLED_LENDING_POOLS = [ + '0x4601ad6ffd55f15dadc639b8704b19dc4b7dfc91', + '0x6d368f3f94601cce3f9806381a6132feb0dd6272', +]; + +const transformTokenForApi = (chain, token, transform) => { + const transformedToken = transform(token); + if (transformedToken !== token && transformedToken.indexOf(':') < 0) { + return `ethereum:${transformedToken}`; + } else if (transformedToken.indexOf(':') > -1) { + return `${transformedToken}`; + } else { + return `${chain}:${transform(token)}`; + } +}; + +const getAllLendingPools = async (factory, chain, block) => { + const { output: allLendingPoolsLength } = await tryUntilSucceed(() => + sdk.api.abi.call({ + target: factory, + abi: abi.allLendingPoolsLength, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + // get all of the lending pools from the factory contract + const poolCalls = []; + for (let i = 0; i < +allLendingPoolsLength; i++) + poolCalls.push({ params: i }); + const { output: lendingPoolsResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + target: factory, + abi: abi.allLendingPools, + calls: poolCalls, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + const lendingPoolAddresses = lendingPoolsResults.map((i) => i.output); + const lendingPoolAddressesParamsCalls = lendingPoolAddresses.map((i) => ({ + params: i, + })); + const lendingPoolAddressesTargetCalls = lendingPoolAddresses.map((i) => ({ + target: i, + })); + const { output: getLendingPools } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + target: factory, + abi: abi.getLendingPool, + calls: lendingPoolAddressesParamsCalls, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + const lendingPoolsDetails = getLendingPools.map((i) => i.output); + // get tokens 0 and 1 of all lending pools + const { output: token0sResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: lendingPoolAddressesTargetCalls, + abi: abi.token0, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + const token0s = token0sResults.map((i) => i.output); + const { output: token1sResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: lendingPoolAddressesTargetCalls, + abi: abi.token1, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + const token1s = token1sResults.map((i) => i.output); + // get lending pool address decimals + const { output: lendingPoolDecimalsResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: lendingPoolAddressesTargetCalls, + abi: abi.decimals, + chain, + block, + requery: true, + permitFailure: true, + }) + ); + const lendingPoolDecimals = lendingPoolDecimalsResults.map((i) => i.output); + // get reserves + const { output: getReservesResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: lendingPoolAddressesTargetCalls, + abi: abi.getReserves, + chain, + block, + permitFailure: true, + }) + ); + const lendingPoolReserves = getReservesResults.map((i) => { + if (!i.output || !i.output.reserve0 || !i.output.reserve1) { + return null; + } else { + return [i.output.reserve0, i.output.reserve1]; + } + }); + return { + lendingPoolAddresses, + lendingPoolAddressesParamsCalls, + lendingPoolAddressesTargetCalls, + lendingPoolsDetails, + token0s, + token1s, + lendingPoolDecimals, + lendingPoolReserves, + }; +}; + +const getUnderlyingLiquidityPoolAddresses = async ( + lendingPoolAddresses, + lendingPoolAddressesTargetCalls, + chain, + block +) => { + const { output: lendingPoolSymbolsResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: lendingPoolAddressesTargetCalls, + abi: abi.symbol, + chain, + block, + }) + ); + const lendingPoolSymbols = lendingPoolSymbolsResults.map((i) => i.output); + // get underlying LP related info + let slpLpAddressesCalls = []; + let slpLpAddressesCallsIndex = []; + for (let index = 0; index < lendingPoolAddresses.length; index++) { + // slightly different logic for SLP and spLP lending pools where underlying liquidity pool is the same as the tarot's lending pool + if ( + lendingPoolSymbols[index] === 'SLP' || + lendingPoolSymbols[index] === 'spLP' + ) { + slpLpAddressesCalls.push({ target: lendingPoolAddresses[index] }); + slpLpAddressesCallsIndex.push(index); + } + } + const { output: underlyingLpAddressesResults } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + abi: abi.underlying, + calls: lendingPoolAddressesTargetCalls, + chain, + block, + }) + ); + let underlyingLpAddresses = underlyingLpAddressesResults.map((i) => i.output); + // for slp and spLP use same lendingpool as underlying + if (slpLpAddressesCalls.length > 0) { + for (let x = 0; x < slpLpAddressesCalls.length; x++) { + underlyingLpAddresses[slpLpAddressesCallsIndex[x]] = + lendingPoolAddresses[slpLpAddressesCallsIndex[x]]; + } + } + const underlyingLpAddressesTargetCalls = underlyingLpAddresses.map((i) => ({ + target: i, + })); + const { output: underlyingLiquidityPoolSymbolsResults } = + await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + calls: underlyingLpAddressesTargetCalls, + abi: abi.symbol, + chain, + block, + }) + ); + const underlyingLiquidityPoolSymbols = + underlyingLiquidityPoolSymbolsResults.map((i) => i.output); + return { + lendingPoolSymbols, + underlyingLpAddresses, + underlyingLiquidityPoolSymbols, + }; +}; + +const removeDuplicatesFromArray = (arr) => { + return [...new Set([].concat(...arr))]; +}; + +// Liquidity Pool Names are sometimes the same (since they are forked or upgraded) so look up by the underlying factory contract to determine the name +const transformTarotLPName = async ( + underlyingLiquidityPoolSymbol, + lendingPoolAddress, + token0Symbol, + token1Symbol, + supplyTokenSymbol, + chain, + block +) => { + let poolName; + let poolId; + let poolMeta; + // if symbols are matched below, use the factory to determine the pool name + if ( + underlyingLiquidityPoolSymbol === 'spLP' || + underlyingLiquidityPoolSymbol === 'SPIRIT-LP' || + underlyingLiquidityPoolSymbol === 'TOMB-V2-LP' || + underlyingLiquidityPoolSymbol.indexOf('vAMM') > -1 + ) { + const { output: lendingPoolFactory } = await tryUntilSucceed(() => + sdk.api.abi.call({ + target: lendingPoolAddress, + abi: abi.factory, + chain, + block, + requery: false, + }) + ); + // if symbol is from solidex/0xDAO/Velodrome + if (underlyingLiquidityPoolSymbol.indexOf('vAMM') !== -1) { + switch (lendingPoolFactory.toLowerCase()) { + // Solidex 0x17235bb61f7a8c3e93a8ad2b1b12802e00121c35 + case '0x17235bb61f7a8c3e93a8ad2b1b12802e00121c35': + poolName = 'Solidex'; + break; + // 0xDAO 0x1f8e600303a7c85166467b0e5921ab394dc5cdb7 + case '0x1f8e600303a7c85166467b0e5921ab394dc5cdb7': + poolName = '0xDAO'; + break; + // velodrome 0x19283dd283c31bf3920f7a530aa3a81a2792dc52 + case '0x19283dd283c31bf3920f7a530aa3a81a2792dc52': + poolName = 'Velodrome'; + break; + } + } else { + switch (underlyingLiquidityPoolSymbol) { + case 'spLP': + switch (lendingPoolFactory.toLowerCase()) { + //spooky v2 0x10ea0977f832f851786cfdc2f29a9fc1b97b79b1 + case '0x701e3156c4e5abe044f756936792032bb96481b9': + poolName = 'Spooky V2'; + break; + //2omb 0x10ea0977f832f851786cfdc2f29a9fc1b97b79b1 + case '0x10ea0977f832f851786cfdc2f29a9fc1b97b79b1': + poolName = '2omb'; + break; + //3omb 0xd25005e7280420a60092f3963d6a1cb7543ce7df + case '0xd25005e7280420a60092f3963d6a1cb7543ce7df': + poolName = '3omb'; + break; + default: + poolName = 'Spooky'; + break; + } + break; + case 'SPIRIT-LP': + // differentiate boosted and non boosted spirit ppols + // boosted pools have factory address of 0x9f28680ebaca6ef09c1db327f8d0f9b6fc498127 + switch (lendingPoolFactory.toLowerCase()) { + case '0x9f28680ebaca6ef09c1db327f8d0f9b6fc498127': + poolName = 'Spirit Boosted'; + break; + case '0x51d49f3731a9591d6eb4fe79523f20ae5e560ba7': + poolName = 'Spirit v2'; + default: + poolName = 'Spirit'; + break; + } + break; + case 'TOMB-V2-LP': + switch (lendingPoolFactory.toLowerCase()) { + // tomb cemetery 0x9189a6c06a33dea7ad82201e37b73fe2adc595ed + case '0x9189a6c06a33dea7ad82201e37b73fe2adc595ed': + poolName = 'Tomb Cemetery'; + break; + // tomb cemetery v2 0x2dc3be114ec36ae0e8dc70f3090b8f2bcb7c18e7 + case '0x2dc3be114ec36ae0e8dc70f3090b8f2bcb7c18e7': + poolName = 'Tomb Cemetery V2'; + break; + // Based Agora 0xfcfcf2f7773a303fdd3eb003edf23e213a92547c or 0xe62745519c1d2af846387b8abd142a2d2583c275 + case '0xfcfcf2f7773a303fdd3eb003edf23e213a92547c': + case '0xe62745519c1d2af846387b8abd142a2d2583c275': + poolName = 'Based Agora'; + break; + } + break; + } + } + } else { + switch (underlyingLiquidityPoolSymbol) { + case 'SLP': + poolName = 'Sushi'; + break; + default: + poolName = underlyingLiquidityPoolSymbol; + } + } + + // if pool name chnaged from conditions above + if (poolName !== undefined) { + poolName = poolName.includes('-ZS') ? 'ZipSwap' : poolName; + poolId = `${lendingPoolAddress}-${supplyTokenSymbol}-${chain}`; + poolMeta = `${poolName} ${token0Symbol}/${token1Symbol}`; + } + return { poolId, poolMeta }; +}; + +// get prices function +const getPrices = async (coinKeys) => { + let results = {}; + // fetch prices by 100 + if (coinKeys.length > 0) { + for (let i = 0; i < coinKeys.length; i += 100) { + const { + data: { coins }, + } = await axios.get( + `https://coins.llama.fi/prices/current/${coinKeys.slice(i, i + 100)}` + ); + for (const key of Object.keys(coins)) { + results[key] = coins[key]; + } + } + } + return results; +}; + +const checkIfTokenKeyExists = (fetchedData, key) => { + return ( + fetchedData[key] && fetchedData[key].symbol && fetchedData[key].decimals + ); +}; + +const getTokenDetails = async (allUniqueTokens, chain, block) => { + let results = {}; + const tokensCalls = allUniqueTokens.map((i) => ({ target: i })); + const { output: getTokenDecimals } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + abi: `erc20:decimals`, + calls: tokensCalls, + chain, + block, + requery: true, + }) + ); + // underlying tokens symbol just reference from bulk + const { output: getTokenSymbols } = await tryUntilSucceed(() => + sdk.api.abi.multiCall({ + abi: `erc20:symbol`, + calls: tokensCalls, + chain, + block, + requery: true, + }) + ); + const tokensSymbols = getTokenSymbols.map((i) => i.output); + + for (let i = 0; i < getTokenDecimals.length; i++) { + tokensDecimalResult = getTokenDecimals[i]; + tokenSymbolResult = getTokenSymbols[i]; + let key = tokensDecimalResult.input.target; + results[key] = { + decimals: tokensDecimalResult.output, + symbol: tokenSymbolResult.output, + }; + } + return results; +}; + +// calculate tvl function +const caculateTvl = ( + excessSupply, + tokenDecimals, + underlyingTokenPriceUsd, + lpReserve +) => { + const excessSupplyUsd = BigNumber(excessSupply) + .div(BigNumber(10).pow(BigNumber(tokenDecimals))) + .times(BigNumber(underlyingTokenPriceUsd)); + const lpTvlUsd = BigNumber(lpReserve) + .div(BigNumber(10).pow(BigNumber(tokenDecimals))) + .times(BigNumber(underlyingTokenPriceUsd)); + const totalTvl = excessSupplyUsd.plus(lpTvlUsd); + return totalTvl; +}; + +// calculate apy function +const calculateApy = ( + borrowRate, + borrowableDecimal, + totalBorrows, + totalSupply, + reserveFactor +) => { + const borrowRateAPY = BigNumber(borrowRate) + .div(BigNumber(10).pow(BigNumber(borrowableDecimal))) + .times(SECONDS_IN_YEAR); + const utilization = BigNumber(totalBorrows).div(BigNumber(totalSupply)); + const supplyRateAPY = BigNumber(borrowRate) + .times(BigNumber(utilization)) + .times( + BigNumber(10) + .pow(BigNumber(borrowableDecimal)) + .minus(BigNumber(reserveFactor)) + ) + .times(SECONDS_IN_YEAR) + .div( + BigNumber(10) + .pow(BigNumber(borrowableDecimal)) + .times(BigNumber(10).pow(BigNumber(borrowableDecimal))) + ); + return { borrowRateAPY, utilization, supplyRateAPY }; +}; +const main = async () => { + let data = []; + for (const chain of Object.keys(config)) { + const { factories } = config[chain]; + const transform = (addr) => `${chain}:${addr}` + let collaterals = []; + let borrowables = []; + const provider = getProvider(chain); + const block = await provider.getBlockNumber(); + for (const factory of factories) { + const { + lendingPoolAddresses, + lendingPoolAddressesParamsCalls, + lendingPoolAddressesTargetCalls, + lendingPoolsDetails, + token0s, + token1s, + lendingPoolDecimals, + lendingPoolReserves, + } = await getAllLendingPools(factory, chain, block); + // get underlying LP related info + const { + lendingPoolSymbols, + underlyingLpAddresses, + underlyingLiquidityPoolSymbols, + } = await getUnderlyingLiquidityPoolAddresses( + lendingPoolAddresses, + lendingPoolAddressesTargetCalls, + chain, + block + ); + const allTokens = [...token0s, ...token1s]; + const allUniqueTokens = removeDuplicatesFromArray(allTokens); + const coinKeys = allUniqueTokens.map((token) => { + let transformedToken = transformTokenForApi(chain, token, transform); + return transformedToken; + }); + let fetchedPrices = await getPrices(coinKeys); + // go to the next factory contract since no tokens were found here. + if (Object.keys(fetchedPrices) === 0) { + continue; + } + const tokenDetailsDict = await getTokenDetails( + allUniqueTokens, + chain, + block + ); + // fetch the data in batches for the underlying assets of the lending pool first. + // flatmap borrowables + let allBorrowables = lendingPoolsDetails.flatMap( + (lendingPoolDetails, i) => { + const reserves = lendingPoolReserves[i]; + const lendingPoolAddress = lendingPoolAddresses[i]; + if (reserves === null) { + return null; + } + const underlyingLiquidityPoolSymbol = + underlyingLiquidityPoolSymbols[i]; + // check if the lending pool has a name + if (underlyingLiquidityPoolSymbol === null) { + return null; + } + const borrowable0 = lendingPoolDetails.borrowable0; + const borrowable1 = lendingPoolDetails.borrowable1; + const collateral = lendingPoolDetails.collateral; + const token0 = token0s[i]; + const token1 = token1s[i]; + const lendingPoolDecimal = lendingPoolDecimals[i]; + + return [ + { + lpReserve: reserves[0], + lendingPoolAddress, + underlyingLiquidityPoolSymbol, + underlyingTokenAddress: token0, + borrowableTokenAddress: borrowable0, + collateral, + token0, + token1, + lendingPoolDecimal, + tokenSymbol: tokenDetailsDict[token0].symbol, + tokenDecimals: tokenDetailsDict[token0].decimals, + }, + { + lpReserve: reserves[1], + lendingPoolAddress, + underlyingLiquidityPoolSymbol, + underlyingTokenAddress: token1, + borrowableTokenAddress: borrowable1, + collateral, + token0, + token1, + lendingPoolDecimal, + tokenSymbol: tokenDetailsDict[token1].symbol, + tokenDecimals: tokenDetailsDict[token1].decimals, + }, + ]; + } + ); + // remove null + allBorrowables = allBorrowables.filter((p) => p); + + const excessSupplyRes = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: allBorrowables.map((b) => ({ + target: b.underlyingTokenAddress, + params: b.borrowableTokenAddress, + })), + chain, + }); + const excessSupply = excessSupplyRes.output.map((res) => res.output); + + const [ + reserveFactorRes, + totalBorrowsRes, + borrowRateRes, + borrowableDecimalRes, + ] = await Promise.all( + ['reserveFactor', 'totalBorrows', 'borrowRate', 'decimals'].map( + (method) => + sdk.api.abi.multiCall({ + abi: abi[method], + calls: allBorrowables.map((b) => ({ + target: b.borrowableTokenAddress, + params: null, + })), + chain: chain, + }) + ) + ); + const reserveFactor = reserveFactorRes.output.map((res) => res.output); + const totalBorrows = totalBorrowsRes.output.map((res) => res.output); + const borrowRate = borrowRateRes.output.map((res) => res.output); + const borrowableDecimal = borrowableDecimalRes.output.map( + (res) => res.output + ); + + const poolMetaData = await Promise.all( + allBorrowables.map((borrowable) => { + return borrowable !== null + ? transformTarotLPName( + borrowable.underlyingLiquidityPoolSymbol, + borrowable.lendingPoolAddress, + tokenDetailsDict[borrowable.token0].symbol, + tokenDetailsDict[borrowable.token1].symbol, + borrowable.tokenSymbol, + chain, + block + ) + : null; + }) + ); + // calculate the tvl and yields for each borrowables + data = [ + ...data, + ...allBorrowables + .map((borrowable, i) => { + // skip if no data + if (!borrowable) { + return null; + } + const totalSupply = BigNumber(totalBorrows[i]).plus( + BigNumber(excessSupply[i]) + ); + //apy calculations + const { borrowRateAPY, utilization, supplyRateAPY } = calculateApy( + borrowRate[i], + borrowableDecimal[i], + totalBorrows[i], + totalSupply, + reserveFactor[i] + ); + const { poolId, poolMeta } = poolMetaData[i]; + // if poolId is undefined, probably abi is not published so skip + if (poolId === undefined) { + return null; + } + const key = `${transformTokenForApi( + chain, + borrowable.underlyingTokenAddress, + transform + )}`; + // ignore pools where we can not find the price + if (!checkIfTokenKeyExists(fetchedPrices, key.toLowerCase())) { + return null; + } + // tvl calculations + const underlyingTokenPriceUsd = + fetchedPrices[key.toLowerCase()].price; + const totalTvl = caculateTvl( + excessSupply[i], + borrowable.tokenDecimals, + underlyingTokenPriceUsd, + borrowable.lpReserve + ); + let poolData = { + pool: `${poolId}`, + poolMeta: `${poolMeta}`, + chain: chain, + project: protocolSlug, + symbol: utils.formatSymbol(borrowable.tokenSymbol), + tvlUsd: totalTvl.toNumber(), + apyBase: supplyRateAPY.times(BigNumber(100)).toNumber(), + underlyingTokens: [borrowable.token0, borrowable.token1], + }; + // add the data if the supply apy exists and the total tvl is under the threshold + if (!supplyRateAPY.isNaN()) { + return poolData; + } else { + return null; + } + }) + .filter((data) => { + return data !== null; + }), + ]; + } + } + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.tarot.to/', +}; diff --git a/src/adaptors/teahouse-managed/abi.ts b/src/adaptors/teahouse-managed/abi.ts new file mode 100644 index 0000000000..9b2a183508 --- /dev/null +++ b/src/adaptors/teahouse-managed/abi.ts @@ -0,0 +1,967 @@ +const TEAHOUSE_VAULT_MANAGED_ABI = [{ + "inputs": [{ + "internalType": "string", + "name": "_name", + "type": "string" + }, {"internalType": "string", "name": "_symbol", "type": "string"}, { + "internalType": "address", + "name": "_weth9", + "type": "address" + }, {"internalType": "uint128", "name": "_priceNumerator", "type": "uint128"}, { + "internalType": "uint128", + "name": "_priceDenominator", + "type": "uint128" + }, {"internalType": "uint64", "name": "_startTimestamp", "type": "uint64"}, { + "internalType": "address", + "name": "_initialAdmin", + "type": "address" + }], "stateMutability": "nonpayable", "type": "constructor" +}, {"inputs": [], "name": "AssetNotWETH9", "type": "error"}, { + "inputs": [], + "name": "CancelDepositDisabled", + "type": "error" +}, {"inputs": [], "name": "CancelWithdrawDisabled", "type": "error"}, { + "inputs": [], + "name": "DepositDisabled", + "type": "error" +}, {"inputs": [], "name": "ExceedDepositLimit", "type": "error"}, { + "inputs": [], + "name": "FundIsClosed", + "type": "error" +}, {"inputs": [], "name": "FundIsNotClosed", "type": "error"}, { + "inputs": [], + "name": "FundingLocked", + "type": "error" +}, {"inputs": [], "name": "IncorrectCycleIndex", "type": "error"}, { + "inputs": [], + "name": "IncorrectCycleStartTimestamp", + "type": "error" +}, {"inputs": [], "name": "IncorrectETHAmount", "type": "error"}, { + "inputs": [], + "name": "IncorrectVaultAddress", + "type": "error" +}, {"inputs": [], "name": "InvalidFeePercentage", "type": "error"}, { + "inputs": [], + "name": "InvalidFundValue", + "type": "error" +}, {"inputs": [], "name": "InvalidInitialPrice", "type": "error"}, { + "inputs": [], + "name": "NoDeposits", + "type": "error" +}, {"inputs": [], "name": "NotAcceptingETH", "type": "error"}, { + "inputs": [], + "name": "NotEnoughAssets", + "type": "error" +}, {"inputs": [], "name": "NotEnoughDeposits", "type": "error"}, { + "inputs": [], + "name": "NotEnoughWithdrawals", + "type": "error" +}, {"inputs": [], "name": "OnlyAvailableToAdmins", "type": "error"}, { + "inputs": [], + "name": "OnlyAvailableToAuditors", + "type": "error" +}, {"inputs": [], "name": "ReceiverDoNotHasNFT", "type": "error"}, { + "inputs": [], + "name": "WithdrawDisabled", + "type": "error" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], + "name": "Approval", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "assets", "type": "uint256"}], + "name": "ClaimOwedAssets", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256"}], + "name": "ClaimOwedShares", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }], + "name": "ConvertToAssets", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "uint256", "name": "assets", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "name": "ConvertToShares", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": true, "internalType": "address", "name": "receiver", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }], + "name": "DepositCanceled", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "uint256", "name": "depositLimit", "type": "uint256"}], + "name": "DepositLimitUpdated", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": true, "internalType": "address", "name": "receiver", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }], + "name": "DepositRequested", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "address", "name": "teaVaultV2", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], + "name": "DepositToVault", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "bool", "name": "disableChecks", "type": "bool"}], + "name": "DisableNFTChecks", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "uint256", "name": "fundValue", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "priceNumerator", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "priceDenominator", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "depositLimit", + "type": "uint256" + }, {"indexed": false, "internalType": "uint64", "name": "startTimestamp", "type": "uint64"}, { + "indexed": false, + "internalType": "uint64", + "name": "lockTimestamp", + "type": "uint64" + }, {"indexed": false, "internalType": "bool", "name": "fundClosed", "type": "bool"}, { + "indexed": false, + "internalType": "uint256", + "name": "platformFee", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "managerFee", "type": "uint256"}], + "name": "EnterNextCycle", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, { + "components": [{ + "internalType": "address", + "name": "platformVault", + "type": "address" + }, {"internalType": "address", "name": "managerVault", "type": "address"}, { + "internalType": "uint24", + "name": "platformEntryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerEntryFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformExitFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerExitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformPerformanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerPerformanceFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformManagementFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerManagementFee", "type": "uint24"}], + "indexed": false, + "internalType": "struct IHighTableVault.FeeConfig", + "name": "feeConfig", + "type": "tuple" + }], + "name": "FeeConfigChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "priceNumerator", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "priceDenominator", "type": "uint256"}, { + "indexed": false, + "internalType": "uint64", + "name": "startTimestamp", + "type": "uint64" + }, {"indexed": false, "internalType": "address", "name": "admin", "type": "address"}], + "name": "FundInitialized", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "uint64", "name": "lockTimestamp", "type": "uint64"}], + "name": "FundLockingTimestampUpdated", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "bool", "name": "disableDepositing", "type": "bool"}, { + "indexed": false, + "internalType": "bool", + "name": "disableWithdrawing", + "type": "bool" + }, {"indexed": false, "internalType": "bool", "name": "disableCancelDepositing", "type": "bool"}, { + "indexed": false, + "internalType": "bool", + "name": "disableCancelWithdrawing", + "type": "bool" + }], + "name": "FundingChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "address[]", "name": "nfts", "type": "address[]"}], + "name": "NFTEnabled", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, {"indexed": true, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}], + "name": "RoleAdminChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, {"indexed": true, "internalType": "address", "name": "sender", "type": "address"}], + "name": "RoleGranted", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, {"indexed": true, "internalType": "address", "name": "sender", "type": "address"}], + "name": "RoleRevoked", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "from", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], + "name": "Transfer", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "address", "name": "teaVaultV2", "type": "address"}], + "name": "UpdateTeaVaultV2", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": false, "internalType": "address", "name": "teaVaultV2", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }], + "name": "WithdrawFromVault", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": true, "internalType": "address", "name": "receiver", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "name": "WithdrawalCanceled", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "caller", "type": "address"}, { + "indexed": true, + "internalType": "uint32", + "name": "cycleIndex", + "type": "uint32" + }, {"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "name": "WithdrawalRequested", + "type": "event" +}, { + "inputs": [], + "name": "AUDITOR_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "SECONDS_IN_A_YEAR", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "owner", "type": "address"}, { + "internalType": "address", + "name": "spender", + "type": "address" + }], + "name": "allowance", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "approve", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "asset", + "outputs": [{"internalType": "address", "name": "assetTokenAddress", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "account", "type": "address"}], + "name": "balanceOf", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], "name": "cancelDeposit", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }], "name": "cancelDepositETH", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], "name": "cancelWithdraw", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], + "name": "claimAndRequestDeposit", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], + "name": "claimAndRequestDepositETH", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "payable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "address", + "name": "_owner", + "type": "address" + }], + "name": "claimAndRequestWithdraw", + "outputs": [{"internalType": "uint256", "name": "shares", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_receiver", "type": "address"}], + "name": "claimOwedAssets", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address payable", "name": "_receiver", "type": "address"}], + "name": "claimOwedAssetsETH", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_receiver", "type": "address"}], + "name": "claimOwedFunds", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}, { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address payable", "name": "_receiver", "type": "address"}], + "name": "claimOwedFundsETH", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}, { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_receiver", "type": "address"}], + "name": "claimOwedShares", + "outputs": [{"internalType": "uint256", "name": "shares", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "address", + "name": "_owner", + "type": "address" + }], + "name": "closePosition", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_receiver", "type": "address"}], + "name": "closePositionAndClaim", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address payable", "name": "_receiver", "type": "address"}], + "name": "closePositionAndClaimETH", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "closePrice", + "outputs": [{"internalType": "uint128", "name": "numerator", "type": "uint128"}, { + "internalType": "uint128", + "name": "denominator", + "type": "uint128" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint32", "name": "", "type": "uint32"}], + "name": "cycleState", + "outputs": [{"internalType": "uint128", "name": "totalFundValue", "type": "uint128"}, { + "internalType": "uint128", + "name": "fundValueAfterRequests", + "type": "uint128" + }, {"internalType": "uint128", "name": "requestedDeposits", "type": "uint128"}, { + "internalType": "uint128", + "name": "convertedDeposits", + "type": "uint128" + }, {"internalType": "uint128", "name": "requestedWithdrawals", "type": "uint128"}, { + "internalType": "uint128", + "name": "convertedWithdrawals", + "type": "uint128" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "decimals", + "outputs": [{"internalType": "uint8", "name": "", "type": "uint8"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + }], + "name": "decreaseAllowance", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_value", "type": "uint256"}], + "name": "depositToVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_value", "type": "uint256"}], + "name": "depositToVaultETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint32", "name": "_cycleIndex", "type": "uint32"}, { + "internalType": "uint128", + "name": "_fundValue", + "type": "uint128" + }, {"internalType": "uint128", "name": "_depositLimit", "type": "uint128"}, { + "internalType": "uint128", + "name": "_withdrawAmount", + "type": "uint128" + }, {"internalType": "uint64", "name": "_cycleStartTimestamp", "type": "uint64"}, { + "internalType": "uint64", + "name": "_fundingLockTimestamp", + "type": "uint64" + }, {"internalType": "bool", "name": "_closeFund", "type": "bool"}], + "name": "enterNextCycle", + "outputs": [{"internalType": "uint256", "name": "platformFee", "type": "uint256"}, { + "internalType": "uint256", + "name": "managerFee", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint32", "name": "_cycleIndex", "type": "uint32"}, { + "internalType": "uint128", + "name": "_fundValue", + "type": "uint128" + }, {"internalType": "uint128", "name": "_depositLimit", "type": "uint128"}, { + "internalType": "uint128", + "name": "_withdrawAmount", + "type": "uint128" + }, {"internalType": "uint64", "name": "_cycleStartTimestamp", "type": "uint64"}, { + "internalType": "uint64", + "name": "_fundingLockTimestamp", + "type": "uint64" + }, {"internalType": "bool", "name": "_closeFund", "type": "bool"}], + "name": "enterNextCycleETH", + "outputs": [{"internalType": "uint256", "name": "platformFee", "type": "uint256"}, { + "internalType": "uint256", + "name": "managerFee", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "feeConfig", + "outputs": [{"internalType": "address", "name": "platformVault", "type": "address"}, { + "internalType": "address", + "name": "managerVault", + "type": "address" + }, {"internalType": "uint24", "name": "platformEntryFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "managerEntryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "platformExitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "managerExitFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "platformPerformanceFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "managerPerformanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "platformManagementFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "managerManagementFee", + "type": "uint24" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "fundConfig", + "outputs": [{ + "internalType": "contract ITeaVaultV2", + "name": "teaVaultV2", + "type": "address" + }, {"internalType": "bool", "name": "disableNFTChecks", "type": "bool"}, { + "internalType": "bool", + "name": "disableDepositing", + "type": "bool" + }, {"internalType": "bool", "name": "disableWithdrawing", "type": "bool"}, { + "internalType": "bool", + "name": "disableCancelDepositing", + "type": "bool" + }, {"internalType": "bool", "name": "disableCancelWithdrawing", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], + "name": "getRoleAdmin", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "globalState", + "outputs": [{"internalType": "uint128", "name": "depositLimit", "type": "uint128"}, { + "internalType": "uint128", + "name": "lockedAssets", + "type": "uint128" + }, {"internalType": "uint32", "name": "cycleIndex", "type": "uint32"}, { + "internalType": "uint64", + "name": "cycleStartTimestamp", + "type": "uint64" + }, {"internalType": "uint64", "name": "fundingLockTimestamp", "type": "uint64"}, { + "internalType": "bool", + "name": "fundClosed", + "type": "bool" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + }], + "name": "increaseAllowance", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "initialPrice", + "outputs": [{"internalType": "uint128", "name": "numerator", "type": "uint128"}, { + "internalType": "uint128", + "name": "denominator", + "type": "uint128" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "name", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "name": "nftEnabled", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint128", "name": "_fundValue", "type": "uint128"}, { + "internalType": "uint64", + "name": "_timestamp", + "type": "uint64" + }], + "name": "previewNextCycle", + "outputs": [{"internalType": "uint256", "name": "withdrawAmount", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], "name": "requestDeposit", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_assets", "type": "uint256"}, { + "internalType": "address", + "name": "_receiver", + "type": "address" + }], "name": "requestDepositETH", "outputs": [], "stateMutability": "payable", "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "address", + "name": "_owner", + "type": "address" + }], "name": "requestWithdraw", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_owner", "type": "address"}], + "name": "requestedFunds", + "outputs": [{"internalType": "uint256", "name": "assets", "type": "uint256"}, { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}, { + "internalType": "address", + "name": "account", + "type": "address" + }], "name": "revokeRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint128", "name": "_depositLimit", "type": "uint128"}], + "name": "setDepositLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bool", "name": "_disableDepositing", "type": "bool"}, { + "internalType": "bool", + "name": "_disableWithdrawing", + "type": "bool" + }, {"internalType": "bool", "name": "_disableCancelDepositing", "type": "bool"}, { + "internalType": "bool", + "name": "_disableCancelWithdrawing", + "type": "bool" + }], "name": "setDisableFunding", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "bool", "name": "_checks", "type": "bool"}], + "name": "setDisableNFTChecks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address[]", "name": "_nfts", "type": "address[]"}], + "name": "setEnabledNFTs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "platformVault", + "type": "address" + }, {"internalType": "address", "name": "managerVault", "type": "address"}, { + "internalType": "uint24", + "name": "platformEntryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerEntryFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformExitFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerExitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformPerformanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerPerformanceFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "platformManagementFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managerManagementFee", "type": "uint24"}], + "internalType": "struct IHighTableVault.FeeConfig", + "name": "_feeConfig", + "type": "tuple" + }], "name": "setFeeConfig", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "uint64", "name": "_fundLockingTimestamp", "type": "uint64"}], + "name": "setFundLockingTimestamp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_teaVaultV2", "type": "address"}], + "name": "setTeaVaultV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], + "name": "supportsInterface", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "symbol", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "totalSupply", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "to", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "transfer", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "from", "type": "address"}, { + "internalType": "address", + "name": "to", + "type": "address" + }, {"internalType": "uint256", "name": "amount", "type": "uint256"}], + "name": "transferFrom", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "", "type": "address"}], + "name": "userState", + "outputs": [{"internalType": "uint128", "name": "requestedDeposits", "type": "uint128"}, { + "internalType": "uint128", + "name": "owedShares", + "type": "uint128" + }, {"internalType": "uint128", "name": "requestedWithdrawals", "type": "uint128"}, { + "internalType": "uint128", + "name": "owedAssets", + "type": "uint128" + }, {"internalType": "uint32", "name": "requestCycleIndex", "type": "uint32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_value", "type": "uint256"}], + "name": "withdrawFromVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_value", "type": "uint256"}], + "name": "withdrawFromVaultETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, {"stateMutability": "payable", "type": "receive"}] + +module.exports = { + TEAHOUSE_VAULT_MANAGED_ABI +} diff --git a/src/adaptors/teahouse-managed/config.ts b/src/adaptors/teahouse-managed/config.ts new file mode 100644 index 0000000000..39364ee92a --- /dev/null +++ b/src/adaptors/teahouse-managed/config.ts @@ -0,0 +1,9 @@ +const TEAHOUSE_VAULT_STAT_API_URL = 'https://vault-api.teahouse.finance'; +const TEAHOUSE_VAULT_CONTENT_API_URL = 'https://vault-content-api.teahouse.finance'; +const TEAHOUSE_WEBSITE_URL = 'https://vault.teahouse.finance'; + +module.exports = { + TEAHOUSE_VAULT_STAT_API_URL, + TEAHOUSE_VAULT_CONTENT_API_URL, + TEAHOUSE_WEBSITE_URL +} diff --git a/src/adaptors/teahouse-managed/index.js b/src/adaptors/teahouse-managed/index.js new file mode 100644 index 0000000000..f5feb790af --- /dev/null +++ b/src/adaptors/teahouse-managed/index.js @@ -0,0 +1,12 @@ +const {topLvl} = require("./utils"); + + +const main = async (timestamp = null) => { + const data = await topLvl(timestamp) + return data; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/teahouse-managed/utils.ts b/src/adaptors/teahouse-managed/utils.ts new file mode 100644 index 0000000000..d39a77094c --- /dev/null +++ b/src/adaptors/teahouse-managed/utils.ts @@ -0,0 +1,255 @@ +const {ethers} = require("ethers"); +const sdk = require('@defillama/sdk') +const utils = require('../utils'); +const {TEAHOUSE_VAULT_STAT_API_URL, TEAHOUSE_VAULT_CONTENT_API_URL, TEAHOUSE_WEBSITE_URL} = require('./config'); +const bn = require('bignumber.js'); +const {TEAHOUSE_VAULT_MANAGED_ABI} = require('./abi'); + + +function generateVaultURL(chainName: string, vaultAddress: string): string { + return `${TEAHOUSE_WEBSITE_URL}/${chainName}/${vaultAddress}`; +} + +async function getManagedVaultData(): Promise { + const contentUrl = `${TEAHOUSE_VAULT_CONTENT_API_URL}/vaults` + let {vaults} = await utils.getData(contentUrl) + const filteredVaults = vaults.filter((el) => { + return (el.isDeFi == false && el.isActive == true) + }).map((el)=>mappingVaultData(el)) + return filteredVaults +} + +function mappingVaultData(vault: any): Vault { + const chain = vault.chain || "" + const contract = vault.share + const address = contract?.address || "" + const shares = vault.share || { + address: "Unknown", + symbol: "Unknown", + decimals: 18 + } + const asset0 = vault.asset0 || { + address: "Unknown", + symbol: "Unknown", + decimals: 18 + } + const strategy = vault.name || "" + const name = vault.name || "" + const vaultMeta = strategy + const url = generateVaultURL(chain, address) + const data = { + address, chain, name, vaultMeta, asset0, url, + shares + } + return data +} + +async function addTVLData(vaults: Vault[]): Promise { + let newVaults = [] + const vaultMap=[]; + const chainMap=new Map(); + vaults.forEach((el) => { + const chain= el.chain + if (!chain) return + if (chainMap.has(chain)){ + const i =chainMap.get(chain) + vaultMap[i].push(el) + }else { + const i = vaultMap.length + vaultMap.push([el]) + chainMap.set(chain,i) + + } + }) + for (let chain of chainMap.keys()){ + const i=chainMap.get(chain) + const filteredVault=vaultMap[i] + const chainVault = await addTvlData(chain,filteredVault) + newVaults.push(...chainVault) + } + return newVaults +} + + +async function addTvlData(chain:string,vaults:Vault[]): Promise { + const newVaults = [] + const vaultAddr=vaults.map((el)=>el.address) + const assetAddr=vaults.map((el)=>el.asset0.address) + const prices = (await utils.getPrices(assetAddr, chain)).pricesByAddress + const tvls = await getAssetTvl(chain,vaultAddr) + for (let j=0;j { + const statUrl = `${TEAHOUSE_VAULT_STAT_API_URL}/vaults/type/managed` + let {vaults: stat} = await utils.getData(statUrl) + return mergeVaultStat(vaults, stat) +} + +function mergeVaultStat(vault: Vault[], stat: any[]): Vault[] { + const newVaults = [] + const vaultMap = new Map(); + vault.forEach((el) => { + const chain = el.chain || "" + //key format: chain:address + const key = `${chain}:${el.address.toLowerCase()}` + vaultMap.set(key, el); + }) + stat.forEach((el) => { + //key format: chain:address + const address = el.address || "" + const chain = el.chain || "" + const key = `${chain}:${address.toLowerCase()}` + if (vaultMap.has(key)) { + newVaults.push(mergeStat(el, vaultMap.get(key))); + } + }) + return newVaults +} + +function mergeStat(stat: any, vault: Vault): Vault { + return { + ...vault, + apy: stat.latestInfo.shareTokenApr, + } +} + +async function makeMulticall(abi: any, addresses: string[], chain: string, params:any[]| undefined| null, options) { + const block = options.block || `latest`; + const data = await sdk.api.abi.multiCall({ + abi, + calls: addresses.map((address,i) => ({ + target: address, + params: params? params[i]:[], + })), chain, block + }); + let outputByArray = [] + let outputByAddress = {} + for (let i = 0; i < data.output.length; i++) { + const key = addresses[i].toLowerCase(); + outputByArray.push(data.output[i].output); + outputByAddress[key] = data.output[i].output; + } + return { + outputByArray: outputByArray, + outputByAddress: outputByAddress + }; +}; + +async function getAssetTvl(chain:string,vaultAddresses:string[]): Promise { + const globalStateFn = TEAHOUSE_VAULT_MANAGED_ABI.find( + (el) => el.name === `globalState` + ) + const globalStates = (await makeMulticall( + globalStateFn, vaultAddresses, chain,null, {})) + .outputByArray + const cycles= globalStates.map((el) => el.cycleIndex-1) + const cycleStateFn = TEAHOUSE_VAULT_MANAGED_ABI.find( + (el) => el.name === `cycleState` + ) + const cycleStates = (await makeMulticall( + cycleStateFn, vaultAddresses, chain,cycles, {})) + .outputByArray + const tvls= cycleStates.map((el) => new bn(el.fundValueAfterRequests || 0)) + return tvls +} + + + + + + + +function convertToPool(vault: Vault): Pool { + return { + pool: `${vault.address}-${vault.chain}`, + chain: vault.chain, + symbol: vault.asset0.symbol, + url: vault.url, + project: 'teahouse-managed', + tvlUsd: vault.tvlUsd, + apyBase: vault.apy / 10000, + apyReward: 0, + underlyingTokens: [vault.asset0.address], + rewardTokens: [], + poolMeta: vault.vaultMeta, + }; +} + +function updateRpcUrl(sdk: any, chain: string, chainId: number, rpcUrl: string) { + const provider = new ethers.providers.StaticJsonRpcProvider( + rpcUrl, {name: chain, chainId: chainId}) + sdk.api.config.setProvider(chain, provider); +} + +async function topLvl(_: number): Promise { + updateRpcUrl(sdk, 'ethereum', 1, "https://cloudflare-eth.com/") + // step 1: get managed vault data + let vaults=await getManagedVaultData() + console.log(`vaults: ${vaults.length}`) + // step 2: add TVL data + vaults=await addTVLData(vaults) + console.log(`vaults: ${vaults.length}`) + // step 3: add apy data + vaults=await addStatsData(vaults) + console.log(`vaults: ${vaults.length}`) + // step 4: convert to pool + const pools = vaults.map((vault) => convertToPool(vault)) + return pools +} + +interface Vault { + address: string; + name: string; + chain: string; + asset0: Token; + share: Token; + url: string; + vaultMeta: string; //other info + tvl:bn; + asset0Price:number; + tvlUsd?: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apy?: number; +} + +interface Token { + symbol: string; + decimals: number; + address: string; +} + +interface Pool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + // optional lending protocol specific fields: + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; // btw [0, 1] +} + +module.exports = { + topLvl +} diff --git a/src/adaptors/teahouse-permissionless/abi.ts b/src/adaptors/teahouse-permissionless/abi.ts new file mode 100644 index 0000000000..acc35168a8 --- /dev/null +++ b/src/adaptors/teahouse-permissionless/abi.ts @@ -0,0 +1,927 @@ +const TEAHOUSE_VAULT_V3_ABI = [{"inputs": [], "stateMutability": "nonpayable", "type": "constructor"}, { + "inputs": [], + "name": "CallerIsNotManager", + "type": "error" +}, { + "inputs": [{"internalType": "uint256", "name": "minAmount", "type": "uint256"}, { + "internalType": "uint256", + "name": "convertedAmount", + "type": "uint256" + }], "name": "InsufficientSwapResult", "type": "error" +}, {"inputs": [], "name": "InvalidCallbackCaller", "type": "error"}, { + "inputs": [], + "name": "InvalidCallbackStatus", + "type": "error" +}, {"inputs": [], "name": "InvalidFeeCap", "type": "error"}, { + "inputs": [], + "name": "InvalidFeePercentage", + "type": "error" +}, { + "inputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], "name": "InvalidPriceSlippage", "type": "error" +}, {"inputs": [], "name": "InvalidShareAmount", "type": "error"}, { + "inputs": [], + "name": "InvalidSwapReceiver", + "type": "error" +}, {"inputs": [], "name": "InvalidSwapToken", "type": "error"}, { + "inputs": [], + "name": "InvalidTokenOrder", + "type": "error" +}, {"inputs": [], "name": "PoolNotInitialized", "type": "error"}, { + "inputs": [], + "name": "PositionDoesNotExist", + "type": "error" +}, {"inputs": [], "name": "PositionLengthExceedsLimit", "type": "error"}, { + "inputs": [], + "name": "SwapInZeroLiquidityRegion", + "type": "error" +}, {"inputs": [], "name": "TransactionExpired", "type": "error"}, { + "inputs": [], + "name": "ZeroLiquidity", + "type": "error" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "pool", "type": "address"}, { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, {"indexed": false, "internalType": "int24", "name": "tickUpper", "type": "int24"}, { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, {"indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "name": "AddLiquidity", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, {"indexed": false, "internalType": "address", "name": "newAdmin", "type": "address"}], + "name": "AdminChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "owner", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], + "name": "Approval", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "beacon", "type": "address"}], + "name": "BeaconUpgraded", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "pool", "type": "address"}, { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, {"indexed": false, "internalType": "int24", "name": "tickUpper", "type": "int24"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256"}], + "name": "Collect", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "pool", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount0", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "feeAmount1", "type": "uint256"}], + "name": "CollectSwapFees", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "shareOwner", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "feeAmount0", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "feeAmount1", + "type": "uint256" + }], + "name": "DepositShares", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, { + "components": [{"internalType": "address", "name": "vault", "type": "address"}, { + "internalType": "uint24", + "name": "entryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "exitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "performanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managementFee", "type": "uint24"}], + "indexed": false, + "internalType": "struct ITeaVaultV3Pair.FeeConfig", + "name": "feeConfig", + "type": "tuple" + }], + "name": "FeeConfigChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": false, "internalType": "uint8", "name": "version", "type": "uint8"}], + "name": "Initialized", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256"}], + "name": "ManagementFeeCollected", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "newManager", + "type": "address" + }], + "name": "ManagerChanged", + "type": "event" +}, { + "anonymous": false, + "inputs": [{ + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, {"indexed": true, "internalType": "address", "name": "newOwner", "type": "address"}], + "name": "OwnershipTransferred", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "pool", "type": "address"}, { + "indexed": false, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, {"indexed": false, "internalType": "int24", "name": "tickUpper", "type": "int24"}, { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, {"indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "name": "RemoveLiquidity", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "bool", "name": "zeroForOne", "type": "bool"}, { + "indexed": true, + "internalType": "bool", + "name": "exactInput", + "type": "bool" + }, {"indexed": false, "internalType": "uint256", "name": "amountIn", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }], + "name": "Swap", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "teaVaultAddress", "type": "address"}], + "name": "TeaVaultV3PairCreated", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "from", "type": "address"}, { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, {"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}], + "name": "Transfer", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "implementation", "type": "address"}], + "name": "Upgraded", + "type": "event" +}, { + "anonymous": false, + "inputs": [{"indexed": true, "internalType": "address", "name": "shareOwner", "type": "address"}, { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, {"indexed": false, "internalType": "uint256", "name": "feeShares", "type": "uint256"}], + "name": "WithdrawShares", + "type": "event" +}, { + "inputs": [], + "name": "DECIMALS_MULTIPLIER", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "FEE_CAP", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "FEE_MULTIPLIER", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "SECONDS_IN_A_YEAR", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "_tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "_tickUpper", + "type": "int24" + }, {"internalType": "uint128", "name": "_liquidity", "type": "uint128"}, { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amount1Min", "type": "uint256"}, { + "internalType": "uint64", + "name": "_deadline", + "type": "uint64" + }], + "name": "addLiquidity", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "allPositionInfo", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, {"internalType": "uint256", "name": "fee0", "type": "uint256"}, { + "internalType": "uint256", + "name": "fee1", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "owner", "type": "address"}, { + "internalType": "address", + "name": "spender", + "type": "address" + }], + "name": "allowance", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "approve", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "assetToken0", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "assetToken1", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_manager", "type": "address"}], + "name": "assignManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "_router1Inch", "type": "address"}], + "name": "assignRouter1Inch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "account", "type": "address"}], + "name": "balanceOf", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "clipperExchange", "type": "address"}, { + "internalType": "address", + "name": "srcToken", + "type": "address" + }, {"internalType": "address", "name": "dstToken", "type": "address"}, { + "internalType": "uint256", + "name": "inputAmount", + "type": "uint256" + }, {"internalType": "uint256", "name": "outputAmount", "type": "uint256"}, { + "internalType": "uint256", + "name": "goodUntil", + "type": "uint256" + }, {"internalType": "bytes32", "name": "r", "type": "bytes32"}, { + "internalType": "bytes32", + "name": "vs", + "type": "bytes32" + }], + "name": "clipperSwap", + "outputs": [{"internalType": "uint256", "name": "returnAmount", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "collectAllSwapFee", + "outputs": [{"internalType": "uint128", "name": "amount0", "type": "uint128"}, { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "collectManagementFee", + "outputs": [{"internalType": "uint256", "name": "collectedShares", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "_tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "_tickUpper", + "type": "int24" + }], + "name": "collectPositionSwapFee", + "outputs": [{"internalType": "uint128", "name": "amount0", "type": "uint128"}, { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "decimals", + "outputs": [{"internalType": "uint8", "name": "", "type": "uint8"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + }], + "name": "decreaseAllowance", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "uint256", + "name": "_amount0Max", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amount1Max", "type": "uint256"}], + "name": "deposit", + "outputs": [{"internalType": "uint256", "name": "depositedAmount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "depositedAmount1", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "estimatedValueInToken0", + "outputs": [{"internalType": "uint256", "name": "value0", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "estimatedValueInToken1", + "outputs": [{"internalType": "uint256", "name": "value1", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "feeConfig", + "outputs": [{"internalType": "address", "name": "vault", "type": "address"}, { + "internalType": "uint24", + "name": "entryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "exitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "performanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managementFee", "type": "uint24"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getAllPositions", + "outputs": [{ + "components": [{ + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, {"internalType": "int24", "name": "tickUpper", "type": "int24"}, { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }], "internalType": "struct ITeaVaultV3Pair.Position[]", "name": "results", "type": "tuple[]" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, {"internalType": "uint128", "name": "liquidity", "type": "uint128"}], + "name": "getAmountsForLiquidity", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, {"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "name": "getLiquidityForAmounts", + "outputs": [{"internalType": "uint128", "name": "liquidity", "type": "uint128"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getPoolInfo", + "outputs": [{"internalType": "address", "name": "", "type": "address"}, { + "internalType": "address", + "name": "", + "type": "address" + }, {"internalType": "uint8", "name": "", "type": "uint8"}, { + "internalType": "uint8", + "name": "", + "type": "uint8" + }, {"internalType": "uint24", "name": "", "type": "uint24"}, { + "internalType": "uint160", + "name": "", + "type": "uint160" + }, {"internalType": "int24", "name": "", "type": "int24"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getToken0Balance", + "outputs": [{"internalType": "uint256", "name": "amount", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "getToken1Balance", + "outputs": [{"internalType": "uint256", "name": "amount", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "spender", "type": "address"}, { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + }], + "name": "increaseAllowance", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "string", "name": "_name", "type": "string"}, { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, {"internalType": "address", "name": "_factory", "type": "address"}, { + "internalType": "address", + "name": "_token0", + "type": "address" + }, {"internalType": "address", "name": "_token1", "type": "address"}, { + "internalType": "uint24", + "name": "_feeTier", + "type": "uint24" + }, {"internalType": "uint8", "name": "_decimalOffset", "type": "uint8"}, { + "internalType": "uint24", + "name": "_feeCap", + "type": "uint24" + }, { + "components": [{"internalType": "address", "name": "vault", "type": "address"}, { + "internalType": "uint24", + "name": "entryFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "exitFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "performanceFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "managementFee", "type": "uint24"}], + "internalType": "struct ITeaVaultV3Pair.FeeConfig", + "name": "_feeConfig", + "type": "tuple" + }, {"internalType": "address", "name": "_owner", "type": "address"}], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "lastCollectManagementFee", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "manager", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "bytes[]", "name": "data", "type": "bytes[]"}], + "name": "multicall", + "outputs": [{"internalType": "bytes[]", "name": "results", "type": "bytes[]"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "name", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "owner", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "pool", + "outputs": [{"internalType": "contract IUniswapV3Pool", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_index", "type": "uint256"}], + "name": "positionInfo", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, {"internalType": "uint256", "name": "fee0", "type": "uint256"}, { + "internalType": "uint256", + "name": "fee1", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "_tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "_tickUpper", + "type": "int24" + }], + "name": "positionInfo", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, {"internalType": "uint256", "name": "fee0", "type": "uint256"}, { + "internalType": "uint256", + "name": "fee1", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "name": "positions", + "outputs": [{"internalType": "int24", "name": "tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, {"internalType": "uint128", "name": "liquidity", "type": "uint128"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "proxiableUUID", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "int24", "name": "_tickLower", "type": "int24"}, { + "internalType": "int24", + "name": "_tickUpper", + "type": "int24" + }, {"internalType": "uint128", "name": "_liquidity", "type": "uint128"}, { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amount1Min", "type": "uint256"}, { + "internalType": "uint64", + "name": "_deadline", + "type": "uint64" + }], + "name": "removeLiquidity", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "router1Inch", + "outputs": [{"internalType": "contract IGenericRouter1Inch", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{ + "components": [{ + "internalType": "address", + "name": "vault", + "type": "address" + }, {"internalType": "uint24", "name": "entryFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "exitFee", + "type": "uint24" + }, {"internalType": "uint24", "name": "performanceFee", "type": "uint24"}, { + "internalType": "uint24", + "name": "managementFee", + "type": "uint24" + }], "internalType": "struct ITeaVaultV3Pair.FeeConfig", "name": "_feeConfig", "type": "tuple" + }], "name": "setFeeConfig", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{"internalType": "bool", "name": "_zeroForOne", "type": "bool"}, { + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + }], "name": "simulateSwapInputSingleInternal", "outputs": [], "stateMutability": "nonpayable", "type": "function" +}, { + "inputs": [{ + "internalType": "address", + "name": "executor", + "type": "address" + }, { + "components": [{"internalType": "address", "name": "srcToken", "type": "address"}, { + "internalType": "address", + "name": "dstToken", + "type": "address" + }, { + "internalType": "address payable", + "name": "srcReceiver", + "type": "address" + }, {"internalType": "address payable", "name": "dstReceiver", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, {"internalType": "uint256", "name": "minReturnAmount", "type": "uint256"}, { + "internalType": "uint256", + "name": "flags", + "type": "uint256" + }], "internalType": "struct IGenericRouter1Inch.SwapDescription", "name": "desc", "type": "tuple" + }, {"internalType": "bytes", "name": "permit", "type": "bytes"}, { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }], + "name": "swap", + "outputs": [{"internalType": "uint256", "name": "returnAmount", "type": "uint256"}, { + "internalType": "uint256", + "name": "spentAmount", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bool", "name": "_zeroForOne", "type": "bool"}, { + "internalType": "uint256", + "name": "_amountIn", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amountOutMin", "type": "uint256"}, { + "internalType": "uint160", + "name": "_minPriceInSqrtPriceX96", + "type": "uint160" + }, {"internalType": "uint64", "name": "_deadline", "type": "uint64"}], + "name": "swapInputSingle", + "outputs": [{"internalType": "uint256", "name": "amountOut", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "bool", "name": "_zeroForOne", "type": "bool"}, { + "internalType": "uint256", + "name": "_amountOut", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amountInMax", "type": "uint256"}, { + "internalType": "uint160", + "name": "_maxPriceInSqrtPriceX96", + "type": "uint160" + }, {"internalType": "uint64", "name": "_deadline", "type": "uint64"}], + "name": "swapOutputSingle", + "outputs": [{"internalType": "uint256", "name": "amountIn", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [], + "name": "symbol", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [], + "name": "totalSupply", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "to", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }], + "name": "transfer", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "from", "type": "address"}, { + "internalType": "address", + "name": "to", + "type": "address" + }, {"internalType": "uint256", "name": "amount", "type": "uint256"}], + "name": "transferFrom", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "newOwner", "type": "address"}], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_amount0Owed", "type": "uint256"}, { + "internalType": "uint256", + "name": "_amount1Owed", + "type": "uint256" + }, {"internalType": "bytes", "name": "_data", "type": "bytes"}], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "amount", "type": "uint256"}, { + "internalType": "uint256", + "name": "minReturn", + "type": "uint256" + }, {"internalType": "uint256[]", "name": "pools", "type": "uint256[]"}], + "name": "uniswapV3Swap", + "outputs": [{"internalType": "uint256", "name": "returnAmount", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "int256", "name": "_amount0Delta", "type": "int256"}, { + "internalType": "int256", + "name": "_amount1Delta", + "type": "int256" + }, {"internalType": "bytes", "name": "_data", "type": "bytes"}], + "name": "uniswapV3SwapCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "srcToken", "type": "address"}, { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, {"internalType": "uint256", "name": "minReturn", "type": "uint256"}, { + "internalType": "uint256[]", + "name": "pools", + "type": "uint256[]" + }], + "name": "unoswap", + "outputs": [{"internalType": "uint256", "name": "returnAmount", "type": "uint256"}], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "newImplementation", "type": "address"}], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" +}, { + "inputs": [{"internalType": "address", "name": "newImplementation", "type": "address"}, { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }], "name": "upgradeToAndCall", "outputs": [], "stateMutability": "payable", "type": "function" +}, { + "inputs": [], + "name": "vaultAllUnderlyingAssets", + "outputs": [{"internalType": "uint256", "name": "amount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }], + "stateMutability": "view", + "type": "function" +}, { + "inputs": [{"internalType": "uint256", "name": "_shares", "type": "uint256"}, { + "internalType": "uint256", + "name": "_amount0Min", + "type": "uint256" + }, {"internalType": "uint256", "name": "_amount1Min", "type": "uint256"}], + "name": "withdraw", + "outputs": [{"internalType": "uint256", "name": "withdrawnAmount0", "type": "uint256"}, { + "internalType": "uint256", + "name": "withdrawnAmount1", + "type": "uint256" + }], + "stateMutability": "nonpayable", + "type": "function" +}] + +module.exports = { + TEAHOUSE_VAULT_V3_ABI +} diff --git a/src/adaptors/teahouse-permissionless/config.ts b/src/adaptors/teahouse-permissionless/config.ts new file mode 100644 index 0000000000..39364ee92a --- /dev/null +++ b/src/adaptors/teahouse-permissionless/config.ts @@ -0,0 +1,9 @@ +const TEAHOUSE_VAULT_STAT_API_URL = 'https://vault-api.teahouse.finance'; +const TEAHOUSE_VAULT_CONTENT_API_URL = 'https://vault-content-api.teahouse.finance'; +const TEAHOUSE_WEBSITE_URL = 'https://vault.teahouse.finance'; + +module.exports = { + TEAHOUSE_VAULT_STAT_API_URL, + TEAHOUSE_VAULT_CONTENT_API_URL, + TEAHOUSE_WEBSITE_URL +} diff --git a/src/adaptors/teahouse-permissionless/data.json b/src/adaptors/teahouse-permissionless/data.json new file mode 100644 index 0000000000..d819c44beb --- /dev/null +++ b/src/adaptors/teahouse-permissionless/data.json @@ -0,0 +1,380 @@ +[ + { + "address": "0x1546B2aE60a2aDe3F8F1a9276c198e8f52212c05", + "chain": "arbitrum", + "name": "USDs-USDC.e 0.05%", + "vaultMeta": "0.05%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0xd74f5255d557944cf7dd0e45ff521520002d5748", + "symbol": "USDs", + "decimals": 18, + "tvl": "1171200315051802504733", + "shareTokenApr": 63602 + }, + { + "name": "token1", + "address": "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", + "symbol": "USDC.e", + "decimals": 6, + "tvl": "1173606372", + "shareTokenApr": 66371 + } + ], + "url": "https://vault.teahouse.finance/arbitrum/0x1546B2aE60a2aDe3F8F1a9276c198e8f52212c05", + "isAsset0Main": false, + "shareDecimals": "30", + "rewardTokens": [] + }, + { + "address": "0x433821D0653548482Fa22479721db15fbcf303a3", + "chain": "arbitrum", + "name": "WBTC-WETH 0.05%", + "vaultMeta": "0.05%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", + "symbol": "WBTC", + "decimals": 8, + "tvl": "118973994", + "shareTokenApr": -236192 + }, + { + "name": "token1", + "address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "symbol": "WETH", + "decimals": 18, + "tvl": "20981591633338679316", + "shareTokenApr": -8739 + } + ], + "url": "https://vault.teahouse.finance/arbitrum/0x433821D0653548482Fa22479721db15fbcf303a3", + "isAsset0Main": false, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0x99c2901d2883F8D295A989544f118e31eC21823e", + "chain": "arbitrum", + "name": "wstETH-WETH 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x5979D7b546E38E414F7E9822514be443A4800529", + "symbol": "wstETH", + "decimals": 18, + "tvl": "66361762570823551324", + "shareTokenApr": 48019 + }, + { + "name": "token1", + "address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "symbol": "WETH", + "decimals": 18, + "tvl": "76852250423235416280", + "shareTokenApr": 85074 + } + ], + "url": "https://vault.teahouse.finance/arbitrum/0x99c2901d2883F8D295A989544f118e31eC21823e", + "isAsset0Main": false, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0xB38e48B8Bc33CD65551BdaC8d954801D56625eeC", + "chain": "arbitrum", + "name": "wstETH-WETH 0.3%", + "vaultMeta": "0.30%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x5979D7b546E38E414F7E9822514be443A4800529", + "symbol": "wstETH", + "decimals": 18, + "tvl": "8897261648767841842", + "shareTokenApr": 73584 + }, + { + "name": "token1", + "address": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "symbol": "WETH", + "decimals": 18, + "tvl": "10301383897521686232", + "shareTokenApr": 113156 + } + ], + "url": "https://vault.teahouse.finance/arbitrum/0xB38e48B8Bc33CD65551BdaC8d954801D56625eeC", + "isAsset0Main": false, + "shareDecimals": "30", + "rewardTokens": [] + }, + { + "address": "0xB9Fe0EC178163a66f2BAf8eD97E057964cCaE876", + "chain": "arbitrum", + "name": "USDC-USDC.e 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + "symbol": "USDC", + "decimals": 6, + "tvl": "257135583840", + "shareTokenApr": 65431 + }, + { + "name": "token1", + "address": "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", + "symbol": "USDC.e", + "decimals": 6, + "tvl": "257116453354", + "shareTokenApr": 65215 + } + ], + "url": "https://vault.teahouse.finance/arbitrum/0xB9Fe0EC178163a66f2BAf8eD97E057964cCaE876", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0x07811284e36fDc45f65cd56FC7c6929855d6A0cc", + "chain": "boba", + "name": "USDC-BOBA 0.05%", + "vaultMeta": "0.05%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc", + "symbol": "USDC", + "decimals": 6, + "tvl": "151211551801", + "shareTokenApr": -30090 + }, + { + "name": "token1", + "address": "0xa18bf3994c0cc6e3b63ac420308e5383f53120d7", + "symbol": "BOBA", + "decimals": 18, + "tvl": "386982783246078397971107", + "shareTokenApr": -1612660 + } + ], + "url": "https://vault.teahouse.finance/boba/0x07811284e36fDc45f65cd56FC7c6929855d6A0cc", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [ + { + "address": "0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7", + "chain": "boba", + "decimals": 18, + "rewardBook": { + "address": "0x7d28E4f0dd90216c3f8B8E101a7169a604626482", + "endTime": "1721491200", + "startTime": "1706457600", + "totalReward": "480000000000000000000000" + }, + "symbol": "BOBA", + "type": "Erc20" + } + ] + }, + { + "address": "0x216d3e7520B09605B7c4243b59aD02Cc6E052F52", + "chain": "boba", + "name": "USDC-WETH 0.05%", + "vaultMeta": "0.05%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x66a2A913e447d6b4BF33EFbec43aAeF87890FBbc", + "symbol": "USDC", + "decimals": 6, + "tvl": "202645796804", + "shareTokenApr": -16336 + }, + { + "name": "token1", + "address": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "symbol": "WETH", + "decimals": 18, + "tvl": "54726702564651441056", + "shareTokenApr": -1037110 + } + ], + "url": "https://vault.teahouse.finance/boba/0x216d3e7520B09605B7c4243b59aD02Cc6E052F52", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [ + { + "address": "0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7", + "chain": "boba", + "decimals": 18, + "rewardBook": { + "address": "0xF2Beec0d7dEB5416C750AE41bFD2309c9072494B", + "endTime": "1721491200", + "startTime": "1706457600", + "totalReward": "260000000000000000000000" + }, + "symbol": "BOBA", + "type": "Erc20" + } + ] + }, + { + "address": "0xB67A8Af68207cceEaD014b6ceFA3Fc40BfBBBD0e", + "chain": "boba", + "name": "WBTC-WETH 0.3%", + "vaultMeta": "0.3%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0xdc0486f8bf31df57a952bcd3c1d3e166e3d9ec8b", + "symbol": "WBTC", + "decimals": 8, + "tvl": "720807894", + "shareTokenApr": -149470 + }, + { + "name": "token1", + "address": "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + "symbol": "WETH", + "decimals": 18, + "tvl": "125468752993052486543", + "shareTokenApr": 16534 + } + ], + "url": "https://vault.teahouse.finance/boba/0xB67A8Af68207cceEaD014b6ceFA3Fc40BfBBBD0e", + "isAsset0Main": false, + "shareDecimals": "18", + "rewardTokens": [ + { + "address": "0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7", + "chain": "boba", + "decimals": 18, + "rewardBook": { + "address": "0x74f03bd9A803424974D6526Ed7200777c45d5B74", + "endTime": "1721491200", + "startTime": "1706457600", + "totalReward": "240000000000000000000000" + }, + "symbol": "BOBA", + "type": "Erc20" + } + ] + }, + { + "address": "0x878aD0bD8DB80A8C6Cc650EdEEd4B9941b571c5F", + "chain": "mantle", + "name": "USDC-USDT 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9", + "symbol": "USDC", + "decimals": 6, + "tvl": "34030784019", + "shareTokenApr": 16341 + }, + { + "name": "token1", + "address": "0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE", + "symbol": "USDT", + "decimals": 6, + "tvl": "34013359470", + "shareTokenApr": 14411 + } + ], + "url": "https://vault.teahouse.finance/mantle/0x878aD0bD8DB80A8C6Cc650EdEEd4B9941b571c5F", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0x199044E2799cf9099B1d84B29A09f8ff23D00391", + "chain": "optimism", + "name": "USDC-USDC.e 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", + "symbol": "USDC", + "decimals": 6, + "tvl": "168518365240", + "shareTokenApr": 111750 + }, + { + "name": "token1", + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "symbol": "USDC.e", + "decimals": 6, + "tvl": "168548289037", + "shareTokenApr": 111604 + } + ], + "url": "https://vault.teahouse.finance/optimism/0x199044E2799cf9099B1d84B29A09f8ff23D00391", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0xF31900132dFf544Cfe536e76C38a357FF08183D9", + "chain": "optimism", + "name": "USDC.e-sUSD 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "symbol": "USDC.e", + "decimals": 6, + "tvl": "20253791635", + "shareTokenApr": 16359 + }, + { + "name": "token1", + "address": "0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9", + "symbol": "sUSD", + "decimals": 18, + "tvl": "20271831023514689415089", + "shareTokenApr": 12161 + } + ], + "url": "https://vault.teahouse.finance/optimism/0xF31900132dFf544Cfe536e76C38a357FF08183D9", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [] + }, + { + "address": "0x1546B2aE60a2aDe3F8F1a9276c198e8f52212c05", + "chain": "polygon", + "name": "USDC.e-agEUR 0.01%", + "vaultMeta": "0.01%", + "underlyingTokens": [ + { + "name": "token0", + "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", + "symbol": "USDC.e", + "decimals": 6, + "tvl": "7468574611", + "shareTokenApr": 50078 + }, + { + "name": "token1", + "address": "0xE0B52e49357Fd4DAf2c15e02058DCE6BC0057db4", + "symbol": "agEUR", + "decimals": 18, + "tvl": "6867465452242839351424", + "shareTokenApr": 66631 + } + ], + "url": "https://vault.teahouse.finance/polygon/0x1546B2aE60a2aDe3F8F1a9276c198e8f52212c05", + "isAsset0Main": true, + "shareDecimals": "18", + "rewardTokens": [] + } +] diff --git a/src/adaptors/teahouse-permissionless/index.js b/src/adaptors/teahouse-permissionless/index.js new file mode 100644 index 0000000000..f5feb790af --- /dev/null +++ b/src/adaptors/teahouse-permissionless/index.js @@ -0,0 +1,12 @@ +const {topLvl} = require("./utils"); + + +const main = async (timestamp = null) => { + const data = await topLvl(timestamp) + return data; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/teahouse-permissionless/utils.ts b/src/adaptors/teahouse-permissionless/utils.ts new file mode 100644 index 0000000000..8338785a81 --- /dev/null +++ b/src/adaptors/teahouse-permissionless/utils.ts @@ -0,0 +1,388 @@ +const {ethers} = require("ethers"); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const {TEAHOUSE_VAULT_STAT_API_URL, TEAHOUSE_VAULT_CONTENT_API_URL, TEAHOUSE_WEBSITE_URL} = require('./config'); +const bn = require('bignumber.js'); +const {TEAHOUSE_VAULT_V3_ABI} = require('./abi'); +const VAULT_DATA = require('./data.json'); + + +const interval = 24 * 60 * 60 * 7 + +function generateVaultURL(chainName: string, vaultAddress: string): string { + return `${TEAHOUSE_WEBSITE_URL}/${chainName}/${vaultAddress}`; +} + +async function getVaultData(type: string): Promise { + const statUrl = `${TEAHOUSE_VAULT_STAT_API_URL}/vaults/type/${type}` + let {vaults: stats} = await utils.getData(statUrl) + const vaults = await addVaultInfo(stats) + return vaults +} + +async function addVaultInfo(stats: any[]): Promise { + const vaultMap = new Map(); + stats.forEach((el) => { + const chain = el.network || "" + //key format: chain:address + const key = `${chain}:${el.address}` + vaultMap.set(key, el); + }) + const contentUrl = `${TEAHOUSE_VAULT_CONTENT_API_URL}/vaults` + let infoList = []; + let {vaults} = await utils.getData(contentUrl) + vaults.forEach((el) => { + //key format: chain:address + const address = el.share?.address || "" + const chain = el.chain || "" + const key = `${chain}:${address}` + if (vaultMap.has(key)) { + infoList.push(mergeToVault(el, vaultMap.get(key))); + } + }); + return infoList +} + +function mergeToVault(info: any, stat: any): Vault { + const chain = info.chain || "" + const contract = info.share + const address = contract?.address || "" + const name = info.name || "" + const vaultMeta = info.feeTier || "" + const url = generateVaultURL(chain, address) + const shareDecimals = new bn(contract?.decimals || 0) + const tokens = [] + let rewardTokens = [] + if (stat.latestInfo?.token0) + tokens.push(getTokenData("0", info, stat)) + if (stat.latestInfo?.token1) + tokens.push(getTokenData("1", info, stat)) + if (info.rewardTokens){ + rewardTokens=info.rewardTokens.map((el)=>({ + address:el.address, + chain:chain, + decimals:el.decimals, + rewardBook:el.rewardBook, + symbol:el.symbol, + type:el.type + })) + }else { + rewardTokens=[] + } + const data = { + address, chain, name, vaultMeta, underlyingTokens: tokens, url, + isAsset0Main: info.isAsset0Main, shareDecimals,rewardTokens:rewardTokens + } + return data +} + +function getTokenData(num: string, info: any, stat: any): UnderlyingToken { + const asset = `asset${num}` + const tokenInfo = info[asset] || {} + const statInfo = stat.latestInfo || {} + const token = `token${num}` + const tokenStat = statInfo[token] || {} + const data = { + name: token, + address: tokenInfo.address || "", + symbol: tokenInfo.symbol || "", + decimals: tokenInfo.decimals || 0, + tvl: tokenStat.tvl || "0", + shareTokenApr: tokenStat.shareTokenApr || 0, + } + return data +} + +function getUnderlyingToken(name: string, vault: Vault): UnderlyingToken { + const token = vault.underlyingTokens.find((el) => el.name === name) + return token +} + +function updateRpcUrl(sdk: any, chain: string, chainId: number, rpcUrl: string) { + const provider = new ethers.providers.StaticJsonRpcProvider( + rpcUrl, {name: chain, chainId: chainId}) + sdk.api.config.setProvider(chain, provider); +} + +async function makeCall(abi: any, address: string, chain: string, params = null, options) { + const block = options.block || `latest`; + console.log(`block: ${block}`, `chain: ${chain}`, `address: ${address}`, `params: ${params}`); + console.log(`abi: ${JSON.stringify(abi)}`); + const data = await sdk.api.abi.call({ + abi, + target: address, + params, + // calls: addresses.map((address) => ({ + // target: address, + // params, + // })), + chain, block + }); + // let outputByArray = [] + // let outputByAddress = {} + // for (let i = 0; i < data.output.length; i++) { + // const key = addresses[i].toLowerCase(); + // outputByArray.push(data.output[i].output); + // outputByAddress[key] = data.output[i].output; + // } + return data.output +}; + + +async function getLiquidityData(vault: Vault, block?: number): Promise<{ + tvl: bn, shareSupply: bn +}> { + const chain = vault.chain + const estimatedFn = `estimatedValueInToken${vault.isAsset0Main ? "0" : "1"}` + const estimatedFnABI = TEAHOUSE_VAULT_V3_ABI.find( + (el) => el.name === estimatedFn + ) + const tvl = (await makeCall( + estimatedFnABI, vault.address, chain, null, {block: block})) + const supplyFnABI = TEAHOUSE_VAULT_V3_ABI.find( + (el) => el.name === `totalSupply` + ) + const shareSupply = (await makeCall( + supplyFnABI, vault.address, chain, null, {block: block})) + return { + tvl: new bn(tvl || 0), + shareSupply: new bn(shareSupply || 0) + } +} + +async function searchInterval(start: number, end: number, minInterval: number, check: (x: number) => Promise): Promise { + if (end <= start + minInterval) return -1 + const mid = Math.floor((start + end) / 2) + if (await check(mid)) { + return mid + } else { + return searchInterval(mid, end, minInterval, check) + } + +} + +async function checkVaultSupply(vault: Vault, time: number): Promise { + const [block] = await utils.getBlocksByTime([time], vault.chain) + const supplyFnABI = TEAHOUSE_VAULT_V3_ABI.find( + (el) => el.name === `totalSupply` + ) + const shareSupply = (await makeCall( + supplyFnABI, vault.address, vault.chain, null, {block: block})) + const supply = new bn(shareSupply || 0) + if (supply?.gt(0)) return true + return false +} + +async function addLiquidityData(vault: Vault, interval: number): Promise { + const chain = vault.chain + const tokenName = vault.isAsset0Main ? "token0" : "token1" + const token = getUnderlyingToken(tokenName, vault) + let rewardTokens = vault.rewardTokens; + if (rewardTokens.length) { + rewardTokens = rewardTokens.filter( + (t) => new Date(+t.rewardBook.endTime * 1000) > new Date() + ); + } + const { + tvl, shareSupply + } = await getLiquidityData(vault) + const before = (Math.floor(Date.now() / 1000)) - interval + const [blockBefore] = await utils.getBlocksByTime([before], chain) + const { + tvl: tvlBefore, shareSupply: shareSupplyBefore + } = await getLiquidityData(vault, blockBefore) + const prices = (await utils.getPrices([token.address], chain)).pricesByAddress + const tokenKey = token.address.toLowerCase() + const tokenDecimals = new bn(10).pow(token.decimals) + const tvlUsd = new bn(tvl || 0).multipliedBy(prices[tokenKey]).div(tokenDecimals) + const rewardApy = await getRewardTokenApy(chain,rewardTokens,tvlUsd) + vault.tvlUsd = tvlUsd + vault.tvl = new bn(tvl || 0) + vault.tvlBefore = new bn(tvlBefore || 0) + vault.shareSupply = new bn(shareSupply || 0) + vault.shareSupplyBefore = new bn(shareSupplyBefore || 0) + vault.rewardApy = rewardApy + return vault +} + +async function getRewardTokenApy(chain:string,rewardTokens:RewardToken[],tvlUsd:bn):Promise{ + if (rewardTokens.length===0) return 0 + const addresses= rewardTokens.map((el)=>el.address.toLowerCase()) + const prices = (await utils.getPrices(addresses, chain)).pricesByAddress + const totalApr = rewardTokens.reduce((acc,el)=>{ + const rewardBook = el.rewardBook + const reward = new bn(rewardBook.totalReward) + const totalRewardUsd = reward.multipliedBy(prices[el.address.toLowerCase()]).div(new bn(10).pow(el.decimals)) + const apy = totalRewardUsd + .div(Number(rewardBook.endTime)-Number(rewardBook.startTime)) + .multipliedBy(365*24*60*60) + .div(tvlUsd).multipliedBy(100) + return acc.plus(apy) + },new bn(0)) + return totalApr.toNumber() +} + +async function updateBeforeLiquidityData(vault: Vault, time: number): Promise { + const chain = vault.chain + const [blockBefore] = await utils.getBlocksByTime([time], chain) + const { + tvl: tvlBefore, shareSupply: shareSupplyBefore + } = await getLiquidityData(vault, blockBefore) + vault.tvlBefore = new bn(tvlBefore || 0) + vault.shareSupplyBefore = new bn(shareSupplyBefore || 0) + return vault +} + + +function calculateSharePrice(tvl: bn, supply: bn, decimals: bn): bn { + if (supply.isZero()) { + return new bn(0) + } + const price = tvl.multipliedBy(decimals).dividedBy(supply) + return price +} + +function calculateAPY(price: bn, priceBefore: bn, interval: number): number { + if (priceBefore.isZero()) { + return 0 + } + const diff = price.minus(priceBefore) + const diffPercent = diff.dividedBy(priceBefore) + const diffPercentYear = diffPercent.dividedBy(interval).multipliedBy(365 * 24 * 60 * 60) + return diffPercentYear +} + +function convertToPool(vault: Vault): Promise { + const tokens = vault.underlyingTokens.map((el) => el.address) + const rewardTokens = vault.rewardTokens.map((el) => el.address) + const pool = { + pool: `${vault.address}-${vault.chain}`, + chain: vault.chain, + symbol: vault.name, + url: vault.url, + project: 'teahouse-permissionless', + tvlUsd: vault.tvlUsd.toNumber(), + apyBase: vault.apy, + apyReward: vault.rewardApy, + underlyingTokens: tokens, + rewardTokens: rewardTokens, + poolMeta: vault.vaultMeta, + } + return pool; +} + +function getVaultData2(): Promise { + return VAULT_DATA +} + +async function topLvl(_: number): Promise { + // step 1: get vault data + // const vaultType = 'permissionless' + // const vaults = await getVaultData(vaultType) + const vaults = getVaultData2() + const interval = 24 * 60 * 60 + updateRpcUrl(sdk, 'arbitrum', 42161, "https://rpc.ankr.com/arbitrum") + updateRpcUrl(sdk, 'boba', 288, "https://lightning-replica.boba.network/") + updateRpcUrl(sdk, 'mantle', 5000, "https://rpc.mantle.xyz/") + const pools = [] + + for (let vault of vaults) { + //step 2: get TVL and Share Supply + vault = await addLiquidityData(vault, interval) + const decimals = new bn(10).pow(vault.shareDecimals) + //step 3: if TVL is 0, update the start time + // if (!(vault.shareSupplyBefore?.gt(0))) { + // const end = Math.floor(Date.now() / 1000) + // const start = end - interval + // const minInterval = 60 * 60 * 24 + // const check = async (x: number) => { + // return await checkVaultSupply(vault, x) + // } + // const newStart = await searchInterval(start, end, minInterval, check) + // if (newStart === -1) continue + // vault = await updateBeforeLiquidityData(vault, newStart) + // } + //step 4: calculate share token price + const sharePrice = calculateSharePrice(vault.tvl, vault.shareSupply, decimals) + const sharePriceBefore = calculateSharePrice(vault.tvlBefore, vault.shareSupplyBefore, decimals) + //step 5: calculate apy + const apy = calculateAPY(sharePrice, sharePriceBefore, interval) + vault.apy = apy * 100 + const pool = await convertToPool(vault) + pools.push(pool) + } + return pools +} + +interface Vault { + address: string; + name: string; + chain: string; + underlyingTokens: Array; + rewardTokens: Array; + isAsset0Main: boolean; + url: string; + vaultMeta: string; //other info + shareDecimals: number; + tvlUsd?: bn; + tvl?: bn; + tvlBefore?: bn; + shareSupply?: bn; + shareSupplyBefore?: bn; + apy?: number; + rewardApy?: number; +} + +interface UnderlyingToken { + name: string; + address: string; + symbol: string; + decimals: number; + tvl: string; + shareTokenApr: number; +} + +interface RewardBook { + address: string; + endTime: string; + startTime: string; + totalReward: string; +} + +interface RewardToken { + address: string; + chain: string; + decimals: number; + rewardBook: RewardBook; + symbol: string; + type: string; +} + +interface Performance { + tvlUsd: number; + apy: number; +} + +interface Pool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + // optional lending protocol specific fields: + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; // btw [0, 1] +} + +module.exports = { + topLvl, +} diff --git a/src/adaptors/tectonic/abi.js b/src/adaptors/tectonic/abi.js new file mode 100644 index 0000000000..78d4a173bf --- /dev/null +++ b/src/adaptors/tectonic/abi.js @@ -0,0 +1,2646 @@ +module.exports = { + comptrollerAbi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'currentBlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastBlock', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tonicTokens', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'currentAmount', + type: 'uint256', + }, + ], + name: 'CollectVaultReward', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorTonicSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tonicDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tonicBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerTonic', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tonicDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tonicSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierTonic', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLimitPerUser', + type: 'uint256', + }, + ], + name: 'TVLProtectLimitUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'TonicBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'TonicGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'TonicSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract TToken', + name: 'tToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'TonicSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'WhitelistAccountAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'WhitelistAccountRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'bool', name: 'enabled', type: 'bool' }, + ], + name: 'WhitelistStatusChanged', + type: 'event', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'accounts', type: 'address[]' }, + ], + name: '_addToWhitelistProtect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TectonicSocket', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantTonic', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: '_removeFromWhitelistProtect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'tonicSpeed', type: 'uint256' }, + ], + name: '_setContributorTonicSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TToken[]', + name: 'tTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'newBorrowCaps', type: 'uint256[]' }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'newPauseGuardian', type: 'address' }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + { internalType: 'uint256', name: 'tonicSpeed', type: 'uint256' }, + ], + name: '_setTonicSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TToken[]', + name: 'tTokens', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'supplySpeeds', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'borrowSpeeds', type: 'uint256[]' }, + ], + name: '_setTonicSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'whitelistStatus', type: 'bool' }], + name: '_setWhitelistProtect', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TToken[]', + name: 'tTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newLimitPerUser', + type: 'uint256[]', + }, + ], + name: '_updateTvlProtectLimit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_upgradeSplitTonicRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract TToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract TToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract TToken[]', + name: 'tTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimTonic', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimTonic', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract TToken[]', + name: 'tTokens', + type: 'address[]', + }, + ], + name: 'claimTonic', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'collectTonicToVault', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'tTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract TToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract TToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'tTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getTonicAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract TToken', name: 'tToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isTectonicCore', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'tTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'tTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'tTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'tTokenCollateral', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isTonicized', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'actualMintAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingTectonicCoreImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'actualRepayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'tTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tTokenCollateral', type: 'address' }, + { internalType: 'address', name: 'tTokenBorrowed', type: 'address' }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_tonicAddress', type: 'address' }, + ], + name: 'setTonicAddress', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vaultAddress', type: 'address' }, + { internalType: 'uint256', name: 'tonicSpeed', type: 'uint256' }, + { internalType: 'uint256', name: 'tonicCap', type: 'uint256' }, + { internalType: 'uint256', name: 'initialSupply', type: 'uint256' }, + ], + name: 'setVaultReward', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tectonicCoreImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tectonicCoreVersion', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'pure', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tectonicVaultContract', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tokenToPerUserTvlProtectLimit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'tonicBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'tonicSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'tonicSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicToVaultAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicToVaultAmountCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicToVaultLastBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tonicToVaultSpeed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'tToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'utilizedTvlAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'whitelistProtectEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'whitelistedAddresses', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + ercDelegator: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'tTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract TectonicCoreInterface', + name: 'oldTectonicCore', + type: 'address', + }, + { + indexed: false, + internalType: 'contract TectonicCoreInterface', + name: 'newTectonicCore', + type: 'address', + }, + ], + name: 'NewTectonicCore', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'tonicLikeDelegatee', + type: 'address', + }, + ], + name: '_delegateTonicLikeTo', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TectonicCoreInterface', + name: 'newTectonicCore', + type: 'address', + }, + ], + name: '_setTectonicCore', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract TectonicCoreInterface', + name: 'tcore_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract TectonicCoreInterface', + name: 'tcore_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { + internalType: 'contract InterestRateModel', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isTToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract TTokenInterface', + name: 'tTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolSeizeShareMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract EIP20NonStandardInterface', + name: 'token', + type: 'address', + }, + ], + name: 'sweepToken', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'tectonicCore', + outputs: [ + { + internalType: 'contract TectonicCoreInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/tectonic/index.js b/src/adaptors/tectonic/index.js new file mode 100644 index 0000000000..de832ff49e --- /dev/null +++ b/src/adaptors/tectonic/index.js @@ -0,0 +1,224 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const COMPTROLLER_ADDRESS = '0xb3831584acb95ED9cCb0C11f677B5AD01DeaeEc0'; +const CHAIN = 'cronos'; +const GET_ALL_MARKETS = 'getAllMarkets'; +// const REWARD_SPEED = 'tonicSpeeds'; +const REWARD_SPEED = 'tonicSupplySpeeds'; +const REWARD_SPEED_BORROW = 'tonicBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const TOTAL_RESERVES = 'totalReserves'; +const GET_CHASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 6; +const PROJECT_NAME = 'tectonic'; + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'CRO', + address: '0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'TONIC', + address: '0xDD73dEa10ABC2Bff99c60882EC5b2B81Bb1Dc5B2'.toLowerCase(), +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const getApy = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CHASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const totalReserves = await multiCallMarkets( + allMarkets, + TOTAL_RESERVES, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator + ); + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || NATIVE_TOKEN.symbol; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + + Number(totalBorrows[i]) - + Number(totalReserves[i])) / + 10 ** decimals) * + price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_TOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + prices[PROTOCOL_TOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + + return { + pool: market, + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_TOKEN.address : null].filter(Boolean), + url: `https://app.tectonic.finance/markets/${symbol.toLowerCase()}`, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/teller/index.js b/src/adaptors/teller/index.js new file mode 100644 index 0000000000..47f804a3f4 --- /dev/null +++ b/src/adaptors/teller/index.js @@ -0,0 +1,322 @@ + const sdk = require('@defillama/sdk'); + const { request, gql } = require('graphql-request'); + const utils = require('../utils'); + + // Supported chains and their subgraph endpoints + const pools_v1_endpoints = { + + + ethereum: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-pools-mainnet/api" ,//sdk.graph.modifyEndpoint('x6qJPkv7FaCWkfcjDWx12Z2NEfsvCCwuy87vQzk9zRh'), + // base: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-pools-base/api", + arbitrum: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-pools-arbitrum/api", + polygon: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-pools-polygon/api", + + }; + const pools_v2_endpoints = { + + + ethereum: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-poolsv2-mainnet/api" ,//sdk.graph.modifyEndpoint('x6qJPkv7FaCWkfcjDWx12Z2NEfsvCCwuy87vQzk9zRh'), + base: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-poolsv2-base/api", + arbitrum: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-poolsv2-arbitrum/api", + polygon: "https://subgraph.satsuma-prod.com/daba7a4f162f/teller--16564/tellerv2-poolsv2-polygon/api", + // katana: "https://api.goldsky.com/api/public/project_cme01oezy1dwd01um5nile55y/subgraphs/teller-poolsv2-katana/0.4.21.8/gn" + + }; + + + + // GraphQL query to get current pool metrics + const query = gql` + query { + groupPoolMetrics (first: 1000) { + id + group_pool_address + principal_token_address + collateral_token_address + market_id + total_principal_tokens_committed + + total_principal_tokens_withdrawn + total_principal_tokens_borrowed + token_difference_from_liquidations + total_collateral_withdrawn + total_interest_collected + total_principal_tokens_repaid + total_collateral_tokens_escrowed + interest_rate_upper_bound + interest_rate_lower_bound + liquidity_threshold_percent + collateral_ratio + } + } + `; + + // Fetch token info (symbols and decimals) + const fetchTokenInfo = async (tokenAddresses, chainString) => { + const tokens = {}; + for (const address of tokenAddresses) { + try { + + + // Add timeout to prevent hanging + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Token fetch timeout')), 1500 ) + ); + + const tokenInfoPromise = sdk.api.erc20.info(address, chainString); + const tokenInfo = await Promise.race([tokenInfoPromise, timeoutPromise]); + + + + // const tokenInfo = await sdk.api.erc20.info(address, chainString); + tokens[address.toLowerCase()] = { + symbol: tokenInfo.output.symbol, + decimals: Number(tokenInfo.output.decimals) || 18, + }; + + console.log(`Successfully fetched ${tokenInfo.output.symbol} for ${address}`); + + + } catch (error) { + console.warn(`failure to fetch token info ${address}, ${chainString}`); + tokens[address.toLowerCase()] = { symbol: 'UNKNOWN', decimals: 18 }; + } + } + return tokens; + }; + + const topLvl = async (chainString, url, query, timestamp) => { + // Fetch pool data from current state (Hasura endpoint doesn't support block queries) + // console.log(`Making GraphQL request to ${url} for ${chainString}`); + let dataNow = await request(url, query); + // console.log(`Raw response for ${chainString}:`, Object.keys(dataNow)); + dataNow = dataNow.groupPoolMetrics; + console.log(`Found ${dataNow ? dataNow.length : 0} pools for ${chainString}`); + + if (!dataNow || dataNow.length === 0) { + console.log(`No pools found for ${chainString}, returning empty array`); + return []; + } + + // Get unique token addresses from all pools + const tokenAddresses = new Set(); + dataNow.forEach(pool => { + tokenAddresses.add(pool.principal_token_address); + tokenAddresses.add(pool.collateral_token_address); + }); + + // Fetch token info (symbols and decimals) + // console.log(`Fetching token info for ${tokenAddresses.size} unique tokens for ${chainString}`); + const tokenInfo = await fetchTokenInfo(Array.from(tokenAddresses), chainString); + console.log(`Token info fetched for ${chainString}, processing pools...`); + + // Enrich pool data with calculated metrics + const enrichedData = await Promise.all( + dataNow.map(async (pool, index) => { + console.log(`Processing pool ${index + 1}/${dataNow.length} for ${chainString}: ${pool.group_pool_address}`); + + let pricesByAddress = {}; + try { + const prices = await utils.getPrices( + [pool.principal_token_address, pool.collateral_token_address], + chainString + ); + pricesByAddress = prices.pricesByAddress || {}; + console.log(`Got prices for pool ${index + 1}/${dataNow.length} for ${chainString}`); + } catch (priceError) { + console.warn(`Failed to get prices for pool ${pool.group_pool_address} on ${chainString}:`, priceError.message); + pricesByAddress = {}; + } + + const principalTokenDecimals = tokenInfo[pool.principal_token_address.toLowerCase()]?.decimals || 18; + const principalTokenDivisor = 10 ** principalTokenDecimals; + + const collateralTokenDecimals = tokenInfo[pool.collateral_token_address.toLowerCase()]?.decimals || 18; + const collateralTokenDivisor = 10 ** collateralTokenDecimals; + + const totalInterestCollected = Number(pool.total_interest_collected); + const tokenDifferenceFromLiquidatons = Number(pool.token_difference_from_liquidations); + const totalCollateralEscrowedNet = Number(pool.total_collateral_tokens_escrowed) - Number(pool.total_collateral_withdrawn); + + const totalCollateralUsd = + totalCollateralEscrowedNet * + (parseFloat(pricesByAddress[pool.collateral_token_address.toLowerCase()] || 0) / collateralTokenDivisor); + + const totalTokensActivelyBorrowed = + Number(pool.total_principal_tokens_borrowed) - Number(pool.total_principal_tokens_repaid); + const totalTokensActivelyCommitted = + Number(pool.total_principal_tokens_committed) + + totalInterestCollected + + tokenDifferenceFromLiquidatons - + Number(pool.total_principal_tokens_withdrawn); + + const totalCommitted = Number(totalTokensActivelyCommitted); + const totalBorrowed = Number(totalTokensActivelyBorrowed); + + const totalSupplyUsd = + Math.max(0, totalCommitted * + (parseFloat(pricesByAddress[pool.principal_token_address.toLowerCase()] || 0) / principalTokenDivisor)); + + const totalBorrowUsd = + Math.max(0, totalBorrowed * + (parseFloat(pricesByAddress[pool.principal_token_address.toLowerCase()] || 0) / principalTokenDivisor)); + + const tvlUsd = totalSupplyUsd - totalBorrowUsd; + const poolBorrowedPercent = totalCommitted > 0 ? Math.min(Math.max(totalBorrowed / totalCommitted, 0), 1) : 0; + + const interestRateLowerBound = Number(pool.interest_rate_lower_bound) || 500; + const interestRateUpperBound = Number(pool.interest_rate_upper_bound) || 1500; + + const apyBase = calculateActiveLenderYield(poolBorrowedPercent, interestRateLowerBound, interestRateUpperBound); + const ltv = 100.0 / (Number(pool.collateral_ratio) / 100.0); + const borrowApy = calculateActiveBorrowerYield(poolBorrowedPercent, interestRateLowerBound, interestRateUpperBound); + + const principalSymbol = tokenInfo[pool.principal_token_address.toLowerCase()]?.symbol || 'UNKNOWN'; + const collateralSymbol = tokenInfo[pool.collateral_token_address.toLowerCase()]?.symbol || 'UNKNOWN'; + + return { + ...pool, + tvlUsd, + apyBase, + totalSupplyUsd, + totalBorrowUsd, + ltv, + borrowApy, + principalSymbol, + collateralSymbol, + principalTokenDecimals, + collateralTokenDecimals, + totalCollateralUsd, + }; + }) + ); + + console.log(`enriching data for ${chainString} ...`); + + + // For each enriched pool, create separate lending and collateral pool objects + return enrichedData.flatMap((p) => { + // Skip pools with unknown tokens or invalid data + if (p.principalSymbol === 'UNKNOWN' || p.collateralSymbol === 'UNKNOWN') { + console.log(`Skipping pool ${p.group_pool_address} due to unknown tokens`); + return []; + } + + // Skip pools with invalid LTV (too small or too large) + if (p.ltv < 0.001 || p.ltv > 1) { + console.log(`Skipping pool ${p.group_pool_address} due to invalid LTV: ${p.ltv}`); + return []; + } + + // Skip pools with very low TVL + if (p.totalSupplyUsd < 1000 || p.totalCollateralUsd < 1000) { + console.log(`Skipping pool ${p.group_pool_address} due to low TVL`); + return []; + } + + const underlyingTokens = [p.principal_token_address, p.collateral_token_address]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + const url = `https://app.teller.org/${chainString}/lend/pool/${p.group_pool_address}`; + + const lendingPool = { + pool: p.group_pool_address + "-lending", + chain: utils.formatChain(chainString), + project: 'teller', + symbol: p.principalSymbol, + poolMeta: p.collateralSymbol, + tvlUsd: Number(p.totalSupplyUsd.toFixed(4)), + apyBase: p.apyBase, + underlyingTokens, + url, + }; + + const collateralPool = { + pool: p.group_pool_address + "-collateral", + chain: utils.formatChain(chainString), + project: 'teller', + symbol: p.collateralSymbol, + mintedCoin: p.principalSymbol, + tvlUsd: Number(p.totalCollateralUsd.toFixed(4)), + totalSupplyUsd: Number(p.totalCollateralUsd.toFixed(4)), + totalBorrowUsd: Number(p.totalBorrowUsd.toFixed(4)), + ltv: p.ltv, + apyBaseBorrow: p.borrowApy, + apyBase: 0, + underlyingTokens, + url, + }; + + return [lendingPool, collateralPool]; + }); + }; + + // Calculate active yield for lenders + const calculateActiveLenderYield = (poolBorrowedPercent, interestRateLowerBound, interestRateUpperBound) => { + let poolYieldRaw; + if (poolBorrowedPercent === 0) { + poolYieldRaw = interestRateLowerBound; + } else if (poolBorrowedPercent === 1) { + poolYieldRaw = interestRateUpperBound; + } else { + const range = interestRateUpperBound - interestRateLowerBound; + poolYieldRaw = interestRateLowerBound + (poolBorrowedPercent * range); + } + return (poolYieldRaw / 100) * poolBorrowedPercent; + }; + + // Calculate active yield for borrowers + const calculateActiveBorrowerYield = (poolBorrowedPercent, interestRateLowerBound, interestRateUpperBound) => { + let poolYieldRaw; + if (poolBorrowedPercent === 0) { + poolYieldRaw = interestRateLowerBound; + } else if (poolBorrowedPercent === 1) { + poolYieldRaw = interestRateUpperBound; + } else { + const range = interestRateUpperBound - interestRateLowerBound; + poolYieldRaw = interestRateLowerBound + (poolBorrowedPercent * range); + } + return poolYieldRaw / 100; + }; + + const main = async (timestamp = null) => { + let data = []; + + + for (const [chain, url] of Object.entries(pools_v2_endpoints)) { + if (!url) { + console.log(`Skipping v2 data for ${chain} - no URL configured`); + continue; + } + try { + console.log(`Fetching v2 data for ${chain}...`); + const chainData = await topLvl(chain, url, query, timestamp); + data.push(...chainData); + } catch (err) { + console.log(chain, err); + } + } + + for (const [chain, url] of Object.entries(pools_v1_endpoints)) { + if (!url) { + console.log(`Skipping v1 data for ${chain} - no URL configured`); + continue; + } + try { + console.log(`Fetching v1 data for ${chain}...`); + const chainData = await topLvl(chain, url, query, timestamp); + data.push(...chainData); + } catch (err) { + console.log(chain, err); + } + } + + console.log(`build filteredData ...`); + + const filteredData = data.filter((p) => utils.keepFinite(p)); + return filteredData; + }; + + module.exports = { + timetravel: false, + apy: main, + }; diff --git a/src/adaptors/tempus-finance/abis/TempStaking.json b/src/adaptors/tempus-finance/abis/TempStaking.json new file mode 100644 index 0000000000..1b1cca4980 --- /dev/null +++ b/src/adaptors/tempus-finance/abis/TempStaking.json @@ -0,0 +1,43 @@ +{ + "totalStakedSupply": { + "inputs": [], + "name": "totalStakedSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + "rewardPrograms": { + "inputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "name": "rewardPrograms", + "outputs": [ + { + "internalType": "uint256", + "name": "rewardPerSecond", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardPerTokenCached", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { "internalType": "uint256", "name": "startTime", "type": "uint256" }, + { "internalType": "uint256", "name": "finishTime", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + "timeMultiplierIncreasePerSec": { + "inputs": [], + "name": "timeMultiplierIncreasePerSec", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/tempus-finance/index.js b/src/adaptors/tempus-finance/index.js new file mode 100644 index 0000000000..f22467ed5a --- /dev/null +++ b/src/adaptors/tempus-finance/index.js @@ -0,0 +1,105 @@ +const { default: BigNumber } = require('bignumber.js'); +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const tempStaking = require('./abis/TempStaking.json'); + +const STAKING = '0x6C6D4753a1107585121599746c2E398cCbEa5119'; +const TEMP = '0xA36FDBBAE3c9d55a1d67EE5821d53B50B63A1aB9'; +const RAFT = '0x4C5Cb5D87709387f8821709f7a6664f00DcF0C93'; + +async function getEstimatedApy( + rewardPerSecond, + timeMultiplierIncreasePerSec, + stakeAmount, + totalTempStaked, + tempPrice, + raftPrice, + stakeStart, + stakeEnd +) { + // rewards = (stakeAmount / (stakeAmount + totalTempStaked)) * rewardsPerSecond * (stakeEnd - stakeStart) * (1 + timeMultiplierIncreasePerSec * (stakeEnd - stakeStart)); + const rewards = stakeAmount + .times(1e18) + .div(stakeAmount.plus(totalTempStaked)) + .times(rewardPerSecond) + .div(1e18) + .times(stakeEnd - stakeStart) + .times( + BigNumber(1).plus( + timeMultiplierIncreasePerSec.times(stakeEnd - stakeStart).div(1e18) + ) + ); + + // apr = rewards * (raftPrice / tempPrice) * (SECONDS_IN_A_YEAR / stakeEnd) / stakeAmount; + return rewards + .times(raftPrice / tempPrice) + .times((60 * 60 * 24 * 365) / stakeEnd) + .div(stakeAmount); +} + +async function getTokenPrice(token) { + const networkTokenPair = `ethereum:${token}`; + return ( + await axios.get(`https://coins.llama.fi/prices/current/${networkTokenPair}`) + ).data.coins[networkTokenPair].price; +} + +async function apy() { + const totalStaked = BigNumber( + ( + await sdk.api.abi.call({ + target: STAKING, + abi: tempStaking.totalStakedSupply, + }) + ).output + ); + const rewardPerSecond = BigNumber( + ( + await sdk.api.abi.call({ + target: STAKING, + abi: tempStaking.rewardPrograms, + params: [RAFT], + }) + ).output.rewardPerSecond + ); + const timeMultiplierIncreasePerSec = BigNumber( + ( + await sdk.api.abi.call({ + target: STAKING, + abi: tempStaking.timeMultiplierIncreasePerSec, + }) + ).output + ); + const tempPrice = await getTokenPrice(TEMP); + const raftPrice = await getTokenPrice(RAFT); + + const apy = await getEstimatedApy( + rewardPerSecond, + timeMultiplierIncreasePerSec, + BigNumber(1), + totalStaked, + tempPrice, + raftPrice, + 0, + 1 + ); + const totalStakedUsd = totalStaked.times(tempPrice).div(1e18).toNumber(); + + return [ + { + pool: `${STAKING}-${RAFT}`.toLowerCase(), + project: 'tempus-finance', + symbol: 'TEMP', + chain: 'Ethereum', + poolMeta: 'TEMP Staking', + apyReward: apy.toNumber() * 100, + rewardTokens: [RAFT], + tvlUsd: totalStakedUsd, + }, + ]; +} + +module.exports = { + apy, + url: 'https://stake.tempus.finance/', +}; diff --git a/src/adaptors/tender-finance/abis/gmd.json b/src/adaptors/tender-finance/abis/gmd.json new file mode 100644 index 0000000000..94998f8f8e --- /dev/null +++ b/src/adaptors/tender-finance/abis/gmd.json @@ -0,0 +1,29 @@ +{ + "poolInfo": { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "contract GDtoken", + "name": "GDlptoken", + "type": "address" + }, + { "internalType": "uint256", "name": "EarnRateSec", "type": "uint256" }, + { "internalType": "uint256", "name": "totalStaked", "type": "uint256" }, + { "internalType": "uint256", "name": "lastUpdate", "type": "uint256" }, + { "internalType": "uint256", "name": "vaultcap", "type": "uint256" }, + { "internalType": "uint256", "name": "glpFees", "type": "uint256" }, + { "internalType": "uint256", "name": "APR", "type": "uint256" }, + { "internalType": "bool", "name": "stakable", "type": "bool" }, + { "internalType": "bool", "name": "withdrawable", "type": "bool" }, + { "internalType": "bool", "name": "rewardStart", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + } +} diff --git a/src/adaptors/tender-finance/abis/gmx.json b/src/adaptors/tender-finance/abis/gmx.json new file mode 100644 index 0000000000..4a073e4bfc --- /dev/null +++ b/src/adaptors/tender-finance/abis/gmx.json @@ -0,0 +1,34 @@ +{ + "tokensPerInterval": { + "inputs": [], + "name": "tokensPerInterval", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getAumInUsdg": { + "inputs": [ + { + "internalType": "bool", + "name": "maximise", + "type": "bool" + } + ], + "name": "getAumInUsdg", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/tender-finance/abis/tender.js b/src/adaptors/tender-finance/abis/tender.js new file mode 100644 index 0000000000..1a4a4d34cb --- /dev/null +++ b/src/adaptors/tender-finance/abis/tender.js @@ -0,0 +1,2102 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'string', + name: 'action', + type: 'string', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompAccrued', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompAccrued', + type: 'uint256', + }, + ], + name: 'CompAccruedAdjusted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'CompGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCompReceivable', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCompReceivable', + type: 'uint256', + }, + ], + name: 'CompReceivableUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'CompSupplySpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'contributor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'ContributorCompSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'compSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierComp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldBorrowCapGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: 'NewBorrowCapGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: '_mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newBorrowCapGuardian', + type: 'address', + }, + ], + name: '_setBorrowCapGuardian', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setBorrowPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setCompSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + { internalType: 'uint256', name: 'compSpeed', type: 'uint256' }, + ], + name: '_setContributorCompSpeed', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract CToken', + name: 'cToken', + type: 'address', + }, + { internalType: 'bool', name: 'state', type: 'bool' }, + ], + name: '_setMintPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setSeizePaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setTransferPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract CToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract CToken[]', + name: 'cTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimComp', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compContributorSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'compRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compReceivable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'compSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'compSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'cTokens', type: 'address[]' }, + ], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address[]', + name: 'affectedUsers', + type: 'address[]', + }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + name: 'fixBadAccruals', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract CToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCompAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'cTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'contract CToken', name: 'cToken', type: 'address' }, + ], + name: 'isDeprecated', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'lastContributorBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isComped', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'proposal65FixExecuted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'seizeGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'cTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'cTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'transferGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'cToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'contributor', type: 'address' }, + ], + name: 'updateContributorRewards', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/tender-finance/index.js b/src/adaptors/tender-finance/index.js new file mode 100644 index 0000000000..02cb30e53a --- /dev/null +++ b/src/adaptors/tender-finance/index.js @@ -0,0 +1,367 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const gmdAbi = require('./abis/gmd.json'); +const { comptrollerAbi, ercDelegator } = require('./abis/tender'); +const utils = require('../utils'); +const gmxAbi = require('./abis/gmx.json'); + +const COMPTROLLER_ADDRESS = '0xeed247Ba513A8D6f78BE9318399f5eD1a4808F8e'; +const CHAIN = 'arbitrum'; +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const GET_CASH = 'getCash'; +const UNDERLYING = 'underlying'; +const BLOCKS_PER_DAY = 86400 / 12; +const PROJECT_NAME = 'tender-finance'; + +async function getGlpApy() { + const arbitrumGmxAddress = '0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a'; + const arbitrumGlpManagerAddress = + '0x321F653eED006AD1C29D174e17d96351BDe22649'; + const arbitrumFeeGmxTrackerAddress = + '0xd2D1162512F927a7e282Ef43a362659E4F2a728F'; + const arbitrumInflationGmxTrackerAddress = + '0x908C4D94D34924765f1eDc22A1DD098397c59dD4'; + const arbitrumFeeGlpTrackerAddress = + '0x4e971a87900b931fF39d1Aad67697F49835400b6'; + const arbitrumInflationGlpTrackerAddress = + '0x1aDDD80E6039594eE970E5872D247bf0414C8903'; + const secondsPerYear = 31536000; + + async function getAdjustedAmount(pTarget, pChain, pgmxAbi, pParams = []) { + let decimals = await sdk.api.abi.call({ + target: pTarget, + abi: 'erc20:decimals', + chain: pChain, + permitFailure: true, + }); + let supply = await sdk.api.abi.call({ + target: pTarget, + abi: pgmxAbi, + chain: pChain, + params: pParams, + permitFailure: true, + }); + + return pgmxAbi == gmxAbi['tokensPerInterval'] + ? supply.output * 10 ** -decimals.output * secondsPerYear + : supply.output * 10 ** -decimals.output; + } + async function getGlpTvl(pChain) { + let tvl = await sdk.api.abi.call({ + target: + pChain == 'arbitrum' + ? arbitrumGlpManagerAddress + : avalancheGlpManagerAddress, + abi: gmxAbi['getAumInUsdg'], + chain: pChain, + params: [false], + permitFailure: true, + }); + + return tvl.output * 10 ** -18; + } + + async function glpApyBase( + pChain, + pTvl, + pInflationTrackerAddress, + pFeeGlp, + pInflationGlp, + pPriceData + ) { + const yearlyFeeGlp = pFeeGlp * pPriceData['coingecko:ethereum'].price; + const yearlyInflationGlp = + pInflationGlp * pPriceData['coingecko:gmx'].price; + const apyFee = (yearlyFeeGlp / pTvl) * 100; + const apyInflation = (yearlyInflationGlp / pTvl) * 100; + const chainString = pChain === 'avax' ? 'avalanche' : pChain; + + return apyFee; + } + + const arbitrumFeeGlp = await getAdjustedAmount( + arbitrumFeeGlpTrackerAddress, + 'arbitrum', + gmxAbi['tokensPerInterval'] + ); + const arbitrumInflationGlp = await getAdjustedAmount( + arbitrumInflationGlpTrackerAddress, + 'arbitrum', + gmxAbi['tokensPerInterval'] + ); + const priceKeys = ['gmx', 'ethereum'].map((t) => `coingecko:${t}`).join(','); + const { coins: priceData } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKeys}` + ); + return await glpApyBase( + 'arbitrum', + await getGlpTvl('arbitrum'), + arbitrumInflationGlpTrackerAddress, + arbitrumFeeGlp, + arbitrumInflationGlp, + priceData + ); +} + +const NATIVE_TOKEN = { + decimals: 18, + symbol: 'WETH', + address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'.toLowerCase(), +}; + +const PROTOCOL_TOKEN = { + decimals: 18, + symbol: 'TND', + address: '0xC47D9753F3b32aA9548a7C3F30b6aEc3B2d2798C'.toLowerCase(), +}; + +const PROTOCOL_ESTOKEN = { + decimals: 18, + symbol: 'esTND', + address: '0xff9bD42211F12e2de6599725895F37b4cE654ab2'.toLowerCase(), +}; + +const GMD_VAULT = '0x8080B5cE6dfb49a6B86370d6982B3e2A86FBBb08'; + +const GMD_IDS = [0, 1, 2, 4]; + +const GMD_TOKENS = { + gmdUSDC: { + underlying: '0x3DB4B7DA67dd5aF61Cb9b3C70501B1BdB24b2C22', + }, + gmdETH: { + underlying: '0x1E95A37Be8A17328fbf4b25b9ce3cE81e271BeB3', + }, + gmdBTC: { + underlying: '0x147FF11D9B9Ae284c271B2fAaE7068f4CA9BB619', + }, + gmdUSDT: { + underlying: '0x34101Fe647ba02238256b5C5A58AeAa2e532A049', + }, +}; + +const getGmdInfo = async () => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: [0, 1, 2, 4].map((id) => ({ + target: GMD_VAULT, + params: [id], + })), + abi: gmdAbi['poolInfo'], + permitFailure: true, + }) + ).output.map(({ output }) => [output.GDlptoken, output]); +}; +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps) => { + const blocksPerDay = BLOCKS_PER_DAY; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ + target: COMPTROLLER_ADDRESS, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi) => { + return ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const main = async () => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: COMPTROLLER_ADDRESS, + chain: CHAIN, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: CHAIN, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: COMPTROLLER_ADDRESS, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const extraRewards = await getRewards(allMarkets, REWARD_SPEED); + const extraRewardsBorrow = await getRewards(allMarkets, REWARD_SPEED_BORROW); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused'); + + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CASH, + ercDelegator + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + 'underlying', + ercDelegator + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator + ); + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator + ); + const prices = await getPrices( + underlyingTokens + .concat([NATIVE_TOKEN.address]) + .map((token) => `${CHAIN}:` + token) + ); + const gmdInfo = Object.fromEntries(await getGmdInfo(GMD_IDS)); + const glpApy = await getGlpApy(); + + const tenderPrices = await getPrices([`${CHAIN}:${PROTOCOL_TOKEN.address}`]); + tenderPrices[PROTOCOL_ESTOKEN.address] = tenderPrices[PROTOCOL_TOKEN.address]; + + const handleApyUnderlying = (market, symbol, supplyRewards) => { + const aprToApy = (interest, frequency) => + ((1 + interest / 100 / frequency) ** frequency - 1) * 100; + + if (symbol == 'fsGLP') { + return glpApy; + } else if (GMD_TOKENS[symbol]) { + const apr = gmdInfo[GMD_TOKENS[symbol].underlying].APR; + return aprToApy(apr / 100, 365).toPrecision(4); + } + return calculateApy(supplyRewards / 10 ** 18); + }; + + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || NATIVE_TOKEN.address; + const symbol = underlyingSymbols[i] || 'ETH'; + + const decimals = Number(underlyingDecimals[i]) || NATIVE_TOKEN.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') + ? 1 + : symbol == 'gmdBTC' + ? prices['0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f'.toLowerCase()] + : symbol == 'gmdETH' + ? prices[NATIVE_TOKEN.address.toLowerCase()] + : 0; + + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const tvlUsd = (marketsCash[i] / 10 ** decimals) * price; + + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + + const apyBase = handleApyUnderlying(market, symbol, supplyRewards[i]); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18); + + const calcRewardApy = (rewards, denom) => { + return ( + (((rewards[i] / 10 ** PROTOCOL_ESTOKEN.decimals) * + BLOCKS_PER_DAY * + 365 * + tenderPrices[PROTOCOL_ESTOKEN.address]) / + denom) * + 100 + ); + }; + const apyReward = calcRewardApy(extraRewards, totalSupplyUsd); + const _apyRewardBorrow = calcRewardApy(extraRewardsBorrow, totalBorrowUsd); + const apyRewardBorrow = isNaN(_apyRewardBorrow) ? 0 : _apyRewardBorrow; + + let poolReturned = { + pool: market.toLowerCase(), + chain: utils.formatChain(CHAIN), + project: PROJECT_NAME, + symbol: symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [token], + rewardTokens: [apyReward ? PROTOCOL_ESTOKEN.address : null].filter( + Boolean + ), + totalSupplyUsd, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + }; + return poolReturned; + }); + return pools.filter((i) => utils.keepFinite(i)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.tender.fi', +}; diff --git a/src/adaptors/tenderize/index.js b/src/adaptors/tenderize-v1/index.js similarity index 76% rename from src/adaptors/tenderize/index.js rename to src/adaptors/tenderize-v1/index.js index 76497fb812..e17f240811 100644 --- a/src/adaptors/tenderize/index.js +++ b/src/adaptors/tenderize-v1/index.js @@ -1,11 +1,10 @@ +const sdk = require('@defillama/sdk'); const { GraphQLClient, gql } = require('graphql-request'); const utils = require('../utils'); const fetch = require('node-fetch'); -const ethereumEndpoint = - 'https://api.thegraph.com/subgraphs/name/tenderize/tenderize-ethereum'; -const arbitrumEndpoint = - 'https://api.thegraph.com/subgraphs/name/tenderize/tenderize-arbitrum'; +const ethereumEndpoint = sdk.graph.modifyEndpoint('G4tmH3LNcPYUzuXx1Lqv7egUzyQpagNWn8MCpwMtEVFF'); +const arbitrumEndpoint = sdk.graph.modifyEndpoint('BKHH9dfKgGR4KmrkpvN8r8JMHEmtYqFgdiUe9C6VZk9K'); const query = gql` { @@ -38,7 +37,7 @@ const topLvl = async (endpoint, chain, apyResponse) => { pools.push({ pool: `tenderize-${config.tenderToken}`, chain: utils.formatChain(chain), - project: 'tenderize', + project: 'tenderize-v1', symbol: tokens.find((v) => v.address === config.tenderToken).symbol, tvlUsd: Number.parseFloat( tenderizers.find((v) => v.id === config.id).TVL @@ -51,10 +50,10 @@ const topLvl = async (endpoint, chain, apyResponse) => { }; const main = async () => { - const resp = await fetch('https://www.tenderize.me/api/apy', { + const resp = await fetch('https://v1.tenderize.me/api/apy', { headers: { accept: '*/*', - 'cache-control': 'no-cache', + 'cache-control': 'no-cache', pragma: 'no-cache', }, method: 'GET', @@ -72,4 +71,5 @@ const main = async () => { module.exports = { timetravel: false, apy: main, + url: 'https://app.tenderize.me/stakers/livepeer', }; diff --git a/src/adaptors/termmax/index.js b/src/adaptors/termmax/index.js new file mode 100644 index 0000000000..849489e49e --- /dev/null +++ b/src/adaptors/termmax/index.js @@ -0,0 +1,748 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const { Interface } = require('ethers/lib/utils'); + +const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; + +const EVENTS = { + V1: { + CreateVault: + 'event CreateVault(address indexed vault, address indexed creator, (address admin,address curator,uint256 timelock,address asset,uint256 maxCapacity,string name,string symbol,uint64 performanceFeeRate) indexed initialParams)', + }, + V1Plus: { + VaultCreated: + 'event VaultCreated(address indexed vault, address indexed creator, tuple(address admin,address curator,address guardian,uint256 timelock,address asset,uint256 maxCapacity,string name,string symbol,uint64 performanceFeeRate,uint64 minApy,uint64 minIdleFundRate) initialParams)', + }, + V2: { + VaultCreated: + 'event VaultCreated(address indexed vault, address indexed creator, (address admin,address curator,address guardian,uint256 timelock,address asset,address pool,uint256 maxCapacity,string name,string symbol,uint64 performanceFeeRate,uint64 minApy) initialParams)', + }, +}; +const v1iface = new Interface([EVENTS.V1.CreateVault]); +const v1plusiface = new Interface([EVENTS.V1Plus.VaultCreated]); +const v2iface = new Interface([EVENTS.V2.VaultCreated]); + +const VAULTS = { + ethereum: { + alias: 'eth', + chain: 'ethereum', + chainId: 1, + vaultFactory: [ + { + address: '0x01D8C1e0584751085a876892151Bf8490e862E3E', + fromBlock: 22174789, + }, + { + address: '0x4778CBf91d8369843281c8f5a2D7b56d1420dFF5', + fromBlock: 22283092, + }, + ], + vaultFactoryV1Plus: [ + { + address: '0x3a9ECfFDBDc595907f65640F810d3dDDDDe2FA61', + fromBlock: 23138659, + }, + ], + vaultFactoryV2: [ + { + address: '0xF2BDa87CA467eB90A1b68f824cB136baA68a8177', + fromBlock: 23430000, + }, + { + address: '0x5b8B26a6734B5eABDBe6C5A19580Ab2D0424f027', + fromBlock: 23430000, + }, + ], + }, + arbitrum: { + alias: 'arb', + chain: 'arbitrum', + chainId: 42161, + vaultFactory: [ + { + address: '0x929CBcb8150aD59DB63c92A7dAEc07b30d38bA79', + fromBlock: 322193571, + }, + ], + vaultFactoryV2: [ + { + address: '0xa7c93162962D050098f4BB44E88661517484C5EB', + fromBlock: 385228046, + }, + { + address: '0x18b8A9433dBefcd15370F10a75e28149bcc2e301', + fromBlock: 385228046, + }, + ], + }, + bsc: { + alias: 'bnb', + chain: 'bsc', + chainId: 56, + vaultFactory: [ + { + address: '0x48bCd27e208dC973C3F56812F762077A90E88Cea', + fromBlock: 50519589, + }, + ], + vaultFactoryV2: [ + { + address: '0x1401049368eD6AD8194f8bb7E41732c4620F170b', + fromBlock: 63100000, + }, + { + address: '0xdffE6De6de1dB8e1B5Ce77D3222eba401C2573b5', + fromBlock: 63100000, + }, + ], + }, +}; + +const VAULT_BLACKLIST = { + arbitrum: [ + '0x8531dC1606818A3bc3D26207a63641ac2F1f6Dc8', // misconfigured asset + ], + ethereum: [], + bsc: [ + '0xe5E01B82904a49Ce5a670c1B7488C3f29433088a', // misconfigured asset + ], +}; + +async function getMerklOpportunities() { + const res = await axios.get( + new URL('https://api.merkl.xyz/v4/opportunities?name=termmax') + ); + return res.data.filter((o) => o.status === 'LIVE'); +} + +async function getPrices(chain, addresses) { + const priceMap = new Map(); + + const tasks = []; + for (const address of addresses) { + const url = new URL( + `https://coins.llama.fi/prices/current/${chain}:${address}` + ); + tasks.push( + axios.get(url).then((response) => { + const priceKey = `${chain}:${address}`; + priceMap.set(address, response.data.coins[priceKey]?.price || 0); + }) + ); + } + await Promise.all(tasks); + + return priceMap; +} + +async function getVaultV1Addresses(chain, blockNumber) { + const { vaultFactory } = VAULTS[chain]; + + const addresses = []; + + const tasks = []; + for (const factory of vaultFactory) { + const task = async () => { + const { output } = await sdk.api2.util.getLogs({ + target: factory.address, + topic: '', + fromBlock: factory.fromBlock, + toBlock: blockNumber, + keys: [], + topics: [v1iface.getEventTopic('CreateVault')], + chain, + }); + const events = output + .filter((e) => !e.removed) + .map((e) => v1iface.parseLog(e)); + for (const { args } of events) { + const [vault] = args; + addresses.push(vault); + } + }; + tasks.push(task()); + } + await Promise.all(tasks); + + return addresses; +} + +async function getVaultsV1({ alias, chain, chainId, number, opportunities }) { + const vaults = []; + + const addresses = await getVaultV1Addresses(chain, number).then((addresses) => + addresses.filter((a) => !VAULT_BLACKLIST[chain].includes(a)) + ); + const calls = addresses.map((target) => ({ target })); + const [aprs, assets, decimalses, names, totalAssetses] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:apr', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'address:asset', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint8:decimals', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'string:name', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:totalAssets', + }), + ]); + + const [assetNames, priceMap] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls: assets.output.map((a) => ({ target: a.output })), + abi: 'string:symbol', + }), + getPrices( + chain, + assets.output.map((a) => a.output) + ), + ]); + + for (let i = 0; i < addresses.length; i++) { + const address = addresses[i]; + const assetAddress = assets.output[i].output; + + const readableApr = new BigNumber(aprs.output[i].output) + .div(new BigNumber(10).pow(6)) // actual decimals for APR is 8 + .toNumber(); + const tvlUsd = new BigNumber(totalAssetses.output[i].output) + .div(new BigNumber(10).pow(decimalses.output[i].output)) + .times(priceMap.get(assetAddress) || 0) + .toNumber(); + + const url = new URL( + `https://app.termmax.ts.finance/earn/${alias}/${address.toLowerCase()}` + ); + url.searchParams.set('chain', alias); + + const vault = { + pool: `${address}-${chain.toLowerCase()}`, + chain, + project: 'termmax', + symbol: assetNames.output[i].output, + tvlUsd, + apyBase: readableApr, + url: String(url), + underlyingTokens: [assetAddress], + poolMeta: names.output[i].output, + }; + + const opportunity = opportunities.find( + (o) => + o.chainId === chainId && + o.identifier.toLowerCase() === address.toLowerCase() + ); + if (opportunity) { + vault.apyReward = opportunity.apr; + + const breakdowns = + (opportunity.rewardsRecord && opportunity.rewardsRecord.breakdowns) || + []; + vault.rewardTokens = breakdowns + .map((b) => b.token.address) + .filter((a) => a); + } + + vaults.push(vault); + } + + return vaults; +} + +async function getVaultV1PlusAddresses(chain, blockNumber) { + const { vaultFactoryV1Plus } = VAULTS[chain]; + if (!vaultFactoryV1Plus) return []; + + const addresses = []; + + const tasks = []; + for (const factory of vaultFactoryV1Plus) { + const task = async () => { + const { output } = await sdk.api2.util.getLogs({ + target: factory.address, + topic: '', + fromBlock: factory.fromBlock, + toBlock: blockNumber, + keys: [], + topics: [v1plusiface.getEventTopic('VaultCreated')], + chain, + }); + const events = output + .filter((e) => !e.removed) + .map((e) => v1plusiface.parseLog(e)); + for (const { args } of events) { + const [vault] = args; + addresses.push(vault); + } + }; + tasks.push(task()); + } + await Promise.all(tasks); + + return addresses; +} + +async function getVaultsV1Plus({ + alias, + chain, + chainId, + number, + opportunities, +}) { + const vaults = []; + + const addresses = await getVaultV1PlusAddresses(chain, number).then( + (addresses) => addresses.filter((a) => !VAULT_BLACKLIST[chain].includes(a)) + ); + if (addresses.length === 0) return vaults; + + const calls = addresses.map((target) => ({ target })); + const [apys, assets, decimalses, names, totalAssetses] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:apy', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'address:asset', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint8:decimals', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'string:name', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:totalAssets', + }), + ]); + + const [assetNames, priceMap] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls: assets.output.map((a) => ({ target: a.output })), + abi: 'string:symbol', + }), + getPrices( + chain, + assets.output.map((a) => a.output) + ), + ]); + + for (let i = 0; i < addresses.length; i++) { + const address = addresses[i]; + const assetAddress = assets.output[i].output; + + const readableApy = new BigNumber(apys.output[i].output) + .div(new BigNumber(10).pow(6)) // actual decimals for APY is 8 + .toNumber(); + const tvlUsd = new BigNumber(totalAssetses.output[i].output) + .div(new BigNumber(10).pow(decimalses.output[i].output)) + .times(priceMap.get(assetAddress) || 0) + .toNumber(); + + const url = new URL( + `https://app.termmax.ts.finance/earn/${alias}/${address.toLowerCase()}` + ); + url.searchParams.set('chain', alias); + + const vault = { + pool: `${address}-${chain.toLowerCase()}`, + chain, + project: 'termmax', + symbol: assetNames.output[i].output, + tvlUsd, + apyBase: readableApy, + url: String(url), + underlyingTokens: [assetAddress], + poolMeta: names.output[i].output, + }; + + const opportunity = opportunities.find( + (o) => + o.chainId === chainId && + o.identifier.toLowerCase() === address.toLowerCase() + ); + if (opportunity) { + vault.apyReward = opportunity.apr; + + const breakdowns = + (opportunity.rewardsRecord && opportunity.rewardsRecord.breakdowns) || + []; + vault.rewardTokens = breakdowns + .map((b) => b.token.address) + .filter((a) => a); + } + + vaults.push(vault); + } + + return vaults; +} + +async function getVaultV2Addresses(chain, blockNumber) { + const { vaultFactoryV2 } = VAULTS[chain]; + + const addresses = []; + + const tasks = []; + for (const factory of vaultFactoryV2) { + const task = async () => { + const { output } = await sdk.api2.util.getLogs({ + target: factory.address, + topic: '', + fromBlock: factory.fromBlock, + toBlock: blockNumber, + keys: [], + topics: [v2iface.getEventTopic('VaultCreated')], + chain, + }); + const events = output + .filter((e) => !e.removed) + .map((e) => v2iface.parseLog(e)); + for (const { args } of events) { + const [vault] = args; + addresses.push(vault); + } + }; + tasks.push(task()); + } + await Promise.all(tasks); + + return addresses; +} + +async function getAaveVaultEffectiveApy({ + aavePool, + apy, + assetAddress, + chain, + poolAddress, + vaultAddress, +}) { + const aToken = await sdk.api.abi + .call({ + target: poolAddress, + abi: 'address:aToken', + chain, + }) + .then((r) => r.output) + .catch(() => NULL_ADDRESS); + if (aToken === NULL_ADDRESS) return apy; + + const [assetsInThirdPool, idle] = await Promise.all([ + sdk.api.abi + .call({ + target: aToken, + abi: { + inputs: [{ type: 'address' }], + name: 'balanceOf', + outputs: [{ type: 'uint256' }], + }, + params: [poolAddress], + chain, + }) + .then((r) => r.output), + sdk.api.abi + .call({ + target: assetAddress, + abi: { + inputs: [{ type: 'address' }], + name: 'balanceOf', + outputs: [{ type: 'uint256' }], + }, + params: [poolAddress], + chain, + }) + .then((r) => r.output), + ]); + + const idleFund = new BigNumber(assetsInThirdPool).plus(idle); + if (idleFund.isZero()) return apy; + + const passiveRatio = new BigNumber(assetsInThirdPool).div(idleFund); + + const currentLiquidityRate = await sdk.api.abi + .call({ + target: aavePool, + abi: { + inputs: [{ type: 'address' }], + name: 'getReserveData', + outputs: [ + { + components: [ + { + components: [{ type: 'uint256', name: 'data' }], + name: 'configuration', + type: 'tuple', + }, + { type: 'uint128', name: 'liquidityIndex' }, + { type: 'uint128', name: 'currentLiquidityRate' }, + { type: 'uint128', name: 'variableBorrowIndex' }, + { type: 'uint128', name: 'currentVariableBorrowRate' }, + { type: 'uint128', name: 'currentStableBorrowRate' }, + { type: 'uint40', name: 'lastUpdateTimestamp' }, + { type: 'uint16', name: 'id' }, + { type: 'address', name: 'aTokenAddress' }, + { type: 'address', name: 'stableDebtTokenAddress' }, + { type: 'address', name: 'variableDebtTokenAddress' }, + { type: 'address', name: 'interestRateStrategyAddress' }, + { type: 'uint128', name: 'accruedToTreasury' }, + { type: 'uint128', name: 'unbacked' }, + { type: 'uint128', name: 'isolationModeTotalDebt' }, + ], + name: 'res', + type: 'tuple', + }, + ], + }, + params: [assetAddress], + chain, + }) + .then((r) => r.output.currentLiquidityRate); + + const passiveApy = new BigNumber(currentLiquidityRate).div( + new BigNumber(10).pow(27) + ); + return new BigNumber(apy).plus(passiveApy.times(passiveRatio)).toNumber(); +} + +async function getVaultEffectiveApy({ + apy, + assetAddress, + chain, + chainId, + poolAddress, + vaultAddress, +}) { + const aavePool = await sdk.api.abi + .call({ + target: poolAddress, + abi: 'address:aavePool', + chain, + }) + .then((r) => r.output) + .catch(() => NULL_ADDRESS); + if (aavePool !== NULL_ADDRESS) + return await getAaveVaultEffectiveApy({ + apy, + assetAddress, + chain, + poolAddress, + vaultAddress, + aavePool, + }); + + return apy; +} + +async function getVaultsV2({ alias, chain, chainId, number, opportunities }) { + const vaults = []; + + const addresses = await getVaultV2Addresses(chain, number).then((addresses) => + addresses.filter((a) => !VAULT_BLACKLIST[chain].includes(a)) + ); + const calls = addresses.map((target) => ({ target })); + const [apys, assets, decimalses, names, totalAssetses, pools] = + await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:apy', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'address:asset', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint8:decimals', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'string:name', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'uint256:totalAssets', + }), + sdk.api.abi.multiCall({ + chain, + calls, + abi: 'address:pool', + }), + ]); + + const [assetNames, priceMap] = await Promise.all([ + sdk.api.abi.multiCall({ + chain, + calls: assets.output.map((a) => ({ target: a.output })), + abi: 'string:symbol', + }), + getPrices( + chain, + assets.output.map((a) => a.output) + ), + ]); + + for (let i = 0; i < addresses.length; i++) { + const address = addresses[i]; + const assetAddress = assets.output[i].output; + + let apy = new BigNumber(apys.output[i].output) + .div(new BigNumber(10).pow(8)) + .toNumber(); + if (pools.output[i].output !== NULL_ADDRESS) { + apy = await getVaultEffectiveApy({ + apy, + assetAddress, + chain, + chainId, + poolAddress: pools.output[i].output, + vaultAddress: address, + }); + } + const tvlUsd = new BigNumber(totalAssetses.output[i].output) + .div(new BigNumber(10).pow(decimalses.output[i].output)) + .times(priceMap.get(assetAddress) || 0) + .toNumber(); + + const url = new URL( + `https://app.termmax.ts.finance/earn/${alias}/${address.toLowerCase()}` + ); + url.searchParams.set('chain', alias); + + const vault = { + pool: `${address}-${chain.toLowerCase()}`, + chain, + project: 'termmax', + symbol: assetNames.output[i].output, + tvlUsd, + apyBase: apy, + url: String(url), + underlyingTokens: [assetAddress], + poolMeta: names.output[i].output, + }; + + const opportunity = opportunities.find( + (o) => + o.chainId === chainId && + o.identifier.toLowerCase() === address.toLowerCase() + ); + if (opportunity) { + vault.apyReward = opportunity.apr; + + const breakdowns = + (opportunity.rewardsRecord && opportunity.rewardsRecord.breakdowns) || + []; + vault.rewardTokens = breakdowns + .map((b) => b.token.address) + .filter((a) => a); + } + + vaults.push(vault); + } + + return vaults; +} + +async function getVaultsOnChain(chain, chainId, alias) { + const vaultsOnChain = []; + + const [opportunities, { number }] = await Promise.all([ + getMerklOpportunities(), + sdk.api.util.getLatestBlock(chain), + ]); + + const tasks = []; + { + const taskV1 = async () => { + const vaultsV1 = await getVaultsV1({ + alias, + chain, + chainId, + number, + opportunities, + }); + for (const vault of vaultsV1) vaultsOnChain.push(vault); + }; + tasks.push(taskV1()); + } + { + const taskV1Plus = async () => { + const vaultsV1Plus = await getVaultsV1Plus({ + alias, + chain, + chainId, + number, + opportunities, + }); + for (const vault of vaultsV1Plus) vaultsOnChain.push(vault); + }; + tasks.push(taskV1Plus()); + } + { + const taskV2 = async () => { + const vaultsV2 = await getVaultsV2({ + alias, + chain, + chainId, + number, + opportunities, + }); + for (const vault of vaultsV2) vaultsOnChain.push(vault); + }; + tasks.push(taskV2()); + } + await Promise.all(tasks); + + return vaultsOnChain; +} + +async function apy() { + const vaults = []; + const tasks = []; + for (const key of Object.keys(VAULTS)) { + const task = async () => { + const { alias, chain, chainId } = VAULTS[key]; + const vaultsOnChain = await getVaultsOnChain(chain, chainId, alias); + for (const vault of vaultsOnChain) vaults.push(vault); + }; + tasks.push(task()); + } + await Promise.all(tasks); + return vaults; +} + +module.exports = { + apy, +}; diff --git a/src/adaptors/test.js b/src/adaptors/test.js index 2a7fee194f..7d519b708b 100644 --- a/src/adaptors/test.js +++ b/src/adaptors/test.js @@ -1,54 +1,198 @@ -const fs = require('fs'); -const path = require('path'); -require('dotenv').config({ path: './config.env' }); - -const keyType = { - tvlUsd: 'number', - apy: 'number', +const baseFields = { + pool: 'string', + chain: 'string', + project: 'string', + symbol: 'string', }; -if (process.argv.length < 3) { - console.error(`Missing argument, you need to provide the filename of the adapter to test. - Eg: node src/adaptors/test.js src/adaptors/aave/index.js`); - process.exit(1); -} -const f = process.argv[2]; -const passedFile = path.resolve(process.cwd(), f); -(async () => { - console.log(`==== Testing ${f} ====`); - - const time = () => Date.now() / 1000; - - const module = require(passedFile); - const start = time(); - let apy = await module.apy(process.argv[3]); - apy = apy.sort((a, b) => b.tvlUsd - a.tvlUsd); - - const uniquePoolIdentifiers = new Set(); - apy.map((pool) => { - if (uniquePoolIdentifiers.has(pool.pool)) { - throw new Error(`Pool identifier ${pool.pool} is repeated`); - } - uniquePoolIdentifiers.add(pool.pool); - for (const key of ['pool', 'chain', 'project', 'symbol', 'tvlUsd', 'apy']) { - const intendedType = keyType[key] ?? 'string'; - if (typeof pool[key] !== intendedType) { - throw new Error( - `Key ${key} of pool ${pool.pool} should be "${intendedType}" but is ${pool[key]}` - ); +const adapter = global.adapter; +const apy = global.apy; +const poolsUrl = global.poolsUrl; + +const uniquePoolIdentifiersDB = global.uniquePoolIdentifiersDB; +const protocols = global.protocolsSlug; + +// fast mode: only ensure adapter main function executed +if (process.env.npm_config_fast) { + describe(`Running ${process.env.npm_config_adapter} Test (fast)`, () => { + test('Adapter executed and returned an array', () => { + expect(Array.isArray(apy)).toBe(true); + }); + }); + // skip rest of the checks in fast mode +} else { + +describe(`Running ${process.env.npm_config_adapter} Test`, () => { + describe('Check for allowed field names', () => { + const optionalFields = [ + 'apy', + 'apyBase', + 'apyReward', + 'underlyingTokens', + 'rewardTokens', + 'poolMeta', + 'url', + 'apyBaseBorrow', + 'apyRewardBorrow', + 'totalSupplyUsd', + 'totalBorrowUsd', + 'ltv', + 'borrowable', + 'borrowFactor', + 'debtCeilingUsd', + 'mintedCoin', + 'apyBase7d', + 'apyRewardFake', + 'apyRewardBorrowFake', + 'il7d', + 'volumeUsd1d', + 'volumeUsd7d', + 'apyBaseInception', + ]; + const fields = [...Object.keys(baseFields), ...optionalFields, 'tvlUsd']; + apy.forEach((pool) => { + test(`Expects pool id ${ + pool.pool + } to contain only allowed keys: ${fields} and has: ${Object.keys( + pool + )}`, () => { + expect(Object.keys(pool).every((f) => fields.includes(f))).toBe(true); + }); + }); + }); + + test("Check if link to the pool's page exist", () => { + const poolsLink = apy[0].url || poolsUrl; + expect(typeof poolsLink).toBe('string'); + }); + + test('Check for unique pool ids', () => { + const poolIds = apy.map((pool) => pool.pool); + const uniquePoolIds = [...new Set(poolIds)]; + expect(poolIds).toEqual(uniquePoolIds); + }); + + describe('Check apy data types', () => { + const apyFields = ['apy', 'apyBase', 'apyReward']; + + apy.forEach((pool) => { + test(`Expects pool with id ${pool.pool} to have at least one number apy field`, () => { + expect( + apyFields.map((field) => Number.isFinite(pool[field])) + ).toContain(true); + }); + }); + }); + + describe('Check tvl data type', () => { + apy.forEach((pool) => { + test(`tvlUsd field of pool with id ${pool.pool} should be number `, () => { + expect(Number.isFinite(pool.tvlUsd)).toBe(true); + }); + }); + }); + + describe('Check tokens data types', () => { + const tokenFields = ['rewardTokens', 'underlyingTokens']; + + apy.forEach((pool) => { + tokenFields.forEach((field) => { + if (pool[field]) { + test(`${field} field of pool with id ${pool.pool} should be an Array of strings`, () => { + expect(Array.isArray(pool[field])).toBe(true); + const isStringArray = + pool[field].map((v) => typeof v).filter((v) => v === 'string') + .length === pool[field].length; + expect(isStringArray).toBe(true); + }); + } + }); + }); + }); + + describe('Check other fields data types', () => { + apy.forEach((pool) => { + test(`Expect other fields of pool with id ${pool.pool} to match thier data types`, () => { + Object.entries(baseFields).map(([field, type]) => { + expect(typeof pool[field]).toBe(type); + }); + }); + }); + }); + + describe('Check if pool has a rewardApy then rewardTokens must also exist', () => { + apy.forEach((pool) => { + test(`The pool ${pool.pool} is expected to have a rewardTokens field`, () => { + if (pool.apyReward) + expect((pool.rewardTokens || []).length).toBeGreaterThan(0); + }); + }); + }); + + describe('Check if pool id already used by other project', () => { + const uniqueIds = new Set(apy.map(({ pool }) => pool)); + const duplicatedPoolIds = [...uniqueIds].filter((p) => + uniquePoolIdentifiersDB.has(p) + ); + + test('Print duplicated pool IDs and their existing projects', () => { + if (duplicatedPoolIds.length > 0) { + console.log('\nDuplicated pool IDs found:'); + duplicatedPoolIds.forEach((poolId) => { + console.log(`Pool ID: ${poolId} is already used by another project`); + }); } - } + expect(duplicatedPoolIds.length).toBe(0); + }); }); - console.log(`\nNb of pools: ${apy.length}\n `); - console.log('\nSample pools:', apy.slice(0, 10)); - console.log(`\nRuntime: ${(time() - start).toFixed(2)} sec`); + test('Check project field is constant in all pools and if folder name and project field in pool objects matches the information in /protocols slug', () => { + expect(new Set(apy.map((p) => p.project)).size).toBe(1); + expect( + protocolsSlug.includes(apy[0].project) && apy[0].project === adapter + ).toBe(true); + }); - // store full adaptor output for checks - fs.writeFileSync( - `./${f.split('/').slice(-2, -1)[0] + '_output'}.json`, - JSON.stringify(apy) - ); + describe('Check additional field data rules', () => { + // All fields added here are treated as optional + // If a field is present, it will be checked against its rules + let additionalFieldRules = { + totalSupplyUsd: { + type: 'number', + }, + totalBorrowUsd: { + type: 'number', + }, + ltv: { + min: 0, + max: 1, + }, + }; - process.exit(0); -})(); + apy.forEach((pool) => { + Object.entries(additionalFieldRules).map(([field, rule]) => { + if (pool[field] !== undefined) { + if (rule.type !== undefined) { + test(`${field} field of pool with id ${pool.pool} should be a ${rule.type}`, () => { + expect(typeof pool[field]).toBe(rule.type); + }); + } + if (rule.max !== undefined && rule.min !== undefined) { + test(`${field} field of pool with id ${pool.pool} should be in the range of ${rule.min}-${rule.max}`, () => { + expect(pool[field]).toBeLessThanOrEqual(rule.max); + }); + } else if (rule.min !== undefined && rule.max === undefined) { + test(`${field} field of pool with id ${pool.pool} should be greater than or equal to ${rule.min}`, () => { + expect(pool[field]).toBeGreaterThanOrEqual(rule.min); + }); + } else if (rule.max !== undefined && rule.min === undefined) { + test(`${field} field of pool with id ${pool.pool} should be less than or equal to ${rule.max}`, () => { + expect(pool[field]).toBeLessThanOrEqual(rule.max); + }); + } + } + }); + }); + }); +}); +} diff --git a/src/adaptors/tetu-earn/abi.json b/src/adaptors/tetu-earn/abi.json new file mode 100644 index 0000000000..dd75fc6938 --- /dev/null +++ b/src/adaptors/tetu-earn/abi.json @@ -0,0 +1,2325 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "ToolAddressUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldValue", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "UpdateController", + "type": "event" + }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bookkeeper", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "computeApr", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + }, + { + "internalType": "address", + "name": "rt", + "type": "address" + } + ], + "name": "computeRewardApr", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "adr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "created", + "outputs": [ + { + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + }, + { + "internalType": "address", + "name": "_calculator", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "initializeControllable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_adr", + "type": "address" + } + ], + "name": "isController", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_adr", + "type": "address" + } + ], + "name": "isGovernance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceCalculator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newValue", + "type": "address" + } + ], + "name": "setPriceCalculator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strategies", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "strategiesLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyAssets", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyCreated", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyPausedInvesting", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyPlatform", + "outputs": [ + { + "internalType": "enum IStrategy.Platform", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_strategy", + "type": "address" + } + ], + "name": "strategyRewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tetuTokenValues", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "totalTetuBoughBack", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_strategies", + "type": "address[]" + } + ], + "name": "totalTetuBoughBack2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "totalTvlUsdc", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "totalUsers", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUsersForAllVaults", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userDepositedShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userDepositedUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userDepositedUnderlyingUsdc", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingBalanceUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoost", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoostUsdc", + "type": "uint256[]" + } + ], + "internalType": "struct ContractReader.UserInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userInfoLight", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.UserInfoLight", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "userInfosLight", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.UserInfoLight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userRewards", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userRewardsBoost", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userRewardsBoostUsdc", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userRewardsUsdc", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userUnderlyingBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "userUnderlyingBalanceUsdc", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultCreated", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "vaultInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBal", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBalUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "users", + "type": "uint256" + }, + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strategyCreated", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "strategyRewards", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "strategyOnPause", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "vaultInfoLight", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfoLight", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "vaultInfos", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBal", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBalUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "users", + "type": "uint256" + }, + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strategyCreated", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "strategyRewards", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "strategyOnPause", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "vaultInfosLight", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfoLight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultPlatform", + "outputs": [ + { + "internalType": "enum IStrategy.Platform", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultPpfs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultPpfsApr", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultPpfsLastApr", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultRewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultRewardTokensBal", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultRewardTokensBalUsdc", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultRewardsApr", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultTvl", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultTvlUsdc", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultUnderlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vault", + "type": "address" + } + ], + "name": "vaultUsers", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "page", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pageSize", + "type": "uint256" + } + ], + "name": "vaultWithUserInfoPages", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBal", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBalUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "users", + "type": "uint256" + }, + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strategyCreated", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "strategyRewards", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "strategyOnPause", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfo", + "name": "vault", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingBalanceUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoost", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoostUsdc", + "type": "uint256[]" + } + ], + "internalType": "struct ContractReader.UserInfo", + "name": "user", + "type": "tuple" + } + ], + "internalType": "struct ContractReader.VaultWithUserInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "page", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pageSize", + "type": "uint256" + } + ], + "name": "vaultWithUserInfoPagesLight", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfoLight", + "name": "vault", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.UserInfoLight", + "name": "user", + "type": "tuple" + } + ], + "internalType": "struct ContractReader.VaultWithUserInfoLight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "vaultWithUserInfos", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBal", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardTokensBalUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "users", + "type": "uint256" + }, + { + "internalType": "address", + "name": "strategy", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strategyCreated", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "strategyRewards", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "strategyOnPause", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfo", + "name": "vault", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "underlyingBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "underlyingBalanceUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsUsdc", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoost", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsBoostUsdc", + "type": "uint256[]" + } + ], + "internalType": "struct ContractReader.UserInfo", + "name": "user", + "type": "tuple" + } + ], + "internalType": "struct ContractReader.VaultWithUserInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_vaults", + "type": "address[]" + } + ], + "name": "vaultWithUserInfosLight", + "outputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "created", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tvlUsdc", + "type": "uint256" + }, + { + "internalType": "address", + "name": "underlying", + "type": "address" + }, + { + "internalType": "address[]", + "name": "rewardTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "rewardsApr", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "ppfsApr", + "type": "uint256" + }, + { + "internalType": "enum IStrategy.Platform", + "name": "platform", + "type": "uint8" + }, + { + "internalType": "address[]", + "name": "assets", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "earned", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.VaultInfoLight", + "name": "vault", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "depositedUnderlying", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedUnderlyingUsdc", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositedShare", + "type": "uint256" + } + ], + "internalType": "struct ContractReader.UserInfoLight", + "name": "user", + "type": "tuple" + } + ], + "internalType": "struct ContractReader.VaultWithUserInfoLight[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaults", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/tetu-earn/index.js b/src/adaptors/tetu-earn/index.js new file mode 100644 index 0000000000..7704ed0f9a --- /dev/null +++ b/src/adaptors/tetu-earn/index.js @@ -0,0 +1,101 @@ +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); + +const POLY_BOOKKEEPER = '0x0A0846c978a56D6ea9D2602eeb8f977B21F3207F'; +const POLY_CONTRACT_READER = '0xCa9C8Fba773caafe19E6140eC0A7a54d996030Da'; + +const FTM_BOOKKEEPER = '0x00379dD90b2A337C4652E286e4FBceadef940a21'; +const FTM_CONTRACT_READER = '0xa4EB2E1284D9E30fb656Fe6b34c1680Ef5d4cBFC'; + +const TETU_Reward_Token_FTM = '0x65c9d9d080714cDa7b5d58989Dc27f897F165179'; +const TETU_Reward_Token_MATIC = '0x255707B70BF90aa112006E1b07B9AeA6De021424'; + +const chainDataMap = { + polygon: { + BOOKKEEPER_ADDRESS: POLY_BOOKKEEPER, + CONTRACT_READER: POLY_CONTRACT_READER, + BASE_REWARD_TOKEN: TETU_Reward_Token_MATIC, + }, + fantom: { + BOOKKEEPER_ADDRESS: FTM_BOOKKEEPER, + CONTRACT_READER: FTM_CONTRACT_READER, + BASE_REWARD_TOKEN: TETU_Reward_Token_FTM, + }, +}; + +const apyChain = async (chain) => { + const vaultsAdderssCall = await sdk.api.abi.call({ + abi: abi.find((e) => e.name === 'vaults'), + chain: chain, + target: chainDataMap[chain]['BOOKKEEPER_ADDRESS'], + params: [], + }); + const vaultAddress = vaultsAdderssCall.output; + + const vaultInfoCall = await sdk.api.abi.multiCall({ + abi: abi.find((e) => e.name === 'vaultInfo'), + calls: vaultAddress.map((vault) => ({ + target: chainDataMap[chain]['CONTRACT_READER'], + params: vault, + })), + chain: chain, + permitFailure: true, + }); + + const vaultInfo = vaultInfoCall.output + .map((e) => e.output) + .filter((e) => e?.active) + .filter((e) => e.ppfsApr !== 0); + + const lpSymbol = await Promise.all( + vaultInfo.map(async (pool, i) => + ( + await sdk.api.abi.multiCall({ + calls: pool.assets.map((assetsAddress) => ({ + target: assetsAddress, + })), + abi: 'erc20:symbol', + chain: chain, + permitFailure: true, + }) + ).output.map(({ output }) => output) + ) + ); + + const result = vaultInfo.map((pool, index) => { + const tvlUsd = BigNumber(pool.tvlUsdc).div(BigNumber('10').pow(18)); + const ppfsApr = BigNumber(pool.ppfsApr || '0').div(BigNumber('10').pow(18)); + const rewardApr = pool.rewardsApr + .reduce((acc, pev) => acc.plus(BigNumber(pev)), BigNumber('0')) + .div(BigNumber('10').pow(18)); + + return { + pool: `${pool.addr}-${chain}`, + chain: utils.formatChain(chain), + project: 'tetu-earn', + symbol: lpSymbol[index].join('-'), + tvlUsd: tvlUsd.toNumber(), + apyReward: rewardApr.toNumber(), + apyBase: ppfsApr.toNumber(), + rewardTokens: pool.rewardTokens.length + ? pool.rewardTokens + : [chainDataMap[chain]['BASE_REWARD_TOKEN']], + url: `https://app.tetu.io/vault/${pool.addr}`, + underlyingTokens: pool.assets, + }; + }); + return result; +}; + +async function apy() { + const apyPolygon = await apyChain('polygon'); + const apyFantom = await apyChain('fantom'); + return apyPolygon.concat(apyFantom); +} + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/thalaswap-v2/index.js b/src/adaptors/thalaswap-v2/index.js new file mode 100644 index 0000000000..bc065b168c --- /dev/null +++ b/src/adaptors/thalaswap-v2/index.js @@ -0,0 +1,73 @@ +const utils = require('../utils'); + +const thalaswapV2Address = + '0x7730cd28ee1cdc9e999336cbc430f99e7c44397c0aa77516f6f23a78559bb5'; +const THALA_DAPP_URL = 'http://app.thala.fi'; +const THALA_POOL_API_URL = `${THALA_DAPP_URL}/api/liquidity-pool`; +const THALA_COIN_INFO_URL = `${THALA_DAPP_URL}/api/coin-info`; + +const coinInfoCache = {}; + +async function main() { + // We use Thala's API and not resources on chain as there are too many pools to parse and query + // for TVL, APR, etc. metrics. This way we fetch all our pools with TVL attached, then can filter. + const liquidityPools = (await utils.getData(`${THALA_POOL_API_URL}s`)) + ?.data; + if (!liquidityPools) { + return []; + } + const filteredPools = liquidityPools.filter((pool) => pool.tvl > 10000); + const v2Pools = filteredPools.filter((pool) => pool.metadata.isV2 === true); + + const tvlArr = []; + for (const liquidityPool of v2Pools) { + const swapFeesApr = liquidityPool.apr.find(item => item.source === 'Swap Fees')?.apr; + const farmingTHLApr = liquidityPool.apr.find(item => item.source === 'THL')?.apr; + const farmingTHAPTApr = liquidityPool.apr.find(item => item.source === 'thAPT')?.apr; + const rewardTokens = []; + + // Check and push for THL + if (farmingTHLApr > 0) { + rewardTokens.push('0x7fd500c11216f0fe3095d0c4b8aa4d64a4e2e04f83758462f2b127255643615::thl_coin::THL'); + } + // Check and push for thAPT + if (farmingTHAPTApr > 0) { + rewardTokens.push('0xfaf4e633ae9eb31366c9ca24214231760926576c7b625313b3688b5e900731f6::staking::ThalaAPT'); + } + const coinInfos = await Promise.all(liquidityPool.metadata.coinAddresses.map(async (address) => await getCoinInfoWithCache(address))); + const coinNames = coinInfos.map((coinInfo) => coinInfo.symbol).join('-'); + tvlArr.push({ + pool: + liquidityPool.metadata.type + '-aptos', + chain: utils.formatChain('aptos'), + project: 'thalaswap-v2', + apyBase: (swapFeesApr ?? 0) * 100, + apyReward: ((farmingTHLApr ?? 0) + (farmingTHAPTApr ?? 0)) * 100, + rewardTokens, + symbol: coinNames, + tvlUsd: liquidityPool.tvl, + underlyingTokens: liquidityPool.metadata.coinAddresses, + url: `${THALA_DAPP_URL}/pools/${liquidityPool.metadata.type}`, + }); + } + + return tvlArr; +} + +async function getCoinInfoWithCache(coinAddress) { + if (coinInfoCache[coinAddress]) { + return coinInfoCache[coinAddress]; + } + + const coinInfo = await utils.getData(`${THALA_COIN_INFO_URL}?coin=${coinAddress}`); + console.log(coinAddress, coinInfo); + coinInfoCache[coinAddress] = coinInfo?.data; + + return coinInfo?.data; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.thala.fi/pools', +}; diff --git a/src/adaptors/thalaswap/index.js b/src/adaptors/thalaswap/index.js new file mode 100644 index 0000000000..54a1286a08 --- /dev/null +++ b/src/adaptors/thalaswap/index.js @@ -0,0 +1,76 @@ +const utils = require('../utils'); + +const thalaswapAddress = + '0x48271d39d0b05bd6efca2278f22277d6fcc375504f9839fd73f74ace240861af'; +const THALA_DAPP_URL = 'http://app.thala.fi'; +const THALA_POOL_API_URL = `${THALA_DAPP_URL}/api/liquidity-pool`; +const THALA_COIN_INFO_URL = `${THALA_DAPP_URL}/api/coin-info`; +const stablePoolType = `${thalaswapAddress}::stable_pool::StablePool<`; +const weightedPoolType = `${thalaswapAddress}::weighted_pool::WeightedPool<`; + +const coinInfoCache = {}; + +async function main() { + // We use Thala's API and not resources on chain as there are too many pools to parse and query + // for TVL, APR, etc. metrics. This way we fetch all our pools with TVL attached, then can filter. + const liquidityPools = (await utils.getData(`${THALA_POOL_API_URL}s`)) + ?.data; + if (!liquidityPools) { + return []; + } + const filteredPools = liquidityPools.filter((pool) => pool.tvl > 10000); + const v1Pools = filteredPools.filter((pool) => pool.metadata.isV2 === false); + + const tvlArr = []; + for (const liquidityPool of v1Pools) { + const swapFeesApr = liquidityPool.apr.find(item => item.source === 'Swap Fees')?.apr; + const farmingTHLApr = liquidityPool.apr.find(item => item.source === 'THL')?.apr; + const farmingTHAPTApr = liquidityPool.apr.find(item => item.source === 'thAPT')?.apr; + const rewardTokens = []; + + // Check and push for THL + if (farmingTHLApr > 0) { + rewardTokens.push('0x7fd500c11216f0fe3095d0c4b8aa4d64a4e2e04f83758462f2b127255643615::thl_coin::THL'); + } + // Check and push for thAPT + if (farmingTHAPTApr > 0) { + rewardTokens.push('0xfaf4e633ae9eb31366c9ca24214231760926576c7b625313b3688b5e900731f6::staking::ThalaAPT'); + } + const coinInfos = await Promise.all(liquidityPool.metadata.coinAddresses.map(async (address) => await getCoinInfoWithCache(address))); + const coinNames = coinInfos.map((coinInfo) => coinInfo.symbol).join('-'); + tvlArr.push({ + pool: + (liquidityPool.metadata.poolType === 'Stable' ? stablePoolType : weightedPoolType) + + coinNames + + '>', + chain: utils.formatChain('aptos'), + project: 'thalaswap', + apyBase: (swapFeesApr ?? 0) * 100, + apyReward: ((farmingTHLApr ?? 0) + (farmingTHAPTApr ?? 0)) * 100, + rewardTokens, + symbol: coinNames, + tvlUsd: liquidityPool.tvl, + underlyingTokens: liquidityPool.metadata.coinAddresses, + url: `${THALA_DAPP_URL}/pools/${liquidityPool.metadata.type}`, + }); + } + + return tvlArr; +} + +async function getCoinInfoWithCache(coinAddress) { + if (coinInfoCache[coinAddress]) { + return coinInfoCache[coinAddress]; + } + + const coinInfo = await utils.getData(`${THALA_COIN_INFO_URL}?coin=${coinAddress}`); + coinInfoCache[coinAddress] = coinInfo?.data; + + return coinInfo?.data; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.thala.fi/pools', +}; diff --git a/src/adaptors/the-standard/index.js b/src/adaptors/the-standard/index.js new file mode 100644 index 0000000000..9d8ed7a1d9 --- /dev/null +++ b/src/adaptors/the-standard/index.js @@ -0,0 +1,135 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { default: BigNumber } = require('bignumber.js'); +const { parseUnits, formatUnits } = require('ethers/lib/utils'); + +const MASTERCHEF = '0x8a8fde5d57725f070bfc55cd022b924e1c36c8a0'; + +const gammaPools = [ + '0x52ee1FFBA696c5E9b0Bc177A9f8a3098420EA691', + '0x6B7635b7d2E85188dB41C3c05B1efa87B143fcE8', + '0xfA392dbefd2d5ec891eF5aEB87397A89843a8260', + '0xF08BDBC590C59cb7B27A8D224E419ef058952b5f', + '0x547a116a2622876ce1c8d19d41c683c8f7bec5c0', + '0x95375694685E39997828Ed5B17f30f0A3eD90537', + '0xa7fce463815f18dbe246152c5291b84db07c0bcd' +]; + +const unwrappedTokenData = async (tokenAddress, tokenAmount) => { + try { + const priceKey = `arbitrum:${tokenAddress}`; + const { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${priceKey}` + ); + const tokenData = coins[priceKey]; + + if (!tokenData) { + console.log(`No price data found for token: ${priceKey}`); + return [null, 0]; + } + + return [ + tokenData.symbol, + formatUnits(tokenAmount, tokenData.decimals) * tokenData.price, + ]; + } catch (error) { + console.error(`Error fetching price for token ${tokenAddress}:`, error); + return [null, 0]; + } +}; + +const getApy = async () => { + const poolData = await utils.getData( + 'https://wire3.gamma.xyz/frontend/hypervisors/allDataSummary?chain=arbitrum&protocol=uniswapv3' + ); + const rewardData = await utils.getData( + 'https://wire2.gamma.xyz/arbitrum/allRewards2' + ); + + return ( + await Promise.all( + poolData + .filter((result) => + gammaPools + .map((pool) => pool.toLowerCase()) + .includes(result.address.toLowerCase()) + ) + .map(async (pool) => { + try { + const gammaPool = gammaPools.filter( + (p) => p.toLowerCase() === pool.address + )[0]; + const poolRewardData = rewardData[MASTERCHEF].pools[pool.address]; + let poolRewardTokens = []; + if (pool.rewardsDetails) { + poolRewardTokens = [ + ...poolRewardTokens, + ...pool.rewardsDetails.map((reward) => reward.rewardToken), + ]; + } + + const token0 = ( + await sdk.api.abi.call({ + target: pool.address, + abi: 'address:token0', + chain: 'arbitrum', + }) + ).output; + + const token1 = ( + await sdk.api.abi.call({ + target: pool.address, + abi: 'address:token1', + chain: 'arbitrum', + }) + ).output; + + const totalAmounts = ( + await sdk.api.abi.call({ + target: pool.address, + abi: 'function getTotalAmounts() view returns (uint256 token0Bal, uint256 token1Bal)', + chain: 'arbitrum', + }) + ).output; + + const [token0Symbol, token0TVLUSD] = await unwrappedTokenData( + token0, + totalAmounts[0] + ); + const [token1Symbol, token1TVLUSD] = await unwrappedTokenData( + token1, + totalAmounts[1] + ); + + if (!token0Symbol || !token1Symbol) { + console.log( + `Missing token symbol data for pool: ${pool.address}` + ); + return null; + } + + return { + pool: `${pool.address}-arbitrum`, + chain: 'Arbitrum', + project: 'the-standard', + symbol: `${token0Symbol}-${token1Symbol}`, + tvlUsd: token0TVLUSD + token1TVLUSD, + apyBase: parseFloat(pool.feeApr) * 100, + apyReward: parseFloat(pool.rewardApr) * 100, + rewardTokens: poolRewardTokens, + underlyingTokens: [token0, token1], + }; + } catch (error) { + console.error(`Error processing pool ${pool.address}:`, error); + return null; + } + }) + ) + ).filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.thestandard.io', +}; diff --git a/src/adaptors/thegoblins/index.js b/src/adaptors/thegoblins/index.js new file mode 100644 index 0000000000..480d19ad97 --- /dev/null +++ b/src/adaptors/thegoblins/index.js @@ -0,0 +1,55 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const bankAbi = { + inputs: [], + name: 'getLastUpdatedModulesBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', +}; + +async function bankTvl() { + const totalBalance = ( + await sdk.api.abi.call({ + abi: bankAbi, + chain: 'arbitrum', + target: '0xceF63C8507004a8d079daE3c83e369De0Adfa7Aa', + params: [], + }) + ).output; + + return totalBalance; +} + +const poolsFunction = async () => { + const bankApy = await utils.getData( + 'https://api.thegoblins.finance/aggregator/performance' + ); + + const key = 'arbitrum:0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'; + const price = ( + await superagent.get(`https://coins.llama.fi/prices/current/${key}`) + ).body.coins[key].price; + + const tvl = await bankTvl(); + + const bank = { + pool: '0xceF63C8507004a8d079daE3c83e369De0Adfa7Aa', + chain: utils.formatChain('arbitrum'), + project: 'thegoblins', + symbol: utils.formatSymbol('USDC.e'), + tvlUsd: (tvl / 1e6) * price, + apy: bankApy.last24hApy * 100, + underlyingTokens: ['0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8'], + }; + + return [bank]; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://thegoblins.finance', +}; diff --git a/src/adaptors/thena-fusion/index.js b/src/adaptors/thena-fusion/index.js new file mode 100644 index 0000000000..05fba45561 --- /dev/null +++ b/src/adaptors/thena-fusion/index.js @@ -0,0 +1,302 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { print } = require('graphql'); + +const EXCHANGES_API = { + thena: 'thena/', +}; +const EXCHANGES_CHAINS = { + thena: ['bsc'], +}; +const CHAINS_API = { + bsc: 'bsc/', +}; +const CHAIN_IDS = { + bsc: 56, +}; +const UNISWAP_FEE = { + 100: '0.01%', + 500: '0.05%', + 1000: '0.1%', + 3000: '0.3%', + 10000: '1%', + 0: '', +}; + +var pools_processed = []; // unique pools name +// v1 pools (read only) and private hypervisors ( non retail) +const blacklist = { + ethereum: [ + '0xd930ab15c8078ebae4ac8da1098a81583603f7ce', + '0xdbaa93e030bf2983add67c851892a9e2ee51e66a', + '0x586880065937a0b1b9541723619b75739df8ef13', + '0x33412fef1af035d6dba8b2f9b33b022e4c31dbb4', + '0xf6eeca73646ea6a5c878814e6508e87facc7927c', + '0x336d7e0a0f87e2729c0080f86801e6f4becf146f', + '0xc86b1e7fa86834cac1468937cdd53ba3ccbc1153', + '0x85cbed523459b7f6f81c11e710df969703a8a70c', + '0x7f92463e24b2ea1f7267aceed3ad68f7a956d2d8', + '0x23c85dca3d19b31f14aeea19beac32c2cb2ffc72', + '0x5230371a6d5311b1d7dd30c0f5474c2ef0a24661', + '0xc14e7ec60699a39cfd59bae06168afc2c76f32ac', + '0xbff4a47a0f77637f735e3a0ce10ff2bf9be12e89', + '0x93acb12ae1effb3426220c20c6d408eeaae59d72', + '0x65bc5c6a2630a87c2b494f36148e338dd76c054f', + '0xed354a827d99992d9cdada809449985cb73b8bb1', + '0xb666bfdb553a1aff4042c1e4f39e43852ba9731d', + '0xbb9b86a75ca3115caab045e2af17b0bba483acbc', + '0x0407c810546f1dc007f01a80e65983072d5c6dfa', + '0x4564a37c88e3b13d3a0c08832dcf88278997e6fe', + '0xd8dbdb77305898365d7ba6dd438f2663f7d4e409', + '0x33682bfc1d94480a0e3de0a565180b182b71d485', + '0x53a4512bbe5083695d8e890789fe1cf6f5686d52', + '0x09b8d86c6275e707155cdb5963cf611a432ccb21', + '0xc92ff322c8a18e38b46393dbcc8a7c5691586497', + '0x6e67bb258b6485b688cbb526c868d4428b634cf1', + '0x18d3284d9eff64fc97b64ab2b871738e684aa151', + '0x407e99b20d61f245426031df872966953909e9d3', + '0x97491b65c9c8e8754b5c55ed208ff490b2ee6190', + '0x6c8116abe5c5f2c39553c6f4217840e71462539c', + '0x716bd8a7f8a44b010969a1825ae5658e7a18630d', + '0x9a98bffabc0abf291d6811c034e239e916bbcec0', + '0xe065ff6a26f286ddb0e823920caaecd1fcd57ba1', + '0x5d40e4687e36628267854d0b985a9b6e26493b74', + '0xf0a9f5c64f80fa390a46b298791dab9e2bb29bca', + '0xe14dbb7d054ff1ff5c0cd6adac9f8f26bc7b8945', + '0xa625ea468a4c70f13f9a756ffac3d0d250a5c276', + ], + optimism: [], + polygon: [], + polygon_zkevm: [], + arbitrum: [], + celo: [], + bsc: [], + moonbeam: [], + avalanche: [], + fantom: [], + mantle: [], + base: [], + linea: [], + rollux: [], +}; +const masterchef_blacklist = { + bsc: [], +}; +const getUrl_allData = (chain, exchange) => + `https://wire2.gamma.xyz/${exchange}${chain}hypervisors/allData`; + +const getUrl_allRewards2 = (chain, exchange) => + `https://wire2.gamma.xyz/${exchange}${chain}allRewards2`; + +const pairsToObj = (pairs) => + pairs.reduce((acc, [el1, el2]) => ({ ...acc, [el1]: el2 }), {}); + +const getApy = async () => { + var hype_allData = {}; + for (const [exchange, chains] of Object.entries(EXCHANGES_CHAINS)) { + try { + let tmp_dict = pairsToObj( + await Promise.all( + Object.values(chains).map(async (chain) => [ + chain, + await utils.getData( + getUrl_allData(CHAINS_API[chain], EXCHANGES_API[exchange]) + ), + ]) + ) + ); + + Object.entries(tmp_dict).forEach(([chain, hypervisors]) => { + // include exchange to hypervisor dta + Object.entries(hypervisors).forEach(([hyp_id, hyp_dta]) => { + hyp_dta['dex'] = exchange; + }); + + if (chain in hype_allData) { + hype_allData[chain] = Object.assign(hype_allData[chain], hypervisors); + } else { + hype_allData[chain] = hypervisors; + } + }); + } catch (error) { + console.log(error); + } + + // try add rewards + try { + let tmp_rwrds_dict = await Promise.allSettled( + Object.values(chains).map(async (chain) => [ + chain, + await utils.getData( + getUrl_allRewards2(CHAINS_API[chain], EXCHANGES_API[exchange]) + ), + ]) + ).then((results) => { + results.forEach((result) => { + if (result.status == 'fulfilled') { + // result.value[0] = chain + // result.value[1] = items + Object.entries(result.value[1]).forEach(([chef_id, chef_dta]) => { + if ( + masterchef_blacklist[result.value[0]].indexOf(chef_id) == -1 + ) { + Object.entries(chef_dta['pools']).forEach(([k, v]) => { + if (k in hype_allData[result.value[0]]) { + if (!('apr_rewards2' in hype_allData[result.value[0]][k])) { + hype_allData[result.value[0]][k]['apr_rewards2'] = []; + } + hype_allData[result.value[0]][k]['apr_rewards2'].push(v); + } + }); + } + }); + } + }); + }); + } catch (error) { + console.log(error); + } + } + + const tokens = Object.entries(hype_allData).reduce( + (acc, [chain, hypervisors]) => ({ + ...acc, + [chain]: [ + ...new Set( + Object.values(hypervisors) + .map((hypervisor) => [hypervisor.token0, hypervisor.token1]) + .flat() + ), + ], + }), + {} + ); + + let keys = []; + for (const key of Object.keys(tokens)) { + keys.push(tokens[key].map((t) => `${key}:${t}`)); + } + keys = [...new Set(keys.flat())]; + + const maxSize = 50; + const pages = Math.ceil(keys.length / maxSize); + let pricesA = []; + let url = ''; + for (const p of [...Array(pages).keys()]) { + url = keys + .slice(p * maxSize, maxSize * (p + 1)) + .join(',') + .toLowerCase(); + pricesA = [ + ...pricesA, + (await superagent.get(`https://coins.llama.fi/prices/current/${url}`)) + .body.coins, + ]; + } + let prices = {}; + for (const p of pricesA) { + prices = { ...prices, ...p }; + } + + const pools = Object.keys(hype_allData).map((chain) => { + const chainAprs = Object.keys(hype_allData[chain]) + .filter(function (hypervisor_id) { + if (blacklist[chain].indexOf(hypervisor_id) >= 0) { + return false; + } else { + return true; + } + }) + .map((hypervisor_id) => { + // MAIN CALC + const hypervisor = hype_allData[chain][hypervisor_id]; + const TVL = + hypervisor.tvl0 * prices[`${chain}:${hypervisor.token0}`]?.price + + hypervisor.tvl1 * prices[`${chain}:${hypervisor.token1}`]?.price; + const apy = hypervisor['returns']['daily']['feeApy']; + const apr = hypervisor['returns']['daily']['feeApr']; + const TVL_alternative = Number(hypervisor.tvlUSD); + + // rewards + let apr_rewards2 = 0; + const rewards2_tokens = new Set(); + try { + hype_allData[chain][hypervisor_id]['apr_rewards2'].forEach((item) => { + // sum of all + apr_rewards2 += item['apr']; + // add token addresses + Object.entries(item['rewarders']).forEach(([k, v]) => { + rewards2_tokens.add(v['rewardToken']); + }); + }); + } catch (error) {} + + // create a unique pool name + var pool_name = hypervisor_id; + if (pools_processed.indexOf(pool_name) >= 0) { + pool_name = `${hypervisor_id}-${ + chain === 'polygon_zkevm' + ? 'Polygon_zkevm' + : utils.formatChain(chain) + }`; + } + pools_processed.push(pool_name); + + // create a symbol + var symbol_name = hypervisor.name; + let fee_name = ''; + // uniswap (fee%) quickswap no fee + try { + var symbol_spl = hypervisor.name.split('-'); + fee_name = `${UNISWAP_FEE[symbol_spl[symbol_spl.length - 1]]}`; + if (fee_name == ' undefined' || fee_name == 'undefined') { + fee_name = ''; + } + symbol_spl.pop(); + symbol_name = symbol_spl.join('-'); + //symbol_name = `${prices[`${chain}:${hypervisor.token0}`]?.symbol}-${prices[`${chain}:${hypervisor.token1}`]?.symbol}${fee_name}`; + if (symbol_name.includes('undefined')) { + symbol_name = hypervisor.name; + } + } catch { + symbol_name = hypervisor.name; + } + + return { + pool: `${pool_name}-Binance`, + chain: utils.formatChain(chain), + project: 'thena-fusion', + symbol: `${symbol_name}`, + tvlUsd: TVL || TVL_alternative, + apyBase: apr * 100 || apy * 100, + apyReward: apr_rewards2 * 100, + rewardTokens: [...rewards2_tokens], + underlyingTokens: [hypervisor.token0, hypervisor.token1], + poolMeta: fee_name, + }; + }); + return chainAprs; + }); + + // pools on optimism which have wrong reward apy + const x = [ + '0x431f6e577a431d9ee87a535fde2db830e352e33c', + '0xed17209ab7f9224e29cc9894fa14a011f37b6115', + ]; + return pools + .flat() + .map((i) => ({ + ...i, + apyReward: x.includes(i.pool) ? null : i.apyReward, + rewardTokens: x.includes(i.pool) ? null : i.rewardTokens, + })) + .filter((i) => i.chain === 'Binance'); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.gamma.xyz/dashboard', +}; diff --git a/src/adaptors/thena-v1/index.js b/src/adaptors/thena-v1/index.js new file mode 100644 index 0000000000..8a7c9dd7c7 --- /dev/null +++ b/src/adaptors/thena-v1/index.js @@ -0,0 +1,126 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); + +const API_URL = 'https://api.thena.fi/api/v1/fusions'; + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint('FKEt2N5VmSdEYcz7fYLPvvnyEUkReQ7rvmXzs6tiKCz1'); + +const swapPairsQuery = (skip) => { + return gql` + query MyQuery { + pairs(first: 100, skip: ${skip}, where: {reserveUSD_gt: 10000}) { + reserve0 + reserve1 + token1 { + id + symbol + } + token0 { + id + symbol + } + reserveUSD + id + } + } + `; +}; + +const getPairs = async () => { + let pairs = []; + let index = 0; + let res; + do { + res = await request(SUBGRAPH_URL, swapPairsQuery(index), {}); + if (res.pairs.length > 0) { + pairs = [...pairs, ...res.pairs]; + } + index += res.pairs.length; + } while (res.pairs.length > 0); + return pairs; +}; + +const getApy = async () => { + // APR is retrieved using our api, tvl pairs etc trough subgraph + const poolsRes = (await axios.get(API_URL)).data.data; + + const apyDict = {}; + const alreadySeen = []; + + const v1Pools = poolsRes.filter((pool) => !pool.isGamma); + + for (const pool of poolsRes) { + apyDict[pool.address.toLowerCase()] = pool.gauge.apr; + } + + const pairs = await getPairs(); + for (const pair of pairs) { + const token0Key = 'bsc:' + pair.token0.id.toLowerCase(); + const token1Key = 'bsc:' + pair.token1.id.toLowerCase(); + + if (!alreadySeen.includes(token0Key)) { + alreadySeen.push(token0Key); + } + + if (!alreadySeen.includes(token1Key)) { + alreadySeen.push(token1Key); + } + } + + // asking price to defillama chunking requests (currently running with 1 request could be lowered if needed) + let fullCoin = {}; + const chunkSize = 60; + for (let i = 0; i < alreadySeen.length; i += chunkSize) { + const chunk = alreadySeen.slice(i, i + chunkSize); + + const { coins } = await utils.getData( + `https://coins.llama.fi/prices/current/${chunk.join(',')}?searchWidth=4h` + ); + fullCoin = { ...fullCoin, ...coins }; + } + + const pools = pairs.map((pair) => { + let tvl = 0; + + if ( + fullCoin['bsc:' + pair.token0.id.toLowerCase()] && + fullCoin['bsc:' + pair.token1.id.toLowerCase()] + ) { + const token0ValueInReserve = + parseFloat(pair.reserve0) * + parseFloat(fullCoin['bsc:' + pair.token0.id.toLowerCase()].price); + const token1ValueInReserve = + parseFloat(pair.reserve1) * + parseFloat(fullCoin['bsc:' + pair.token1.id.toLowerCase()].price); + + tvl = token0ValueInReserve + token1ValueInReserve; + } else { + // fallbacking to the one from api if defillama price are missing + tvl = parseFloat(pair.reserveUSD); + } + + return { + pool: pair.id, + chain: utils.formatChain('bsc'), + project: 'thena-v1', + symbol: `${pair.token0.symbol}-${pair.token1.symbol}`, + tvlUsd: tvl, + apyReward: parseFloat(apyDict[pair.id.toLowerCase()]), + underlyingTokens: [pair.token0.id, pair.token1.id], + rewardTokens: [ + '0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11', // THE + ], + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://thena.fi/liquidity', +}; diff --git a/src/adaptors/thesauros/index.js b/src/adaptors/thesauros/index.js new file mode 100644 index 0000000000..8263372177 --- /dev/null +++ b/src/adaptors/thesauros/index.js @@ -0,0 +1,269 @@ +const sdk = require('@defillama/sdk'); +const { formatChain, getERC4626Info, getPrices } = require('../utils'); + +// Thesauros vault configuration +const VAULTS = { + base: { + chainId: 8453, + chainName: 'base', + vaults: [ + { + address: '0x6C7013b3596623d146781c90b4Ee182331Af6148', + symbol: 'USDC', + asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base + assetSymbol: 'USDC', + name: 'Thesauros - Base', + decimals: 6, + }, + ], + providers: { + "aaveV3Provider": "0x034a62f9617E8A1770f7c7EbA04e2DAb2Fda7f12", + "compoundV3Provider": "0xFFAc48125fa4Bd8BC03CDCA725459563aAe77406", + "re7MorphoProvider": "0x642E31bE2fF6d3EBa38dC16760f3a146092d89e3", + "steakhouseHighYieldMorphoProvider": "0x0EF8ceD75e5877c69ac8619145219b67D76193a1", + "steakhousePrimeMorphoProvider": "0x4516F8324bfAcC71e5099FabFC51E97e4905c062", + "gauntletCoreMorphoProvider": "0x34c164e7021e38921aE20a723234d2b1B52289E9" + }, + }, + arbitrum: { + chainId: 42161, + chainName: 'arbitrum', + vaults: [ + { + address: '0x57C10bd3fdB2849384dDe954f63d37DfAD9d7d70', + symbol: 'USDC', + asset: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum + assetSymbol: 'USDC', + name: 'Thesauros - Arbitrum', + decimals: 6, + }, + { + address: '0xcd72118C0707D315fa13350a63596dCd9B294A30', + symbol: 'USDT', + asset: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT on Arbitrum + assetSymbol: 'USDT', + name: 'Thesauros - Arbitrum USDT', + decimals: 6, + }, + ], + providers: { + aaveV3: '0xbeEdb89DC47cab2678eBB796cfc8131062F16E39', + compoundV3: '0xaBD932E0Fff6417a4Af16431d8D86a4e62d62fA3', + dolomite: '0x3D036B97482CC6c42753dA51917B3302D5d0E9AE', + steakhouseHighYieldMorpho: '0x00651b3E70873AfC852d9068Da4d359C473aA6c3', + yearnDegenMorpho: '0x7b77caFe29d62c984e569793AD1C1DC9eD542413', + gauntletCoreMorpho: '0xfFD8B1A9B97787c169154a485925512C79CA53E7', + hyperithmMorpho: '0x54E5FF7FF115E2B01332D81f7efFB02adEF3c23D', + }, + }, +}; + +// ABI for Vault contract +const vaultAbi = [ + { + inputs: [], + name: 'activeProvider', + outputs: [ + { + internalType: 'contract IProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +// ABI for Provider contract +const providerAbi = [ + { + inputs: [ + { + internalType: 'contract IVault', + name: 'vault', + type: 'address', + }, + ], + name: 'getDepositRate', + outputs: [ + { + internalType: 'uint256', + name: 'rate', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getIdentifier', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +/** + * Get APY from provider + * @param {string} providerAddress - Provider contract address + * @param {string} vaultAddress - Vault contract address + * @param {string} chain - Chain name + * @returns {Promise} APY in percentage (e.g., 5.5 for 5.5%) + */ +async function getProviderApy(providerAddress, vaultAddress, chain) { + try { + const rate = ( + await sdk.api.abi.call({ + target: providerAddress, + abi: providerAbi.find((m) => m.name === 'getDepositRate'), + params: [vaultAddress], + chain, + }) + ).output; + + // Rate is in ray units (1e27), convert to APY percentage + // APY = (rate / 1e27) * 100 + const apy = (Number(rate) / 1e27) * 100; + return apy; + } catch (error) { + console.error( + `Error getting APY from provider ${providerAddress}:`, + error.message + ); + return 0; + } +} + +/** + * Main APY function + * @returns {Promise} Array of pool objects + */ +async function apy() { + const pools = []; + + for (const [chainKey, chainConfig] of Object.entries(VAULTS)) { + const { chainName, vaults } = chainConfig; + + for (const vault of vaults) { + try { + // Get TVL using ERC4626 info + // Use decimals from vault config (default to 6 for USDC/USDT) + const decimals = vault.decimals || 6; + const assetUnit = '1' + '0'.repeat(decimals); + + const erc4626Info = await getERC4626Info( + vault.address.toLowerCase(), + chainName, + undefined, + { assetUnit } + ); + + if (!erc4626Info || !erc4626Info.tvl) { + console.warn( + `No TVL data for vault ${vault.address} on ${chainName}` + ); + continue; + } + + // Get asset price + const prices = await getPrices([vault.asset], chainName); + + const assetPrice = + prices.pricesByAddress?.[vault.asset.toLowerCase()] || 1; + + // Calculate TVL in USD + const tvlUsd = (erc4626Info.tvl / 10 ** decimals) * assetPrice; + + // Get active provider APY + const activeProviderAddress = ( + await sdk.api.abi.call({ + target: vault.address, + abi: vaultAbi.find((m) => m.name === 'activeProvider'), + chain: chainName, + }) + ).output; + + const apyBase = await getProviderApy( + activeProviderAddress, + vault.address, + chainName + ); + + const pool = { + pool: `${vault.address}-${chainName}`.toLowerCase(), + chain: formatChain(chainName), + project: 'thesauros', + symbol: vault.symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: [vault.asset], + poolMeta: 'Instant withdraw | Points Incentive', + url: `https://app.thesauros.io/vault/${vault.address}`, + }; + + pools.push(pool); + } catch (error) { + console.error( + `Error processing vault ${vault.address} on ${chainName}:`, + error.message + ); + // Continue with other vaults even if one fails + continue; + } + } + } + + return pools.filter((p) => p && p.tvlUsd > 0); +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/thorchain/index.js b/src/adaptors/thorchain-dex/index.js similarity index 72% rename from src/adaptors/thorchain/index.js rename to src/adaptors/thorchain-dex/index.js index b888dfabf7..42636c38bf 100644 --- a/src/adaptors/thorchain/index.js +++ b/src/adaptors/thorchain-dex/index.js @@ -6,13 +6,17 @@ const chainMapping = { BCH: 'bitcoincash', BNB: 'binance', DOGE: 'doge', - LTC: 'litecoin', + LTC: 'litecoin', TERRA: 'terra', + GAIA: 'cosmos', + AVAX: 'avalanche', + BASE: 'base', + XRP: 'ripple' }; const buildPool = (entry, runePrice) => { const asset = entry.asset.split('.'); - const chain = asset[0]; + const chain = chainMapping[asset[0]]; const symbol = `${asset[1].split('-')[0]}-RUNE`; const balanceAsset = @@ -21,8 +25,8 @@ const buildPool = (entry, runePrice) => { const newObj = { pool: entry.asset, - chain: utils.formatChain(chainMapping[chain]), - project: 'thorchain', + chain: chain !== undefined ? utils.formatChain(chain) : null, + project: 'thorchain-dex', symbol: utils.formatSymbol(symbol), tvlUsd: balanceAsset + balanceRune, apy: Number(entry.poolAPY) * 100, @@ -40,9 +44,9 @@ const topLvl = async () => { ); // build pool objects - data = data.map((el) => buildPool(el, Number(runePrice.runePriceUSD))); + const pools = data.map((el) => buildPool(el, Number(runePrice.runePriceUSD))); - return data; + return [...pools].filter((p) => p.chain && utils.keepFinite(p)); }; const main = async () => { @@ -53,4 +57,5 @@ const main = async () => { module.exports = { timetravel: false, apy: main, + url: 'https://app.thorswap.finance/liquidity', }; diff --git a/src/adaptors/tlx-finance/index.ts b/src/adaptors/tlx-finance/index.ts new file mode 100644 index 0000000000..56c488555a --- /dev/null +++ b/src/adaptors/tlx-finance/index.ts @@ -0,0 +1,128 @@ +const sdk = require('@defillama/sdk'); +const { getPrices, getBlocksByTime } = require('../utils'); +const { utils } = require('ethers'); + +const LOCKER_ADDRESS = '0xc068c3261522c97ff719dc97c98c63a1356fef0f'; +const TLX_ADDRESS = '0xd9cc3d70e730503e7f28c1b407389198c4b75fa2'; +const STAKER_ADDRESS = '0xc30877315f3b621a8f7bcda27819ec29429f3817'; +const SUSD_ADDRESS = '0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9'; + +const LOCKER_LAUNCH_DATE = new Date(1712731443000); +const LOCK_DURATION = 26 * 7 * 24 * 60 * 60 * 1000; // 26 weeks +const CHAIN = 'optimism'; +const SAMPLE_PERIOD_DAYS = 30; +const SECONDS_PER_BLOCK = 2; +const SECONDS_IN_A_DAY = 24 * 60 * 60; +const SAMPLE_PERIOD_SECONDS = SAMPLE_PERIOD_DAYS * SECONDS_IN_A_DAY; +const SAMPLE_PERIOD_BLOCKS = SAMPLE_PERIOD_SECONDS / SECONDS_PER_BLOCK; +const BLOCKS_PER_YEAR = (365 * SECONDS_IN_A_DAY) / SECONDS_PER_BLOCK; + +const getTlxPrice = async (timestamp: number | null): Promise => { + if (!timestamp) { + const reponse = await getPrices([TLX_ADDRESS], CHAIN); + return reponse.pricesBySymbol.tlx; + } else { + const id = `${CHAIN}:${TLX_ADDRESS}`; + const url = `https://coins.llama.fi/prices/historical/${timestamp}/${id}`; + const res = await fetch(url); + const data: any = await res.json(); + return data.coins[id].price; + } +}; + +const getBlock = async (timestamp: number | null): Promise => { + if (timestamp) { + const [block] = await getBlocksByTime([timestamp], CHAIN); + return block; + } else { + const block = await sdk.api.util.getLatestBlock(CHAIN); + return block.number; + } +}; + +const getView = async (address: string, name: string): Promise => { + const abi = `function ${name}() view returns (uint256)`; + const { output } = await sdk.api.abi.call({ + chain: CHAIN, + abi, + target: address, + }); + return output / 1e18; +}; + +const apy = async (timestamp: number | null = null) => { + // General + const tlxPrice = await getTlxPrice(timestamp); + const currentBlock = await getBlock(timestamp); + + // Locker + const rewards = await getView(LOCKER_ADDRESS, 'totalRewards'); + const totalLocked = await getView(LOCKER_ADDRESS, 'totalStaked'); + const timePassed = new Date().getTime() - LOCKER_LAUNCH_DATE.getTime(); + const percentComplete = Math.min(timePassed / LOCK_DURATION, 1); + const lockerApr = (rewards / totalLocked) * 2 * (1 - percentComplete) * 100; + + // Staker + const totalStaked = await getView(STAKER_ADDRESS, 'totalStaked'); + const totalPrepared = await getView(STAKER_ADDRESS, 'totalPrepared'); + const startBlock = currentBlock - SAMPLE_PERIOD_BLOCKS; + const event = 'event DonatedRewards(address indexed account, uint256 amount)'; + const iface = new utils.Interface([event]); + const events = ( + await sdk.api.util.getLogs({ + target: STAKER_ADDRESS, + topic: '', + fromBlock: startBlock, + toBlock: currentBlock, + topics: [iface.getEventTopic('DonatedRewards')], + keys: [], + chain: CHAIN, + }) + ).output.filter((ev) => !ev.removed); + const eventArgs = events.map((ev) => iface.parseLog(ev).args); + const firstEventBlock = events[0].blockNumber; + const annualMultiplier = BLOCKS_PER_YEAR / (currentBlock - firstEventBlock); + const start = eventArgs[0].amount.sub(eventArgs[0].amount); + const totalBn = eventArgs.reduce( + (acc, event) => acc.add(event.amount), + start + ); + const total = totalBn / 1e18; + const annualStakerEarnings = total * annualMultiplier; + const totalActive = totalStaked - totalPrepared; + const totalActiveUsd = totalActive * tlxPrice; + const stakerApr = (annualStakerEarnings / totalActiveUsd) * 100; + + return [ + { + pool: 'tlx-locker', + chain: CHAIN, + project: 'tlx-finance', + symbol: 'lockedTLX', + tvlUsd: totalLocked * tlxPrice, + apyBase: 0, + apyReward: lockerApr, + rewardTokens: [TLX_ADDRESS], + underlyingTokens: [TLX_ADDRESS], + poolMeta: 'TLX Genesis Locker', + }, + { + pool: 'tlx-staker', + chain: CHAIN, + project: 'tlx-finance', + symbol: 'stTLX', + tvlUsd: totalStaked * tlxPrice, + apyBase: 0, + apyReward: stakerApr, + rewardTokens: [SUSD_ADDRESS], + underlyingTokens: [TLX_ADDRESS], + poolMeta: 'TLX Staker', + }, + ]; +}; + +module.exports = { + timetravel: true, + apy: apy, + url: 'https://tlx.fi/rewards', +}; diff --git a/src/adaptors/tokan-exchange/abis/Gauge.json b/src/adaptors/tokan-exchange/abis/Gauge.json new file mode 100644 index 0000000000..8c5fa85efd --- /dev/null +++ b/src/adaptors/tokan-exchange/abis/Gauge.json @@ -0,0 +1,687 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_distribution", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isForPair", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DISTRIBUTION", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_VE", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "_balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugeRewarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardForDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewarderPid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_distribution", + "type": "address" + } + ], + "name": "setDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeRewarder", + "type": "address" + } + ], + "name": "setGaugeRewarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "setRewarderPid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAllAndHarvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/tokan-exchange/abis/Pair.json b/src/adaptors/tokan-exchange/abis/Pair.json new file mode 100644 index 0000000000..999e0900e5 --- /dev/null +++ b/src/adaptors/tokan-exchange/abis/Pair.json @@ -0,0 +1,1112 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyIndex1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/tokan-exchange/abis/PairAPI.json b/src/adaptors/tokan-exchange/abis/PairAPI.json new file mode 100644 index 0000000000..dd50c340b3 --- /dev/null +++ b/src/adaptors/tokan-exchange/abis/PairAPI.json @@ -0,0 +1,650 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "Owner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVoter", + "type": "address" + } + ], + "name": "Voter", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_EPOCHS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PAIRS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REWARDS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEEK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + } + ], + "name": "getAllPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pairFee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fee", + "type": "address" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo[]", + "name": "Pairs", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getPair", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pair_address", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pairFee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "string", + "name": "token0_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token0_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable0", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "string", + "name": "token1_symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "token1_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimable1", + "type": "uint256" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "uint256", + "name": "gauge_total_supply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "fee", + "type": "address" + }, + { + "internalType": "address", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + }, + { + "internalType": "address", + "name": "emissions_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "emissions_token_decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_lp_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token0_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_token1_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "account_gauge_earned", + "type": "uint256" + } + ], + "internalType": "struct PairAPI.pairInfo", + "name": "_pairInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amounts", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_offset", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_pair", + "type": "address" + } + ], + "name": "getPairBribe", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "epochTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVotes", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "internalType": "struct PairAPI.tokenBribe[]", + "name": "bribes", + "type": "tuple[]" + } + ], + "internalType": "struct PairAPI.pairBribeEpoch[]", + "name": "_pairEpoch", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voter", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pair", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "_rewPerEpoch", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairFactory", + "outputs": [ + { + "internalType": "contract IPairFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voter", + "type": "address" + } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "contract IVoter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/tokan-exchange/abis/PairFactory.json b/src/adaptors/tokan-exchange/abis/PairFactory.json new file mode 100644 index 0000000000..7e1da3aaa6 --- /dev/null +++ b/src/adaptors/tokan-exchange/abis/PairFactory.json @@ -0,0 +1,459 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allPairs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "bool", + "name": "stable", + "type": "bool" + } + ], + "name": "createPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "getFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "getFeeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_state", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/tokan-exchange/abis/Voter.json b/src/adaptors/tokan-exchange/abis/Voter.json new file mode 100644 index 0000000000..631d9cb627 --- /dev/null +++ b/src/adaptors/tokan-exchange/abis/Voter.json @@ -0,0 +1,1402 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "internal_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "external_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "_initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_bribes", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_fees", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "createGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "finish", + "type": "uint256" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "external_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gauges", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "gaugesDistributionTimestmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "increaseGaugeApprovals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_pools", + "type": "address[]" + } + ], + "name": "initGauges", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauges", + "type": "address" + }, + { + "internalType": "address", + "name": "_bribes", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "internal_bribes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isAlive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isGauge", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "killGaugeTotally", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lastVoted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolForGauge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolVote", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "poolVoteLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bribeFactory", + "type": "address" + } + ], + "name": "setBribeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_council", + "type": "address" + } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gaugeFactory", + "type": "address" + } + ], + "name": "setGaugeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal", + "type": "address" + }, + { + "internalType": "address", + "name": "_external", + "type": "address" + } + ], + "name": "setNewBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + } + ], + "name": "setPairFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_usdr", + "type": "address" + } + ], + "name": "setUSDR", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_gauges", + "type": "address[]" + } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "usdr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usedWeights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_poolVote", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_weights", + "type": "uint256[]" + } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "weights", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_token", + "type": "address[]" + } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/tokan-exchange/index.js b/src/adaptors/tokan-exchange/index.js new file mode 100644 index 0000000000..00defc65eb --- /dev/null +++ b/src/adaptors/tokan-exchange/index.js @@ -0,0 +1,215 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abis/PairFactory.json'); +const abiPairAPI = require('./abis/PairAPI.json'); + +const PAIR_FACTORY_ADDRESS = '0x92aF10c685D2CF4CD845388C5f45aC5dc97C5024'; +const PAIR_API_ADDRESS = '0xCDC8b03a1a8318d7b78d5D6349B4435b251f8853'; +const TKN_ADDRESS = '0x1a2fCB585b327fAdec91f55D45829472B15f17a4'; +const CHAIN_NAME = 'scroll'; + +/** + * Retrieves and computes APY for pools of tokens on the Polygon blockchain. + */ +const getAPY = async () => { + const allPairs = await getAllPairs(); + const pairInfo = await getPairInfo(allPairs); + const prices = await getTokenPrices(pairInfo); + const tknPrice = prices[TKN_ADDRESS.toLowerCase()]; + + computePairInfo(pairInfo, prices, tknPrice); + + return pairInfo.map(formatPool).filter(utils.keepFinite); +}; + +/** + * Fetches all pairs from the blockchain. + */ +async function getAllPairs() { + const allPairsLength = ( + await sdk.api.abi.call({ + target: PAIR_FACTORY_ADDRESS, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: CHAIN_NAME, + }) + ).output; + + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: PAIR_FACTORY_ADDRESS, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: CHAIN_NAME, + }) + ).output.map((o) => o.output); + + return allPairs; +} + +/** + * Fetches and formats pair info from the blockchain. + */ +async function getPairInfo(allPairs) { + const zip = (a, b) => a.map((k, i) => [k, b[i]]); + const keys = [ + 'pair_address', + 'symbol', + 'name', + 'decimals', + 'pairFee', + 'stable', + 'total_supply', + // token pair info + 'token0', + 'token0_symbol', + 'token0_decimals', + 'reserve0', + 'claimable0', + 'token1', + 'token1_symbol', + 'token1_decimals', + 'reserve1', + 'claimable1', + // pairs gauge + 'gauge', + 'gauge_total_supply', + 'fee', + 'bribe', + 'weight', + 'emissions', + 'emissions_token', + 'emissions_token_decimals', + // user deposit + 'account_lp_balance', + 'account_token0_balance', + 'account_token1_balance', + 'account_gauge_balance', + 'account_gauge_earned', + ]; + + const pairInfo = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: PAIR_API_ADDRESS, + params: [i, '0x0000000000000000000000000000000000000000'], + })), + abi: abiPairAPI.find((m) => m.name === 'getPair'), + chain: CHAIN_NAME, + }) + ).output.map((o) => Object.fromEntries(zip(keys, o.output))); + + return pairInfo; +} + +/** + * Fetches prices for all tokens used in the pairs. + */ +async function getTokenPrices(pairInfo) { + const tokens = [ + ...new Set( + pairInfo + .map((p) => [p.token0, p.token1]) + .flat() + .concat(TKN_ADDRESS) + ), + ]; + + const allCoins = ( + await axios.get( + 'https://api.coingecko.com/api/v3/coins/list?include_platform=true' + ) + ).data.filter( + (coin) => coin && coin.platforms && coin.platforms['scroll'] + ); + + const tokenAddresses = tokens.map((a) => a.toLowerCase()); + const coins = allCoins.filter((coin) => + tokenAddresses.includes(coin.platforms['scroll'].toLowerCase()) + ); + const markets = ( + await axios.get( + `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${coins + .map((c) => c.id) + .join(',')}` + ) + ).data; + + async function getPriceFromGeckoTerminal(token) { + const price = ( + await axios.get(`https://api.geckoterminal.com/api/v2/networks/scroll/tokens/${token}`) + ).data.data.attributes.price_usd + return price + } + + function getPriceFromCoinGecko(token) { + const id = allCoins.find( + (coin) => + coin.platforms['scroll'].toLowerCase() === token.toLowerCase() + )?.id; + if (id === undefined) return undefined; + const marketData = markets.find((m) => m.id === id); + return marketData?.current_price; + } + + async function getPrice(token) { + return getPriceFromCoinGecko(token) + } + + const pricePromises = tokenAddresses.map((t) => + getPrice(t).then((p) => [t, p]) + ); + const prices = await Promise.all(pricePromises).then((results) => + Object.fromEntries(results) + ); + + return prices; +} + +/** + * Computes additional properties for each pair info object. + */ +function computePairInfo(pairInfo, prices, tknPrice) { + for (const pi of pairInfo) { + pi.reserve0Usd = + (pi.reserve0 / Math.pow(10, pi.token0_decimals)) * + prices[pi.token0.toLowerCase()]; + pi.reserve1Usd = + (pi.reserve1 / Math.pow(10, pi.token1_decimals)) * + prices[pi.token1.toLowerCase()]; + pi.pairTvlUsd = pi.reserve0Usd + pi.reserve1Usd; + pi.staked = pi.gauge_total_supply / pi.total_supply; + pi.stakedUsd = pi.pairTvlUsd * pi.staked; + pi.apr = + (((pi.emissions / Math.pow(10, 18)) * tknPrice * 86400 * 365) / + pi.stakedUsd) * + 100; + } +} + +/** + * Formats a pair info object into a pool object. + */ +function formatPool(p) { + const apyReward =p.apr; // NOT daily compounding, APR NOT APY + return { + pool: p.pair_address, + chain: utils.formatChain('Scroll'), + project: 'tokan-exchange', + symbol: utils.formatSymbol(p.symbol.split('-')[1]), + poolMeta: p.stable ? 'stable' : 'volatile', + tvlUsd: p.pairTvlUsd, + apyReward, + rewardTokens: p.apr ? [TKN_ADDRESS] : [], + underlyingTokens: [p.token0, p.token1], + }; +} + +module.exports = { + timetravel: false, + apy: getAPY, + url: 'https://app.tokan.exchange/liquidity', +}; \ No newline at end of file diff --git a/src/adaptors/tokensfarm/index.js b/src/adaptors/tokensfarm/index.js new file mode 100644 index 0000000000..17ed105222 --- /dev/null +++ b/src/adaptors/tokensfarm/index.js @@ -0,0 +1,34 @@ +const utils = require('../utils'); +const FARM_URL = 'https://api.tokensfarm.com/farm/list?active=true&page=1&page_size=100&farm_type=LP,STAKE,STAKING'; +const FARM_CONFIG_URL = (symbol, type, nonce) => + `https://api.tokensfarm.com/farm/config?symbol=${symbol}&type=${type}&nonce=${nonce}` + +const apy = async () => { + const data = await utils.getData(FARM_URL); + const { farms } = data; + const poolDetailCall = farms + .map(pool => utils.getData(FARM_CONFIG_URL(pool.symbol, pool.type, pool.nonce))); + const poolDetail = await Promise.all(poolDetailCall); + return poolDetail.map(pool => { + const { TokensFarm, RewardToken } = pool.contracts; + const { chainName } = pool.network; + const [farmAssets] = pool.farmAssets; + return { + pool: `${TokensFarm}-${pool.type}-${chainName}`, + chain: utils.formatChain(chainName), + project: 'tokensfarm', + symbol: farmAssets.assets.map(e => e.symbol).join('-'), + poolMeta: pool.type, + apy: pool.apy, + underlyingTokens: farmAssets.assets.map(e => e.address), + tvlUsd: pool.farmLiquidity, + rewardTokens: [RewardToken] + }; + }); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://tokensfarm.com/', +}; diff --git a/src/adaptors/tonco/index.js b/src/adaptors/tonco/index.js new file mode 100644 index 0000000000..ab21159185 --- /dev/null +++ b/src/adaptors/tonco/index.js @@ -0,0 +1,65 @@ +const utils = require('../utils'); +const { Address } = require('@ton/core'); + +const GRAPHQL_ENDPOINT = 'https://indexer.tonco.io/'; +const POOLS_QUERY = ` + query Pools { + pools ( filter: { orderBy: "usd" } ) { + address + apr + name + totalValueLockedUsd + jetton0 { + address + } + jetton1 { + address + } + } + } +`; + +const getApy = async () => { + console.log("Requesting pools list") + const poolsList = (await utils.getData(GRAPHQL_ENDPOINT, { + query: POOLS_QUERY + })).data.pools; + + const poolsInfo = {}; + for (const pool of poolsList.slice(0, 10)) { + const address = pool.address; + + const tvl = pool.totalValueLockedUsd; + + poolsInfo[pool.address] = { + symbol: pool.name.replace('wTTon', 'TON'), + tvl: tvl, + apyBase: pool.apr, + underlyingTokens: [Address.parse(pool.jetton0.address).toString(), Address.parse(pool.jetton1.address).toString()] + } + } + console.log(`Inited ${Object.keys(poolsInfo).length} pools`); + + + const pools = Object.keys(poolsInfo) + .map((pool_address) => { + const pool = poolsInfo[pool_address]; + return { + pool: `${pool_address}-ton`.toLowerCase(), + chain: 'Ton', + project: 'tonco', + symbol: pool.symbol, + tvlUsd: pool.tvl, + apyBase: pool.apyBase, + underlyingTokens: pool.underlyingTokens, + url: `https://app.tonco.io/#/pool/${pool_address}` + }; + }); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://tonco.io/', +}; diff --git a/src/adaptors/toros/index.js b/src/adaptors/toros/index.js new file mode 100644 index 0000000000..f6a3d14afb --- /dev/null +++ b/src/adaptors/toros/index.js @@ -0,0 +1,142 @@ +const axios = require('axios'); +const BN = require('bignumber.js'); +const { request, gql } = require('graphql-request'); + +const { formatChain } = require('../utils'); + +const DHEDGE_REWARDS_API_URL = 'https://app.dhedge.org/api/rewards'; + +const DHEDGE_API_URL = 'https://api-v2.dhedge.org/graphql'; + +const YIELD_PRODUCTS_QUERY = gql` + query YieldProducts { + yieldProducts { + address + } + } +`; + +const POOL_DATA_QUERY = gql` + query PoolData($address: String!) { + fund(address: $address) { + address + blockchainCode + blockTime + fundComposition { + amount + tokenAddress + } + performanceMetrics { + week + month + quarter + halfyear + year + } + symbol + totalValue + apy { + monthly + weekly + } + } + } +`; + +const formatValue = (value) => new BN(value).shiftedBy(-18).toNumber(); + +const getDaysSincePoolCreation = (blockTime) => + Math.round((Date.now() / 1000 - +blockTime) / 86400); + +const chooseApy = (apy, blockTime, metrics) => { + if (!apy) return calcApy(blockTime, metrics); + + return apy.weekly; +}; + +// Fallback APY calculation simply based on pool's past performance +const calcApy = (blockTime, metrics) => { + const daysActive = getDaysSincePoolCreation(blockTime); + return daysActive >= 360 + ? (formatValue(metrics.year) - 1) * 100 + : daysActive >= 180 + ? (formatValue(metrics.halfyear) - 1) * 2 * 100 + : daysActive >= 90 + ? (formatValue(metrics.quarter) - 1) * 4 * 100 + : daysActive >= 30 + ? (formatValue(metrics.month) - 1) * 12 * 100 + : (formatValue(metrics.week) - 1) * 52 * 100; +}; + +const fetchTorosYieldProducts = async () => { + try { + const response = await request(DHEDGE_API_URL, YIELD_PRODUCTS_QUERY); + const products = await Promise.all( + response.yieldProducts.map(async ({ address }) => { + const { fund } = await request(DHEDGE_API_URL, POOL_DATA_QUERY, { + address, + }); + return fund; + }) + ); + return products; + } catch (err) { + console.error('Failed to fetch toros yield pools: ', err); + return []; + } +}; + +const fetchRewardIncentivesData = async () => { + try { + const response = await axios.get(DHEDGE_REWARDS_API_URL); + return response.data; + } catch (err) { + console.error('Failed to fetch toros reward data: ', err); + return; + } +}; + +const listTorosYieldProducts = async () => { + const [products, rewardData] = await Promise.all([ + fetchTorosYieldProducts(), + fetchRewardIncentivesData(), + ]); + + return products.map( + ({ + address, + blockchainCode, + symbol, + totalValue, + performanceMetrics, + blockTime, + fundComposition, + apy, + }) => { + const rewardIncentivisedPool = rewardData?.poolsWithRewards + .map((address) => address.toLowerCase()) + .includes(address.toLowerCase()); + return { + pool: address, + chain: formatChain(blockchainCode.toLowerCase()), + project: 'toros', + symbol, + tvlUsd: formatValue(totalValue), + apy: chooseApy(apy, blockTime, performanceMetrics), + rewardTokens: + rewardIncentivisedPool && rewardData?.rewardToken + ? [rewardData.rewardToken] + : [], + underlyingTokens: fundComposition + .filter(({ amount }) => amount !== '0') + .map(({ tokenAddress }) => tokenAddress), + url: `https://toros.finance/vault/${address}`, + }; + } + ); +}; + +module.exports = { + timetravel: false, + apy: listTorosYieldProducts, +}; diff --git a/src/adaptors/tortuga/index.js b/src/adaptors/tortuga/index.js new file mode 100644 index 0000000000..6d2cb97c64 --- /dev/null +++ b/src/adaptors/tortuga/index.js @@ -0,0 +1,84 @@ +const { default: BigNumber } = require('bignumber.js'); + +const utils = require('../utils'); + +const TGOV_ADDRESS = + '0x84d7aeef42d38a5ffc3ccef853e1b82e4958659d16a7de736a29c55fbbeb0114'; +const NODE_URL = 'https://fullnode.mainnet.aptoslabs.com/v1'; +const RESOURCE_URL = `${NODE_URL}/accounts/${TGOV_ADDRESS}/resources`; +const COINS_LLAMA_PRICE_URL = 'https://coins.llama.fi/prices/current/'; +const DECIMALS = 1e8; + +const aptosCoinName = 'coingecko:aptos'; + +async function main() { + const [resources, aptPrice] = await Promise.all([ + utils.getData(RESOURCE_URL), + utils.getData(`${COINS_LLAMA_PRICE_URL}${aptosCoinName}`), + ]); + + const stakingStatus = resources.filter((r) => + r.type.endsWith('StakingStatus') + )[0].data; + + const aptosCoinReserve = resources.filter((r) => + r.type.endsWith('AptosCoinReserve') + )[0].data; + + const validatorSystem = resources.filter((r) => + r.type.endsWith('ValidatorSystem') + )[0].data; + + const tAptCoinInfo = resources.filter((r) => + r.type.endsWith( + `CoinInfo<${TGOV_ADDRESS}::staked_aptos_coin::StakedAptosCoin>` + ) + )[0].data; + + const unclaimed_balance = new BigNumber( + stakingStatus.total_claims_balance + ).minus(BigNumber(stakingStatus.total_claims_balance_cleared)); + + const total_balance_with_validators = new BigNumber( + validatorSystem.total_balance_with_validators + ); + + const aptStaked = BigNumber(aptosCoinReserve.coin.value) + .plus(total_balance_with_validators) + .minus(unclaimed_balance); + + const tAptSupply = new BigNumber( + tAptCoinInfo.supply.vec[0].integer.vec[0].value + ); + + const aptPerTApt = aptStaked.dividedBy(tAptSupply); + const secsInYear = 60 * 60 * 24 * 365; + const secsSinceDeployment = BigNumber(new Date().valueOf() / 1000).minus( + stakingStatus.deployment_time + ); + const apy = aptPerTApt + .minus(1) + .multipliedBy(secsInYear) + .dividedBy(secsSinceDeployment) + .multipliedBy(100); + + return [ + { + pool: `${TGOV_ADDRESS}-tortuga`, + chain: utils.formatChain('aptos'), + project: 'tortuga', + symbol: utils.formatSymbol('tAPT'), + tvlUsd: aptStaked + .multipliedBy(aptPrice.coins[aptosCoinName].price) + .dividedBy(DECIMALS) + .toNumber(), + apy: apy.toNumber(), + }, + ]; +} + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.tortuga.finance', +}; diff --git a/src/adaptors/tr-energy/index.js b/src/adaptors/tr-energy/index.js new file mode 100644 index 0000000000..948a1e77bd --- /dev/null +++ b/src/adaptors/tr-energy/index.js @@ -0,0 +1,50 @@ + +const axios = require("axios"); + + +async function getConfig() { + const { data } = await axios.get("https://core.tr.energy/api/config"); + return data.data; +} +async function getStats() { + const { data } = await axios.get("https://core.tr.energy/api/energy-stats"); + return data.data; +} + +async function getTrxPrice() { + const { data } = await axios.get('https://coins.llama.fi/prices/current/coingecko:tron') + return data.coins +} + + +async function apy() { + const cfg = await getConfig(); + const stats = await getStats(); + const trxPrice = await getTrxPrice(); + + // TVL + const tvlTrx = Number((stats.total_energy / cfg.trx_staking_energy_rate).toFixed(2)); + const tvlUsd = Number((tvlTrx * trxPrice['coingecko:tron'].price).toFixed(2)); + + // APY (profit_percent + static_percent) * percent_cef + const baseApy = Number(((cfg.profit_percent + cfg.static_percent) * 100).toFixed(2)); + + return [ + { + pool: "trenergy-trx", + chain: "Tron", + project: "tr-energy", + symbol: "TRX", + tvlUsd, + apyBase: baseApy, + underlyingTokens: ["TRX"], + url: "https://tr.energy", + }, + ]; +} + +module.exports = { + timetravel: false, + apy, + url: "https://tr.energy", +} diff --git a/src/adaptors/trader-joe/index.js b/src/adaptors/trader-joe/index.js deleted file mode 100644 index c36a1e8523..0000000000 --- a/src/adaptors/trader-joe/index.js +++ /dev/null @@ -1,150 +0,0 @@ -const { request, gql } = require('graphql-request'); - -const utils = require('../utils'); - -const url = 'https://api.thegraph.com/subgraphs/name/traderjoe-xyz/exchange'; -const urlLM = - 'https://api.thegraph.com/subgraphs/name/traderjoe-xyz/masterchefv2'; - -const query = gql` - { - pairs(first: 1000, orderBy: trackedReserveAVAX, orderDirection: desc block: {number: }) { - id - volumeUSD - reserve0 - reserve1 - token0 { - symbol - id - } - token1 { - symbol - id - } - } - } -`; - -const queryPrior = gql` - { - pairs (first: 1000 orderBy: trackedReserveAVAX orderDirection: desc block: {number: }) { - id - volumeUSD - } - } -`; - -const queryMasterChef = gql` - { - masterChefs(block: {number: }) { - totalAllocPoint - joePerSec - } - } -`; - -const queryJoeAllocation = gql` - { - pools(first: 1000, orderBy: allocPoint, orderDirection: desc block: {number: }) { - pair - allocPoint - } - } -`; - -const prepareLMData = async (urlLM, block) => { - const joeUsd = await utils.getCGpriceData('joe', true); - - // get pair allocation points - let joeAllocation = await request( - urlLM, - queryJoeAllocation.replace('', block) - ); - - // get total Allocation points - let joeMc = await request( - urlLM, - queryMasterChef.replace('', block) - ); - const details = joeMc.masterChefs[0]; - - for (const el of joeAllocation.pools) { - const relPoolShare = - Number(el.allocPoint) / Number(details.totalAllocPoint); - - // LPs receive 50% of rewards, so we divide by 2 - const rewardPerSecond = - (relPoolShare * Number(details.joePerSec)) / 1e18 / 2; - const rewardPerDay = rewardPerSecond * 86400; - - el['joePerDay'] = rewardPerDay; - el['joePerYear'] = rewardPerDay * 365; - el['joePerYearUsd'] = rewardPerDay * 365 * joeUsd.joe.usd; - } - - return joeAllocation; -}; - -const buildPool = (entry, chainString) => { - const apyFee = Number(entry.apy); - const apyJoe = isNaN(entry.apyJoe) ? 0 : entry.apyJoe; - const symbol = utils.formatSymbol( - `${entry.token0.symbol}-${entry.token1.symbol}` - ); - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'trader-joe', - symbol, - tvlUsd: entry.totalValueLockedUSD, - apy: apyFee + apyJoe, - }; - - return newObj; -}; - -const topLvl = async (chainString, timestamp, url, urlLM) => { - const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ - url, - urlLM, - ]); - - // pull data - let dataNow = await request(url, query.replace('', block)); - - // pull 24h offset data to calculate fees from swap volume - const dataPrior = await request( - url, - queryPrior.replace('', blockPrior) - ); - - // calculate tvl - dataNow = await utils.tvl(dataNow.pairs, 'avax'); - - // calculate apy - let data = dataNow.map((el) => utils.apy(el, dataPrior.pairs, 'v2')); - - // get LM rewards and add to object - const dataLm = await prepareLMData(urlLM, block); - for (const el of data) { - el['joePerYearUsd'] = dataLm.pools.find( - (x) => x.pair === el.id - )?.joePerYearUsd; - el['apyJoe'] = (el.joePerYearUsd / Number(el.totalValueLockedUSD)) * 100; - } - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async (timestamp = null) => { - const data = await Promise.all([topLvl('avalanche', timestamp, url, urlLM)]); - return data.flat(); -}; - -module.exports = { - timetravel: true, - apy: main, -}; diff --git a/src/adaptors/tranchess-ether/abi.json b/src/adaptors/tranchess-ether/abi.json new file mode 100644 index 0000000000..ba8b3426f1 --- /dev/null +++ b/src/adaptors/tranchess-ether/abi.json @@ -0,0 +1,41 @@ +{ + "tokenUnderlying": { + "inputs": [], + "name": "tokenUnderlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getTotalUnderlying": { + "inputs": [], + "name": "getTotalUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + "getEquivalentTotalQ": { + "inputs": [], + "name": "getEquivalentTotalQ", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +} \ No newline at end of file diff --git a/src/adaptors/tranchess-ether/index.js b/src/adaptors/tranchess-ether/index.js new file mode 100644 index 0000000000..24b5433357 --- /dev/null +++ b/src/adaptors/tranchess-ether/index.js @@ -0,0 +1,74 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const abi = require('./abi.json'); + +const ethFund = '0x69c53679EC1C06f3275b64C428e8Cd069a2d3966'; // ETH V2 Fund (ETH mainnet) +const ethFundUnderlying = 'ethereum:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; + +const topLvl = async (chainString, token, address) => { + // Onchain APY calculation. Should return the same value as the API. + currentTime = new Date().getTime(); + startTime = new Date('2022-11-20T14:00:00Z').getTime(); + daysDiff = (currentTime - startTime) / (1000 * 3600 * 24); + + const tokenUnderlying = ( + await sdk.api.abi.call({ + target: ethFund, + abi: abi.tokenUnderlying, + chain: 'ethereum', + }) + ).output; + + const totalUnderlying = ( + await sdk.api.abi.call({ + target: ethFund, + abi: abi.getTotalUnderlying, + chain: 'ethereum', + }) + ).output; + + const equivalentTotalQ = ( + await sdk.api.abi.call({ + target: ethFund, + abi: abi.getEquivalentTotalQ, + chain: 'ethereum', + }) + ).output; + + let apyBase = + ((totalUnderlying / equivalentTotalQ - 1) / daysDiff) * 365 * 100; + + const eth_token_data = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${ethFundUnderlying}` + ) + ).coins[ethFundUnderlying]; + + const tvlUsd = + (totalUnderlying * eth_token_data.price) / + Math.pow(10, eth_token_data.decimals); + + return { + pool: `${address}-${chainString}`.toLowerCase(), + chain: utils.formatChain(chainString), + project: 'tranchess-ether', + symbol: utils.formatSymbol(token), + tvlUsd: tvlUsd, + apyBase, + underlyingTokens: ['0x0000000000000000000000000000000000000000'], + }; +}; + +const main = async () => { + const data = await Promise.all([ + topLvl('ethereum', 'qETH', '0x93ef1Ea305D11A9b2a3EbB9bB4FCc34695292E7d'), + ]); + + return data.flat(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://tranchess.com/liquid-staking', +}; diff --git a/src/adaptors/treehouse-protocol/index.js b/src/adaptors/treehouse-protocol/index.js new file mode 100644 index 0000000000..70b4d8e715 --- /dev/null +++ b/src/adaptors/treehouse-protocol/index.js @@ -0,0 +1,73 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const teth = '0xd11c452fc99cf405034ee446803b6f6c1f6d5ed8'; +const wsteth = '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0'; +const project = 'treehouse-protocol'; +const symbol = 'teth'; + +const apy = async () => { + + const priceKey = `ethereum:${wsteth}`; + const wstEthPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const timestampNow = Math.floor(Date.now() / 1000); + const timestampYesterday = timestampNow - 86400; + + const blockNow = ( + await axios.get(`https://coins.llama.fi/block/ethereum/${timestampNow}`) + ).data.height; + const blockYesterday = ( + await axios.get( + `https://coins.llama.fi/block/ethereum/${timestampYesterday}` + ) + ).data.height; + + const exchangeRateAbi = { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + const exchangeRateYesterday = await sdk.api.abi.call({ + target: teth, + chain: 'ethereum', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockYesterday, + }); + + const exchangeRateToday = await sdk.api.abi.call({ + target: teth, + chain: 'ethereum', + abi: exchangeRateAbi, + params: ['1000000000000000000'], + block: blockNow, + }); + const totalPooledBWsteth = await sdk.api.abi.call({ + target: teth, + chain: 'ethereum', + abi: 'uint256:totalAssets', + }); + + const apr = + ((exchangeRateToday.output / 1e18 - exchangeRateYesterday.output / 1e18) / + (exchangeRateYesterday.output / 1e18)) * 365 * 100; + + return [ + { + pool: `${teth}`, + chain: 'ethereum', + project, + symbol, + underlyingTokens: [wsteth], + apyBase: apr, + tvlUsd: totalPooledBWsteth.output / 1e18 * wstEthPrice, + }, + ]; +}; + +module.exports = { apy, url: 'https://www.treehouse.finance/' }; diff --git a/src/adaptors/trevee-earn/index.js b/src/adaptors/trevee-earn/index.js new file mode 100644 index 0000000000..532536faae --- /dev/null +++ b/src/adaptors/trevee-earn/index.js @@ -0,0 +1,52 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { default: axios } = require('axios'); + +const wrappers = [ + { + address: '0x9fb76f7ce5fceaa2c42887ff441d46095e494206', + symbol: 'wstkscUSD', + underlyingToken: '0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE', + }, + { + address: '0xDb58c4DB1a0f45DDA3d2F8e44C3300BB6510c866', + symbol: 'wstkscBTC', + underlyingToken: '0xBb30e76d9Bb2CC9631F7fC5Eb8e87B5Aff32bFbd', + }, + { + address: '0xe8a41c62bb4d5863c6eadc96792cfe90a1f37c47', + symbol: 'wstkscETH', + underlyingToken: '0x3bcE5CB273F0F148010BbEa2470e7b5df84C7812', + }, +]; + +const main = async () => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${wrappers + .map((w) => `sonic:${w.underlyingToken}`) + .join(',')}` + ) + ).data.coins; + const infos = await Promise.all( + wrappers.map((w) => utils.getERC4626Info(w.address, 'sonic')) + ); + return infos.map((info, i) => { + const token = `sonic:${wrappers[i].underlyingToken}`; + return { + pool: info.pool, + chain: 'sonic', + project: 'trevee-earn', + symbol: wrappers[i].symbol, + tvlUsd: (info.tvl / 10 ** prices[token].decimals) * prices[token].price, + apyBase: info.apyBase, + underlyingTokens: [wrappers[i].underlyingToken], + }; + }); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.rings.money/earn/mint/', +}; diff --git a/src/adaptors/trisolaris/abi.ts b/src/adaptors/trisolaris/abi.ts new file mode 100644 index 0000000000..d5ef1bbec1 --- /dev/null +++ b/src/adaptors/trisolaris/abi.ts @@ -0,0 +1,29 @@ +module.exports = { + token0: { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + token1: { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + name: { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +}; diff --git a/src/adaptors/trisolaris/index.ts b/src/adaptors/trisolaris/index.ts new file mode 100644 index 0000000000..1ba52834b1 --- /dev/null +++ b/src/adaptors/trisolaris/index.ts @@ -0,0 +1,62 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); + +const { token0, token1, name } = require('./abi'); + +const API_URL = 'https://cdn.trisolaris.io/datav2.json'; + +const TRI_TOKEN = '0xFa94348467f64D5A457F75F8bc40495D33c65aBB'; + +const makeCall = async (targets, abi) => { + return ( + await sdk.api.abi.multiCall({ + abi, + calls: targets.map((target) => ({ target })), + chain: 'aurora', + permitFailure: true, + }) + ).output.map(({ output }) => output); +}; + +const apy = async () => { + const farms = await utils.getData(API_URL); + const lpAddresses = farms.map(({ lpAddress }) => lpAddress); + + const tokens0 = await makeCall(lpAddresses, token0); + const tokens1 = await makeCall(lpAddresses, token1); + const names = await makeCall(lpAddresses, name); + const token0Symbols = await makeCall(tokens0, 'erc20:symbol'); + const token1Symbols = await makeCall(tokens1, 'erc20:symbol'); + + const pools = farms.map((farm, i) => { + const isStablePool = token0Symbols[i] === null; + const name = isStablePool + ? names[i].replace('Trisolaris ', '') + : `${token0Symbols[i]}-${token1Symbols[i]}`; + const extraApr = farm.nonTriAPRs.reduce((acc, val) => acc + val.apr, 0); + + return { + pool: `${farm.lpAddress}-${farm.id}`, + chain: utils.formatChain('aurora'), + project: 'trisolaris', + symbol: utils.formatSymbol(name), + tvlUsd: farm.totalStakedInUSD, + apyReward: farm.apr + extraApr, + underlyingTokens: isStablePool + ? [farm.lpAddress] + : [tokens0[i], tokens1[i]], + rewardTokens: [ + TRI_TOKEN, + ...(extraApr ? farm.nonTriAPRs.map(({ address }) => address) : []), + ], + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://www.trisolaris.io/#/farm', +}; diff --git a/src/adaptors/troves/index.js b/src/adaptors/troves/index.js new file mode 100644 index 0000000000..51ad0e9230 --- /dev/null +++ b/src/adaptors/troves/index.js @@ -0,0 +1,44 @@ +const utils = require('../utils'); + +const apy = async () => { + const apyData = await utils.getData( + 'https://app.strkfarm.com/api/strategies' + ); + + return apyData.strategies + .filter((strategy) => parseFloat(strategy.tvlUsd) > 10000) + .map((strategy) => { + const currTvlUsd = parseFloat(strategy.tvlUsd); + const currPool = strategy.name; + const currPoolId = strategy.id; + const baseApy = (strategy.apySplit.baseApy || 0) * 100; + const rewardsApy = (strategy.apySplit.rewardsApy || 0) * 100; + const rewardTokens = strategy.depositToken.map((token) => token.address); + const underlyingTokens = strategy.depositToken.map( + (token) => token.address + ); + const symbols = strategy.depositToken + .map((token) => token.symbol) + .join('-'); + + return { + pool: currPoolId, + chain: 'Starknet', + project: 'troves', + symbol: symbols, + underlyingTokens: underlyingTokens, + tvlUsd: currTvlUsd, + apyBase: baseApy, + apyReward: rewardsApy, + rewardTokens: rewardTokens, + url: `https://app.strkfarm.com/strategy/${currPoolId}`, + poolMeta: currPool, + }; + }); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://www.troves.fi/', +}; diff --git a/src/adaptors/truefi/abis/distributor.json b/src/adaptors/truefi/abis/distributor.json new file mode 100644 index 0000000000..e53734867e --- /dev/null +++ b/src/adaptors/truefi/abis/distributor.json @@ -0,0 +1,326 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Distributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_distributionStart", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_dailyDistribution", + "type": "uint256" + } + ], + "name": "DistributionRestarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newFarm", + "type": "address" + } + ], + "name": "FarmChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalAmount", + "type": "uint256" + } + ], + "name": "TotalAmountChanged", + "type": "event" + }, + { + "inputs": [], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributionStart", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "empty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "farm", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_distributionStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_trustToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastDistribution", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextDistribution", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_distributionStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_dailyDistribution", + "type": "uint256" + } + ], + "name": "restart", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dailyDistribution", + "type": "uint256" + } + ], + "name": "setDailyDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newFarm", + "type": "address" + } + ], + "name": "setFarm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "trustToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/truefi/abis/erc20.json b/src/adaptors/truefi/abis/erc20.json new file mode 100644 index 0000000000..58f67d9a52 --- /dev/null +++ b/src/adaptors/truefi/abis/erc20.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/src/adaptors/truefi/abis/multifarm.json b/src/adaptors/truefi/abis/multifarm.json new file mode 100644 index 0000000000..4c085bad42 --- /dev/null +++ b/src/adaptors/truefi/abis/multifarm.json @@ -0,0 +1,425 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountClaimed", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountStaked", + "type": "uint256" + } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountUnstaked", + "type": "uint256" + } + ], + "name": "Unstake", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "claimable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "exit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "farmRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "cumulativeRewardPerToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalClaimedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITrueDistributor", + "name": "_trueDistributor", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "updatedShares", + "type": "uint256[]" + } + ], + "name": "setShares", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "totalStaked", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "staker", + "type": "address" + } + ], + "name": "staked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "stakerRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "cumulativeRewardPerToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalClaimedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "stakes", + "outputs": [ + { + "internalType": "uint256", + "name": "totalStaked", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "trueDistributor", + "outputs": [ + { + "internalType": "contract ITrueDistributor", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unstake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/truefi/abis/pool.json b/src/adaptors/truefi/abis/pool.json new file mode 100644 index 0000000000..4d76df27c2 --- /dev/null +++ b/src/adaptors/truefi/abis/pool.json @@ -0,0 +1,1222 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newBeneficiary", + "type": "address" + } + ], + "name": "BeneficiaryChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Collected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ITrueCreditAgency", + "name": "newCreditAgency", + "type": "address" + } + ], + "name": "CreditAgencyChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ILoanToken2", + "name": "loan", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "deficit", + "type": "uint256" + } + ], + "name": "DeficitReclaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Exited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "currencyAmount", + "type": "uint256" + } + ], + "name": "Flushed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "staker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "deposited", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minted", + "type": "uint256" + } + ], + "name": "Joined", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newFee", + "type": "uint256" + } + ], + "name": "JoiningFeeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ITrueFiPoolOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "OracleChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "pauseStatus", + "type": "bool" + } + ], + "name": "PauseStatusChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "minTokenAmount", + "type": "uint256" + } + ], + "name": "Pulled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ISAFU", + "name": "newSafu", + "type": "address" + } + ], + "name": "SafuChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ITrueStrategy", + "name": "newStrategy", + "type": "address" + } + ], + "name": "StrategySwitched", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "TOLERATED_SLIPPAGE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOLERATED_STRATEGY_LOSS", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "to", + "type": "uint256" + } + ], + "name": "averageExitPenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "beneficiary", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimableFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "collectFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "creditAgency", + "outputs": [ + { + "internalType": "contract ITrueCreditAgency", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "creditValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currencyBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deficitValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "flush", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "contract ITrueLender2", + "name": "_lender", + "type": "address" + }, + { + "internalType": "contract ISAFU", + "name": "_safu", + "type": "address" + }, + { + "internalType": "address", + "name": "__owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + } + ], + "name": "integrateAtPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "join", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "joiningFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lender", + "outputs": [ + { + "internalType": "contract ITrueLender2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "liquidExit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "liquidExitPenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILoanToken2", + "name": "loan", + "type": "address" + } + ], + "name": "liquidate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "loansValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract ITrueFiPoolOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "proFormaLiquidRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minTokenAmount", + "type": "uint256" + } + ], + "name": "pull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILoanToken2", + "name": "loan", + "type": "address" + } + ], + "name": "reclaimDeficit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currencyAmount", + "type": "uint256" + } + ], + "name": "repay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "safu", + "outputs": [ + { + "internalType": "contract ISAFU", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newBeneficiary", + "type": "address" + } + ], + "name": "setBeneficiary", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITrueCreditAgency", + "name": "_creditAgency", + "type": "address" + } + ], + "name": "setCreditAgency", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "setJoiningFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITrueFiPoolOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "name": "setPauseStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISAFU", + "name": "_safu", + "type": "address" + } + ], + "name": "setSafuAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20", + "name": "_token", + "type": "address" + }, + { + "internalType": "contract ITrueLender2", + "name": "_lender", + "type": "address" + }, + { + "internalType": "contract ISAFU", + "name": "_safu", + "type": "address" + }, + { + "internalType": "address", + "name": "__owner", + "type": "address" + }, + { + "internalType": "string", + "name": "borrowerName", + "type": "string" + }, + { + "internalType": "string", + "name": "borrowerSymbol", + "type": "string" + } + ], + "name": "singleBorrowerInitialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strategy", + "outputs": [ + { + "internalType": "contract ITrueStrategy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "strategyValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITrueStrategy", + "name": "newStrategy", + "type": "address" + } + ], + "name": "switchStrategy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "utilization", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/truefi/connection.ts b/src/adaptors/truefi/connection.ts new file mode 100644 index 0000000000..4bb0eb7b0c --- /dev/null +++ b/src/adaptors/truefi/connection.ts @@ -0,0 +1,4 @@ +const { Web3 } = require('web3'); +const web3 = new Web3('https://cloudflare-eth.com'); + +module.exports = { web3 }; diff --git a/src/adaptors/truefi/getActiveLoans.ts b/src/adaptors/truefi/getActiveLoans.ts new file mode 100644 index 0000000000..6da6506349 --- /dev/null +++ b/src/adaptors/truefi/getActiveLoans.ts @@ -0,0 +1,56 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const { gql, request } = require('graphql-request'); + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint('8dmnAhKpSrBvcCMyy1Fr7RjRsmoM2Gpw9bg2KXsS7Vps'); +const LOAN_FACTORY_2_START_BLOCK = 12467595; + +interface Loan { + id: string; + amount: typeof BigNumber; + apy: number; + poolAddress: string; + status: string; + startDate: number; + endDate: number; +} + +const getLoans = gql` + { + loans(first: 1000) { + id + amount + APY + poolAddress + status + startDate + endDate + } + } +`; + +function isLoanActive(status: string) { + return status === '1' || status === '2'; +} + +async function getActiveLoans() { + const { loans } = await request( + SUBGRAPH_URL, + getLoans.replace('', LOAN_FACTORY_2_START_BLOCK) + ); + const activeLoansRaw = loans.filter(({ status }) => isLoanActive(status)); + const activeLoans: Loan[] = activeLoansRaw.map( + ({ amount, startDate, endDate, APY, ...rest }) => ({ + ...rest, + apy: Number(APY), + startDate: Number(startDate), + endDate: Number(endDate), + amount: new BigNumber(Number(amount)), + }) + ); + return activeLoans; +} + +module.exports = { + getActiveLoans, +}; diff --git a/src/adaptors/truefi/getPoolApyBase.ts b/src/adaptors/truefi/getPoolApyBase.ts new file mode 100644 index 0000000000..836e1f3415 --- /dev/null +++ b/src/adaptors/truefi/getPoolApyBase.ts @@ -0,0 +1,59 @@ +const BigNumber = require('bignumber.js') +const erc20Abi = require('./abis/erc20.json') +const { web3 } = require('./connection') + +const YEAR_IN_DAYS = 365 +const SECOND_IN_MS = 1000 +const DAY_IN_SECONDS = 24 * 60 * 60 + +const PRECISION = 10 ** 10 +const APY_PRECISION = 10_000 + +const LENDER_ADDRESS = '0xa606dd423dF7dFb65Efe14ab66f5fDEBf62FF583' + +interface Loan { + amount: typeof BigNumber + apy: number + poolAddress: string + status: string + startDate: number + endDate: number +} + +function getInterestForPeriod(periodInDays: number, apyInBps: number) { + return 1 + (apyInBps / APY_PRECISION) * (periodInDays / YEAR_IN_DAYS) +} + +async function getLoanWeightedApyValue({ apy, startDate, endDate, id }: Loan, nowInDays: number) { + if(nowInDays > endDate) { + return new BigNumber(0) + } + + const loanDuration = (endDate - startDate) / DAY_IN_SECONDS + const daysPassed = (nowInDays - startDate) / DAY_IN_SECONDS + + const totalInterest = getInterestForPeriod(loanDuration, apy) + const accruedInterest = getInterestForPeriod(daysPassed, apy) + + const loanTokenPrice = Math.floor(accruedInterest / totalInterest * PRECISION) + + const loan = new web3.eth.Contract(erc20Abi, id) + const lenderBalance = new BigNumber(await loan.methods.balanceOf(LENDER_ADDRESS).call()) + + const scaledAmount = lenderBalance.multipliedBy(loanTokenPrice).div(PRECISION) + return scaledAmount.multipliedBy(apy) +} + +async function getPoolApyBase(poolLoans: Loan[], poolValue: number, tokenDecimals: number) { + const nowInDays = Date.now() / SECOND_IN_MS + + const loanWeightedApyValues = await Promise.all(poolLoans.map(async (loan) => await getLoanWeightedApyValue(loan, nowInDays))) + const loansWeightedApySum = loanWeightedApyValues.reduce((sum, value) => sum.plus(value), new BigNumber(0)) + + const poolApyBaseInBps = loansWeightedApySum.div(poolValue).toNumber() / (10 ** tokenDecimals) + return poolApyBaseInBps / 100 +} + +module.exports = { + getPoolApyBase +} diff --git a/src/adaptors/truefi/getPoolApyRewards.ts b/src/adaptors/truefi/getPoolApyRewards.ts new file mode 100644 index 0000000000..6b2cd8cf68 --- /dev/null +++ b/src/adaptors/truefi/getPoolApyRewards.ts @@ -0,0 +1,26 @@ +const BigNumber = require('bignumber.js') + +const TRU_DECIMALS = 8 +const YEAR_IN_DAYS = 365 +const DAY_IN_SECONDS = 24 * 60 * 60 + +async function getPoolApyRewards(poolAddress: string, poolDecimals: number, truPrice: number, multifarm: any, distributor: any) { + const poolStakes = new BigNumber(await multifarm.methods.stakes(poolAddress).call()) + const poolShare = new BigNumber(await multifarm.methods.getShare(poolAddress).call()) + const totalShares = new BigNumber(await multifarm.methods.shares().call()) + + const duration = new BigNumber(await distributor.methods.duration().call()) + const totalAmount = new BigNumber(await distributor.methods.totalAmount().call()) + + const divider = duration.multipliedBy(totalShares) + const dailyRewards = totalAmount.multipliedBy(poolShare).multipliedBy(DAY_IN_SECONDS).div(divider) + const yearlyRewards = dailyRewards.multipliedBy(YEAR_IN_DAYS) + const yearlyRewardsInUsd = yearlyRewards.multipliedBy(truPrice) + + // rewards / poolStakes * 100% + return yearlyRewardsInUsd.multipliedBy(10 ** (2 + poolDecimals - TRU_DECIMALS)).div(poolStakes).toNumber() +} + +module.exports = { + getPoolApyRewards +} diff --git a/src/adaptors/truefi/getPoolValues.ts b/src/adaptors/truefi/getPoolValues.ts new file mode 100644 index 0000000000..545a284233 --- /dev/null +++ b/src/adaptors/truefi/getPoolValues.ts @@ -0,0 +1,23 @@ +const poolAbi = require('./abis/pool.json') +const { web3 } = require('./connection') + +const unitsMap = { + 6: 'mwei', + 18: 'ether' +} + +async function getPoolValues(poolAddress: string, tokenDecimals: number) { + const pool = new web3.eth.Contract(poolAbi, poolAddress) + + const poolValueRaw: string = await pool.methods.poolValue().call() + const poolValue = web3.utils.fromWei(poolValueRaw, unitsMap[tokenDecimals]) + + const liquidValueRaw: string = await pool.methods.liquidValue().call() + const liquidValue = web3.utils.fromWei(liquidValueRaw, unitsMap[tokenDecimals]) + + return { poolValue, liquidValue } +} + +module.exports = { + getPoolValues +} diff --git a/src/adaptors/truefi/index.ts b/src/adaptors/truefi/index.ts new file mode 100644 index 0000000000..0c716c6ca6 --- /dev/null +++ b/src/adaptors/truefi/index.ts @@ -0,0 +1,149 @@ +const BigNumber = require('bignumber.js'); +const superagent = require('superagent'); + +const { web3 } = require('./connection'); +const { getPoolValues } = require('./getPoolValues'); +const { getActiveLoans } = require('./getActiveLoans'); +const { getPoolApyBase } = require('./getPoolApyBase'); +const { getPoolApyRewards } = require('./getPoolApyRewards'); +const multifarmAbi = require('./abis/multifarm.json'); +const distributorAbi = require('./abis/distributor.json'); +const utils = require('../utils'); + +const MULTIFARM_ADDRESS = + '0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10'.toLowerCase(); +const DISTRIBUTOR_ADDRESS = + '0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70'.toLowerCase(); +const TRU_ADDRESS = '0x4c19596f5aaff459fa38b0f7ed92f11ae6543784'.toLowerCase(); + +const getAddressKey = (address: string) => `ethereum:${address}`; + +interface PoolInfo { + symbol: string; + address: string; + decimals: number; + tokenAddress: string; +} + +const POOL_INFOS: PoolInfo[] = [ + { + symbol: 'USDC', + address: '0xA991356d261fbaF194463aF6DF8f0464F8f1c742'.toLowerCase(), + decimals: 6, + tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'.toLowerCase(), + }, + { + symbol: 'USDT', + address: '0x6002b1dcB26E7B1AA797A17551C6F487923299d7'.toLowerCase(), + decimals: 6, + tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7'.toLowerCase(), + }, + { + symbol: 'TUSD', + address: '0x97cE06c3e3D027715b2d6C22e67D5096000072E5'.toLowerCase(), + decimals: 18, + tokenAddress: '0x0000000000085d4780b73119b644ae5ecd22b376'.toLowerCase(), + }, + { + symbol: 'BUSD', + address: '0x1Ed460D149D48FA7d91703bf4890F97220C09437'.toLowerCase(), + decimals: 18, + tokenAddress: '0x4fabb145d64652a948d72533023f6e7a623c7c53'.toLowerCase(), + }, +]; + +interface PoolAdapter { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + ltv: number; +} + +const buildPoolAdapter = async ( + { address, decimals, symbol, tokenAddress }: PoolInfo, + tokenPrice: number, + allActiveLoans: Loan[], + truPrice: number, + multifarm: any, + distributor: any +): Promise => { + const poolActiveLoans = allActiveLoans.filter( + ({ poolAddress }) => poolAddress === address + ); + const { poolValue, liquidValue } = await getPoolValues(address, decimals); + const poolApyBase = await getPoolApyBase( + poolActiveLoans, + poolValue, + decimals + ); + const poolApyRewards = await getPoolApyRewards( + address, + decimals, + truPrice, + multifarm, + distributor + ); + + return { + pool: address, + chain: utils.formatChain('ethereum'), + project: 'truefi', + symbol, + tvlUsd: liquidValue * tokenPrice, + apyBase: poolApyBase, + apyReward: poolApyRewards, + rewardTokens: [TRU_ADDRESS], + underlyingTokens: [tokenAddress], + // borrow fields + ltv: 0, // permissioned borrowing + }; +}; + +const apy = async () => { + const coins = [ + ...POOL_INFOS.map(({ tokenAddress }) => tokenAddress).map(getAddressKey), + getAddressKey(TRU_ADDRESS), + ] + .join(',') + .toLowerCase(); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${coins}`) + ).body.coins; + + const truPrice = prices[getAddressKey(TRU_ADDRESS)].price; + const activeLoans = await getActiveLoans(); + const multifarm = new web3.eth.Contract(multifarmAbi, MULTIFARM_ADDRESS); + const distributor = new web3.eth.Contract( + distributorAbi, + DISTRIBUTOR_ADDRESS + ); + + const adapters: PoolAdapter[] = []; + for (const poolInfo of POOL_INFOS) { + const tokenPriceKey = getAddressKey(poolInfo.tokenAddress); + const tokenPrice = prices[tokenPriceKey].price; + const adapter = await buildPoolAdapter( + poolInfo, + tokenPrice, + activeLoans, + truPrice, + multifarm, + distributor + ); + adapters.push(adapter); + } + + return adapters; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://app.truefi.io/lend', +}; diff --git a/src/adaptors/turbos/index.js b/src/adaptors/turbos/index.js new file mode 100644 index 0000000000..ce6a7210ec --- /dev/null +++ b/src/adaptors/turbos/index.js @@ -0,0 +1,51 @@ +const utils = require('../utils'); +const axios = require('axios'); + +const PAGE_SIZE = 100; +const API_URL = 'https://api2.turbos.finance/pools'; + +const getApy = async () => { + let pools = []; + let currentPage = 1; + + while (true) { + const result = await axios.get(API_URL, { + params: { + page: currentPage++, + pageSize: PAGE_SIZE, + includeRisk: false, + }, + headers: { 'Api-Version': 'v2' }, + }); + pools.push(...result.data.result); + if (result.data.result.length < PAGE_SIZE) break; + } + + pools = pools.filter((p) => p.apr > 0 && p.liquidity_usd >= 10000); + + return pools.map((p) => ({ + chain: utils.formatChain('sui'), + project: 'turbos', + pool: p.pool_id, + symbol: p.coin_symbol_a + '-' + p.coin_symbol_b, + tvlUsd: p.liquidity_usd, + apyBase: p.fee_apr, + apyBase7d: p.fee_7d_apr, + volumeUsd1d: p.volume_24h_usd, + volumeUsd7d: p.volume_7d_usd, + apyReward: p.reward_apr, + rewardTokens: p.reward_infos.map((info) => { + // Get token symbol + return info.fields.vault_coin_type.split('::').pop(); + }), + poolMeta: `${Number(p.fee) / 10000}%`, + underlyingTokens: [p.coin_symbol_a, p.coin_symbol_b], + url: `https://app.turbos.finance/#/pools/${p.pool_id}/add-liquidity`, + })); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.turbos.finance/#/pools', +}; diff --git a/src/adaptors/umami-finance/abis/arbMasterchef.js b/src/adaptors/umami-finance/abis/arbMasterchef.js new file mode 100644 index 0000000000..447567a22c --- /dev/null +++ b/src/adaptors/umami-finance/abis/arbMasterchef.js @@ -0,0 +1,363 @@ +const ARB_MASTER_CHEF_ABI = [ + { + type: 'constructor', + inputs: [ + { name: '_arb', type: 'address', internalType: 'contract ERC20' }, + { + name: '_arbVault', + type: 'address', + internalType: 'contract ArbVaultGmx', + }, + { name: '_auth', type: 'address', internalType: 'contract Auth' }, + { name: '_arbPerSec', type: 'uint256', internalType: 'uint256' }, + { name: '_startTimestamp', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'ARB', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract ERC20' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'AUTH', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract Auth' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'add', + inputs: [ + { name: '_allocPoint', type: 'uint256', internalType: 'uint256' }, + { name: '_lpToken', type: 'address', internalType: 'contract ERC20' }, + { + name: '_rewarder', + type: 'address', + internalType: 'contract IRewarder', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'arbPerSec', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'arbVault', + inputs: [], + outputs: [ + { name: '', type: 'address', internalType: 'contract ArbVaultGmx' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'collectAllPoolRewards', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'deposit', + inputs: [ + { name: '_pid', type: 'uint256', internalType: 'uint256' }, + { name: '_amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'emergencyWithdraw', + inputs: [{ name: '_pid', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getPIdFromLP', + inputs: [{ name: 'lp', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'massUpdatePools', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'pendingTokens', + inputs: [ + { name: '_pid', type: 'uint256', internalType: 'uint256' }, + { name: '_user', type: 'address', internalType: 'address' }, + ], + outputs: [ + { name: 'pendingOArb', type: 'uint256', internalType: 'uint256' }, + { name: 'bonusTokenAddress', type: 'address', internalType: 'address' }, + { name: 'bonusTokenSymbol', type: 'string', internalType: 'string' }, + { name: 'pendingBonusToken', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'poolInfo', + inputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + outputs: [ + { name: 'lpToken', type: 'address', internalType: 'contract ERC20' }, + { name: 'allocPoint', type: 'uint256', internalType: 'uint256' }, + { name: 'lastRewardTimestamp', type: 'uint256', internalType: 'uint256' }, + { name: 'accOArbPerShare', type: 'uint256', internalType: 'uint256' }, + { name: 'rewarder', type: 'address', internalType: 'contract IRewarder' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'poolLength', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'rewarderBonusTokenInfo', + inputs: [{ name: '_pid', type: 'uint256', internalType: 'uint256' }], + outputs: [ + { name: 'bonusTokenAddress', type: 'address', internalType: 'address' }, + { name: 'bonusTokenSymbol', type: 'string', internalType: 'string' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'set', + inputs: [ + { name: '_pid', type: 'uint256', internalType: 'uint256' }, + { name: '_allocPoint', type: 'uint256', internalType: 'uint256' }, + { + name: '_rewarder', + type: 'address', + internalType: 'contract IRewarder', + }, + { name: 'overwrite', type: 'bool', internalType: 'bool' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'startTimestamp', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalAllocPoint', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'updateEmissionRate', + inputs: [{ name: '_arbPerSec', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updatePool', + inputs: [{ name: '_pid', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'userInfo', + inputs: [ + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'address', internalType: 'address' }, + ], + outputs: [ + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { name: 'rewardDebt', type: 'uint256', internalType: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'withdraw', + inputs: [ + { name: '_pid', type: 'uint256', internalType: 'uint256' }, + { name: '_amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Add', + inputs: [ + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'allocPoint', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'lpToken', + type: 'address', + indexed: true, + internalType: 'contract ERC20', + }, + { + name: 'rewarder', + type: 'address', + indexed: true, + internalType: 'contract IRewarder', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Deposit', + inputs: [ + { name: 'user', type: 'address', indexed: true, internalType: 'address' }, + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'EmergencyWithdraw', + inputs: [ + { name: 'user', type: 'address', indexed: true, internalType: 'address' }, + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Harvest', + inputs: [ + { name: 'user', type: 'address', indexed: true, internalType: 'address' }, + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Set', + inputs: [ + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'allocPoint', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'rewarder', + type: 'address', + indexed: true, + internalType: 'contract IRewarder', + }, + { name: 'overwrite', type: 'bool', indexed: false, internalType: 'bool' }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'UpdateEmissionRate', + inputs: [ + { name: 'user', type: 'address', indexed: true, internalType: 'address' }, + { + name: '_arbPerSec', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'UpdatePool', + inputs: [ + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'lastRewardTimestamp', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'lpSupply', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'accOArbPerShare', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Withdraw', + inputs: [ + { name: 'user', type: 'address', indexed: true, internalType: 'address' }, + { name: 'pid', type: 'uint256', indexed: true, internalType: 'uint256' }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, +]; + +module.exports = { + ARB_MASTER_CHEF_ABI, +}; diff --git a/src/adaptors/umami-finance/abis/glpAssetVault.js b/src/adaptors/umami-finance/abis/glpAssetVault.js new file mode 100644 index 0000000000..b1a50c7a6f --- /dev/null +++ b/src/adaptors/umami-finance/abis/glpAssetVault.js @@ -0,0 +1,935 @@ +const GLP_ASSET_VAULT_ABI = [ + { + inputs: [ + { + internalType: 'contract ERC20', + name: '_asset', + type: 'address', + }, + { + internalType: 'string', + name: '_name', + type: 'string', + }, + { + internalType: 'string', + name: '_symbol', + type: 'string', + }, + { + internalType: 'address', + name: '_aggregateVault', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'AUTH', + outputs: [ + { + internalType: 'contract Auth', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'aggregateVault', + outputs: [ + { + internalType: 'contract AggregateVault', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [ + { + internalType: 'contract ERC20', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'convertToAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'convertToShares', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'deposit', + outputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'maxDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'maxMint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'maxRedeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'maxWithdraw', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'mint', + outputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_mintAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: '_timelockContract', + type: 'address', + }, + ], + name: 'mintTimelockBoost', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'nonces', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauseDepositWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'deadline', + type: 'uint256', + }, + { + internalType: 'uint8', + name: 'v', + type: 'uint8', + }, + { + internalType: 'bytes32', + name: 'r', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 's', + type: 'bytes32', + }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pps', + outputs: [ + { + internalType: 'uint256', + name: 'pricePerShare', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'previewDeposit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'size', + type: 'uint256', + }, + ], + name: 'previewDepositFee', + outputs: [ + { + internalType: 'uint256', + name: 'totalDepositFee', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'previewMint', + outputs: [ + { + internalType: 'uint256', + name: '_mintAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'previewRedeem', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'previewVaultCap', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'previewWithdraw', + outputs: [ + { + internalType: 'uint256', + name: '_withdrawAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'size', + type: 'uint256', + }, + ], + name: 'previewWithdrawalFee', + outputs: [ + { + internalType: 'uint256', + name: 'totalWithdrawalFee', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'redeem', + outputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'tvl', + outputs: [ + { + internalType: 'uint256', + name: 'totalValueLocked', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unpauseDepositWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AggregateVault', + name: '_newAggregateVault', + type: 'address', + }, + ], + name: 'updateAggregateVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'bytes32[]', + name: 'merkleProof', + type: 'bytes32[]', + }, + ], + name: 'whitelistDeposit', + outputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + ], + name: 'withdraw', + outputs: [ + { + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + +module.exports = { + GLP_ASSET_VAULT_ABI, +}; diff --git a/src/adaptors/umami-finance/abis/gmAssetVault.js b/src/adaptors/umami-finance/abis/gmAssetVault.js new file mode 100644 index 0000000000..bf572a31b3 --- /dev/null +++ b/src/adaptors/umami-finance/abis/gmAssetVault.js @@ -0,0 +1,615 @@ +const GM_ASSET_VAULT_ABI = [ + { + inputs: [ + { internalType: 'contract ERC20', name: '_asset', type: 'address' }, + { internalType: 'string', name: '_name', type: 'string' }, + { internalType: 'string', name: '_symbol', type: 'string' }, + { internalType: 'address', name: '_aggregateVault', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'DepositsPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'DepositsUnpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'WithdrawalsPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'WithdrawalsUnpaused', + type: 'event', + }, + { + inputs: [], + name: 'AUTH', + outputs: [{ internalType: 'contract Auth', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'aggregateVault', + outputs: [ + { internalType: 'contract AggregateVault', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'contract ERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_burnAmount', type: 'uint256' }], + name: 'burnShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'key', type: 'uint256' }], + name: 'cancelRequest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'depositPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + ], + name: 'depositWithCallback', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_assetAmount', type: 'uint256' }, + { internalType: 'address', name: 'feeReciever', type: 'address' }, + { internalType: 'uint256', name: '_depositFees', type: 'uint256' }, + ], + name: 'lodgeAssets', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_mintAmount', type: 'uint256' }, + { internalType: 'address', name: '_toAddress', type: 'address' }, + ], + name: 'mintTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pauseDepositWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseDeposits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseWithdrawals', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pps', + outputs: [ + { internalType: 'uint256', name: 'pricePerShare', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'size', type: 'uint256' }], + name: 'previewDepositFee', + outputs: [ + { internalType: 'uint256', name: 'totalDepositFee', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'previewVaultCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'size', type: 'uint256' }], + name: 'previewWithdrawalFee', + outputs: [ + { internalType: 'uint256', name: 'totalWithdrawalFee', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + ], + name: 'redeemWithCallback', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_amt', type: 'uint256' }, + ], + name: 'returnAssets', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: '_amt', type: 'uint256' }, + ], + name: 'returnShares', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { internalType: 'uint256', name: 'totalValueLocked', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpauseDepositWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpauseDeposits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpauseWithdrawals', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract AggregateVault', + name: '_newAggregateVault', + type: 'address', + }, + ], + name: 'updateAggregateVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawalPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { + GM_ASSET_VAULT_ABI, +}; diff --git a/src/adaptors/umami-finance/abis/gmiAggregateVault.js b/src/adaptors/umami-finance/abis/gmiAggregateVault.js new file mode 100644 index 0000000000..4aaad827c0 --- /dev/null +++ b/src/adaptors/umami-finance/abis/gmiAggregateVault.js @@ -0,0 +1,716 @@ +const GMI_AGGREGATE_VAULT_ABI = [ + { + inputs: [ + { internalType: 'contract Auth', name: '_auth', type: 'address' }, + { + internalType: 'contract WhitelistedTokenRegistry', + name: '_whitelistedTokenRegistry', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AmountEqualsZero', type: 'error' }, + { inputs: [], name: 'CallbackHandlerNotSet', type: 'error' }, + { inputs: [], name: 'DelegateViewRevert', type: 'error' }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'EmptyContract', + type: 'error', + }, + { inputs: [], name: 'FailedConfigValidation', type: 'error' }, + { inputs: [], name: 'FailedNettingCheck', type: 'error' }, + { inputs: [], name: 'InvalidAsset', type: 'error' }, + { inputs: [], name: 'MinGasRequirement', type: 'error' }, + { inputs: [], name: 'NotAssetVault', type: 'error' }, + { inputs: [], name: 'NotWhitelistedToken', type: 'error' }, + { inputs: [], name: 'OnlySelf', type: 'error' }, + { inputs: [], name: 'OraclePriceSizeInvalid', type: 'error' }, + { inputs: [], name: 'RebalanceNotOpen', type: 'error' }, + { inputs: [], name: 'RebalanceOpen', type: 'error' }, + { inputs: [], name: 'UnknownCallback', type: 'error' }, + { inputs: [], name: 'UnknownHandlerContract', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { inputs: [], name: 'notRequestHandlerOrAssetVault', type: 'error' }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes4', name: '_sig', type: 'bytes4' }, + { + indexed: true, + internalType: 'address', + name: '_handler', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: '_enabled', type: 'bool' }, + ], + name: 'CallbackHandlerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'bytes4', name: '_sig', type: 'bytes4' }, + { + indexed: true, + internalType: 'address', + name: '_handler', + type: 'address', + }, + ], + name: 'DefaultHandlerContractUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_contract', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: '_enabled', type: 'bool' }, + ], + name: 'HandlerContractUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_handled', + type: 'address', + }, + { indexed: false, internalType: 'bool', name: '_enabled', type: 'bool' }, + ], + name: 'SwapHandlerUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_token', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: '_isWhitelisted', + type: 'bool', + }, + ], + name: 'WhitelistedTokenUpdated', + type: 'event', + }, + { stateMutability: 'payable', type: 'fallback' }, + { + inputs: [], + name: 'AUTH', + outputs: [{ internalType: 'contract Auth', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPositionManager', + name: '_manager', + type: 'address', + }, + ], + name: 'addPositionManager', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'key', type: 'uint256' }], + name: 'clearRequest', + outputs: [ + { + components: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + { internalType: 'bool', name: 'isDeposit', type: 'bool' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'minOut', type: 'uint256' }, + { internalType: 'uint256', name: 'requestBlock', type: 'uint256' }, + ], + internalType: 'struct AggregateVaultStorage.OCRequest', + name: 'order', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address[]', + name: 'realtimeFeedTokens', + type: 'address[]', + }, + { + internalType: 'bytes[]', + name: 'realtimeFeedData', + type: 'bytes[]', + }, + ], + internalType: 'struct AggregateVaultStorage.SetPricesParams', + name: 'priceData', + type: 'tuple', + }, + { internalType: 'bytes', name: '_hook', type: 'bytes' }, + ], + name: 'closeRebalancePeriod', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'currentCallbackHandler', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: '', type: 'bytes4' }], + name: 'defaultHandlers', + outputs: [ + { internalType: 'contract IHandlerContract', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_target', type: 'address' }, + { internalType: 'bytes', name: '_data', type: 'bytes' }, + ], + name: 'delegateview', + outputs: [ + { internalType: 'bool', name: '_success', type: 'bool' }, + { internalType: 'bytes', name: '_ret', type: 'bytes' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_target', type: 'address' }, + { internalType: 'bytes', name: '_data', type: 'bytes' }, + ], + name: 'delegateviewRevert', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'depositEth', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_handler', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'execute', + outputs: [{ internalType: 'bytes', name: 'ret', type: 'bytes' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ISwapManager', + name: '_swapManager', + type: 'address', + }, + { internalType: 'address', name: '_tokenIn', type: 'address' }, + { internalType: 'address', name: '_tokenOut', type: 'address' }, + { internalType: 'uint256', name: '_amountIn', type: 'uint256' }, + { internalType: 'uint256', name: '_minOut', type: 'uint256' }, + { internalType: 'bytes', name: '_data', type: 'bytes' }, + ], + name: 'executeSwap', + outputs: [{ internalType: 'uint256', name: '_amountOut', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_handler', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + { internalType: 'address', name: '_callbackHandler', type: 'address' }, + ], + name: 'executeWithCallbackHandler', + outputs: [{ internalType: 'bytes', name: 'ret', type: 'bytes' }], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'key', type: 'uint256' }], + name: 'getRequest', + outputs: [ + { + components: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + { internalType: 'bool', name: 'isDeposit', type: 'bool' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'minOut', type: 'uint256' }, + { internalType: 'uint256', name: 'requestBlock', type: 'uint256' }, + ], + internalType: 'struct AggregateVaultStorage.OCRequest', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_assetVault', type: 'address' }, + { internalType: 'bool', name: 'isDeposit', type: 'bool' }, + { internalType: 'bool', name: 'useLlo', type: 'bool' }, + ], + name: 'getVaultPPS', + outputs: [{ internalType: 'uint256', name: '_pps', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_assetVault', type: 'address' }, + { internalType: 'bool', name: 'useLlo', type: 'bool' }, + ], + name: 'getVaultTVL', + outputs: [{ internalType: 'uint256', name: '_tvl', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_asset', type: 'address' }], + name: 'getVaultTimelockAddress', + outputs: [{ internalType: 'address', name: 'timelock', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + ], + name: 'handleDeposit', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'minOutAfterFees', type: 'uint256' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'callback', type: 'address' }, + ], + name: 'handleWithdraw', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IHandlerContract', name: '', type: 'address' }, + { internalType: 'bytes4', name: '', type: 'bytes4' }, + ], + name: 'handlerContractCallbacks', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract IHandlerContract', name: '', type: 'address' }, + ], + name: 'handlerContracts', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'int256', name: 'amount', type: 'int256' }, + ], + name: 'incrementEpochDelta', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes[]', name: 'data', type: 'bytes[]' }], + name: 'multicall', + outputs: [ + { internalType: 'bytes[]', name: 'results', type: 'bytes[]' }, + { internalType: 'uint256[]', name: 'gasEstimates', type: 'uint256[]' }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256[2]', + name: 'nextVaultIndexAlloc', + type: 'uint256[2]', + }, + { + internalType: 'uint256[2]', + name: 'nextIndexComposition', + type: 'uint256[2]', + }, + { internalType: 'int256', name: 'externalPosition', type: 'int256' }, + { + components: [ + { + internalType: 'address[]', + name: 'realtimeFeedTokens', + type: 'address[]', + }, + { + internalType: 'bytes[]', + name: 'realtimeFeedData', + type: 'bytes[]', + }, + ], + internalType: 'struct AggregateVaultStorage.SetPricesParams', + name: 'priceData', + type: 'tuple', + }, + { internalType: 'bytes', name: '_hook', type: 'bytes' }, + ], + name: 'openRebalancePeriod', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseDeposits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'size', type: 'uint256' }, + { internalType: 'bool', name: 'useLlo', type: 'bool' }, + ], + name: 'previewDepositFee', + outputs: [ + { internalType: 'uint256', name: 'totalDepositFee', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_asset', type: 'address' }], + name: 'previewVaultCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'size', type: 'uint256' }, + { internalType: 'bool', name: 'useLlo', type: 'bool' }, + ], + name: 'previewWithdrawalFee', + outputs: [ + { internalType: 'uint256', name: 'totalWithdrawalFee', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32[]', name: '_slots', type: 'bytes32[]' }], + name: 'readStorageSlots', + outputs: [ + { internalType: 'bytes32[]', name: '_values', type: 'bytes32[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rebalanceOpen', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'underlyingToken', type: 'address' }, + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'totalWithdrawalFee', type: 'uint256' }, + ], + name: 'releaseWithdrawal', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'address', name: 'vault', type: 'address' }, + { internalType: 'address', name: 'token', type: 'address' }, + { + internalType: 'address', + name: 'timelockYieldBoost', + type: 'address', + }, + { internalType: 'uint256', name: 'feeWatermarkPPS', type: 'uint256' }, + { + internalType: 'uint256', + name: 'feeWatermarkDate', + type: 'uint256', + }, + { internalType: 'int256', name: 'epochDelta', type: 'int256' }, + { + internalType: 'uint256', + name: 'lastCheckpointTvl', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'timelockBoostPercent', + type: 'uint256', + }, + ], + internalType: 'struct AggregateVaultStorage.AssetVaultStorage[2]', + name: 'assetVaults', + type: 'tuple[2]', + }, + ], + name: 'setAssetVaults', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'executionGasAmount', type: 'uint256' }, + { + internalType: 'uint256', + name: 'executionGasAmountCallback', + type: 'uint256', + }, + ], + name: 'setExecutionGasAmounts', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_recipient', type: 'address' }, + { internalType: 'address', name: '_depositFeeEscrow', type: 'address' }, + { + internalType: 'address', + name: '_withdrawalFeeEscrow', + type: 'address', + }, + ], + name: 'setFeeRecipient', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint8', name: '_newBlockTolerance', type: 'uint8' }, + ], + name: 'setL1BlockTolerance', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'enum Peripheral', name: 'peripheral', type: 'uint8' }, + { internalType: 'address', name: 'addr', type: 'address' }, + ], + name: 'setPeripheral', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newKeeper', type: 'address' }], + name: 'setRebalanceKeeper', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_newVal', type: 'bool' }], + name: 'setShouldCheckNetting', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bool', name: '_newVal', type: 'bool' }], + name: 'setShouldUseGmxFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newNettedThreshold', type: 'uint256' }, + { + internalType: 'uint256', + name: '_zeroSumPnlThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: '_swapSlippage', type: 'uint256' }, + ], + name: 'setThresholds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256[2]', name: '_newCaps', type: 'uint256[2]' }, + ], + name: 'setVaultCaps', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_performanceFee', type: 'uint256' }, + { internalType: 'uint256', name: '_managementFee', type: 'uint256' }, + { internalType: 'uint256', name: '_withdrawalFee', type: 'uint256' }, + { internalType: 'uint256', name: '_depositFee', type: 'uint256' }, + ], + name: 'setVaultFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { + internalType: 'uint256', + name: 'newTimelockFeePercent', + type: 'uint256', + }, + ], + name: 'setVaultTimelockPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'contract ISwapManager', name: '', type: 'address' }, + ], + name: 'swapHandlers', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'unpauseDeposits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes4', name: '_sig', type: 'bytes4' }, + { + internalType: 'contract IHandlerContract', + name: '_handler', + type: 'address', + }, + ], + name: 'updateDefaultHandlerContract', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IHandlerContract', + name: '_handler', + type: 'address', + }, + { internalType: 'bool', name: '_enabled', type: 'bool' }, + ], + name: 'updateHandlerContract', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract ISwapManager', + name: '_manager', + type: 'address', + }, + { internalType: 'bool', name: '_enabled', type: 'bool' }, + ], + name: 'updateSwapHandler', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdrawEth', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, +]; + +module.exports = { + GMI_AGGREGATE_VAULT_ABI, +}; diff --git a/src/adaptors/umami-finance/abis/gmiVault.js b/src/adaptors/umami-finance/abis/gmiVault.js new file mode 100644 index 0000000000..692142ad47 --- /dev/null +++ b/src/adaptors/umami-finance/abis/gmiVault.js @@ -0,0 +1,1023 @@ +const GMI_VAULT_ABI = [ + { + type: 'constructor', + inputs: [ + { name: 'auth', type: 'address', internalType: 'contract Auth' }, + { + name: 'registry', + type: 'address', + internalType: 'contract WhitelistedTokenRegistry', + }, + ], + stateMutability: 'nonpayable', + }, + { type: 'fallback', stateMutability: 'payable' }, + { type: 'receive', stateMutability: 'payable' }, + { + type: 'function', + name: 'AUTH', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract Auth' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'DOMAIN_SEPARATOR', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'INDEX_SIZE', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'STORAGE_SLOT', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { name: '', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'appraiseAssets', + inputs: [ + { + name: 'assetAmounts', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: '', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'balances', + inputs: [], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'collectArb', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'currentCallbackHandler', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'defaultHandlers', + inputs: [{ name: '', type: 'bytes4', internalType: 'bytes4' }], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IHandlerContract', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'deposit', + inputs: [ + { name: 'assets', type: 'uint256[]', internalType: 'uint256[]' }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + { name: 'receiver', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: 'shares', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'depositEth', + inputs: [], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'execute', + inputs: [ + { name: '_handler', type: 'address', internalType: 'address' }, + { name: 'data', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [{ name: 'ret', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'executeSwap', + inputs: [ + { + name: '_swapManager', + type: 'address', + internalType: 'contract ISwapManager', + }, + { name: '_tokenIn', type: 'address', internalType: 'address' }, + { name: '_tokenOut', type: 'address', internalType: 'address' }, + { name: '_amountIn', type: 'uint256', internalType: 'uint256' }, + { name: '_minOut', type: 'uint256', internalType: 'uint256' }, + { name: '_data', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [{ name: '_amountOut', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'executeWithCallbackHandler', + inputs: [ + { name: '_handler', type: 'address', internalType: 'address' }, + { name: 'data', type: 'bytes', internalType: 'bytes' }, + { + name: '_callbackHandler', + type: 'address', + internalType: 'address', + }, + ], + outputs: [{ name: 'ret', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'getUnderlyingMarketCompositions', + inputs: [], + outputs: [ + { + name: 'underlyingBalances', + type: 'uint256[2]', + internalType: 'uint256[2]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getWeights', + inputs: [], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'handlerContractCallbacks', + inputs: [ + { + name: '', + type: 'address', + internalType: 'contract IHandlerContract', + }, + { name: '', type: 'bytes4', internalType: 'bytes4' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'handlerContracts', + inputs: [ + { + name: '', + type: 'address', + internalType: 'contract IHandlerContract', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'indexAssets', + inputs: [], + outputs: [ + { + name: 'assetAddresses', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'initStorage', + inputs: [ + { name: 'gmHandler', type: 'address', internalType: 'address' }, + { + name: '_indexAssets', + type: 'address[]', + internalType: 'address[]', + }, + { + name: '_weights', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: '_depositTolerance', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '_mintCapTolerance', + type: 'uint256', + internalType: 'uint256', + }, + { name: '_fallbackPool', type: 'uint8', internalType: 'uint8' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'nonces', + inputs: [{ name: '', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'permit', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + { name: 'deadline', type: 'uint256', internalType: 'uint256' }, + { name: 'v', type: 'uint8', internalType: 'uint8' }, + { name: 'r', type: 'bytes32', internalType: 'bytes32' }, + { name: 's', type: 'bytes32', internalType: 'bytes32' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'pps', + inputs: [ + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [ + { + name: 'pricePerShare', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewMint', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'previewRedeem', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'redeem', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { name: 'receiver', type: 'address', internalType: 'address' }, + { name: 'owner', type: 'address', internalType: 'address' }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [{ name: 'assets', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'retrieveEth', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'setDepositTolerance', + inputs: [ + { + name: 'newTolderance', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setFallbackMintPool', + inputs: [{ name: 'poolIndex', type: 'uint8', internalType: 'uint8' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setGmiV2Handler', + inputs: [{ name: 'gmiHandler', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setMintCapTolerance', + inputs: [ + { + name: 'newTolderance', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setTargetWeights', + inputs: [ + { + name: 'newWeights', + type: 'uint256[]', + internalType: 'uint256[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'sharesToMarketTokens', + inputs: [ + { name: 'shares', type: 'uint256', internalType: 'uint256' }, + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [{ name: '', type: 'uint256[]', internalType: 'uint256[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'swapHandlers', + inputs: [ + { + name: '', + type: 'address', + internalType: 'contract ISwapManager', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'tvl', + inputs: [ + { + name: 'prices', + type: 'tuple[]', + internalType: 'struct GmxStorage.MarketPrices[]', + components: [ + { + name: 'indexTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'longTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + name: 'shortTokenPrice', + type: 'tuple', + internalType: 'struct GmxStorage.Price', + components: [ + { name: 'min', type: 'uint256', internalType: 'uint256' }, + { name: 'max', type: 'uint256', internalType: 'uint256' }, + ], + }, + ], + }, + ], + outputs: [ + { + name: 'totalValueLocked', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'updateDefaultHandlerContract', + inputs: [ + { name: '_sig', type: 'bytes4', internalType: 'bytes4' }, + { + name: '_handler', + type: 'address', + internalType: 'contract IHandlerContract', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updateHandlerContract', + inputs: [ + { + name: '_handler', + type: 'address', + internalType: 'contract IHandlerContract', + }, + { name: '_enabled', type: 'bool', internalType: 'bool' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updateSwapHandler', + inputs: [ + { + name: '_manager', + type: 'address', + internalType: 'contract ISwapManager', + }, + { name: '_enabled', type: 'bool', internalType: 'bool' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'CallbackHandlerUpdated', + inputs: [ + { + name: '_sig', + type: 'bytes4', + indexed: true, + internalType: 'bytes4', + }, + { + name: '_handler', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: '_enabled', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultHandlerContractUpdated', + inputs: [ + { + name: '_sig', + type: 'bytes4', + indexed: true, + internalType: 'bytes4', + }, + { + name: '_handler', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Deposit', + inputs: [ + { + name: 'caller', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'shares', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'HandlerContractUpdated', + inputs: [ + { + name: '_contract', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: '_enabled', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'SwapHandlerUpdated', + inputs: [ + { + name: '_handled', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: '_enabled', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'WhitelistedTokenUpdated', + inputs: [ + { + name: '_token', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: '_isWhitelisted', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Withdraw', + inputs: [ + { + name: 'caller', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + { + name: 'shares', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'CallbackHandlerNotSet', inputs: [] }, + { + type: 'error', + name: 'EmptyContract', + inputs: [{ name: '', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'NotWhitelistedToken', inputs: [] }, + { type: 'error', name: 'OnlySelf', inputs: [] }, + { type: 'error', name: 'UnknownCallback', inputs: [] }, + { type: 'error', name: 'UnknownHandlerContract', inputs: [] }, +]; + +module.exports = { GMI_VAULT_ABI }; diff --git a/src/adaptors/umami-finance/abis/gmxDataStore.js b/src/adaptors/umami-finance/abis/gmxDataStore.js new file mode 100644 index 0000000000..20f5e7ff98 --- /dev/null +++ b/src/adaptors/umami-finance/abis/gmxDataStore.js @@ -0,0 +1,1435 @@ +const ABI = [ + { + inputs: [ + { + internalType: 'contract RoleStore', + name: '_roleStore', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'address', + name: 'msgSender', + type: 'address', + }, + { + internalType: 'string', + name: 'role', + type: 'string', + }, + ], + name: 'Unauthorized', + type: 'error', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'addAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'addBytes32', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'addUint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'addressArrayValues', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'addressValues', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + ], + name: 'applyBoundedDeltaToUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + ], + name: 'applyDeltaToInt', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + { + internalType: 'string', + name: 'errorMessage', + type: 'string', + }, + ], + name: 'applyDeltaToUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'boolArrayValues', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'boolValues', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'bytes32ArrayValues', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'bytes32Values', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'containsAddress', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'containsBytes32', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'containsUint', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + ], + name: 'decrementInt', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'decrementUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getAddressArray', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + ], + name: 'getAddressCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getAddressValuesAt', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getBool', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getBoolArray', + outputs: [ + { + internalType: 'bool[]', + name: '', + type: 'bool[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getBytes32', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getBytes32Array', + outputs: [ + { + internalType: 'bytes32[]', + name: '', + type: 'bytes32[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + ], + name: 'getBytes32Count', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getBytes32ValuesAt', + outputs: [ + { + internalType: 'bytes32[]', + name: '', + type: 'bytes32[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getInt', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getIntArray', + outputs: [ + { + internalType: 'int256[]', + name: '', + type: 'int256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getString', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getStringArray', + outputs: [ + { + internalType: 'string[]', + name: '', + type: 'string[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getUintArray', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + ], + name: 'getUintCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getUintValuesAt', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + ], + name: 'incrementInt', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'incrementUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'intArrayValues', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'intValues', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'removeAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeAddressArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeBool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeBoolArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'removeBytes32', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeBytes32', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeBytes32Array', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeInt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeIntArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeString', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeStringArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeUint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'setKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'removeUint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'removeUintArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'roleStore', + outputs: [ + { + internalType: 'contract RoleStore', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'value', + type: 'address', + }, + ], + name: 'setAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'address[]', + name: 'value', + type: 'address[]', + }, + ], + name: 'setAddressArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bool', + name: 'value', + type: 'bool', + }, + ], + name: 'setBool', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bool[]', + name: 'value', + type: 'bool[]', + }, + ], + name: 'setBoolArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32', + name: 'value', + type: 'bytes32', + }, + ], + name: 'setBytes32', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'bytes32[]', + name: 'value', + type: 'bytes32[]', + }, + ], + name: 'setBytes32Array', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256', + name: 'value', + type: 'int256', + }, + ], + name: 'setInt', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'int256[]', + name: 'value', + type: 'int256[]', + }, + ], + name: 'setIntArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'string', + name: 'value', + type: 'string', + }, + ], + name: 'setString', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'string[]', + name: 'value', + type: 'string[]', + }, + ], + name: 'setStringArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'setUint', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + { + internalType: 'uint256[]', + name: 'value', + type: 'uint256[]', + }, + ], + name: 'setUintArray', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'stringArrayValues', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'stringValues', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'uintArrayValues', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + name: 'uintValues', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { ABI }; diff --git a/src/adaptors/umami-finance/abis/gmxSyntheticsReader.js b/src/adaptors/umami-finance/abis/gmxSyntheticsReader.js new file mode 100644 index 0000000000..b50005e41c --- /dev/null +++ b/src/adaptors/umami-finance/abis/gmxSyntheticsReader.js @@ -0,0 +1,3953 @@ +const ABI = [ + { + inputs: [ + { + internalType: 'address', + name: 'market', + type: 'address', + }, + ], + name: 'DisabledMarket', + type: 'error', + }, + { + inputs: [], + name: 'EmptyMarket', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getAccountOrders', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'cancellationReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialCollateralToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'swapPath', + type: 'address[]', + }, + ], + internalType: 'struct Order.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'enum Order.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'enum Order.DecreasePositionSwapType', + name: 'decreasePositionSwapType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialCollateralDeltaAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'triggerPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'acceptablePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minOutputAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Order.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + { + internalType: 'bool', + name: 'autoCancel', + type: 'bool', + }, + ], + internalType: 'struct Order.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Order.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'contract IReferralStorage', + name: 'referralStorage', + type: 'address', + }, + { + internalType: 'bytes32[]', + name: 'positionKeys', + type: 'bytes32[]', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices[]', + name: 'prices', + type: 'tuple[]', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getAccountPositionInfoList', + outputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: 'position', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'bytes32', + name: 'referralCode', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'affiliate', + type: 'address', + }, + { + internalType: 'address', + name: 'trader', + type: 'address', + }, + { + internalType: 'uint256', + name: 'totalRebateFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalRebateAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'affiliateRewardAmount', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionReferralFees', + name: 'referral', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'fundingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestFundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestLongTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestShortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFundingFees', + name: 'funding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'borrowingFeeUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmountForFeeReceiver', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionBorrowingFees', + name: 'borrowing', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionUiFees', + name: 'ui', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'collateralTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionFeeFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmountExcludingFunding', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFees', + name: 'fees', + type: 'tuple', + }, + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: 'executionPriceResult', + type: 'tuple', + }, + { + internalType: 'int256', + name: 'basePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'uncappedBasePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'pnlAfterPriceImpactUsd', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.PositionInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getAccountPositions', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + ], + name: 'getAdlState', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'bool', + name: '', + type: 'bool', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getDeposit', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialLongToken', + type: 'address', + }, + { + internalType: 'address', + name: 'initialShortToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'longTokenSwapPath', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'shortTokenSwapPath', + type: 'address[]', + }, + ], + internalType: 'struct Deposit.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'initialLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minMarketTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + ], + internalType: 'struct Deposit.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + ], + internalType: 'struct Deposit.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Deposit.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'longTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'enum ISwapPricingUtils.SwapPricingType', + name: 'swapPricingType', + type: 'uint8', + }, + { + internalType: 'bool', + name: 'includeVirtualInventoryImpact', + type: 'bool', + }, + ], + name: 'getDepositAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionSizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionSizeInTokens', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'sizeDeltaUsd', + type: 'int256', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + name: 'getExecutionPrice', + outputs: [ + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'key', + type: 'address', + }, + ], + name: 'getMarket', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'salt', + type: 'bytes32', + }, + ], + name: 'getMarketBySalt', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + ], + name: 'getMarketInfo', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForLongs', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForShorts', + type: 'uint256', + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSize', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSize', + type: 'tuple', + }, + ], + internalType: 'struct ReaderUtils.BaseFundingValues', + name: 'baseFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'longsPayShorts', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'fundingFactorPerSecond', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'nextSavedFundingFactorPerSecond', + type: 'int256', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSizeDelta', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSizeDelta', + type: 'tuple', + }, + ], + internalType: + 'struct MarketUtils.GetNextFundingAmountPerSizeResult', + name: 'nextFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'virtualPoolAmountForLongToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'virtualPoolAmountForShortToken', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'virtualInventoryForPositions', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.VirtualInventory', + name: 'virtualInventory', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isDisabled', + type: 'bool', + }, + ], + internalType: 'struct ReaderUtils.MarketInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices[]', + name: 'marketPricesList', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getMarketInfoList', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForLongs', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactorPerSecondForShorts', + type: 'uint256', + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSize', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSize', + type: 'tuple', + }, + ], + internalType: 'struct ReaderUtils.BaseFundingValues', + name: 'baseFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'longsPayShorts', + type: 'bool', + }, + { + internalType: 'uint256', + name: 'fundingFactorPerSecond', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'nextSavedFundingFactorPerSecond', + type: 'int256', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'fundingFeeAmountPerSizeDelta', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'long', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'longToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortToken', + type: 'uint256', + }, + ], + internalType: 'struct MarketUtils.CollateralType', + name: 'short', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.PositionType', + name: 'claimableFundingAmountPerSizeDelta', + type: 'tuple', + }, + ], + internalType: + 'struct MarketUtils.GetNextFundingAmountPerSizeResult', + name: 'nextFunding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'virtualPoolAmountForLongToken', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'virtualPoolAmountForShortToken', + type: 'uint256', + }, + { + internalType: 'int256', + name: 'virtualInventoryForPositions', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.VirtualInventory', + name: 'virtualInventory', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isDisabled', + type: 'bool', + }, + ], + internalType: 'struct ReaderUtils.MarketInfo[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + { + internalType: 'bytes32', + name: 'pnlFactorType', + type: 'bytes32', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getMarketTokenPrice', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + components: [ + { + internalType: 'int256', + name: 'poolValue', + type: 'int256', + }, + { + internalType: 'int256', + name: 'longPnl', + type: 'int256', + }, + { + internalType: 'int256', + name: 'shortPnl', + type: 'int256', + }, + { + internalType: 'int256', + name: 'netPnl', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'longTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalBorrowingFees', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeePoolFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'impactPoolAmount', + type: 'uint256', + }, + ], + internalType: 'struct MarketPoolValueInfo.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'uint256', + name: 'start', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'end', + type: 'uint256', + }, + ], + name: 'getMarkets', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getNetPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getOpenInterestWithPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getOrder', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'cancellationReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'initialCollateralToken', + type: 'address', + }, + { + internalType: 'address[]', + name: 'swapPath', + type: 'address[]', + }, + ], + internalType: 'struct Order.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'enum Order.OrderType', + name: 'orderType', + type: 'uint8', + }, + { + internalType: 'enum Order.DecreasePositionSwapType', + name: 'decreasePositionSwapType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'initialCollateralDeltaAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'triggerPrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'acceptablePrice', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minOutputAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Order.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isFrozen', + type: 'bool', + }, + { + internalType: 'bool', + name: 'autoCancel', + type: 'bool', + }, + ], + internalType: 'struct Order.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Order.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getPnl', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketAddress', + type: 'address', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + { + internalType: 'bool', + name: 'maximize', + type: 'bool', + }, + ], + name: 'getPnlToPoolFactor', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getPosition', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'contract IReferralStorage', + name: 'referralStorage', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'positionKey', + type: 'bytes32', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'bool', + name: 'usePositionSizeAsSizeDeltaUsd', + type: 'bool', + }, + ], + name: 'getPositionInfo', + outputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address', + name: 'collateralToken', + type: 'address', + }, + ], + internalType: 'struct Position.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'sizeInUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'sizeInTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'collateralAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'fundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'longTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'shortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'increasedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'decreasedAtTime', + type: 'uint256', + }, + ], + internalType: 'struct Position.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'isLong', + type: 'bool', + }, + ], + internalType: 'struct Position.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Position.Props', + name: 'position', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'bytes32', + name: 'referralCode', + type: 'bytes32', + }, + { + internalType: 'address', + name: 'affiliate', + type: 'address', + }, + { + internalType: 'address', + name: 'trader', + type: 'address', + }, + { + internalType: 'uint256', + name: 'totalRebateFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalRebateAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'traderDiscountAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'affiliateRewardAmount', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionReferralFees', + name: 'referral', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'fundingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'claimableShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestFundingFeeAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestLongTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'latestShortTokenClaimableFundingAmountPerSize', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFundingFees', + name: 'funding', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'borrowingFeeUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'borrowingFeeAmountForFeeReceiver', + type: 'uint256', + }, + ], + internalType: + 'struct PositionPricingUtils.PositionBorrowingFees', + name: 'borrowing', + type: 'tuple', + }, + { + components: [ + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionUiFees', + name: 'ui', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'collateralTokenPrice', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'positionFeeFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'protocolFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'positionFeeAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmountExcludingFunding', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'totalCostAmount', + type: 'uint256', + }, + ], + internalType: 'struct PositionPricingUtils.PositionFees', + name: 'fees', + type: 'tuple', + }, + { + components: [ + { + internalType: 'int256', + name: 'priceImpactUsd', + type: 'int256', + }, + { + internalType: 'uint256', + name: 'priceImpactDiffUsd', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionPrice', + type: 'uint256', + }, + ], + internalType: 'struct ReaderPricingUtils.ExecutionPriceResult', + name: 'executionPriceResult', + type: 'tuple', + }, + { + internalType: 'int256', + name: 'basePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'uncappedBasePnlUsd', + type: 'int256', + }, + { + internalType: 'int256', + name: 'pnlAfterPriceImpactUsd', + type: 'int256', + }, + ], + internalType: 'struct ReaderUtils.PositionInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'bytes32', + name: 'positionKey', + type: 'bytes32', + }, + { + internalType: 'uint256', + name: 'sizeDeltaUsd', + type: 'uint256', + }, + ], + name: 'getPositionPnlUsd', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getShift', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'fromMarket', + type: 'address', + }, + { + internalType: 'address', + name: 'toMarket', + type: 'address', + }, + ], + internalType: 'struct Shift.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minMarketTokens', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + ], + internalType: 'struct Shift.Numbers', + name: 'numbers', + type: 'tuple', + }, + ], + internalType: 'struct Shift.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + ], + name: 'getSwapAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'feeReceiverAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'feeAmountForPool', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amountAfterFees', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'uint256', + name: 'uiFeeReceiverFactor', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'uiFeeAmount', + type: 'uint256', + }, + ], + internalType: 'struct SwapPricingUtils.SwapFees', + name: 'fees', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'address', + name: 'marketKey', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenOut', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'tokenInPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'tokenOutPrice', + type: 'tuple', + }, + ], + name: 'getSwapPriceImpact', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + internalType: 'bytes32', + name: 'key', + type: 'bytes32', + }, + ], + name: 'getWithdrawal', + outputs: [ + { + components: [ + { + components: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + internalType: 'address', + name: 'callbackContract', + type: 'address', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'address', + name: 'market', + type: 'address', + }, + { + internalType: 'address[]', + name: 'longTokenSwapPath', + type: 'address[]', + }, + { + internalType: 'address[]', + name: 'shortTokenSwapPath', + type: 'address[]', + }, + ], + internalType: 'struct Withdrawal.Addresses', + name: 'addresses', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'marketTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minLongTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minShortTokenAmount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtBlock', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'updatedAtTime', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'executionFee', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'callbackGasLimit', + type: 'uint256', + }, + ], + internalType: 'struct Withdrawal.Numbers', + name: 'numbers', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldUnwrapNativeToken', + type: 'bool', + }, + ], + internalType: 'struct Withdrawal.Flags', + name: 'flags', + type: 'tuple', + }, + ], + internalType: 'struct Withdrawal.Props', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract DataStore', + name: 'dataStore', + type: 'address', + }, + { + components: [ + { + internalType: 'address', + name: 'marketToken', + type: 'address', + }, + { + internalType: 'address', + name: 'indexToken', + type: 'address', + }, + { + internalType: 'address', + name: 'longToken', + type: 'address', + }, + { + internalType: 'address', + name: 'shortToken', + type: 'address', + }, + ], + internalType: 'struct Market.Props', + name: 'market', + type: 'tuple', + }, + { + components: [ + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'indexTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'longTokenPrice', + type: 'tuple', + }, + { + components: [ + { + internalType: 'uint256', + name: 'min', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'max', + type: 'uint256', + }, + ], + internalType: 'struct Price.Props', + name: 'shortTokenPrice', + type: 'tuple', + }, + ], + internalType: 'struct MarketUtils.MarketPrices', + name: 'prices', + type: 'tuple', + }, + { + internalType: 'uint256', + name: 'marketTokenAmount', + type: 'uint256', + }, + { + internalType: 'address', + name: 'uiFeeReceiver', + type: 'address', + }, + { + internalType: 'enum ISwapPricingUtils.SwapPricingType', + name: 'swapPricingType', + type: 'uint8', + }, + ], + name: 'getWithdrawalAmountOut', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; + +module.exports = { + ABI, +}; diff --git a/src/adaptors/umami-finance/arbitrum/umamiConstants.js b/src/adaptors/umami-finance/arbitrum/umamiConstants.js new file mode 100644 index 0000000000..88e272dc26 --- /dev/null +++ b/src/adaptors/umami-finance/arbitrum/umamiConstants.js @@ -0,0 +1,152 @@ +// -- Project + +const wETH_ADDRESS = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1'; +const USDC_ADDRESS = '0xaf88d065e77c8cc2239327c5edb3a432268e5831'; +const WBTC_ADDRESS = '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f'; +const ARB_ADDRESS = '0x912ce59144191c1204e64559fe8253a0e49e6548'; + +const REWARD_TOKEN_ADDRESS = ARB_ADDRESS; + +const MASTER_CHEF = '0x52f6159dcae4ce617a3d50aeb7fab617526d9d8f'; + +const GM_MARKETS = [ + { + // ETH/USD + indexTokenName: 'ETH', + longTokenName: 'ETH', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0x70d95587d40a2caf56bd97485ab3eec10bee6336', + }, + { + // XRP/USD + indexTokenName: 'XRP', + longTokenName: 'ETH', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0x0ccb4faa6f1f1b30911619f1184082ab4e25813c', + }, + { + // DOGE/USD + indexTokenName: 'DOGE', + longTokenName: 'ETH', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0x6853ea96ff216fab11d2d930ce3c508556a4bdc4', + }, + { + // LTC/USD + indexTokenName: 'LTC', + longTokenName: 'ETH', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0xd9535bb5f58a1a75032416f2dfe7880c30575a41', + }, + { + // WBTC/USD + indexTokenName: 'BTC', + longTokenName: 'BTC', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0x47c031236e19d024b42f8ae6780e44a573170703', + }, +]; + +// ---- GM Synth Vaults ---- + +const GM_USDC = '0x959f3807f0aa7921e18c78b00b2819ba91e52fef'; // USDC part of the GMX GM synthetics pools (backed by ETH/USDC) +const GM_WETH = '0x4bca8d73561aaeee2d3a584b9f4665310de1dd69'; // WETH part of the GMX GM synthetics pools (backed by ETH/USDC) + +// This vault holds the GMX GM tokens for the Synth GM vaults +const GMI_VAULT = '0x9d2f33af8610f1b53dd6fce593f76a2b4b402176'; +const GMI_AGGREGATE_VAULT = '0x0ca62954b46afee430d645da493c6c783448c4ed'; + +const UMAMI_SYNTH_GM_VAULTS = [ + { + id: 'gmusdc', + symbol: 'gmUSDC', + address: GM_USDC, + underlyingAsset: USDC_ADDRESS, + decimals: 6, + underlyingGmMarkets: [ + GM_MARKETS[0], + GM_MARKETS[1], + GM_MARKETS[2], + GM_MARKETS[3], + ], + masterchefLpId: 0n, + aggregateVaultAddress: GMI_AGGREGATE_VAULT, + url: 'https://umami.finance/vaults/arbitrum/gm/gmusdc', + }, + { + id: 'gmweth', + symbol: 'gmWETH', + address: GM_WETH, + underlyingAsset: wETH_ADDRESS, + decimals: 18, + underlyingGmMarkets: [ + GM_MARKETS[0], + GM_MARKETS[1], + GM_MARKETS[2], + GM_MARKETS[3], + ], + masterchefLpId: 1n, + aggregateVaultAddress: GMI_AGGREGATE_VAULT, + url: 'https://umami.finance/vaults/arbitrum/gm/gmweth', + }, +]; + +// ---- GM Assets Vaults ---- + +const GM_USDC_WBTC = '0x5f851f67d24419982ecd7b7765defd64fbb50a97'; // USDC part of the GMX GM USDC-WBTC pool +const GM_WBTC = '0xcd8011aab161a75058eab24e0965bab0b918af29'; // WBTC part of the GMX GM USDC-WBTC pool + +// Hold GM tokens for GM vaults + +const GM_GMI_CONTRACT_ADDRESS = '0xb472fdfd589f404b4cf4f76baf7e5286cbc39790'; +const GM_WBTC_AGGREGATE_VAULT_ADDRESS = + '0x1e914730b4cd343ae14530f0bbf6b350d83b833d'; + +const UMAMI_GM_VAULTS = [ + { + id: 'gmusdc', + symbol: 'gmUSDC (wBTC)', + address: GM_USDC_WBTC, + underlyingAsset: USDC_ADDRESS, + decimals: 6, + underlyingGmMarkets: [GM_MARKETS[4]], + masterchefLpId: 3n, + aggregateVaultAddress: GM_WBTC_AGGREGATE_VAULT_ADDRESS, + url: 'https://umami.finance/vaults/arbitrum/gm/gmusdc_wbtc', + }, + { + id: 'gmwbtc', + symbol: 'gmWBTC', + address: GM_WBTC, + underlyingAsset: WBTC_ADDRESS, + decimals: 8, + underlyingGmMarkets: [GM_MARKETS[4]], + masterchefLpId: 2n, + aggregateVaultAddress: GM_WBTC_AGGREGATE_VAULT_ADDRESS, + url: 'https://umami.finance/vaults/arbitrum/gm/gmwbtc', + }, +]; + +module.exports = { + UMAMI_SYNTH_GM_VAULTS, + UMAMI_GM_VAULTS, + GMI_VAULT, + GM_MARKETS, + GM_USDC, + GM_WETH, + MASTER_CHEF, + REWARD_TOKEN_ADDRESS, + GMI_AGGREGATE_VAULT, + GM_GMI_CONTRACT_ADDRESS, + GM_WBTC_AGGREGATE_VAULT_ADDRESS, +}; diff --git a/src/adaptors/umami-finance/avalanche/umamiConstants.js b/src/adaptors/umami-finance/avalanche/umamiConstants.js new file mode 100644 index 0000000000..770d494fee --- /dev/null +++ b/src/adaptors/umami-finance/avalanche/umamiConstants.js @@ -0,0 +1,75 @@ +// -- Project + +const wETH_ADDRESS = '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab'; +const USDC_ADDRESS = '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e'; + +const REWARD_TOKEN_ADDRESS = undefined; + +const MASTER_CHEF = ''; // TBD + +const GM_MARKETS = [ + { + // WETH/USD + indexTokenName: 'ETH', + longTokenName: 'ETH', + shortTokenName: 'USDC', + longToken: wETH_ADDRESS, + shortToken: USDC_ADDRESS, + address: '0xb7e69749e3d2edd90ea59a4932efea2d41e245d7', + }, +]; + +// ---- GM Synth Vaults ---- + +// This vault holds the GMX GM tokens for the Synth GM vaults +const GMI_VAULT = ''; // TBD +const GMI_AGGREGATE_VAULT = ''; // TBD + +const UMAMI_SYNTH_GM_VAULTS = [ + // TBD +]; + +// ---- GM Assets Vaults ---- + +const GM_USDC_WETH = '0x4f3274c3889e6cd54c9c739757ab8ea4b246d76b'; // USDC part of the GMX GM USDC-WETH pool +const GM_WETH = '0xfce0a462585a422bac0ca443b102d0ac1ff20f9e'; // WETH part of the GMX GM USDC-WETH pool + +// Hold GM tokens for GM vaults + +const GM_GMI_CONTRACT_ADDRESS = '0x4ba2396086d52ca68a37d9c0fa364286e9c7835a'; +const GM_WETH_AGGREGATE_VAULT_ADDRESS = + '0xba51670cd6a3f6258459234928ac36cca39af516'; + +const UMAMI_GM_VAULTS = [ + { + id: 'avax_gmusdc_weth', + symbol: 'gmUSDC', + address: GM_USDC_WETH, + underlyingAsset: USDC_ADDRESS, + decimals: 6, + underlyingGmMarkets: [GM_MARKETS[0]], + masterchefLpId: undefined, + aggregateVaultAddress: GM_WETH_AGGREGATE_VAULT_ADDRESS, + url: 'https://umami.finance/vaults/avax/gm/gmusdc', + }, + { + id: 'avax_gmweth', + symbol: 'gmWETH', + address: GM_WETH, + underlyingAsset: wETH_ADDRESS, + decimals: 18, + underlyingGmMarkets: [GM_MARKETS[0]], + masterchefLpId: undefined, + aggregateVaultAddress: GM_WETH_AGGREGATE_VAULT_ADDRESS, + url: 'https://umami.finance/vaults/avax/gm/gmweth', + }, +]; + +module.exports = { + UMAMI_SYNTH_GM_VAULTS, + UMAMI_GM_VAULTS, + GMI_VAULT, + GM_MARKETS, + MASTER_CHEF, + GMI_AGGREGATE_VAULT, +}; diff --git a/src/adaptors/umami-finance/gmxHelpers/constants.js b/src/adaptors/umami-finance/gmxHelpers/constants.js new file mode 100644 index 0000000000..3267670c7e --- /dev/null +++ b/src/adaptors/umami-finance/gmxHelpers/constants.js @@ -0,0 +1,26 @@ +const SYNTHS_STATS_SUBGRAPH_URL = { + arbitrum: 'https://gmx.squids.live/gmx-synthetics-arbitrum/graphql', + avax: 'https://gmx.squids.live/gmx-synthetics-avalanche/graphql', +}; + +const CONTRACTS = { + arbitrum: { + syntheticsReader: '0x5ca84c34a381434786738735265b9f3fd814b824', + dataStore: '0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8', + }, + avax: { + syntheticsReader: '0xbad04ddcc5cc284a86493afa75d2beb970c72216', + dataStore: '0x2f0b22339414aded7d5f06f9d604c7ff5b2fe3f6', + }, +}; + +const SIGNED_PRICES_API_URL = { + arbitrum: 'https://arbitrum-api.gmxinfra.io/signed_prices/latest', + avax: 'https://avalanche-api.gmxinfra.io/signed_prices/latest', +}; + +module.exports = { + SYNTHS_STATS_SUBGRAPH_URL, + CONTRACTS, + SIGNED_PRICES_API_URL, +}; diff --git a/src/adaptors/umami-finance/gmxHelpers/gmMarketsApr.js b/src/adaptors/umami-finance/gmxHelpers/gmMarketsApr.js new file mode 100644 index 0000000000..9e0f24b4ba --- /dev/null +++ b/src/adaptors/umami-finance/gmxHelpers/gmMarketsApr.js @@ -0,0 +1,298 @@ +const sdk = require('@defillama/sdk'); +const { gql, default: request } = require('graphql-request'); +const { default: axios } = require('axios'); + +const { + SYNTHS_STATS_SUBGRAPH_URL, + CONTRACTS, + SIGNED_PRICES_API_URL, +} = require('./constants.js'); +const { marketFeesQuery } = require('./queries.js'); +const { + expandDecimals, + bigintToNumber, + numberToBigint, + hashString, + hashData, +} = require('./helpers.js'); + +const arbitrumConstants = require('../arbitrum/umamiConstants.js'); +const avalancheConstants = require('../avalanche/umamiConstants.js'); + +const { ABI: GmxDataStoreAbi } = require('../abis/gmxDataStore.js'); +const { + ABI: GmxSyntheticsReaderAbi, +} = require('../abis/gmxSyntheticsReader.js'); + +const getBorrowingFactorPerPeriod = (marketInfo, isLong) => { + const factorPerSecond = isLong + ? marketInfo.borrowingFactorPerSecondForLongs + : marketInfo.borrowingFactorPerSecondForShorts; + const oneYearInSeconds = 60 * 60 * 24 * 365; + return BigInt(factorPerSecond) * BigInt(oneYearInSeconds); +}; + +const calcAprByBorrowingFee = (marketInfo, poolValue) => { + const precision = expandDecimals(1, 30); + const longOi = marketInfo.longInterestUsd; + const shortOi = marketInfo.shortInterestUsd; + const isLongPayingBorrowingFee = longOi > shortOi; + const borrowingFactorPerYear = getBorrowingFactorPerPeriod( + marketInfo, + isLongPayingBorrowingFee + ); + + const borrowingFeeUsdForPoolPerYear = + (borrowingFactorPerYear * + (isLongPayingBorrowingFee ? longOi : shortOi) * + BigInt(63)) / + precision / + BigInt(100); + + const borrowingFeeUsdPerPoolValuePerYear = + (borrowingFeeUsdForPoolPerYear * precision) / poolValue; + + return borrowingFeeUsdPerPoolValuePerYear; +}; + +const calculateGmMarketAPY = (apr) => { + const aprNumber = bigintToNumber(apr, 30); + const apyNumber = Math.exp(aprNumber) - 1; + if (apyNumber !== Infinity) { + return numberToBigint(apyNumber, 30); + } + return apr; +}; + +// Get GMX tokens prices from their API +const getGmxRealtimePrices = async (chain) => { + const apiUrl = SIGNED_PRICES_API_URL[chain]; + + const { + data: { signedPrices }, + } = await axios.get(apiUrl, { + headers: { + 'accept-encoding': 'gzip', + }, + }); + + return signedPrices.map(({ tokenSymbol, maxPriceFull, minPriceFull }) => ({ + tokenSymbol, + maxPriceFull, + minPriceFull, + })); +}; + +// Get the price of a specific GMX token +const getGmxRealtimePriceForToken = async (chain, tokenName) => { + const prices = await getGmxRealtimePrices(chain); + + const find = (symbol) => { + const priceObj = prices.find( + (priceObject) => + priceObject.tokenSymbol.toLowerCase() === symbol.toLowerCase() + ); + if (priceObj === undefined) { + throw new Error(`price not found for ${symbol}`); + } + + const minPrice = BigInt(priceObj.minPriceFull); + const maxPrice = BigInt(priceObj.maxPriceFull); + const avgPrice = (minPrice + maxPrice) / BigInt(2); + + return avgPrice; + }; + + return find(tokenName); +}; + +// Gets the open interest informations from GMX for a given GM market +const getGmMarketOiFromDataStore = async ( + chain, + gmMarketTokensPrices, + addresses +) => { + const oiKey = hashString('OPEN_INTEREST'); + const callsHashedParams = { + longInterestUsingLongToken: hashData( + ['bytes32', 'address', 'address', 'bool'], + [oiKey, addresses.gmMarket, addresses.longToken, true] + ), + longInterestUsingShortToken: hashData( + ['bytes32', 'address', 'address', 'bool'], + [oiKey, addresses.gmMarket, addresses.shortToken, true] + ), + shortInterestUsingLongToken: hashData( + ['bytes32', 'address', 'address', 'bool'], + [oiKey, addresses.gmMarket, addresses.longToken, false] + ), + shortInterestUsingShortToken: hashData( + ['bytes32', 'address', 'address', 'bool'], + [oiKey, addresses.gmMarket, addresses.shortToken, false] + ), + }; + + const oiInformationsForGmMarket = ( + await sdk.api.abi.multiCall({ + chain, + abi: GmxDataStoreAbi.find((abiItem) => abiItem.name === 'getUint'), + calls: [ + { + target: addresses.dataStore, + params: callsHashedParams.longInterestUsingLongToken, + }, + { + target: addresses.dataStore, + params: callsHashedParams.longInterestUsingShortToken, + }, + { + target: addresses.dataStore, + params: callsHashedParams.shortInterestUsingLongToken, + }, + { + target: addresses.dataStore, + params: callsHashedParams.shortInterestUsingShortToken, + }, + ], + }) + ).output.map((o) => o.output); + + const gmMarketInfos = ( + await sdk.api.abi.call({ + chain, + target: addresses.syntheticsReader, + abi: GmxSyntheticsReaderAbi.find( + (abiItem) => abiItem.name === 'getMarketInfo' + ), + params: [ + addresses.dataStore, + { + indexTokenPrice: { + min: gmMarketTokensPrices.indexTokenPrice, + max: gmMarketTokensPrices.indexTokenPrice, + }, + longTokenPrice: { + min: gmMarketTokensPrices.longTokenPrice, + max: gmMarketTokensPrices.longTokenPrice, + }, + shortTokenPrice: { + min: gmMarketTokensPrices.shortTokenPrice, + max: gmMarketTokensPrices.shortTokenPrice, + }, + }, + addresses.gmMarket, + ], + }) + ).output; + + const isSameCollaterals = addresses.longToken === addresses.shortToken; + const marketDivisor = isSameCollaterals ? BigInt(2) : BigInt(1); + + const longInterestUsingLongToken = + BigInt(oiInformationsForGmMarket[0]) / marketDivisor; + const longInterestUsingShortToken = + BigInt(oiInformationsForGmMarket[1]) / marketDivisor; + const shortInterestUsingLongToken = + BigInt(oiInformationsForGmMarket[2]) / marketDivisor; + const shortInterestUsingShortToken = + BigInt(oiInformationsForGmMarket[3]) / marketDivisor; + + const marketInfoResult = gmMarketInfos; + + const longInterestUsd = + longInterestUsingLongToken + longInterestUsingShortToken; + const shortInterestUsd = + shortInterestUsingLongToken + shortInterestUsingShortToken; + + return { + longInterestUsd, + shortInterestUsd, + borrowingFactorPerSecondForLongs: BigInt( + marketInfoResult.borrowingFactorPerSecondForLongs + ), + borrowingFactorPerSecondForShorts: BigInt( + marketInfoResult.borrowingFactorPerSecondForShorts + ), + }; +}; + +const getGmMarketsAprForUmami = async (chain) => { + const gmMarketsForChain = + chain === 'arbitrum' + ? arbitrumConstants.GM_MARKETS + : avalancheConstants.GM_MARKETS; + + const feesQuery = gmMarketsForChain.reduce( + (acc, market) => acc + marketFeesQuery(market.address), + '' + ); + + const feesQueryResponse = await request( + SYNTHS_STATS_SUBGRAPH_URL[chain], + gql`query M { + ${feesQuery} + }` + ); + + const marketTokensAPRData = await Promise.all( + gmMarketsForChain.map(async (market) => { + const [indexTokenPrice, longTokenPrice, shortTokenPrice] = + await Promise.all([ + getGmxRealtimePriceForToken(chain, market.indexTokenName), + getGmxRealtimePriceForToken(chain, market.longTokenName), + getGmxRealtimePriceForToken(chain, market.shortTokenName), + ]); + + const oiInfos = await getGmMarketOiFromDataStore( + chain, + { + indexTokenPrice, + longTokenPrice, + shortTokenPrice, + }, + { + dataStore: CONTRACTS[chain].dataStore, + syntheticsReader: CONTRACTS[chain].syntheticsReader, + gmMarket: market.address, + longToken: market.longToken, + shortToken: market.shortToken, + } + ); + const lteStartOfPeriodFees = + feesQueryResponse[`_${market.address}_lte_start_of_period_`]; + const recentFees = feesQueryResponse[`_${market.address}_recent`]; + const poolValueRaw = feesQueryResponse[`_${market.address}_poolValue`]; + + const poolValue = BigInt(poolValueRaw[0].poolValue); + const startFees = lteStartOfPeriodFees[0]; + const currentFees = recentFees[0]; + + const startTotal = + BigInt(startFees.cumulativeFeeUsdPerPoolValue) - + BigInt(startFees.cumulativeBorrowingFeeUsdPerPoolValue); + const currentTotal = + BigInt(currentFees.cumulativeFeeUsdPerPoolValue) - + BigInt(currentFees.cumulativeBorrowingFeeUsdPerPoolValue); + + const incomePercentageForPeriod = currentTotal - startTotal; + + const yearMultiplier = BigInt(Math.floor(365 / 7)); + + const aprByFees = incomePercentageForPeriod * yearMultiplier; + const aprByBorrowingFee = calcAprByBorrowingFee(oiInfos, poolValue); + const completeApy = + calculateGmMarketAPY(aprByFees + aprByBorrowingFee) / BigInt(10 ** 28); + + return { + pool: market.address, + apyBase: completeApy.toString(), + }; + }) + ); + + return marketTokensAPRData; +}; + +module.exports = { + getGmMarketsAprForUmami, +}; diff --git a/src/adaptors/umami-finance/gmxHelpers/helpers.js b/src/adaptors/umami-finance/gmxHelpers/helpers.js new file mode 100644 index 0000000000..c023a0c77f --- /dev/null +++ b/src/adaptors/umami-finance/gmxHelpers/helpers.js @@ -0,0 +1,73 @@ +const { ethers, BigNumber } = require('ethers'); + +const hashData = (dataTypes, dataValues) => { + const bytes = ethers.utils.defaultAbiCoder.encode(dataTypes, dataValues); + const hash = ethers.utils.keccak256(ethers.utils.arrayify(bytes)); + + return hash; +}; + +const hashString = (string) => { + return hashData(['string'], [string]); +}; + +const bigNumberify = (n) => { + try { + return BigNumber(n); + } catch (e) { + console.error('bigNumberify error', e); + return undefined; + } +}; + +const expandDecimals = (n, decimals) => { + return BigInt(n) * BigInt(10 ** decimals); +}; + +const bigintToNumber = (value, decimals) => { + let myValue = value; + const negative = myValue < 0; + if (negative) { + myValue *= -1n; + } + const precision = BigInt(10) ** BigInt(decimals); + const int = myValue / precision; + const frac = myValue % precision; + + const num = parseFloat(`${int}.${frac.toString().padStart(decimals, '0')}`); + return negative ? -num : num; +}; + +const numberToBigint = (value, decimals) => { + let myValue = value; + const negative = value < 0; + if (negative) { + myValue *= -1; + } + + const int = Math.trunc(myValue); + let frac = myValue - int; + + let res = BigInt(int); + + for (let i = 0; i < decimals; i++) { + res *= 10n; + if (frac !== 0) { + frac *= 10; + const fracInt = Math.trunc(frac); + res += BigInt(fracInt); + frac -= fracInt; + } + } + + return negative ? -res : res; +}; + +module.exports = { + hashData, + hashString, + bigNumberify, + expandDecimals, + bigintToNumber, + numberToBigint, +}; diff --git a/src/adaptors/umami-finance/gmxHelpers/queries.js b/src/adaptors/umami-finance/gmxHelpers/queries.js new file mode 100644 index 0000000000..b615105862 --- /dev/null +++ b/src/adaptors/umami-finance/gmxHelpers/queries.js @@ -0,0 +1,40 @@ +const { sub } = require('date-fns'); + +const marketFeesQuery = (marketAddress) => { + return ` + _${marketAddress}_lte_start_of_period_: collectedMarketFeesInfos( + orderBy: timestampGroup_DESC, + where: { + marketAddress_containsInsensitive: "${marketAddress}", + period_eq: "1h", + timestampGroup_lte: ${Math.floor( + sub(new Date(), { days: 7 }).valueOf() / 1000 + )} + }, + limit: 1 + ) { + cumulativeFeeUsdPerPoolValue + cumulativeBorrowingFeeUsdPerPoolValue + } + + _${marketAddress}_recent: collectedMarketFeesInfos( + orderBy: timestampGroup_DESC, + where: { + marketAddress_containsInsensitive: "${marketAddress}", + period_eq: "1h" + }, + limit: 1 + ) { + cumulativeFeeUsdPerPoolValue + cumulativeBorrowingFeeUsdPerPoolValue + } + + _${marketAddress}_poolValue: poolValues(where: { marketAddress_containsInsensitive: "${marketAddress}" }) { + poolValue + } + `; +}; + +module.exports = { + marketFeesQuery, +}; diff --git a/src/adaptors/umami-finance/index.js b/src/adaptors/umami-finance/index.js new file mode 100644 index 0000000000..533fa23582 --- /dev/null +++ b/src/adaptors/umami-finance/index.js @@ -0,0 +1,52 @@ +const { getGmMarketsAprForUmami } = require('./gmxHelpers/gmMarketsApr.js'); +const { getUmamiGmSynthsVaultsYield } = require('./umamiGmSynthVaults.js'); +const { getUmamiGmVaultsYield } = require('./umamiGmVaults.js'); + +const main = async () => { + // Fetch infos & fees from GM markets first + const [arbitrumGmMarketsInfos, avalancheGmMarketsInfos] = await Promise.all([ + getGmMarketsAprForUmami('arbitrum'), + getGmMarketsAprForUmami('avax'), + ]); + const [ + arbitrumSynthGmVaultsResult, + arbitrumGmVaultsResult, + avaxGmVaultsResult, + ] = await Promise.allSettled([ + getUmamiGmSynthsVaultsYield('arbitrum', arbitrumGmMarketsInfos), + getUmamiGmVaultsYield('arbitrum', arbitrumGmMarketsInfos), + getUmamiGmVaultsYield('avax', avalancheGmMarketsInfos), + ]); + + const arbitrumSynthGmVaults = + arbitrumSynthGmVaultsResult.status === 'fulfilled' + ? arbitrumSynthGmVaultsResult.value + : []; + const arbitrumGmVaults = + arbitrumGmVaultsResult.status === 'fulfilled' + ? arbitrumGmVaultsResult.value + : []; + const avaxGmVaults = + avaxGmVaultsResult.status === 'fulfilled' ? avaxGmVaultsResult.value : []; + + const arbitrumVaults = [...arbitrumSynthGmVaults, ...arbitrumGmVaults].map( + (strat) => ({ + ...strat, + chain: 'Arbitrum', + project: 'umami-finance', + }) + ); + const avaxVaults = [...avaxGmVaults].map((strat) => ({ + ...strat, + chain: 'Avalanche', + project: 'umami-finance', + })); + + return [...arbitrumVaults, ...avaxVaults]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://umami.finance/', +}; diff --git a/src/adaptors/umami-finance/umamiContracts.js b/src/adaptors/umami-finance/umamiContracts.js new file mode 100644 index 0000000000..8ba25d2f9e --- /dev/null +++ b/src/adaptors/umami-finance/umamiContracts.js @@ -0,0 +1,74 @@ +const superagent = require('superagent'); +const { Web3 } = require('web3'); +const sdk = require('@defillama/sdk'); + +const arbitrumCoreAddresses = require('./arbitrum/umamiConstants.js'); +const avalancheCoreAddresses = require('./avalanche/umamiConstants.js'); + +const { GM_ASSET_VAULT_ABI } = require('./abis/gmAssetVault.js'); +const { GMI_VAULT_ABI } = require('./abis/gmiVault.js'); +const { GMI_AGGREGATE_VAULT_ABI } = require('./abis/gmiAggregateVault.js'); +const { ARB_MASTER_CHEF_ABI } = require('./abis/arbMasterchef.js'); + +const ARB_RPC_URL = 'https://arbitrum.llamarpc.com'; +const AVAX_RPC_URL = 'https://avalanche.public-rpc.com'; + +const arbitrumWeb3Client = new Web3(ARB_RPC_URL); +const avalancheWeb3Client = new Web3(AVAX_RPC_URL); + +const getUmamiContractsForChain = (chain) => { + if (chain === 'arbitrum') { + return { + gmiContract: new arbitrumWeb3Client.eth.Contract( + GMI_VAULT_ABI, + arbitrumCoreAddresses.GMI_VAULT + ), + masterchefContract: new arbitrumWeb3Client.eth.Contract( + ARB_MASTER_CHEF_ABI, + arbitrumCoreAddresses.MASTER_CHEF + ), + }; + } else { + return { + gmiContract: new avalancheWeb3Client.eth.Contract( + GMI_VAULT_ABI, + avalancheCoreAddresses.GMI_VAULT + ), + masterchefContract: undefined, + }; + } +}; + +const getAggregateVaultContractForVault = (chain, aggregateVaultAddress) => { + if (chain === 'arbitrum') { + return new arbitrumWeb3Client.eth.Contract( + GMI_AGGREGATE_VAULT_ABI, + aggregateVaultAddress + ); + } else { + return new avalancheWeb3Client.eth.Contract( + GMI_AGGREGATE_VAULT_ABI, + aggregateVaultAddress + ); + } +}; + +const getVaultContractForVault = (chain, vaultAddress) => { + if (chain === 'arbitrum') { + return new arbitrumWeb3Client.eth.Contract( + GM_ASSET_VAULT_ABI, + vaultAddress + ); + } else { + return new avalancheWeb3Client.eth.Contract( + GM_ASSET_VAULT_ABI, + vaultAddress + ); + } +}; + +module.exports = { + getUmamiContractsForChain, + getAggregateVaultContractForVault, + getVaultContractForVault, +}; diff --git a/src/adaptors/umami-finance/umamiGmSynthVaults.js b/src/adaptors/umami-finance/umamiGmSynthVaults.js new file mode 100644 index 0000000000..09b34c246c --- /dev/null +++ b/src/adaptors/umami-finance/umamiGmSynthVaults.js @@ -0,0 +1,105 @@ +const superagent = require('superagent'); +const { Web3 } = require('web3'); +const sdk = require('@defillama/sdk'); + +const arbitrumConstants = require('./arbitrum/umamiConstants.js'); +const avalancheConstants = require('./avalanche/umamiConstants.js'); + +const { getIncentivesAprForVault } = require('./umamiIncentivesHelper.js'); +const { + getUmamiContractsForChain, + getAggregateVaultContractForVault, +} = require('./umamiContracts.js'); +const { default: BigNumber } = require('bignumber.js'); +const { formatUnits } = require('ethers/lib/utils.js'); + +const INCENTIVES_ENABLED = false; + +// returns the weights of GMX GM tokens held in the GMI vault +const getGmiGmMarketsWeights = async (gmiContract) => { + const weights = await gmiContract.methods.getWeights().call(); + + return weights.map((weight) => parseFloat(formatUnits(BigInt(weight), 18))); +}; + +const getUmamiGmSynthsVaultsYield = async (chain, gmMarketsInfos) => { + const gmVaults = []; + const vaultsList = + chain === 'arbitrum' + ? arbitrumConstants.UMAMI_SYNTH_GM_VAULTS + : avalancheConstants.UMAMI_SYNTH_GM_VAULTS; + + const rewardToken = + chain === 'arbitrum' + ? arbitrumConstants.REWARD_TOKEN_ADDRESS + : avalancheConstants.REWARD_TOKEN_ADDRESS; + + const coreContracts = getUmamiContractsForChain(chain); + + const weights = await getGmiGmMarketsWeights(coreContracts.gmiContract); + + for (let i = 0; i < vaultsList.length; i++) { + const vault = vaultsList[i]; + const aggregateVaultContract = getAggregateVaultContractForVault( + chain, + vault.aggregateVaultAddress + ); + + // get aprs out of GM markets + const gmMarketsAprs = vault.underlyingGmMarkets.map((gmMarket, _index) => { + const gmMarketYieldInfos = gmMarketsInfos.find( + (market) => market.pool.toLowerCase() === gmMarket.address.toLowerCase() + ); + if (!gmMarketYieldInfos) { + return 0; + } + const gmMarketApr = gmMarketsInfos[_index].apyBase; + const gmMarketWeight = weights[_index]; + return gmMarketApr * gmMarketWeight; + }); + + const underlyingTokenPriceKey = + `${chain}:${vault.underlyingAsset}`.toLowerCase(); + + const [tvlRaw, underlyingTokenPriceObj] = await Promise.all([ + aggregateVaultContract.methods + .getVaultTVL(vault.address.toLowerCase(), false) + .call(), + superagent.get( + `https://coins.llama.fi/prices/current/${underlyingTokenPriceKey}` + ), + ]); + + const underlyingTokenPrice = + underlyingTokenPriceObj.body.coins[underlyingTokenPriceKey].price; + const tvl = Number(tvlRaw) / 10 ** vault.decimals; + + const vaultApr = gmMarketsAprs.reduce((acc, apr) => acc + Number(apr), 0); + + let vaultObject = { + pool: vault.address, + tvlUsd: +(tvl * underlyingTokenPrice), + apyBase: +vaultApr.toFixed(2), + symbol: vault.symbol, + underlyingTokens: [vault.underlyingAsset], + url: vault.url, + }; + + if (INCENTIVES_ENABLED) { + const vaultIncentivesApr = await getIncentivesAprForVault(vault, chain); + vaultObject = { + ...vaultObject, + apyReward: +vaultIncentivesApr.toFixed(2), + rewardTokens: [rewardToken], + }; + } + + gmVaults.push(vaultObject); + } + + return gmVaults; +}; + +module.exports = { + getUmamiGmSynthsVaultsYield, +}; diff --git a/src/adaptors/umami-finance/umamiGmVaults.js b/src/adaptors/umami-finance/umamiGmVaults.js new file mode 100644 index 0000000000..ef2b50d48c --- /dev/null +++ b/src/adaptors/umami-finance/umamiGmVaults.js @@ -0,0 +1,88 @@ +const superagent = require('superagent'); +const { Web3 } = require('web3'); +const sdk = require('@defillama/sdk'); + +const arbitrumConstants = require('./arbitrum/umamiConstants.js'); +const avalancheConstants = require('./avalanche/umamiConstants.js'); + +const { getIncentivesAprForVault } = require('./umamiIncentivesHelper.js'); +const { + getUmamiContractsForChain, + getAggregateVaultContractForVault, +} = require('./umamiContracts.js'); + +const INCENTIVES_ENABLED = false; + +/** ---- GM VAULTS ---- */ + +const getUmamiGmVaultsYield = async (chain, gmMarketsInfos) => { + const gmVaults = []; + + const vaultsList = + chain === 'arbitrum' + ? arbitrumConstants.UMAMI_GM_VAULTS + : avalancheConstants.UMAMI_GM_VAULTS; + + const rewardToken = + chain === 'arbitrum' + ? arbitrumConstants.REWARD_TOKEN_ADDRESS + : avalancheConstants.REWARD_TOKEN_ADDRESS; + + for (let i = 0; i < vaultsList.length; i++) { + const vault = vaultsList[i]; + const aggregateVaultContract = getAggregateVaultContractForVault( + chain, + vault.aggregateVaultAddress + ); + // get aprs out of GM markets + const gmMarket = gmMarketsInfos.find( + (market) => + market.pool.toLowerCase() === + vault.underlyingGmMarkets[0].address.toLowerCase() + ); + + const underlyingTokenPriceKey = + `${chain}:${vault.underlyingAsset}`.toLowerCase(); + + const [tvlRaw, underlyingTokenPriceObj] = await Promise.all([ + aggregateVaultContract.methods + .getVaultTVL(vault.address.toLowerCase(), false) + .call(), + superagent.get( + `https://coins.llama.fi/prices/current/${underlyingTokenPriceKey}` + ), + , + ]); + + const underlyingTokenPrice = + underlyingTokenPriceObj.body.coins[underlyingTokenPriceKey].price; + const tvl = Number(tvlRaw) / 10 ** vault.decimals; + + let vaultObject = { + pool: vault.address, + tvlUsd: +(tvl * underlyingTokenPrice), + apyBase: +Number(gmMarket.apyBase).toFixed(2), + symbol: vault.symbol, + underlyingTokens: [vault.underlyingAsset], + url: vault.url, + }; + + if (INCENTIVES_ENABLED) { + const vaultIncentivesApr = await getIncentivesAprForVault(vault, chain); + + vaultObject = { + ...vaultObject, + apyReward: +vaultIncentivesApr.toFixed(2), + rewardTokens: [rewardToken], + }; + } + + gmVaults.push(vaultObject); + } + + return gmVaults; +}; + +module.exports = { + getUmamiGmVaultsYield, +}; diff --git a/src/adaptors/umami-finance/umamiIncentivesHelper.js b/src/adaptors/umami-finance/umamiIncentivesHelper.js new file mode 100644 index 0000000000..56553d2d4b --- /dev/null +++ b/src/adaptors/umami-finance/umamiIncentivesHelper.js @@ -0,0 +1,89 @@ +const superagent = require('superagent'); +const ethers = require('ethers'); + +const arbitrumConstants = require('./arbitrum/umamiConstants.js'); +const avalancheConstants = require('./arbitrum/umamiConstants.js'); + +const { + getUmamiContractsForChain, + getVaultContractForVault, +} = require('./umamiContracts.js'); + +// Incentives through Masterchef +const getIncentivesAprForVault = async (vault, chain) => { + const rewardTokenAddress = + chain === 'arbitrum' + ? arbitrumConstants.REWARD_TOKEN_ADDRESS + : avalancheConstants.REWARD_TOKEN_ADDRESS; + const masterChefAddress = + chain === 'arbitrum' + ? arbitrumConstants.MASTER_CHEF + : avalancheConstants.MASTER_CHEF; + + const coreContracts = getUmamiContractsForChain(chain); + const vaultContract = getVaultContractForVault(chain, vault.address); + + const underlyingTokenPriceKey = + `${chain}:${vault.underlyingAsset}`.toLowerCase(); + const arbTokenPriceKey = `${chain}:${rewardTokenAddress}`.toLowerCase(); + const [ + arbPerSecRaw, + totalAllocpointsRaw, + vaultPoolInfos, + stakedBalanceRaw, + vaultPpsRaw, + underlyingTokenPriceObj, + arbTokenPriceObj, + ] = await Promise.all([ + coreContracts.masterchefContract.methods.arbPerSec().call(), + coreContracts.masterchefContract.methods.totalAllocPoint().call(), + coreContracts.masterchefContract.methods + .poolInfo(vault.masterchefLpId) + .call(), + vaultContract.methods.balanceOf(masterChefAddress).call(), + vaultContract.methods.pps().call(), + superagent.get( + `https://coins.llama.fi/prices/current/${underlyingTokenPriceKey}` + ), + superagent.get(`https://coins.llama.fi/prices/current/${arbTokenPriceKey}`), + ]); + + const underlyingTokenPrice = + underlyingTokenPriceObj.body.coins[underlyingTokenPriceKey].price; + const arbTokenPrice = arbTokenPriceObj.body.coins[arbTokenPriceKey].price; + + const arbPerSec = Number(ethers.utils.formatUnits(arbPerSecRaw, 18)); + const vaultAllocPoints = Number( + ethers.utils.formatUnits(vaultPoolInfos.allocPoint, 0) + ); + const totalAllocpoints = Number( + ethers.utils.formatUnits(totalAllocpointsRaw, 0) + ); + const vaultPps = Number( + ethers.utils.formatUnits(vaultPpsRaw, vault.decimals) + ); + const assetsStakedTvl = + Number(ethers.utils.formatUnits(stakedBalanceRaw, vault.decimals)) * + vaultPps; + + const emissionsPerYearInUsd = + (arbPerSec * + (vaultAllocPoints / totalAllocpoints) * + arbTokenPrice * + 60 * + 60 * + 24 * + 365) / + underlyingTokenPrice; + + const emissionsPerYearInTokens = + emissionsPerYearInUsd / (assetsStakedTvl * vaultPps); + + const apr = emissionsPerYearInTokens * 100; + + return isNaN(apr) ? 0 : apr; +}; + +module.exports = { + getIncentivesAprForVault, +}; diff --git a/src/adaptors/umoja-ybtc/index.ts b/src/adaptors/umoja-ybtc/index.ts new file mode 100644 index 0000000000..2bcfff6b24 --- /dev/null +++ b/src/adaptors/umoja-ybtc/index.ts @@ -0,0 +1,34 @@ +const SDK = require( "@defillama/sdk" ); +const HelperUtils = require( "../../helper/utils" ); +const AdaptorUtils = require( "../utils" ); + +const ybtcContract = "0xba3e932310CD1dBF5Bd13079BD3D6bAe4570886f"; +const umjaContract = "0x16A500Aec6c37F84447ef04E66c57cfC6254cF92"; +const chain = "Arbitrum"; + +async function umojaYbtcYield() +{ + // Refer: https://github.com/DefiLlama/DefiLlama-Adapters/blob/e8819d280c3edebbe87242ca2b487d5effbc3f3f/projects/umoja-ybtc/index.js + const [reqApy, reqTotalSupply, reqPrice] = await Promise.all( [ + HelperUtils.fetchURL( "https://gateway-prod.umoja.services/smartcoins/global/apy" ), + SDK.api.abi.call( { abi: 'erc20:totalSupply', target: ybtcContract, chain: "arbitrum" } ), + AdaptorUtils.getPrices( [ybtcContract], chain ) + ] ); + + return [{ + pool: `${ybtcContract}-${chain}`.toLowerCase(), + chain: chain, + project: "umoja-ybtc", + symbol: "YBTC", + tvlUsd: reqTotalSupply.output / 1e18 * reqPrice.pricesBySymbol.ybtc, + apy: reqApy.data.YBTC, + rewardTokens: [umjaContract], // UMJA. + poolMeta: "YBTC", + }]; +}; + +module.exports = { + timetravel: false, + apy: umojaYbtcYield, + url: "https://umoja.xyz/smartcoins", +}; \ No newline at end of file diff --git a/src/adaptors/uncx-network-v2/index.ts b/src/adaptors/uncx-network-v2/index.ts new file mode 100644 index 0000000000..940727c6fb --- /dev/null +++ b/src/adaptors/uncx-network-v2/index.ts @@ -0,0 +1,77 @@ +const utils = require('../utils'); +const fetch = require('node-fetch'); + +const API_URL: string = + 'https://api-chain-eth.unicrypt.network/api/v1/farms/search'; + +const SECONDS_PER_DAY = 86400; + +interface Farm { + apy: number; + tvl: number; + spool_address: string; + stoken_symbol: string; + meta: { + lp_meta: { + token0: { symbol: string; address: string }; + token1: { symbol: string; address: string }; + } | null; + rewards: Array<{ address: string }>; + staking_token: { address: string }; + min_staking_period: number; + }; +} + +interface Response { + rows: Array; + count: number; +} + +const getData = async () => { + const body = { + filters: { sort: 'tvl', sortAscending: false }, + page: 0, + rows_per_page: 100, + }; + return await fetch(API_URL, { + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify(body), + method: 'POST', + }).then(async (data) => await data.json()); +}; + +const getApy = async () => { + const { rows: farms }: Response = await getData(); + + const pools = farms.map((farm) => { + const isLp = !!farm.meta.lp_meta; + const symbol = isLp + ? `${farm.meta.lp_meta.token0.symbol}-${farm.meta.lp_meta.token1.symbol} LP` + : farm.stoken_symbol; + const lockDuration = farm.meta.min_staking_period / SECONDS_PER_DAY; + + return { + pool: farm.spool_address, + chain: utils.formatChain('ethereum'), + project: 'uncx-network-v2', + symbol: symbol.replace('LP', '').trim(), + poolMeta: lockDuration > 2 ? `${lockDuration} days lock` : null, + apy: farm.apy, + tvlUsd: farm.tvl, + underlyingTokens: isLp + ? [farm.meta.lp_meta.token0.address, farm.meta.lp_meta.token1.address] + : [farm.meta.staking_token.address], + rewardTokens: farm.meta.rewards.map(({ address }) => address), + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.unicrypt.network/chain/mainnet/farms', +}; diff --git a/src/adaptors/unidex-perp/abi.json b/src/adaptors/unidex-perp/abi.json new file mode 100644 index 0000000000..310af29ee9 --- /dev/null +++ b/src/adaptors/unidex-perp/abi.json @@ -0,0 +1,128 @@ +[ + { + "inputs": [], + "name": "getInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "__totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct SingleStaking.Token", + "name": "_stakingToken", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "internalType": "struct SingleStaking.Token", + "name": "token", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardsDistributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardsDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + } + ], + "internalType": "struct SingleStaking.Reward", + "name": "rewardData", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "lastTimeRewardApplicable", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardForDuration", + "type": "uint256" + } + ], + "internalType": "struct SingleStaking.RewardToken[]", + "name": "_rewardTokens", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/unidex-perp/index.js b/src/adaptors/unidex-perp/index.js new file mode 100644 index 0000000000..60af9c1cdf --- /dev/null +++ b/src/adaptors/unidex-perp/index.js @@ -0,0 +1,105 @@ +const sdk = require('@defillama/sdk'); +const fetch = require('node-fetch'); +const utils = require('../utils'); +const ABI = require('./abi'); +const { default: BigNumber } = require('bignumber.js'); + +const stakingContracts = [ + { + target: '0x35ad17c9ee4aab967ecbd95b4ce7eb9d8e761a2b', + chain: 'arbitrum', + chainId: 42161, + chainName: 'Arbitrum', + }, +]; +const getInfoABI = ABI.find(({ name }) => name === 'getInfo'); + +const ten = toBN('10'); +function fromWei(wei, unit = 18) { + return toBN(wei).dividedBy(ten.pow(unit)); +} +function toBN(wei) { + return new BigNumber(wei); +} + +module.exports = { + timetravel: false, + apy: async () => { + const pools = []; + const poolsData = await Promise.all( + stakingContracts.map(async (stakingContract) => { + const { + output: { + __totalSupply: totalSupply, + _stakingToken: stakingToken, + _rewardTokens: rewardTokens, + }, + } = await sdk.api.abi.call({ + ...stakingContract, + abi: getInfoABI, + }); + return { + ...stakingContract, + totalSupply, + stakingToken, + rewardTokens, + }; + }) + ); + const { pricesByAddress } = await utils.getPrices( + poolsData.reduce((addresses, poolData) => { + addresses.push( + `${poolData.chain}:${poolData.stakingToken.tokenAddress}` + ); + addresses.push( + ...poolData.rewardTokens.map( + (rewardToken) => + `${poolData.chain}:${rewardToken.token.tokenAddress}` + ) + ); + return addresses; + }, []) + ); + + for (const pool of poolsData) { + const tvlUsd = fromWei( + pool.totalSupply, + pool.stakingToken.decimals + ).multipliedBy( + pricesByAddress[pool.stakingToken.tokenAddress.toLowerCase()] + ); + pools.push({ + pool: `${pool.target.toLowerCase()}-${pool.chain}`, + chain: pool.chainName, + project: 'unidex-perp', + symbol: pool.stakingToken.symbol, + tvlUsd: Number(tvlUsd.toFixed(2)), + apyReward: Number( + pool.rewardTokens + .reduce( + (rewardsInUSD, reward) => + rewardsInUSD.plus( + fromWei( + reward.rewardData.rewardRate, + reward.token.decimals + ).multipliedBy( + pricesByAddress[reward.token.tokenAddress.toLowerCase()] + ) + ), + toBN(0) + ) + .multipliedBy(60 * 60 * 24 * 365) + .div(tvlUsd) + .multipliedBy(100) + .toFixed(2) + ), + rewardTokens: pool.rewardTokens.map((rewardToken) => + rewardToken.token.tokenAddress.toLowerCase() + ), + underlyingTokens: [pool.stakingToken.tokenAddress.toLowerCase()], + url: `https://leverage.unidex.exchange/staking`, + }); + } + return pools; + }, +}; diff --git a/src/adaptors/unilend-protocol/index.js b/src/adaptors/unilend-protocol/index.js new file mode 100755 index 0000000000..7e776f2bc8 --- /dev/null +++ b/src/adaptors/unilend-protocol/index.js @@ -0,0 +1,141 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const poolAbi = require('./poolAbi'); + +const protocolDataProviders = { + unit0: '0x99118c1Ca7D0DC824719E740d4b4721009a267d6', +}; + +const getApy = async (market) => { + const chain = market; + + const protocolDataProvider = protocolDataProviders[market]; + + // 1. Get a list of all pool tokens + const reserveTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllReservesTokens'), + chain, + }) + ).output; + + // 2. Get a list of all uTokens + const uTokens = ( + await sdk.api.abi.call({ + target: protocolDataProvider, + abi: poolAbi.find((m) => m.name === 'getAllATokens'), + chain, + }) + ).output; + + // 3. Reserve data + const poolsReserveData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveData'), + chain, + }) + ).output.map((o) => o.output); + + // 4. Configuration data (ltv, borrowingEnabled) + const poolsReservesConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reserveTokens.map((p) => ({ + target: protocolDataProvider, + params: p.tokenAddress, + })), + abi: poolAbi.find((m) => m.name === 'getReserveConfigurationData'), + chain, + }) + ).output.map((o) => o.output); + + // 5. Total supply for uTokens + const totalSupply = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:totalSupply', + calls: uTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + // 6. uTokens underlying token balance (TVL) + const underlyingBalances = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:balanceOf', + calls: uTokens.map((t, i) => ({ + target: reserveTokens[i].tokenAddress, + params: [t.tokenAddress], + })), + }) + ).output.map((o) => o.output); + + // 7. Get decimals + const underlyingDecimals = ( + await sdk.api.abi.multiCall({ + chain, + abi: 'erc20:decimals', + calls: uTokens.map((t) => ({ + target: t.tokenAddress, + })), + }) + ).output.map((o) => o.output); + + // 8. Get token prices via DefiLlama price API + const priceKeys = reserveTokens + .map((t) => `${chain}:${t.tokenAddress}`) + .join(','); + + const prices = (await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`)).data.coins; + + // 9. Forming final pools + return reserveTokens + .map((pool, i) => { + const frozen = poolsReservesConfigurationData[i].isFrozen; + if (frozen) return null; + + const p = poolsReserveData[i]; + const price = prices[`${chain}:${pool.tokenAddress}`]?.price || 0; + + const supply = totalSupply[i]; + const totalSupplyUsd = (supply / 10 ** underlyingDecimals[i]) * price; + + const currentSupply = underlyingBalances[i]; + const tvlUsd = (currentSupply / 10 ** underlyingDecimals[i]) * price; + + const totalBorrowUsd = totalSupplyUsd - tvlUsd; + + return { + pool: `${uTokens[i].tokenAddress}-${market}`.toLowerCase(), + chain, + project: 'unilend-protocol', + symbol: pool.symbol, + tvlUsd, + apyBase: (p.liquidityRate / 1e27) * 100, + apyBaseBorrow: Number(p.variableBorrowRate) / 1e25, + underlyingTokens: [pool.tokenAddress], + totalSupplyUsd, + totalBorrowUsd, + ltv: poolsReservesConfigurationData[i].ltv / 10000, + borrowable: poolsReservesConfigurationData[i].borrowingEnabled, + url: `https://unilend.io/reserves/${pool.tokenAddress.toLowerCase()}`, + }; + }) + .filter((i) => Boolean(i)); +}; + +const apy = async () => { + const pools = await getApy('unit0'); + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/unilend-protocol/poolAbi.js b/src/adaptors/unilend-protocol/poolAbi.js new file mode 100644 index 0000000000..bba1c9dc38 --- /dev/null +++ b/src/adaptors/unilend-protocol/poolAbi.js @@ -0,0 +1,242 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: 'addressesProvider', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'ADDRESSES_PROVIDER', + outputs: [ + { + internalType: 'contract IPoolAddressesProvider', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getATokenTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllATokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllReservesTokens', + outputs: [ + { + components: [ + { internalType: 'string', name: 'symbol', type: 'string' }, + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + ], + internalType: 'struct IPoolDataProvider.TokenData[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getDebtCeiling', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDebtCeilingDecimals', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getFlashLoanEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getInterestRateStrategyAddress', + outputs: [ + { internalType: 'address', name: 'irStrategyAddress', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getLiquidationProtocolFee', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getPaused', + outputs: [{ internalType: 'bool', name: 'isPaused', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveCaps', + outputs: [ + { internalType: 'uint256', name: 'borrowCap', type: 'uint256' }, + { internalType: 'uint256', name: 'supplyCap', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveConfigurationData', + outputs: [ + { internalType: 'uint256', name: 'decimals', type: 'uint256' }, + { internalType: 'uint256', name: 'ltv', type: 'uint256' }, + { + internalType: 'uint256', + name: 'liquidationThreshold', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidationBonus', type: 'uint256' }, + { internalType: 'uint256', name: 'reserveFactor', type: 'uint256' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + { internalType: 'bool', name: 'borrowingEnabled', type: 'bool' }, + { internalType: 'bool', name: 'stableBorrowRateEnabled', type: 'bool' }, + { internalType: 'bool', name: 'isActive', type: 'bool' }, + { internalType: 'bool', name: 'isFrozen', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveData', + outputs: [ + { internalType: 'uint256', name: 'unbacked', type: 'uint256' }, + { + internalType: 'uint256', + name: 'accruedToTreasuryScaled', + type: 'uint256', + }, + { internalType: 'uint256', name: 'totalAToken', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'totalVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { + internalType: 'uint256', + name: 'averageStableBorrowRate', + type: 'uint256', + }, + { internalType: 'uint256', name: 'liquidityIndex', type: 'uint256' }, + { internalType: 'uint256', name: 'variableBorrowIndex', type: 'uint256' }, + { internalType: 'uint40', name: 'lastUpdateTimestamp', type: 'uint40' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveEModeCategory', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getReserveTokensAddresses', + outputs: [ + { internalType: 'address', name: 'aTokenAddress', type: 'address' }, + { + internalType: 'address', + name: 'stableDebtTokenAddress', + type: 'address', + }, + { + internalType: 'address', + name: 'variableDebtTokenAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getSiloedBorrowing', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getTotalDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], + name: 'getUnbackedMintCap', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'address', name: 'user', type: 'address' }, + ], + name: 'getUserReserveData', + outputs: [ + { + internalType: 'uint256', + name: 'currentATokenBalance', + type: 'uint256', + }, + { internalType: 'uint256', name: 'currentStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'currentVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'principalStableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'scaledVariableDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'stableBorrowRate', type: 'uint256' }, + { internalType: 'uint256', name: 'liquidityRate', type: 'uint256' }, + { internalType: 'uint40', name: 'stableRateLastUpdated', type: 'uint40' }, + { internalType: 'bool', name: 'usageAsCollateralEnabled', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/unipilot/index.js b/src/adaptors/unipilot/index.js new file mode 100644 index 0000000000..ad73083458 --- /dev/null +++ b/src/adaptors/unipilot/index.js @@ -0,0 +1,214 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const { gql, request } = require('graphql-request'); +const axios = require('axios'); +const utils = require('../utils'); + +const EXCHANGES_CHAINS = { + quickswap: { + polygon: 'polygon', + polygon_zkevm: 'polygon_zkevm', + dogechain: 'dogechain', + }, + uniswapv3: { + ethereum: 'ethereum', + polygon: 'polygon', + arbitrum: 'arbitrum', + bsc: 'bsc', + }, +}; + +const GRAPH_URLS = { + uniswapv3: { + ethereum: + 'https://api.thegraph.com/subgraphs/name/unipilotvoirstudio/unipilot-v2-stats', + polygon: sdk.graph.modifyEndpoint('5wUArtUmdKBipfXaD9Rwg3ZDWUTPRBTBJSDHvyhc7AHb'), + arbitrum: + 'https://api.thegraph.com/subgraphs/name/hamzabhatti125/unipilot-stats-arbitrum', + bsc: 'https://api.thegraph.com/subgraphs/name/hamzabhatti125/unipilot-stats-bnb', + }, + quickswap: { + polygon: sdk.graph.modifyEndpoint('GXc2d1wMCbyKq2F2qRo8zcCad6tXsmXubEA5F8jGKBTG'), + polygon_zkevm: + 'https://api.studio.thegraph.com/query/19956/unipilot-stats-polygonzkevm/v0.0.1', + dogechain: + 'https://apis.unipilot.io:5000/subgraphs/name/hamzabhatti125/stats-dogechain', + }, +}; + +const vaultsQueryEthereum = gql` + { + vaults { + id + token0 { + id + symbol + decimals + } + token1 { + id + symbol + decimals + } + totalLockedToken0 + totalLockedToken1 + } + } +`; + +const vaultsQuery = gql` + { + vaults { + id + strategyId + token0 { + id + symbol + decimals + } + token1 { + id + symbol + decimals + } + totalLockedToken0 + totalLockedToken1 + } + } +`; + +const pairsToObj = (pairs) => + pairs.reduce((acc, [el1, el2]) => ({ ...acc, [el1]: el2 }), {}); + +const APR_SERVER_ENDPOINT = (vaultAddresses, chainId, exchange) => { + if (exchange === 'uniswapv3') { + return `https://apis.unipilot.io/api/unipilot/aprs?vaultAddresses=${vaultAddresses.join( + ',' + )}&chaiId=${chainId}`; + } else if (exchange === 'quickswap') { + return `https://apis.unipilot.io:447/api/unipilot/aprs?vaultAddresses=${vaultAddresses.join( + ',' + )}&chaiId=${chainId}`; + } +}; + +const CHAIN_IDS = { + ethereum: 1, + polygon: 137, + polygon_zkevm: 1101, + arbitrum: 42161, + bsc: 56, + dogechain: 2000, +}; + +const resultArray = []; + +const getStrategties = (strategyId) => { + if (strategyId === '1') return 'Wide'; + else if (strategyId === '2') return 'Balanced'; + else if (strategyId === '3') return 'Narrow'; + else return ''; +}; + +const getApy = async () => { + for (const [exchange, chains] of Object.entries(EXCHANGES_CHAINS)) { + try { + const vaultData = pairsToObj( + await Promise.all( + Object.values(chains).map(async (chain) => [ + chain, + await request( + GRAPH_URLS[exchange][chains[chain]], + chain === 'ethereum' ? vaultsQueryEthereum : vaultsQuery + ), + ]) + ) + ); + + const aprs = pairsToObj( + await Promise.all( + Object.values(chains).map(async (chain) => { + //convert array of string to single string with comma separated + const vaultAddresses = vaultData[chain].vaults.map( + (vault) => vault.id + ); + const res = await axios.get( + APR_SERVER_ENDPOINT(vaultAddresses, CHAIN_IDS[chain], exchange) + ); + return [chain, res.data.doc]; + }) + ) + ); + + // get token object where key is chain and value is array of token addresses + const tokens = Object.entries(vaultData).reduce( + (acc, [chain, { vaults }]) => ({ + ...acc, + [chain]: [ + ...new Set( + vaults.map((vault) => [vault.token0.id, vault.token1.id]).flat() + ), + ], + }), + {} + ); + + let keys = []; + for (const key of Object.keys(tokens)) { + keys.push(tokens[key].map((t) => `${key}:${t}`)); + } + keys = [...new Set(keys.flat())]; + + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${keys + .flat() + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pools = Object.entries(vaultData).map(([chain, { vaults }]) => { + const vaultsAprs = aprs[chain]; + const modifiedVaults = vaults.map((vault) => { + const tvl0 = + Number(vault.totalLockedToken0) / + 10 ** Number(vault.token0.decimals); + const tvl1 = + Number(vault.totalLockedToken1) / + 10 ** Number(vault.token1.decimals); + const tvlUSD = + tvl0 * prices[`${chain}:${vault.token0.id}`]?.price + + tvl1 * prices[`${chain}:${vault.token1.id}`]?.price; + + return { + pool: vault.id, + chain: utils.formatChain(chain), + project: 'unipilot', + symbol: `${vault.token0.symbol}-${vault.token1.symbol} ${ + vault.strategyId ? getStrategties(vault.strategyId) : '' + }`, + tvlUsd: tvlUSD || 0, + url: + exchange === 'quickswap' + ? `https://quickswap.unipilot.io/add?vault=${vault.id}&chainId=${CHAIN_IDS[chain]}` + : `https://app.unipilot.io/add?vault=${vault.id}&chainId=${CHAIN_IDS[chain]}`, + underlyingTokens: [vault.token0.id, vault.token1.id], + apyBase: Number(vaultsAprs[vault.id]?.avg24Hrs.total) ?? 0, + apyBase7d: Number(vaultsAprs[vault.id]?.avgAprWeekly.total) ?? 0, + }; + }); + return modifiedVaults; + }); + resultArray.push(...pools.flat()); + } catch (error) { + console.log(error); + } + } + return resultArray; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/uniswap-v2/index.js b/src/adaptors/uniswap-v2/index.js new file mode 100755 index 0000000000..7ade7c8d25 --- /dev/null +++ b/src/adaptors/uniswap-v2/index.js @@ -0,0 +1,141 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); +const { addMerklRewardApy } = require('../merkl/merkl-additional-reward'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + 'FEtpnfQ1aqF8um2YktEkfzFD11ZKrfurvBLPeQzv9JB1' + ), + base: sdk.graph.modifyEndpoint( + '4jGhpKjW4prWoyt5Bwk1ZHUwdEmNWveJcjEyjoTZWCY9' + ), +}; + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + const url = `https://app.uniswap.org/positions/create/v2?currencyA=${token0}¤cyB=${token1}&chain=${chain}`; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'uniswap-v2', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +}; + +const main = async (timestamp = null) => { + let data = []; + + for (const [chain, url] of Object.entries(chains)) { + try { + console.log(`Fetching data for ${chain}...`); + const chainData = await topLvl( + chain, + url, + query, + queryPrior, + 'v2', + timestamp + ); + data.push(...chainData); + } catch (err) { + console.log(chain, err); + } + } + + const pools = await addMerklRewardApy( + data.filter((p) => utils.keepFinite(p)), + 'uniswap' + ); + + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/uniswap-v3/estimateFee.ts b/src/adaptors/uniswap-v3/estimateFee.ts new file mode 100644 index 0000000000..86e458b11c --- /dev/null +++ b/src/adaptors/uniswap-v3/estimateFee.ts @@ -0,0 +1,230 @@ +// forked from https://github.com/chunza2542/uniswap.fish + +const bn = require('bignumber.js'); + +interface Tick { + tickIdx: string; + liquidityNet: string; + price0: string; + price1: string; +} + +bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 }); + +const Q96 = new bn(2).pow(96); + +const getTickFromPrice = ( + price: number, + token0Decimal: string, + token1Decimal: string +): number => { + const token0 = expandDecimals(price, Number(token0Decimal)); + const token1 = expandDecimals(1, Number(token1Decimal)); + const sqrtPrice = encodeSqrtPriceX96(token1).div(encodeSqrtPriceX96(token0)); + + return Math.log(sqrtPrice.toNumber()) / Math.log(Math.sqrt(1.0001)); +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 1) +interface TokensAmount { + amount0: number; + amount1: number; +} +const getTokensAmountFromDepositAmountUSD = ( + P: number, + Pl: number, + Pu: number, + priceUSDX: number, + priceUSDY: number, + depositAmountUSD: number +): TokensAmount => { + const deltaL = + depositAmountUSD / + ((Math.sqrt(P) - Math.sqrt(Pl)) * priceUSDY + + (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)) * priceUSDX); + + let deltaY = deltaL * (Math.sqrt(P) - Math.sqrt(Pl)); + if (deltaY * priceUSDY < 0) deltaY = 0; + if (deltaY * priceUSDY > depositAmountUSD) + deltaY = depositAmountUSD / priceUSDY; + + let deltaX = deltaL * (1 / Math.sqrt(P) - 1 / Math.sqrt(Pu)); + if (deltaX * priceUSDX < 0) deltaX = 0; + if (deltaX * priceUSDX > depositAmountUSD) + deltaX = depositAmountUSD / priceUSDX; + + return { amount0: deltaX, amount1: deltaY }; +}; + +// for calculation detail, please visit README.md (Section: Calculation Breakdown, No. 2) +const getLiquidityForAmount0 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount0: bn +): bn => { + // amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) + const intermediate = mulDiv(sqrtRatioBX96, sqrtRatioAX96, Q96); + return mulDiv(amount0, intermediate, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getLiquidityForAmount1 = ( + sqrtRatioAX96: bn, + sqrtRatioBX96: bn, + amount1: bn +): bn => { + // amount1 / (sqrt(upper) - sqrt(lower)) + return mulDiv(amount1, Q96, sqrtRatioBX96.minus(sqrtRatioAX96)); +}; + +const getSqrtPriceX96 = ( + price: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const token0 = expandDecimals(price, token0Decimal); + const token1 = expandDecimals(1, token1Decimal); + + return token0.div(token1).sqrt().multipliedBy(Q96); +}; + +const getLiquidityDelta = ( + P: number, + lowerP: number, + upperP: number, + amount0: number, + amount1: number, + token0Decimal: number, + token1Decimal: number +): bn => { + const amt0 = expandDecimals(amount0, token1Decimal); + const amt1 = expandDecimals(amount1, token0Decimal); + + const sqrtRatioX96 = getSqrtPriceX96(P, token0Decimal, token1Decimal); + const sqrtRatioAX96 = getSqrtPriceX96(lowerP, token0Decimal, token1Decimal); + const sqrtRatioBX96 = getSqrtPriceX96(upperP, token0Decimal, token1Decimal); + + let liquidity: bn; + if (sqrtRatioX96.lte(sqrtRatioAX96)) { + liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amt0); + } else if (sqrtRatioX96.lt(sqrtRatioBX96)) { + const liquidity0 = getLiquidityForAmount0( + sqrtRatioX96, + sqrtRatioBX96, + amt0 + ); + const liquidity1 = getLiquidityForAmount1( + sqrtRatioAX96, + sqrtRatioX96, + amt1 + ); + + liquidity = bn.min(liquidity0, liquidity1); + } else { + liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amt1); + } + + return liquidity; +}; + +const estimateFee = ( + liquidityDelta: bn, + liquidity: bn, + volume24H: number, + feeTier: string +): number => { + const feeTierPercentage = getFeeTierPercentage(feeTier); + const liquidityPercentage = liquidityDelta + .div(liquidity.plus(liquidityDelta)) + .toNumber(); + + return feeTierPercentage * volume24H * liquidityPercentage; +}; + +const getLiquidityFromTick = (poolTicks: Tick[], tick: number): bn => { + // calculate a cumulative of liquidityNet from all ticks that poolTicks[i] <= tick + let liquidity: bn = new bn(0); + for (let i = 0; i < poolTicks.length - 1; ++i) { + liquidity = liquidity.plus(new bn(poolTicks[i].liquidityNet)); + + const lowerTick = Number(poolTicks[i].tickIdx); + const upperTick = Number(poolTicks[i + 1]?.tickIdx); + + if (lowerTick <= tick && tick <= upperTick) { + break; + } + } + + return liquidity; +}; + +// private helper functions +const encodeSqrtPriceX96 = (price: number | string | bn): bn => { + return new bn(price).sqrt().multipliedBy(Q96).integerValue(3); +}; + +const expandDecimals = (n: number | string | bn, exp: number): bn => { + return new bn(n).multipliedBy(new bn(10).pow(exp)); +}; + +const mulDiv = (a: bn, b: bn, multiplier: bn) => { + return a.multipliedBy(b).div(multiplier); +}; + +const getFeeTierPercentage = (tier: string): number => { + if (tier === '100') return 0.01 / 100; + if (tier === '500') return 0.05 / 100; + if (tier === '3000') return 0.3 / 100; + if (tier === '10000') return 1 / 100; + return 0; +}; + +module.exports.EstimatedFees = ( + priceAssumptionValue, + priceRangeValue, + currentPriceUSDToken1, + currentPriceUSDToken0, + depositAmountUSD, + decimalsToken0, + decimalsToken1, + feeTier, + volume, + poolTicks +) => { + const P = priceAssumptionValue; + let Pl = priceRangeValue[0]; + let Pu = priceRangeValue[1]; + const priceUSDX = currentPriceUSDToken1 || 1; + const priceUSDY = currentPriceUSDToken0 || 1; + + const { amount0, amount1 } = getTokensAmountFromDepositAmountUSD( + P, + Pl, + Pu, + priceUSDX, + priceUSDY, + depositAmountUSD + ); + + const deltaL = getLiquidityDelta( + P, + Pl, + Pu, + amount0, + amount1, + Number(decimalsToken0 || 18), + Number(decimalsToken1 || 18) + ); + + let currentTick = getTickFromPrice( + P, + decimalsToken0 || '18', + decimalsToken1 || '18' + ); + + const L = getLiquidityFromTick(poolTicks, currentTick); + + const estimatedFee = + P >= Pl && P <= Pu ? estimateFee(deltaL, L, volume, feeTier) : 0; + + return estimatedFee; +}; diff --git a/src/adaptors/uniswap-v3/index.js b/src/adaptors/uniswap-v3/index.js new file mode 100644 index 0000000000..e00e24db91 --- /dev/null +++ b/src/adaptors/uniswap-v3/index.js @@ -0,0 +1,378 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); + +const utils = require('../utils'); +const { EstimatedFees } = require('./estimateFee.ts'); +const { checkStablecoin } = require('../../handlers/triggerEnrichment'); +const { boundaries } = require('../../utils/exclude'); +const getOnchainPools = require('./onchain'); +const { addMerklRewardApy } = require('../merkl/merkl-additional-reward'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + '5zvR82QoaXYFyDEKLZ9t6v9adgnptxYpKpSbxtgVENFV' + ), + polygon: sdk.graph.modifyEndpoint( + '3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm' + ), + arbitrum: sdk.graph.modifyEndpoint( + 'FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM' + ), + optimism: sdk.graph.modifyEndpoint( + '7SVwgBfXoWmiK6x1NF1VEo1szkeWLniqWN1oYsX3UMb5' + ), + celo: sdk.graph.modifyEndpoint( + '5GMxLtvwbfKxyCpSgHvS8FbeofS2ry9K76NL9RCzPNm2' + ), + avax: sdk.graph.modifyEndpoint( + 'GVH9h9KZ9CqheUEL93qMbq7QwgoBu32QXQDPR6bev4Eo' + ), + bsc: sdk.graph.modifyEndpoint('GcKPSgHoY42xNYVAkSPDhXSzi6aJDRQSKqBSXezL47gV'), + base: sdk.graph.modifyEndpoint( + 'HMuAwufqZ1YCRmzL2SfHTVkzZovC9VL2UAKhjvRqKiR1' + ), +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + feeTier + token0 { + symbol + id + decimals + } + token1 { + symbol + id + decimals + } + } + } +`; + +const queryPrior = gql` + { + pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp, + stablecoins +) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + // uni v3 subgraph reserves values are wrong! + // instead of relying on subgraph values, gonna pull reserve data from contracts + // new tvl calc + // let + if (chainString === 'base') { + const excludeTokens = [ + '0xb50721bcf8d664c30412cfbc6cf7a15145234ad1', + '0x4d224452801aced8b2f0aebe155379bb5d594381', + '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', + '0x385eeac5cb85a38a9a07a70c73e0a3271cfb54a7', + '0x4701f80124f5ebf6846a43929b22a917bc30b2ca', + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + ]; + dataNow = dataNow.filter( + (p) => + !excludeTokens.some((i) => i === p.token0.id || i === p.token1.id) + ); + } + + const balanceCalls = []; + for (const pool of dataNow) { + balanceCalls.push({ + target: pool.token0.id, + params: pool.id, + }); + balanceCalls.push({ + target: pool.token1.id, + params: pool.id, + }); + } + + const tokenBalances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: balanceCalls, + chain: chainString, + permitFailure: true, + }); + + dataNow = dataNow.map((p) => { + const x = tokenBalances.output.filter((i) => i.input.params[0] === p.id); + return { + ...p, + reserve0: + x.find((i) => i.input.target === p.token0.id).output / + `1e${p.token0.decimals}`, + reserve1: + x.find((i) => i.input.target === p.token1.id).output / + `1e${p.token1.decimals}`, + }; + }); + + // balance calls not working on the uni v3 avax contracts + if (chainString === 'avax') { + dataNow = dataNow.map((p) => ({ + ...p, + reserve0: Number(p.totalValueLockedToken0), + reserve1: Number(p.totalValueLockedToken1), + })); + } + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + + // to reduce the nb of subgraph calls for tick range, we apply the lb db filter in here + dataNow = dataNow.filter( + (p) => p.totalValueLockedUSD >= boundaries.tvlUsdDB.lb + ); + // add the symbol for the stablecoin (we need to distinguish btw stable and non stable pools + // so we apply the correct tick range) + dataNow = dataNow.map((p) => { + const symbol = utils.formatSymbol( + `${p.token0.symbol}-${p.token1.symbol}` + ); + const stablecoin = checkStablecoin({ ...p, symbol }, stablecoins); + return { + ...p, + symbol, + stablecoin, + }; + }); + + // for new v3 apy calc + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pools; + + // calc apy (note: old way of using 24h fees * 365 / tvl. keeping this for now) and will store the + // new apy calc as a separate field + // note re arbitrum: their subgraph is outdated (no tick data -> no uni v3 style apy calc) + dataNow = dataNow.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + const enableV3Apy = true; + if (enableV3Apy && chainString !== 'arbitrum') { + dataNow = dataNow.map((p) => ({ + ...p, + token1_in_token0: p.price1 / p.price0, + })); + + // batching the tick query into 3 chunks to prevent it from breaking + const nbBatches = 3; + const chunkSize = Math.ceil(dataNow.length / nbBatches); + const chunks = [ + dataNow.slice(0, chunkSize).map((i) => i.id), + dataNow.slice(chunkSize, chunkSize * 2).map((i) => i.id), + dataNow.slice(chunkSize * 2, dataNow.length).map((i) => i.id), + ]; + + const tickData = {}; + // we fetch 3 pages for each pool + for (const page of [0, 1, 2]) { + console.log(`page nb: ${page}`); + let pageResults = {}; + for (const chunk of chunks) { + console.log(chunk.length); + const tickQuery = ` + query { + ${chunk + .map( + (poolAddress, index) => ` + pool_${poolAddress}: ticks( + first: 1000, + skip: ${page * 1000}, + where: { poolAddress: "${poolAddress}" }, + orderBy: tickIdx + ) { + tickIdx + liquidityNet + price0 + price1 + } + ` + ) + .join('\n')} + } + `; + + try { + const response = await request(url, tickQuery); + pageResults = { ...pageResults, ...response }; + } catch (err) { + console.log(err); + } + } + tickData[`page_${page}`] = pageResults; + } + + // reformat tickData + const ticks = {}; + Object.values(tickData).forEach((page) => { + Object.entries(page).forEach(([pool, values]) => { + if (!ticks[pool]) { + ticks[pool] = []; + } + ticks[pool] = ticks[pool].concat(values); + }); + }); + + // assume an investment of 1e5 USD + const investmentAmount = 1e5; + + // tick range + const pct = 0.3; + const pctStablePool = 0.001; + + dataNow = dataNow.map((p) => { + const poolTicks = ticks[`pool_${p.id}`] ?? []; + + if (!poolTicks.length) { + console.log(`No pool ticks found for ${p.id}`); + return { ...p, estimatedFee: null, apy7d: null }; + } + + const delta = p.stablecoin ? pctStablePool : pct; + + const priceAssumption = p.stablecoin ? 1 : p.token1_in_token0; + + const estimatedFee = EstimatedFees( + priceAssumption, + [p.token1_in_token0 * (1 - delta), p.token1_in_token0 * (1 + delta)], + p.price1, + p.price0, + investmentAmount, + p.token0.decimals, + p.token1.decimals, + p.feeTier, + p.volumeUSD7d, + poolTicks + ); + + const apy7d = ((estimatedFee * 52) / investmentAmount) * 100; + + return { ...p, estimatedFee, apy7d }; + }); + } + + return dataNow.map((p) => { + const poolMeta = `${p.feeTier / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + const feeTier = Number(poolMeta.replace('%', '')) * 10000; + const url = `https://app.uniswap.org/positions/create/v3?currencyA=${token0}¤cyB=${token1}&chain=${chain}&fee={"feeAmount":${feeTier}}`; + + let symbol = p.symbol; + if ( + chainString === 'arbitrum' && + underlyingTokens + .map((t) => t.toLowerCase()) + .includes('0xff970a61a04b1ca14834a43f5de4533ebddb5cc8') + ) { + symbol = p.symbol.replace('USDC', 'USDC.e'); + } + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'uniswap-v3', + poolMeta: `${poolMeta}, stablePool=${p.stablecoin}`, + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url, + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + } catch (e) { + console.log(chainString, e); + return []; + } +}; + +const main = async (timestamp = null) => { + const stablecoins = ( + await axios.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).data.peggedAssets.map((s) => s.symbol.toLowerCase()); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + + const data = []; + for (const [chain, url] of Object.entries(chains)) { + console.log(chain); + data.push( + await topLvl(chain, url, query, queryPrior, 'v3', timestamp, stablecoins) + ); + } + + const bobPools = await getOnchainPools(); + data.push(bobPools); + + const pools = await addMerklRewardApy( + data + .flat() + .filter( + (p) => + utils.keepFinite(p) && + ![ + '0x0c6d9d0f82ed2e0b86c4d3e9a9febf95415d1b76', + '0xc809d13e9ea08f296d3b32d4c69d46ff90f73fd8', + ].includes(p.pool) + ), + 'uniswap' + ); + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/uniswap-v3/onchain.js b/src/adaptors/uniswap-v3/onchain.js new file mode 100644 index 0000000000..f645d42ce4 --- /dev/null +++ b/src/adaptors/uniswap-v3/onchain.js @@ -0,0 +1,206 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { ethers } = require('ethers'); +const { getUniqueAddresses } = require('@defillama/sdk/build/generalUtil'); +const BigNumber = require('bignumber.js'); + +const chains = { + bob: { + factory: '0xcb2436774C3e191c85056d248EF4260ce5f27A9D', + fromBlock: 5188280, + blockTime: 2, + ui: 'oku', + }, +}; + +const SwapInterface = new ethers.utils.Interface([ + 'event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)', +]); + +const getPools = async (chain) => { + const config = chains[chain]; + const dataPools = []; + + const currentBlock = await sdk.api.util.getLatestBlock(chain); + + const poolCreatedLogs = await sdk.api.util.getLogs({ + chain, + target: config.factory, + topic: 'PoolCreated(address,address,uint24,int24,address)', + keys: [], + fromBlock: config.fromBlock, + toBlock: currentBlock.number, + }); + + const pools = poolCreatedLogs.output.map((log) => ({ + token0: '0x' + log.topics[1].slice(-40), + token1: '0x' + log.topics[2].slice(-40), + address: '0x' + log.data.slice(-40), + fee: BigInt(log.topics[3]), + })); + + const tokens = getUniqueAddresses( + pools.map((p) => p.token0).concat(pools.map((p) => p.token1)) + ); + const prices = await utils.getPrices(tokens, chain); + + const tokenDecimals = Object.fromEntries( + ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((t) => ({ + target: t, + params: [], + })), + chain, + permitFailure: true, + }) + ).output.map((o) => [o.input.target, Number(o.output)]) + ); + + const tokenSymbols = Object.fromEntries( + ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((t) => ({ + target: t, + params: [], + })), + chain, + permitFailure: true, + }) + ).output.map((o) => [o.input.target, o.output]) + ); + + const token0Balances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: pools.map((p) => ({ + target: p.token0, + params: [p.address], + })), + chain, + permitFailure: true, + }); + const token1Balances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: pools.map((p) => ({ + target: p.token1, + params: [p.address], + })), + chain, + permitFailure: true, + }); + + pools.forEach((p, i) => { + pools[i].balance0 = BigNumber(token0Balances.output[i].output); + pools[i].balance1 = BigNumber(token1Balances.output[i].output); + }); + + for (const pool of pools) { + if ( + !prices.pricesByAddress[pool.token0] || + !prices.pricesByAddress[pool.token1] + ) { + continue; + } + + const swapLogs = await sdk.api.util.getLogs({ + chain, + target: pool.address, + topic: '', + topics: [SwapInterface.getEventTopic('Swap')], + keys: [], + fromBlock: currentBlock.number - (24 * 3600) / config.blockTime, + toBlock: currentBlock.number, + }); + + const parsedSwapLogs = swapLogs.output.map( + (log) => SwapInterface.parseLog(log).args + ); + + const totalFee0 = parsedSwapLogs + .map((log) => log.amount0.toBigInt()) + .filter((x) => x > 0n) + .reduce((sum, x) => sum + (x * pool.fee) / 1_000_000n, 0n); + const totalFee1 = parsedSwapLogs + .map((log) => log.amount1.toBigInt()) + .filter((x) => x > 0n) + .reduce((sum, x) => sum + (x * pool.fee) / 1_000_000n, 0n); + + const feeValue0 = BigNumber(totalFee0) + .times(10 ** (18 - tokenDecimals[pool.token0])) + .times(prices.pricesByAddress[pool.token0]) + .div(1e18); + const feeValue1 = BigNumber(totalFee1) + .times(10 ** (18 - tokenDecimals[pool.token1])) + .times(prices.pricesByAddress[pool.token1]) + .div(1e18); + + const feeValue = feeValue0.plus(feeValue1); + + const totalVolume0 = parsedSwapLogs + .map((log) => log.amount0.toBigInt()) + .filter((x) => x > 0n) + .reduce((sum, x) => sum + x, 0n); + const totalVolume1 = parsedSwapLogs + .map((log) => log.amount1.toBigInt()) + .filter((x) => x > 0n) + .reduce((sum, x) => sum + x, 0n); + + const volumeValue0 = BigNumber(totalVolume0) + .times(10 ** (18 - tokenDecimals[pool.token0])) + .times(prices.pricesByAddress[pool.token0]) + .div(1e18); + const volumeValue1 = BigNumber(totalVolume1) + .times(10 ** (18 - tokenDecimals[pool.token1])) + .times(prices.pricesByAddress[pool.token1]) + .div(1e18); + + const volumeValue = volumeValue0.plus(volumeValue1); + + const tvl0 = pool.balance0 + .times(10 ** (18 - tokenDecimals[pool.token0])) + .times(prices.pricesByAddress[pool.token0]) + .div(1e18); + const tvl1 = pool.balance1 + .times(10 ** (18 - tokenDecimals[pool.token1])) + .times(prices.pricesByAddress[pool.token1]) + .div(1e18); + + const tvl = tvl0.plus(tvl1); + + const apr = feeValue.div(tvl).times(100).times(365); + const apy = utils.aprToApy(apr.toNumber()); + + const poolMeta = `${Number(pool.fee) / 1e4}%`; + + dataPools.push({ + pool: pool.address, + chain, + project: 'uniswap-v3', + poolMeta, + symbol: [tokenSymbols[pool.token0], tokenSymbols[pool.token1]].join('-'), + tvlUsd: tvl.toNumber(), + apyBase: apy, + underlyingTokens: [pool.token0, pool.token1], + url: + config.ui === 'oku' + ? `https://oku.trade/app/${chain}/liquidity/${pool.address}` + : `https://app.uniswap.org/#/add/${pool.token0}/${pool.token1}/${pool.fee}?chain=${chain}`, + volumeUsd1d: volumeValue.toNumber(), + }); + } + + return dataPools; +}; + +const getOnchainPools = async () => { + const data = []; + for (const chain of Object.keys(chains)) { + console.log(chain); + data.push(await getPools(chain)); + } + return data.flat(); +}; + +module.exports = getOnchainPools; diff --git a/src/adaptors/uniswap-v4/index.js b/src/adaptors/uniswap-v4/index.js new file mode 100644 index 0000000000..c0dc439ca2 --- /dev/null +++ b/src/adaptors/uniswap-v4/index.js @@ -0,0 +1,133 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const chains = { + ethereum: sdk.graph.modifyEndpoint( + 'DiYPVdygkfjDWhbxGSqAQxwBKmfKnkWQojqeM2rkLb3G' + ), + base: sdk.graph.modifyEndpoint( + 'Gqm2b5J85n1bhCyDMpGbtbVn4935EvvdyHdHrx3dibyj' + ), + arbitrum: sdk.graph.modifyEndpoint( + 'G5TsTKNi8yhPSV7kycaE23oWbqv9zzNqR49FoEQjzq1r' + ), + polygon: sdk.graph.modifyEndpoint( + 'CwpebM66AH5uqS5sreKij8yEkkPcHvmyEs7EwFtdM5ND' + ), + unichain: sdk.graph.modifyEndpoint( + 'aa3YpPCxatg4LaBbLFuv2iBC8Jvs9u3hwt5GTpS4Kit' + ), + bsc: sdk.graph.modifyEndpoint('2qQpC8inZPZL4tYfRQPFGZhsE8mYzE67n5z3Yf5uuKMu'), + avax: sdk.graph.modifyEndpoint( + '49JxRo9FGxWpSf5Y5GKQPj5NUpX2HhpoZHpGzNEWQZjq' + ), + optimism: sdk.graph.modifyEndpoint( + '6RBtsmGUYfeLeZsYyxyKSUiaA6WpuC69shMEQ1Cfuj9u' + ), +}; + +const query = gql` + { + pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { + id + feeTier + liquidity + totalValueLockedUSD + totalValueLockedToken0 + totalValueLockedToken1 + volumeUSD + token0 { + symbol + decimals + id + } + token1 { + symbol + decimals + id + } + } + } +`; + +const topLvl = async (chainString, url, query, timestamp) => { + try { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pools; + + let dataPrior = await request( + url, + queryC.replace('', blockPrior) + ); + dataPrior = dataPrior.pools; + + dataNow = dataNow.map((p) => ({ + ...p, + reserve0: p.totalValueLockedToken0, + reserve1: p.totalValueLockedToken1, + })); + + dataNow = await utils.tvl(dataNow, chainString); + + dataNow = dataNow.map((pool) => { + const poolPrior = dataPrior.find((p) => p.id === pool.id); + const volumeUSD = Number(pool.volumeUSD || 0); + const volumeUSDPrior = Number(poolPrior?.volumeUSD || 0); + const volumeUSD1d = volumeUSD - volumeUSDPrior; + + const feeTier = Number(pool.feeTier || 0); + const feeUSD1d = (volumeUSD1d * feeTier) / 1e6; + + const apy = + pool.totalValueLockedUSD > 0 + ? (feeUSD1d * 365 * 100) / pool.totalValueLockedUSD + : 0; + + return { + ...pool, + apyBase: apy, + volumeUsd1d: volumeUSD1d, + }; + }); + + return dataNow.map((p) => { + const poolMeta = `${Number(p.feeTier) / 1e4}%`; + const underlyingTokens = [p.token0.id, p.token1.id]; + const chain = chainString === 'avax' ? 'avalanche' : chainString; + + return { + pool: `${p.id}-${chainString}-uniswap-v4`, + chain: utils.formatChain(chainString), + project: 'uniswap-v4', + poolMeta: poolMeta, + symbol: `${p.token0.symbol}-${p.token1.symbol}`, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apyBase, + underlyingTokens, + url: `https://app.uniswap.org/explore/pools/${chain}/${p.id}`, + volumeUsd1d: p.volumeUsd1d, + }; + }); + } catch (e) { + console.log(chainString, e); + return []; + } +}; + +const main = async (timestamp = null) => { + const data = []; + for (const [chain, url] of Object.entries(chains)) { + data.push(await topLvl(chain, url, query, timestamp)); + } + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + apy: main, +}; diff --git a/src/adaptors/uniswap/index.js b/src/adaptors/uniswap/index.js deleted file mode 100755 index 7071983dd5..0000000000 --- a/src/adaptors/uniswap/index.js +++ /dev/null @@ -1,145 +0,0 @@ -const { request, gql } = require('graphql-request'); - -const utils = require('../utils'); - -const baseUrl = 'https://api.thegraph.com/subgraphs/name'; -const urlV2 = `${baseUrl}/ianlapham/uniswapv2`; -const urlV3 = `${baseUrl}/uniswap/uniswap-v3`; -const urlPolygon = `${baseUrl}/ianlapham/uniswap-v3-polygon`; -const urlArbitrum = `${baseUrl}/ianlapham/arbitrum-minimal`; -const urlOptimism = `${baseUrl}/ianlapham/optimism-post-regenesis`; - -const queryV2 = gql` - { - pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { - id - reserve0 - reserve1 - volumeUSD - token0 { - symbol - id - } - token1 { - symbol - id - } - } - } -`; - -const queryPriorV2 = gql` - { - pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { - id - volumeUSD - } - } -`; - -const queryV3 = gql` - { - pools(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc block: {number: }) { - id - totalValueLockedToken0 - totalValueLockedToken1 - volumeUSD - feeTier - token0 { - symbol - id - } - token1 { - symbol - id - } - } - } -`; - -const queryPriorV3 = gql` - { - pools( first: 1000 orderBy: totalValueLockedUSD orderDirection:desc block: {number: }) { - id - volumeUSD - } - } -`; - -const buildPool = (entry, version, chainString) => { - const symbol = utils.formatSymbol( - `${entry.token0.symbol}-${entry.token1.symbol}` - ); - const newObj = { - pool: entry.id, - chain: utils.formatChain(chainString), - project: 'uniswap', - market: version, - symbol: version === 'v3' ? `${symbol} (${entry.feeTier / 1e4}%)` : symbol, - tvlUsd: entry.totalValueLockedUSD, - apy: entry.apy, - }; - - return newObj; -}; - -const topLvl = async ( - chainString, - url, - query, - queryPrior, - version, - timestamp -) => { - const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ - url, - ]); - - // pull data - queryC = query; - let dataNow = await request(url, queryC.replace('', block)); - dataNow = version === 'v2' ? dataNow.pairs : dataNow.pools; - - // v3 subgraph has different fields, will copy and keep the v2 name - if (version === 'v3') { - for (const e of dataNow) { - e['reserve0'] = e.totalValueLockedToken0; - e['reserve1'] = e.totalValueLockedToken1; - } - } - - // pull 24h offset data to calculate fees from swap volume - queryPriorC = queryPrior; - let dataPrior = await request( - url, - queryPriorC.replace('', blockPrior) - ); - dataPrior = version === 'v2' ? dataPrior.pairs : dataPrior.pools; - - // calculate tvl - dataNow = await utils.tvl(dataNow, chainString); - // calculate apy - let data = dataNow.map((el) => utils.apy(el, dataPrior, version)); - - // build pool objects - data = data.map((el) => buildPool(el, version, chainString)); - - return data; -}; - -const main = async (timestamp = null) => { - let data = await Promise.all([ - topLvl('ethereum', urlV2, queryV2, queryPriorV2, 'v2', timestamp), - topLvl('ethereum', urlV3, queryV3, queryPriorV3, 'v3', timestamp), - topLvl('polygon', urlPolygon, queryV3, queryPriorV3, 'v3', timestamp), - topLvl('arbitrum', urlArbitrum, queryV3, queryPriorV3, 'v3', timestamp), - topLvl('optimism', urlOptimism, queryV3, queryPriorV3, 'v3', timestamp), - ]); - - return data.flat(); -}; - -module.exports = { - timetravel: true, - apy: main, -}; diff --git a/src/adaptors/unitas/index.js b/src/adaptors/unitas/index.js new file mode 100644 index 0000000000..8a6629138d --- /dev/null +++ b/src/adaptors/unitas/index.js @@ -0,0 +1,131 @@ +const axios = require('axios'); +const {aprToApy} = require("../utils"); + +const SOL_RPC = 'https://api.mainnet-beta.solana.com'; +const STAKE_POOL = 'CFgrWjb9DYKVqf7QyQfmwjboDDkXpFHQ6292rnYxrjsa'; +const SUSDU = '9iq5Q33RSiz1WcupHAQKbHBZkpn92UxBG2HfPWAZhMCa'; +const DISTRIBUTE_ACCOUNT = "AmAcmYeJgxdHfoMSb3zwWFFPwWivADiyMozHwg5WyTtW" +const DISTRIBUTOR_DISCRIMINATOR = "FytrVezW" + +async function getStakePoolSize() { + const res = await axios.post(SOL_RPC, { + jsonrpc: "2.0", + id: 1, + method: "getTokenAccountBalance", + params: [ + STAKE_POOL, + ] + }); + + const amount = res.data.result.value.amount; + const decimal = res.data.result.value.decimals; + + return Number(amount) / Math.pow(10, decimal); +} + +async function getSignatures() { + const res = await axios.post(SOL_RPC, { + jsonrpc: "2.0", + id: 1, + method: "getSignaturesForAddress", + params: [ + DISTRIBUTE_ACCOUNT, + { + "limit": 20, + "commitment": "finalized" + } + ] + }); + return res.data.result +} + +async function getTransaction(sig) { + const res = await axios.post(SOL_RPC, { + jsonrpc: '2.0', + id: 1, + method: 'getTransaction', + params: [ + sig, + { + encoding: 'jsonParsed', + commitment: 'finalized' + } + ] + }); + + return res.data.result; +} + +function createRateLimiter(interval) { + let queue = Promise.resolve(); + + return function (fn) { + queue = queue.then(() => new Promise((resolve) => { + setTimeout(async () => { + try { + const result = await fn(); + resolve(result); + } catch (e) { + resolve(null); + } + }, interval); + })); + return queue; + }; +} + +function matchDis(data) { + for (let i = 0; i < DISTRIBUTOR_DISCRIMINATOR.length; i++) { + if (data[i] !== DISTRIBUTOR_DISCRIMINATOR[i]) return false; + } + return true +} + +async function getRewardDistribution() { + const rateLimit = createRateLimiter(5000); + + const signatures = await rateLimit(() => getSignatures()) + + for (const sig of signatures) { + const signature = sig.signature + const tx = await rateLimit(() => getTransaction(signature)); + if (!tx) continue; + + const message = tx.transaction.message; + const instructions = message.instructions; + + for (const inst of instructions) { + if (matchDis(inst.data)) { + const amount = tx.meta.innerInstructions[0].instructions[0].parsed.info.tokenAmount.amount + const decimal = tx.meta.innerInstructions[0].instructions[0].parsed.info.tokenAmount.decimals + return amount / Math.pow(10, decimal) + } + } + } +} + +async function apy() { + const tvlUsd = await getStakePoolSize() + + const reward = await getRewardDistribution() + + //rewards are now beeing streamed every 8hours, which we scale up to a year + const aprBase = ((reward * 3 * 365) / tvlUsd) * 100; + + const apyBase = aprToApy(aprBase, 52); + return [ + { + pool: SUSDU, + symbol: 'sUSDu', + project: 'unitas', + chain: 'Solana', + tvlUsd, + apyBase, + }, + ]; +} + +module.exports = { + apy, + url: "https://app.unitas.so/dashboard/apy", +}; diff --git a/src/adaptors/uniwhale/index.js b/src/adaptors/uniwhale/index.js new file mode 100644 index 0000000000..677b248397 --- /dev/null +++ b/src/adaptors/uniwhale/index.js @@ -0,0 +1,42 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const USDT = '0x55d398326f99059fF775485246999027B3197955'; +const UNIWHALE_LIQUIDITY_POOL = '0xBdeCAFd9096D43616a8E0eB8F3fa0865fD4769E7'; + +const getApy = async (...args) => { + const tvl = await axios.post('https://bsc-dataseed1.binance.org/', { + method: 'eth_call', + params: [{ to: UNIWHALE_LIQUIDITY_POOL, data: '0xdd363371' }, 'latest'], + id: 1, + jsonrpc: '2.0', + }); + const apr = await axios.post('https://gql.uniwhale.co/v1/graphql', { + query: `query LatestTradeStats { + latest_trade_stats_7d { + apr_7d + } + }`, + operationName: 'LatestTradeStats', + variables: {}, + }); + return [ + { + chain: utils.formatChain('bsc'), + project: 'uniwhale', + pool: UNIWHALE_LIQUIDITY_POOL, + symbol: utils.formatSymbol('ULP'), + tvlUsd: parseInt(tvl.data.result.substring(2), 16) / 1e18, + apyBase: utils.aprToApy( + apr.data.data.latest_trade_stats_7d[0].apr_7d * 70 + ), + underlyingTokens: [UNIWHALE_LIQUIDITY_POOL], + url: 'https://app.uniwhale.co/liquidity', + }, + ]; +}; + +module.exports = { + apy: getApy, + url: 'https://app.uniwhale.co/earn', +}; diff --git a/src/adaptors/unizen/abis.js b/src/adaptors/unizen/abis.js new file mode 100644 index 0000000000..8daef70db9 --- /dev/null +++ b/src/adaptors/unizen/abis.js @@ -0,0 +1,1994 @@ +module.exports = { + ethABI: [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newTokenAddress", + "type": "address" + } + ], + "name": "MembershipTokenUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "canReceiveRewards", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimAllRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "claimReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IUZV1RewardPool[]", + "name": "pools", + "type": "address[]" + } + ], + "name": "claimRewardsFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint8", + "name": "poolType", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "blockchain", + "type": "string" + }, + { + "internalType": "string", + "name": "cAddress", + "type": "string" + } + ], + "name": "createNewPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "emergencyWithdrawTokenFromRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "contract IUZV1Factory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllPools", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokenList", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "tokenTVLs", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "weights", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "combinedWeight", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_blocknumber", + "type": "uint256" + } + ], + "name": "getAllTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokenList", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "tokenTVLs", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "weights", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "combinedWeight", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getAllUserRewards", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getAmountOfOpenRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "components": [ + { + "internalType": "enum SharedDataTypes.PoolState", + "name": "state", + "type": "uint8" + }, + { + "components": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "blockchain", + "type": "string" + }, + { + "internalType": "string", + "name": "cAddress", + "type": "string" + } + ], + "internalType": "struct SharedDataTypes.PoolInfo", + "name": "info", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "paymentStartBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "paymentEndBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "distributionStartBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "distributionEndBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardsPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardTokenPrice", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "poolType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "paymentToken", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardPool", + "type": "address" + } + ], + "internalType": "struct SharedDataTypes.PoolData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getPoolStakerUser", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "totalSavedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPurchasedAllocation", + "type": "uint256" + }, + { + "internalType": "string", + "name": "nativeAddress", + "type": "string" + }, + { + "internalType": "uint256", + "name": "claimedTime", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "claimedBlocks", + "type": "uint256[]" + } + ], + "internalType": "struct SharedDataTypes.PoolStakerUser[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolState", + "outputs": [ + { + "internalType": "enum SharedDataTypes.PoolState", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getPoolType", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getPoolUserInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "pendingRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPurchasedAllocation", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSavedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimedTime", + "type": "uint256" + }, + { + "internalType": "enum SharedDataTypes.PoolState", + "name": "state", + "type": "uint8" + }, + { + "internalType": "enum SharedDataTypes.UserPoolState", + "name": "userState", + "type": "uint8" + } + ], + "internalType": "struct SharedDataTypes.FlatPoolStakerUser", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getPoolUserReceiverAddress", + "outputs": [ + { + "internalType": "string", + "name": "receiverAddress", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getStakingUserData", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTVLs", + "outputs": [ + { + "internalType": "uint256[]", + "name": "_tokenTVLs", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getTimeWindows", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTokenWeights", + "outputs": [ + { + "internalType": "uint256[]", + "name": "weights", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "combinedWeight", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalPriceForPurchaseableTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "getUserPoolState", + "outputs": [ + { + "internalType": "enum SharedDataTypes.UserPoolState", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_blocknumber", + "type": "uint256" + } + ], + "name": "getUserStakes", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getUserStakes", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_endBlock", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_claimedBlocks", + "type": "uint256[]" + } + ], + "name": "getUserStakesSnapshots", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startTVL", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTVL", + "type": "uint256" + } + ], + "internalType": "struct SharedDataTypes.StakeSnapshot[]", + "name": "snapshots", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_precision", + "type": "uint256" + } + ], + "name": "getUserTVLShare", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getUsersStakedAmountOfToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_staking", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + } + ], + "name": "isPoolNative", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "membershipToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_receiver", + "type": "string" + } + ], + "name": "payRewardAndSetNativeAddressForPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "payRewardPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + } + ], + "name": "setFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newToken", + "type": "address" + } + ], + "name": "setMembershipToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "string", + "name": "_receiver", + "type": "string" + } + ], + "name": "setNativeAddressForPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_staking", + "type": "address" + } + ], + "name": "setStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "contract IUZV1Staking", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + polygonABI: [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newTokenAddress", + "type": "address" + } + ], + "name": "MembershipTokenUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardsToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardsToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isNative", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_isPurchaseable", + "type": "bool" + }, + { + "internalType": "string", + "name": "_tokenName", + "type": "string" + } + ], + "name": "addReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "balanceHolderTokenOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "getRewardForDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "getRewardTokenState", + "outputs": [ + { + "internalType": "enum SharedDataTypes.PoolState", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "membershipToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_reward", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_tokenAmount", + "type": "uint256" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardData", + "outputs": [ + { + "internalType": "uint256", + "name": "rewardsDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodStart", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isNative", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPurchaseable", + "type": "bool" + }, + { + "internalType": "string", + "name": "tokenName", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "savedRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newToken", + "type": "address" + } + ], + "name": "setMembershipToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newRouter", + "type": "address" + } + ], + "name": "setRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingHolderToken", + "type": "address" + } + ], + "name": "setStakingHolderToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rewardsToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_tokenName", + "type": "string" + } + ], + "name": "setTokenName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingHolderToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalHolderTokenSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + \ No newline at end of file diff --git a/src/adaptors/unizen/index.js b/src/adaptors/unizen/index.js new file mode 100644 index 0000000000..e14ae1e53a --- /dev/null +++ b/src/adaptors/unizen/index.js @@ -0,0 +1,59 @@ +const axios = require('axios'); +const utils = require('../utils'); +const BigNumber = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { ethABI, polygonABI } = require('./abis'); +const API_URL = 'https://api.zcx.com/private/apr/current'; +const ZCX = '0xc52c326331e9ce41f04484d3b5e5648158028804'; +const polygonStakingAddr = '0x078f188810ad3F2506a4FD76a982F281f4df15F2'; + +async function getTvl() { + const totalStakedETH = ( + await sdk.api.abi.call({ + abi: ethABI.find((a) => a.name === 'getTVLs'), + chain: 'ethereum', + target: '0x57A34b17F859D92B7D5aAf03748C7A280cFbE521', + params: [], + }) + ).output[0]; + + const totalStakedPolygon = ( + await sdk.api.abi.call({ + abi: polygonABI.find((a) => a.name === 'totalSupply'), + chain: 'polygon', + target: '0x078f188810ad3F2506a4FD76a982F281f4df15F2', + params: [], + }) + ).output; + const tvlETH = new BigNumber(totalStakedETH); + const tvlPolygon = new BigNumber(totalStakedPolygon); + const tvl = tvlETH.plus(tvlPolygon); + return tvl; + } + + + +const getApy = async () => { + const data = await utils.getData(API_URL); + const tvl = await getTvl(); + const price = (await utils.getPrices([ZCX], 'ethereum')).pricesByAddress; + const poolInfos = data.items; + let rewardTokens = [] + poolInfos.filter(e => e.totalApr !== '0').map((item) => { + rewardTokens.push(item.token) + }); + return [{ + pool: polygonStakingAddr, + chain: utils.formatChain('polygon'), + project: 'unizen', + symbol: 'ZCX', + tvlUsd: Number(tvl) * price[ZCX] / 1e18, + apyReward: data.apr, + rewardTokens: rewardTokens + }] +} + +module.exports = { + apy: getApy, + url: 'https://zcx.com/earn', +}; diff --git a/src/adaptors/unknown/index.js b/src/adaptors/unknown/index.js new file mode 100644 index 0000000000..5cb2d21187 --- /dev/null +++ b/src/adaptors/unknown/index.js @@ -0,0 +1,28 @@ +const utils = require('../utils'); + +const API_URL = 'https://api.unknown.money/pools'; + +const getApy = async () => { + const poolInfos = await utils.getData(API_URL); + const pools = poolInfos.filter(e => e.totalApr !== 'N/A').map((item) => { + return { + pool: item.id, + chain: utils.formatChain('binance'), + project: 'unknown', + symbol: item.poolData.symbol + .replaceAll('vAMM-', '') + .replaceAll('sAMM-', '') + .split('/').join('-'), + tvlUsd: Number(item.totalTvlUsd), + apyReward: Number(item.totalApr), + rewardTokens: item.rewardTokens.map(e => e.id), + }; + }); + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.unknown.money/', +}; diff --git a/src/adaptors/unsheth/DarknetABI.js b/src/adaptors/unsheth/DarknetABI.js new file mode 100644 index 0000000000..c20b02757a --- /dev/null +++ b/src/adaptors/unsheth/DarknetABI.js @@ -0,0 +1,37 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address[]", + "name": "_lsds", + "type": "address[]" + }, + { + "internalType": "bytes4[]", + "name": "_links", + "type": "bytes4[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "lsd", + "type": "address" + } + ], + "name": "checkPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/unsheth/FarmABI.js b/src/adaptors/unsheth/FarmABI.js new file mode 100644 index 0000000000..71cb8117c3 --- /dev/null +++ b/src/adaptors/unsheth/FarmABI.js @@ -0,0 +1,1018 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "string[]", + "name": "_rewardSymbols", + "type": "string[]" + }, + { + "internalType": "address[]", + "name": "_rewardTokens", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "_rewardManagers", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_rewardRates", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "LockedStakeMaxMultiplierUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "secs", + "type": "uint256" + } + ], + "name": "LockedStakeMinTime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "secs", + "type": "uint256" + } + ], + "name": "LockedStakeTimeForMaxMultiplier", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerNominated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "destination_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "token_address", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "destination_address", + "type": "address" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "RewardsPeriodRenewed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "secs", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "kek_id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "source_address", + "type": "address" + } + ], + "name": "StakeLocked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "kek_id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "destination_address", + "type": "address" + } + ], + "name": "WithdrawLocked", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "calcCurCombinedWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "old_combined_weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "new_combined_weight", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reward_token_address", + "type": "address" + }, + { + "internalType": "address", + "name": "new_manager_address", + "type": "address" + } + ], + "name": "changeTokenManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "combinedWeightOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256[]", + "name": "new_earned", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllRewardRates", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllRewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardForDuration", + "outputs": [ + { + "internalType": "uint256[]", + "name": "rewards_per_duration_arr", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardSymbols", + "outputs": [ + { + "internalType": "string[]", + "name": "", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "greylist", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "greylistAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller_addr", + "type": "address" + }, + { + "internalType": "address", + "name": "reward_token_addr", + "type": "address" + } + ], + "name": "isTokenManagerFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "secs", + "type": "uint256" + } + ], + "name": "lockMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lock_max_multiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lock_time_for_max_multiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lock_time_min", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "lockedLiquidityOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "lockedStakesOf", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "kek_id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "start_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "ending_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lock_multiplier", + "type": "uint256" + } + ], + "internalType": "struct CommunalFarm.LockedStake[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "nominateNewOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nominatedOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmount", + "type": "uint256" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardManagers", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardRates", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardSymbols", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAddrToIdx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsCollectionPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerToken", + "outputs": [ + { + "internalType": "uint256[]", + "name": "newRewardsPerTokenStored", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lock_time_for_max_multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lock_time_min", + "type": "uint256" + } + ], + "name": "setLockedStakeTimeForMinAndMaxMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lock_max_multiplier", + "type": "uint256" + } + ], + "name": "setMultipliers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "reward_token_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "new_rate", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "sync_too", + "type": "bool" + } + ], + "name": "setRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + } + ], + "name": "setRewardsDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "secs", + "type": "uint256" + } + ], + "name": "stakeLocked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakesUnlocked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toggleRewardsCollection", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toggleStaking", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toggleWithdrawals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalCombinedWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalLiquidityLocked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unlockStakes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "kek_id", + "type": "bytes32" + } + ], + "name": "withdrawLocked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/adaptors/unsheth/LSDVaultABI.js b/src/adaptors/unsheth/LSDVaultABI.js new file mode 100644 index 0000000000..8a10d462c5 --- /dev/null +++ b/src/adaptors/unsheth/LSDVaultABI.js @@ -0,0 +1 @@ +module.exports = [{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_darknetAddress","type":"address"},{"internalType":"address","name":"_unshethAddress","type":"address"},{"internalType":"address[]","name":"_lsds","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"useAbsoluteCaps","type":"bool"}],"name":"AbsoluteCapsToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"DepositPauseToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"includeV1Assets","type":"bool"}],"name":"IncludeV1VaultAssetsToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lsd","type":"address"}],"name":"LSDAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lsd","type":"address"},{"components":[{"internalType":"uint256","name":"targetWeightBps","type":"uint256"},{"internalType":"uint256","name":"weightCapBps","type":"uint256"},{"internalType":"uint256","name":"absoluteCapEth","type":"uint256"}],"indexed":false,"internalType":"struct LSDVault.LSDConfig","name":"config","type":"tuple"}],"name":"LSDConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lsd","type":"address"}],"name":"LSDDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lsd","type":"address"}],"name":"LSDEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"redeemFee","type":"uint256"}],"name":"RedeemFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"ShanghaiTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum LSDVault.TimelockFunctions","name":"_fn","type":"uint8"}],"name":"TimelockUpdateCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum LSDVault.TimelockFunctions","name":"_fn","type":"uint8"}],"name":"TimelockUpdateCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum LSDVault.TimelockFunctions","name":"_fn","type":"uint8"},{"indexed":false,"internalType":"address","name":"_newAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_unlockTime","type":"uint256"}],"name":"TimelockUpdateProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"unshethAddress","type":"address"}],"name":"UnshethAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"unshethZapAddress","type":"address"}],"name":"UnshethZapAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapper","type":"address"}],"name":"VdAmmDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"useWeightCaps","type":"bool"}],"name":"WeightCapsToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawalUnpauseTime","type":"uint256"}],"name":"WithdrawalsPaused","type":"event"},{"anonymous":false,"inputs":[],"name":"WithdrawalsUnpaused","type":"event"},{"inputs":[],"name":"_TIMELOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lsd","type":"address"}],"name":"addLSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ammEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceInUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum LSDVault.TimelockFunctions","name":"_fn","type":"uint8"}],"name":"cancelTimelockProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum LSDVault.TimelockFunctions","name":"_fn","type":"uint8"},{"internalType":"address","name":"_proposedAddress","type":"address"}],"name":"createTimelockProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"darknetAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[4]","name":"amounts","type":"uint256[4]"}],"name":"depositMultipleNoCapCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositNoCapCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_lsd","type":"address"}],"name":"disableLSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableVdAmm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAllLSDs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lsd","type":"address"}],"name":"enableLSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"getAbsoluteCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"getCombinedVaultBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDeposit","type":"uint256"}],"name":"getEffectiveCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"getEthConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"getLsdIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDeposit","type":"uint256"}],"name":"getTargetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDeposit","type":"uint256"}],"name":"getWeightCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"includeV1VaultAssets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"}],"name":"isLsdEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lsdConfigs","outputs":[{"internalType":"uint256","name":"targetWeightBps","type":"uint256"},{"internalType":"uint256","name":"weightCapBps","type":"uint256"},{"internalType":"uint256","name":"absoluteCapEth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lsdIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unpauseTime","type":"uint256"}],"name":"pauseWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDeposit","type":"uint256"}],"name":"remainingRoomToCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDepositEth","type":"uint256"}],"name":"remainingRoomToCapInEthTerms","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDeposit","type":"uint256"}],"name":"remainingRoomToTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lsd","type":"address"},{"internalType":"uint256","name":"marginalDepositEth","type":"uint256"}],"name":"remainingRoomToTargetInEthTerms","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lsd","type":"address"},{"internalType":"uint256","name":"_targetWeightBps","type":"uint256"},{"internalType":"uint256","name":"_maxWeightBps","type":"uint256"},{"internalType":"uint256","name":"_maxEthCap","type":"uint256"}],"name":"setLSDConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_redeemFee","type":"uint256"}],"name":"setRedeemFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_unshethZapAddress","type":"address"}],"name":"setUnshethZap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setVdAmm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shanghaiTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedETHperunshETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportedLSDs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapperAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum LSDVault.TimelockFunctions","name":"","type":"uint8"}],"name":"timelock","outputs":[{"internalType":"address","name":"proposedAddress","type":"address"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleAbsoluteCaps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleV1VaultAssetsForCaps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleWeightCaps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unshETHAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unshethZapAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateDarknetAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTime","type":"uint256"}],"name":"updateShanghaiTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateUnshethZapAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"useAbsoluteCaps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useWeightCaps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v1VaultAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalUnpauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/unsheth/bnb-unsheth-farm.js b/src/adaptors/unsheth/bnb-unsheth-farm.js new file mode 100644 index 0000000000..e1d26918be --- /dev/null +++ b/src/adaptors/unsheth/bnb-unsheth-farm.js @@ -0,0 +1,194 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const contract_addresses = require('./contract_addresses'); +const cbETHAdaptor = require('../coinbase-wrapped-staked-eth'); +const darknetABI = require('./DarknetABI'); +const lsdVaultABI = require('./LSDVaultABI'); +const farmABI = require('./FarmABI'); +const utils = require('../utils'); +const { seconds_per_year, denomination, tokensToCheck, BINANCE_RPC_URL } = require('./constants'); + +const getPoolInfo = async () => { + try { + let apyBase = await getWeightedApr(); + let tvlUsd = await getTVLUSD(); + + let usdRewardPerYear = await getUSDRewardPerYear(); + let apyReward = parseFloat(parseFloat(usdRewardPerYear / tvlUsd * 100).toFixed(2)); + + return { + pool: `${contract_addresses['BNBunshETH-farm']}-${utils.formatChain('binance')}`, + chain: utils.formatChain('binance'), + project: 'unsheth', + symbol: 'unshETH', + tvlUsd, + apyBase, + apyReward, + rewardTokens: [contract_addresses.BNBUSH], + underlyingTokens: [contract_addresses.BNBETH] + } + } + catch (e) { + console.log(e); + throw new Error(e); + } +}; + +async function getUSDRewardPerYear(){ + + let provider = new ethers.providers.JsonRpcProvider(BINANCE_RPC_URL); + let farmContract = new ethers.Contract(contract_addresses["BNBunshETH-farm"], farmABI, provider); + let baseRewardsPerSecond = (await farmContract.getAllRewardRates())[0]; + + let rewardsPerSecond = (parseFloat(baseRewardsPerSecond)/denomination) + + let rewardsPerYear = rewardsPerSecond * seconds_per_year; + + let priceKey = `coingecko:unsheth`; + let USHPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + + let USDRewardPerYear = USHPrice * parseFloat(rewardsPerYear); + + return USDRewardPerYear; +} + +async function getTVLUSD(){ + const priceKey = `ethereum:${contract_addresses.WETH}`; + const ethPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + let darknetRates = await getDarknetRates(); + + let lsdVaultTokenBalances = await getLSDVaultTokenBalances(); + + let lsdPrices = await getLSDPrices(); + + let lsdVaultUSDBalances = { + sfrxETH: parseFloat(lsdVaultTokenBalances.sfrxETH)/denomination * lsdPrices.sfrxETH, + cbETH: parseFloat(lsdVaultTokenBalances.cbETH)/denomination * lsdPrices.cbETH, + rETH: parseFloat(lsdVaultTokenBalances.rETH)/denomination * lsdPrices.rETH, + wstETH: parseFloat(lsdVaultTokenBalances.wstETH)/denomination * lsdPrices.wstETH + } + + let totalUsdBalance = 0; + for (const [key, value] of Object.entries(lsdVaultUSDBalances)) { + totalUsdBalance += value; + } + + let percentageOfUnshETHInFarm = await getPercentageOfUnshethInFarm(); + + return totalUsdBalance*percentageOfUnshETHInFarm; +} + +async function getLSDPrices() { + const coingeckoIds = { + sfrxETH: 'staked-frax-ether', + rETH: 'rocket-pool-eth', + wstETH: 'staked-ether', + cbETH: 'coinbase-wrapped-staked-eth', + }; + + let prices = { + sfrxETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.sfrxETH}`)).data.coins[`coingecko:${coingeckoIds.sfrxETH}`]?.price, + rETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.rETH}`)).data.coins[`coingecko:${coingeckoIds.rETH}`]?.price, + wstETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.wstETH}`)).data.coins[`coingecko:${coingeckoIds.wstETH}`]?.price, + cbETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.cbETH}`)).data.coins[`coingecko:${coingeckoIds.cbETH}`]?.price, + } + + return prices +} + +async function getPercentageOfUnshethInFarm(){ + + + let provider = new ethers.providers.JsonRpcProvider(BINANCE_RPC_URL); + let eth_provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + + const erc20Abi = [ + "function balanceOf(address account) view returns (uint256)", + "function totalSupply() view returns (uint256)" + ]; + + let BNBunshETHContract = new ethers.Contract(contract_addresses.BNBunshETH, erc20Abi, provider); + let BNBunshETHFarmBalance = await BNBunshETHContract.balanceOf(contract_addresses['BNBunshETH-farm']); + + let unshETHContract = new ethers.Contract(contract_addresses.unshETH, erc20Abi, eth_provider); + let unshETHTotalSupply = await unshETHContract.totalSupply(); + + let percentageOfUnshETHInFarm = parseFloat(BNBunshETHFarmBalance)/parseFloat(unshETHTotalSupply); + + return percentageOfUnshETHInFarm; +} + +async function getWeightedApr(){ + + let underlyingAPR = { + sfrxETH: (await axios.get('https://api.frax.finance/v2/frxeth/summary/latest')).data.sfrxethApr, + cbETH: (await cbETHAdaptor.apy())[0].apyBase, + rETH: parseFloat((await axios.get('https://api.rocketpool.net/api/apr')).data.yearlyAPR), + wstETH: parseFloat((await axios.get('https://stake.lido.fi/api/sma-steth-apr')).data.data.smaApr) + } + + let darknetRates = await getDarknetRates(); + + let lsdVaultTokenBalances = await getLSDVaultTokenBalances(); + + let lsdVaultEthBalances = { + sfrxETH: parseFloat(lsdVaultTokenBalances.sfrxETH)/denomination * parseFloat(darknetRates.sfrxETH)/denomination, + cbETH: parseFloat(lsdVaultTokenBalances.cbETH)/denomination * parseFloat(darknetRates.cbETH)/denomination, + rETH: parseFloat(lsdVaultTokenBalances.rETH)/denomination * parseFloat(darknetRates.rETH)/denomination, + wstETH: parseFloat(lsdVaultTokenBalances.wstETH)/denomination * parseFloat(darknetRates.wstETH)/denomination + } + + let totalEthBalance = 0; + for (let lsd in lsdVaultEthBalances) { + totalEthBalance += lsdVaultEthBalances[lsd]; + } + let lsdVaultWeights = { + sfrxETH: lsdVaultEthBalances.sfrxETH/totalEthBalance, + cbETH: lsdVaultEthBalances.cbETH/totalEthBalance, + rETH: lsdVaultEthBalances.rETH/totalEthBalance, + wstETH: lsdVaultEthBalances.wstETH/totalEthBalance + } + + let weightedApr = 0; + for (let lsd in lsdVaultWeights) { + weightedApr += underlyingAPR[lsd] * lsdVaultWeights[lsd]; + } + + return weightedApr; +} + +async function getDarknetRates() { + const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + let darknet = new ethers.Contract(contract_addresses.darknet, darknetABI, provider); + let darknetRates = { + sfrxETH: await darknet.checkPrice(...[contract_addresses.sfrxETH]), + cbETH: await darknet.checkPrice(...[contract_addresses.cbETH]), + rETH: await darknet.checkPrice(...[contract_addresses.rETH]), + wstETH: await darknet.checkPrice(...[contract_addresses.wstETH]) + } + + return darknetRates; +} + +async function getLSDVaultTokenBalances() { + const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + const balances = {}; + const erc20Abi = [ + "function balanceOf(address account) view returns (uint256)" + ]; + + for (const tokenKey of tokensToCheck) { + const tokenAddress = contract_addresses[tokenKey]; + const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, provider); + balances[tokenKey] = await tokenContract.balanceOf(contract_addresses.LSDVault); + } + + return balances; +} + +module.exports = { + getPoolInfo +}; + diff --git a/src/adaptors/unsheth/constants.js b/src/adaptors/unsheth/constants.js new file mode 100644 index 0000000000..5dd6356766 --- /dev/null +++ b/src/adaptors/unsheth/constants.js @@ -0,0 +1,44 @@ +const sdk = require('@defillama/sdk'); +try { + require('dotenv').config({ path: './config.env' }); +} catch (e) {} + +const seconds_per_year = 60 * 60 * 24 * 365.25; +const denomination = 1e18; +const coingeckoIds = { + sfrxETH: 'staked-frax-ether', + rETH: 'rocket-pool-eth', + wstETH: 'staked-ether', + cbETH: 'coinbase-wrapped-staked-eth', +}; + + +const tokensToCheck = [ +"sfrxETH", +"rETH", +"wstETH", +"cbETH" +]; + +const ETHEREUM_RPC_URL = process.env.ALCHEMY_CONNECTION_ETHEREUM; +const BINANCE_RPC_URL = "https://bsc-dataseed.binance.org/"; +const sushiSwapSubgraphUrl = sdk.graph.modifyEndpoint('6NUtT5mGjZ1tSshKLf5Q3uEEJtjBZJo1TpL5MXsUBqrT'); +const pancakeSwapSubgraphUrl = "https://data-platform.nodereal.io/graph/v1/a1db26ba19064757ac7f991b9383402d/projects/pancakeswap"; +const BLOCK_TIME_SECONDS = 12; // Approximate block time in seconds +const BNB_BLOCK_TIME_SECONDS = 3; +const feeRate = 0.003; // Sushi Swap Pool Fee + +module.exports = { + ETHEREUM_RPC_URL, + BNB_BLOCK_TIME_SECONDS, + pancakeSwapSubgraphUrl, + sushiSwapSubgraphUrl, + BLOCK_TIME_SECONDS, + feeRate, + BINANCE_RPC_URL, + tokensToCheck, + seconds_per_year, + coingeckoIds, + denomination +} + diff --git a/src/adaptors/unsheth/contract_addresses.js b/src/adaptors/unsheth/contract_addresses.js new file mode 100644 index 0000000000..2df059f119 --- /dev/null +++ b/src/adaptors/unsheth/contract_addresses.js @@ -0,0 +1,70 @@ +module.exports = { + "darknet": "0xe8ef2e07e2fca3305372cb0345c686efbec75658", + "darknetV1": "0xe8ef2e07e2fca3305372cb0345c686efbec75658", + + "LSDRegistry":"", + "LSDRegistryV1":"0xA857904691bbdEca2e768B318B5f6b9bfA698b7C", + + "LSDVault": "0x51A80238B5738725128d3a3e06Ab41c1d4C05C74", + "LSDVaultV1": "0xE76Ffee8722c21b390eebe71b67D95602f58237F", + + "unshETHV1": "0x846982C0a47b0e9f4c13F3251ba972Bb8D32a8cA", + "unshETH": "0x0Ae38f7E10A43B5b2fB064B42a2f4514cbA909ef", + "unshETHProxy":"0x35f899CE6cC304AeDFDB7835f623A30473b26457", + + "USH": "0xe60779cc1b2c1d0580611c526a8df0e3f870ec48", + "USHProxy":"0xA8b326Ca02650Ac968C554d6C534412e49c92BC4", + + "USH-farm": "0xf728dB9182e7c3a9dFfbD71f9506d04f129Ac9C8", + + "unshETH-farm":"0x33890B88F98a9D511678954AD8DB0510B6953Cfc", + "unshETH-farmV1":"0x954d5088d88291146ce58270add820e809ff3d7e", + + "sushi-farm": "0x5153b553d8ae3cbbb5ac97f5e4c8e5776d30ee09", + + "claim": "0x2955c9cba43e769017caf257dd96c0dd9d79bd3a", + + "frxETH":"0xbafa44efe7901e04e39dad13167d089c559c1138", + "sfrxETH": "0xac3e018457b222d93114458476f3e3416abbe38f", + "rETH": "0xae78736cd615f374d3085123a210448e74fc6393", + "wstETH":"0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", + + "cbETH": "0xbe9895146f7af43049ca1c1ae358b0541ea49704", + "WETH":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "rETHRouter":"0x16D5A408e807db8eF7c578279BEeEe6b228f1c1C", + + "USDT": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + + "univ3quoter":"0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + + "sushiSwapLP": "0xAAF448d30F01b429FB6e7F9AF6A8FF66e694F312", + + "unshETHZap": "0x7461092AA5234b42A17ee8Cc51CfDE6Ef4BeCbc7" , + "unshETHZapV1":"0x718C26E5e60829a36feE8DF1d791F340aaa91B4b", + + "WBNB": "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", + + "SGReceiver":"0xe3f2E5D41c49fE62a37725a8fF94A65e9a1A165C", + + "BNBStargateRouter":"0x4a364f8c717cAAD9A442737Eb7b8A55cc6cf18D8", + + "StargateRouter":"0x8731d54E9D02c286767d56ac03e8037C07e01e98", + + "BNBStargateFee":"0xCa46058a5682B13c44F4Dd2558aFDEbf3A28f41f", + + "BNBETH":"0x2170ed0880ac9a755fd29b2688956bd959f933f8", + "BNBUSDT":"0x55d398326f99059ff775485246999027b3197955", + + "BNBunshETH":"0x0Ae38f7E10A43B5b2fB064B42a2f4514cbA909ef", + "BNBUSH":"0x91d6d6aF7635B7b23A8CED9508117965180e2362", + + "BNBSGSender":"0x51A80238B5738725128d3a3e06Ab41c1d4C05C74", + + "BNBPancakeSwapRouter":"0x10ED43C718714eb63d5aA57B78B54704E256024E", //Update + + "BNBpancake-farm":"0x73F3BF38C6bdBc69042049c022080D14885Ff32D", //Update + "BNBUSH-farm":"0xa974c41748e8464Baf978e3268CDdb0d6A1fdBDA", //Update + "BNBunshETH-farm":"0x2C8a4058DB744808FFFA97E29c8E1b7cBF7AAd01", //Update + "BNBpancakeSwapLP":"0xC9C33A4Aa8fb9F50579EE4d89Fb8a45EECCD6f0a" //Update +} + diff --git a/src/adaptors/unsheth/index.js b/src/adaptors/unsheth/index.js new file mode 100644 index 0000000000..0f64bf5cbf --- /dev/null +++ b/src/adaptors/unsheth/index.js @@ -0,0 +1,44 @@ +const unshETHFarm = require('./unsheth-farm'); +const BNBunshETHFarm = require('./bnb-unsheth-farm'); +const sushiFarm = require('./ush-weth-sushi'); +const pancakeFarm = require('./ush-bnb-pancake'); + +//TODO: Notes for llama team: +// We calculate the yield for unshETH staking farms +// 1) We are calculating the base APR of unshETH based on the weighted average of the underlying LSD APR. +// -- For each of the underlying LSDs, we use their official API to pull their APR, except for cbETH +// -- For cbETH we use the DefiLlama calculation and import it directly since there's no official API (pls let us know if this is ok) +// 2) We are calculating the farm APR for unshETH based on the USH emissions +// . +// We are also including the yield for USH-WETH and USH-WBNB LPs on Sushi and PancakeSwap. These are pool2 yields: +// 1) For the base APR based on trading volume, we're pulling using Sushi and Pancakeswap APIs +// -- For the PancakeSwap API, we're using the NodeReal subgraph URL as used in official PancakeSwap repo. If there's a official Defillama API Key, pls let us know how to include it (we included a free API key) +// -- Maybe we weren't looking properly, but we didn't see any Pancakeswap pool2 in the yield section? +// 2) Farm APR is based on the USH emissions +// . +// How do we get properly listed with the right attributes on Defillama? +// 1) We would like to represent unshETH as a single-sided ETH staking yield with no IL. +// -- For unshETH on ETH Mainnet, the underlying asset is mainnet ETH. For the adapter, we said it is WETH (which is how cbETH adapter does it) +// -- For BNB Chain, the underlying asset is technically still mainnet ETH. For the adapter, we said it is Binance-pegged ETH +// 2) We are an audited farm. Audit link is: https://unsheth.xyz/v2-audit.pdf +// . +// Please reach out to wagmi33 on twitter or wagmi@unsheth.xyz if you have any questions + +const getApy = async () => { + const promises = [ + unshETHFarm.getPoolInfo(), + BNBunshETHFarm.getPoolInfo(), + sushiFarm.getPoolInfo(), + pancakeFarm.getPoolInfo(), + ]; + + const results = await Promise.allSettled(promises); + + return results.filter((i) => i.status === 'fulfilled').map((i) => i.value); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://unsheth.xyz', +}; diff --git a/src/adaptors/unsheth/pancakeBaseAPR.js b/src/adaptors/unsheth/pancakeBaseAPR.js new file mode 100644 index 0000000000..8764687851 --- /dev/null +++ b/src/adaptors/unsheth/pancakeBaseAPR.js @@ -0,0 +1,155 @@ +const ethers = require('ethers'); +const {pancakeSwapSubgraphUrl, BNB_BLOCK_TIME_SECONDS, feeRate, BINANCE_RPC_URL} = require('./constants'); +const contract_addresses = require('./contract_addresses'); +const axios = require('axios'); +const fetch = require('node-fetch'); + +async function getBlockNumberOf24HoursAgo(providerUrl) { + const provider = new ethers.providers.JsonRpcProvider(providerUrl); + + // Get the current block number + const currentBlockNumber = await provider.getBlockNumber(); + + // Estimate the number of blocks in the past 24 hours + const blocksIn24Hours = Math.floor(24 * 60 * 60 / BNB_BLOCK_TIME_SECONDS); + + // Get the block number of approximately 24 hours ago + let approxBlockNumber = currentBlockNumber - blocksIn24Hours; + + return approxBlockNumber; + } + + async function get24HourTradingVolume(pairAddress, providerUrl) { + const blockNumberOneDayAgo = await getBlockNumberOf24HoursAgo(providerUrl); + + const query = ` + { + pair(id: "${pairAddress.toLowerCase()}", block: { number: ${blockNumberOneDayAgo} }) { + volumeUSD + } + } + `; + + const response = await fetch(pancakeSwapSubgraphUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query }), + }); + + const data = await response.json(); + const previousVolumeUSD = parseFloat(data.data.pair?.volumeUSD || 0); + + const queryCurrent = ` + { + pair(id: "${pairAddress.toLowerCase()}") { + volumeUSD + } + } + `; + + const responseCurrent = await fetch(pancakeSwapSubgraphUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query: queryCurrent }), + }); + + const dataCurrent = await responseCurrent.json(); + const currentVolumeUSD = parseFloat(dataCurrent.data.pair?.volumeUSD || 0); + + // Calculate the 24-hour trading volume + const volume24h = currentVolumeUSD - previousVolumeUSD; + + return volume24h; + } + +async function getTotalValueInUSD(pairAddress) { + // Query the reserves and token data from the PancakeSwap Subgraph + const query = ` + { + pair(id: "${pairAddress.toLowerCase()}") { + reserve0 + reserve1 + token0 { + symbol + derivedBNB + } + token1 { + symbol + derivedBNB + } + } + } + `; + + const response = await fetch(pancakeSwapSubgraphUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query }), + }); + + const data = await response.json(); + const pairData = data.data.pair; + + if (!pairData) { + return null; + } + + // Get the reserves of each token + const reserve0 = parseFloat(pairData.reserve0); + const reserve1 = parseFloat(pairData.reserve1); + + // Get the prices of each token in BNB + const price0InBNB = parseFloat(pairData.token0.derivedBNB); + const price1InBNB = parseFloat(pairData.token1.derivedBNB); + + // Get the price of BNB in USD + const priceKey = `coingecko:binancecoin`; + const ethPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + // Calculate the total value of the liquidity pool's reserves in USD + const totalValueInUSD = + (reserve0 * price0InBNB + reserve1 * price1InBNB) * ethPrice; + + return totalValueInUSD; +} + +async function calculateTotalAPRPancake(pairAddress, providerUrl) { + const volume24h = await get24HourTradingVolume(pairAddress, providerUrl); + + // Calculate the total value of the liquidity pool's reserves in USD + const totalValueInUSD = await getTotalValueInUSD(pairAddress, providerUrl); + + if (totalValueInUSD === null) { + return "Unable to calculate the total value in USD. Please check the pair address and try again."; + } + + // Calculate the trading fees APR based on the 24-hour volume and total liquidity in USD + + const feesIn24Hours = (volume24h * feeRate); + + const feesInYear = feesIn24Hours * 365; + + const tradingFeesAPR = (feesInYear / totalValueInUSD) * 100; + + const totalAPR = tradingFeesAPR; //+ pancakeRewardsAPR; + + return totalAPR; +} + + +async function getLatestAPRPancake() { + try { + const pairAddress = contract_addresses.BNBpancakeSwapLP; + const providerUrl = BINANCE_RPC_URL; + + const totalAPR = await calculateTotalAPRPancake(pairAddress, providerUrl); + return totalAPR; + } + catch(err){ + console.log(err); + } +} + +module.exports = { + getLatestAPRPancake, +}; \ No newline at end of file diff --git a/src/adaptors/unsheth/sushiBaseAPR.js b/src/adaptors/unsheth/sushiBaseAPR.js new file mode 100644 index 0000000000..f77e804f31 --- /dev/null +++ b/src/adaptors/unsheth/sushiBaseAPR.js @@ -0,0 +1,155 @@ +const ethers = require('ethers'); +const {sushiSwapSubgraphUrl, BLOCK_TIME_SECONDS, feeRate, ETHEREUM_RPC_URL} = require('./constants'); +const contract_addresses = require('./contract_addresses'); +const axios = require('axios'); +const fetch = require('node-fetch'); + +async function getBlockNumberOf24HoursAgo(providerUrl) { + const provider = new ethers.providers.JsonRpcProvider(providerUrl); + + // Get the current block number + const currentBlockNumber = await provider.getBlockNumber(); + + // Estimate the number of blocks in the past 24 hours + const blocksIn24Hours = Math.floor(24 * 60 * 60 / BLOCK_TIME_SECONDS); + + // Get the block number of approximately 24 hours ago + let approxBlockNumber = currentBlockNumber - blocksIn24Hours; + + return approxBlockNumber; + } + + async function get24HourTradingVolume(pairAddress, providerUrl) { + const blockNumberOneDayAgo = await getBlockNumberOf24HoursAgo(providerUrl); + + const query = ` + { + pair(id: "${pairAddress.toLowerCase()}", block: { number: ${blockNumberOneDayAgo} }) { + volumeUSD + } + } + `; + + const response = await fetch(sushiSwapSubgraphUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query }), + }); + + const data = await response.json(); + const previousVolumeUSD = parseFloat(data.data.pair?.volumeUSD || 0); + + const queryCurrent = ` + { + pair(id: "${pairAddress.toLowerCase()}") { + volumeUSD + } + } + `; + + const responseCurrent = await fetch(sushiSwapSubgraphUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query: queryCurrent }), + }); + + const dataCurrent = await responseCurrent.json(); + const currentVolumeUSD = parseFloat(dataCurrent.data.pair?.volumeUSD || 0); + + // Calculate the 24-hour trading volume + const volume24h = currentVolumeUSD - previousVolumeUSD; + return volume24h; + } + +async function getTotalValueInUSD(pairAddress) { + // Query the reserves and token data from the SushiSwap Subgraph + const query = ` + { + pair(id: "${pairAddress.toLowerCase()}") { + reserve0 + reserve1 + token0 { + symbol + derivedETH + } + token1 { + symbol + derivedETH + } + } + } + `; + + const response = await fetch(sushiSwapSubgraphUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query }), + }); + + const data = await response.json(); + const pairData = data.data.pair; + + if (!pairData) { + return null; + } + + // Get the reserves of each token + const reserve0 = parseFloat(pairData.reserve0); + const reserve1 = parseFloat(pairData.reserve1); + + // Get the prices of each token in ETH + const price0InETH = parseFloat(pairData.token0.derivedETH); + const price1InETH = parseFloat(pairData.token1.derivedETH); + + // Get the price of ETH in USD + const priceKey = `ethereum:${contract_addresses.WETH}`; + const ethPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + // Calculate the total value of the liquidity pool's reserves in USD + const totalValueInUSD = + (reserve0 * price0InETH + reserve1 * price1InETH) * ethPrice; + + return totalValueInUSD; +} + +async function calculateTotalAPRSushi(pairAddress, providerUrl) { + const volume24h = await get24HourTradingVolume(pairAddress, providerUrl); + + // Calculate the total value of the liquidity pool's reserves in USD + const totalValueInUSD = await getTotalValueInUSD(pairAddress, providerUrl); + + if (totalValueInUSD === null) { + return "Unable to calculate the total value in USD. Please check the pair address and try again."; + } + + // Calculate the trading fees APR based on the 24-hour volume and total liquidity in USD + + const feesIn24Hours = (volume24h * feeRate); + + const feesInYear = feesIn24Hours * 365; + + const tradingFeesAPR = (feesInYear / totalValueInUSD) * 100; + + const totalAPR = tradingFeesAPR; //+ sushiRewardsAPR; + + return totalAPR; +} + + +async function getLatestAPRSushi() { + try { + const pairAddress = contract_addresses.sushiSwapLP; + const providerUrl = ETHEREUM_RPC_URL; + + const totalAPR = await calculateTotalAPRSushi(pairAddress, providerUrl); + return totalAPR; + } + catch(err){ + console.log("here in sushi"); + console.log(err); + } +} + +module.exports = { + getLatestAPRSushi, +}; \ No newline at end of file diff --git a/src/adaptors/unsheth/unsheth-farm.js b/src/adaptors/unsheth/unsheth-farm.js new file mode 100644 index 0000000000..8d064f5652 --- /dev/null +++ b/src/adaptors/unsheth/unsheth-farm.js @@ -0,0 +1,184 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const contract_addresses = require('./contract_addresses'); +const cbETHAdaptor = require('../coinbase-wrapped-staked-eth'); +const darknetABI = require('./DarknetABI'); +const lsdVaultABI = require('./LSDVaultABI'); +const farmABI = require('./FarmABI'); +const { seconds_per_year, denomination, tokensToCheck, ETHEREUM_RPC_URL} = require('./constants'); +const utils = require('../utils'); + +const getPoolInfo = async () => { + let apyBase = await getWeightedApr(); + let tvlUsd = await getTVLUSD(); + + let usdRewardPerYear = await getUSDRewardPerYear(); + let apyReward = parseFloat(parseFloat(usdRewardPerYear / tvlUsd * 100).toFixed(2)); + + return { + pool: `${contract_addresses['unshETH-farm']}-${utils.formatChain('ethereum')}`, + chain: utils.formatChain('ethereum'), + project: 'unsheth', + symbol: 'unshETH', + tvlUsd, + apyBase, + apyReward, + rewardTokens: [contract_addresses.USH], + underlyingTokens: [contract_addresses.WETH] + } +}; + +async function getUSDRewardPerYear(){ + let provider = new ethers.providers.JsonRpcProvider(ETHEREUM_RPC_URL); + let farmContract = new ethers.Contract(contract_addresses["unshETH-farm"], farmABI, provider); + + let baseRewardsPerSecond = (await farmContract.getAllRewardRates())[0]; + + let rewardsPerSecond = (parseFloat(baseRewardsPerSecond)/denomination) + + let rewardsPerYear = rewardsPerSecond * seconds_per_year; + + + let priceKey = `coingecko:unsheth`; + let USHPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + + let USDRewardPerYear = USHPrice * parseFloat(rewardsPerYear); + + return USDRewardPerYear; +} + +async function getTVLUSD(){ + const priceKey = `ethereum:${contract_addresses.WETH}`; + const ethPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + let darknetRates = await getDarknetRates(); + + let lsdVaultTokenBalances = await getLSDVaultTokenBalances(); + + let lsdPrices = await getLSDPrices(); + + let lsdVaultUSDBalances = { + sfrxETH: parseFloat(lsdVaultTokenBalances.sfrxETH)/denomination * lsdPrices.sfrxETH, + cbETH: parseFloat(lsdVaultTokenBalances.cbETH)/denomination * lsdPrices.cbETH, + rETH: parseFloat(lsdVaultTokenBalances.rETH)/denomination * lsdPrices.rETH, + wstETH: parseFloat(lsdVaultTokenBalances.wstETH)/denomination * lsdPrices.wstETH + } + + let totalUsdBalance = 0; + for (const [key, value] of Object.entries(lsdVaultUSDBalances)) { + totalUsdBalance += value; + } + + let percentageOfUnshETHInFarm = await getPercentageOfUnshethInFarm(); + + return totalUsdBalance*percentageOfUnshETHInFarm; +} + +async function getLSDPrices() { + const coingeckoIds = { + sfrxETH: 'staked-frax-ether', + rETH: 'rocket-pool-eth', + wstETH: 'staked-ether', + cbETH: 'coinbase-wrapped-staked-eth', + }; + + let prices = { + sfrxETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.sfrxETH}`)).data.coins[`coingecko:${coingeckoIds.sfrxETH}`]?.price, + rETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.rETH}`)).data.coins[`coingecko:${coingeckoIds.rETH}`]?.price, + wstETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.wstETH}`)).data.coins[`coingecko:${coingeckoIds.wstETH}`]?.price, + cbETH: (await axios.get(`https://coins.llama.fi/prices/current/coingecko:${coingeckoIds.cbETH}`)).data.coins[`coingecko:${coingeckoIds.cbETH}`]?.price, + } + + return prices +} + +async function getPercentageOfUnshethInFarm(){ + let provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + const erc20Abi = [ + "function balanceOf(address account) view returns (uint256)", + "function totalSupply() view returns (uint256)" + ]; + + let unshETHContract = new ethers.Contract(contract_addresses.unshETH, erc20Abi, provider); + + let unshETHFarmBalance = await unshETHContract.balanceOf(contract_addresses['unshETH-farm']); + let unshETHTotalSupply = await unshETHContract.totalSupply(); + + let percentageOfUnshETHInFarm = parseFloat(unshETHFarmBalance)/parseFloat(unshETHTotalSupply); + + return percentageOfUnshETHInFarm; +} + +async function getWeightedApr(){ + + let underlyingAPR = { + sfrxETH: (await axios.get('https://api.frax.finance/v2/frxeth/summary/latest')).data.sfrxethApr, + cbETH: (await cbETHAdaptor.apy())[0].apyBase, + rETH: parseFloat((await axios.get('https://api.rocketpool.net/api/apr')).data.yearlyAPR), + wstETH: parseFloat((await axios.get('https://eth-api.lido.fi/v1/protocol/steth/apr/last')).data.data.apr) + } + + let darknetRates = await getDarknetRates(); + + let lsdVaultTokenBalances = await getLSDVaultTokenBalances(); + + let lsdVaultEthBalances = { + sfrxETH: parseFloat(lsdVaultTokenBalances.sfrxETH)/denomination * parseFloat(darknetRates.sfrxETH)/denomination, + cbETH: parseFloat(lsdVaultTokenBalances.cbETH)/denomination * parseFloat(darknetRates.cbETH)/denomination, + rETH: parseFloat(lsdVaultTokenBalances.rETH)/denomination * parseFloat(darknetRates.rETH)/denomination, + wstETH: parseFloat(lsdVaultTokenBalances.wstETH)/denomination * parseFloat(darknetRates.wstETH)/denomination + } + + let totalEthBalance = 0; + for (let lsd in lsdVaultEthBalances) { + totalEthBalance += lsdVaultEthBalances[lsd]; + } + let lsdVaultWeights = { + sfrxETH: lsdVaultEthBalances.sfrxETH/totalEthBalance, + cbETH: lsdVaultEthBalances.cbETH/totalEthBalance, + rETH: lsdVaultEthBalances.rETH/totalEthBalance, + wstETH: lsdVaultEthBalances.wstETH/totalEthBalance + } + + let weightedApr = 0; + for (let lsd in lsdVaultWeights) { + weightedApr += underlyingAPR[lsd] * lsdVaultWeights[lsd]; + } + + return weightedApr; +} + +async function getDarknetRates() { + const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + let darknet = new ethers.Contract(contract_addresses.darknet, darknetABI, provider); + let darknetRates = { + sfrxETH: await darknet.checkPrice(...[contract_addresses.sfrxETH]), + cbETH: await darknet.checkPrice(...[contract_addresses.cbETH]), + rETH: await darknet.checkPrice(...[contract_addresses.rETH]), + wstETH: await darknet.checkPrice(...[contract_addresses.wstETH]) + } + + return darknetRates; +} + +async function getLSDVaultTokenBalances() { + const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + const balances = {}; + const erc20Abi = [ + "function balanceOf(address account) view returns (uint256)" + ]; + + for (const tokenKey of tokensToCheck) { + const tokenAddress = contract_addresses[tokenKey]; + const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, provider); + balances[tokenKey] = await tokenContract.balanceOf(contract_addresses.LSDVault); + } + + return balances; +} + +module.exports = { + getPoolInfo +}; + diff --git a/src/adaptors/unsheth/ush-bnb-pancake.js b/src/adaptors/unsheth/ush-bnb-pancake.js new file mode 100644 index 0000000000..162fe5d03b --- /dev/null +++ b/src/adaptors/unsheth/ush-bnb-pancake.js @@ -0,0 +1,88 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const ethers = require('ethers'); +const contract_addresses = require('./contract_addresses'); +const cbETHAdaptor = require('../coinbase-wrapped-staked-eth'); +const darknetABI = require('./DarknetABI'); +const lsdVaultABI = require('./LSDVaultABI'); +const farmABI = require('./FarmABI'); +const { seconds_per_year, denomination, tokensToCheck, BINANCE_RPC_URL } = require('./constants'); +const utils = require('../utils'); +const { getLatestAPRPancake } = require('./pancakeBaseAPR'); + +const getPoolInfo = async () => { + const apyBase = await getLatestAPRPancake(); + + let tvlUsd = await getTVLUSD(); + + let usdRewardPerYear = await getUSDRewardPerYear(); + let apyReward = parseFloat(parseFloat(usdRewardPerYear / tvlUsd * 100).toFixed(2)); + + return { + pool: `${contract_addresses['BNBpancake-farm']}-${utils.formatChain('binance')}`, + chain: utils.formatChain('binance'), + project: 'unsheth', + symbol: 'USH-WBNB', + tvlUsd, + apyBase, + apyReward, + rewardTokens: [contract_addresses.BNBUSH], + underlyingTokens: [contract_addresses['BNBpancakeSwapLP']], + poolMeta: 'Pancakeswap LP' + } +}; + +async function getUSDRewardPerYear(){ + let provider = new ethers.providers.JsonRpcProvider(BINANCE_RPC_URL); + let farmContract = new ethers.Contract(contract_addresses["BNBpancake-farm"], farmABI, provider); + + let baseRewardsPerSecond = (await farmContract.getAllRewardRates())[0]; + + let rewardsPerSecond = (parseFloat(baseRewardsPerSecond)/denomination) + + let rewardsPerYear = rewardsPerSecond * seconds_per_year; + + let priceKey = `coingecko:unsheth`; + let USHPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + + let USDRewardPerYear = USHPrice * parseFloat(rewardsPerYear); + + return USDRewardPerYear; +} + +async function getTVLUSD(){ + const priceKey = `coingecko:binancecoin`; + const bnbPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + //erc20 abi for getting the total supply of the token + const erc20ABI = [ + "function totalSupply() view returns (uint256)", + "function balanceOf(address owner) view returns (uint256)", + ]; + + let provider = new ethers.providers.JsonRpcProvider(BINANCE_RPC_URL); + let pancakeContract = new ethers.Contract(contract_addresses["BNBpancakeSwapLP"], erc20ABI, provider); + let farmContract = new ethers.Contract(contract_addresses["BNBpancake-farm"], farmABI, provider); + let wbnbContract = new ethers.Contract(contract_addresses.WBNB, erc20ABI, provider ); + + let totalSupply = await pancakeContract.totalSupply(); + + let totalStaked = await farmContract.totalLiquidityLocked(); + + let percentageStaked = (parseFloat(totalStaked)/denomination) / (parseFloat(totalSupply)/denomination); + + let wbnbBalance = await wbnbContract.balanceOf(contract_addresses["BNBpancakeSwapLP"]); + + let totalBalanceUSDInPancake = (parseFloat(wbnbBalance)/denomination)*2*bnbPrice; + + let totalBalanceUSD = totalBalanceUSDInPancake * percentageStaked; + + return totalBalanceUSD; +} + + +module.exports = { + getPoolInfo +}; + diff --git a/src/adaptors/unsheth/ush-weth-sushi.js b/src/adaptors/unsheth/ush-weth-sushi.js new file mode 100644 index 0000000000..cc8556b9d1 --- /dev/null +++ b/src/adaptors/unsheth/ush-weth-sushi.js @@ -0,0 +1,87 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const ethers = require('ethers'); +const contract_addresses = require('./contract_addresses'); +const cbETHAdaptor = require('../coinbase-wrapped-staked-eth'); +const darknetABI = require('./DarknetABI'); +const lsdVaultABI = require('./LSDVaultABI'); +const farmABI = require('./FarmABI'); +const { seconds_per_year, denomination, tokensToCheck, ETHEREUM_RPC_URL } = require('./constants'); +const {getLatestAPRSushi} = require('./sushiBaseAPR'); +const utils = require('../utils'); + +const getPoolInfo = async () => { + const apyBase = await getLatestAPRSushi(); + + let tvlUsd = await getTVLUSD(); + + let usdRewardPerYear = await getUSDRewardPerYear(); + let apyReward = parseFloat(parseFloat(usdRewardPerYear / tvlUsd * 100).toFixed(2)); + + return { + pool: `${contract_addresses['sushi-farm']}-${utils.formatChain('ethereum')}`, + chain: utils.formatChain('ethereum'), + project: 'unsheth', + symbol: 'USH-WETH', + tvlUsd, + apyBase, + apyReward, + rewardTokens: [contract_addresses.USH], + underlyingTokens: [contract_addresses['sushiSwapLP']], + poolMeta: 'Sushiswap LP' + } +}; + +async function getUSDRewardPerYear(){ + let provider = new ethers.providers.JsonRpcProvider(ETHEREUM_RPC_URL); + let farmContract = new ethers.Contract(contract_addresses["sushi-farm"], farmABI, provider); + + let baseRewardsPerSecond = (await farmContract.getAllRewardRates())[0]; + + let rewardsPerSecond = (parseFloat(baseRewardsPerSecond)/denomination) + + let rewardsPerYear = rewardsPerSecond * seconds_per_year; + + let priceKey = `coingecko:unsheth`; + let USHPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + let USDRewardPerYear = USHPrice * parseFloat(rewardsPerYear); + + return USDRewardPerYear; +} + +async function getTVLUSD(){ + const priceKey = `ethereum:${contract_addresses.WETH}`; + const ethPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + //erc20 abi for getting the total supply of the token + const erc20ABI = [ + "function totalSupply() view returns (uint256)", + "function balanceOf(address owner) view returns (uint256)", + ]; + + let provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_CONNECTION_ETHEREUM); + let sushiContract = new ethers.Contract(contract_addresses["sushiSwapLP"], erc20ABI, provider); + let farmContract = new ethers.Contract(contract_addresses["sushi-farm"], farmABI, provider); + let wethContract = new ethers.Contract(contract_addresses.WETH, erc20ABI, provider ); + + let totalSupply = await sushiContract.totalSupply(); + + let totalStaked = await farmContract.totalLiquidityLocked(); + + let percentageStaked = (parseFloat(totalStaked)/denomination) / (parseFloat(totalSupply)/denomination); + + let wethBalance = await wethContract.balanceOf(contract_addresses["sushiSwapLP"]); + + let totalBalanceUSDInSushi = (parseFloat(wethBalance)/denomination)*2*ethPrice; + + let totalBalanceUSD = totalBalanceUSDInSushi * percentageStaked; + + return totalBalanceUSD; +} + + +module.exports = { + getPoolInfo +}; + diff --git a/src/adaptors/upshift/abi.js b/src/adaptors/upshift/abi.js new file mode 100644 index 0000000000..8639b7ada9 --- /dev/null +++ b/src/adaptors/upshift/abi.js @@ -0,0 +1,208 @@ +module.exports = [ + { + inputs: [{ internalType: "address", name: "ownerAddr", type: "address" }], + stateMutability: "nonpayable", + type: "constructor", + }, + { inputs: [], name: "InvalidPoolAddress", type: "error" }, + { inputs: [], name: "InvalidRewardTokenAddress", type: "error" }, + { inputs: [], name: "OwnerOnly", type: "error" }, + { inputs: [], name: "OwnerRequired", type: "error" }, + { inputs: [], name: "PoolAddressNotExist", type: "error" }, + { inputs: [], name: "PoolAlreadyExist", type: "error" }, + { inputs: [], name: "ReentrantCall", type: "error" }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "poolAddress", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "rewardToken", + type: "address", + }, + { + indexed: false, + internalType: "uint16", + name: "apyBase", + type: "uint16", + }, + { + indexed: false, + internalType: "uint16", + name: "apyReward", + type: "uint16", + }, + ], + name: "PoolAdded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "poolAddress", + type: "address", + }, + ], + name: "PoolDeleted", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "poolAddress", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "rewardToken", + type: "address", + }, + { + indexed: false, + internalType: "uint16", + name: "apyBase", + type: "uint16", + }, + { + indexed: false, + internalType: "uint16", + name: "apyReward", + type: "uint16", + }, + { + indexed: false, + internalType: "uint256", + name: "updatedAt", + type: "uint256", + }, + ], + name: "PoolUpdated", + type: "event", + }, + { + inputs: [ + { internalType: "uint16", name: "chainId", type: "uint16" }, + { internalType: "uint16", name: "apyBase", type: "uint16" }, + { internalType: "uint16", name: "apyReward", type: "uint16" }, + { internalType: "address", name: "poolAddress", type: "address" }, + { internalType: "address", name: "rewardToken", type: "address" }, + ], + name: "addPool", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "poolAddress", type: "address" }, + { internalType: "uint16", name: "chainId", type: "uint16" }, + ], + name: "deletePool", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "poolAddress", type: "address" }], + name: "getPoolInfo", + outputs: [ + { + components: [ + { internalType: "uint16", name: "apyBase", type: "uint16" }, + { internalType: "uint16", name: "apyReward", type: "uint16" }, + { internalType: "uint256", name: "updatedAt", type: "uint256" }, + { internalType: "address", name: "rewardToken", type: "address" }, + ], + internalType: "struct APYRegistry.PoolInfo", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint16", name: "chainId", type: "uint16" }], + name: "getPools", + outputs: [{ internalType: "address[]", name: "", type: "address[]" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes[]", name: "data", type: "bytes[]" }], + name: "multicall", + outputs: [{ internalType: "bytes[]", name: "results", type: "bytes[]" }], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "newOwner", type: "address" }], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "poolAddress", type: "address" }, + { internalType: "uint16", name: "apyBase", type: "uint16" }, + { internalType: "uint16", name: "apyReward", type: "uint16" }, + { internalType: "address", name: "rewardToken", type: "address" }, + ], + name: "updatePool", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "poolAddress", type: "address" }, + { internalType: "uint16", name: "apyBase", type: "uint16" }, + { internalType: "uint16", name: "apyReward", type: "uint16" }, + ], + name: "updatePoolAPYs", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ]; + \ No newline at end of file diff --git a/src/adaptors/upshift/index.js b/src/adaptors/upshift/index.js new file mode 100644 index 0000000000..790e0506de --- /dev/null +++ b/src/adaptors/upshift/index.js @@ -0,0 +1,180 @@ +const lendingPoolABI = require('./lending-pool.json'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const utils = require('../utils'); +const abi = require('./abi') +const axios = require('axios'); + +const APYRegistry = "0x3161676467636Ce9027AC16268Fd351861b052b4"; +const nativeToken = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + +const chainMapping = { + ethereum: { + chain: 'ethereum', + chainId: '1', + nativeToken: ethers.constants.AddressZero, + decimals: 18, + symbol: 'ETH', + }, + avax: { + chain: 'avax', + chainId: '43114', + nativeToken: ethers.constants.AddressZero, + decimals: 18, + symbol: 'AVAX', + }, + base: { + chain: 'base', + chainId: '8453', + nativeToken: ethers.constants.AddressZero, + decimals: 18, + symbol: 'ETH', + } +} + +const projectName = 'upshift'; + +const getApy = async () => { + const poolInfos = []; + + const ethPools = await sdk.api.abi.call({ + target: APYRegistry, + params: [chainMapping.ethereum.chainId], + abi: abi.find(abi => abi.name === 'getPools'), + chain: 'base' + }); + + + const avaxPools = await sdk.api.abi.call({ + target: APYRegistry, + params: [chainMapping.avax.chainId], + abi: abi.find(abi => abi.name === 'getPools'), + chain: 'base' + }); + + + const basePools = await sdk.api.abi.call({ + target: APYRegistry, + params: [chainMapping.base.chainId], + abi: abi.find(abi => abi.name === 'getPools'), + chain: 'base' + }); + + + + const ethereumPoolsInfo = await Promise.all( + ethPools.output.map(async (pool) => { + return await getPoolInfo(pool, 'ethereum'); + }), + ); + + poolInfos.push(...ethereumPoolsInfo); + + const avaxPoolsInfo = await Promise.all( + avaxPools.output.map(async (pool) => { + return await getPoolInfo(pool, 'avax'); + }), + ); + + poolInfos.push(...avaxPoolsInfo); + + const basePoolsInfo = await Promise.all( + basePools.output.map(async (pool) => { + return await getPoolInfo(pool, 'base'); + }), + ); + + poolInfos.push(...basePoolsInfo); + + return poolInfos; +} + + +const getPoolInfo = async (pool, chain) => { + + const symbol = (await sdk.api.abi.call({ + target: pool, + abi: lendingPoolABI.find(abi => abi.name === 'symbol'), + chain: chain, + }))?.output; + + const underlying_token = (await sdk.api.abi.call({ + target: pool, + abi: lendingPoolABI.find(abi => abi.name === 'asset'), + chain: chain, + }))?.output; + + const totalSupply = (await sdk.api.abi.call({ + target: pool, + abi: lendingPoolABI.find(abi => abi.name === 'totalSupply'), + chain: chain, + }))?.output; + + const totalAsset = (await sdk.api.abi.call({ + target: pool, + abi: lendingPoolABI.find(abi => abi.name === 'totalAssets'), + chain: chain, + }))?.output; + + const pool_decimals = (await sdk.api.abi.call({ + target: pool, + abi: 'erc20:decimals', + chain: chain, + }))?.output; + + const underlyingDecimals = (await sdk.api.abi.call({ + target: underlying_token, + abi: 'erc20:decimals', + chain: chain, + }))?.output; + + + + const priceKey = `${utils.formatChain(chain)}:${underlying_token}`; + const underlyingPrice = (await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`)).data.coins[priceKey]?.price; + + const tvlUsd = Number(ethers.utils.formatUnits(totalAsset, underlyingDecimals)) * underlyingPrice; + + + const poolInfo = await sdk.api.abi.call({ + target: APYRegistry, + params: [pool], + abi: abi.find(abi => abi.name === 'getPoolInfo'), + chain: 'base' + }); + + const rewardToken = poolInfo.output.rewardToken === nativeToken ? chainMapping[chain].nativeToken : poolInfo.output.rewardToken; + const apyBase = poolInfo.output.apyBase / 100; + const apyReward = poolInfo.output.apyReward / 100; + + if(apyReward === 0) { + return { + pool: `${pool}-${utils.formatChain(chain)}`, + chain: utils.formatChain(chain), + project: projectName, + symbol: symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + underlyingTokens: [underlying_token], + } + } else { + return { + pool: `${pool}-${utils.formatChain(chain)}`, + chain: utils.formatChain(chain), + project: projectName, + symbol: symbol, + tvlUsd: tvlUsd, + apyBase: apyBase, + apyReward: apyReward, + rewardTokens: [rewardToken], + underlyingTokens: [underlying_token], + } + } + +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://www.upshift.finance/' +}; \ No newline at end of file diff --git a/src/adaptors/upshift/lending-pool.json b/src/adaptors/upshift/lending-pool.json new file mode 100644 index 0000000000..b816698011 --- /dev/null +++ b/src/adaptors/upshift/lending-pool.json @@ -0,0 +1,1815 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "bDepositsPaused", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "bWithdrawalsPaused", + "type": "bool" + } + ], + "name": "DepositWithdrawalStatusChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newFeeCollectorAddr", + "type": "address" + } + ], + "name": "FeeCollectorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "loanAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aprWithTwoDecimals", + "type": "uint256" + } + ], + "name": "NewLoanDeployedByPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawalAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "destinationAddr", + "type": "address" + } + ], + "name": "OnEmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "prevValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "OnMaxSupplyChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "assetsAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "processedOn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiverAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "requestedOn", + "type": "uint256" + } + ], + "name": "WithdrawalProcessed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "ownerAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiverAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "day", + "type": "uint256" + } + ], + "name": "WithdrawalRequested", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "ownerAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "spenderAddr", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "callbackPeriodInSeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gracePeriodInSeconds", + "type": "uint256" + } + ], + "name": "callLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lateInterestFeeWithTwoDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "latePrincipalFeeWithTwoDecimals", + "type": "uint256" + } + ], + "name": "changeLateFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maintenanceCollateralRatioWith2Decimals", + "type": "uint256" + } + ], + "name": "changeMaintenanceCollateralRatio", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiverAddr", + "type": "address" + } + ], + "name": "claim", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "collectFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLagDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newMaxDepositAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newMaxWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newMaxTokenSupply", + "type": "uint256" + }, + { + "internalType": "address", + "name": "newUnderlyingAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "newLoansOperator", + "type": "address" + }, + { + "internalType": "address", + "name": "newLoansDeployerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "newFeesCollectorAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "newScheduledCallerAddress", + "type": "address" + }, + { + "internalType": "uint8", + "name": "newProcessingHour", + "type": "uint8" + } + ], + "name": "configurePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "fundingPeriodInSeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newPaymentIntervalInSeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newLoanAmountInPrincipalTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "originationFeePercent2Decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newAprWithTwoDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialCollateralRatioWith2Decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maintenanceCollateralRatioWith2Decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lateInterestFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "latePrincipalFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiryInfo", + "type": "uint256" + }, + { + "internalType": "string", + "name": "loanTypeInfo", + "type": "string" + }, + { + "internalType": "address", + "name": "lenderAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "borrowerAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "newCollateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "newPrincipalToken", + "type": "address" + }, + { + "internalType": "address", + "name": "feesManagerAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "priceOracleAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "feesCollectorAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "categoryFeesAdress", + "type": "address" + }, + { + "internalType": "bool", + "name": "allowSeizeCollateral", + "type": "bool" + } + ], + "internalType": "struct LoanDeploymentParams", + "name": "loanParams", + "type": "tuple" + } + ], + "name": "deployLoan", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "destinationAddr", + "type": "address" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feesCollector", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + } + ], + "name": "fundLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiverAddr", + "type": "address" + } + ], + "name": "getBurnableAmountByReceiver", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiverAddr", + "type": "address" + } + ], + "name": "getClaimableAmountByReceiver", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializedVersion", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + } + ], + "name": "getRequirementByDate", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + } + ], + "name": "getScheduledTransactionsByDate", + "outputs": [ + { + "internalType": "uint256", + "name": "totalTransactions", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "executionEpoch", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalLoansDeployed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWithdrawalEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableEpoch", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalLiabilityShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalLoansAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint8", + "name": "erc20Decimals", + "type": "uint8" + }, + { + "internalType": "string", + "name": "erc20Symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "erc20Name", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lagDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + } + ], + "name": "liquidate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationHour", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "loansDeployed", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loansDeployerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "loansOperator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxDepositAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holderAddr", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holderAddr", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxWithdrawalAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "notifyLoanClosed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "notifyLoanMatured", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "effectiveLoanAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalRepaid", + "type": "uint256" + } + ], + "name": "notifyPrincipalRepayment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "bPauseDeposits", + "type": "bool" + }, + { + "internalType": "bool", + "name": "bPauseWithdrawals", + "type": "bool" + } + ], + "name": "pauseDepositsAndWithdrawals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "year", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "month", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "day", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxLimit", + "type": "uint256" + } + ], + "name": "processAllClaimsByDate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "loanAddr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newAprWithTwoDecimals", + "type": "uint256" + } + ], + "name": "proposeNewApr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiverAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "holderAddr", + "type": "address" + } + ], + "name": "requestRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableEpoch", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "scheduledCallerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalCollectableFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newFeeCollectorAddr", + "type": "address" + } + ], + "name": "updateFeeCollector", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMaxDepositAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newMaxWithdrawalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newMaxTokenSupply", + "type": "uint256" + } + ], + "name": "updateIssuanceLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "updateTimelockDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newWithdrawalFee", + "type": "uint256" + } + ], + "name": "updateWithdrawalFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/usual/abi.js b/src/adaptors/usual/abi.js new file mode 100644 index 0000000000..817dbce800 --- /dev/null +++ b/src/adaptors/usual/abi.js @@ -0,0 +1,650 @@ +module.exports = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + inputs: [{ internalType: 'address', name: 'target', type: 'address' }], + name: 'AddressEmptyCode', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'AddressInsufficientBalance', + type: 'error', + }, + { inputs: [], name: 'AmountTooBig', type: 'error' }, + { inputs: [], name: 'Blacklisted', type: 'error' }, + { inputs: [], name: 'CurrentTimeBeforePeriodFinish', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'allowance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'uint256', name: 'balance', type: 'uint256' }, + { internalType: 'uint256', name: 'needed', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'approver', type: 'address' }], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'receiver', type: 'address' }], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'spender', type: 'address' }], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxDeposit', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxMint', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxRedeem', + type: 'error', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'uint256', name: 'max', type: 'uint256' }, + ], + name: 'ERC4626ExceededMaxWithdraw', + type: 'error', + }, + { inputs: [], name: 'EndTimeNotAfterStartTime', type: 'error' }, + { inputs: [], name: 'EnforcedPause', type: 'error' }, + { inputs: [], name: 'ExpectedPause', type: 'error' }, + { inputs: [], name: 'FailedInnerCall', type: 'error' }, + { inputs: [], name: 'InsufficientAssetsForYield', type: 'error' }, + { inputs: [], name: 'InvalidInitialization', type: 'error' }, + { inputs: [], name: 'MathOverflowedMulDiv', type: 'error' }, + { inputs: [], name: 'NotAuthorized', type: 'error' }, + { inputs: [], name: 'NotInitializing', type: 'error' }, + { inputs: [], name: 'NullAddress', type: 'error' }, + { inputs: [], name: 'ReentrancyGuardReentrantCall', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'SafeERC20FailedOperation', + type: 'error', + }, + { inputs: [], name: 'SameValue', type: 'error' }, + { inputs: [], name: 'StartTimeBeforePeriodFinish', type: 'error' }, + { inputs: [], name: 'StartTimeNotInFuture', type: 'error' }, + { inputs: [], name: 'ZeroYieldAmount', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Blacklist', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { anonymous: false, inputs: [], name: 'EIP712DomainChanged', type: 'event' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'collector', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'FeeSwept', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'version', + type: 'uint64', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Paused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'UnBlacklist', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'Unpaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'shares', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newWithdrawFeeBps', + type: 'uint256', + }, + ], + name: 'WithdrawFeeUpdated', + type: 'event', + }, + { + inputs: [], + name: 'UsualXStorageV0Location', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'blacklist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'convertToShares', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'deposit', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'eip712Domain', + outputs: [ + { internalType: 'bytes1', name: 'fields', type: 'bytes1' }, + { internalType: 'string', name: 'name', type: 'string' }, + { internalType: 'string', name: 'version', type: 'string' }, + { internalType: 'uint256', name: 'chainId', type: 'uint256' }, + { internalType: 'address', name: 'verifyingContract', type: 'address' }, + { internalType: 'bytes32', name: 'salt', type: 'bytes32' }, + { internalType: 'uint256[]', name: 'extensions', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAccumulatedFees', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getYieldRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'isBlacklisted', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'maxMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxRedeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'maxWithdraw', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + ], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'paused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewMint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'previewRedeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + name: 'previewWithdraw', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'shares', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'yieldAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'startTime', type: 'uint256' }, + { internalType: 'uint256', name: 'endTime', type: 'uint256' }, + ], + name: 'startYieldDistribution', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sweepFees', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'unBlacklist', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpause', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newWithdrawFeeBps', type: 'uint256' }, + ], + name: 'updateWithdrawFee', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'assets', type: 'uint256' }, + { internalType: 'address', name: 'receiver', type: 'address' }, + { internalType: 'address', name: 'owner', type: 'address' }, + ], + name: 'withdraw', + outputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawFeeBps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/usual/index.js b/src/adaptors/usual/index.js new file mode 100644 index 0000000000..246b03b1a9 --- /dev/null +++ b/src/adaptors/usual/index.js @@ -0,0 +1,349 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); +const ethers = require('ethers'); +const abi = require('./abi'); + +const API_ALIASES = { + 'USD0++': 'bUSD0', +}; + +const CONFIG = { + ETHEREUM: { + USD0PP: '0x35D8949372D46B7a3D5A56006AE77B215fc69bC0', + USD0: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5', + ETH0: '0x734eec7930bc84eC5732022B9EB949A81fB89AbE', + STETH: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', + CHAIN: 'Ethereum', + }, + ARBITRUM: { + USD0PP: '0x2B65F9d2e4B84a2dF6ff0525741b75d1276a9C2F', + USD0: '0x35f1C5cB7Fb977E669fD244C567Da99d8a3a6850', + CHAIN: 'Arbitrum', + }, + USUSDSPP_VAULT: '0x67ec31a47a4126A66C7bb2fE017308cf5832A4Db', + USUSDSPP_VAULT_SYMBOL: 'usUSDS++', + USUAL_TOKEN: '0xC4441c2BE5d8fA8126822B9929CA0b81Ea0DE38E', + SUSDS_TOKEN: '0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD', + USUALX_TOKEN: '0x06B964d96f5dCF7Eae9d7C559B09EDCe244d4B8E', + USUALX_LOCKUP: '0x85B6F9BDdb10c6B320d07416a250F984f0F0E9ED', + USUALX_LOCKUP_SYMBOL: 'lUSUALx (12 months)', + USD0_SYMBOL: 'USD0', + USUAL_SYMBOL: 'USUAL', + USUALX_SYMBOL: 'USUALx', + USD0PP_SYMBOL: 'USD0++', + ETH0_SYMBOL: 'ETH0', + URLS: { + REWARD_APR_RATE: 'https://app.usual.money/api/tokens/yields', + LLAMA_PRICE: 'https://coins.llama.fi/prices/current/', + }, + SCALAR: 1e18, + DAYS_PER_YEAR: 365, + DAO_PROJECTED_WEEKLY_REVENUE: 500000, + WEEKS_PER_YEAR: 52, + USUALX_BALANCES_BLACKLIST: [ + '0x86E2a16A5aBC67467Ce502e3Dab511c909C185A8', // Pendle SY + '0xF9F7ee120E4Ce2b4500611952Df8C7470Af09816', // Uniswap USUALx/USUAL + '0x36dee1e8B4679c67d73C8361E943C3401aD77FE3', // Uniswap USUALx/USD0 + '0xDe4b4eaF83b678017E1b3C455117E752fE4e70eA', // Uniswap USUALx/USDT + '0x06B964d96f5dCF7Eae9d7C559B09EDCe244d4B8E', // USUALx dead shares + ], +}; + +async function getTokenSupply(chain, address) { + const params = { + chain: chain.toLowerCase(), + target: address, + abi: 'erc20:totalSupply', + }; + const { output } = await sdk.api.abi.call(params); + return output / CONFIG.SCALAR; +} + +async function getTokenBalance(chain, address, user) { + const params = { + target: address, + chain: chain.toLowerCase(), + abi: 'erc20:balanceOf', + params: [user], + }; + + const { output } = await sdk.api.abi.call(params); + return output / CONFIG.SCALAR; +} + +async function getTokenPrice(chain, address) { + const priceKey = `${chain.toLowerCase()}:${address}`; + const { data } = await axios.get(`${CONFIG.URLS.LLAMA_PRICE}${priceKey}`); + return data.coins[priceKey].price; +} + +function createPoolData( + chain, + poolAddress, + symbol, + tvlUsd, + apyReward, + rewardToken, + underlyingToken +) { + return { + pool: poolAddress, + chain, + project: 'usual', + symbol, + tvlUsd, + apyReward, + rewardTokens: [rewardToken], + underlyingTokens: [underlyingToken], + }; +} + +async function getChainData(chainConfig) { + const supply = await getTokenSupply(chainConfig.CHAIN, chainConfig.USD0PP); + const price = await getTokenPrice(chainConfig.CHAIN, chainConfig.USD0PP); + return { supply, price }; +} + +async function getETH0ChainData(chainConfig) { + const supply = await getTokenSupply(chainConfig.CHAIN, chainConfig.ETH0); + const price = await getTokenPrice(chainConfig.CHAIN, chainConfig.STETH); + return { supply, price }; +} + +async function getUsualXAPY(chain, usualXPrice) { + const blacklistedBalances = await sdk.api.abi + .multiCall({ + abi: 'erc20:balanceOf', + calls: CONFIG.USUALX_BALANCES_BLACKLIST.map((address) => ({ + target: CONFIG.USUALX_TOKEN, + params: [address], + })), + chain: chain.toLowerCase(), + permitFailure: true, + }) + .then((call) => + call.output.map((e) => { + return e.output / CONFIG.SCALAR; + }) + ); + + const rawUsualXTVL = await getTokenSupply(chain, CONFIG.USUALX_TOKEN); + const usualXLockupBalance = await getTokenBalance( + 'Ethereum', + CONFIG.USUALX_TOKEN, + CONFIG.USUALX_LOCKUP + ); + const UsualXUnlockedTVL = rawUsualXTVL - usualXLockupBalance; + const usualXTVL = + rawUsualXTVL - (blacklistedBalances?.reduce((a, b) => a + b, 0) ?? 0); + + const usualXApr = await getRewardData( + CONFIG.USUALX_SYMBOL, + CONFIG.USUAL_SYMBOL + ); + + // Applying daily compounding only to USUALx apyReward + const usualxApyReward = utils.aprToApy(usualXApr.apr, CONFIG.DAYS_PER_YEAR); // Daily compounding for apyReward + + const usualxMarketCap = usualXTVL * usualXPrice; + const usualXLockupMarketCap = usualXLockupBalance * usualXPrice; + const usualXUnlockedMarketCap = usualxMarketCap - usualXLockupMarketCap; + + const revenueSwitch = await getRewardData( + CONFIG.USUALX_LOCKUP_SYMBOL, + CONFIG.USD0_SYMBOL + ); + const usualxApyRevenueSwitch = utils.aprToApy( + revenueSwitch.apr, + CONFIG.WEEKS_PER_YEAR + ); + + return { + usualxApyReward, + usualxApyRevenueSwitch, + rawUsualXTVL, + usualXLockupMarketCap, + usualXUnlockedMarketCap, + }; +} + +async function getUsUSDSAPY(chain) { + const { output } = await sdk.api.abi.call({ + target: CONFIG.USUSDSPP_VAULT, + chain: chain.toLowerCase(), + abi: abi.find((abi) => abi.name === 'totalAssets'), + }); + const totalAssets = output / CONFIG.SCALAR; + + const blacklistedBalances = await sdk.api.abi + .multiCall({ + abi: 'erc20:balanceOf', + calls: CONFIG.USUALX_BALANCES_BLACKLIST.map((address) => ({ + target: CONFIG.USUSDSPP_VAULT, + params: [address], + })), + chain: chain.toLowerCase(), + permitFailure: true, + }) + .then((call) => + call.output.map((e) => { + return e.output / CONFIG.SCALAR; + }) + ); + + const rawUsUSDSppTVL = await getTokenSupply(chain, CONFIG.USUSDSPP_VAULT); + + const usualXTVL = + rawUsUSDSppTVL - (blacklistedBalances?.reduce((a, b) => a + b, 0) ?? 0); + + //sUSDS++ vault data + const susdsBalance = await getTokenBalance( + 'Ethereum', + CONFIG.SUSDS_TOKEN, + CONFIG.USUSDSPP_VAULT + ); + const susdsPrice = await getTokenPrice('Ethereum', CONFIG.SUSDS_TOKEN); + const usUSDSppMarketCap = susdsBalance * susdsPrice; + + const baseRewards = await getRewardData( + CONFIG.USUSDSPP_VAULT_SYMBOL, + CONFIG.USD0PP_SYMBOL + ); + const baseUsUSDSApy = utils.aprToApy(baseRewards.apr, CONFIG.WEEKS_PER_YEAR); + const usualRewards = await getRewardData( + CONFIG.USUSDSPP_VAULT_SYMBOL, + CONFIG.USUAL_SYMBOL + ); + const usUSDSRewardApy = utils.aprToApy( + usualRewards.apr, + CONFIG.DAYS_PER_YEAR + ); + return { + baseUsUSDSApy, + usUSDSRewardApy, + usUSDSppMarketCap, + }; +} + +async function getRewardData(pool, reward) { + const { data } = await axios.get(`${CONFIG.URLS.REWARD_APR_RATE}`); + const poolKey = API_ALIASES[pool] ?? pool; + const rewardKey = API_ALIASES[reward] ?? reward; + const apr = data[poolKey]?.[rewardKey]; + + if (!apr) { + throw new Error(`Reward "${reward}" not found for pool "${pool}"`); + } + + return { + apr, + }; +} + +const apy = async () => { + const rewardUsd0pp = await getRewardData( + CONFIG.USD0PP_SYMBOL, + CONFIG.USUAL_SYMBOL + ); + + const apyReward = utils.aprToApy(rewardUsd0pp.apr, CONFIG.WEEKS_PER_YEAR); + const ethData = await getChainData(CONFIG.ETHEREUM); + const arbData = await getChainData(CONFIG.ARBITRUM); + + const rewardEth0 = await getRewardData( + CONFIG.ETH0_SYMBOL, + CONFIG.USUAL_SYMBOL + ); + const apyRewardEth0 = utils.aprToApy(rewardEth0.apr, CONFIG.WEEKS_PER_YEAR); + const eth0Data = await getETH0ChainData(CONFIG.ETHEREUM); + + const usualbalance = await getTokenBalance( + 'Ethereum', + CONFIG.USUAL_TOKEN, + CONFIG.USUALX_TOKEN + ); + const usualxPrice = await getTokenPrice('Ethereum', CONFIG.USUALX_TOKEN); + const { + usualxApyReward, + usualxApyRevenueSwitch, + rawUsualXTVL, + usualXLockupMarketCap, + usualXUnlockedMarketCap, + } = await getUsualXAPY('Ethereum', usualxPrice); + const { baseUsUSDSApy, usUSDSRewardApy, usUSDSppMarketCap } = + await getUsUSDSAPY('Ethereum'); + return [ + createPoolData( + CONFIG.ETHEREUM.CHAIN, + CONFIG.ETHEREUM.ETH0, + CONFIG.ETH0_SYMBOL, + eth0Data.supply * eth0Data.price, + apyRewardEth0, + CONFIG.USUAL_TOKEN, + CONFIG.ETHEREUM.STETH + ), + createPoolData( + CONFIG.ETHEREUM.CHAIN, + CONFIG.ETHEREUM.USD0PP, + CONFIG.USD0PP_SYMBOL, + ethData.supply * ethData.price, + apyReward, // Corrected to USD0++ APY + CONFIG.USUAL_TOKEN, + CONFIG.ETHEREUM.USD0 + ), + createPoolData( + CONFIG.ARBITRUM.CHAIN, + CONFIG.ARBITRUM.USD0PP, + CONFIG.USD0PP_SYMBOL, + arbData.supply * arbData.price, + apyReward, // Corrected for Arbitrum USD0++ + CONFIG.USUAL_TOKEN, + CONFIG.ARBITRUM.USD0 + ), + { + pool: CONFIG.USUALX_TOKEN, + chain: 'Ethereum', + project: 'usual', + symbol: 'USUALx', + tvlUsd: usualXUnlockedMarketCap, + apyBase: usualxApyReward, // Daily compounding for USUALx APY + apyReward: 0, // No additional reward for USUALx + rewardTokens: [CONFIG.ETHEREUM.USD0], + poolMeta: 'Staked USUAL', + underlyingTokens: [CONFIG.USUAL_TOKEN], + url: 'https://app.usual.money/swap?action=stake&from=USUAL&to=USUALx', + }, + { + pool: CONFIG.USUALX_LOCKUP, + chain: 'Ethereum', + project: 'usual', + symbol: 'USUALx', + tvlUsd: usualXLockupMarketCap, + apyBase: usualxApyReward, // Daily compounding for USUALx APY + apyReward: usualxApyRevenueSwitch, // Revenue switch APY for Lockup USUALx Weekly compounding + rewardTokens: [CONFIG.ETHEREUM.USD0], + underlyingTokens: [CONFIG.USUAL_TOKEN], + poolMeta: 'Lockup', + url: 'https://app.usual.money/swap?from=USUALx&to=lUSUALx', + }, + { + pool: CONFIG.USUSDSPP_VAULT, + chain: 'Ethereum', + project: 'usual', + symbol: 'usUSDS++', + tvlUsd: usUSDSppMarketCap, + apyBase: baseUsUSDSApy, // Weekly compounding for USUSDS++ APY in USD0++ + apyReward: usUSDSRewardApy, // Reward in Usual APY for USUSDS++ + rewardTokens: [CONFIG.USUAL_TOKEN], + underlyingTokens: [CONFIG.ETHEREUM.USD0PP], + poolMeta: 'usUSDS++ vault', + url: 'https://app.usual.money/vault/susds', + }, + ]; +}; + +module.exports = { + apy, + url: 'https://app.usual.money/swap?action=stake', +}; diff --git a/src/adaptors/utils.js b/src/adaptors/utils.js index d49521927b..6b24576aaf 100755 --- a/src/adaptors/utils.js +++ b/src/adaptors/utils.js @@ -1,102 +1,80 @@ const superagent = require('superagent'); +const axios = require('axios'); const { request, gql } = require('graphql-request'); +const { chunk } = require('lodash'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); -exports.formatChain = (chain) => chain.charAt(0).toUpperCase() + chain.slice(1); +exports.formatAddress = (address) => { + return String(address).toLowerCase(); +}; + +exports.formatChain = (chain) => { + if (chain && chain.toLowerCase() === 'xdai') return 'Gnosis'; + if (chain && chain.toLowerCase() === 'kcc') return 'KCC'; + if (chain && chain.toLowerCase() === 'okexchain') return 'OKExChain'; + if (chain && chain.toLowerCase() === 'bsc') return 'Binance'; + if (chain && chain.toLowerCase() === 'milkomeda') return 'Milkomeda C1'; + if (chain && chain.toLowerCase() === 'milkomeda_a1') return 'Milkomeda A1'; + if (chain && chain.toLowerCase() === 'boba_avax') return 'Boba_Avax'; + if (chain && chain.toLowerCase() === 'boba_bnb') return 'Boba_Bnb'; + if (chain && chain.toLowerCase() === 'iotaevm') return 'IOTA EVM'; + if ( + chain && + (chain.toLowerCase() === 'zksync_era' || + chain.toLowerCase() === 'zksync era' || + chain.toLowerCase() === 'era') + ) + return 'zkSync Era'; + if (chain && chain.toLowerCase() === 'polygon_zkevm') return 'Polygon zkEVM'; + if (chain && chain.toLowerCase() === 'real') return 're.al'; + if (chain && chain.toLowerCase() === 'plume_mainnet') return 'Plume Mainnet'; + return chain.charAt(0).toUpperCase() + chain.slice(1); +}; + +const getFormatter = (symbol) => { + if (symbol.includes('USD+')) return /[_:\/]/g; + return /[_+:\/]/g; +}; // replace / with - and trim potential whitespace -exports.formatSymbol = (symbol) => - symbol - .replace(/[_+\/]/g, '-') +// set mimatic to mai, uppercase all symbols +exports.formatSymbol = (symbol) => { + return symbol + .replace(getFormatter(symbol), '-') .replace(/\s/g, '') - .trim(); + .trim() + .toLowerCase() + .replaceAll('mimatic', 'mai') + .toUpperCase(); +}; exports.getData = async (url, query = null) => { + let res; if (query !== null) { res = await superagent.post(url).send(query); } else { res = await superagent.get(url); } - res = res.body; - return res; -}; - -exports.getCGpriceData = async (tokenString, symbols, chainId = 'ethereum') => { - let url = 'https://api.coingecko.com/api/v3/simple/'; - if (symbols === true) { - url = `${url}price?ids=${tokenString}&vs_currencies=usd`; - } else { - url = `${url}token_price/${chainId}?contract_addresses=${tokenString}&vs_currencies=usd`; - } - - let res = await superagent.get(url); - res = res.body; - return res; + return res.body; }; // retrive block based on unixTimestamp array -exports.getBlocksByTime = async (timestamps, chainString) => { - const urlsKeys = { - ethereum: { - url: 'https://api.etherscan.io', - key: process.env.ETHERSCAN, - }, - polygon: { - url: 'https://api.polygonscan.com', - key: process.env.POLYGONSCAN, - }, - avalanche: { - url: 'https://api.snowtrace.io', - key: process.env.SNOWTRACE, - }, - arbitrum: { - url: 'https://api.arbiscan.io', - key: process.env.ARBISCAN, - }, - optimism: { - url: 'https://api-optimistic.etherscan.io', - key: process.env.OPTIMISM, - }, - xdai: { - url: 'https://blockscout.com/xdai/mainnet', - key: process.env.XDAI, - }, - }; - +const getBlocksByTime = async (timestamps, chainString) => { + const chain = chainString === 'avalanche' ? 'avax' : chainString; const blocks = []; for (const timestamp of timestamps) { - const url = - `${urlsKeys[chainString].url}/api?module=block&action=getblocknobytime×tamp=` + - timestamp + - '&closest=before&apikey=' + - urlsKeys[chainString].key; - - const response = await superagent.get(url); - - let blockNumber; - - if (url.includes('blockscout')) { - blockNumber = response.body.result.blockNumber; - } else { - blockNumber = response.body.result; - } - - blocks.push(parseInt(blockNumber)); + const response = await superagent.get( + `https://coins.llama.fi/block/${chain}/${timestamp}` + ); + blocks.push(response.body.height); } return blocks; }; +exports.getBlocksByTime = getBlocksByTime; + const getLatestBlockSubgraph = async (url) => { - // const queryGraph = gql` - // { - // indexingStatusForCurrentVersion(subgraphName: "") { - // chains { - // latestBlock { - // number - // } - // } - // } - // } - // `; const queryGraph = gql` { _meta { @@ -107,14 +85,37 @@ const getLatestBlockSubgraph = async (url) => { } `; - // const blockGraph = await request( - // 'https://api.thegraph.com/index-node/graphql', - // queryGraph.replace('', url.split('name/')[1]) - // ); - const blockGraph = await request( - `https://api.thegraph.com/subgraphs/name/${url.split('name/')[1]}`, - queryGraph - ); + const blockGraph = + url.includes('https://gateway-arbitrum.network.thegraph.com/api') || + url.includes('metis-graph.maiadao.io') || + url.includes('babydoge/faas') || + url.includes('kybernetwork/kyberswap-elastic-cronos') || + url.includes('kybernetwork/kyberswap-elastic-matic') || + url.includes('metisapi.0xgraph.xyz/subgraphs/name') || + url.includes( + 'https://subgraph.satsuma-prod.com/09c9cf3574cc/orbital-apes/v3-subgraph/api' + ) || + url.includes('api.goldsky.com') || + url.includes('api.studio.thegraph.com') || + url.includes('48211/uniswap-v3-base') || + url.includes('horizondex/block') || + url.includes('pancake-swap.workers.dev') || + url.includes('pancakeswap/exchange-v3-linea') || + url.includes('exchange-v3-polygon-zkevm/version/latest') || + url.includes('exchange-v3-zksync/version/latest') || + url.includes('balancer-base-v2/version/latest') || + url.includes('horizondex') || + url.includes('swopfi-units') + ? await request(url, queryGraph) + : url.includes('aperture/uniswap-v3') + ? await request( + 'https://api.goldsky.com/api/public/project_clnz7akg41cv72ntv0uhyd3ai/subgraphs/aperture/manta-pacific-blocks/gn', + queryGraph + ) + : await request( + `https://api.thegraph.com/subgraphs/name/${url.split('name/')[1]}`, + queryGraph + ); // return Number( // blockGraph.indexingStatusForCurrentVersion.chains[0].latestBlock.number @@ -123,17 +124,21 @@ const getLatestBlockSubgraph = async (url) => { }; // func which queries subgraphs for their latest block nb and compares it against -// the latest block from etherscan api, if within a certain bound -> ok, otherwise +// the latest block from https://coins.llama.fi/block/, if within a certain bound -> ok, otherwise // will break as data is stale -exports.getBlocks = async (chainString, tsTimeTravel, urlArray) => { +exports.getBlocks = async ( + chainString, + tsTimeTravel, + urlArray, + offset = 86400 +) => { const timestamp = tsTimeTravel !== null ? Number(tsTimeTravel) : Math.floor(Date.now() / 1000); - const offset = 86400; const timestampPrior = timestamp - offset; - let [block, blockPrior] = await this.getBlocksByTime( + let [block, blockPrior] = await getBlocksByTime( [timestamp, timestampPrior], chainString ); @@ -146,14 +151,15 @@ exports.getBlocks = async (chainString, tsTimeTravel, urlArray) => { for (const url of urlArray.filter((el) => el !== null)) { blocksPromises.push(getLatestBlockSubgraph(url)); } - blocks = await Promise.all(blocksPromises); + const blocks = await Promise.all(blocksPromises); // we use oldest block - blockGraph = Math.min(...blocks); + const blockGraph = Math.min(...blocks); // calc delta - blockDelta = Math.abs(block - blockGraph); + const blockDelta = Math.abs(block - blockGraph); // check delta (keeping this large for now) - const thr = chainString === 'ethereum' ? 300 : 3000; + const thr = + chainString === 'ethereum' ? 300 : chainString === 'cronos' ? 6000 : 3000; if (blockDelta > thr) { console.log(`block: ${block}, blockGraph: ${blockGraph}`); throw new Error(`Stale subgraph of ${blockDelta} blocks!`); @@ -172,26 +178,37 @@ exports.tvl = async (dataNow, networkString) => { // make copy const dataNowCopy = dataNow.map((el) => ({ ...el })); - // extract unique token id's - const ids = []; - for (const e of dataNowCopy) { - ids.push([ - `${networkString}:${e.token0.id}`, - `${networkString}:${e.token1.id}`, - ]); - } - let idsSet = [...new Set(ids.flat())]; + const formatId = (id) => `${networkString}:${String(id).toLowerCase()}`; + const idsSet = Array.from( + new Set( + dataNowCopy.flatMap((pool) => [ + formatId(pool.token0.id), + formatId(pool.token1.id), + ]) + ) + ); - // pull token prices - let prices = await this.getData('https://coins.llama.fi/prices', { - coins: idsSet, - }); - prices = prices.coins; + // price endpoint seems to break with too many tokens, splitting it to max 50 per request + const fetchTokenPrices = async (tokenIds) => { + const idList = tokenIds.join(',').replaceAll('/', ''); + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/${idList}` + ); + return data.coins; + }; + + const prices = {}; + for (let index = 0; index < idsSet.length; index += 50) { + const chunk = idsSet.slice(index, index + 50); + const chunkPrices = await fetchTokenPrices(chunk); + Object.assign(prices, chunkPrices); + } // calc tvl for (const el of dataNowCopy) { - let price0 = prices[`${networkString}:${el.token0.id}`]?.price; - let price1 = prices[`${networkString}:${el.token1.id}`]?.price; + let price0 = prices[formatId(el.token0.id)]?.price; + let price1 = prices[formatId(el.token1.id)]?.price; + let tvl; if (price0 !== undefined && price1 !== undefined) { tvl = Number(el.reserve0) * price0 + Number(el.reserve1) * price1; @@ -204,6 +221,8 @@ exports.tvl = async (dataNow, networkString) => { } el['totalValueLockedUSD'] = tvl; + el['price0'] = price0; + el['price1'] = price1; } return dataNowCopy; @@ -214,32 +233,304 @@ exports.aprToApy = (apr, compoundFrequency = 365) => { ((1 + (apr * 0.01) / compoundFrequency) ** compoundFrequency - 1) * 100 ); }; + +exports.apyToApr = (apy, compoundFrequency = 365) => { + return ( + (((apy / 100 + 1) ** (1 / compoundFrequency) - 1) * compoundFrequency) / + 0.01 + ); +}; + // calculating apy based on subgraph data -exports.apy = (entry, dataPrior, version) => { - entry = { ...entry }; +exports.apy = (pool, dataPrior1d, dataPrior7d, version) => { + pool = { ...pool }; // uni v2 forks set feeTier to constant if (version === 'v2') { - entry['feeTier'] = 3000; + pool['feeTier'] = 3000; + } else if (version === 'stellaswap') { + pool['feeTier'] = 2000; + } else if (version === 'baseswap') { + pool['feeTier'] = 1700; + } else if (version === 'zyberswap') { + pool['feeTier'] = 1500; + } else if (version === 'arbidex') { + pool['feeTier'] = 500; } // calc prior volume on 24h offset - entry['volumeUSDPrior'] = dataPrior.find( - (el) => el.id === entry.id + pool['volumeUSDPrior1d'] = dataPrior1d.find( + (el) => el.id === pool.id + )?.volumeUSD; + + pool['volumeUSDPrior7d'] = dataPrior7d.find( + (el) => el.id === pool.id )?.volumeUSD; // calc 24h volume - entry['volumeUSD24h'] = - Number(entry.volumeUSD) - Number(entry.volumeUSDPrior); + pool['volumeUSD1d'] = Number(pool.volumeUSD) - Number(pool.volumeUSDPrior1d); + pool['volumeUSD7d'] = Number(pool.volumeUSD) - Number(pool.volumeUSDPrior7d); + + if ( + pool.volumeToken0 && + (pool['volumeUSD1d'] === 0 || pool['volumeUSD7d'] === 0) + ) { + const poolDataPrior1D = dataPrior1d.find((el) => el.id === pool.id); + const poolDataPrior7D = dataPrior7d.find((el) => el.id === pool.id); + + if (pool['volumeUSD1d'] === 0 && poolDataPrior1D) { + const volumeToken0 = + Number(pool.volumeToken0) - Number(poolDataPrior1D.volumeToken0); + pool['volumeUSD1d'] = volumeToken0 * pool.price0; + } + if (pool['volumeUSD7d'] === 0 && poolDataPrior7D) { + const volumeToken0 = + Number(pool.volumeToken0) - Number(poolDataPrior7D.volumeToken0); + pool['volumeUSD7d'] = volumeToken0 * pool.price0; + } + } // calc fees - entry['feeUSD24h'] = (entry.volumeUSD24h * Number(entry.feeTier)) / 1e6; + pool['feeUSD1d'] = (pool.volumeUSD1d * Number(pool.feeTier)) / 1e6; + pool['feeUSD7d'] = (pool.volumeUSD7d * Number(pool.feeTier)) / 1e6; // annualise - entry['feeUSD365days'] = entry.feeUSD24h * 365; + pool['feeUSDyear1d'] = pool.feeUSD1d * 365; + pool['feeUSDyear7d'] = pool.feeUSD7d * 52; // calc apy - entry['apy'] = (entry.feeUSD365days / entry.totalValueLockedUSD) * 100; + pool['apy1d'] = (pool.feeUSDyear1d / pool.totalValueLockedUSD) * 100; + pool['apy7d'] = (pool.feeUSDyear7d / pool.totalValueLockedUSD) * 100; + + return pool; +}; + +exports.keepFinite = (p) => { + if ( + !['apyBase', 'apyReward', 'apy'] + .map((f) => Number.isFinite(p[f])) + .includes(true) + ) + return false; + + return Number.isFinite(p['tvlUsd']); +}; + +exports.getPrices = async (addresses, chain) => { + const priceKeys = chain + ? addresses.map((address) => `${chain}:${address}`) + : addresses; + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + return { pricesBySymbol, pricesByAddress }; +}; + +///////// UNISWAP V2 + +const calculateApy = ( + poolInfo, + totalAllocPoint, + rewardPerBlock, + rewardPrice, + reserveUSD, + blocksPerYear +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + const tokensPerYear = blocksPerYear * rewardPerBlock; + + return ((poolWeight * tokensPerYear * rewardPrice) / reserveUSD) * 100; +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, id: token0Address } = token0; + const { decimals: token1Decimals, id: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2).div(1e18); + if (token1Price) return reserve1.times(token1Price).times(2).div(1e18); +}; + +const getPairsInfo = async (pairs, url) => { + const pairQuery = gql` + query pairQuery($id_in: [ID!]) { + pairs(where: { id_in: $id_in }) { + name + id + token0 { + decimals + id + } + token1 { + decimals + id + } + } + } + `; + const pairInfo = await Promise.all( + chunk(pairs, 7).map((tokens) => + request(url, pairQuery, { + id_in: tokens.map((pair) => pair.toLowerCase()), + }) + ) + ); + + return pairInfo + .map(({ pairs }) => pairs) + .flat() + .reduce((acc, pair) => ({ ...acc, [pair.id.toLowerCase()]: pair }), {}); +}; + +exports.uniswap = { calculateApy, calculateReservesUSD, getPairsInfo }; + +/// MULTICALL + +const makeMulticall = async (abi, addresses, chain, params = null) => { + const data = await sdk.api.abi.multiCall({ + abi, + calls: addresses.map((address) => ({ + target: address, + params, + })), + chain, + permitFailure: true, + }); + + const res = data.output.map(({ output }) => output); + + return res; +}; + +exports.makeMulticall = makeMulticall; + +const capitalizeFirstLetter = (str) => { + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +}; + +exports.capitalizeFirstLetter = capitalizeFirstLetter; + +exports.removeDuplicates = (pools) => { + const seen = {}; + return pools.filter((i) => { + return seen.hasOwnProperty(i.pool) ? false : (seen[i.pool] = true); + }); +}; + +exports.getERC4626Info = async ( + address, + chain, + timestamp = Math.floor(Date.now() / 1e3), + { + assetUnit = '100000000000000000', + totalAssetsAbi = 'uint:totalAssets', + convertToAssetsAbi = 'function convertToAssets(uint256 shares) external view returns (uint256)', + } = {} +) => { + const DAY = 24 * 3600; + + const [blockNow, blockYesterday] = await Promise.all( + [timestamp, timestamp - DAY].map((time) => + axios + .get(`https://coins.llama.fi/block/${chain}/${time}`) + .then((r) => r.data.height) + ) + ); + const [tvl, priceNow, priceYesterday] = await Promise.all([ + sdk.api.abi.call({ + target: address, + block: blockNow, + abi: totalAssetsAbi, + chain: chain, + }), + sdk.api.abi.call({ + target: address, + block: blockNow, + abi: convertToAssetsAbi, + params: [assetUnit], + chain: chain, + }), + sdk.api.abi.call({ + target: address, + block: blockYesterday, + abi: convertToAssetsAbi, + params: [assetUnit], + chain: chain, + }), + ]); + const apy = (priceNow.output / priceYesterday.output) ** 365 * 100 - 100; + return { + pool: address, + chain, + tvl: tvl.output, + apyBase: apy, + }; +}; + +// solana +exports.getTotalSupply = async (tokenMintAddress) => { + const rpcUrl = 'https://api.mainnet-beta.solana.com'; + const requestBody = { + jsonrpc: '2.0', + id: 1, + method: 'getTokenSupply', + params: [ + tokenMintAddress, + { + commitment: 'confirmed', + }, + ], + }; + + const response = await axios.post(rpcUrl, requestBody, { + headers: { + 'Content-Type': 'application/json', + }, + }); + + const data = response.data; + if (data.error) { + throw new Error(`Error fetching total supply: ${data.error.message}`); + } + + const totalSupply = data.result.value.amount; + const decimals = data.result.value.decimals; + const supplyInTokens = totalSupply / Math.pow(10, decimals); - return entry; + return supplyInTokens; }; diff --git a/src/adaptors/uwu-lend/abiChefIncentiveController.json b/src/adaptors/uwu-lend/abiChefIncentiveController.json new file mode 100644 index 0000000000..a92f3f10b1 --- /dev/null +++ b/src/adaptors/uwu-lend/abiChefIncentiveController.json @@ -0,0 +1,329 @@ +[ + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + }, + { + "internalType": "address", + "name": "_poolConfigurator", + "type": "address" + }, + { + "internalType": "contract IMultiFeeDistribution", + "name": "_rewardMinter", + "type": "address" + }, + { "internalType": "uint256", "name": "_maxMintable", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "BalanceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "_allocPoints", + "type": "uint256[]" + } + ], + "name": "batchUpdateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimReceiver", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "claimableReward", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "emissionSchedule", + "outputs": [ + { + "internalType": "uint128", + "name": "startTimeOffset", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardsPerSecond", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "_balance", "type": "uint256" }, + { "internalType": "uint256", "name": "_totalSupply", "type": "uint256" } + ], + "name": "handleAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxMintableTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintedTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolConfigurator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "uint256", "name": "totalSupply", "type": "uint256" }, + { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardPerShare", + "type": "uint256" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "onwardIncentives", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "registeredTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardMinter", + "outputs": [ + { + "internalType": "contract IMultiFeeDistribution", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "setClaimReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "_incentives", + "type": "address" + } + ], + "name": "setOnwardIncentives", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "start", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userBaseClaimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userInfo", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardDebt", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/uwu-lend/abiLendingPool.json b/src/adaptors/uwu-lend/abiLendingPool.json new file mode 100644 index 0000000000..ec3e9a3393 --- /dev/null +++ b/src/adaptors/uwu-lend/abiLendingPool.json @@ -0,0 +1,793 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "premium", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidatedCollateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "LiquidationCall", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Paused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RebalanceStableBorrowRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Unpaused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "FLASHLOAN_PREMIUM_TOTAL", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LENDINGPOOL_REVISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_NUMBER_RESERVES", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STABLE_RATE_BORROW_SIZE_PERCENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "interestRateMode", + "type": "uint256" + }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "balanceFromBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceToBefore", + "type": "uint256" + } + ], + "name": "finalizeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiverAddress", + "type": "address" + }, + { "internalType": "address[]", "name": "assets", "type": "address[]" }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "modes", "type": "uint256[]" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "bytes", "name": "params", "type": "bytes" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { "internalType": "uint8", "name": "id", "type": "uint8" } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedIncome", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedVariableDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserAccountData", + "outputs": [ + { + "internalType": "uint256", + "name": "totalCollateralETH", + "type": "uint256" + }, + { "internalType": "uint256", "name": "totalDebtETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "availableBorrowsETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentLiquidationThreshold", + "type": "uint256" + }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { "internalType": "uint256", "name": "healthFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.UserConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "name": "initReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { "internalType": "address", "name": "debtAsset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "debtToCover", "type": "uint256" }, + { "internalType": "bool", "name": "receiveAToken", "type": "bool" } + ], + "name": "liquidationCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "rebalanceStableBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "repay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "configuration", "type": "uint256" } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "val", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { + "internalType": "address", + "name": "rateStrategyAddress", + "type": "address" + } + ], + "name": "setReserveInterestRateStrategyAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "bool", "name": "useAsCollateral", "type": "bool" } + ], + "name": "setUserUseReserveAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" } + ], + "name": "swapBorrowRateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/uwu-lend/abiProtocolDataProvider.json b/src/adaptors/uwu-lend/abiProtocolDataProvider.json new file mode 100644 index 0000000000..bbf43f504f --- /dev/null +++ b/src/adaptors/uwu-lend/abiProtocolDataProvider.json @@ -0,0 +1,233 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "addressesProvider", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADDRESSES_PROVIDER", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllATokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReservesTokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserveFactor", "type": "uint256" }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "isActive", "type": "bool" }, + { "internalType": "bool", "name": "isFrozen", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVariableDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveTokensAddresses", + "outputs": [ + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "currentATokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "scaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint40", + "name": "stableRateLastUpdated", + "type": "uint40" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/uwu-lend/index.js b/src/adaptors/uwu-lend/index.js new file mode 100644 index 0000000000..557b84df6c --- /dev/null +++ b/src/adaptors/uwu-lend/index.js @@ -0,0 +1,200 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const abiLendingPool = require('./abiLendingPool.json'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider.json'); +const abiChefIncentiveController = require('./abiChefIncentiveController.json'); +const utils = require('../utils'); + +const lendingPool = '0x2409aF0251DCB89EE3Dee572629291f9B087c668'; +const protocolDataProvider = '0x17938eDE656Ca1901807abf43a6B1D138D8Cd521'; +const chefIncentiveController = '0x21953192664867e19F85E96E1D1Dd79dc31cCcdB'; +const lendingPoolAddressesProvider = + '0x011c0d38da64b431a1bdfc17ad72678eabf7f1fb'; +const rewardToken = '0x55c08ca52497e2f1534b59e2917bf524d4765257'; + +// uwu-lend has an early exit penalty of 50% +const earlyExitPenalty = 0.5; + +const apy = async () => { + const chain = 'ethereum'; + // underlying pools + const reservesList = ( + await sdk.api.abi.call({ + target: lendingPool, + chain, + abi: abiLendingPool.find((n) => n.name === 'getReservesList'), + }) + ).output; + + // supply and borrow base rate, interest and debt addresses + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ target: lendingPool, params: t })), + chain, + abi: abiLendingPool.find((n) => n.name === 'getReserveData'), + }) + ).output.map((o) => o.output); + + // available + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' ? reserveData[i].aTokenAddress : null, + })), + chain, + }) + ) + ); + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + // borrowed + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ target: p.variableDebtTokenAddress })), + chain, + }) + ).output.map((o) => o.output); + + // ltv + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: protocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + // --- rewards + const rewardsPerSecond = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find( + (n) => n.name === 'rewardsPerSecond' + ), + target: chefIncentiveController, + chain, + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find((n) => n.name === 'totalAllocPoint'), + target: chefIncentiveController, + chain, + }) + ).output; + + // poolInfo (alloc point) + // need to run this twice, + // once for inteteres bearing and another time for debt bearing tokens + const poolInfoInterest = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].aTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const poolInfoDebt = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + // prices + const pricesArray = [rewardToken, ...reservesList] + .map((t) => `${chain}:${t}`) + .concat(['coingecko:wrapped-memory']); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).body.coins; + + const secondsPerYear = 60 * 60 * 24 * 365; + const rewardPerYear = + (rewardsPerSecond / 1e18) * + secondsPerYear * + prices[`${chain}:${rewardToken}`]?.price; + + return reservesList + .map((t, i) => { + const price = + // wmemo no price via chain:address but only via cg id + t === '0x3b79a28264fC52c7b4CEA90558AA0B162f7Faf57' + ? prices['coingecko:wrapped-memory']?.price + : prices[`${chain}:${t}`]?.price; + + // tvl data + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + // apy base + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + // apy reward + const apyReward = + (((poolInfoInterest[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalSupplyUsd) * + 100 * + earlyExitPenalty; + + const apyRewardBorrow = + (((poolInfoDebt[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalBorrowUsd) * + 100 * + earlyExitPenalty; + + // ltv + const ltv = reserveConfigurationData[i].ltv / 1e4; + + // url for pools + const url = + `https://app.uwulend.fi/reserve-overview/${t}-${t}${lendingPoolAddressesProvider}`.toLowerCase(); + + return { + pool: reserveData[i].aTokenAddress, + symbol: utils.formatSymbol(symbols[i]), + project: 'uwu-lend', + chain: 'Ethereum', + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [t], + rewardTokens: [rewardToken], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv, + }; + }) + .filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/valas-finance/abiChefIncentiveController.json b/src/adaptors/valas-finance/abiChefIncentiveController.json new file mode 100644 index 0000000000..b4ece50364 --- /dev/null +++ b/src/adaptors/valas-finance/abiChefIncentiveController.json @@ -0,0 +1,323 @@ +[ + { + "inputs": [ + { + "internalType": "uint128[]", + "name": "_startTimeOffset", + "type": "uint128[]" + }, + { + "internalType": "uint128[]", + "name": "_rewardsPerSecond", + "type": "uint128[]" + }, + { + "internalType": "address", + "name": "_poolConfigurator", + "type": "address" + }, + { + "internalType": "contract IMultiFeeDistribution", + "name": "_rewardMinter", + "type": "address" + }, + { "internalType": "uint256", "name": "_maxMintable", "type": "uint256" }, + { "internalType": "uint256", "name": "_startTime", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "BalanceUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_allocPoint", "type": "uint256" } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { + "internalType": "uint256[]", + "name": "_allocPoints", + "type": "uint256[]" + } + ], + "name": "batchUpdateAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimReceiver", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" } + ], + "name": "claimableReward", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "emissionSchedule", + "outputs": [ + { + "internalType": "uint128", + "name": "startTimeOffset", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardsPerSecond", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "_balance", "type": "uint256" }, + { "internalType": "uint256", "name": "_totalSupply", "type": "uint256" } + ], + "name": "handleAction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxMintableTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintedTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolConfigurator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolInfo", + "outputs": [ + { "internalType": "uint256", "name": "totalSupply", "type": "uint256" }, + { "internalType": "uint256", "name": "allocPoint", "type": "uint256" }, + { + "internalType": "uint256", + "name": "lastRewardTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accRewardPerShare", + "type": "uint256" + }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "onwardIncentives", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "registeredTokens", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardMinter", + "outputs": [ + { + "internalType": "contract IMultiFeeDistribution", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsPerSecond", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" } + ], + "name": "setClaimReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { + "internalType": "contract IOnwardIncentivesController", + "name": "_incentives", + "type": "address" + } + ], + "name": "setOnwardIncentives", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userBaseClaimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userInfo", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rewardDebt", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/valas-finance/abiLendingPool.json b/src/adaptors/valas-finance/abiLendingPool.json new file mode 100644 index 0000000000..ec3e9a3393 --- /dev/null +++ b/src/adaptors/valas-finance/abiLendingPool.json @@ -0,0 +1,793 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRateMode", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowRate", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalfOf", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint16", + "name": "referral", + "type": "uint16" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "premium", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "referralCode", + "type": "uint16" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "debtAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "debtToCover", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidatedCollateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "receiveAToken", + "type": "bool" + } + ], + "name": "LiquidationCall", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Paused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "RebalanceStableBorrowRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "repayer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Repay", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + } + ], + "name": "ReserveDataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "ReserveUsedAsCollateralEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rateMode", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { "anonymous": false, "inputs": [], "name": "Unpaused", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "reserve", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "FLASHLOAN_PREMIUM_TOTAL", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LENDINGPOOL_REVISION", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_NUMBER_RESERVES", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_STABLE_RATE_BORROW_SIZE_PERCENT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "interestRateMode", + "type": "uint256" + }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "borrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { + "internalType": "uint256", + "name": "balanceFromBefore", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceToBefore", + "type": "uint256" + } + ], + "name": "finalizeTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiverAddress", + "type": "address" + }, + { "internalType": "address[]", "name": "assets", "type": "address[]" }, + { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }, + { "internalType": "uint256[]", "name": "modes", "type": "uint256[]" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" }, + { "internalType": "bytes", "name": "params", "type": "bytes" }, + { "internalType": "uint16", "name": "referralCode", "type": "uint16" } + ], + "name": "flashLoan", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAddressesProvider", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "components": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.ReserveConfigurationMap", + "name": "configuration", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentLiquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentVariableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "currentStableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "aTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { "internalType": "uint8", "name": "id", "type": "uint8" } + ], + "internalType": "struct DataTypes.ReserveData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedIncome", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveNormalizedVariableDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReservesList", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserAccountData", + "outputs": [ + { + "internalType": "uint256", + "name": "totalCollateralETH", + "type": "uint256" + }, + { "internalType": "uint256", "name": "totalDebtETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "availableBorrowsETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentLiquidationThreshold", + "type": "uint256" + }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { "internalType": "uint256", "name": "healthFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserConfiguration", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "data", "type": "uint256" } + ], + "internalType": "struct DataTypes.UserConfigurationMap", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + } + ], + "name": "initReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collateralAsset", + "type": "address" + }, + { "internalType": "address", "name": "debtAsset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" }, + { "internalType": "uint256", "name": "debtToCover", "type": "uint256" }, + { "internalType": "bool", "name": "receiveAToken", "type": "bool" } + ], + "name": "liquidationCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "rebalanceStableBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" }, + { "internalType": "address", "name": "onBehalfOf", "type": "address" } + ], + "name": "repay", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "configuration", "type": "uint256" } + ], + "name": "setConfiguration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "val", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { + "internalType": "address", + "name": "rateStrategyAddress", + "type": "address" + } + ], + "name": "setReserveInterestRateStrategyAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "bool", "name": "useAsCollateral", "type": "bool" } + ], + "name": "setUserUseReserveAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "rateMode", "type": "uint256" } + ], + "name": "swapBorrowRateMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" } + ], + "name": "withdraw", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/valas-finance/abiProtocolDataProvider.json b/src/adaptors/valas-finance/abiProtocolDataProvider.json new file mode 100644 index 0000000000..bbf43f504f --- /dev/null +++ b/src/adaptors/valas-finance/abiProtocolDataProvider.json @@ -0,0 +1,233 @@ +[ + { + "inputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "addressesProvider", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ADDRESSES_PROVIDER", + "outputs": [ + { + "internalType": "contract ILendingPoolAddressesProvider", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllATokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllReservesTokens", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "symbol", "type": "string" }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + } + ], + "internalType": "struct AaveProtocolDataProvider.TokenData[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveConfigurationData", + "outputs": [ + { "internalType": "uint256", "name": "decimals", "type": "uint256" }, + { "internalType": "uint256", "name": "ltv", "type": "uint256" }, + { + "internalType": "uint256", + "name": "liquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationBonus", + "type": "uint256" + }, + { "internalType": "uint256", "name": "reserveFactor", "type": "uint256" }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, + { + "internalType": "bool", + "name": "stableBorrowRateEnabled", + "type": "bool" + }, + { "internalType": "bool", "name": "isActive", "type": "bool" }, + { "internalType": "bool", "name": "isFrozen", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVariableDebt", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint256", + "name": "variableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "averageStableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidityIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableBorrowIndex", + "type": "uint256" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getReserveTokensAddresses", + "outputs": [ + { "internalType": "address", "name": "aTokenAddress", "type": "address" }, + { + "internalType": "address", + "name": "stableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "getUserReserveData", + "outputs": [ + { + "internalType": "uint256", + "name": "currentATokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "principalStableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "scaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stableBorrowRate", + "type": "uint256" + }, + { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, + { + "internalType": "uint40", + "name": "stableRateLastUpdated", + "type": "uint40" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/valas-finance/index.js b/src/adaptors/valas-finance/index.js new file mode 100644 index 0000000000..451a36dafb --- /dev/null +++ b/src/adaptors/valas-finance/index.js @@ -0,0 +1,195 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); + +const abiLendingPool = require('./abiLendingPool.json'); +const abiProtocolDataProvider = require('./abiProtocolDataProvider.json'); +const abiChefIncentiveController = require('./abiChefIncentiveController.json'); +const utils = require('../utils'); + +const lendingPool = '0xE29A55A6AEFf5C8B1beedE5bCF2F0Cb3AF8F91f5'; +const protocolDataProvider = '0xc9704604E18982007fdEA348e8DDc7CC652E34cA'; +const chefIncentiveController = '0xB7c1d99069a4eb582Fc04E7e1124794000e7ecBF'; +const lendingPoolAddressesProvider = + '0x0736B3dAdDe5B78354BF7F7faaFAcEE82B1851b9'; +const rewardToken = '0xb1ebdd56729940089ecc3ad0bbeeb12b6842ea6f'; + +// valas has an early exit penalty of 75% -> 25% of the rewards are left +const earlyExitPenalty = 1 - 0.75; + +const apy = async () => { + const chain = 'bsc'; + // underlying pools + const reservesList = ( + await sdk.api.abi.call({ + target: lendingPool, + chain, + abi: abiLendingPool.find((n) => n.name === 'getReservesList'), + }) + ).output; + + // supply and borrow base rate, interest and debt addresses + const reserveData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ target: lendingPool, params: t })), + chain, + abi: abiLendingPool.find((n) => n.name === 'getReserveData'), + }) + ).output.map((o) => o.output); + + // available + const [liquidityRes, decimalsRes, symbolsRes] = await Promise.all( + ['erc20:balanceOf', 'erc20:decimals', 'erc20:symbol'].map((method) => + sdk.api.abi.multiCall({ + abi: method, + calls: reservesList.map((t, i) => ({ + target: t, + params: + method === 'erc20:balanceOf' ? reserveData[i].aTokenAddress : null, + })), + chain, + }) + ) + ); + const liquidity = liquidityRes.output.map((o) => o.output); + const decimals = decimalsRes.output.map((o) => o.output); + const symbols = symbolsRes.output.map((o) => o.output); + + // borrowed + const totalBorrow = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:totalSupply', + calls: reserveData.map((p) => ({ target: p.variableDebtTokenAddress })), + chain, + }) + ).output.map((o) => o.output); + + // ltv + const reserveConfigurationData = ( + await sdk.api.abi.multiCall({ + calls: reservesList.map((t) => ({ + target: protocolDataProvider, + params: t, + })), + chain, + abi: abiProtocolDataProvider.find( + (n) => n.name === 'getReserveConfigurationData' + ), + }) + ).output.map((o) => o.output); + + // --- rewards + const rewardsPerSecond = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find( + (n) => n.name === 'rewardsPerSecond' + ), + target: chefIncentiveController, + chain, + }) + ).output; + + const totalAllocPoint = ( + await sdk.api.abi.call({ + abi: abiChefIncentiveController.find((n) => n.name === 'totalAllocPoint'), + target: chefIncentiveController, + chain, + }) + ).output; + + // poolInfo (alloc point) + // need to run this twice, + // once for inteteres bearing and another time for debt bearing tokens + const poolInfoInterest = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].aTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + const poolInfoDebt = ( + await sdk.api.abi.multiCall({ + abi: abiChefIncentiveController.find((n) => n.name === 'poolInfo'), + calls: reserveData.map((t, i) => ({ + target: chefIncentiveController, + params: reserveData[i].variableDebtTokenAddress, + })), + chain, + }) + ).output.map((o) => o.output); + + // prices + const pricesArray = [rewardToken, ...reservesList].map( + (t) => `${chain}:${t}` + ); + const prices = ( + await superagent.get(`https://coins.llama.fi/prices/current/${pricesArray}`) + ).body.coins; + + const secondsPerYear = 60 * 60 * 24 * 365; + const rewardPerYear = + (rewardsPerSecond / 1e18) * + secondsPerYear * + prices[`${chain}:${rewardToken}`].price; + + return reservesList.map((t, i) => { + const price = prices[`${chain}:${t}`]?.price; + + // tvl data + const tvlUsd = (liquidity[i] / 10 ** decimals[i]) * price; + const totalBorrowUsd = (totalBorrow[i] / 10 ** decimals[i]) * price; + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + + // apy base + const apyBase = reserveData[i].currentLiquidityRate / 1e25; + const apyBaseBorrow = reserveData[i].currentVariableBorrowRate / 1e25; + + // apy reward + const apyReward = + (((poolInfoInterest[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalSupplyUsd) * + 100 * + earlyExitPenalty; + + const apyRewardBorrow = + (((poolInfoDebt[i].allocPoint / totalAllocPoint) * rewardPerYear) / + totalBorrowUsd) * + 100 * + earlyExitPenalty; + + // ltv + const ltv = reserveConfigurationData[i].ltv / 1e4; + + // url for pools + const url = `https://valasfinance.com/reserve-overview/${ + symbols[i] + }-${t.toLowerCase()}${lendingPoolAddressesProvider.toLowerCase()}`; + + return { + pool: reserveData[i].aTokenAddress, + symbol: utils.formatSymbol(symbols[i]), + project: 'valas-finance', + chain: utils.formatChain(chain), + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [t], + rewardTokens: [rewardToken], + url, + // borrow fields + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow, + ltv, + }; + }); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/vaultcraft/index.js b/src/adaptors/vaultcraft/index.js new file mode 100644 index 0000000000..d0511c1a6c --- /dev/null +++ b/src/adaptors/vaultcraft/index.js @@ -0,0 +1,145 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); +const { formatChain, keepFinite } = require('../utils.js'); + +const vaultAbi = require('./vaultAbi.json'); + +const ADDRESSES = { + ethereum: { + vaultRegistry: '0x007318Dc89B314b47609C684260CfbfbcD412864', + gaugeController: '0xD57d8EEC36F0Ba7D8Fd693B9D97e02D8353EB1F4', + oVCX: '0xaFa52E3860b4371ab9d8F08E801E9EA1027C0CA2', + }, + arbitrum: { + vaultRegistry: '0xB205e94D402742B919E851892f7d515592a7A6cC', + oVCX: '0x59a696bF34Eae5AD8Fd472020e3Bed410694a230', + }, + polygon: { + vaultRegistry: '0x2246c4c469735bCE95C120939b0C078EC37A08D0', + }, + bsc: { + vaultRegistry: '0x25172C73958064f9ABc757ffc63EB859D7dc2219', + }, + optimism: { + vaultRegistry: '0xdD0d135b5b52B7EDd90a83d4A4112C55a1A6D23A', + oVCX: '0xD41d34d6b50785fDC025caD971fE940B8AA1bE45', + }, +}; + +const CHAIN_TO_ID = { + ethereum: 1, + optimism: 10, + polygon: 137, + arbitrum: 42161, + base: 8453, + avax: 43114, + fraxtal: 252, + bsc: 56, +}; + +// returns a list of vaults, see https://github.com/Popcorn-Limited/defi-db/blob/main/archive/vaults/1.json +// for schema +const getVaults = async (chainID) => { + const vaults = ( + await axios.get(`https://app.vaultcraft.io/api/vaults?chainId=${chainID}`) + ).data; + return Object.values(vaults); +}; + +async function getTokenPrice(chain, token) { + const { data } = await axios.get( + `https://coins.llama.fi/prices/current/${chain}:${token}` + ); + return data.coins[`${chain}:${token}`]?.price; +} + +const apy = async (timestamp = null) => { + const yieldData = []; + const chainEntries = Object.entries(CHAIN_TO_ID); + + const chainResults = await Promise.allSettled( + chainEntries.map(([chain, chainId]) => + (async () => { + const chainYieldData = []; + const vaults = await getVaults(chainId); + + for (const vault of vaults) { + if (!vault.baseApy) { + // no apy + continue; + } + if (vault?.address === undefined || vault?.asset === undefined) { + continue; + } + + try { + const symbol = ( + await sdk.api.abi.call({ + target: vault.address, + abi: vaultAbi.find((n) => n.name === 'symbol'), + chain, + }) + ).output.replace('pop-', ''); + + const totalAssets = ( + await sdk.api.abi.call({ + target: vault.address, + abi: vaultAbi.find((n) => n.name === 'totalAssets'), + chain, + }) + ).output; + + const price = await getTokenPrice(chain, vault.asset.address); + if (!price) { + continue; + } + + const tvl = (totalAssets * price) / 10 ** vault.asset.decimals; + + const data = { + pool: `${vault.address}-${chain}`, + chain: formatChain(chain), + project: 'vaultcraft', + symbol, + tvlUsd: tvl, + apyBase: vault.baseApy, + underlyingTokens: [vault.asset.address], + }; + + if (vault.gaugeLowerApr && ADDRESSES[chain]?.oVCX) { + data.apyReward = vault.gaugeLowerApr; + data.rewardTokens = [ADDRESSES[chain].oVCX]; + } + chainYieldData.push(data); + } catch (vaultError) { + console.error( + `vaultcraft: failed to load vault ${vault.address} on ${chain}`, + vaultError?.message || vaultError + ); + } + } + + return chainYieldData; + })() + ) + ); + + chainResults.forEach((result, index) => { + const [chain] = chainEntries[index]; + if (result.status === 'fulfilled') { + yieldData.push(...result.value); + } else { + console.error( + `vaultcraft: failed to load vaults for chain ${chain}`, + result.reason?.message || result.reason + ); + } + }); + + return yieldData.filter((p) => keepFinite(p)); +}; + +module.exports = { + apy, + url: 'https://app.vaultcraft.io/vaults', +}; diff --git a/src/adaptors/vaultcraft/vaultAbi.json b/src/adaptors/vaultcraft/vaultAbi.json new file mode 100644 index 0000000000..c0d7da763f --- /dev/null +++ b/src/adaptors/vaultcraft/vaultAbi.json @@ -0,0 +1,1669 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientWithdrawalAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAdapter", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAsset", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFeeRecipient", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidQuitPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "InvalidSigner", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidVaultFees", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "MaxError", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "quitPeriod", + "type": "uint256" + } + ], + "name": "NotPassedQuitPeriod", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "PermitDeadlineExpired", + "type": "error" + }, + { + "inputs": [], + "name": "VaultAssetMismatchNewAdapterAsset", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC4626Upgradeable", + "name": "oldAdapter", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC4626Upgradeable", + "name": "newAdapter", + "type": "address" + } + ], + "name": "ChangedAdapter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct VaultFees", + "name": "oldFees", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct VaultFees", + "name": "newFees", + "type": "tuple" + } + ], + "name": "ChangedFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "depositLimit", + "type": "uint256" + } + ], + "name": "DepositLimitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldFeeRecipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newFeeRecipient", + "type": "address" + } + ], + "name": "FeeRecipientUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC4626Upgradeable", + "name": "newAdapter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "NewAdapterProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct VaultFees", + "name": "newFees", + "type": "tuple" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "NewFeesProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerNominated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "quitPeriod", + "type": "uint256" + } + ], + "name": "QuitPeriodSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "contractName", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "VaultInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accruedManagementFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accruedPerformanceFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "adapter", + "outputs": [ + { + "internalType": "contract IERC4626Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "assetsCheckpoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "changeAdapter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "changeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "contractName", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimalOffset", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeRecipient", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feesUpdatedAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "highWaterMark", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "asset_", + "type": "address" + }, + { + "internalType": "contract IERC4626Upgradeable", + "name": "adapter_", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "internalType": "struct VaultFees", + "name": "fees_", + "type": "tuple" + }, + { + "internalType": "address", + "name": "feeRecipient_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "depositLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "nominateNewOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nominatedOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC4626Upgradeable", + "name": "newAdapter", + "type": "address" + } + ], + "name": "proposeAdapter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "internalType": "struct VaultFees", + "name": "newFees", + "type": "tuple" + } + ], + "name": "proposeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedAdapter", + "outputs": [ + { + "internalType": "contract IERC4626Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedAdapterTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedFeeTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedFees", + "outputs": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "withdrawal", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "management", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "performance", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "quitPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_depositLimit", + "type": "uint256" + } + ], + "name": "setDepositLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeRecipient", + "type": "address" + } + ], + "name": "setFeeRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_quitPeriod", + "type": "uint256" + } + ], + "name": "setQuitPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "takeManagementAndPerformanceFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/vaultka/index.js b/src/adaptors/vaultka/index.js new file mode 100644 index 0000000000..04af33584d --- /dev/null +++ b/src/adaptors/vaultka/index.js @@ -0,0 +1,46 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const getApy = async () => { + const response = await axios.get( + 'https://solana-api.vaultka.com/lend/all/11111111111111111111111111111111' + ); + const { usdc, sol, usdt } = response.data.data; + const poolsConfig = [ + { + pool: 'nKMLJtN1rr64K9DjmfzXvzaq4JEy5a4AJHHP9gY1dW6', + symbol: 'USDC', + underlyingTokens: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'], + data: usdc, + }, + { + pool: 'DMhoXyVNpCFeCEfEjEQfS6gzAEcPUUSXM8Xnd2UXJfiS', + symbol: 'SOL', + underlyingTokens: ['So11111111111111111111111111111111111111112'], + data: sol, + }, + { + pool: '69oX4gmwgDAfXWxSRtTx9SHvWmu2bd9qVGjQPpAFHaBF', + symbol: 'USDT', + underlyingTokens: ['Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'], + data: usdt, + }, + ]; + + return poolsConfig.map(({ pool, symbol, underlyingTokens, data }) => ({ + pool, + chain: 'Solana', + project: 'vaultka', + symbol, + underlyingTokens, + url: 'https://solana.vaultka.com/', + apyBase: data.apr, + tvlUsd: data.vaultBalanceInUsd + data.borrowedAmountInUsd, + totalBorrowUsd: data.borrowedAmountInUsd, + })); +}; + +module.exports = { + apy: getApy, + url: 'https://solana.vaultka.com/', +}; diff --git a/src/adaptors/vector-finance/index.js b/src/adaptors/vector-finance/index.js index c821a493a4..109a63f650 100644 --- a/src/adaptors/vector-finance/index.js +++ b/src/adaptors/vector-finance/index.js @@ -1,49 +1,49 @@ -const axios = require("axios"); +const axios = require('axios'); const utils = require('../utils'); function aggregateApys(aprs, key, locking) { - const stakingApys = aprs.Staking[key].total; - if (locking) { - const lockingApys = aprs.Locking[key].total; - return stakingApys + lockingApys; - } else { - return stakingApys; - }; -}; + const stakingApys = aprs.Staking[key]?.total; + if (locking) { + const lockingApys = aprs.Locking[key].total; + return stakingApys + lockingApys; + } else { + return stakingApys; + } +} async function apy() { - const [ - { data: aprs }, - { data: tvls }, - { data: prices } - ] = await Promise.all([ - axios.get(`https://api.vectorfinance.io/api/v1/vtx/apr`), - axios.get(`https://api.vectorfinance.io/api/v1/vtx/tvl`), - axios.get(`https://api.vectorfinance.io/api/v1/vtx/marketPrices`) - ]); + const [{ data: aprs }, { data: tvls }, { data: prices }] = await Promise.all([ + axios.get(`https://api.vectorfinance.io/api/v1/vtx/apr`), + axios.get(`https://api.vectorfinance.io/api/v1/vtx/tvl`), + axios.get(`https://api.vectorfinance.io/api/v1/vtx/marketPrices`), + ]); + + const lockingLength = Object.entries(aprs.Locking).length; - const lockingLength = Object.entries(aprs.Locking).length; + return [...Object.entries(aprs.Locking), ...Object.entries(aprs.Staking)].map( + ([k, v], i) => { + if (['VTXAVAX', 'PTPXPTP', 'ZJOEJOE'].includes(k)) return undefined; - return [ - ...Object.entries(aprs.Locking), - ...Object.entries(aprs.Staking) - ].map(([k, v], i) => ({ + return { pool: `vector-${k}-${i < lockingLength ? 'locking' : 'staking'}`, chain: 'Avalanche', project: 'vector-finance', - symbol: utils.formatSymbol(k.replace(/_/g, "-")), - tvlUsd: Number( - tvls[i < lockingLength ? 'Locking' : 'Staking'][k] - ) * prices[k], - apy: aggregateApys(aprs, k, i < lockingLength) - })); -}; + symbol: utils.formatSymbol(k.replace(/_/g, '-')), + tvlUsd: + Number(tvls[i < lockingLength ? 'Locking' : 'Staking'][k]) * + prices[k], + apy: aggregateApys(aprs, k, i < lockingLength), + }; + } + ); +} const main = async () => { - return await apy(); + return (await apy()).filter(Boolean).filter((p) => utils.keepFinite(p)); }; module.exports = { - timetravel: false, - apy: main, -}; \ No newline at end of file + timetravel: false, + apy: main, + url: 'https://vectorfinance.io/stake', +}; diff --git a/src/adaptors/vela-exchange/RewarderABI.json b/src/adaptors/vela-exchange/RewarderABI.json new file mode 100644 index 0000000000..d24d0493cf --- /dev/null +++ b/src/adaptors/vela-exchange/RewarderABI.json @@ -0,0 +1,20 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_stakeToken", "type": "address" } + ], + "name": "poolRewardsPerSec", + "outputs": [ + { "internalType": "address[]", "name": "addresses", "type": "address[]" }, + { "internalType": "string[]", "name": "symbols", "type": "string[]" }, + { "internalType": "uint256[]", "name": "decimals", "type": "uint256[]" }, + { + "internalType": "uint256[]", + "name": "rewardsPerSec", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/vela-exchange/TokenFarmABI.json b/src/adaptors/vela-exchange/TokenFarmABI.json new file mode 100644 index 0000000000..0ba382e1ee --- /dev/null +++ b/src/adaptors/vela-exchange/TokenFarmABI.json @@ -0,0 +1,20 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_stakeToken", "type": "address" } + ], + "name": "poolTotalLp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "esVELA", + "outputs": [ + { "internalType": "contract IBoringERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/vela-exchange/VLPABI.json b/src/adaptors/vela-exchange/VLPABI.json new file mode 100644 index 0000000000..9b16a31932 --- /dev/null +++ b/src/adaptors/vela-exchange/VLPABI.json @@ -0,0 +1,9 @@ +[ + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/vela-exchange/VaultABI.json b/src/adaptors/vela-exchange/VaultABI.json new file mode 100644 index 0000000000..120851950c --- /dev/null +++ b/src/adaptors/vela-exchange/VaultABI.json @@ -0,0 +1,9 @@ +[ + { + "inputs": [], + "name": "getVLPPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/vela-exchange/index.js b/src/adaptors/vela-exchange/index.js new file mode 100644 index 0000000000..bff255c221 --- /dev/null +++ b/src/adaptors/vela-exchange/index.js @@ -0,0 +1,191 @@ +const ethers = require('ethers'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const VaultABI = require('./VaultABI.json'); +const VLPABI = require('./VLPABI.json'); +const RewarderABI = require('./RewarderABI.json'); +const TokenFarmABI = require('./TokenFarmABI.json'); +const axios = require('axios'); + +const VELA_ADDRESS = { + ['arbitrum']: '0x088cd8f5eF3652623c22D48b1605DCfE860Cd704', + ['base']: '0x5A76A56ad937335168b30dF3AA1327277421C6Ae', +}; +const USDC_ADDRESS = { + ['arbitrum']: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', + ['base']: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', +}; + +const GHO_ADDRESS = { + ['arbitrum']: '0x7dfF72693f6A4149b17e7C6314655f6A9F7c8B33', +}; + +const VELA_REWARDER_ADDRESS = { + ['arbitrum']: '0x1353e6C747Da576cEB760862f610b3ec5DBA0D21', + ['base']: '0xDD5aD536E987bF72Dddc1BF518f3bb8Cc2c615e2' +} + +const TOKEN_FARM_ADDRESS = { + ['arbitrum']: '0x60b8C145235A31f1949a831803768bF37d7Ab7AA', + ['base']: '0x00B01710c2098b883C4F93dD093bE8Cf605a7BDe' +} + +const VAULT_ADDRESS = '0xC4ABADE3a15064F9E3596943c699032748b13352'; + +const VLP_ADDRESS = { + ['arbitrum']: '0xC5b2D9FDa8A82E8DcECD5e9e6e99b78a9188eB05', + ['base']: '0xEBf154Ee70de5237aB07Bd6428310CbC5e5c7C6E', +}; + +const RPC = { + ['arbitrum']: 'https://arbitrum.llamarpc.com', + ['base']: 'https://mainnet.base.org', +}; + +const chains = ['arbitrum', 'base']; + +const VAULT_START_TIME = { + ['arbitrum']: new Date(Date.UTC(2023, 5, 26, 4, 38)).getTime(), + ['base']: new Date(Date.UTC(2023, 8, 5, 15, 0)).getTime(), +}; + +const poolsFunction = async () => { + const pools = []; + const secondsPerYear = 31536000; + + for (let i = 0; i < chains.length; i++) { + const chain = chains[i]; + + const velaPrice = ( + await utils.getPrices( + ['0x088cd8f5eF3652623c22D48b1605DCfE860Cd704'], + 'arbitrum' + ) + ).pricesBySymbol.vela; + + sdk.api.config.setProvider( + `${chain}`, + new ethers.providers.JsonRpcProvider(`${RPC[chain]}`) + ); + + const esVela = ( + await sdk.api.abi.call({ + target: TOKEN_FARM_ADDRESS[chain], + abi: TokenFarmABI.filter(({ name }) => name === 'esVELA')[0], + chain: `${chain}`, + }) + ).output + + const poolTotalLP = ethers.utils.formatUnits( + ( + await sdk.api.abi.call({ + target: TOKEN_FARM_ADDRESS[chain], + abi: TokenFarmABI.filter(({ name }) => name === 'poolTotalLp')[0], + chain: `${chain}`, + params: [esVela] + }) + ).output, + 18 + ); + + const poolTotal = poolTotalLP * parseFloat(velaPrice) + const rewardsPerSecUSDC = ethers.utils.formatUnits( + ( + await sdk.api.abi.call({ + target: VELA_REWARDER_ADDRESS[chain], + abi: RewarderABI.filter(({ name }) => name === 'poolRewardsPerSec')[0], + chain: `${chain}`, + params: [esVela] + }) + ).output.rewardsPerSec[1], + 18 + ); + + + const USDC_ROI = (100 * (parseFloat(rewardsPerSecUSDC) * 365 * 86400)) / poolTotal + + const current = ethers.utils.formatUnits( + ( + await sdk.api.abi.call({ + target: VAULT_ADDRESS, + abi: VaultABI.filter(({ name }) => name === 'getVLPPrice')[0], + chain: `${chain}`, + }) + ).output, + 5 + ); + + const totalSupply = ( + await sdk.api.abi.call({ + target: VLP_ADDRESS[chain], + abi: VLPABI.filter(({ name }) => name === 'totalSupply')[0], + chain: `${chain}`, + }) + ).output; + + const diff = current - 1; + const now = new Date(); + const dayDiff = Math.floor( + (new Date( + Date.UTC( + now.getUTCFullYear(), + now.getUTCMonth(), + now.getUTCDate(), + now.getUTCHours(), + now.getUTCMinutes() + ) + ).getTime() - + VAULT_START_TIME[chain]) / + (24 * 60 * 60 * 1000) + ); + /// APR Calculations /// + const APR = 365 * (diff / 1 / dayDiff) * 100; + + const VLPPool = { + pool: `${VAULT_ADDRESS}-${chain}`.toLowerCase(), + chain: utils.formatChain(`${chain}`), + project: 'vela-exchange', + symbol: 'USDC', + poolMeta: 'VLP', + tvlUsd: (Number(totalSupply) / 1e18) * Number(current), + apyBase: APR, + underlyingTokens: chain === 'arbitrum'? [USDC_ADDRESS[chain], GHO_ADDRESS[chain]] : [USDC_ADDRESS[chain]], + }; + + const GHOPool = { + pool: `${VAULT_ADDRESS}-${GHO_ADDRESS[chain]}-${chain}`.toLowerCase(), + chain: utils.formatChain(`${chain}`), + project: 'vela-exchange', + symbol: 'GHO', + poolMeta: 'VLP', + tvlUsd: (Number(totalSupply) / 1e18) * Number(current), + apyBase: APR, + underlyingTokens: [GHO_ADDRESS[chain], USDC_ADDRESS[chain]], + }; + + const VelaPool = { + pool: `${TOKEN_FARM_ADDRESS[chain]}-${chain}`.toLowerCase(), + chain: utils.formatChain(`${chain}`), + project: 'vela-exchange', + symbol: 'esVELA', + poolMeta: 'esVela vesting is up to 6 months', + tvlUsd: Number(poolTotalLP) * Number(velaPrice), + apyReward: (USDC_ROI * current) + APR, + underlyingTokens: [VELA_ADDRESS[chain]], + rewardTokens: [USDC_ADDRESS[chain]] + }; + + pools.push(VLPPool); + pools.push(VelaPool) + if(chain === 'arbitrum'){ pools.push(GHOPool) } + + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.vela.exchange/staking/vlp', +}; diff --git a/src/adaptors/velocimeter-v2/abis/Gauge.json b/src/adaptors/velocimeter-v2/abis/Gauge.json new file mode 100644 index 0000000000..dee27f85f4 --- /dev/null +++ b/src/adaptors/velocimeter-v2/abis/Gauge.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_stake","type":"address"},{"internalType":"address","name":"_external_bribe","type":"address"},{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_oFlow","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"bool","name":"_forPair","type":"bool"},{"internalType":"address[]","name":"_allowedRewardTokens","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oFlow","type":"address"}],"name":"OFlowSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceWithLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchUpdateRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"balanceOf","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_lockDuration","type":"uint256"}],"name":"depositWithLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"derivedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"derivedBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derivedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"external_bribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fees1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorBalanceIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorRewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorSupplyIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isForPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"lastEarn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"left","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lockEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oFlow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerTokenCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"rewardPerToken","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oFlow","type":"address"}],"name":"setOFlow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supplyCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"},{"internalType":"address","name":"oldToken","type":"address"},{"internalType":"address","name":"newToken","type":"address"}],"name":"swapOutRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/velocimeter-v2/abis/Option.json b/src/adaptors/velocimeter-v2/abis/Option.json new file mode 100644 index 0000000000..22aa26c27e --- /dev/null +++ b/src/adaptors/velocimeter-v2/abis/Option.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"},{"internalType":"address","name":"_underlyingToken","type":"address"},{"internalType":"contract IPair","name":"_pair","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_votingEscrow","type":"address"},{"internalType":"address","name":"_router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"OptionToken_IncorrectPairToken","type":"error"},{"inputs":[],"name":"OptionToken_InvalidDiscount","type":"error"},{"inputs":[],"name":"OptionToken_InvalidLockDuration","type":"error"},{"inputs":[],"name":"OptionToken_InvalidTeamFee","type":"error"},{"inputs":[],"name":"OptionToken_InvalidTwapPoints","type":"error"},{"inputs":[],"name":"OptionToken_NoAdminRole","type":"error"},{"inputs":[],"name":"OptionToken_NoMinterRole","type":"error"},{"inputs":[],"name":"OptionToken_NoPauserRole","type":"error"},{"inputs":[],"name":"OptionToken_PastDeadline","type":"error"},{"inputs":[],"name":"OptionToken_Paused","type":"error"},{"inputs":[],"name":"OptionToken_SlippageTooHigh","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"}],"name":"Exercise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"}],"name":"ExerciseLp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"ExerciseVe","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"discount","type":"uint256"}],"name":"SetDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGauge","type":"address"}],"name":"SetGauge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockDurationForMaxLpDiscount","type":"uint256"}],"name":"SetLockDurationForMaxLpDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockDurationForMinLpDiscount","type":"uint256"}],"name":"SetLockDurationForMinLpDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lpMaxDiscount","type":"uint256"}],"name":"SetMaxLPDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lpMinDiscount","type":"uint256"}],"name":"SetMinLPDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IPair","name":"newPair","type":"address"},{"indexed":true,"internalType":"address","name":"newPaymentToken","type":"address"}],"name":"SetPairAndPaymentToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newRouter","type":"address"}],"name":"SetRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"SetTeamFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"SetTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"twapPoints","type":"uint256"}],"name":"SetTwapPoints","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"veDiscount","type":"uint256"}],"name":"SetVeDiscount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FULL_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DISCOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TEAM_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TWAP_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_DISCOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exercise","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"exercise","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_discount","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exerciseLp","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPaymentAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"exerciseVe","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getLockDurationForLpDiscount","outputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getLpDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"getPaymentTokenAmountForExerciseLp","outputs":[{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"uint256","name":"paymentAmountToAddLiquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSlopeInterceptForLpDiscount","outputs":[{"internalType":"int256","name":"slope","type":"int256"},{"internalType":"int256","name":"intercept","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getTimeWeightedAveragePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getVeDiscountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDurationForMaxLpDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDurationForMinLpDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLPDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minLPDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"contract IPair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paymentToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"setGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setLockDurationForMaxLpDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setLockDurationForMinLpDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpMaxDiscount","type":"uint256"}],"name":"setMaxLPDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpMinDiscount","type":"uint256"}],"name":"setMinLPDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPair","name":"_pair","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"}],"name":"setPairAndPaymentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setTeamFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_twapPoints","type":"uint256"}],"name":"setTwapPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_veDiscount","type":"uint256"}],"name":"setVeDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlyingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingEscrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/velocimeter-v2/abis/Pair.json b/src/adaptors/velocimeter-v2/abis/Pair.json new file mode 100644 index 0000000000..831cb3c121 --- /dev/null +++ b/src/adaptors/velocimeter-v2/abis/Pair.json @@ -0,0 +1,1041 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "current", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "blockTimestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "_reserve0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_reserve1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + }, + { + "internalType": "bool", + "name": "_stable", + "type": "bool" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { + "internalType": "uint256", + "name": "dec0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dec1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "r1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "st", + "type": "bool" + }, + { + "internalType": "address", + "name": "t0", + "type": "address" + }, + { + "internalType": "address", + "name": "t1", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + } + ], + "name": "prices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "granularity", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "points", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "window", + "type": "uint256" + } + ], + "name": "sample", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/velocimeter-v2/abis/PairFactory.json b/src/adaptors/velocimeter-v2/abis/PairFactory.json new file mode 100644 index 0000000000..66b19b7628 --- /dev/null +++ b/src/adaptors/velocimeter-v2/abis/PairFactory.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pauser","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"tank","type":"address"}],"name":"TankSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"voter","type":"address"}],"name":"VoterSet","type":"event"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesOverrides","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitializable","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFeesOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tank","type":"address"}],"name":"setTank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"}],"name":"setVoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tank","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/velocimeter-v2/abis/Voter.json b/src/adaptors/velocimeter-v2/abis/Voter.json new file mode 100644 index 0000000000..7a6eab7994 --- /dev/null +++ b/src/adaptors/velocimeter-v2/abis/Voter.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"__ve","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_gauges","type":"address"},{"internalType":"address","name":"_bribes","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Abstained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Attach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"blacklister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":false,"internalType":"address","name":"newBribeFatory","type":"address"}],"name":"BribeFactorySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Detach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"externalBribe","type":"address"}],"name":"ExternalBribeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"pairFactory","type":"address"},{"indexed":true,"internalType":"address","name":"gaugeFactory","type":"address"}],"name":"FactoryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"FactoryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"setter","type":"address"},{"indexed":true,"internalType":"address","name":"pairFactory","type":"address"},{"indexed":true,"internalType":"address","name":"gaugeFactory","type":"address"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"FactoryReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"external_bribe","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"GaugeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeKilledTotally","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeRestarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"_factories","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gaugeFactories","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_killedGauges","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"}],"name":"addFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"attachTokenToGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"blacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribefactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bribes","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimBribes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint256","name":"_gaugeType","type":"uint256"}],"name":"createGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"detachTokenFromGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"finish","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distro","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"external_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"factories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"gaugeFactories","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactoriesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_minter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAlive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGaugeFactory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"killGaugeTotally","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"killedGauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"killedGaugesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastVoted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"pauseGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"poke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolForGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolVote","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pos","type":"uint256"}],"name":"removeFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"uint256","name":"_pos","type":"uint256"}],"name":"replaceFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"reset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"restartGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bribeFactory","type":"address"}],"name":"setBribeFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_council","type":"address"}],"name":"setEmergencyCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_external","type":"address"}],"name":"setExternalBribeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"name":"setGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"updateFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"updateForRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedWeights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"_poolVote","type":"address[]"},{"internalType":"uint256[]","name":"_weights","type":"uint256[]"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/src/adaptors/velocimeter-v2/index.js b/src/adaptors/velocimeter-v2/index.js new file mode 100644 index 0000000000..3ddeed888b --- /dev/null +++ b/src/adaptors/velocimeter-v2/index.js @@ -0,0 +1,261 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const abiPairFactory = require('./abis/PairFactory.json'); +const abiGauge = require('./abis/Gauge.json'); +const abiPair = require('./abis/Pair.json'); +const abiVoter = require('./abis/Voter.json'); +const abiOption = require('./abis/Option.json'); + +const pairFactory = '0xe21Aac7F113Bd5DC2389e4d8a8db854a87fD6951'; +const voter = '0xab9B68c9e53c94D7c0949FB909E80e4a29F9134A'; + +const chain = 'base'; + +const oBVM = '0x762eb51d2e779eeec9b239ffb0b2ec8262848f3e'; +const BVM = '0xd386a121991E51Eab5e3433Bf5B1cF4C8884b47a'; + +// option to buy underlying token at a discount +// we'll need to update this if more options are added as there's no way to get the list of options from the contracts +const optionTokenToGovToken = { + [oBVM.toLowerCase()]: BVM.toLowerCase(), + ['0x6c743ee9ef26b445d80f19cc783e89b43dcffa07'.toLowerCase()]: + '0x356BDb09C6D095464a3B009C64920a8BDa629060'.toLowerCase(), // oSmooth smooth +}; + +const getApy = async () => { + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain, + }) + ).output; + + let allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain, + }) + ).output.map((o) => o.output); + + let metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain, + }) + ).output.map((o) => o.output); + + const tokens = [...new Set(metaData.map((m) => [m.t0, m.t1]).flat())].map( + (t) => t.toLowerCase() + ); + + const priceKeys = tokens.map((i) => `${chain}:${i}`).join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const optionTokens = Object.keys(optionTokenToGovToken); + // get discount for redeeming option token to liquidity token + const discounts = ( + await sdk.api.abi.multiCall({ + calls: optionTokens.map((optionToken) => ({ + target: optionToken, + })), + abi: abiOption.find((m) => m.name === 'discount'), + chain, + }) + ).output + .map((o) => 100 - parseFloat(o.output)) + .map((discount, index) => ({ + [optionTokens[index]]: discount, + })); + + // calculate profit from option token + // oTokenPrice = (underlyingTokenPrice * discount) / 100 + /** + * @type {Object.} + */ + const optionTokenPrices = optionTokens + .map((optionToken, index) => { + const underlyingToken = optionTokenToGovToken[optionToken]; + const underlyingTokenPrice = + prices[`${chain}:${underlyingToken.toLowerCase()}`]?.price; + + const discount = discounts[index][optionToken]; + return (underlyingTokenPrice * discount) / 100; + }) + .reduce((acc, cur, index) => { + acc[optionTokens[index]] = isNaN(cur) ? 0 : cur; + return acc; + }, {}); + + let symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain, + }) + ).output.map((o) => o.output); + + let gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain, + }) + ).output.map((o) => o.output); + + // we have some gauges set to null address 0x0000000000000000000000000000000000000000 + // and they're not supported in sdk4 as target value + // thus we need to filter them out + const nullAddress = '0x0000000000000000000000000000000000000000'; + allPairs = allPairs.filter((pair, index) => gauges[index] != nullAddress); + metaData = metaData.filter((meta, index) => gauges[index] != nullAddress); + symbols = symbols.filter((symbol, index) => gauges[index] != nullAddress); + gauges = gauges.filter((gauge) => gauge != nullAddress); + + const rewardsListLengthForGauges = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewardsListLength'), + calls: gauges.map((i) => ({ + target: i, + })), + chain, + }) + ).output.map((o) => o.output); + + // one gauge might have multiple reward tokens + const rewardTokensAndRates = await Promise.all( + // get all reward tokens for each gauge + rewardsListLengthForGauges.map(async (i, index) => { + const gauge = gauges[index]; + return ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewards'), + calls: [...Array(Number(i ?? 0)).keys()].map((j) => ({ + target: gauge, + params: [j], + })), + chain, + }) + ).output.map((o) => o.output); + }) + ).then(async (rewardTokensForGauges) => { + // get reward rate of each reward token + return await Promise.all( + rewardTokensForGauges.map(async (rewardTokensOfGauge, index) => { + const rates = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'rewardRate'), + calls: rewardTokensOfGauge.map((rewardToken) => ({ + target: gauges[index], + params: [rewardToken], + })), + chain, + }) + ).output.map((o) => o.output); + + const left = ( + await sdk.api.abi.multiCall({ + abi: abiGauge.find((m) => m.name === 'left'), + calls: rewardTokensOfGauge.map((rewardToken) => ({ + target: gauges[index], + params: [rewardToken], + })), + chain, + }) + ).output.map((o) => o.output); + + return rates.map((rate, index) => { + // if left is 0, the reward rate will be 0 + if (left[index] === '0') { + return '0'; + } + return rate; + }); + }) + ).then((rewardRatesForGauges) => { + return rewardRatesForGauges.map((rewardRatesOfGauge, index) => { + const rewardTokensOfGauge = rewardTokensForGauges[index]; + return rewardRatesOfGauge.map((rate, index) => { + const rewardToken = rewardTokensOfGauge[index].toLowerCase(); + if (rewardToken === BVM.toLowerCase()) { + // FVM reward will be converted to oFVM when claiming + return [oBVM, rate]; + } + return [rewardToken, rate]; + }); + }); + }); + }); + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + const p0 = prices[`${chain}:${poolMeta.t0.toLowerCase()}`]?.price; + const p1 = prices[`${chain}:${poolMeta.t1.toLowerCase()}`]?.price; + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const totalRewardPerDay = rewardTokensAndRates[i].reduce( + (acc, [rewardToken, rewardRate]) => { + let tokenPrice = 0; + if (optionTokenPrices[rewardToken.toLowerCase()]) { + tokenPrice = optionTokenPrices[rewardToken.toLowerCase()]; + } else if (prices[`${chain}:${rewardToken.toLowerCase()}`]) { + tokenPrice = prices[`${chain}:${rewardToken.toLowerCase()}`]?.price; + } + + const reward = ((rewardRate * 60 * 60 * 24) / 1e18) * tokenPrice; + + return acc + reward; + }, + 0 + ); + + // tvlUsd is used here instead of stakedUsd + const apyReward = ((totalRewardPerDay * 365) / tvlUsd) * 100; + + const rewardTokens = rewardTokensAndRates[i].map(([token]) => + token.toLowerCase() + ); + + return { + pool: p, + chain: utils.formatChain(chain), + project: 'velocimeter-v2', + symbol: utils.formatSymbol(s.split('-')[1]), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [...new Set(rewardTokens)] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + url: `https://base.velocimeter.xyz/liquidity/${p}`, + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/velodrome-v1/abiGauge.json b/src/adaptors/velodrome-v1/abiGauge.json new file mode 100644 index 0000000000..9e5acdc9a5 --- /dev/null +++ b/src/adaptors/velodrome-v1/abiGauge.json @@ -0,0 +1,328 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_forwarder", "type": "address" }, + { "internalType": "address", "name": "_stakingToken", "type": "address" }, + { + "internalType": "address", + "name": "_feesVotingReward", + "type": "address" + }, + { "internalType": "address", "name": "_rewardToken", "type": "address" }, + { "internalType": "address", "name": "_voter", "type": "address" }, + { "internalType": "bool", "name": "_isPool", "type": "bool" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "NotAlive", "type": "error" }, + { "inputs": [], "name": "NotAuthorized", "type": "error" }, + { "inputs": [], "name": "NotVoter", "type": "error" }, + { "inputs": [], "name": "RewardRateTooHigh", "type": "error" }, + { "inputs": [], "name": "ZeroAmount", "type": "error" }, + { "inputs": [], "name": "ZeroRewardRate", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_recipient", "type": "address" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feesVotingReward", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "forwarder", "type": "address" } + ], + "name": "isTrustedForwarder", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "left", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardRateByEpoch", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "rewards", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/velodrome-v1/abiPool.json b/src/adaptors/velodrome-v1/abiPool.json new file mode 100644 index 0000000000..f9452586bb --- /dev/null +++ b/src/adaptors/velodrome-v1/abiPool.json @@ -0,0 +1,759 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { "inputs": [], "name": "BelowMinimumK", "type": "error" }, + { "inputs": [], "name": "DepositsNotEqual", "type": "error" }, + { "inputs": [], "name": "FactoryAlreadySet", "type": "error" }, + { "inputs": [], "name": "InsufficientInputAmount", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidity", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidityBurned", "type": "error" }, + { "inputs": [], "name": "InsufficientLiquidityMinted", "type": "error" }, + { "inputs": [], "name": "InsufficientOutputAmount", "type": "error" }, + { "inputs": [], "name": "InvalidTo", "type": "error" }, + { "inputs": [], "name": "IsPaused", "type": "error" }, + { "inputs": [], "name": "K", "type": "error" }, + { "inputs": [], "name": "NotEmergencyCouncil", "type": "error" }, + { + "inputs": [{ "internalType": "string", "name": "str", "type": "string" }], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "version", "type": "string" }, + { "internalType": "uint256", "name": "chainId", "type": "uint256" }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, + { "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token0", "type": "address" }, + { "internalType": "address", "name": "_token1", "type": "address" }, + { "internalType": "bool", "name": "_stable", "type": "bool" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pool.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolFees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "__name", "type": "string" } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "__symbol", "type": "string" } + ], + "name": "setSymbol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/velodrome-v1/abiPoolFactory.json b/src/adaptors/velodrome-v1/abiPoolFactory.json new file mode 100644 index 0000000000..5c1822244b --- /dev/null +++ b/src/adaptors/velodrome-v1/abiPoolFactory.json @@ -0,0 +1,406 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "FeeInvalid", "type": "error" }, + { "inputs": [], "name": "FeeTooHigh", "type": "error" }, + { "inputs": [], "name": "InvalidPool", "type": "error" }, + { "inputs": [], "name": "NotFeeManager", "type": "error" }, + { "inputs": [], "name": "NotPauser", "type": "error" }, + { "inputs": [], "name": "NotSinkConverter", "type": "error" }, + { "inputs": [], "name": "NotVoter", "type": "error" }, + { "inputs": [], "name": "PoolAlreadyExists", "type": "error" }, + { "inputs": [], "name": "SameAddress", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { "inputs": [], "name": "ZeroFee", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "SetCustomFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeManager", + "type": "address" + } + ], + "name": "SetFeeManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "SetPauseState", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pauser", + "type": "address" + } + ], + "name": "SetPauser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "voter", + "type": "address" + } + ], + "name": "SetVoter", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ZERO_FEE_INDICATOR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPoolsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "createPool", + "outputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "customFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "bool", "name": "_stable", "type": "bool" } + ], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "uint24", "name": "fee", "type": "uint24" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "getPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" } + ], + "name": "isPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauser", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "pool", "type": "address" }, + { "internalType": "uint256", "name": "fee", "type": "uint256" } + ], + "name": "setCustomFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bool", "name": "_stable", "type": "bool" }, + { "internalType": "uint256", "name": "_fee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPauseState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pauser", "type": "address" } + ], + "name": "setPauser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sinkConverter", + "type": "address" + }, + { "internalType": "address", "name": "_velo", "type": "address" }, + { "internalType": "address", "name": "_veloV2", "type": "address" } + ], + "name": "setSinkConverter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_voter", "type": "address" } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sinkConverter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "velo", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "veloV2", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/velodrome-v1/abiVoter.json b/src/adaptors/velodrome-v1/abiVoter.json new file mode 100644 index 0000000000..822d5fc9c1 --- /dev/null +++ b/src/adaptors/velodrome-v1/abiVoter.json @@ -0,0 +1,789 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_forwarder", "type": "address" }, + { "internalType": "address", "name": "_ve", "type": "address" }, + { + "internalType": "address", + "name": "_factoryRegistry", + "type": "address" + }, + { "internalType": "address", "name": "_v1Factory", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AlreadyVotedOrDeposited", "type": "error" }, + { "inputs": [], "name": "DistributeWindow", "type": "error" }, + { "inputs": [], "name": "FactoryPathNotApproved", "type": "error" }, + { "inputs": [], "name": "GaugeAlreadyKilled", "type": "error" }, + { "inputs": [], "name": "GaugeAlreadyRevived", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "GaugeDoesNotExist", + "type": "error" + }, + { "inputs": [], "name": "GaugeExists", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "GaugeNotAlive", + "type": "error" + }, + { "inputs": [], "name": "InactiveManagedNFT", "type": "error" }, + { "inputs": [], "name": "MaximumVotingNumberTooLow", "type": "error" }, + { "inputs": [], "name": "NonZeroVotes", "type": "error" }, + { "inputs": [], "name": "NotAPool", "type": "error" }, + { "inputs": [], "name": "NotApprovedOrOwner", "type": "error" }, + { "inputs": [], "name": "NotEmergencyCouncil", "type": "error" }, + { "inputs": [], "name": "NotGovernor", "type": "error" }, + { "inputs": [], "name": "NotMinter", "type": "error" }, + { "inputs": [], "name": "NotWhitelistedNFT", "type": "error" }, + { "inputs": [], "name": "NotWhitelistedToken", "type": "error" }, + { "inputs": [], "name": "SameValue", "type": "error" }, + { "inputs": [], "name": "SpecialVotingWindow", "type": "error" }, + { "inputs": [], "name": "TooManyPools", "type": "error" }, + { "inputs": [], "name": "UnequalLengths", "type": "error" }, + { "inputs": [], "name": "ZeroAddress", "type": "error" }, + { "inputs": [], "name": "ZeroBalance", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "poolFactory", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "votingRewardsFactory", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gaugeFactory", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "bribeVotingReward", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeVotingReward", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_bool", + "type": "bool" + } + ], + "name": "WhitelistNFT", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "_bool", + "type": "bool" + } + ], + "name": "WhitelistToken", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_fees", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolFactory", "type": "address" }, + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_mTokenId", "type": "uint256" } + ], + "name": "depositManaged", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_start", "type": "uint256" }, + { "internalType": "uint256", "name": "_finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epochGovernor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochNext", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochVoteEnd", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_timestamp", "type": "uint256" } + ], + "name": "epochVoteStart", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "factoryRegistry", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forwarder", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugeToBribe", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugeToFees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "forwarder", "type": "address" } + ], + "name": "isTrustedForwarder", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "isWhitelistedNFT", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelistedToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxVotingNum", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_epochGovernor", "type": "address" } + ], + "name": "setEpochGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_maxVotingNum", "type": "uint256" } + ], + "name": "setMaxVotingNum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "v1Factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "bool", "name": "_bool", "type": "bool" } + ], + "name": "whitelistNFT", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "bool", "name": "_bool", "type": "bool" } + ], + "name": "whitelistToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "withdrawManaged", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/velodrome-v1/index.ts b/src/adaptors/velodrome-v1/index.ts new file mode 100644 index 0000000000..c653a1acd4 --- /dev/null +++ b/src/adaptors/velodrome-v1/index.ts @@ -0,0 +1,44 @@ +const utils = require('../utils'); + +const API_URL: string = 'https://api.velodrome.finance/api/v1/pairs'; + +const project = 'velodrome-v1'; + +interface Pool { + address: string; + token0: { address: string; symbol: string }; + token1: Pool['token0']; + tvl: number; + apr: number; +} + +interface Response { + data: Array; +} + +const apy = async () => { + const { data: poolsRes }: Response = await utils.getData(API_URL); + + const pools = poolsRes.map((pool) => { + return { + pool: pool.address, + chain: utils.formatChain('optimism'), + project, + symbol: `${pool.token0.symbol}-${pool.token1.symbol}`, + tvlUsd: pool.tvl, + apyReward: pool.apr, + underlyingTokens: [pool.token0.address, pool.token1.address], + rewardTokens: [ + '0x3c8B650257cFb5f272f799F5e2b4e65093a11a05', // velo + ], + url: 'https://app.velodrome.finance/liquidity', + }; + }); + + return pools; +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/velodrome-v2/index.js b/src/adaptors/velodrome-v2/index.js new file mode 100644 index 0000000000..160a1390d6 --- /dev/null +++ b/src/adaptors/velodrome-v2/index.js @@ -0,0 +1,225 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const abiPoolFactory = require('../velodrome-v1/abiPoolFactory.json'); +const abiPool = require('../velodrome-v1/abiPool.json'); +const abiVoter = require('../velodrome-v1/abiVoter.json'); +const abiGauge = require('../velodrome-v1/abiGauge.json'); + +const PoolFactory = '0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a'; +const sinkConverter = '0x585Af0b397AC42dbeF7f18395426BF878634f18D'; +const Voter = '0x41C914ee0c7E1A5edCD0295623e6dC557B5aBf3C'; +const velo = '0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db'; +const chain = 'optimism'; +const project = 'velodrome-v2'; + +const apy = async () => { + const allPoolsLength = ( + await sdk.api.abi.call({ + target: PoolFactory, + chain, + abi: abiPoolFactory.find((i) => i.name === 'allPoolsLength'), + }) + ).output; + + const allPools = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPoolsLength)).keys()].map((i) => ({ + target: PoolFactory, + params: [i], + })), + chain, + abi: abiPoolFactory.find((i) => i.name === 'allPools'), + }) + ).output + .map((o) => o.output) + .filter((p) => p !== sinkConverter); + + const poolFees = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: i, + })), + chain, + abi: abiPool.find((i) => i.name === 'poolFees'), + }) + ).output.map((o) => o.output); + + const metadata = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: i, + })), + chain, + abi: abiPool.find((i) => i.name === 'metadata'), + }) + ).output.map((o) => o.output); + + const feeBalanceNow = await Promise.all( + poolFees.map((p, i) => + sdk.api.abi.multiCall({ + calls: [ + { target: metadata[i].t0, params: poolFees[i] }, + { target: metadata[i].t1, params: poolFees[i] }, + ], + chain, + abi: 'erc20:balanceOf', + }) + ) + ); + + const feeStable = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: PoolFactory, + params: [i, true], + })), + chain, + abi: abiPoolFactory.find((i) => i.name === 'getFee'), + }) + ).output.map((o) => o.output); + + const feeVolatile = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ + target: PoolFactory, + params: [i, false], + })), + chain, + abi: abiPoolFactory.find((i) => i.name === 'getFee'), + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ target: i })), + chain, + abi: 'erc20:symbol', + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ target: Voter, params: [i] })), + chain, + abi: abiVoter.find((i) => i.name === 'gauges'), + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ target: i })), + chain, + abi: abiGauge.find((i) => i.name === 'rewardRate'), + permitFailure: true, + }) + ).output.map((o) => o.output); + + const poolSupply = ( + await sdk.api.abi.multiCall({ + calls: allPools.map((i) => ({ target: i })), + chain, + abi: 'erc20:totalSupply', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const gaugeSupply = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ target: i })), + chain, + abi: 'erc20:totalSupply', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const uniqueTokens = [...new Set(metadata.map((i) => [i.t0, i.t1]).flat())]; + + const maxSize = 50; + const pages = Math.ceil(uniqueTokens.length / maxSize); + let prices_ = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = uniqueTokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((t) => `optimism:${t}`) + .join(','); + prices_ = [ + ...prices_, + (await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + ]; + } + // flatten + let prices = {}; + for (const p of prices_.flat()) { + prices = { ...prices, ...p }; + } + + const pools = allPools.map((p, i) => { + const meta = metadata[i]; + const r0 = meta.r0 / meta.dec0; + const r1 = meta.r1 / meta.dec1; + + const p0 = prices[`optimism:${meta.t0}`]?.price; + const p1 = prices[`optimism:${meta.t1}`]?.price; + + const price0 = p0 || 0; + const price1 = p1 || 0; + + const tvlUsd = + price0 === 0 && price1 === 0 + ? 0 + : price0 === 0 + ? r1 * price1 * 2 + : price1 === 0 + ? r0 * price0 * 2 + : r0 * price0 + r1 * price1; + + const symbol = symbols[i].split('-')[1]; + + // Only staked supply is eligible for the rewardRate's emissions + let stakedSupplyRatio = 1; + if (gaugeSupply[i] !== 0) { + stakedSupplyRatio = poolSupply[i] / gaugeSupply[i]; + } + + const apyReward = + (((rewardRate[i] / 1e18) * + 86400 * + 365 * + prices[`optimism:${velo}`]?.price) / + tvlUsd) * stakedSupplyRatio * 100; + + const feeTier = meta.st + ? `${feeStable[i] / 100}` + : `${feeVolatile[i] / 100}`; + const poolMeta = meta.st + ? `stable - ${feeTier}%` + : `volatile - ${feeTier}%`; + + const url = + `https://app.velodrome.finance/deposit?token0=${meta.t0}&token1=${meta.t1}&stable=${meta.st}`.toLowerCase(); + + return { + pool: p, + chain: 'Optimism', + project, + symbol: utils.formatSymbol(symbol), + tvlUsd, + apyReward, + rewardTokens: apyReward > 0 ? [velo] : [], + poolMeta, + url, + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/velodrome-v3/abiSugar.json b/src/adaptors/velodrome-v3/abiSugar.json new file mode 100644 index 0000000000..62d1d0faf5 --- /dev/null +++ b/src/adaptors/velodrome-v3/abiSugar.json @@ -0,0 +1,835 @@ +[ + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { + "name": "_voter", + "type": "address" + }, + { + "name": "_registry", + "type": "address" + }, + { + "name": "_convertor", + "type": "address" + }, + { + "name": "_slipstream_helper", + "type": "address" + } + ], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "forSwaps", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "tokens", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + }, + { + "name": "_addresses", + "type": "address[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "token_address", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "account_balance", + "type": "uint256" + }, + { + "name": "listed", + "type": "bool" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "all", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "tick", + "type": "int24" + }, + { + "name": "sqrt_ratio", + "type": "uint160" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "reserve0", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "reserve1", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "gauge", + "type": "address" + }, + { + "name": "gauge_liquidity", + "type": "uint256" + }, + { + "name": "gauge_alive", + "type": "bool" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "emissions_token", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + }, + { + "name": "unstaked_fee", + "type": "uint256" + }, + { + "name": "token0_fees", + "type": "uint256" + }, + { + "name": "token1_fees", + "type": "uint256" + }, + { + "name": "nfpm", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "byIndex", + "inputs": [ + { + "name": "_index", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "components": [ + { + "name": "lp", + "type": "address" + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "decimals", + "type": "uint8" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "type", + "type": "int24" + }, + { + "name": "tick", + "type": "int24" + }, + { + "name": "sqrt_ratio", + "type": "uint160" + }, + { + "name": "token0", + "type": "address" + }, + { + "name": "reserve0", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "token1", + "type": "address" + }, + { + "name": "reserve1", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "gauge", + "type": "address" + }, + { + "name": "gauge_liquidity", + "type": "uint256" + }, + { + "name": "gauge_alive", + "type": "bool" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + }, + { + "name": "factory", + "type": "address" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "emissions_token", + "type": "address" + }, + { + "name": "pool_fee", + "type": "uint256" + }, + { + "name": "unstaked_fee", + "type": "uint256" + }, + { + "name": "token0_fees", + "type": "uint256" + }, + { + "name": "token1_fees", + "type": "uint256" + }, + { + "name": "nfpm", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "positions", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "staked", + "type": "uint256" + }, + { + "name": "amount0", + "type": "uint256" + }, + { + "name": "amount1", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "unstaked_earned0", + "type": "uint256" + }, + { + "name": "unstaked_earned1", + "type": "uint256" + }, + { + "name": "emissions_earned", + "type": "uint256" + }, + { + "name": "tick_lower", + "type": "int24" + }, + { + "name": "tick_upper", + "type": "int24" + }, + { + "name": "sqrt_ratio_lower", + "type": "uint160" + }, + { + "name": "sqrt_ratio_upper", + "type": "uint160" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "positionsByFactory", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_account", + "type": "address" + }, + { + "name": "_factory", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "liquidity", + "type": "uint256" + }, + { + "name": "staked", + "type": "uint256" + }, + { + "name": "amount0", + "type": "uint256" + }, + { + "name": "amount1", + "type": "uint256" + }, + { + "name": "staked0", + "type": "uint256" + }, + { + "name": "staked1", + "type": "uint256" + }, + { + "name": "unstaked_earned0", + "type": "uint256" + }, + { + "name": "unstaked_earned1", + "type": "uint256" + }, + { + "name": "emissions_earned", + "type": "uint256" + }, + { + "name": "tick_lower", + "type": "int24" + }, + { + "name": "tick_upper", + "type": "int24" + }, + { + "name": "sqrt_ratio_lower", + "type": "uint160" + }, + { + "name": "sqrt_ratio_upper", + "type": "uint160" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "epochsLatest", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "ts", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "votes", + "type": "uint256" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "bribes", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + }, + { + "name": "fees", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "epochsByAddress", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_address", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "ts", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "votes", + "type": "uint256" + }, + { + "name": "emissions", + "type": "uint256" + }, + { + "name": "bribes", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + }, + { + "name": "fees", + "type": "tuple[]", + "components": [ + { + "name": "token", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ] + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewards", + "inputs": [ + { + "name": "_limit", + "type": "uint256" + }, + { + "name": "_offset", + "type": "uint256" + }, + { + "name": "_venft_id", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "venft_id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + }, + { + "name": "token", + "type": "address" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "rewardsByAddress", + "inputs": [ + { + "name": "_venft_id", + "type": "uint256" + }, + { + "name": "_pool", + "type": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "components": [ + { + "name": "venft_id", + "type": "uint256" + }, + { + "name": "lp", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + }, + { + "name": "token", + "type": "address" + }, + { + "name": "fee", + "type": "address" + }, + { + "name": "bribe", + "type": "address" + } + ] + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "registry", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "voter", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "convertor", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "cl_helper", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/velodrome-v3/abiSugarHelper.json b/src/adaptors/velodrome-v3/abiSugarHelper.json new file mode 100644 index 0000000000..390f7fa951 --- /dev/null +++ b/src/adaptors/velodrome-v3/abiSugarHelper.json @@ -0,0 +1,533 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tickLow", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickHigh", + "type": "int24" + } + ], + "name": "estimateAmount0", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tickLow", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickHigh", + "type": "int24" + } + ], + "name": "estimateAmount1", + "outputs": [ + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "positionManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "fees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "getAmount0Delta", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidity", + "type": "int128" + } + ], + "name": "getAmount0Delta", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "getAmount0ForLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidity", + "type": "int128" + } + ], + "name": "getAmount1Delta", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "roundUp", + "type": "bool" + } + ], + "name": "getAmount1Delta", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "getAmount1ForLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "getAmountsForLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioAX96", + "type": "uint160" + }, + { + "internalType": "uint160", + "name": "sqrtRatioBX96", + "type": "uint160" + } + ], + "name": "getLiquidityForAmounts", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "startTick", + "type": "int24" + } + ], + "name": "getPopulatedTicks", + "outputs": [ + { + "components": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + } + ], + "internalType": "struct ISugarHelper.PopulatedTick[]", + "name": "populatedTicks", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "getSqrtRatioAtTick", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "getTickAtSqrtRatio", + "outputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "int24", + "name": "tickCurrent", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "poolFees", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract INonfungiblePositionManager", + "name": "positionManager", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtRatioX96", + "type": "uint160" + } + ], + "name": "principal", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/velodrome-v3/index.js b/src/adaptors/velodrome-v3/index.js new file mode 100644 index 0000000000..4e651621fc --- /dev/null +++ b/src/adaptors/velodrome-v3/index.js @@ -0,0 +1,176 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); + +const abiSugar = require('./abiSugar.json'); +const abiSugarHelper = require('./abiSugarHelper.json'); + +const VELO = '0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db'; +const sugar = '0x766133beae539ed33a7e27dfa3a840deaad88947'; +const sugarHelper = '0x5Bd7E2221C2d59c99e6A9Cd18D80A5F4257D0f32'; +const nullAddress = '0x0000000000000000000000000000000000000000'; + +const tickWidthMappings = {1: 5, 50: 5, 100: 15, 200: 10, 2000: 2}; + +const getApy = async () => { + + const chunkSize = 400; + let currentOffset = 630; // Ignore older non-Slipstream pools + let unfinished = true; + let allPoolsData = []; + + while (unfinished) { + const poolsChunkUnfiltered = ( + await sdk.api.abi.call({ + target: sugar, + params: [chunkSize, currentOffset], + abi: abiSugar.find((m) => m.name === 'all'), + chain: 'optimism', + }) + ).output; + + const poolsChunk = poolsChunkUnfiltered.filter(t => Number(t.type) > 0 && t.gauge != nullAddress); + + unfinished = poolsChunkUnfiltered.length !== 0; + currentOffset += chunkSize; + allPoolsData.push(...poolsChunk); + } + + unfinished = true; + currentOffset = 0; + let allTokenData = []; + + while (unfinished) { + const tokensChunk = ( + await sdk.api.abi.call({ + target: sugar, + params: [chunkSize, currentOffset, sugar, []], + abi: abiSugar.find((m) => m.name === 'tokens'), + chain: 'optimism', + }) + ).output; + + unfinished = tokensChunk.length !== 0; + currentOffset += chunkSize; + allTokenData.push(...tokensChunk); + } + + const tokens = [ + ...new Set( + allPoolsData + .map((m) => [m.token0, m.token1]) + .flat() + .concat(VELO) + ), + ]; + + const maxSize = 50; + const pages = Math.ceil(tokens.length / maxSize); + let pricesA = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = tokens + .slice(p * maxSize, maxSize * (p + 1)) + .map((i) => `optimism:${i}`) + .join(',') + .replaceAll('/', ''); + pricesA = [ + ...pricesA, + (await axios.get(`https://coins.llama.fi/prices/current/${x}`)).data + .coins, + ]; + } + let prices = {}; + for (const p of pricesA.flat()) { + prices = { ...prices, ...p }; + } + + let allStakedData = []; + for (const pool of allPoolsData) { + // don't waste RPC calls if gauge has no staked liquidity + if (Number(pool.gauge_liquidity) == 0) { + allStakedData.push({'amount0': 0, 'amount1': 0}); + continue; + } + + const wideTickAmount = tickWidthMappings[Number(pool.type)] !== undefined ? tickWidthMappings[Number(pool.type)] : 5; + const lowTick = Number(pool.tick) - (wideTickAmount * Number(pool.type)); + const highTick = Number(pool.tick) + ((wideTickAmount - 1) * Number(pool.type)); + + try { + const ratioA = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [lowTick], + abi: abiSugarHelper.find((m) => m.name === 'getSqrtRatioAtTick'), + chain: 'optimism', + }) + ).output; + + const ratioB = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [highTick], + abi: abiSugarHelper.find((m) => m.name === 'getSqrtRatioAtTick'), + chain: 'optimism', + }) + ).output; + + // fetch staked liquidity around wide set of ticks + const stakedAmounts = ( + await sdk.api.abi.call({ + target: sugarHelper, + params: [pool.sqrt_ratio, ratioA, ratioB, pool.gauge_liquidity], + abi: abiSugarHelper.find((m) => m.name === 'getAmountsForLiquidity'), + chain: 'optimism', + }) + ).output; + + allStakedData.push(stakedAmounts); + } catch(e) { + allStakedData.push({'amount0': 0, 'amount1': 0}); + } + } + + const pools = allPoolsData.map((p, i) => { + const token0Data = allTokenData.find(({token_address}) => token_address == p.token0); + const token1Data = allTokenData.find(({token_address}) => token_address == p.token1); + + const p0 = prices[`optimism:${p.token0}`]?.price; + const p1 = prices[`optimism:${p.token1}`]?.price; + + const tvlUsd = ((p.reserve0 / (10**Number(token0Data.decimals))) * p0) + ((p.reserve1 / (10**Number(token1Data.decimals))) * p1); + + // use wider staked TVL across many ticks + const stakedTvlUsd = ((allStakedData[i]['amount0'] / (10**token0Data.decimals)) * p0) + ((allStakedData[i]['amount1'] / (10**token1Data.decimals)) * p1); + + const s = token0Data.symbol + '-' + token1Data.symbol; + + const veloPrice = prices[`optimism:${VELO}`]?.price + const apyReward = (((p.emissions / 1e18) * 86400 * 365 * veloPrice) / stakedTvlUsd) * 100; + + const url = 'https://velodrome.finance/deposit?token0=' + p.token0 + '&token1=' + p.token1 + '&type=' + p.type.toString() + '&factory=' + p.factory; + const poolMeta = 'CL' + p.type.toString() + ' - ' + (p.pool_fee / 10000).toString() + '%'; + + return { + pool: p.lp, + chain: utils.formatChain('optimism'), + project: 'velodrome-v3', + symbol: s, + tvlUsd, + apyReward, + rewardTokens: apyReward ? [VELO] : [], + underlyingTokens: [p.token0, p.token1], + poolMeta, + url, + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; \ No newline at end of file diff --git a/src/adaptors/vendor-v1/ContractABIs.js b/src/adaptors/vendor-v1/ContractABIs.js new file mode 100644 index 0000000000..f7f09ed085 --- /dev/null +++ b/src/adaptors/vendor-v1/ContractABIs.js @@ -0,0 +1,533 @@ +const FeesManagerABI = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'BorrowingPaused', + type: 'error', + }, + { + inputs: [], + name: 'ColTokenNotSupported', + type: 'error', + }, + { + inputs: [], + name: 'DebtIsLess', + type: 'error', + }, + { + inputs: [], + name: 'DifferentColToken', + type: 'error', + }, + { + inputs: [], + name: 'DifferentLendToken', + type: 'error', + }, + { + inputs: [], + name: 'DifferentPoolOwner', + type: 'error', + }, + { + inputs: [], + name: 'DiscountTooLarge', + type: 'error', + }, + { + inputs: [], + name: 'FeeTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'FeeTooLarge', + type: 'error', + }, + { + inputs: [], + name: 'FeedAlreadySet', + type: 'error', + }, + { + inputs: [], + name: 'IllegalImplementation', + type: 'error', + }, + { + inputs: [], + name: 'InsufficientBalance', + type: 'error', + }, + { + inputs: [], + name: 'InvalidDiscount', + type: 'error', + }, + { + inputs: [], + name: 'InvalidExpiry', + type: 'error', + }, + { + inputs: [], + name: 'InvalidParameters', + type: 'error', + }, + { + inputs: [], + name: 'InvalidTokenPair', + type: 'error', + }, + { + inputs: [], + name: 'InvalidType', + type: 'error', + }, + { + inputs: [], + name: 'LendTokenNotSupported', + type: 'error', + }, + { + inputs: [], + name: 'LicenseNotFound', + type: 'error', + }, + { + inputs: [], + name: 'MintRatio0', + type: 'error', + }, + { + inputs: [], + name: 'NoDebt', + type: 'error', + }, + { + inputs: [], + name: 'NoPermission', + type: 'error', + }, + { + inputs: [], + name: 'NotAPool', + type: 'error', + }, + { + inputs: [], + name: 'NotAuthorized', + type: 'error', + }, + { + inputs: [], + name: 'NotEnoughLiquidity', + type: 'error', + }, + { + inputs: [], + name: 'NotFactory', + type: 'error', + }, + { + inputs: [], + name: 'NotGranted', + type: 'error', + }, + { + inputs: [], + name: 'NotOwner', + type: 'error', + }, + { + inputs: [], + name: 'NotValidPrice', + type: 'error', + }, + { + inputs: [], + name: 'OperationsPaused', + type: 'error', + }, + { + inputs: [], + name: 'OracleNotSet', + type: 'error', + }, + { + inputs: [], + name: 'PoolActive', + type: 'error', + }, + { + inputs: [], + name: 'PoolClosed', + type: 'error', + }, + { + inputs: [], + name: 'PoolNotWhitelisted', + type: 'error', + }, + { + inputs: [], + name: 'PrivatePool', + type: 'error', + }, + { + inputs: [], + name: 'RoundIncomplete', + type: 'error', + }, + { + inputs: [], + name: 'StaleAnswer', + type: 'error', + }, + { + inputs: [], + name: 'TransferFailed', + type: 'error', + }, + { + inputs: [], + name: 'UpgradeNotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + indexed: false, + internalType: 'uint48', + name: '_feeRate', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint256', + name: '_type', + type: 'uint256', + }, + ], + name: 'ChangeFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + inputs: [], + name: 'factory', + outputs: [ + { + internalType: 'contract IPoolFactory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'feeRates', + outputs: [ + { + internalType: 'uint48', + name: '', + type: 'uint48', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + ], + name: 'getCurrentRate', + outputs: [ + { + internalType: 'uint48', + name: '', + type: 'uint48', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'uint256', + name: '_rawPayoutAmount', + type: 'uint256', + }, + ], + name: 'getFee', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolFactory', + name: '_factory', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'rateFunction', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'uint48', + name: '_feeRate', + type: 'uint48', + }, + { + internalType: 'uint256', + name: '_type', + type: 'uint256', + }, + ], + name: 'setPoolFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, +]; + +module.exports = { + FeesManagerABI, +}; diff --git a/src/adaptors/vendor-v1/index.js b/src/adaptors/vendor-v1/index.js new file mode 100644 index 0000000000..b77a5ddea0 --- /dev/null +++ b/src/adaptors/vendor-v1/index.js @@ -0,0 +1,194 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const axios = require('axios'); +const { ethers } = require('ethers'); +const networkData = require('./network-data'); +const utils = require('../utils'); +const { FeesManagerABI } = require('./ContractABIs'); + +const ENTITY_URL = process.env.VENDOR_FINANCE; +const ARBITRUM_FEES_MANAGER = '0x34F429e82dA625aBa84e80B5c2a9fa471771B807'; +const ETHEREUM_FEES_MANAGER = '0xeCBFd6cF5Eebe9313D386A19a42a474a2998e56b'; + +const getGenericTokenInfo = async (tokens, network) => { + const tokenSymbols = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((tokenAddr) => ({ + target: tokenAddr, + })), + chain: network, + }) + ).output; + const tokenDecimals = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((tokenAddr) => ({ + target: tokenAddr, + })), + chain: network, + }) + ).output; + return { tokenSymbols, tokenDecimals }; +}; + +const getAvailableLiquidity = async ( + pool, + lendTokenInfo, + lendDecimals, + network +) => { + const lendBalance = ( + await sdk.api.abi.call({ + target: pool._lendToken, + abi: 'erc20:balanceOf', + params: pool.id, + chain: network, + }) + ).output; + const formattedLendBal = ethers.utils.formatUnits( + lendBalance, + lendDecimals.output + ); + return Object.entries(lendTokenInfo)[0][1].price * formattedLendBal; +}; + +const getTokenPriceInfo = async (network, tokenAddresses) => { + const tokenDataPromises = tokenAddresses.map((address) => + utils.getData( + `https://coins.llama.fi/prices/current/${network.toLowerCase()}:${address.toLowerCase()}` + ) + ); + const tokenDataArray = await Promise.all(tokenDataPromises); + const tokenData = tokenDataArray.map((tokenInfo) => tokenInfo.coins); + return tokenData; +}; + +const getLoanToValue = (tokenInfo, pool) => { + // get token prices from tokenPrice context object + let lendPrice = Object.entries(tokenInfo[0])[0][1].price; + const colPrice = Object.entries(tokenInfo[1])[0][1].price; + // calculate LTV from lend and collateral prices + const mintRatio = ethers.utils.formatUnits(pool._mintRatio, 18); + const ltvLendValue = parseFloat(mintRatio) * lendPrice; + const ltvColValue = colPrice; + return ltvLendValue / ltvColValue; +}; + +const getSuppliedAndBorrowedUsd = async ( + pool, + lendDecimals, + colDecimals, + network, + tokenPriceInfo +) => { + const lendFee = ( + await sdk.api.abi.call({ + target: + network === 'arbitrum' ? ARBITRUM_FEES_MANAGER : ETHEREUM_FEES_MANAGER, + abi: FeesManagerABI.find( + (fragment) => fragment.name === 'getCurrentRate' + ), + chain: network, + params: pool.id, + }) + ).output; + const colBalance = ( + await sdk.api.abi.call({ + target: pool._colToken, + abi: 'erc20:balanceOf', + params: pool.id, + chain: network, + }) + ).output; + const lendBalance = ( + await sdk.api.abi.call({ + target: pool._lendToken, + abi: 'erc20:balanceOf', + params: pool.id, + chain: network, + }) + ).output; + // Calculated the total borrowed amount in $USD + let totalBorrowed = + parseFloat(pool._mintRatio / 10 ** 18) * + parseFloat(ethers.utils.formatUnits(colBalance, colDecimals.output)); + const poolFee = Number(lendFee) / 10000 / 100; + const protocolFee = pool._protocolFee / 1000000; + const totalBorrowedAdjusted = (totalBorrowed *= 1 - protocolFee - poolFee); + const lendTokenPrice = Object.entries(tokenPriceInfo)[0][1].price; + const totalBorrowedUsd = totalBorrowedAdjusted * lendTokenPrice; + // Calculates the total supplied amount (available lend balance + total borrowed) in $USD + const lendBalanceUsd = + lendTokenPrice * + parseFloat(ethers.utils.formatUnits(lendBalance, lendDecimals.output)); + const totalSuppliedUsd = lendBalanceUsd + totalBorrowed; + + return { totalBorrowedUsd, totalSuppliedUsd, lendFee }; +}; + +const getPools = async () => { + const pools = []; + for (const networkConfig of networkData.networkData) { + const response = await axios.post(ENTITY_URL, { + query: networkConfig.query, + type: networkConfig.type, + }); + const network = networkConfig.network.toLowerCase(); + for (const pool of Object.entries(response.data)[0][1]) { + const { tokenSymbols, tokenDecimals } = await getGenericTokenInfo( + [pool._lendToken, pool._colToken], + network + ); + const tokenPriceInfo = await getTokenPriceInfo(network, [ + pool._lendToken, + pool._colToken, + ]); + const availableLiquidity = await getAvailableLiquidity( + pool, + tokenPriceInfo[0], + tokenDecimals[0], + network + ); + const { totalBorrowedUsd, totalSuppliedUsd, lendFee } = + await getSuppliedAndBorrowedUsd( + pool, + tokenDecimals[0], + tokenDecimals[1], + network, + tokenPriceInfo[0] + ); + const loanToValue = getLoanToValue(tokenPriceInfo, pool); + const poolObj = { + pool: pool.id, + chain: networkConfig.network, + project: 'vendor-v1', + ltv: loanToValue, + underlyingTokens: [pool._lendToken, pool._colToken], + symbol: tokenSymbols[0].output, + tvlUsd: availableLiquidity, + totalBorrowUsd: totalBorrowedUsd, + totalSupplyUsd: totalSuppliedUsd, + apyBase: 0, + apyBaseBorrow: + pool._type == 1 + ? ((31536000 / + (Number(pool._expiry) - new Date().getTime() / 1000)) * + pool._feeRate) / + 10000 + : pool._feeRate / 10000, + poolMeta: `Due ${new Date(pool._expiry * 1000) + .toUTCString() + .slice(5, -13)}, ${tokenSymbols[1].output} collateral`, + }; + pools.push(poolObj); + } + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://v1.vendor.finance', +}; diff --git a/src/adaptors/vendor-v1/network-data.js b/src/adaptors/vendor-v1/network-data.js new file mode 100644 index 0000000000..bddf411a8b --- /dev/null +++ b/src/adaptors/vendor-v1/network-data.js @@ -0,0 +1,60 @@ +const arbitrum_query = { + query: ` + query { + pools( + first: 1000, where: { + _lendBalance_gt: 0, + _paused: false, + _expiry_gt: ${Math.floor(new Date().getTime() / 1000)} + } + ) { + id + _colToken + _lendToken + _type + _feeRate + _expiry + _mintRatio + _lendBalance + _protocolFee + } + } +`, +}; + +const ethereum_query = { + query: ` + query { + pools( + first: 1000, where: { + _lendBalance_gt: 0, + _paused: false, + _expiry_gt: ${Math.floor(new Date().getTime() / 1000)} + } + ) { + id + _colToken + _lendToken + _type + _feeRate + _expiry + _mintRatio + _lendBalance + _protocolFee + } + } +`, +}; + +exports.networkData = [ + { + network: 'Ethereum', + query: ethereum_query, + type: 'v1-Ethereum', + }, + { + network: 'Arbitrum', + query: arbitrum_query, + type: 'v1-Arbitrum', + }, +]; diff --git a/src/adaptors/vendor-v2/ContractABIs.js b/src/adaptors/vendor-v2/ContractABIs.js new file mode 100644 index 0000000000..5321d9079f --- /dev/null +++ b/src/adaptors/vendor-v2/ContractABIs.js @@ -0,0 +1,1445 @@ +const LendingPoolV2ABI = [ + { + inputs: [], + name: 'BorrowingPaused', + type: 'error', + }, + { + inputs: [], + name: 'DebtIsLess', + type: 'error', + }, + { + inputs: [], + name: 'FailedStrategyWithdraw', + type: 'error', + }, + { + inputs: [], + name: 'FeeTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'ImplementationNotWhitelisted', + type: 'error', + }, + { + inputs: [], + name: 'InvalidCollateralReceived', + type: 'error', + }, + { + inputs: [], + name: 'InvalidParameters', + type: 'error', + }, + { + inputs: [], + name: 'NoDebt', + type: 'error', + }, + { + inputs: [], + name: 'NotEnoughLiquidity', + type: 'error', + }, + { + inputs: [], + name: 'NotGranted', + type: 'error', + }, + { + inputs: [], + name: 'NotOwner', + type: 'error', + }, + { + inputs: [], + name: 'NotPrivatePool', + type: 'error', + }, + { + inputs: [], + name: 'NotValidPrice', + type: 'error', + }, + { + inputs: [], + name: 'OperationsPaused', + type: 'error', + }, + { + inputs: [], + name: 'PoolExpired', + type: 'error', + }, + { + inputs: [], + name: 'PoolNotWhitelisted', + type: 'error', + }, + { + inputs: [], + name: 'PoolStillActive', + type: 'error', + }, + { + inputs: [], + name: 'PrivatePool', + type: 'error', + }, + { + inputs: [], + name: 'RolloverPartialAmountNotSupported', + type: 'error', + }, + { + inputs: [], + name: 'TransferFailed', + type: 'error', + }, + { + inputs: [], + name: 'UpgradeNotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'incoming', + type: 'bool', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'BalanceChange', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'vendorFees', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lenderFees', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint48', + name: 'borrowRate', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint256', + name: 'additionalColAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'additionalDebt', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'lender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lenderLend', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lenderCol', + type: 'uint256', + }, + ], + name: 'Collect', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'lender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldOwner', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint48', + name: 'timestamp', + type: 'uint48', + }, + ], + name: 'Pause', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'debtRepaid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'colReturned', + type: 'uint256', + }, + ], + name: 'Repay', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'originPool', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'originDebt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lendToRepay', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lenderFeeAmt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'protocolFeeAmt', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'colRolled', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'colToReimburse', + type: 'uint256', + }, + ], + name: 'RollIn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'enabled', + type: 'bool', + }, + ], + name: 'RolloverPoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'allowed', + type: 'bool', + }, + ], + name: 'UpdateBorrower', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'lender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'sharesAmount', + type: 'uint256', + }, + ], + name: 'WithdrawStrategyTokens', + type: 'event', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'allowedBorrowers', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'allowedRollovers', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: '_colDepositAmount', + type: 'uint256', + }, + { + internalType: 'uint48', + name: '_rate', + type: 'uint48', + }, + ], + name: 'borrowOnBehalfOf', + outputs: [ + { + internalType: 'uint256', + name: 'assetsBorrowed', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lenderFees', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'vendorFees', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'claimOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'colBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'collect', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'debts', + outputs: [ + { + internalType: 'uint256', + name: 'debt', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'colAmount', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_depositAmount', + type: 'uint256', + }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'factory', + outputs: [ + { + internalType: 'contract IPoolFactory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'feesManager', + outputs: [ + { + internalType: 'contract IFeesManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPoolSettings', + outputs: [ + { + components: [ + { + internalType: 'enum PoolType', + name: 'poolType', + type: 'uint8', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint48', + name: 'expiry', + type: 'uint48', + }, + { + internalType: 'contract IERC20MetadataUpgradeable', + name: 'colToken', + type: 'address', + }, + { + internalType: 'uint48', + name: 'protocolFee', + type: 'uint48', + }, + { + internalType: 'contract IERC20MetadataUpgradeable', + name: 'lendToken', + type: 'address', + }, + { + internalType: 'uint48', + name: 'ltv', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'pauseTime', + type: 'uint48', + }, + { + internalType: 'uint256', + name: 'lendRatio', + type: 'uint256', + }, + { + internalType: 'address[]', + name: 'allowlist', + type: 'address[]', + }, + { + internalType: 'bytes32', + name: 'feeRatesAndType', + type: 'bytes32', + }, + ], + internalType: 'struct GeneralPoolSettings', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_newOwner', + type: 'address', + }, + ], + name: 'grantOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_factoryParametersBytes', + type: 'bytes', + }, + { + internalType: 'bytes', + name: '_poolSettingsBytes', + type: 'bytes', + }, + { + internalType: 'bytes', + name: '', + type: 'bytes', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'lendBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lenderTotalFees', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracle', + outputs: [ + { + internalType: 'contract IOracle', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolSettings', + outputs: [ + { + internalType: 'enum PoolType', + name: 'poolType', + type: 'uint8', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint48', + name: 'expiry', + type: 'uint48', + }, + { + internalType: 'contract IERC20MetadataUpgradeable', + name: 'colToken', + type: 'address', + }, + { + internalType: 'uint48', + name: 'protocolFee', + type: 'uint48', + }, + { + internalType: 'contract IERC20MetadataUpgradeable', + name: 'lendToken', + type: 'address', + }, + { + internalType: 'uint48', + name: 'ltv', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'pauseTime', + type: 'uint48', + }, + { + internalType: 'uint256', + name: 'lendRatio', + type: 'uint256', + }, + { + internalType: 'bytes32', + name: 'feeRatesAndType', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'positionTracker', + outputs: [ + { + internalType: 'contract IPositionTracker', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_borrower', + type: 'address', + }, + { + internalType: 'uint256', + name: '_repayAmount', + type: 'uint256', + }, + ], + name: 'repayOnBehalfOf', + outputs: [ + { + internalType: 'uint256', + name: 'lendTokenReceived', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'colReturnAmount', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_originPool', + type: 'address', + }, + { + internalType: 'uint256', + name: '_originDebt', + type: 'uint256', + }, + { + internalType: 'uint48', + name: '_rate', + type: 'uint48', + }, + ], + name: 'rollInFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint48', + name: '_timestamp', + type: 'uint48', + }, + ], + name: 'setPauseBorrowing', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_ratesAndType', + type: 'bytes32', + }, + ], + name: 'setPoolRates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bool', + name: '_enabled', + type: 'bool', + }, + ], + name: 'setRolloverPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'strategy', + outputs: [ + { + internalType: 'contract IStrategy', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'treasury', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_borrower', + type: 'address', + }, + { + internalType: 'bool', + name: '_allowed', + type: 'bool', + }, + ], + name: 'updateBorrower', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_withdrawAmount', + type: 'uint256', + }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawStrategyTokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; + +const FeesManagerABI = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'InvalidExpiry', + type: 'error', + }, + { + inputs: [], + name: 'InvalidFeeDates', + type: 'error', + }, + { + inputs: [], + name: 'InvalidFeeRate', + type: 'error', + }, + { + inputs: [], + name: 'InvalidType', + type: 'error', + }, + { + inputs: [], + name: 'NoPermission', + type: 'error', + }, + { + inputs: [], + name: 'NotAPool', + type: 'error', + }, + { + inputs: [], + name: 'ZeroAddress', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'enum IFeesManager.FeeType', + name: 'rateType', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint48', + name: 'startRate', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'endRate', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'auctionStartDate', + type: 'uint48', + }, + { + indexed: false, + internalType: 'uint48', + name: 'auctionEndDate', + type: 'uint48', + }, + ], + name: 'ChangeFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + inputs: [], + name: 'factory', + outputs: [ + { + internalType: 'contract IPoolFactory', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + ], + name: 'getCurrentRate', + outputs: [ + { + internalType: 'uint48', + name: '', + type: 'uint48', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolFactory', + name: '_factory', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'poolFeesData', + outputs: [ + { + internalType: 'enum IFeesManager.FeeType', + name: 'rateType', + type: 'uint8', + }, + { + internalType: 'uint48', + name: 'startRate', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'endRate', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'auctionStartDate', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'auctionEndDate', + type: 'uint48', + }, + { + internalType: 'uint48', + name: 'poolExpiry', + type: 'uint48', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_pool', + type: 'address', + }, + { + internalType: 'bytes32', + name: '_ratesAndType', + type: 'bytes32', + }, + { + internalType: 'uint48', + name: '_expiry', + type: 'uint48', + }, + { + internalType: 'uint48', + name: '_protocolFee', + type: 'uint48', + }, + ], + name: 'setPoolRates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, +]; + +module.exports = { + LendingPoolV2ABI, + FeesManagerABI, +}; diff --git a/src/adaptors/vendor-v2/custom-prices/umami-vaults.js b/src/adaptors/vendor-v2/custom-prices/umami-vaults.js new file mode 100644 index 0000000000..cc638d5787 --- /dev/null +++ b/src/adaptors/vendor-v2/custom-prices/umami-vaults.js @@ -0,0 +1,53 @@ +const axios = require('axios'); +const { ethers } = require('ethers'); +const sdk = require('@defillama/sdk'); + +exports.getUmamiVaultSharePrice = async (vaultAddress, network) => { + const symbol = ( + await sdk.api.abi.call({ + target: vaultAddress, + abi: 'erc20:symbol', + chain: network, + }) + ).output; + const decimals = Number( + ( + await sdk.api.abi.call({ + target: vaultAddress, + abi: 'erc20:decimals', + chain: network, + }) + ).output + ); + const umamiGraphUrl = sdk.graph.modifyEndpoint('EoXjimvYjR9KR5f33r3j3jAvD6PfJ9cVSarQ84Lg7SLb'); + + // execute price per share query + const response = await axios.post(umamiGraphUrl, { + query: `{ + vaultPricePerShares( + first: 1, + where: {vault: "${vaultAddress}"}, + orderBy: timestamp, + orderDirection: desc + ) { + id + block + timestamp + vault + pricePerShare + } + }`, + }); + // extract the price data + const priceData = response.data.data.vaultPricePerShares[0]; + const price = Number( + ethers.utils.formatUnits(priceData.pricePerShare, decimals) + ); + return { + [`${network}:${vaultAddress}`]: { + decimals, + symbol, + price, + }, + }; +}; diff --git a/src/adaptors/vendor-v2/index.js b/src/adaptors/vendor-v2/index.js new file mode 100644 index 0000000000..68040fb6dc --- /dev/null +++ b/src/adaptors/vendor-v2/index.js @@ -0,0 +1,241 @@ +const sdk = require('@defillama/sdk'); +const { gql } = require('graphql-request'); +const { ethers } = require('ethers'); +const networkData = require('./network-data'); +const axios = require('axios'); +const utils = require('../utils'); +const { LendingPoolV2ABI, FeesManagerABI } = require('./ContractABIs'); +const { getUmamiVaultSharePrice } = require('./custom-prices/umami-vaults'); + +const ENTITY_URL = process.env.VENDOR_FINANCE; + +const ARBITRUM_FEES_MANAGER = '0x6c58D106C613627Bd11A885fC15A1572a358AA27'; +const ETHEREUM_FEES_MANAGER = '0x0Cc43a4C570e7EED16c34Ce8540ae5dA037fDf0A'; + +const getGenericTokenInfo = async (tokens, network) => { + const tokenSymbols = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: tokens.map((tokenAddr) => ({ + target: tokenAddr, + })), + chain: network, + }) + ).output; + const tokenDecimals = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:decimals', + calls: tokens.map((tokenAddr) => ({ + target: tokenAddr, + })), + chain: network, + }) + ).output; + const tokensData = { + lendTokenSymbol: tokenSymbols[0].output, + colTokenSymbol: tokenSymbols[1].output, + lendTokenDecimals: tokenDecimals[0].output, + colTokenDecimals: tokenDecimals[1].output, + }; + return tokensData; +}; + +const getAvailableLiquidity = async ( + poolAddr, + lendTokenInfo, + lendDecimals, + network +) => { + // There are some cases where the lend balance of a pool is not stored in the pool itself, + // but rather an external lending pool (like AAVE). The reason for this is to utilize idle + // capital while the Vendor pool has yet to find a borrower. Due to this, a specific fc on + // lending pool must be called to obtain the lend balance. + const lendBalance = await sdk.api.abi.call({ + target: poolAddr, + abi: LendingPoolV2ABI.find((fragment) => fragment.name === 'lendBalance'), + chain: network, + }); + const formattedLendBal = ethers.utils.formatUnits( + lendBalance.output, + lendDecimals + ); + return Object.entries(lendTokenInfo)[0][1].price * formattedLendBal; +}; + +const getTokenPriceInfo = async (tokens, network) => { + const umamiVaultAddresses = [ + // glpUSDC + '0x727eD4eF04bB2a96Ec77e44C1a91dbB01B605e42', + // glpLINK + '0xe0A21a475f8DA0ee7FA5af8C1809D8AC5257607d', + // glpWETH + '0xbb84D79159D6bBE1DE148Dc82640CaA677e06126', + // glpWBTC + '0x6a89FaF99587a12E6bB0351F2fA9006c6Cd12257', + // glpUNI + '0x37c0705A65948EA5e0Ae1aDd13552BCaD7711A23', + ].map((address) => address.toLowerCase()); + const umamiTokenAddresses = []; + const normalTokenDataPromises = []; + for (const token of tokens) { + if (umamiVaultAddresses.includes(token.toLowerCase())) { + const vaultPrice = await getUmamiVaultSharePrice(token, network); + umamiTokenAddresses.push(vaultPrice); + } else { + normalTokenDataPromises.push( + utils.getData( + `https://coins.llama.fi/prices/current/${network.toLowerCase()}:${token.toLowerCase()}` + ) + ); + } + } + const normalTokenDataArray = await Promise.all(normalTokenDataPromises); + const normalTokenData = normalTokenDataArray.map( + (tokenInfo) => tokenInfo.coins + ); + // Combine the normal tokens data with umami token addresses if present + const finalTokenData = [...normalTokenData, ...umamiTokenAddresses]; + return finalTokenData; +}; + +const getLoanToValue = (lendTokenPriceObj, colTokenPriceObj, pool, poolFee) => { + // get token prices from tokenPrice context object + let lendPrice = Object.entries(lendTokenPriceObj)[0][1].price; + const colPrice = Object.entries(colTokenPriceObj)[0][1].price; + const protocolFee = pool.protocolFee / 1000000; + // calculate LTV from lend and collateral prices + const mintRatio = ethers.utils.formatUnits(pool.mintRatio, 18); + const ltvLendValue = parseFloat(mintRatio) * lendPrice; + const ltvColValue = colPrice; + const totalFees = + ltvLendValue / (1 - protocolFee - Number(poolFee) / 10000 / 100) - + ltvLendValue; + return (ltvLendValue - totalFees) / ltvColValue; +}; + +const getSuppliedAndBorrowedUsd = async ( + pool, + lendDecimals, + colDecimals, + lendTokenPriceObj, + network +) => { + const lendFee = ( + await sdk.api.abi.call({ + target: + network === 'arbitrum' ? ARBITRUM_FEES_MANAGER : ETHEREUM_FEES_MANAGER, + abi: FeesManagerABI.find( + (fragment) => fragment.name === 'getCurrentRate' + ), + chain: network, + params: pool.id, + }) + ).output; + const colBalance = ( + await sdk.api.abi.call({ + target: pool.id, + abi: LendingPoolV2ABI.find((fragment) => fragment.name === 'colBalance'), + chain: network, + }) + ).output; + const lendBalance = ( + await sdk.api.abi.call({ + target: pool.id, + abi: LendingPoolV2ABI.find((fragment) => fragment.name === 'lendBalance'), + chain: network, + }) + ).output; + // Calculated the total borrowed amount in $USD + let totalBorrowed = + parseFloat(pool.mintRatio / 10 ** 18) * + parseFloat(ethers.utils.formatUnits(colBalance, colDecimals)); + const poolFee = Number(lendFee) / 10000 / 100; + const protocolFee = pool.protocolFee / 1000000; + const totalBorrowedAdjusted = (totalBorrowed *= 1 - protocolFee - poolFee); + const lendTokenPrice = Object.entries(lendTokenPriceObj)[0][1].price; + const totalBorrowedUsd = totalBorrowedAdjusted * lendTokenPrice; + // Calculates the total supplied amount (available lend balance + total borrowed) in $USD + const lendBalanceUsd = + lendTokenPrice * + parseFloat(ethers.utils.formatUnits(lendBalance, lendDecimals)) * + (1 - protocolFee + poolFee); + const totalSuppliedUsd = lendBalanceUsd + totalBorrowed; + return { totalBorrowedUsd, totalSuppliedUsd, lendFee }; +}; + +const getPools = async () => { + const pools = []; + for (const networkConfig of networkData.networkData) { + const response = await axios.post(ENTITY_URL, { + query: networkConfig.query, + type: networkConfig.type, + }); + try { + const network = networkConfig.network.toLowerCase(); + for (const pool of Object.entries(response.data)[0][1]) { + const { + lendTokenSymbol, + colTokenSymbol, + lendTokenDecimals, + colTokenDecimals, + } = await getGenericTokenInfo([pool.lendToken, pool.colToken], network); + const [lendTokenPriceInfo, colTokenPriceInfo] = await getTokenPriceInfo( + [pool.lendToken, pool.colToken], + network + ); + const availableLiquidity = await getAvailableLiquidity( + pool.id, + lendTokenPriceInfo, + lendTokenDecimals, + network + ); + const { totalBorrowedUsd, totalSuppliedUsd, lendFee } = + await getSuppliedAndBorrowedUsd( + pool, + lendTokenDecimals, + colTokenDecimals, + lendTokenPriceInfo, + network + ); + const loanToValue = getLoanToValue( + lendTokenPriceInfo, + colTokenPriceInfo, + pool, + lendFee + ); + const poolObj = { + pool: pool.id, + chain: networkConfig.network, + project: 'vendor-v2', + ltv: loanToValue, + underlyingTokens: [pool.lendToken, pool.colToken], + symbol: lendTokenSymbol, + tvlUsd: availableLiquidity, + totalBorrowUsd: totalBorrowedUsd, + totalSupplyUsd: totalSuppliedUsd, + apyBase: 0, + apyBaseBorrow: + pool.feeType == 1 + ? ((31536000 / + (Number(pool.expiry) - new Date().getTime() / 1000)) * + pool.startRate) / + 10000 + : pool.startRate / 10000, + poolMeta: `Due ${new Date(pool.expiry * 1000) + .toUTCString() + .slice(5, -13)}, ${colTokenSymbol} collateral`, + }; + pools.push(poolObj); + } + } catch (err) { + console.log(err); + } + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: 'https://vendor.finance/borrow', +}; diff --git a/src/adaptors/vendor-v2/network-data.js b/src/adaptors/vendor-v2/network-data.js new file mode 100644 index 0000000000..bd68f8c4c1 --- /dev/null +++ b/src/adaptors/vendor-v2/network-data.js @@ -0,0 +1,63 @@ +const arbitrum_query = { + query: ` + query { + pools( + first: 1000, where: { + lendBalance_gt: 0, + paused: false, + expiry_gt: ${Math.round(new Date().getTime() / 1000)} + } + ) { + id + colToken + lendToken + feeType + startRate + poolType + expiry + mintRatio + lendBalance + protocolFee + } + } +`, +}; + +const ethereum_query = { + query: ` + query { + pools( + first: 1000, where: { + lendBalance_gt: 0, + paused: false, + expiry_gt: ${Math.round(new Date().getTime() / 1000)} + } + ) { + id + colToken + lendToken + feeType + startRate + poolType + expiry + mintRatio + lendBalance + borrowers + protocolFee + } + } +`, +}; + +exports.networkData = [ + { + network: 'Ethereum', + query: ethereum_query, + type: 'v2-Ethereum', + }, + { + network: 'Arbitrum', + query: arbitrum_query, + type: 'v2-Arbitrum', + }, +]; diff --git a/src/adaptors/venomstake/index.js b/src/adaptors/venomstake/index.js new file mode 100644 index 0000000000..d527dc5f54 --- /dev/null +++ b/src/adaptors/venomstake/index.js @@ -0,0 +1,26 @@ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + +const fetch = async () => { + const [{ data }, { price }] = await Promise.all([ + utils.getData('https://api.venomstake.com/v1/strategies/main'), + utils.getData('https://api.web3.world/v1/currencies/0:77d36848bb159fa485628bc38dc37eadb74befa514395e09910f601b841f749e', {}), + ]); + + return [{ + pool: 'be424d43-ccb6-4a2e-8064-222150b69aa0', + chain: utils.formatChain('venom'), + project: 'venomstake', + symbol: 'VENOM', + tvlUsd: BigNumber(data.tvl).div(1e9).multipliedBy(price).toNumber(), + rewardTokens: ['0:77d36848bb159fa485628bc38dc37eadb74befa514395e09910f601b841f749e'], + underlyingTokens: ['0:77d36848bb159fa485628bc38dc37eadb74befa514395e09910f601b841f749e'], + apyBase: BigNumber(data.apy).multipliedBy(100).toNumber() + }]; +}; + +module.exports = { + timetravel: false, + apy: fetch, + url: 'https://venomstake.com/', +}; diff --git a/src/adaptors/venus-core-pool/abiPool.js b/src/adaptors/venus-core-pool/abiPool.js new file mode 100644 index 0000000000..6e2ad125d4 --- /dev/null +++ b/src/adaptors/venus-core-pool/abiPool.js @@ -0,0 +1,1000 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'cashPrior', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'interestAccumulated', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowIndex', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'borrowAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'liquidator', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'seizeTokens', + type: 'uint256', + }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'minter', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'mintTokens', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'oldComptroller', + type: 'address', + }, + { + indexed: false, + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'oldInterestRateModel', + type: 'address', + }, + { + indexed: false, + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPendingAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldReserveFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'redeemer', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'feeAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'redeemTokens', + type: 'uint256', + }, + ], + name: 'RedeemFee', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'payer', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'repayAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accountBorrows', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'totalBorrows', + type: 'uint256', + }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'benefactor', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'addAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'admin', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reduceAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTotalReserves', + type: 'uint256', + }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'addAmount', type: 'uint256' }], + name: '_addReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bytes', name: 'data', type: 'bytes' }], + name: '_becomeImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'reduceAmount', type: 'uint256' }, + ], + name: '_reduceReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_resignImplementation', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'newComptroller', + type: 'address', + }, + ], + name: '_setComptroller', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract InterestRateModel', + name: 'newInterestRateModel', + type: 'address', + }, + ], + name: '_setInterestRateModel', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address payable', + name: 'newPendingAdmin', + type: 'address', + }, + ], + name: '_setPendingAdmin', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newReserveFactorMantissa', + type: 'uint256', + }, + ], + name: '_setReserveFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [ + { + internalType: 'contract ComptrollerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'implementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'underlying_', type: 'address' }, + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerInterface', + name: 'comptroller_', + type: 'address', + }, + { + internalType: 'contract InterestRateModel', + name: 'interestRateModel_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'initialExchangeRateMantissa_', + type: 'uint256', + }, + { internalType: 'string', name: 'name_', type: 'string' }, + { internalType: 'string', name: 'symbol_', type: 'string' }, + { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [ + { internalType: 'contract InterestRateModel', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isVToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { + internalType: 'contract VTokenInterface', + name: 'vTokenCollateral', + type: 'address', + }, + ], + name: 'liquidateBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address payable', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeem', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + ], + name: 'redeemUnderlying', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'uint256', name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/venus-core-pool/abiUnitroller.js b/src/adaptors/venus-core-pool/abiUnitroller.js new file mode 100644 index 0000000000..e255521897 --- /dev/null +++ b/src/adaptors/venus-core-pool/abiUnitroller.js @@ -0,0 +1,1849 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: true, + internalType: 'enum ComptrollerV9Storage.Action', + name: 'action', + type: 'uint8', + }, + { + indexed: false, + internalType: 'bool', + name: 'pauseState', + type: 'bool', + }, + ], + name: 'ActionPausedMarket', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'state', + type: 'bool', + }, + ], + name: 'ActionProtocolPaused', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'borrower', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'venusDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'venusBorrowIndex', + type: 'uint256', + }, + ], + name: 'DistributedBorrowerVenus', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'supplier', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'venusDelta', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'venusSupplyIndex', + type: 'uint256', + }, + ], + name: 'DistributedSupplierVenus', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'DistributedVAIVaultVenus', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'error', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'info', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'detail', + type: 'uint256', + }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketEntered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'MarketExited', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + ], + name: 'MarketListed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldAccessControlAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAccessControlAddress', + type: 'address', + }, + ], + name: 'NewAccessControl', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newBorrowCap', + type: 'uint256', + }, + ], + name: 'NewBorrowCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldCloseFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCloseFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'oldCollateralFactorMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: 'NewCollateralFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldComptrollerLens', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newComptrollerLens', + type: 'address', + }, + ], + name: 'NewComptrollerLens', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldLiquidationIncentiveMantissa', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: 'NewLiquidationIncentive', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldLiquidatorContract', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newLiquidatorContract', + type: 'address', + }, + ], + name: 'NewLiquidatorContract', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldPauseGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: 'NewPauseGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'oldPriceOracle', + type: 'address', + }, + { + indexed: false, + internalType: 'contract PriceOracle', + name: 'newPriceOracle', + type: 'address', + }, + ], + name: 'NewPriceOracle', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSupplyCap', + type: 'uint256', + }, + ], + name: 'NewSupplyCap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldTreasuryAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newTreasuryAddress', + type: 'address', + }, + ], + name: 'NewTreasuryAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldTreasuryGuardian', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newTreasuryGuardian', + type: 'address', + }, + ], + name: 'NewTreasuryGuardian', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldTreasuryPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newTreasuryPercent', + type: 'uint256', + }, + ], + name: 'NewTreasuryPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract VAIControllerInterface', + name: 'oldVAIController', + type: 'address', + }, + { + indexed: false, + internalType: 'contract VAIControllerInterface', + name: 'newVAIController', + type: 'address', + }, + ], + name: 'NewVAIController', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldVAIMintRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newVAIMintRate', + type: 'uint256', + }, + ], + name: 'NewVAIMintRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'vault_', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'releaseStartBlock_', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'releaseInterval_', + type: 'uint256', + }, + ], + name: 'NewVAIVaultInfo', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldVenusVAIVaultRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newVenusVAIVaultRate', + type: 'uint256', + }, + ], + name: 'NewVenusVAIVaultRate', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'VenusBorrowSpeedUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'VenusGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newSpeed', + type: 'uint256', + }, + ], + name: 'VenusSupplySpeedUpdated', + type: 'event', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract Unitroller', + name: 'unitroller', + type: 'address', + }, + ], + name: '_become', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: '_grantXVS', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newAccessControlAddress', + type: 'address', + }, + ], + name: '_setAccessControl', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'markets', type: 'address[]' }, + { + internalType: 'enum ComptrollerV9Storage.Action[]', + name: 'actions', + type: 'uint8[]', + }, + { internalType: 'bool', name: 'paused', type: 'bool' }, + ], + name: '_setActionsPaused', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newCloseFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCloseFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract VToken', + name: 'vToken', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newCollateralFactorMantissa', + type: 'uint256', + }, + ], + name: '_setCollateralFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: 'comptrollerLens_', + type: 'address', + }, + ], + name: '_setComptrollerLens', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'newLiquidationIncentiveMantissa', + type: 'uint256', + }, + ], + name: '_setLiquidationIncentive', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newLiquidatorContract_', + type: 'address', + }, + ], + name: '_setLiquidatorContract', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newBorrowCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketBorrowCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'newSupplyCaps', + type: 'uint256[]', + }, + ], + name: '_setMarketSupplyCaps', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newPauseGuardian', + type: 'address', + }, + ], + name: '_setPauseGuardian', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract PriceOracle', + name: 'newOracle', + type: 'address', + }, + ], + name: '_setPriceOracle', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'bool', name: 'state', type: 'bool' }], + name: '_setProtocolPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'newTreasuryGuardian', + type: 'address', + }, + { + internalType: 'address', + name: 'newTreasuryAddress', + type: 'address', + }, + { + internalType: 'uint256', + name: 'newTreasuryPercent', + type: 'uint256', + }, + ], + name: '_setTreasuryData', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract VAIControllerInterface', + name: 'vaiController_', + type: 'address', + }, + ], + name: '_setVAIController', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'newVAIMintRate', type: 'uint256' }, + ], + name: '_setVAIMintRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vault_', type: 'address' }, + { + internalType: 'uint256', + name: 'releaseStartBlock_', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'minReleaseAmount_', + type: 'uint256', + }, + ], + name: '_setVAIVaultInfo', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'supplySpeeds', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'borrowSpeeds', + type: 'uint256[]', + }, + ], + name: '_setVenusSpeeds', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'uint256', + name: 'venusVAIVaultRate_', + type: 'uint256', + }, + ], + name: '_setVenusVAIVaultRate', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'contract VToken', name: 'vToken', type: 'address' }, + ], + name: '_supportMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'accountAssets', + outputs: [{ internalType: 'contract VToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'market', type: 'address' }, + { + internalType: 'enum ComptrollerV9Storage.Action', + name: 'action', + type: 'uint8', + }, + ], + name: 'actionPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'allMarkets', + outputs: [{ internalType: 'contract VToken', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowCapGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'borrowCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'borrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'contract VToken', name: 'vToken', type: 'address' }, + ], + name: 'checkMembership', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + { internalType: 'bool', name: 'collateral', type: 'bool' }, + ], + name: 'claimVenus', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'holder', type: 'address' }, + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + ], + name: 'claimVenus', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimVenus', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address[]', name: 'holders', type: 'address[]' }, + { + internalType: 'contract VToken[]', + name: 'vTokens', + type: 'address[]', + }, + { internalType: 'bool', name: 'borrowers', type: 'bool' }, + { internalType: 'bool', name: 'suppliers', type: 'bool' }, + ], + name: 'claimVenus', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'holder', type: 'address' }], + name: 'claimVenusAsCollateral', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'closeFactorMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptrollerLens', + outputs: [ + { + internalType: 'contract ComptrollerLensInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address[]', name: 'vTokens', type: 'address[]' }], + name: 'enterMarkets', + outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vTokenAddress', type: 'address' }, + ], + name: 'exitMarket', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getAllMarkets', + outputs: [ + { internalType: 'contract VToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAssetsIn', + outputs: [ + { internalType: 'contract VToken[]', name: '', type: 'address[]' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getBlockNumber', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'address', name: 'vTokenModify', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + { internalType: 'uint256', name: 'borrowAmount', type: 'uint256' }, + ], + name: 'getHypotheticalAccountLiquidity', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getXVSAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getXVSVTokenAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isComptroller', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'vTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'liquidateBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'vTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'liquidateBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'vTokenBorrowed', + type: 'address', + }, + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateCalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + ], + name: 'liquidateVAICalculateSeizeTokens', + outputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidationIncentiveMantissa', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'liquidatorContract', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'markets', + outputs: [ + { internalType: 'bool', name: 'isListed', type: 'bool' }, + { + internalType: 'uint256', + name: 'collateralFactorMantissa', + type: 'uint256', + }, + { internalType: 'bool', name: 'isVenus', type: 'bool' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'maxAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'minReleaseAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { internalType: 'uint256', name: 'mintAmount', type: 'uint256' }, + ], + name: 'mintAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'mintVAIGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'minter', type: 'address' }, + { + internalType: 'uint256', + name: 'actualMintAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'mintTokens', type: 'uint256' }, + ], + name: 'mintVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'mintedVAIs', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'oracle', + outputs: [ + { internalType: 'contract PriceOracle', name: '', type: 'address' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pauseGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingComptrollerImplementation', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'protocolPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'redeemer', type: 'address' }, + { internalType: 'uint256', name: 'redeemAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'redeemTokens', type: 'uint256' }, + ], + name: 'redeemVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'releaseStartBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'releaseToVault', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'payer', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { + internalType: 'uint256', + name: 'actualRepayAmount', + type: 'uint256', + }, + { internalType: 'uint256', name: 'borrowerIndex', type: 'uint256' }, + ], + name: 'repayBorrowVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'repayVAIGuardianPaused', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'vTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { + internalType: 'address', + name: 'vTokenCollateral', + type: 'address', + }, + { + internalType: 'address', + name: 'vTokenBorrowed', + type: 'address', + }, + { internalType: 'address', name: 'liquidator', type: 'address' }, + { internalType: 'address', name: 'borrower', type: 'address' }, + { internalType: 'uint256', name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seizeVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'setMintedVAIOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'supplyCaps', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferAllowed', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'vToken', type: 'address' }, + { internalType: 'address', name: 'src', type: 'address' }, + { internalType: 'address', name: 'dst', type: 'address' }, + { internalType: 'uint256', name: 'transferTokens', type: 'uint256' }, + ], + name: 'transferVerify', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'treasuryAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'treasuryGuardian', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'treasuryPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'vaiController', + outputs: [ + { + internalType: 'contract VAIControllerInterface', + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'vaiMintRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'vaiVaultAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusAccrued', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusBorrowSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusBorrowState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'venusBorrowerIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'venusInitialIndex', + outputs: [{ internalType: 'uint224', name: '', type: 'uint224' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'venusRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusSpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'venusSupplierIndex', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusSupplySpeeds', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'venusSupplyState', + outputs: [ + { internalType: 'uint224', name: 'index', type: 'uint224' }, + { internalType: 'uint32', name: 'block', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'venusVAIVaultRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/venus-core-pool/index.js b/src/adaptors/venus-core-pool/index.js new file mode 100644 index 0000000000..4d3dcfbddb --- /dev/null +++ b/src/adaptors/venus-core-pool/index.js @@ -0,0 +1,254 @@ +const sdk = require('@defillama/sdk'); +const superagent = require('superagent'); +const abiUnitroller = require('./abiUnitroller'); +const abiPool = require('./abiPool'); + +const unitroller = '0xfD36E2c2a6789Db23113685031d7F16329158384'; +const VBNB = '0xA07c5b74C9B40447a954e1466938b865b6BBea36'; +const WBNB = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; +const BETH = '0x250632378e573c6be1ac2f97fcdf00515d0aa91b'; +const XVS = '0xcf6bb5389c92bdda8a3747ddb454cb7a64626c63'; + +const poolInfo = async (chain) => { + const getAllMarkets = await sdk.api.abi.call({ + target: unitroller, + chain, + abi: abiUnitroller.find((m) => m.name === 'getAllMarkets'), + permitFailure: true, + }); + + // filter out unsupported vcan pool + const yieldMarkets = getAllMarkets.output + .map((pool) => { + return { pool }; + }) + .filter( + (pool) => + pool.pool.toLowerCase() !== '0xebd0070237a0713e8d94fef1b728d3d993d290ef' + ); + + const getOutput = ({ output }) => output.map(({ output }) => output); + const [markets, venusSupplySpeeds, venusBorrowSpeeds] = await Promise.all( + ['markets', 'venusSupplySpeeds', 'venusBorrowSpeeds'].map((method) => + sdk.api.abi.multiCall({ + abi: abiUnitroller.find((m) => m.name === method), + target: unitroller, + calls: yieldMarkets.map((pool) => ({ + params: pool.pool, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + + const collateralFactor = markets.map((data) => data.collateralFactorMantissa); + + const [ + borrowRatePerBlock, + supplyRatePerBlock, + getCash, + totalBorrows, + totalReserves, + underlyingToken, + tokenSymbol, + ] = await Promise.all( + [ + 'borrowRatePerBlock', + 'supplyRatePerBlock', + 'getCash', + 'totalBorrows', + 'totalReserves', + 'underlying', + 'symbol', + ].map((method) => + sdk.api.abi.multiCall({ + abi: abiPool.find((m) => m.name === method), + calls: yieldMarkets.map((pool) => ({ + target: pool.pool, + })), + chain, + permitFailure: true, + }) + ) + ).then((data) => data.map(getOutput)); + + // no underlying token in vbnb swap null -> wbnb + underlyingToken.find((token, index, arr) => { + if (token === null) arr[index] = WBNB; + }); + + const underlyingTokenDecimals = ( + await sdk.api.abi.multiCall({ + abi: abiPool.find((m) => m.name === 'decimals'), + calls: underlyingToken.map((token) => ({ + target: token, + })), + chain, + permitFailure: true, + }) + ).output.map((decimal) => Math.pow(10, Number(decimal.output))); + + //incorrect beth price swap beth 0xaddress -> coingecko id + const price = await getPrices('bsc', underlyingToken); + + yieldMarkets.map((data, index) => { + data.collateralFactor = collateralFactor[index]; + data.venusSupplySpeeds = venusSupplySpeeds[index]; + data.venusBorrowSpeeds = venusBorrowSpeeds[index]; + data.borrowRatePerBlock = borrowRatePerBlock[index]; + data.supplyRatePerBlock = supplyRatePerBlock[index]; + data.getCash = getCash[index]; + data.totalBorrows = totalBorrows[index]; + data.totalReserves = totalReserves[index]; + data.underlyingToken = underlyingToken[index]; + data.tokenSymbol = tokenSymbol[index]; + data.price = price[underlyingToken[index].toLowerCase()]; + data.underlyingTokenDecimals = underlyingTokenDecimals[index]; + data.rewardTokens = [XVS]; + }); + + return { yieldMarkets }; +}; + +const getPrices = async (chain, addresses) => { + const uri = `${addresses.map((address) => `${chain}:${address}`)}`; + const prices = ( + await superagent.get('https://coins.llama.fi/prices/current/' + uri) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +function calculateApy(rate, decimals, price = 1, tvl = 1) { + // APR compounded daily + const BLOCK_TIME = 0.75; // https://x.com/BNBCHAIN/status/1939374483833335935 + const DAILY_BLOCKS = (24 * 60 * 60) / BLOCK_TIME; + const dailyApr = rate * price * DAILY_BLOCKS / tvl; + const apy = ((dailyApr / decimals + 1) ** 364 - 1) * 100; + return apy; +} + +function calculateTvl(cash, borrows, reserves, price, decimals) { + // ( cash + totalBorrows - reserve value ) * underlying price = balance + const tvl = + ((parseFloat(cash) + parseFloat(borrows) - parseFloat(reserves)) / + decimals) * + price; + return tvl; +} + +const getApy = async () => { + const priceOf = await getPrices(['bsc'], [XVS]); + + const yieldMarkets = (await poolInfo('bsc')).yieldMarkets; + + const symbol = ( + await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: yieldMarkets.map((p) => ({ target: p.underlyingToken })), + chain: 'bsc', + permitFailure: true, + }) + ).output.map((o) => o.output); + + const yieldPools = yieldMarkets.map((pool, i) => { + const totalSupplyUsd = calculateTvl( + pool.getCash, + pool.totalBorrows, + pool.totalReserves, + pool.price, + pool.underlyingTokenDecimals + ); + const totalBorrowUsd = calculateTvl( + 0, + pool.totalBorrows, + 0, + pool.price, + pool.underlyingTokenDecimals + ); + const tvl = totalSupplyUsd - totalBorrowUsd; + const apyBase = calculateApy(pool.supplyRatePerBlock, pool.underlyingTokenDecimals); + const apyReward = calculateApy( + pool.venusSupplySpeeds, + 1e18, // XVS decimals + priceOf[XVS], + totalSupplyUsd + ); + + const apyBaseBorrow = calculateApy(pool.borrowRatePerBlock, pool.underlyingTokenDecimals); + const apyRewardBorrow = calculateApy( + pool.venusBorrowSpeeds, + 1e18, // XVS decimals + priceOf[XVS], + totalBorrowUsd + ); + const ltv = parseInt(pool.collateralFactor) / 1e18; + const readyToExport = exportFormatter( + pool.pool, + 'Binance', + symbol[i], + tvl, + apyBase, + apyReward, + pool.underlyingToken, + pool.rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv + ); + + return readyToExport; + }); + + return yieldPools; +}; + +function exportFormatter( + pool, + chain, + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens, + rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv +) { + return { + pool: pool.toLowerCase(), + chain, + project: 'venus-core-pool', + symbol, + tvlUsd, + apyBase, + apyReward, + underlyingTokens: [underlyingTokens], + rewardTokens, + apyBaseBorrow, + apyRewardBorrow, + totalSupplyUsd, + totalBorrowUsd, + ltv, + }; +} + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.venus.io/markets', +}; diff --git a/src/adaptors/veplus/abiGauge.json b/src/adaptors/veplus/abiGauge.json new file mode 100644 index 0000000000..7b9e3a3ce9 --- /dev/null +++ b/src/adaptors/veplus/abiGauge.json @@ -0,0 +1,1017 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_stake", + "type": "address" + }, + { + "internalType": "address", + "name": "_internal_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "_external_bribe", + "type": "address" + }, + { + "internalType": "address", + "name": "__ve", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "bool", + "name": "_forPair", + "type": "bool" + }, + { + "internalType": "address[]", + "name": "_allowedRewardTokens", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "name": "ClaimFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxRuns", + "type": "uint256" + } + ], + "name": "batchRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxRuns", + "type": "uint256" + } + ], + "name": "batchUpdateRewardPerToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "checkpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "balanceOf", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { + "internalType": "uint256", + "name": "claimed0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimed1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "depositAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "derivedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "derivedBalances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "derivedSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "external_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorBalanceIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorRewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "getPriorSupplyIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "internal_bribe", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isForPair", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastEarn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "left", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardPerTokenCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardPerTokenNumCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsListLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "supplyCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyNumCheckpoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "i", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldToken", + "type": "address" + }, + { + "internalType": "address", + "name": "newToken", + "type": "address" + } + ], + "name": "swapOutRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/veplus/abiPair.json b/src/adaptors/veplus/abiPair.json new file mode 100644 index 0000000000..835c4bc01f --- /dev/null +++ b/src/adaptors/veplus/abiPair.json @@ -0,0 +1,672 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Claim", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Fees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "reserve0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reserve1", + "type": "uint256" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blockTimestampLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "burn", + "outputs": [ + { "internalType": "uint256", "name": "amount0", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimFees", + "outputs": [ + { "internalType": "uint256", "name": "claimed0", "type": "uint256" }, + { "internalType": "uint256", "name": "claimed1", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimStakingFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" } + ], + "name": "current", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentCumulativePrices", + "outputs": [ + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + }, + { "internalType": "uint256", "name": "blockTimestamp", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "address", "name": "tokenIn", "type": "address" } + ], + "name": "getAmountOut", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { "internalType": "uint256", "name": "_reserve0", "type": "uint256" }, + { "internalType": "uint256", "name": "_reserve1", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_blockTimestampLast", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "index1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isStable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastObservation", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "internalType": "struct Pair.Observation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metadata", + "outputs": [ + { "internalType": "uint256", "name": "dec0", "type": "uint256" }, + { "internalType": "uint256", "name": "dec1", "type": "uint256" }, + { "internalType": "uint256", "name": "r0", "type": "uint256" }, + { "internalType": "uint256", "name": "r1", "type": "uint256" }, + { "internalType": "bool", "name": "st", "type": "bool" }, + { "internalType": "address", "name": "t0", "type": "address" }, + { "internalType": "address", "name": "t1", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "mint", + "outputs": [ + { "internalType": "uint256", "name": "liquidity", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "observationLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "observations", + "outputs": [ + { "internalType": "uint256", "name": "timestamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "reserve0Cumulative", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserve1Cumulative", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" } + ], + "name": "prices", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "granularity", "type": "uint256" } + ], + "name": "quote", + "outputs": [ + { "internalType": "uint256", "name": "amountOut", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve0CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reserve1CumulativeLast", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenIn", "type": "address" }, + { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, + { "internalType": "uint256", "name": "points", "type": "uint256" }, + { "internalType": "uint256", "name": "window", "type": "uint256" } + ], + "name": "sample", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "to", "type": "address" }], + "name": "skim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stable", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex0", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "supplyIndex1", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount0Out", "type": "uint256" }, + { "internalType": "uint256", "name": "amount1Out", "type": "uint256" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "swap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sync", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokens", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/veplus/abiPairFactory.json b/src/adaptors/veplus/abiPairFactory.json new file mode 100644 index 0000000000..e493894d42 --- /dev/null +++ b/src/adaptors/veplus/abiPairFactory.json @@ -0,0 +1,351 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "volatileFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "changeMadeTimestamp", + "type": "uint256" + } + ], + "name": "FeesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "stable", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "pair", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "PairCreated", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REFERRAL_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_REFERRAL_FEE_", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "allPairs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "allPairsLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "tokenA", "type": "address" }, + { "internalType": "address", "name": "tokenB", "type": "address" }, + { "internalType": "bool", "name": "stable", "type": "bool" } + ], + "name": "createPair", + "outputs": [ + { "internalType": "address", "name": "pair", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dibs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_stable", "type": "bool" }], + "name": "getFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getInitializable", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "name": "getPair", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isPair", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pairCodeHash", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "pairs", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingFeeManager", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_dibs", "type": "address" } + ], + "name": "setDibs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_stableFee", "type": "uint256" }, + { "internalType": "uint256", "name": "_volatileFee", "type": "uint256" } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feeManager", "type": "address" } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "_state", "type": "bool" }], + "name": "setPause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_refFee", "type": "uint256" } + ], + "name": "setReferralFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_feehandler", "type": "address" } + ], + "name": "setStakingFeeAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setStakingFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stableFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingFeeHandler", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingNFTFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "volatileFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/veplus/abiVoter.json b/src/adaptors/veplus/abiVoter.json new file mode 100644 index 0000000000..37e589b962 --- /dev/null +++ b/src/adaptors/veplus/abiVoter.json @@ -0,0 +1,920 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Abstained", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Attach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Detach", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "internal_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "external_bribe", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "GaugeCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeKilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + } + ], + "name": "GaugeRevived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "reward", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "NotifyReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "Voted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "whitelister", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "Whitelisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lp", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "_initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "_ve", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "attachTokenToGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "bribefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_restTime", "type": "uint256" } + ], + "name": "changeRestTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_bribes", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimBribes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_fees", "type": "address[]" }, + { + "internalType": "address[][]", + "name": "_tokens", + "type": "address[][]" + }, + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "claimFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_tokenId", "type": "uint256[]" } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "claimable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_pool", "type": "address" } + ], + "name": "createGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "detachTokenFromGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "finish", "type": "uint256" } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "distributeFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyCouncil", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "emitWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "external_bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gaugefactory", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gauges", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "gaugesDistributionTimestmap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "increaseGaugeApprovals", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" }, + { "internalType": "address[]", "name": "_pools", "type": "address[]" } + ], + "name": "initGauges", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "__ve", "type": "address" }, + { "internalType": "address", "name": "_factory", "type": "address" }, + { "internalType": "address", "name": "_gauges", "type": "address" }, + { "internalType": "address", "name": "_bribes", "type": "address" }, + { "internalType": "address", "name": "_maNFTs", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "internal_bribes", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isAlive", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isGauge", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "isWhitelisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "killGaugeTotally", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lastVoted", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "length", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maGaugeId", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maNFTs", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "poke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "poolForGauge", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "poolVote", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "poolVoteLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "pools", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "reset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "reviveGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_bribeFactory", "type": "address" } + ], + "name": "setBribeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_council", "type": "address" } + ], + "name": "setEmergencyCouncil", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gaugeFactory", "type": "address" } + ], + "name": "setGaugeFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_governor", "type": "address" } + ], + "name": "setGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_maNFTs", "type": "address" } + ], + "name": "setMaNFTs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_minter", "type": "address" } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" }, + { "internalType": "address", "name": "_internal", "type": "address" }, + { "internalType": "address", "name": "_external", "type": "address" } + ], + "name": "setNewBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_factory", "type": "address" } + ], + "name": "setPairFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_gauges", "type": "address[]" } + ], + "name": "updateFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" } + ], + "name": "updateForRange", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_gauge", "type": "address" } + ], + "name": "updateGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "usedWeights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "address[]", "name": "_poolVote", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" } + ], + "name": "vote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "votes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "weights", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_token", "type": "address[]" } + ], + "name": "whitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/veplus/index.ts b/src/adaptors/veplus/index.ts new file mode 100644 index 0000000000..1553b4d4ca --- /dev/null +++ b/src/adaptors/veplus/index.ts @@ -0,0 +1,158 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const utils = require('../utils'); +const abiPairFactory = require('./abiPairFactory.json'); +const abiPair = require('./abiPair.json'); +const abiGauge = require('./abiGauge.json'); +const abiVoter = require('./abiVoter.json'); +const { request, gql } = require('graphql-request'); + +const SUBGRAPH_URL = sdk.graph.modifyEndpoint( + 'FEYBMUkep7BKAoxP9mX9ZF733SvnTbNMWE9tgtNTw83g' +); + +const pairFactory = '0x5Bcd9eE6C31dEf33334b255EE7A767B6EEDcBa4b'; +const voter = '0x792Ba5586E87005661C4e611b17e01De0de42599'; +const VEP = '0x1e32B79d8203AC691499fBFbB02c07A9C9850Dd7'; +const VEP_USDT_PAIR = '0xcb369dbd43de4a5f1d4341cf6621076a6ce668cd'; + +const pairsQuery = gql` + query pairQuery { + pair(id: "0xcb369dbd43de4a5f1d4341cf6621076a6ce668cd") { + token1Price + } + } +`; + +const getVEPPrice = async () => { + const { pair } = await request(SUBGRAPH_URL, pairsQuery, { + pair: VEP_USDT_PAIR.toLowerCase(), + }); + return pair.token1Price; +}; + +const getApy = async () => { + const vep_price = await getVEPPrice(); + + const allPairsLength = ( + await sdk.api.abi.call({ + target: pairFactory, + abi: abiPairFactory.find((m) => m.name === 'allPairsLength'), + chain: 'bsc', + }) + ).output; + const allPairs = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(allPairsLength)).keys()].map((i) => ({ + target: pairFactory, + params: [i], + })), + abi: abiPairFactory.find((m) => m.name === 'allPairs'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const metaData = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'metadata'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const symbols = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: i, + })), + abi: abiPair.find((m) => m.name === 'symbol'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const gauges = ( + await sdk.api.abi.multiCall({ + calls: allPairs.map((i) => ({ + target: voter, + params: [i], + })), + abi: abiVoter.find((m) => m.name === 'gauges'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const rewardRate = ( + await sdk.api.abi.multiCall({ + calls: gauges.map((i) => ({ + target: i, + params: VEP, + })), + abi: abiGauge.find((m) => m.name === 'rewardRate'), + chain: 'bsc', + }) + ).output.map((o) => o.output); + + const tokens = [ + ...new Set( + metaData + .map((m) => [m.t0, m.t1]) + .flat() + .concat(VEP) + ), + ]; + const priceKeys = tokens.map((i) => `bsc:${i}`).join(','); + + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKeys}`) + ).data.coins; + + const pools = allPairs.map((p, i) => { + const poolMeta = metaData[i]; + + const r0 = poolMeta.r0 / poolMeta.dec0; + const r1 = poolMeta.r1 / poolMeta.dec1; + + let p0, p1; + if (poolMeta.t0 == VEP) { + p0 = vep_price; + } else { + p0 = prices[`bsc:${poolMeta.t0}`]?.price; + } + + if (poolMeta.t1 == VEP) { + p1 = vep_price; + } else { + p1 = prices[`bsc:${poolMeta.t1}`]?.price; + } + + const tvlUsd = r0 * p0 + r1 * p1; + + const s = symbols[i]; + + const totalRewardPerDay = ((rewardRate[i] * 86400) / 1e18) * vep_price; + + const apyReward = (totalRewardPerDay * 36500) / tvlUsd; + + return { + pool: p, + chain: utils.formatChain('bsc'), + project: 'veplus', + symbol: utils.formatSymbol(s.replace('/', '-')), + tvlUsd, + apyReward, + rewardTokens: apyReward ? [VEP] : [], + underlyingTokens: [poolMeta.t0, poolMeta.t1], + }; + }); + + return pools.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://app.veplus.io/pools', +}; diff --git a/src/adaptors/verocket/index.js b/src/adaptors/verocket/index.js new file mode 100644 index 0000000000..5702ce3c5f --- /dev/null +++ b/src/adaptors/verocket/index.js @@ -0,0 +1,76 @@ +const axios = require('axios'); +const utils = require('../utils'); + +const baseUrl = 'https://api-v1.verocket.com'; +const urlApy = `${baseUrl}/apy`; +const tvlApy = `${baseUrl}/dex/overall/lp_volume`; +const vetPrice = `${baseUrl}/price/vet`; + +const getVetPrice = async () => { + return (await axios.get(vetPrice)).data.data.usd; +}; + +const apy = async () => { + const response = (await axios.get(urlApy)).data.data; + + // create a custom object with pool address as the key + var apyObject = {}; + response.forEach((el) => { + apyObject[el.pool] = el; + apyObject[el.pool].apy_status = el.apy_status[1].apy; + }); + + return apyObject; +}; + +const tvl = async (data) => { + const response = (await axios.get(tvlApy)).data.data; + + // get vet price + const vetPrice = await getVetPrice(); + + // fetch latest TVL from the list of 30 days TVL + tvlObjects = response[response.length - 1].items; + + // append TVL data to APY object by identifying using pool key + tvlObjects.forEach((el) => { + data[el.pool].tvl_vet = el.eq_vet; + data[el.pool].tvl_usd = el.eq_vet * vetPrice; + }); + + return data; +}; + +function buildPool(entry) { + const newObj = { + pool: entry[1].pool, + chain: utils.formatChain('vechain'), + project: 'verocket', + symbol: utils.formatSymbol( + `${entry[1].token0.toUpperCase()}-${entry[1].token1.toUpperCase()}` + ), + tvlUsd: Number(entry[1].tvl_usd), + apy: entry[1].apy_status * 100, + }; + + return newObj; +} + +const main = async () => { + // pull apy data + data = await apy(); + + // pull tvl data and merge it with apy data object + data = await tvl(data); + + // build pool objects + data = Object.entries(data).map((entry) => buildPool(entry)); + + return data; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.verocket.com/', +}; diff --git a/src/adaptors/verse/index.ts b/src/adaptors/verse/index.ts new file mode 100644 index 0000000000..759ab82b19 --- /dev/null +++ b/src/adaptors/verse/index.ts @@ -0,0 +1,120 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint('CvSasxLYUvFbYyi7VXGhXL6PNgkZPoVDo2bo66ftEA2V'); + +const query = gql` + { + pairs(first: 1000, orderBy: trackedReserveETH, orderDirection: desc block: {number: }) { + id + reserve0 + reserve1 + volumeUSD + token0 { + symbol + id + } + token1 { + symbol + id + } + + } + } +`; + +const queryPrior = gql` + { + pairs (first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +// + +const getPoolsData = async ( + chainString, + url, + query, + queryPrior, + version, + timestamp +) => { + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + // pull data + let queryC = query; + let dataNow = await request(url, queryC.replace('', block)); + dataNow = dataNow.pairs; + + // pull 24h offset data to calculate fees from swap volume + let queryPriorC = queryPrior; + let dataPrior = await request( + url, + queryPriorC.replace('', blockPrior) + ); + dataPrior = dataPrior.pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPriorC.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + dataNow = await utils.tvl(dataNow, chainString); + // calculate apy + dataNow = dataNow.map((el) => utils.apy(el, dataPrior, dataPrior7d, version)); + + return dataNow.map((p) => { + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id, p.token1.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString === 'ethereum' ? 'mainnet' : chainString; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'verse', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + underlyingTokens, + url: 'https://verse.bitcoin.com/pools/', + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); +}; + +const verseYield = async (timestamp = null) => { + const data = await getPoolsData( + 'ethereum', + url, + query, + queryPrior, + 'v2', + timestamp + ); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: verseYield, +}; diff --git a/src/adaptors/vesper/index.js b/src/adaptors/vesper/index.js index d5825cbdaf..685b68b24b 100644 --- a/src/adaptors/vesper/index.js +++ b/src/adaptors/vesper/index.js @@ -1,46 +1,60 @@ -const axios = require("axios"); +const axios = require('axios'); const utils = require('../utils'); const urls = { - "polygon": "https://api-polygon.vesper.finance/pools?stages=prod", - "ethereum": "https://api.vesper.finance/pools?stages=prod", - "avalanche": "https://api-avalanche.vesper.finance/pools?stages=prod" + ethereum: 'https://api.vesper.finance/pools?stages=prod', + avalanche: 'https://api-avalanche.vesper.finance/pools?stages=prod', + optimism: 'https://api-optimism.vesper.finance/pools?stages=prod', +}; + +const underlyingTokenMapping = { + eth: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + avax: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', + weth: '0x4200000000000000000000000000000000000006', }; async function apy(chain) { - const response = (await axios.get(urls[chain])).data; + const response = (await axios.get(urls[chain])).data; - const farms = response.map(v => ({ - pool: `${v.address}`, - chain: utils.formatChain(chain), - project: 'vesper', - symbol: v.name.startsWith('ve') - ? `${v.name.split('-')[0]} (earn ${v.name.split('-')[1]})` - : utils.formatSymbol(v.name), - tvlUsd: (Number(v.totalValue) / 10 ** Number(v.asset.decimals)) * v.asset.price, - apy: aggregateApys(v) - })); + const farms = response.map((v) => { + const apyReward = v.poolTokenRewardRates.reduce( + (a, r) => Number(r.tokenDeltaRates[14]) + Number(a), + 0 + ); - return farms; -}; + return { + pool: `${v.address}`, + chain: utils.formatChain(chain), + project: 'vesper', + symbol: v.asset.symbol, + poolMeta: v.name.startsWith('ve') + ? `earn ${v.name.split('-')[1]}` + : v.name.startsWith('va') + ? 'Aggressive' + : 'Conservative', + tvlUsd: + (Number(v.totalValue) / 10 ** Number(v.asset.decimals)) * v.asset.price, + apyBase: v.earningRates[14], + apyBase7d: v.earningRates[7], + apyReward, + rewardTokens: apyReward > 0 ? [v.rewardsTokenAddress] : [], + underlyingTokens: + v.asset.address === null + ? [underlyingTokenMapping[v.asset.symbol.toLowerCase()]] + : [v.asset.address], + }; + }); -function aggregateApys(pool) { - const earningRate = pool.earningRates[30]; - const rewardRate = pool.poolTokenRewardRates.reduce( - (a, r) => Number(r.tokenDeltaRates[30]) + Number(a), 0); - return earningRate + rewardRate; -}; + return farms; +} const main = async () => { - const [p, e, a] = await Promise.all([ - apy("polygon"), - apy("ethereum"), - apy("avalanche") - ]); - - return [...p, ...e, ...a]; + return ( + await Promise.all(Object.keys(urls).map((chain) => apy(chain))) + ).flat(); }; module.exports = { - timetravel: false, - apy: main, -}; // node src/adaptors/test.js src/adaptors/vesper/index.js \ No newline at end of file + timetravel: false, + apy: main, + url: 'https://app.vesper.finance/', +}; diff --git a/src/adaptors/vesu/abi/extensionAbi.js b/src/adaptors/vesu/abi/extensionAbi.js new file mode 100644 index 0000000000..8b92c4a609 --- /dev/null +++ b/src/adaptors/vesu/abi/extensionAbi.js @@ -0,0 +1,2443 @@ +module.exports = [ + { + "type": "impl", + "name": "DefaultExtensionPOV2Impl", + "interface_name": "vesu::v2::default_extension_po_v2::IDefaultExtensionPOV2" + }, + { + "type": "enum", + "name": "vesu::vendor::pragma::AggregationMode", + "variants": [ + { + "name": "Median", + "type": "()" + }, + { + "name": "Mean", + "type": "()" + }, + { + "name": "Error", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::pragma_oracle::OracleConfig", + "members": [ + { + "name": "pragma_key", + "type": "core::felt252" + }, + { + "name": "timeout", + "type": "core::integer::u64" + }, + { + "name": "number_of_sources", + "type": "core::integer::u32" + }, + { + "name": "start_time_offset", + "type": "core::integer::u64" + }, + { + "name": "time_window", + "type": "core::integer::u64" + }, + { + "name": "aggregation_mode", + "type": "vesu::vendor::pragma::AggregationMode" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::fee_model::FeeConfig", + "members": [ + { + "name": "fee_recipient", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "struct", + "name": "core::integer::u256", + "members": [ + { + "name": "low", + "type": "core::integer::u128" + }, + { + "name": "high", + "type": "core::integer::u128" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::interest_rate_model::InterestRateConfig", + "members": [ + { + "name": "min_target_utilization", + "type": "core::integer::u256" + }, + { + "name": "max_target_utilization", + "type": "core::integer::u256" + }, + { + "name": "target_utilization", + "type": "core::integer::u256" + }, + { + "name": "min_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "max_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "zero_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "rate_half_life", + "type": "core::integer::u256" + }, + { + "name": "target_rate_percent", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::position_hooks::LiquidationConfig", + "members": [ + { + "name": "liquidation_factor", + "type": "core::integer::u64" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::position_hooks::ShutdownConfig", + "members": [ + { + "name": "recovery_period", + "type": "core::integer::u64" + }, + { + "name": "subscription_period", + "type": "core::integer::u64" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::LTVConfig", + "members": [ + { + "name": "max_ltv", + "type": "core::integer::u64" + } + ] + }, + { + "type": "enum", + "name": "vesu::extension::components::position_hooks::ShutdownMode", + "variants": [ + { + "name": "None", + "type": "()" + }, + { + "name": "Recovery", + "type": "()" + }, + { + "name": "Subscription", + "type": "()" + }, + { + "name": "Redemption", + "type": "()" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::position_hooks::ShutdownStatus", + "members": [ + { + "name": "shutdown_mode", + "type": "vesu::extension::components::position_hooks::ShutdownMode" + }, + { + "name": "violating", + "type": "core::bool" + }, + { + "name": "previous_violation_timestamp", + "type": "core::integer::u64" + }, + { + "name": "count_at_violation_timestamp", + "type": "core::integer::u128" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::components::position_hooks::Pair", + "members": [ + { + "name": "total_collateral_shares", + "type": "core::integer::u256" + }, + { + "name": "total_nominal_debt", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::AssetParams", + "members": [ + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "floor", + "type": "core::integer::u256" + }, + { + "name": "initial_rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "initial_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "max_utilization", + "type": "core::integer::u256" + }, + { + "name": "is_legacy", + "type": "core::bool" + }, + { + "name": "fee_rate", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::default_extension_po::VTokenParams", + "members": [ + { + "name": "v_token_name", + "type": "core::felt252" + }, + { + "name": "v_token_symbol", + "type": "core::felt252" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::LTVParams", + "members": [ + { + "name": "collateral_asset_index", + "type": "core::integer::u32" + }, + { + "name": "debt_asset_index", + "type": "core::integer::u32" + }, + { + "name": "max_ltv", + "type": "core::integer::u64" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::default_extension_po::PragmaOracleParams", + "members": [ + { + "name": "pragma_key", + "type": "core::felt252" + }, + { + "name": "timeout", + "type": "core::integer::u64" + }, + { + "name": "number_of_sources", + "type": "core::integer::u32" + }, + { + "name": "start_time_offset", + "type": "core::integer::u64" + }, + { + "name": "time_window", + "type": "core::integer::u64" + }, + { + "name": "aggregation_mode", + "type": "vesu::vendor::pragma::AggregationMode" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::default_extension_po::LiquidationParams", + "members": [ + { + "name": "collateral_asset_index", + "type": "core::integer::u32" + }, + { + "name": "debt_asset_index", + "type": "core::integer::u32" + }, + { + "name": "liquidation_factor", + "type": "core::integer::u64" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::DebtCapParams", + "members": [ + { + "name": "collateral_asset_index", + "type": "core::integer::u32" + }, + { + "name": "debt_asset_index", + "type": "core::integer::u32" + }, + { + "name": "debt_cap", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::default_extension_po::ShutdownParams", + "members": [ + { + "name": "recovery_period", + "type": "core::integer::u64" + }, + { + "name": "subscription_period", + "type": "core::integer::u64" + }, + { + "name": "ltv_params", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "vesu::extension::default_extension_po::FeeParams", + "members": [ + { + "name": "fee_recipient", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, core::felt252, core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, core::felt252, core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::interest_rate_model::InterestRateConfig)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::interest_rate_model::InterestRateConfig)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::pragma_oracle::OracleConfig)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::pragma_oracle::OracleConfig)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::LiquidationConfig)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::LiquidationConfig)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::Pair)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::Pair)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, core::integer::u256)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, core::integer::u256)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>" + } + ] + }, + { + "type": "interface", + "name": "vesu::v2::default_extension_po_v2::IDefaultExtensionPOV2", + "items": [ + { + "type": "function", + "name": "pool_name", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "pool_owner", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "shutdown_mode_agent", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "pragma_oracle", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "pragma_summary", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "oracle_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::pragma_oracle::OracleConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "fee_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::fee_model::FeeConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "debt_caps", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "interest_rate_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::interest_rate_model::InterestRateConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "liquidation_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::position_hooks::LiquidationConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "shutdown_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::position_hooks::ShutdownConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "shutdown_ltv_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::data_model::LTVConfig" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "shutdown_status", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::position_hooks::ShutdownStatus" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "pairs", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::position_hooks::Pair" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "violation_timestamp_for_pair", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u64" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "violation_timestamp_count", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "violation_timestamp", + "type": "core::integer::u64" + } + ], + "outputs": [ + { + "type": "core::integer::u128" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "oldest_violation_timestamp", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::integer::u64" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "next_violation_timestamp", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "violation_timestamp", + "type": "core::integer::u64" + } + ], + "outputs": [ + { + "type": "core::integer::u64" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "v_token_for_collateral_asset", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "collateral_asset_for_v_token", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "v_token", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "create_pool", + "inputs": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "asset_params", + "type": "core::array::Span::" + }, + { + "name": "v_token_params", + "type": "core::array::Span::" + }, + { + "name": "ltv_params", + "type": "core::array::Span::" + }, + { + "name": "interest_rate_configs", + "type": "core::array::Span::" + }, + { + "name": "pragma_oracle_params", + "type": "core::array::Span::" + }, + { + "name": "liquidation_params", + "type": "core::array::Span::" + }, + { + "name": "debt_caps", + "type": "core::array::Span::" + }, + { + "name": "shutdown_params", + "type": "vesu::extension::default_extension_po::ShutdownParams" + }, + { + "name": "fee_params", + "type": "vesu::extension::default_extension_po::FeeParams" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_asset", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset_params", + "type": "vesu::data_model::AssetParams" + }, + { + "name": "v_token_params", + "type": "vesu::extension::default_extension_po::VTokenParams" + }, + { + "name": "interest_rate_config", + "type": "vesu::extension::components::interest_rate_model::InterestRateConfig" + }, + { + "name": "pragma_oracle_params", + "type": "vesu::extension::default_extension_po::PragmaOracleParams" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_asset_parameter", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "parameter", + "type": "core::felt252" + }, + { + "name": "value", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_debt_cap", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_cap", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_interest_rate_parameter", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "parameter", + "type": "core::felt252" + }, + { + "name": "value", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_oracle_parameter", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "parameter", + "type": "core::felt252" + }, + { + "name": "value", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_liquidation_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "liquidation_config", + "type": "vesu::extension::components::position_hooks::LiquidationConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_ltv_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "ltv_config", + "type": "vesu::data_model::LTVConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_shutdown_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "shutdown_config", + "type": "vesu::extension::components::position_hooks::ShutdownConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_shutdown_ltv_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "shutdown_ltv_config", + "type": "vesu::data_model::LTVConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_shutdown_mode", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "shutdown_mode", + "type": "vesu::extension::components::position_hooks::ShutdownMode" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_pool_owner", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_shutdown_mode_agent", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "shutdown_mode_agent", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_shutdown_status", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::extension::components::position_hooks::ShutdownMode" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_fee_config", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "fee_config", + "type": "vesu::extension::components::fee_model::FeeConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "claim_fees", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "migrate_pool", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "v_token_configs", + "type": "core::array::Span::<(core::felt252, core::felt252, core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress)>" + }, + { + "name": "interest_rate_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::interest_rate_model::InterestRateConfig)>" + }, + { + "name": "pragma_oracle_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::extension::components::pragma_oracle::OracleConfig)>" + }, + { + "name": "liquidation_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::LiquidationConfig)>" + }, + { + "name": "pairs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::extension::components::position_hooks::Pair)>" + }, + { + "name": "debt_caps", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, core::integer::u256)>" + }, + { + "name": "shutdown_ltv_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>" + }, + { + "name": "shutdown_config", + "type": "vesu::extension::components::position_hooks::ShutdownConfig" + }, + { + "name": "fee_config", + "type": "vesu::extension::components::fee_model::FeeConfig" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_migrator", + "inputs": [ + { + "name": "migrator", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_extension_utils_class_hash", + "inputs": [ + { + "name": "extension", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "upgrade_name", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_implementation", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "ExtensionImpl", + "interface_name": "vesu::extension::interface::IExtension" + }, + { + "type": "struct", + "name": "vesu::data_model::AssetPrice", + "members": [ + { + "name": "value", + "type": "core::integer::u256" + }, + { + "name": "is_valid", + "type": "core::bool" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::AssetConfig", + "members": [ + { + "name": "total_collateral_shares", + "type": "core::integer::u256" + }, + { + "name": "total_nominal_debt", + "type": "core::integer::u256" + }, + { + "name": "reserve", + "type": "core::integer::u256" + }, + { + "name": "max_utilization", + "type": "core::integer::u256" + }, + { + "name": "floor", + "type": "core::integer::u256" + }, + { + "name": "scale", + "type": "core::integer::u256" + }, + { + "name": "is_legacy", + "type": "core::bool" + }, + { + "name": "last_updated", + "type": "core::integer::u64" + }, + { + "name": "last_rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "last_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "fee_rate", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::Position", + "members": [ + { + "name": "collateral_shares", + "type": "core::integer::u256" + }, + { + "name": "nominal_debt", + "type": "core::integer::u256" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::Context", + "members": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "name": "debt_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "name": "collateral_asset_price", + "type": "vesu::data_model::AssetPrice" + }, + { + "name": "debt_asset_price", + "type": "vesu::data_model::AssetPrice" + }, + { + "name": "collateral_asset_fee_shares", + "type": "core::integer::u256" + }, + { + "name": "debt_asset_fee_shares", + "type": "core::integer::u256" + }, + { + "name": "max_ltv", + "type": "core::integer::u64" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "position", + "type": "vesu::data_model::Position" + } + ] + }, + { + "type": "enum", + "name": "vesu::data_model::AmountType", + "variants": [ + { + "name": "Delta", + "type": "()" + }, + { + "name": "Target", + "type": "()" + } + ] + }, + { + "type": "enum", + "name": "vesu::data_model::AmountDenomination", + "variants": [ + { + "name": "Native", + "type": "()" + }, + { + "name": "Assets", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "alexandria_math::i257::i257", + "members": [ + { + "name": "abs", + "type": "core::integer::u256" + }, + { + "name": "is_negative", + "type": "core::bool" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::Amount", + "members": [ + { + "name": "amount_type", + "type": "vesu::data_model::AmountType" + }, + { + "name": "denomination", + "type": "vesu::data_model::AmountDenomination" + }, + { + "name": "value", + "type": "alexandria_math::i257::i257" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "vesu::data_model::UnsignedAmount", + "members": [ + { + "name": "amount_type", + "type": "vesu::data_model::AmountType" + }, + { + "name": "denomination", + "type": "vesu::data_model::AmountDenomination" + }, + { + "name": "value", + "type": "core::integer::u256" + } + ] + }, + { + "type": "interface", + "name": "vesu::extension::interface::IExtension", + "items": [ + { + "type": "function", + "name": "singleton", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "price", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::data_model::AssetPrice" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "interest_rate", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "utilization", + "type": "core::integer::u256" + }, + { + "name": "last_updated", + "type": "core::integer::u64" + }, + { + "name": "last_full_utilization_rate", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "rate_accumulator", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "utilization", + "type": "core::integer::u256" + }, + { + "name": "last_updated", + "type": "core::integer::u64" + }, + { + "name": "last_rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "last_full_utilization_rate", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "(core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "before_modify_position", + "inputs": [ + { + "name": "context", + "type": "vesu::data_model::Context" + }, + { + "name": "collateral", + "type": "vesu::data_model::Amount" + }, + { + "name": "debt", + "type": "vesu::data_model::Amount" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::Amount, vesu::data_model::Amount)" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "after_modify_position", + "inputs": [ + { + "name": "context", + "type": "vesu::data_model::Context" + }, + { + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "before_transfer_position", + "inputs": [ + { + "name": "from_context", + "type": "vesu::data_model::Context" + }, + { + "name": "to_context", + "type": "vesu::data_model::Context" + }, + { + "name": "collateral", + "type": "vesu::data_model::UnsignedAmount" + }, + { + "name": "debt", + "type": "vesu::data_model::UnsignedAmount" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::UnsignedAmount, vesu::data_model::UnsignedAmount)" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "after_transfer_position", + "inputs": [ + { + "name": "from_context", + "type": "vesu::data_model::Context" + }, + { + "name": "to_context", + "type": "vesu::data_model::Context" + }, + { + "name": "collateral_delta", + "type": "core::integer::u256" + }, + { + "name": "collateral_shares_delta", + "type": "core::integer::u256" + }, + { + "name": "debt_delta", + "type": "core::integer::u256" + }, + { + "name": "nominal_debt_delta", + "type": "core::integer::u256" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "before_liquidate_position", + "inputs": [ + { + "name": "context", + "type": "vesu::data_model::Context" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(core::integer::u256, core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "after_liquidate_position", + "inputs": [ + { + "name": "context", + "type": "vesu::data_model::Context" + }, + { + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "bad_debt", + "type": "core::integer::u256" + }, + { + "name": "data", + "type": "core::array::Span::" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "singleton", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "oracle_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "summary_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "v_token_class_hash", + "type": "core::felt252" + }, + { + "name": "v_token_v2_class_hash", + "type": "core::felt252" + }, + { + "name": "migrator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "extension_utils_class_hash", + "type": "core::felt252" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::position_hooks::position_hooks_component::SetLiquidationConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "liquidation_config", + "type": "vesu::extension::components::position_hooks::LiquidationConfig", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::position_hooks::position_hooks_component::SetShutdownConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "shutdown_config", + "type": "vesu::extension::components::position_hooks::ShutdownConfig", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::position_hooks::position_hooks_component::SetShutdownLTVConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "shutdown_ltv_config", + "type": "vesu::data_model::LTVConfig", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::position_hooks::position_hooks_component::SetDebtCap", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "debt_cap", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::position_hooks::position_hooks_component::Event", + "kind": "enum", + "variants": [ + { + "name": "SetLiquidationConfig", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetLiquidationConfig", + "kind": "nested" + }, + { + "name": "SetShutdownConfig", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetShutdownConfig", + "kind": "nested" + }, + { + "name": "SetShutdownLTVConfig", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetShutdownLTVConfig", + "kind": "nested" + }, + { + "name": "SetDebtCap", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetDebtCap", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::interest_rate_model::interest_rate_model_component::SetInterestRateConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "interest_rate_config", + "type": "vesu::extension::components::interest_rate_model::InterestRateConfig", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::interest_rate_model::interest_rate_model_component::Event", + "kind": "enum", + "variants": [ + { + "name": "SetInterestRateConfig", + "type": "vesu::extension::components::interest_rate_model::interest_rate_model_component::SetInterestRateConfig", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::pragma_oracle::pragma_oracle_component::SetOracleConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "oracle_config", + "type": "vesu::extension::components::pragma_oracle::OracleConfig", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::pragma_oracle::pragma_oracle_component::SetOracleParameter", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "parameter", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "value", + "type": "core::felt252", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::pragma_oracle::pragma_oracle_component::Event", + "kind": "enum", + "variants": [ + { + "name": "SetOracleConfig", + "type": "vesu::extension::components::pragma_oracle::pragma_oracle_component::SetOracleConfig", + "kind": "nested" + }, + { + "name": "SetOracleParameter", + "type": "vesu::extension::components::pragma_oracle::pragma_oracle_component::SetOracleParameter", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "vesu::map_list::map_list_component::Event", + "kind": "enum", + "variants": [] + }, + { + "type": "event", + "name": "vesu::extension::components::fee_model::fee_model_component::SetFeeConfig", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "fee_config", + "type": "vesu::extension::components::fee_model::FeeConfig", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::fee_model::fee_model_component::ClaimFees", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "recipient", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "amount", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::fee_model::fee_model_component::Event", + "kind": "enum", + "variants": [ + { + "name": "SetFeeConfig", + "type": "vesu::extension::components::fee_model::fee_model_component::SetFeeConfig", + "kind": "nested" + }, + { + "name": "ClaimFees", + "type": "vesu::extension::components::fee_model::fee_model_component::ClaimFees", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::tokenization::tokenization_component::CreateVToken", + "kind": "struct", + "members": [ + { + "name": "v_token", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "vesu::extension::components::tokenization::tokenization_component::Event", + "kind": "enum", + "variants": [ + { + "name": "CreateVToken", + "type": "vesu::extension::components::tokenization::tokenization_component::CreateVToken", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::SetAssetParameter", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "parameter", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "value", + "type": "core::integer::u256", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::SetPoolOwner", + "kind": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252", + "kind": "key" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::ContractUpgraded", + "kind": "struct", + "members": [ + { + "name": "new_implementation", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::Event", + "kind": "enum", + "variants": [ + { + "name": "PositionHooksEvents", + "type": "vesu::extension::components::position_hooks::position_hooks_component::Event", + "kind": "nested" + }, + { + "name": "InterestRateModelEvents", + "type": "vesu::extension::components::interest_rate_model::interest_rate_model_component::Event", + "kind": "nested" + }, + { + "name": "PragmaOracleEvents", + "type": "vesu::extension::components::pragma_oracle::pragma_oracle_component::Event", + "kind": "nested" + }, + { + "name": "MapListEvents", + "type": "vesu::map_list::map_list_component::Event", + "kind": "nested" + }, + { + "name": "FeeModelEvents", + "type": "vesu::extension::components::fee_model::fee_model_component::Event", + "kind": "nested" + }, + { + "name": "TokenizationEvents", + "type": "vesu::extension::components::tokenization::tokenization_component::Event", + "kind": "nested" + }, + { + "name": "SetAssetParameter", + "type": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::SetAssetParameter", + "kind": "nested" + }, + { + "name": "SetPoolOwner", + "type": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::SetPoolOwner", + "kind": "nested" + }, + { + "name": "CreateVToken", + "type": "vesu::extension::components::tokenization::tokenization_component::CreateVToken", + "kind": "nested" + }, + { + "name": "SetInterestRateConfig", + "type": "vesu::extension::components::interest_rate_model::interest_rate_model_component::SetInterestRateConfig", + "kind": "nested" + }, + { + "name": "SetOracleConfig", + "type": "vesu::extension::components::pragma_oracle::pragma_oracle_component::SetOracleConfig", + "kind": "nested" + }, + { + "name": "SetLiquidationConfig", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetLiquidationConfig", + "kind": "nested" + }, + { + "name": "SetDebtCap", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetDebtCap", + "kind": "nested" + }, + { + "name": "SetShutdownLTVConfig", + "type": "vesu::extension::components::position_hooks::position_hooks_component::SetShutdownLTVConfig", + "kind": "nested" + }, + { + "name": "ContractUpgraded", + "type": "vesu::v2::default_extension_po_v2::DefaultExtensionPOV2::ContractUpgraded", + "kind": "nested" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/vesu/abi/singletonAbi.js b/src/adaptors/vesu/abi/singletonAbi.js new file mode 100644 index 0000000000..93af041532 --- /dev/null +++ b/src/adaptors/vesu/abi/singletonAbi.js @@ -0,0 +1,2247 @@ +module.exports = [ + { + "name": "SingletonV2Impl", + "type": "impl", + "interface_name": "vesu::v2::singleton_v2::ISingletonV2" + }, + { + "name": "core::integer::u256", + "type": "struct", + "members": [ + { + "name": "low", + "type": "core::integer::u128" + }, + { + "name": "high", + "type": "core::integer::u128" + } + ] + }, + { + "name": "core::bool", + "type": "enum", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "name": "vesu::data_model::AssetConfig", + "type": "struct", + "members": [ + { + "name": "total_collateral_shares", + "type": "core::integer::u256" + }, + { + "name": "total_nominal_debt", + "type": "core::integer::u256" + }, + { + "name": "reserve", + "type": "core::integer::u256" + }, + { + "name": "max_utilization", + "type": "core::integer::u256" + }, + { + "name": "floor", + "type": "core::integer::u256" + }, + { + "name": "scale", + "type": "core::integer::u256" + }, + { + "name": "is_legacy", + "type": "core::bool" + }, + { + "name": "last_updated", + "type": "core::integer::u64" + }, + { + "name": "last_rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "last_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "fee_rate", + "type": "core::integer::u256" + } + ] + }, + { + "name": "vesu::data_model::LTVConfig", + "type": "struct", + "members": [ + { + "name": "max_ltv", + "type": "core::integer::u64" + } + ] + }, + { + "name": "vesu::data_model::Position", + "type": "struct", + "members": [ + { + "name": "collateral_shares", + "type": "core::integer::u256" + }, + { + "name": "nominal_debt", + "type": "core::integer::u256" + } + ] + }, + { + "name": "alexandria_math::i257::i257", + "type": "struct", + "members": [ + { + "name": "abs", + "type": "core::integer::u256" + }, + { + "name": "is_negative", + "type": "core::bool" + } + ] + }, + { + "name": "vesu::data_model::AmountType", + "type": "enum", + "variants": [ + { + "name": "Delta", + "type": "()" + }, + { + "name": "Target", + "type": "()" + } + ] + }, + { + "name": "vesu::data_model::AmountDenomination", + "type": "enum", + "variants": [ + { + "name": "Native", + "type": "()" + }, + { + "name": "Assets", + "type": "()" + } + ] + }, + { + "name": "vesu::data_model::Amount", + "type": "struct", + "members": [ + { + "name": "amount_type", + "type": "vesu::data_model::AmountType" + }, + { + "name": "denomination", + "type": "vesu::data_model::AmountDenomination" + }, + { + "name": "value", + "type": "alexandria_math::i257::i257" + } + ] + }, + { + "name": "vesu::data_model::AssetPrice", + "type": "struct", + "members": [ + { + "name": "value", + "type": "core::integer::u256" + }, + { + "name": "is_valid", + "type": "core::bool" + } + ] + }, + { + "name": "vesu::data_model::Context", + "type": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "name": "debt_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "name": "collateral_asset_price", + "type": "vesu::data_model::AssetPrice" + }, + { + "name": "debt_asset_price", + "type": "vesu::data_model::AssetPrice" + }, + { + "name": "collateral_asset_fee_shares", + "type": "core::integer::u256" + }, + { + "name": "debt_asset_fee_shares", + "type": "core::integer::u256" + }, + { + "name": "max_ltv", + "type": "core::integer::u64" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "position", + "type": "vesu::data_model::Position" + } + ] + }, + { + "name": "vesu::data_model::AssetParams", + "type": "struct", + "members": [ + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "floor", + "type": "core::integer::u256" + }, + { + "name": "initial_rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "initial_full_utilization_rate", + "type": "core::integer::u256" + }, + { + "name": "max_utilization", + "type": "core::integer::u256" + }, + { + "name": "is_legacy", + "type": "core::bool" + }, + { + "name": "fee_rate", + "type": "core::integer::u256" + } + ] + }, + { + "name": "core::array::Span::", + "type": "struct", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "name": "vesu::data_model::LTVParams", + "type": "struct", + "members": [ + { + "name": "collateral_asset_index", + "type": "core::integer::u32" + }, + { + "name": "debt_asset_index", + "type": "core::integer::u32" + }, + { + "name": "max_ltv", + "type": "core::integer::u64" + } + ] + }, + { + "name": "core::array::Span::", + "type": "struct", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "name": "core::array::Span::", + "type": "struct", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "name": "vesu::data_model::ModifyPositionParams", + "type": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "vesu::data_model::Amount" + }, + { + "name": "debt", + "type": "vesu::data_model::Amount" + }, + { + "name": "data", + "type": "core::array::Span::" + } + ] + }, + { + "name": "vesu::data_model::UpdatePositionResponse", + "type": "struct", + "members": [ + { + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "name": "bad_debt", + "type": "core::integer::u256" + } + ] + }, + { + "name": "vesu::data_model::UnsignedAmount", + "type": "struct", + "members": [ + { + "name": "amount_type", + "type": "vesu::data_model::AmountType" + }, + { + "name": "denomination", + "type": "vesu::data_model::AmountDenomination" + }, + { + "name": "value", + "type": "core::integer::u256" + } + ] + }, + { + "name": "vesu::data_model::TransferPositionParams", + "type": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "from_collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "from_debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to_collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to_debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "from_user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to_user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "vesu::data_model::UnsignedAmount" + }, + { + "name": "debt", + "type": "vesu::data_model::UnsignedAmount" + }, + { + "name": "from_data", + "type": "core::array::Span::" + }, + { + "name": "to_data", + "type": "core::array::Span::" + } + ] + }, + { + "name": "vesu::data_model::LiquidatePositionParams", + "type": "struct", + "members": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "receive_as_shares", + "type": "core::bool" + }, + { + "name": "data", + "type": "core::array::Span::" + } + ] + }, + { + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::data_model::AssetConfig)>", + "type": "struct", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, vesu::data_model::AssetConfig)>" + } + ] + }, + { + "name": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>", + "type": "struct", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>" + } + ] + }, + { + "name": "vesu::v2::singleton_v2::ISingletonV2", + "type": "interface", + "items": [ + { + "name": "creator_nonce", + "type": "function", + "inputs": [ + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "name": "extension", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "name": "asset_config_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::AssetConfig, core::integer::u256)" + } + ], + "state_mutability": "view" + }, + { + "name": "asset_config", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::AssetConfig, core::integer::u256)" + } + ], + "state_mutability": "external" + }, + { + "name": "ltv_config", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::data_model::LTVConfig" + } + ], + "state_mutability": "view" + }, + { + "name": "position_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::Position, core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "view" + }, + { + "name": "position", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(vesu::data_model::Position, core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "external" + }, + { + "name": "check_collateralization_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(core::bool, core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "view" + }, + { + "name": "check_collateralization", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "(core::bool, core::integer::u256, core::integer::u256)" + } + ], + "state_mutability": "external" + }, + { + "name": "rate_accumulator_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "rate_accumulator", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { + "name": "utilization_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "utilization", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { + "name": "delegation", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "delegator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "delegatee", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_pool_id", + "type": "function", + "inputs": [ + { + "name": "caller_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "nonce", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_debt", + "type": "function", + "inputs": [ + { + "name": "nominal_debt", + "type": "alexandria_math::i257::i257" + }, + { + "name": "rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "asset_scale", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_nominal_debt", + "type": "function", + "inputs": [ + { + "name": "debt", + "type": "alexandria_math::i257::i257" + }, + { + "name": "rate_accumulator", + "type": "core::integer::u256" + }, + { + "name": "asset_scale", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_collateral_shares_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "alexandria_math::i257::i257" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_collateral_shares", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "alexandria_math::i257::i257" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { + "name": "calculate_collateral_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_shares", + "type": "alexandria_math::i257::i257" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "name": "calculate_collateral", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral_shares", + "type": "alexandria_math::i257::i257" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "external" + }, + { + "name": "deconstruct_collateral_amount_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "vesu::data_model::Amount" + } + ], + "outputs": [ + { + "type": "(alexandria_math::i257::i257, alexandria_math::i257::i257)" + } + ], + "state_mutability": "view" + }, + { + "name": "deconstruct_collateral_amount", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "collateral", + "type": "vesu::data_model::Amount" + } + ], + "outputs": [ + { + "type": "(alexandria_math::i257::i257, alexandria_math::i257::i257)" + } + ], + "state_mutability": "external" + }, + { + "name": "deconstruct_debt_amount_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt", + "type": "vesu::data_model::Amount" + } + ], + "outputs": [ + { + "type": "(alexandria_math::i257::i257, alexandria_math::i257::i257)" + } + ], + "state_mutability": "view" + }, + { + "name": "deconstruct_debt_amount", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt", + "type": "vesu::data_model::Amount" + } + ], + "outputs": [ + { + "type": "(alexandria_math::i257::i257, alexandria_math::i257::i257)" + } + ], + "state_mutability": "external" + }, + { + "name": "context_unsafe", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::data_model::Context" + } + ], + "state_mutability": "view" + }, + { + "name": "context", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "vesu::data_model::Context" + } + ], + "state_mutability": "external" + }, + { + "name": "create_pool", + "type": "function", + "inputs": [ + { + "name": "asset_params", + "type": "core::array::Span::" + }, + { + "name": "ltv_params", + "type": "core::array::Span::" + }, + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "external" + }, + { + "name": "modify_position", + "type": "function", + "inputs": [ + { + "name": "params", + "type": "vesu::data_model::ModifyPositionParams" + } + ], + "outputs": [ + { + "type": "vesu::data_model::UpdatePositionResponse" + } + ], + "state_mutability": "external" + }, + { + "name": "transfer_position", + "type": "function", + "inputs": [ + { + "name": "params", + "type": "vesu::data_model::TransferPositionParams" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "liquidate_position", + "type": "function", + "inputs": [ + { + "name": "params", + "type": "vesu::data_model::LiquidatePositionParams" + } + ], + "outputs": [ + { + "type": "vesu::data_model::UpdatePositionResponse" + } + ], + "state_mutability": "external" + }, + { + "name": "flash_loan", + "type": "function", + "inputs": [ + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + }, + { + "name": "is_legacy", + "type": "core::bool" + }, + { + "name": "data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "modify_delegation", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "delegatee", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "delegation", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "donate_to_reserve", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "retrieve_from_reserve", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "amount", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_asset_config", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "params", + "type": "vesu::data_model::AssetParams" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_ltv_config", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "ltv_config", + "type": "vesu::data_model::LTVConfig" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_asset_parameter", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "parameter", + "type": "core::felt252" + }, + { + "name": "value", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_extension", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_extension_whitelist", + "type": "function", + "inputs": [ + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "approved", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "claim_fee_shares", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "migrate_pool", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "asset_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, vesu::data_model::AssetConfig)>" + }, + { + "name": "ltv_configs", + "type": "core::array::Span::<(core::starknet::contract_address::ContractAddress, core::starknet::contract_address::ContractAddress, vesu::data_model::LTVConfig)>" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "migrate_position", + "type": "function", + "inputs": [ + { + "name": "pool_id", + "type": "core::felt252" + }, + { + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "set_migrator", + "type": "function", + "inputs": [ + { + "name": "migrator", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "upgrade_name", + "type": "function", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "name": "upgrade", + "type": "function", + "inputs": [ + { + "name": "new_implementation", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "name": "OwnableTwoStepImpl", + "type": "impl", + "interface_name": "vesu::vendor::ownable::IOwnableTwoStep" + }, + { + "name": "vesu::vendor::ownable::IOwnableTwoStep", + "type": "interface", + "items": [ + { + "name": "owner", + "type": "function", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "name": "pending_owner", + "type": "function", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "name": "accept_ownership", + "type": "function", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "transfer_ownership", + "type": "function", + "inputs": [ + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "name": "renounce_ownership", + "type": "function", + "inputs": [], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "name": "constructor", + "type": "constructor", + "inputs": [ + { + "name": "singleton_v1", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "migrator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::vendor::ownable::OwnableComponent::OwnershipTransferred", + "type": "event", + "members": [ + { + "kind": "key", + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::vendor::ownable::OwnableComponent::OwnershipTransferStarted", + "type": "event", + "members": [ + { + "kind": "key", + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "enum", + "name": "vesu::vendor::ownable::OwnableComponent::Event", + "type": "event", + "variants": [ + { + "kind": "nested", + "name": "OwnershipTransferred", + "type": "vesu::vendor::ownable::OwnableComponent::OwnershipTransferred" + }, + { + "kind": "nested", + "name": "OwnershipTransferStarted", + "type": "vesu::vendor::ownable::OwnableComponent::OwnershipTransferStarted" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::CreatePool", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::ModifyPosition", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::TransferPosition", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "from_collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "from_debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "to_collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "to_debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "from_user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "to_user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::LiquidatePosition", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "user", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "liquidator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "collateral_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "collateral_shares_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "nominal_debt_delta", + "type": "alexandria_math::i257::i257" + }, + { + "kind": "data", + "name": "bad_debt", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::AccrueFees", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "recipient", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "fee_shares", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::UpdateContext", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "collateral_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "kind": "data", + "name": "debt_asset_config", + "type": "vesu::data_model::AssetConfig" + }, + { + "kind": "data", + "name": "collateral_asset_price", + "type": "vesu::data_model::AssetPrice" + }, + { + "kind": "data", + "name": "debt_asset_price", + "type": "vesu::data_model::AssetPrice" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::Flashloan", + "type": "event", + "members": [ + { + "kind": "key", + "name": "sender", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "amount", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::ModifyDelegation", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "delegator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "delegatee", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "delegation", + "type": "core::bool" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::Donate", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "amount", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::RetrieveReserve", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "receiver", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::SetLTVConfig", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "ltv_config", + "type": "vesu::data_model::LTVConfig" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::SetAssetConfig", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::SetAssetParameter", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "parameter", + "type": "core::felt252" + }, + { + "kind": "data", + "name": "value", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::SetExtension", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "extension", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::MigratePosition", + "type": "event", + "members": [ + { + "kind": "key", + "name": "pool_id", + "type": "core::felt252" + }, + { + "kind": "key", + "name": "collateral_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "debt_asset", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "key", + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "kind": "data", + "name": "collateral_shares", + "type": "core::integer::u256" + }, + { + "kind": "data", + "name": "nominal_debt", + "type": "core::integer::u256" + } + ] + }, + { + "kind": "struct", + "name": "vesu::v2::singleton_v2::SingletonV2::ContractUpgraded", + "type": "event", + "members": [ + { + "kind": "data", + "name": "new_implementation", + "type": "core::starknet::class_hash::ClassHash" + } + ] + }, + { + "kind": "enum", + "name": "vesu::v2::singleton_v2::SingletonV2::Event", + "type": "event", + "variants": [ + { + "kind": "flat", + "name": "OwnableEvent", + "type": "vesu::vendor::ownable::OwnableComponent::Event" + }, + { + "kind": "nested", + "name": "CreatePool", + "type": "vesu::v2::singleton_v2::SingletonV2::CreatePool" + }, + { + "kind": "nested", + "name": "ModifyPosition", + "type": "vesu::v2::singleton_v2::SingletonV2::ModifyPosition" + }, + { + "kind": "nested", + "name": "TransferPosition", + "type": "vesu::v2::singleton_v2::SingletonV2::TransferPosition" + }, + { + "kind": "nested", + "name": "LiquidatePosition", + "type": "vesu::v2::singleton_v2::SingletonV2::LiquidatePosition" + }, + { + "kind": "nested", + "name": "AccrueFees", + "type": "vesu::v2::singleton_v2::SingletonV2::AccrueFees" + }, + { + "kind": "nested", + "name": "UpdateContext", + "type": "vesu::v2::singleton_v2::SingletonV2::UpdateContext" + }, + { + "kind": "nested", + "name": "Flashloan", + "type": "vesu::v2::singleton_v2::SingletonV2::Flashloan" + }, + { + "kind": "nested", + "name": "ModifyDelegation", + "type": "vesu::v2::singleton_v2::SingletonV2::ModifyDelegation" + }, + { + "kind": "nested", + "name": "Donate", + "type": "vesu::v2::singleton_v2::SingletonV2::Donate" + }, + { + "kind": "nested", + "name": "RetrieveReserve", + "type": "vesu::v2::singleton_v2::SingletonV2::RetrieveReserve" + }, + { + "kind": "nested", + "name": "SetLTVConfig", + "type": "vesu::v2::singleton_v2::SingletonV2::SetLTVConfig" + }, + { + "kind": "nested", + "name": "SetAssetConfig", + "type": "vesu::v2::singleton_v2::SingletonV2::SetAssetConfig" + }, + { + "kind": "nested", + "name": "SetAssetParameter", + "type": "vesu::v2::singleton_v2::SingletonV2::SetAssetParameter" + }, + { + "kind": "nested", + "name": "SetExtension", + "type": "vesu::v2::singleton_v2::SingletonV2::SetExtension" + }, + { + "kind": "nested", + "name": "MigratePosition", + "type": "vesu::v2::singleton_v2::SingletonV2::MigratePosition" + }, + { + "kind": "nested", + "name": "ContractUpgraded", + "type": "vesu::v2::singleton_v2::SingletonV2::ContractUpgraded" + } + ] + } +] \ No newline at end of file diff --git a/src/adaptors/vesu/index.js b/src/adaptors/vesu/index.js new file mode 100644 index 0000000000..947dceb6ff --- /dev/null +++ b/src/adaptors/vesu/index.js @@ -0,0 +1,127 @@ +const utils = require('../utils'); +const { call } = require('./starknet-helper'); +const singletonAbi = require('./abi/singletonAbi'); +const extensionAbi = require('./abi/extensionAbi'); + +const API_URL = 'https://api.vesu.xyz/markets'; +const SINGLETON_CONTRACT = '0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160'; +const EXTENSION_CONTRACT = '0x4e06e04b8d624d039aa1c3ca8e0aa9e21dc1ccba1d88d0d650837159e0ee054'; + +const poolsFunction = async () => { + const markets = await utils.getData(API_URL); + const pools = []; + + // Extract ABI functions once (they're constant) + const assetConfigAbi = singletonAbi + .find(item => item.type === 'interface' && item.name === 'vesu::v2::singleton_v2::ISingletonV2') + .items.find(fn => fn.name === 'asset_config_unsafe'); + + const extensionInterface = extensionAbi.find(item => + item.type === 'interface' && + item.name === 'vesu::extension::interface::IExtension' + ); + const interestRateAbi = extensionInterface?.items.find(fn => fn.name === 'interest_rate'); + + for (const market of markets.data) { + const { pool, stats, symbol, decimals, usdPrice, address } = market; + + try { + if (!stats.totalSupplied?.value || + stats.totalSupplied.value === '0' || + !usdPrice?.value) { + continue; + } + + const totalSuppliedToken = Number(stats.totalSupplied.value) / Math.pow(10, decimals); + const priceUsd = Number(usdPrice.value) / Math.pow(10, usdPrice.decimals); + const totalSupplyUsd = totalSuppliedToken * priceUsd; + + const supplyRewardsAPR = Number(stats.defiSpringSupplyApr.value) / Math.pow(10, stats.defiSpringSupplyApr.decimals) * 100; + + const totalDebtToken = Number(stats.totalDebt?.value || 0) / Math.pow(10, decimals); + const totalBorrowUsd = totalDebtToken * priceUsd; + + const rawResponse = await call({ + target: SINGLETON_CONTRACT, + abi: assetConfigAbi, + params: [pool.id, address] + }); + + if (!rawResponse || rawResponse.length < 2) { + continue; + } + + const [assetConfigStruct, additionalValue] = rawResponse; + + const totalNominalDebt = assetConfigStruct.total_nominal_debt; + const lastRateAccumulator = assetConfigStruct.last_rate_accumulator; + const reserve = assetConfigStruct.reserve; + const lastUpdated = Number(assetConfigStruct.last_updated); + const lastFullUtilizationRate = assetConfigStruct.last_full_utilization_rate; + + const totalDebt = totalNominalDebt * lastRateAccumulator / BigInt(1e18); + const totalSupplied = totalDebt + reserve; + const utilization = totalSupplied > 0n ? Number(totalDebt * BigInt(1e18) / totalSupplied) / 1e18 : 0; + + let supplyAPY = 0; + let borrowAPY = 0; + + if (interestRateAbi) { + const borrowRateResponse = await call({ + target: EXTENSION_CONTRACT, + abi: interestRateAbi, + params: [ + pool.id, + address, + Math.floor(utilization * 1e18).toString(), + lastUpdated.toString(), + lastFullUtilizationRate.toString() + ] + }); + + if (borrowRateResponse && borrowRateResponse[0]) { + const borrowRatePerSecond = Number(borrowRateResponse[0]) / 1e18; + const borrowAPYDecimal = Math.pow(1 + borrowRatePerSecond, 365.25 * 24 * 3600) - 1; + borrowAPY = borrowAPYDecimal * 100; + + const supplyAPYDecimal = utilization * borrowAPYDecimal; + supplyAPY = supplyAPYDecimal * 100; + } + } + + const poolData = { + pool: `${pool.id}-${symbol}-starknet`, + chain: 'Starknet', + project: 'vesu', + symbol: symbol, + tvlUsd: totalSupplyUsd - totalBorrowUsd, + apyBase: supplyAPY > 0 ? supplyAPY : null, + apyReward: supplyRewardsAPR > 0 ? supplyRewardsAPR : null, + apyBaseBorrow: borrowAPY > 0 ? borrowAPY : null, + apyRewardBorrow: null, + totalSupplyUsd: totalSupplyUsd, + totalBorrowUsd: totalBorrowUsd, + underlyingTokens: [address], + url: "https://vesu.xyz/markets", + poolMeta: symbol, + }; + + if (supplyRewardsAPR > 0) { + poolData.rewardTokens = ['0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d']; + } + + pools.push(poolData); + + } catch (error) { + continue; + } + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.vesu.xyz', +}; \ No newline at end of file diff --git a/src/adaptors/vesu/starknet-helper.js b/src/adaptors/vesu/starknet-helper.js new file mode 100644 index 0000000000..ea0c848be9 --- /dev/null +++ b/src/adaptors/vesu/starknet-helper.js @@ -0,0 +1,129 @@ +const { Contract, validateAndParseAddress, number, hash, uint256, } = require('starknet') +const axios = require('axios') + +function formCallBody({ abi, target, params = [] }, id = 0) { + if ((params || params === 0) && !Array.isArray(params)) + params = [params] + + if (abi.name === 'asset_config_unsafe' && params.length >= 1) { + const poolId = params[0] + if (typeof poolId === 'string' && poolId.length > 60 && !poolId.startsWith('0x')) { + params[0] = '0x' + BigInt(poolId).toString(16) + } + } + + if (abi.name === 'interest_rate' && params.length === 5) { + const poolId = params[0] + if (typeof poolId === 'string' && poolId.length > 60 && !poolId.startsWith('0x')) { + params[0] = '0x' + BigInt(poolId).toString(16) + } + + const utilizationU256 = BigInt(params[2]) + const utilizationLow = utilizationU256 & ((1n << 128n) - 1n) + const utilizationHigh = utilizationU256 >> 128n + + const rateU256 = BigInt(params[4]) + const rateLow = rateU256 & ((1n << 128n) - 1n) + const rateHigh = rateU256 >> 128n + + params = [ + params[0], + params[1], + '0x' + utilizationLow.toString(16), + '0x' + utilizationHigh.toString(16), + '0x' + BigInt(params[3]).toString(16), + '0x' + rateLow.toString(16), + '0x' + rateHigh.toString(16) + ] + } + + const entryPointSelector = hash.getSelectorFromName(abi.name) + + const requestData = { + contract_address: target, + entry_point_selector: entryPointSelector, + calldata: params + } + + return { jsonrpc: "2.0", id, method: "starknet_call", params: [requestData, "latest"] } +} + +function parseAssetConfigRaw(result) { + if (!result || result.length < 22) { + return null + } + + const parseU256 = (low, high) => { + return BigInt(low) + (BigInt(high) << 128n) + } + + const assetConfig = { + total_collateral_shares: parseU256(result[0], result[1]), + total_nominal_debt: parseU256(result[2], result[3]), + reserve: parseU256(result[4], result[5]), + max_utilization: parseU256(result[6], result[7]), + floor: parseU256(result[8], result[9]), + scale: parseU256(result[10], result[11]), + is_legacy: result[12] === '1', + last_updated: BigInt(result[13]), + last_rate_accumulator: parseU256(result[14], result[15]), + last_full_utilization_rate: parseU256(result[16], result[17]), + fee_rate: parseU256(result[18], result[19]) + } + + const additionalValue = parseU256(result[20], result[21]) + + return [assetConfig, additionalValue] +} + +function parseOutput(result, abi) { + if (abi.name === 'asset_config_unsafe') { + return parseAssetConfigRaw(result) + } + + if (abi.name === 'interest_rate') { + if (result && result.length >= 2) { + const low = BigInt(result[0]) + const high = BigInt(result[1]) + const fullValue = low + (high << 128n) + return [fullValue.toString()] + } else if (result && result.length === 1) { + return [result[0]] + } + return result + } + + try { + const contract = new Contract([abi], null, null) + let response = contract.parseResponse(abi.name, result) + + if (abi.outputs.length === 1) { + response = response[0] + if (abi.outputs[0].type === 'Uint256') return response + switch (abi.customType) { + case 'address': return validateAndParseAddress(response) + case 'Uint256': return response + } + } + return response + } catch (error) { + return result + } +} + +async function call({ abi, target, params = [] } = {}) { + const callBody = formCallBody({ abi, target, params }) + + const { data } = await axios.post(process.env.STARKNET_RPC, callBody) + + if (data.error) { + throw new Error(`RPC Error: ${data.error.message}`) + } + + const result = data.result + return parseOutput(result, abi) +} + +module.exports = { + call, +} \ No newline at end of file diff --git a/src/adaptors/vires-finance/index.js b/src/adaptors/vires-finance/index.js new file mode 100644 index 0000000000..8f59c47693 --- /dev/null +++ b/src/adaptors/vires-finance/index.js @@ -0,0 +1,57 @@ +const utils = require('../utils'); + +const API_URL = 'https://api.vires.finance/state'; +const API_URL_CONFIG = 'https://api.vires.finance/v2/config'; + +const configStateIDMapping = { + '3PCwFXSq8vj8iKitA5zrrLRbuqehfmimpce': + 'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', // usdn + '3PBEwUv36ZXRiDEaVmXR41sPvbGfm3nyC6k': + '34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ', // usdt + '3PA7QMFyHMtHeP66SUQnwCgwKQHKpCyXWwd': + '8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS', // btc + '3PPdeWwrzaxqgr6BuReoF3sWfxW8SYv743D': + '474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu', // eth + '3PN1LXdwuFWH3paF3fpMNCWk7oWRzXCeMSC': + '6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ', // usdc + '3PBjqiMwwag72VWUtHNnVrxTBrNK8D7bVcN': + 'DUk2YTxhRoAqMJLus4G2b3fR8hMHVh6eiyFx5r29VR6t', // eurn + '3PGzUA7Yp2RFobH9mPFYsZC1wkwWHNsP14q': + '8zUYbdB8Q6mDhpcXYv52ji8ycfj4SDX4gJXS7YY3dA4R', // dai + '3PNKc29PsUULxcHexjcZu7cMBqAAEYNfXnH': + '8DLiYZjo3UUaRBTHU7Ayoqg4ihwb6YH1AfXrrhdjQ7K1', // busd + '3P8G747fnB1DTQ4d5uD114vjAaeezCW4FaM': 'WAVES', // waves +}; + +const getApy = async () => { + const { markets } = await utils.getData(API_URL); + const { assets } = await utils.getData(API_URL_CONFIG); + + const pools = markets.map((item) => { + if (item.name.toLowerCase().includes('legacy')) return null; + + return { + pool: item.address, + chain: utils.formatChain('waves'), + project: 'vires-finance', + symbol: item.name, + tvlUsd: Number(item.totalSupplyUsd) - Number(item.totalDebtUsd), + apyBase: Number(item.supplyApy) * 100, + apyReward: Number(item.supplyViresApr) * 100, + rewardTokens: ['DSbbhLsSTeDg5Lsiufk2Aneh3DjVqJuPr2M9uU1gwy5p'], + // borrow fields + totalSupplyUsd: Number(item.totalSupplyUsd), + totalBorrowUsd: Number(item.totalDebtUsd), + apyBaseBorrow: Number(item.borrowApr) * 100, + apyRewardBorrow: Number(item.borrowViresApr) * 100, + ltv: assets[configStateIDMapping[item.address]]?.collateralFactor / 1000, + }; + }); + return pools.filter((p) => p !== null); +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://vires.finance/', +}; diff --git a/src/adaptors/vvs-standard/abis.js b/src/adaptors/vvs-standard/abis.js new file mode 100644 index 0000000000..f0e27388c8 --- /dev/null +++ b/src/adaptors/vvs-standard/abis.js @@ -0,0 +1,839 @@ +module.exports = { + masterChefABI: [ + { + inputs: [ + { internalType: 'contract VVSToken', name: '_vvs', type: 'address' }, + { internalType: 'contract Workbench', name: '_bench', type: 'address' }, + { internalType: 'address', name: '_devaddr', type: 'address' }, + { internalType: 'uint256', name: '_startBlock', type: 'uint256' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newRatio', + type: 'uint256', + }, + ], + name: 'UpdatedVVSStakingRatio', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'BONUS_MULTIPLIER', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'contract IERC20', name: '_lpToken', type: 'address' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'bench', + outputs: [ + { internalType: 'contract Workbench', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_devaddr', type: 'address' }], + name: 'dev', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'devaddr', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: '_teamAddresses', + type: 'address[]', + }, + { internalType: 'uint256[]', name: '_teamAmounts', type: 'uint256[]' }, + ], + name: 'distributeSupply', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'enterStaking', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_from', type: 'uint256' }, + { internalType: 'uint256', name: '_to', type: 'uint256' }, + ], + name: 'getMultiplier', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_amount', type: 'uint256' }], + name: 'leaveStaking', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'migrator', + outputs: [ + { internalType: 'contract IMigratorChef', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingVVS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'lpToken', type: 'address' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'accVVSPerShare', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'bool', name: '_withUpdate', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IMigratorChef', + name: '_migrator', + type: 'address', + }, + ], + name: 'setMigrator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'multiplierNumber', type: 'uint256' }, + ], + name: 'updateMultiplier', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_ratio', type: 'uint256' }], + name: 'updateStakingRatio', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vvs', + outputs: [ + { internalType: 'contract VVSToken', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vvsPerBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vvsStakingRatio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + lpTokenABI: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/vvs-standard/index.js b/src/adaptors/vvs-standard/index.js new file mode 100644 index 0000000000..919f0a1942 --- /dev/null +++ b/src/adaptors/vvs-standard/index.js @@ -0,0 +1,286 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const { masterChefABI, lpTokenABI } = require('./abis'); +const utils = require('../utils'); + +const RPC_URL = 'https://evm.cronos.org/'; +const API_URL = 'https://graph.cronoslabs.com/subgraphs/name/vvs/exchange'; + +const MASTERCHEF_ADDRESS = '0xdccd6455ae04b03d785f12196b492b18129564bc'; + +const CRONOS_BLOCK_TIME = 6; +const BLOCKS_PER_YEAR = Math.floor((60 / CRONOS_BLOCK_TIME) * 60 * 24 * 365); +const BLOCKS_PER_DAY = Math.floor((60 / CRONOS_BLOCK_TIME) * 60 * 24); +const SECONDS_PER_YEAR = 60 * 60 * 24 * 365; +const FEE_RATE = 0.002; + +const ARGO = '0x47a9d630dc5b28f75d3af3be3aaa982512cd89aa'; +const FERRO = '0x39bc1e38c842c60775ce37566d03b41a7a66c782'; + +const EXTRA_REWARD_ADDRESS = { + 34: '0xb966b5d6a0fcd5b373b180bbe072bbfbbee10552', + 36: FERRO, +}; + +const web3 = new Web3(RPC_URL, 25); + +const pairQuery = gql` + query pairQuery($id: ID!) { + pair(id: $id) { + name + id + token0 { + decimals + id + } + token1 { + decimals + id + } + } + pairDayDatas( + orderBy: date + orderDirection: desc + where: { pairAddress: $id } + first: 7 + ) { + dailyVolumeUSD + } + } +`; + +const getPairInfo = (pair) => { + const pairInfo = request(API_URL, pairQuery, { id: pair.toLowerCase() }); + + return pairInfo; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + vvsPerBlock, + vvsPrice, + reserveUSD, + lpApr +) => { + const poolWeight = poolInfo.allocPoint / Number(totalAllocPoint); + const vvsPerYear = BLOCKS_PER_YEAR * vvsPerBlock; + + return ((poolWeight * vvsPerYear * vvsPrice) / reserveUSD) * 100 + lpApr; +}; + +const BASE_TOKENS = [ + { + symbol: 'WCRO', + cgName: 'wrapped-cro', + }, + { symbol: 'VVS', cgName: 'vvs-finance' }, +]; + +const calculateReservesUSD = ( + pairName, + reserves, + reservesRatio, + token0decimals, + token1decimals, + baseTokenPrices +) => { + const [token0, token1] = pairName.split('-'); + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1decimals)); + + if (token0.includes('USD')) return reserve0.times(2); + if (token1.includes('USD')) return reserve1.times(2); + + const token0Price = baseTokenPrices[token0]; + const token1Price = baseTokenPrices[token1]; + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getExtraRewardPoolsPerYear = async () => { + const tokens = ['argo-finance', 'ferro'] + .map((t) => `coingecko:${t}`) + .join(','); + const prices = ( + await utils.getData(`https://coins.llama.fi/prices/current/${tokens}`) + ).coins; + + const poolsRewardPerSec = { + 'argo-finance': 1.04, + ferro: 1.929, + }; + const poolsIds = { + 'argo-finance': 34, + ferro: 36, + }; + + const rewardTokenAddress = { + 'argo-finance': '0xb966b5d6a0fcd5b373b180bbe072bbfbbee10552', + ferro: FERRO, + }; + + return Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [poolsIds[name.replace('coingecko:', '')]]: + poolsRewardPerSec[name.replace('coingecko:', '')] * + SECONDS_PER_YEAR * + price.price, + }), + {} + ); +}; + +const getBaseTokensPrice = async () => { + const prices = ( + await utils.getData( + `https://coins.llama.fi/prices/current/${BASE_TOKENS.map( + ({ cgName }) => `coingecko:${cgName}` + ).join(',')}` + ) + ).coins; + + const pricesMap = BASE_TOKENS.reduce( + (acc, token) => ({ + ...acc, + [token.symbol]: prices[`coingecko:${token.cgName}`].price, + }), + {} + ); + + return pricesMap; +}; + +const main = async () => { + const baseTokensPrices = await getBaseTokensPrice(); + const extraRewardUsd = await getExtraRewardPoolsPerYear(); + const masterChef = new web3.eth.Contract(masterChefABI, MASTERCHEF_ADDRESS); + + const poolsCount = await masterChef.methods.poolLength().call(); + + const totalAllocPoint = await masterChef.methods.totalAllocPoint().call(); + const vvsPerBlock = await masterChef.methods.vvsPerBlock().call(); + const normilizedVvsPerBlock = Number(vvsPerBlock) / 1e18; + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'cronos', + requery: true, + permitFailure: true, + }); + + const nonLpPools = [0, 23]; + + const poolsInfo = poolsRes.output + .map((res, i) => ({ ...res.output, i })) + .filter((_, id) => !nonLpPools.includes(id)) + .filter(({ allocPoint }) => allocPoint > 0); + + const lpTokens = poolsInfo.map(({ lpToken }) => lpToken); + + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'cronos', + permitFailure: true, + ...(method !== 'getReserves' ? { requery: true } : {}), + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + + const pools = await Promise.all( + poolsInfo.map((pool, i) => + getPairInfo(lpTokens[i]).then( + ({ pair: pairInfo, pairDayDatas: volumeInfo }) => { + const poolInfo = poolsInfo[i]; + const reserves = reservesData[i]; + if (!reserves) return null; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const reserveUSD = calculateReservesUSD( + pairInfo.name, + reserves, + masterChefBalance / supply, + pairInfo.token0.decimals, + pairInfo.token1.decimals, + baseTokensPrices + ) + ?.div(1e18) + ?.toString(); + + const lpFees7D = + volumeInfo.reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * FEE_RATE; + const apyBase = ((lpFees7D * 52) / reserveUSD) * 100; + + const extraReward = extraRewardUsd[poolInfo.i]; + const extraRewardToken = EXTRA_REWARD_ADDRESS[poolInfo.i]; + const extraApy = extraReward ? (extraReward / reserveUSD) * 100 : 0; + + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normilizedVvsPerBlock, + baseTokensPrices['VVS'], + reserveUSD, + extraApy + ); + + const pool = { + pool: pairInfo.id, + chain: utils.formatChain('cronos'), + project: 'vvs-standard', + symbol: pairInfo.name, + tvlUsd: Number(reserveUSD), + apyBase, + apyReward, + underlyingTokens: [pairInfo.token0.id, pairInfo.token1.id], + rewardTokens: extraRewardToken + ? [ + '0x2d03bece6747adc00e1a131bba1469c15fd11e03', // vvs + extraRewardToken, + ] + : ['0x2d03bece6747adc00e1a131bba1469c15fd11e03'], + }; + return pool; + } + ) + ) + ); + + // // rmv null elements + return pools.filter(Boolean).filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://vvs.finance/farms', +}; diff --git a/src/adaptors/wasabi/index.js b/src/adaptors/wasabi/index.js new file mode 100644 index 0000000000..c145cb2251 --- /dev/null +++ b/src/adaptors/wasabi/index.js @@ -0,0 +1,33 @@ +const utils = require('../utils') +const sdk = require('@defillama/sdk'); + +const apy = async () => { + const vaultsData = await utils.getData('https://gateway.wasabi.xyz/vaults') + return vaultsData.items.map(data => { + const vault = data.vault; + const token = data.token; + const totalBorrowUsd = data.tvlUsd * data.utilizationRate; + const apr = data.apr + data.nativeApr; + const isRewardAPY = vault.chain === 'berachain' && token.symbol === 'WBERA'; + const isDeprecated = vault.deprecated; + return { + pool: `wasabi-${vault.chain}-${vault.symbol}`, + chain: vault.chain === "mainnet" ? "Ethereum" : utils.formatChain(vault.chain), + project: 'wasabi', + symbol: token.symbol, + tvlUsd: isDeprecated ? 0 : data.tvlUsd, + apyBase: isRewardAPY ? 0 : apr * 100, + apyReward: isRewardAPY ? apr * 100 : 0, + underlyingTokens: [vault.tokenAddress], + rewardTokens: isRewardAPY ? ["0xac03CABA51e17c86c921E1f6CBFBdC91F8BB2E6b"] : [], + totalSupplyUsd: data.tvlUsd, + totalBorrowUsd, + url: `https://app.wasabi.xyz/earn?vault=${vault.symbol}&network=${vault.chain}`, + } + }) +} + +module.exports = { + timetravel: false, + apy +} diff --git a/src/adaptors/waterneuron/index.js b/src/adaptors/waterneuron/index.js new file mode 100644 index 0000000000..96f02b2b6a --- /dev/null +++ b/src/adaptors/waterneuron/index.js @@ -0,0 +1,71 @@ +const utils = require('../utils'); + +async function fetchPrice() { + try { + const response = await fetch('https://min-api.cryptocompare.com/data/generateAvg?fsym=ICP&tsym=USD&e=coinbase'); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + const data = await response.json(); + return data.RAW.PRICE; + } catch (error) { + throw new Error('There was a problem with the fetch operation:'); + } +} + +function parsePrometheusMetrics(data) { + const lines = data.split('\n'); + let metrics = new Map(); + for (const line of lines) { + if (line.startsWith('#')) { + continue; + } else { + const [name, value, timestamp] = line.split(' '); + metrics.set(name, value); + } + } + return metrics; +} + +async function fetchAndParseMetrics(url) { + try { + const response = await fetch(url, { + method: 'GET', + }); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const rawData = await response.text(); + return parsePrometheusMetrics(rawData); + } catch (error) { + console.error('Error fetching metrics:', error); + throw error; + } +} + +async function fetchData() { + const URL = "https://tsbvt-pyaaa-aaaar-qafva-cai.raw.icp0.io/metrics"; + const res = await fetchAndParseMetrics(URL); + const icp_price = await fetchPrice(); + const E8S = 100000000; + + const tvl = (((Number(res.get("neuron_6m_tracked_stake")) + Number(res.get("neuron_8y_stake"))) / E8S) * icp_price) || 0; + + const apy = Number(res.get("apy")) * 100 || 0; + + return [{ + pool: `waterneuron-icp`, + chain: utils.formatChain('icp'), + project: 'waterneuron', + symbol: 'nICP', + tvlUsd: tvl, + apyBase: apy, + underlyingTokens: ['nICP'], + }]; +} + +module.exports = { + timetravel: false, + apy: fetchData, + url: 'https://waterneuron.fi', +}; diff --git a/src/adaptors/web3.world/index.js b/src/adaptors/web3.world/index.js new file mode 100644 index 0000000000..78fc5993e9 --- /dev/null +++ b/src/adaptors/web3.world/index.js @@ -0,0 +1,73 @@ +const { default: BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + + +const getPoolStats = async () => { + return await utils.getData( + "https://api.web3.world/v2/pools", + { + limit: 1000, + offset: 0, + ordering: "tvldescending", + whiteListUri: "https://static.web3.world/assets/manifest.json", + } + ); +}; + +const getFarmingPoolStats = async () => { + return await utils.getData( + "https://farming.web3.world/v2/gauges", + { + additionalTokenRoots: [], + limit: 1000, + offset: 0, + showLowBalance: false, + whitelistUri: "https://static.web3.world/assets/manifest.json" + } + ); +}; + +const calcApy = (fee7d, tvl) => { + const apy = BigNumber(fee7d).div(7).times(365).div(tvl).div(365).plus(1).pow(365).minus(1); + if (apy.isNaN() || !apy.isFinite()) return 0 + return apy.times(100).toNumber() +} + +const fetch = async () => { + const poolsStats = await getPoolStats(); + const farmingPoolsStats = await getFarmingPoolStats(); + const result = [] + poolsStats.pools.forEach((pool) => { + result.push({ + pool: pool.meta.poolAddress, + chain: utils.formatChain('venom'), + project: 'web3.world', + symbol: pool.meta.currencies.join('-'), + tvlUsd: Number(pool.tvl), + underlyingTokens: pool.meta.currencyAddresses, + apyBase: calcApy(pool.fee7d, pool.tvl), + url: "https://web3.world/pools/" + pool.meta.poolAddress + }) + }) + farmingPoolsStats.gauges.forEach((pool) => { + result.push({ + pool: pool.address, + chain: utils.formatChain('venom'), + project: 'web3.world', + symbol: pool.poolTokens.map(({ tokenSymbol }) => tokenSymbol).join('-'), + tvlUsd: Number(pool.tvl), + rewardTokens: pool.rewardTokens.map(({ tokenRoot }) => tokenRoot), + underlyingTokens: pool.poolTokens.map(({ tokenRoot }) => tokenRoot), + apyBase: Number(pool.minApr), + url: "https://web3.world/farming/" + pool.address + }) + }) + + return result; +}; + +module.exports = { + timetravel: false, + apy: fetch, + url: 'https://web3.world', +}; diff --git a/src/adaptors/wefi/abi.js b/src/adaptors/wefi/abi.js new file mode 100644 index 0000000000..0fcfd9d70e --- /dev/null +++ b/src/adaptors/wefi/abi.js @@ -0,0 +1,2833 @@ +module.exports = { + ercDelegator: [ + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'repayAmount', type: 'uint256' }], + name: 'repayBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'reserveFactorMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'exchangeRateStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'src', type: 'address' }, + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + ], + name: 'repayBorrowBehalf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'pendingAdmin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOfUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getCash', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newComptroller', type: 'address' }], + name: '_setComptroller', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalBorrows', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'comptroller', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'reduceAmount', type: 'uint256' }], + name: '_reduceReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'initialExchangeRateMantissa', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'accrualBlockNumber', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'underlying', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'totalBorrowsCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemAmount', type: 'uint256' }], + name: 'redeemUnderlying', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalReserves', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'borrowBalanceStored', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'mintAmount', type: 'uint256' }], + name: 'mint', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'accrueInterest', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'dst', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowIndex', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'supplyRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'liquidator', type: 'address' }, + { name: 'borrower', type: 'address' }, + { name: 'seizeTokens', type: 'uint256' }, + ], + name: 'seize', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newPendingAdmin', type: 'address' }], + name: '_setPendingAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'exchangeRateCurrent', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ name: 'account', type: 'address' }], + name: 'getAccountSnapshot', + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'borrowAmount', type: 'uint256' }], + name: 'borrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'redeemTokens', type: 'uint256' }], + name: 'redeem', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'spender', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: '_acceptAdmin', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newInterestRateModel', type: 'address' }], + name: '_setInterestRateModel', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'interestRateModel', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { name: 'borrower', type: 'address' }, + { name: 'repayAmount', type: 'uint256' }, + { name: 'cTokenCollateral', type: 'address' }, + ], + name: 'liquidateBorrow', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'admin', + outputs: [{ name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'borrowRatePerBlock', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ name: 'newReserveFactorMantissa', type: 'uint256' }], + name: '_setReserveFactor', + outputs: [{ name: '', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'isCToken', + outputs: [{ name: '', type: 'bool' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'underlying_', type: 'address' }, + { name: 'comptroller_', type: 'address' }, + { name: 'interestRateModel_', type: 'address' }, + { name: 'initialExchangeRateMantissa_', type: 'uint256' }, + { name: 'name_', type: 'string' }, + { name: 'symbol_', type: 'string' }, + { name: 'decimals_', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'interestAccumulated', type: 'uint256' }, + { indexed: false, name: 'borrowIndex', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'AccrueInterest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'minter', type: 'address' }, + { indexed: false, name: 'mintAmount', type: 'uint256' }, + { indexed: false, name: 'mintTokens', type: 'uint256' }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'redeemer', type: 'address' }, + { indexed: false, name: 'redeemAmount', type: 'uint256' }, + { indexed: false, name: 'redeemTokens', type: 'uint256' }, + ], + name: 'Redeem', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'borrowAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'payer', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'accountBorrows', type: 'uint256' }, + { indexed: false, name: 'totalBorrows', type: 'uint256' }, + ], + name: 'RepayBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'liquidator', type: 'address' }, + { indexed: false, name: 'borrower', type: 'address' }, + { indexed: false, name: 'repayAmount', type: 'uint256' }, + { indexed: false, name: 'cTokenCollateral', type: 'address' }, + { indexed: false, name: 'seizeTokens', type: 'uint256' }, + ], + name: 'LiquidateBorrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldPendingAdmin', type: 'address' }, + { indexed: false, name: 'newPendingAdmin', type: 'address' }, + ], + name: 'NewPendingAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldAdmin', type: 'address' }, + { indexed: false, name: 'newAdmin', type: 'address' }, + ], + name: 'NewAdmin', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldComptroller', type: 'address' }, + { indexed: false, name: 'newComptroller', type: 'address' }, + ], + name: 'NewComptroller', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldInterestRateModel', type: 'address' }, + { indexed: false, name: 'newInterestRateModel', type: 'address' }, + ], + name: 'NewMarketInterestRateModel', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'oldReserveFactorMantissa', type: 'uint256' }, + { indexed: false, name: 'newReserveFactorMantissa', type: 'uint256' }, + ], + name: 'NewReserveFactor', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'admin', type: 'address' }, + { indexed: false, name: 'reduceAmount', type: 'uint256' }, + { indexed: false, name: 'newTotalReserves', type: 'uint256' }, + ], + name: 'ReservesReduced', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: false, name: 'error', type: 'uint256' }, + { indexed: false, name: 'info', type: 'uint256' }, + { indexed: false, name: 'detail', type: 'uint256' }, + ], + name: 'Failure', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'amount', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + ], + comptrollerAbi: [ + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "action", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CompGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "CompSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorCompSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "compSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierComp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketBuyListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "MarketSettleListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldBorrowCapGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "NewBorrowCapGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewBuyFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract PriceOracle", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "inputs": [], + "name": "_borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract CToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "compSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isComped", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isBuyAvailable", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "buyFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isSettleAvailable", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract PriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "seizeGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "cTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract PriceOracle", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "_setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newBorrowCapGuardian", + "type": "address" + } + ], + "name": "_setBorrowCapGuardian", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setMintPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setBorrowPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setTransferPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setSeizePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract CToken[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "_grantComp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setCompSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "compSpeed", + "type": "uint256" + } + ], + "name": "_setContributorCompSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract CToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCompAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrowAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "buyAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "partialAmount", + "type": "uint256" + } + ], + "name": "buyAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportBuy", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newBuyFactorMantissa", + "type": "uint256" + } + ], + "name": "_setBuyFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + }, + { + "internalType": "address payable", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "proxyMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "cTokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "enterMarketsForUser", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "borrowedAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowedAssetAmount", + "type": "uint256" + } + ], + "name": "swapAndSettleCalculateRepayAmount", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "err", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetTokensAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "estimatedShortfall", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "estimatedLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "repayAmountRequired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalReceivable", + "type": "uint256" + } + ], + "internalType": "struct ComptrollerInterface.SettleVars", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract CToken", + "name": "cToken", + "type": "address" + } + ], + "name": "_supportSettle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "cToken", + "type": "address" + } + ], + "name": "isMarketListed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], +}; diff --git a/src/adaptors/wefi/index.js b/src/adaptors/wefi/index.js new file mode 100644 index 0000000000..cfce65e21e --- /dev/null +++ b/src/adaptors/wefi/index.js @@ -0,0 +1,279 @@ +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { comptrollerAbi, ercDelegator } = require('./abi'); + +const GET_ALL_MARKETS = 'getAllMarkets'; +const REWARD_SPEED = 'compSupplySpeeds'; +const REWARD_SPEED_BORROW = 'compBorrowSpeeds'; +const SUPPLY_RATE = 'supplyRatePerBlock'; +const BORROW_RATE = 'borrowRatePerBlock'; +const TOTAL_BORROWS = 'totalBorrows'; +const GET_CASH = 'getCash'; +const UNDERLYING = 'underlying'; +const PROJECT_NAME = 'wefi'; + +const markets = [ + { + chain: 'xdc', + comptrollerAddress: '0x301C76e7b60e9824E32991B8F29e1c4a03B4F65b', + blocksPerDay: 43200, + nativeToken: { + decimals: 18, + symbol: 'WXDC', + address: '0x557016277F50f4964569fd6d69813D4C7078D727'.toLowerCase(), + }, + protocolToken: { + decimals: 18, + symbol: 'XDC', + address: '0x49d3f7543335cf38Fa10889CCFF10207e22110B5'.toLowerCase(), + }, + }, + { + chain: 'linea', + comptrollerAddress: '0x301C76e7b60e9824E32991B8F29e1c4a03B4F65b', + blocksPerDay: 14400, + nativeToken: { + decimals: 18, + symbol: 'WETH', + address: '0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f'.toLowerCase(), + }, + protocolToken: { + decimals: 18, + symbol: 'WEFI', + address: '0x60892e742d91d16Be2cB0ffE847e85445989e30B'.toLowerCase(), + }, + }, + { + chain: 'polygon', + comptrollerAddress: '0x1eDf64B621F17dc45c82a65E1312E8df988A94D3', + blocksPerDay: 37565, + nativeToken: { + decimals: 18, + symbol: 'WMATIC', + address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270'.toLowerCase(), + }, + protocolToken: { + decimals: 18, + symbol: 'WEFI', + address: '0xfFA188493C15DfAf2C206c97D8633377847b6a52'.toLowerCase(), + }, + }, +]; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return pricesByAddress; +}; + +const calculateApy = (ratePerTimestamps, pool) => { + const blocksPerDay = pool.blocksPerDay; + const daysPerYear = 365; + + return ( + (Math.pow(ratePerTimestamps * blocksPerDay + 1, daysPerYear) - 1) * 100 + ); +}; + +const getRewards = async (markets, rewardMethod, pool) => { + return ( + await sdk.api.abi.multiCall({ + chain: pool.chain, + calls: markets.map((market) => ({ + target: pool.comptrollerAddress, + params: [market], + })), + abi: comptrollerAbi.find(({ name }) => name === rewardMethod), + }) + ).output.map(({ output }) => output); +}; + +const multiCallMarkets = async (markets, method, abi, pool) => { + return ( + await sdk.api.abi.multiCall({ + chain: pool.chain, + calls: markets.map((market) => ({ target: market })), + abi: abi.find(({ name }) => name === method), + }) + ).output.map(({ output }) => output); +}; + +const main = async (pool) => { + const allMarketsRes = ( + await sdk.api.abi.call({ + target: pool.comptrollerAddress, + chain: pool.chain, + abi: comptrollerAbi.find(({ name }) => name === GET_ALL_MARKETS), + }) + ).output; + const allMarkets = Object.values(allMarketsRes); + + const markets = ( + await sdk.api.abi.multiCall({ + chain: pool.chain, + abi: comptrollerAbi.find((n) => n.name === 'markets'), + calls: allMarkets.map((m) => ({ + target: pool.comptrollerAddress, + params: [m], + })), + }) + ).output.map((o) => o.output); + + const rewardSpeed = await getRewards(allMarkets, REWARD_SPEED, pool); + const rewardSpeedBorrow = await getRewards( + allMarkets, + REWARD_SPEED_BORROW, + pool + ); + const isPaused = await getRewards(allMarkets, 'mintGuardianPaused', pool); + const supplyRewards = await multiCallMarkets( + allMarkets, + SUPPLY_RATE, + ercDelegator, + pool + ); + + const borrowRewards = await multiCallMarkets( + allMarkets, + BORROW_RATE, + ercDelegator, + pool + ); + + const marketsCash = await multiCallMarkets( + allMarkets, + GET_CASH, + ercDelegator, + pool + ); + const totalBorrows = await multiCallMarkets( + allMarkets, + TOTAL_BORROWS, + ercDelegator, + pool + ); + + const underlyingTokens = await multiCallMarkets( + allMarkets, + UNDERLYING, + ercDelegator, + pool + ); + + const underlyingSymbols = await multiCallMarkets( + underlyingTokens, + 'symbol', + ercDelegator, + pool + ); + + const underlyingDecimals = await multiCallMarkets( + underlyingTokens, + 'decimals', + ercDelegator, + pool + ); + + const prices = await getPrices( + underlyingTokens + .concat([pool.nativeToken.address]) + .map((token) => `${pool.chain}:` + token) + ); + + if (pool.chain === 'linea') { + const wefiPrice = await getPrices([ + 'polygon:0xfFA188493C15DfAf2C206c97D8633377847b6a52', + ]); + prices['0x60892e742d91d16be2cb0ffe847e85445989e30b'] = + wefiPrice['0xffa188493c15dfaf2c206c97d8633377847b6a52']; + } + const pools = allMarkets.map((market, i) => { + const token = underlyingTokens[i] || pool.nativeToken.address; + const symbol = underlyingSymbols[i] || pool.nativeToken.symbol; + + const decimals = Number(underlyingDecimals[i]) || pool.nativeToken.decimals; + let price = prices[token.toLowerCase()]; + if (price === undefined) + price = symbol.toLowerCase().includes('usd') ? 1 : 0; + const totalSupplyUsd = + ((Number(marketsCash[i]) + Number(totalBorrows[i])) / 10 ** decimals) * + price; + const tvlUsd = (marketsCash[i] / 10 ** decimals) * price; + const totalBorrowUsd = (Number(totalBorrows[i]) / 10 ** decimals) * price; + const apyBase = calculateApy(supplyRewards[i] / 10 ** 18, pool); + const apyBaseBorrow = calculateApy(borrowRewards[i] / 10 ** 18, pool); + + const calcRewardApy = (rewards, denom, pool) => { + if (denom === 0) return 0; + return ( + (((rewards[i] / 10 ** pool.protocolToken.decimals) * + pool.blocksPerDay * + 365 * + prices[pool.protocolToken.address]) / + denom) * + 100 + ); + }; + + const apyReward = calcRewardApy(rewardSpeed, totalSupplyUsd, pool); + const apyRewardBorrow = calcRewardApy( + rewardSpeedBorrow, + totalBorrowUsd, + pool + ); + + let poolReturned = { + pool: `${market.toLowerCase()}-${pool.chain}`, + chain: utils.formatChain(pool.chain), + project: PROJECT_NAME, + symbol, + tvlUsd, + apyBase, + apyReward: pool.chain === 'polygon' ? 0 : apyReward, + underlyingTokens: [token], + rewardTokens: + pool.chain !== 'polygon' + ? [apyReward ? pool.protocolToken.address : null].filter(Boolean) + : [], + }; + if (isPaused[i] === false) { + poolReturned = { + ...poolReturned, + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow, + apyRewardBorrow: pool.chain === 'polygon' ? 0 : apyRewardBorrow, + ltv: Number(markets[i].collateralFactorMantissa) / 1e18, + }; + } + return poolReturned; + }); + + return pools.filter((p) => p.totalBorrowUsd !== 0 || p.apyReward !== 0); +}; + +const apy = async () => { + const pools = (await Promise.all(markets.map((p) => main(p)))).flat(); + return pools; +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://www.beta.app.wefi.xyz/', +}; diff --git a/src/adaptors/whaleswap/abis.js b/src/adaptors/whaleswap/abis.js new file mode 100644 index 0000000000..6cda08086f --- /dev/null +++ b/src/adaptors/whaleswap/abis.js @@ -0,0 +1,1381 @@ +module.exports = { + podMasterABI: [ + { + "inputs": [ + { + "internalType": "contract PodToken", + "name": "_POD", + "type": "address" + }, + { + "internalType": "address", + "name": "_devAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "name": "AddPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "boostContract", + "type": "address" + } + ], + "name": "UpdateBoostContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldMultiplier", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "UpdateBoostMultiplier", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "podPerBlock", + "type": "uint256" + } + ], + "name": "UpdatePodPerBlock", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "regularFarmRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "specialFarmRate", + "type": "uint256" + } + ], + "name": "UpdatePodRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accPodPerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isValid", + "type": "bool" + } + ], + "name": "UpdateWhiteList", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "ACC_POD_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BOOST_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BOOST_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POD", + "outputs": [ + { + "internalType": "contract PodToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POD_PER_BLOCK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POD_RATE_TOTAL_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isRegular", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "boostContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "getBoostMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingPod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_isRegular", + "type": "bool" + } + ], + "name": "podPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "podRateToRegularFarm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "podRateToSpecialFarm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "accPodPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostedShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "pools", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalRegularAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSpecialAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newBoostContract", + "type": "address" + } + ], + "name": "updateBoostContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newMultiplier", + "type": "uint256" + } + ], + "name": "updateBoostMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + } + ], + "name": "updateDevAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_podPerBlock", + "type": "uint256" + } + ], + "name": "updatePodPerBlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_regularFarmRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_specialFarmRate", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "updatePodRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "accPodPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBoostedShare", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isRegular", + "type": "bool" + } + ], + "internalType": "struct PodMaster.PoolInfo", + "name": "pool", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isValid", + "type": "bool" + } + ], + "name": "updateWhiteList", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "boostMultiplier", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whiteList", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + lpTokenABI: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/whaleswap/index.js b/src/adaptors/whaleswap/index.js new file mode 100644 index 0000000000..98b409507e --- /dev/null +++ b/src/adaptors/whaleswap/index.js @@ -0,0 +1,189 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const { podMasterABI, lpTokenABI } = require('./abis'); +const utils = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const RPC_URL = 'https://bsc-dataseed1.binance.org/'; +const API_URL = sdk.graph.modifyEndpoint( + 'HtdMsZ5CvuaEntqZQybWg5Tw55Kx3FRrius6p7Jhc2XX' +); +const BACKEND_URL = 'https://api.whaleswap.finance'; +const PODMASTER_ADDRESS = '0xdEe627eaaB378ec57ECfB94b389B718ef3687c0D'; + +const web3 = new Web3(RPC_URL); + +const pairQuery = gql` + query pairQuery($id: ID!) { + pair(id: $id) { + name + id + token0 { + id + decimals + } + token1 { + id + decimals + } + } + } +`; + +const priceQuery = gql` + query tokenQuery($id: ID!) { + token(id: $id) { + derivedUSD + } + } +`; + +const getPairInfo = (pair) => { + const pairInfo = request(API_URL, pairQuery, { id: pair.toLowerCase() }); + + return pairInfo; +}; + +const getApy = async (chainId, pid) => { + const apyResult = await fetchURL( + `${BACKEND_URL}/${chainId}/whaleswap/apr/${pid}` + ); + return apyResult.data; +}; + +const calculateReservesUSD = ( + pairName, + reserves, + reservesRatio, + bnbPrice, + podPrice, + ethPrice, + token0decimals, + token1decimals +) => { + const [token0, token1] = pairName.split('-'); + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1decimals)); + + if (token0.includes('USD')) return reserve0.times(2); + if (token0.includes('BNB')) return reserve0.times(bnbPrice).times(2); + if (token0.includes('POD')) return reserve0.times(podPrice).times(2); + if (token0.includes('ETH')) return reserve0.times(ethPrice).times(2); + if (token1.includes('USD')) return reserve1.times(2); + if (token1.includes('BNB')) return reserve1.times(bnbPrice).times(2); + if (token1.includes('POD')) return reserve1.times(podPrice).times(2); + if (token1.includes('ETH')) return reserve1.times(ethPrice).times(2); +}; + +const getBaseTokensPrice = async () => { + const tokens = ['binancecoin', 'ethereum'] + .map((t) => `coingecko:${t}`) + .join(','); + const { coins: prices } = await utils.getData( + `https://coins.llama.fi/prices/current/${tokens}` + ); + + const podPriceResult = await request(API_URL, priceQuery, { + id: '0xdded222297b3d08dafdac8f65eeb799b2674c78f', + }); + + const podPrice = podPriceResult.token.derivedUSD; + const ethPrice = prices['coingecko:ethereum'].price; + const bnbPrice = prices['coingecko:binancecoin'].price; + + return { podPrice, ethPrice, bnbPrice }; +}; + +const main = async () => { + const { podPrice, ethPrice, bnbPrice } = await getBaseTokensPrice(); + const podMaster = new web3.eth.Contract(podMasterABI, PODMASTER_ADDRESS); + + const poolsCount = await podMaster.methods.poolLength().call(); + + const [poolsRes, lpTokensRes] = await Promise.all( + ['poolInfo', 'lpToken'].map((method) => + sdk.api.abi.multiCall({ + abi: podMasterABI.filter(({ name }) => name === method)[0], + calls: [...Array(Number(poolsCount - 1)).keys()].map((i) => ({ + target: PODMASTER_ADDRESS, + params: i, + })), + chain: 'bsc', + }) + ) + ); + const poolsInfo = poolsRes.output.map((res) => res.output); + const lpTokens = lpTokensRes.output.map((res) => res.output); + + const [reservesRes, supplyRes, podMasterBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [PODMASTER_ADDRESS] : null, + })), + chain: 'bsc', + }) + ) + ); + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const podMasterBalData = podMasterBalancesRes.output.map((res) => res.output); + + const pools = await Promise.all( + poolsInfo.map(async (_, i) => { + // the early pools are deprecated or the staking pool (pid 0) + if (i < 45) return; + const apy = await getApy(56, i); + return getPairInfo(lpTokens[i]).then(({ pair: pairInfo }) => { + const reserves = reservesData[i]; + + const supply = supplyData[i]; + const podMasterBalance = podMasterBalData[i]; + + const reserveUSD = calculateReservesUSD( + pairInfo.name, + reserves, + podMasterBalance / supply, + bnbPrice, + podPrice, + ethPrice, + pairInfo.token0.decimals, + pairInfo.token1.decimals + ) + .div(1e18) + .toString(); + + const pool = { + pool: pairInfo.id, + chain: utils.formatChain('binance'), + project: 'whaleswap', + symbol: pairInfo.name, + tvlUsd: Number(reserveUSD), + apyBase: apy.swapFeeApr, + apyReward: apy.stakingApr, + rewardTokens: ['0xDDed222297B3d08DAFDAc8f65eeB799B2674C78F'], + underlyingTokens: [pairInfo.token0.id, pairInfo.token1.id], + }; + return pool; + }); + }) + ); + + // rmv null elements + return pools.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://whaleswap.finance/farm?chain=bsc_mainnet', +}; diff --git a/src/adaptors/wild-base/index.js b/src/adaptors/wild-base/index.js new file mode 100644 index 0000000000..3125b47074 --- /dev/null +++ b/src/adaptors/wild-base/index.js @@ -0,0 +1,366 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const masterchefAbi = require('./masterchef'); +const poolAbi = require('./poolAbi'); +const axios = require('axios'); +const BigNumber = require('bignumber.js'); + +const masterchef = '0x3eAB0C9716b0aA98CdC4c3ae317d69dE301ef247'; +const WILDx = '0xbCDa0bD6Cd83558DFb0EeC9153eD9C9cfa87782E'; +const WETH = '0x4200000000000000000000000000000000000006'; + +const utils = require('../utils'); + +const getPoolDetails = async (block, poolInfo, chainString) => { + const poolDetails = []; + + // console.log(poolInfo); + for (let i = 0; i < poolInfo.length; i++) { + // SKIP LP OF WILDx STANDALONE + if (poolInfo[i].lpToken != '0xbCDa0bD6Cd83558DFb0EeC9153eD9C9cfa87782E') { + const token0Id = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'token0'), + chain: chainString, + }) + ).output; + const token0Symbol = ( + await sdk.api.abi.call({ + target: token0Id, + abi: poolAbi.find((m) => m.name === 'symbol'), + chain: chainString, + }) + ).output; + const token0Decimals = ( + await sdk.api.abi.call({ + target: token0Id, + abi: poolAbi.find((m) => m.name === 'decimals'), + chain: chainString, + }) + ).output; + const token1Id = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'token1'), + chain: chainString, + }) + ).output; + const token1Symbol = ( + await sdk.api.abi.call({ + target: token1Id, + abi: poolAbi.find((m) => m.name === 'symbol'), + chain: chainString, + }) + ).output; + const token1Decimals = ( + await sdk.api.abi.call({ + target: token1Id, + abi: poolAbi.find((m) => m.name === 'decimals'), + chain: chainString, + }) + ).output; + + try { + const reserves = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'getReserves'), + block: block, + chain: chainString, + }) + ).output; + + const lpDecimals = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'decimals'), + block: block, + chain: chainString, + }) + ).output; + + const totalSupply = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'totalSupply'), + block: block, + chain: chainString, + }) + ).output; + + poolDetails.push({ + id: poolInfo[i].lpToken, + reserve0: reserves._reserve0 / (1 * 10 ** token0Decimals), + reserve1: reserves._reserve1 / (1 * 10 ** token1Decimals), + totalSupply: totalSupply, + volumeUSD: 0, + token0: { + symbol: token0Symbol, + id: token0Id, + }, + token1: { + symbol: token1Symbol, + id: token1Id, + }, + }); + } catch (e) { + poolDetails.push({ + id: poolInfo[i].lpToken, + reserve0: 0, + reserve1: 0, + totalSupply: 0, + volumeUSD: 0, + token0: { + symbol: token0Symbol, + id: token0Id, + }, + token1: { + symbol: token1Symbol, + id: token1Id, + }, + }); + } + } else { + try { + const lpDecimals = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'decimals'), + block: block, + chain: chainString, + }) + ).output; + + const totalSupply = ( + await sdk.api.abi.call({ + target: poolInfo[i].lpToken, + abi: poolAbi.find((m) => m.name === 'totalSupply'), + block: block, + chain: chainString, + }) + ).output; + + const tokenId = poolInfo[i].lpToken; + const tokenSymbol = 'WILDx'; + const tokenDecimals = 18; + + poolDetails.push({ + id: poolInfo[i].lpToken, + reserve0: 0, + reserve1: 0, + totalSupply: totalSupply, + volumeUSD: 0, + token0: { + symbol: tokenSymbol, + id: tokenId, + }, + token1: { + symbol: tokenSymbol, + id: tokenId, + }, + }); + } catch (e) { + poolDetails.push({ + id: poolInfo[i].lpToken, + reserve0: 0, + reserve1: 0, + totalSupply: 0, + volumeUSD: 0, + token0: { + symbol: token0Symbol, + id: token0Id, + }, + token1: { + symbol: token1Symbol, + id: token1Id, + }, + }); + } + } + } + + return poolDetails; +}; + +const topLv = async (chainString, version, timestamp) => { + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolLength'), + chain: chainString, + }) + ).output; + + let poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'poolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const exclude = [ + '0x4200000000000000000000000000000000000006', + '0x79474223AEdD0339780baCcE75aBDa0BE84dcBF9', + ]; + + poolInfo = poolInfo.filter( + (obj, index, self) => + index === self.findIndex((o) => o.lpToken === obj.lpToken) && + !exclude.includes(obj.lpToken) + ); + + const WILDxTotalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPoint'), + chain: chainString, + }) + ).output; + const WILDxPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'wildxPerBlock'), + chain: chainString, + }) + ).output / 1e18; + + const wethPriceKey = `base:${WETH}`; + const wethPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${wethPriceKey}`) + ).data.coins[wethPriceKey]?.price; + + WILDxPrice = ( + await axios.get(`https://api.dexscreener.com/latest/dex/tokens/${WILDx}`) + ).data.pairs[0]?.priceUsd; + + const WILDxPerYearUsd = WILDxPerSec * 86400 * 365 * WILDxPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, []); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [], + 604800 + ); + + // pull data + let dataNow = await getPoolDetails(block, poolInfo, chainString); + + // pull data 24h offest + let dataPrior = await getPoolDetails(blockPrior, poolInfo, chainString); + + // pull data 7d offest + let dataPrior7d = await getPoolDetails(blockPrior7d, poolInfo, chainString); + + const dataNowOriginal = dataNow.map((el) => JSON.parse(JSON.stringify(el))); + const dataNowCopy = dataNow.map((el) => JSON.parse(JSON.stringify(el))); + + dataNowCopy.forEach((pool) => { + if (pool.token0.id == '0xbCDa0bD6Cd83558DFb0EeC9153eD9C9cfa87782E') { + pool.token0.id = pool.token1.id; + pool.token0.symbol = pool.token1.symbol; + pool.reserve0 = pool.reserve1; + } else if (pool.token1.id == '0xbCDa0bD6Cd83558DFb0EeC9153eD9C9cfa87782E') { + pool.token1.id = pool.token0.id; + pool.token1.symbol = pool.token0.symbol; + pool.reserve1 = pool.reserve0; + } + }); + + // calculate tvl + dataNow = await utils.tvl(dataNowCopy, chainString); + + const dataNowUpdated = dataNowOriginal.map((obj1) => { + const isWILDxStake = obj1.id == WILDx; + const obj2 = dataNow.find((obj2) => obj2.id === obj1.id); + if (obj2) { + return { + ...obj1, + totalValueLockedUSD: isWILDxStake + ? (poolInfo[0].totalLp / 1e18) * WILDxPrice + : obj2.totalValueLockedUSD, + price0: isWILDxStake ? WILDxPrice : obj2.price0, + price1: isWILDxStake ? WILDxPrice : obj2.price1, + }; + } + return obj1; + }); + + console.log('dataNowUpdated', dataNowUpdated); + + // calculate apy + dataNow = dataNowUpdated.map((el) => + utils.apy(el, dataPrior, dataPrior7d, version) + ); + + dataNow = dataNow.map((p) => { + const isWILDxStake = p.id == WILDx; + const symbol = isWILDxStake + ? p.token0.symbol + : utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + const underlyingTokens = [p.token0.id]; + const token0 = underlyingTokens === undefined ? '' : underlyingTokens[0]; + const token1 = underlyingTokens === undefined ? '' : underlyingTokens[1]; + const chain = chainString; + const url = isWILDxStake + ? `https://pancakeswap.finance/swap` + : `https://pancakeswap.finance/add/${token0}/${token1}`; + + const WILDxAllocPoint = poolInfo.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.allocPoint; + + console.log(symbol, WILDxAllocPoint); + + let totalDeposit = poolInfo.find( + (pid) => pid.lpToken.toLowerCase() === p.id?.toLowerCase() + )?.totalDeposit; + totalDeposit = new BigNumber(totalDeposit) + .dividedBy(new BigNumber(10).pow(18)) + .toFixed(18); + const ratio = totalDeposit / p.totalSupply || 1; + + const WILDxBaseApy = + (((WILDxAllocPoint / WILDxTotalAllocPoint) * WILDxPerYearUsd) / + (p.totalValueLockedUSD * ratio)) * + 100; // deducted by fee as other aggeregator and app shows + + const apyReward = 0; + + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'wild-base', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: WILDxBaseApy || 0, + apyBase7d: 0, + apyReward, + rewardTokens: apyReward > 0 || isWILDxStake ? [WILDx] : [], + underlyingTokens, + url, + volumeUsd1d: p?.volumeUSD1d || 0, + volumeUsd7d: p?.volumeUSD7d || 0, + }; + }); + + return dataNow; +}; + +const main = async (timestamp = Date.now() / 1000) => { + let data = await topLv('base', 'v3', timestamp); + + return data.filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: false, + apy: main, +}; diff --git a/src/adaptors/wild-base/masterchef.js b/src/adaptors/wild-base/masterchef.js new file mode 100644 index 0000000000..b7bfcac94f --- /dev/null +++ b/src/adaptors/wild-base/masterchef.js @@ -0,0 +1,634 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract WILDX", + "name": "_wildx", + "type": "address" + }, + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeAddress1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_wildxPerBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "BONUS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isCompound", + "type": "bool" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_devaddr", + "type": "address" + } + ], + "name": "dev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "devaddr", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_to", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + }, + { + "internalType": "bool", + "name": "_isCompound", + "type": "bool" + } + ], + "name": "harvestMany", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingWildx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardBlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accWildxPerShare", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "depositFeeBP", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_depositFeeBP", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_startBlock", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_withUpdate", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeAddress1", + "type": "address" + } + ], + "name": "setFeeAddress1", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_wildx", + "type": "address" + } + ], + "name": "setWildX", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newPid", + "type": "uint256" + } + ], + "name": "setWildXPoolPid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_wildxPerBlock", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wildPoolPId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wildx", + "outputs": [ + { + "internalType": "contract WILDX", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wildxPerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]; diff --git a/src/adaptors/wild-base/poolAbi.js b/src/adaptors/wild-base/poolAbi.js new file mode 100644 index 0000000000..777420c721 --- /dev/null +++ b/src/adaptors/wild-base/poolAbi.js @@ -0,0 +1,435 @@ +module.exports = [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [{ internalType: 'uint256', name: 'liquidity', type: 'uint256' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/src/adaptors/wildcat-protocol/abi.js b/src/adaptors/wildcat-protocol/abi.js new file mode 100644 index 0000000000..7e7cf2fd15 --- /dev/null +++ b/src/adaptors/wildcat-protocol/abi.js @@ -0,0 +1,1150 @@ +module.exports = [ + { inputs: [], name: 'AccountBlocked', type: 'error' }, + { inputs: [], name: 'AccountNotBlocked', type: 'error' }, + { inputs: [], name: 'BadLaunchCode', type: 'error' }, + { inputs: [], name: 'BorrowAmountTooHigh', type: 'error' }, + { inputs: [], name: 'BorrowFromClosedMarket', type: 'error' }, + { inputs: [], name: 'BorrowWhileSanctioned', type: 'error' }, + { inputs: [], name: 'CloseMarketWithUnpaidWithdrawals', type: 'error' }, + { inputs: [], name: 'DepositToClosedMarket', type: 'error' }, + { inputs: [], name: 'FIFOQueueOutOfBounds', type: 'error' }, + { inputs: [], name: 'InsufficientReservesForFeeWithdrawal', type: 'error' }, + { + inputs: [], + name: 'InsufficientReservesForNewLiquidityRatio', + type: 'error', + }, + { + inputs: [], + name: 'InsufficientReservesForOldLiquidityRatio', + type: 'error', + }, + { inputs: [], name: 'InvalidArrayLength', type: 'error' }, + { inputs: [], name: 'MaxSupplyExceeded', type: 'error' }, + { inputs: [], name: 'NewMaxSupplyTooLow', type: 'error' }, + { inputs: [], name: 'NoReentrantCalls', type: 'error' }, + { inputs: [], name: 'NotApprovedBorrower', type: 'error' }, + { inputs: [], name: 'NotApprovedLender', type: 'error' }, + { inputs: [], name: 'NotController', type: 'error' }, + { inputs: [], name: 'NotReversedOrStunning', type: 'error' }, + { inputs: [], name: 'NullBurnAmount', type: 'error' }, + { inputs: [], name: 'NullFeeAmount', type: 'error' }, + { inputs: [], name: 'NullMintAmount', type: 'error' }, + { inputs: [], name: 'NullRepayAmount', type: 'error' }, + { inputs: [], name: 'NullTransferAmount', type: 'error' }, + { inputs: [], name: 'NullWithdrawalAmount', type: 'error' }, + { inputs: [], name: 'RepayToClosedMarket', type: 'error' }, + { inputs: [], name: 'SphereXOperatorRequired', type: 'error' }, + { inputs: [], name: 'WithdrawalBatchNotExpired', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'annualInterestBipsUpdated', + type: 'uint256', + }, + ], + name: 'AnnualInterestBipsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'enum AuthRole', + name: 'role', + type: 'uint8', + }, + ], + name: 'AuthorizationStatusUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'assetAmount', + type: 'uint256', + }, + ], + name: 'Borrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldEngineAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newEngineAddress', + type: 'address', + }, + ], + name: 'ChangedSpherexEngineAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldSphereXAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newSphereXAdmin', + type: 'address', + }, + ], + name: 'ChangedSpherexOperator', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'assetAmount', + type: 'uint256', + }, + ], + name: 'DebtRepaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'assetAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaledAmount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'FeesCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'fromTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'toTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaleFactor', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'baseInterestRay', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'delinquencyFeeRay', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'protocolFees', + type: 'uint256', + }, + ], + name: 'InterestAndFeesAccrued', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'timestamp', + type: 'uint256', + }, + ], + name: 'MarketClosed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'assets', + type: 'uint256', + }, + ], + name: 'MaxTotalSupplyUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'reserveRatioBipsUpdated', + type: 'uint256', + }, + ], + name: 'ReserveRatioBipsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'escrow', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'SanctionedAccountAssetsSentToEscrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'escrow', + type: 'address', + }, + { + indexed: false, + internalType: 'uint32', + name: 'expiry', + type: 'uint32', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'SanctionedAccountWithdrawalSentToEscrow', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'scaleFactor', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'isDelinquent', + type: 'bool', + }, + ], + name: 'StateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + ], + name: 'WithdrawalBatchClosed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + ], + name: 'WithdrawalBatchCreated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaledTotalAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaledAmountBurned', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'normalizedAmountPaid', + type: 'uint256', + }, + ], + name: 'WithdrawalBatchExpired', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaledAmountBurned', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'normalizedAmountPaid', + type: 'uint256', + }, + ], + name: 'WithdrawalBatchPayment', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'normalizedAmount', + type: 'uint256', + }, + ], + name: 'WithdrawalExecuted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'expiry', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'scaledAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'normalizedAmount', + type: 'uint256', + }, + ], + name: 'WithdrawalQueued', + type: 'event', + }, + { + inputs: [], + name: 'accruedProtocolFees', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'annualInterestBips', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'archController', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'borrow', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'borrowableAssets', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'borrower', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newSphereXEngine', type: 'address' }, + ], + name: 'changeSphereXEngine', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'closeMarket', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'collectFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'controller', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'coverageLiquidity', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'currentState', + outputs: [ + { + components: [ + { internalType: 'bool', name: 'isClosed', type: 'bool' }, + { internalType: 'uint128', name: 'maxTotalSupply', type: 'uint128' }, + { + internalType: 'uint128', + name: 'accruedProtocolFees', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'normalizedUnclaimedWithdrawals', + type: 'uint128', + }, + { + internalType: 'uint104', + name: 'scaledTotalSupply', + type: 'uint104', + }, + { + internalType: 'uint104', + name: 'scaledPendingWithdrawals', + type: 'uint104', + }, + { + internalType: 'uint32', + name: 'pendingWithdrawalExpiry', + type: 'uint32', + }, + { internalType: 'bool', name: 'isDelinquent', type: 'bool' }, + { internalType: 'uint32', name: 'timeDelinquent', type: 'uint32' }, + { + internalType: 'uint16', + name: 'annualInterestBips', + type: 'uint16', + }, + { internalType: 'uint16', name: 'reserveRatioBips', type: 'uint16' }, + { internalType: 'uint112', name: 'scaleFactor', type: 'uint112' }, + { + internalType: 'uint32', + name: 'lastInterestAccruedTimestamp', + type: 'uint32', + }, + ], + internalType: 'struct MarketState', + name: 'state', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'delinquencyFeeBips', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'delinquencyGracePeriod', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'delinquentDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'depositUpTo', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'accountAddress', type: 'address' }, + { internalType: 'uint32', name: 'expiry', type: 'uint32' }, + ], + name: 'executeWithdrawal', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address[]', + name: 'accountAddresses', + type: 'address[]', + }, + { internalType: 'uint32[]', name: 'expiries', type: 'uint32[]' }, + ], + name: 'executeWithdrawals', + outputs: [ + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'feeRecipient', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getAccountRole', + outputs: [{ internalType: 'enum AuthRole', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'accountAddress', type: 'address' }, + { internalType: 'uint32', name: 'expiry', type: 'uint32' }, + ], + name: 'getAccountWithdrawalStatus', + outputs: [ + { + components: [ + { internalType: 'uint104', name: 'scaledAmount', type: 'uint104' }, + { + internalType: 'uint128', + name: 'normalizedAmountWithdrawn', + type: 'uint128', + }, + ], + internalType: 'struct AccountWithdrawalStatus', + name: 'status', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'accountAddress', type: 'address' }, + { internalType: 'uint32', name: 'expiry', type: 'uint32' }, + ], + name: 'getAvailableWithdrawalAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getUnpaidBatchExpiries', + outputs: [{ internalType: 'uint32[]', name: '', type: 'uint32[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint32', name: 'expiry', type: 'uint32' }], + name: 'getWithdrawalBatch', + outputs: [ + { + components: [ + { + internalType: 'uint104', + name: 'scaledTotalAmount', + type: 'uint104', + }, + { + internalType: 'uint104', + name: 'scaledAmountBurned', + type: 'uint104', + }, + { + internalType: 'uint128', + name: 'normalizedAmountPaid', + type: 'uint128', + }, + ], + internalType: 'struct WithdrawalBatch', + name: 'batch', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isClosed', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maxTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maximumDeposit', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'accountAddress', type: 'address' }, + ], + name: 'nukeFromOrbit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'outstandingDebt', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'previousState', + outputs: [ + { + components: [ + { internalType: 'bool', name: 'isClosed', type: 'bool' }, + { internalType: 'uint128', name: 'maxTotalSupply', type: 'uint128' }, + { + internalType: 'uint128', + name: 'accruedProtocolFees', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'normalizedUnclaimedWithdrawals', + type: 'uint128', + }, + { + internalType: 'uint104', + name: 'scaledTotalSupply', + type: 'uint104', + }, + { + internalType: 'uint104', + name: 'scaledPendingWithdrawals', + type: 'uint104', + }, + { + internalType: 'uint32', + name: 'pendingWithdrawalExpiry', + type: 'uint32', + }, + { internalType: 'bool', name: 'isDelinquent', type: 'bool' }, + { internalType: 'uint32', name: 'timeDelinquent', type: 'uint32' }, + { + internalType: 'uint16', + name: 'annualInterestBips', + type: 'uint16', + }, + { internalType: 'uint16', name: 'reserveRatioBips', type: 'uint16' }, + { internalType: 'uint112', name: 'scaleFactor', type: 'uint112' }, + { + internalType: 'uint32', + name: 'lastInterestAccruedTimestamp', + type: 'uint32', + }, + ], + internalType: 'struct MarketState', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolFeeBips', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'queueWithdrawal', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'repay', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'repayAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'maxBatches', type: 'uint256' }, + ], + name: 'repayAndProcessUnpaidWithdrawalBatches', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'repayDelinquentDebt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'repayOutstandingDebt', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'reserveRatioBips', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'scaleFactor', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'scaledBalanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'scaledTotalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sentinel', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: '_annualInterestBips', type: 'uint16' }, + ], + name: 'setAnnualInterestBips', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_maxTotalSupply', type: 'uint256' }, + ], + name: 'setMaxTotalSupply', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint16', name: '_reserveRatioBips', type: 'uint16' }, + ], + name: 'setReserveRatioBips', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'sphereXEngine', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'sphereXOperator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'accountAddress', type: 'address' }, + ], + name: 'stunningReversal', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAssets', + outputs: [ + { internalType: 'uint256', name: '_totalAssets', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalDebts', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'accounts', type: 'address[]' }, + { internalType: 'bool', name: 'authorize', type: 'bool' }, + ], + name: 'updateAccountAuthorizations', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'updateState', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'version', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'withdrawableProtocolFees', + outputs: [{ internalType: 'uint128', name: '', type: 'uint128' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'withdrawalBatchDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/adaptors/wildcat-protocol/index.js b/src/adaptors/wildcat-protocol/index.js new file mode 100644 index 0000000000..4aee5f313d --- /dev/null +++ b/src/adaptors/wildcat-protocol/index.js @@ -0,0 +1,99 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const abi = require('./abi'); + +const archController = '0xfEB516d9D946dD487A9346F6fee11f40C6945eE4'; +const chain = 'ethereum'; + +const apy = async () => { + // all markets + const markets = ( + await sdk.api.abi.call({ + abi: 'address[]:getRegisteredMarkets', + target: archController, + }) + ).output; + + // --- market params + const annualInterestBips = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'annualInterestBips'), + }) + ).output.map((i) => i.output); + + const symbol = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: 'erc20:symbol', + }) + ).output.map((i) => i.output); + + const asset = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'asset'), + }) + ).output.map((i) => i.output); + + const isClosed = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'isClosed'), + }) + ).output.map((i) => i.output); + + const name = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'name'), + }) + ).output.map((i) => i.output); + + const maximumDeposit = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'maximumDeposit'), + }) + ).output.map((i) => i.output); + + const decimals = ( + await sdk.api.abi.multiCall({ + calls: markets.map((m) => ({ target: m })), + abi: abi.find((i) => i.name === 'decimals'), + }) + ).output.map((i) => i.output); + + const priceApiKeys = asset.map((i) => `${chain}:${i}`); + const prices = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceApiKeys}`) + ).data.coins; + + const pools = []; + for (let i = 0; i < markets.length; i++) { + const m = markets[i]; + + if (isClosed[i]) continue; + + pools.push({ + pool: m, + project: 'wildcat-protocol', + chain, + symbol: symbol[i], + apyBase: annualInterestBips[i] / 100, + tvlUsd: + (maximumDeposit[i] / 10 ** decimals[i]) * + prices[`${chain}:${asset[i]}`]?.price, + underlyingTokens: [asset[i]], + poolMeta: name[i], + url: `https://app.wildcat.finance/lender/market/${m.toLowerCase()}`, + }); + } + + return pools; +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/wing-finance/index.js b/src/adaptors/wing-finance/index.js new file mode 100644 index 0000000000..9a08878457 --- /dev/null +++ b/src/adaptors/wing-finance/index.js @@ -0,0 +1,66 @@ +const superagent = require('superagent'); +const { mapKeys, camelCase } = require('lodash'); + +const utils = require('../utils'); + +const API_URL = { + ontology: 'https://flashapi.wing.finance/api/v1/userflashpooloverview', + binance: 'https://ethapi.wing.finance/bsc/flash-pool/overview', + ontologyEvm: 'https://ethapi.wing.finance/ontevm/flash-pool/overview', + ethereum: 'https://ethapi.wing.finance/eth/flash-pool/overview', +}; + +const apy = async () => { + const data = await Promise.all( + Object.entries(API_URL).map(async ([chain, url]) => [ + chain, + (await superagent.post(url).send({ address: '' })).body.result, + ]) + ); + + const normalizedData = data.map(([chain, data]) => [ + chain, + chain === 'ontology' + ? data.UserFlashPoolOverview.AllMarket + : data.allMarket, + ]); + + const pools = normalizedData.map(([chain, chainPools]) => { + return chainPools + .map((pool) => mapKeys(pool, (v, k) => camelCase(k))) + .map((pool) => { + return { + pool: `${pool.name}-wing-finance-${chain}`, + chain: chain === 'ontologyEvm' ? 'ontology' : chain, + project: 'wing-finance', + symbol: pool.name, + tvlUsd: + Number(pool.totalSupplyDollar) - + Number(pool.totalValidBorrowDollar), + apyBase: Number(pool.supplyApy) * 100, + apyReward: + (Number(pool.annualSupplyWingDistributedDollar) / + Number(pool.totalSupplyDollar)) * + 100, + rewardTokens: ['0xDb0f18081b505A7DE20B18ac41856BCB4Ba86A1a'], + // borrow fields + totalSupplyUsd: Number(pool.totalSupplyDollar), + totalBorrowUsd: Number(pool.totalValidBorrowDollar), + apyBaseBorrow: Number(pool.borrowApy) * 100, + apyRewardBorrow: + (Number(pool.annualBorrowWingDistributedDollar) / + Number(pool.totalValidBorrowDollar)) * + 100, + ltv: Number(pool.collateralFactor), + }; + }); + }); + + return pools.flat(); +}; + +module.exports = { + timetravel: false, + apy, + url: 'https://flash.wing.finance/', +}; diff --git a/src/adaptors/wink/index.js b/src/adaptors/wink/index.js new file mode 100644 index 0000000000..f825399981 --- /dev/null +++ b/src/adaptors/wink/index.js @@ -0,0 +1,186 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const ethers = require('ethers'); +const { getProvider } = require('@defillama/sdk/build/general'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); + +const WINK_TOKEN_ADDRESS = '0x8c3441E7B9aA8A30a542DDE048dd067DE2802E9B' + +const USDW_TOKEN_ADDRESS = '0xab670FDfb0060BDC6508B84a309ff41b56CCAf3f' + +const LOCK_WINK_ADDRESS = '0x49C4EeC1d4fFFcdFF415E0757F01Cc50eeF5d4FD' +const LOCK_WINK_ABI = [{"inputs": [],"name": "rebaser","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"}] + +const LOCK_USDW_ADDRESS = '0x231fB0E6AD5d975151fC8d5b5C5EB164D265fE85' +const LOCK_USDW_ABI = [{"inputs": [{"internalType": "enum LockUSDW.LockPeriod","name": "","type": "uint8"}],"name": "lockAPY","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},] + +const S_USDW_ADDRESS = '0xfB379c1f5431E8065e987B36C9BDAF93cba18740' +const S_USDW_ABI = [{"inputs": [],"name": "ssr","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"}] + + +const chain = 'polygon'; +const provider = getProvider(chain); + +const YEAR = 365 * 24 * 60 * 60; +const REBASE_OBSERVATION_PERIOD = 60 * 60; + +const winkTokenInterface = new ethers.utils.Interface([ + 'event Transfer(address indexed from, address indexed to, uint256 value)', +]); + +async function getPrices(chain, addresses) { + const priceKeys = [...new Set(addresses)].map( + (address) => `${chain}:${address}` + ); + return ( + await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys + .join(',') + .toLowerCase()}` + ) + ).body.coins; +} + +const getRebaserTopic = async () => { + return ( + await sdk.api.abi.call({ + abi: LOCK_WINK_ABI.find((abi) => abi.name == 'rebaser'), + target: LOCK_WINK_ADDRESS, + chain, + }) + ).output.replace('0x', '0x000000000000000000000000'); +} + +const getLockWinkBalance = async () => { + return ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: WINK_TOKEN_ADDRESS, + params: [LOCK_WINK_ADDRESS], + chain, + }) + ).output +} + +const getLockWinkApy = async (fromBlock, toBlock, lockedAmount) => { + + const rebases = ( + await sdk.api2.util.getLogs({ + target: WINK_TOKEN_ADDRESS, + toBlock, + fromBlock, + keys: [], + topics: [ + winkTokenInterface.getEventTopic('Transfer'), + await getRebaserTopic() + ], + chain, + }) + ).output + + const rebaseAmounts = rebases.reduce((acc, rebase) => acc.plus(rebase.data), new BigNumber(0)) + + const annualRebased = rebaseAmounts.times(YEAR).div(REBASE_OBSERVATION_PERIOD) + + return annualRebased.times(100).div(lockedAmount).toNumber() +} + +const ssrToApy = (ssr) => { + return Math.round(100 * ((Number(ssr) / 10**27)**(YEAR) - 1) * 100) / 100; +} + +const getLockUsdwApy = async () => { + return ssrToApy(( + await sdk.api.abi.call({ + abi: LOCK_USDW_ABI.find((abi) => abi.name == 'lockAPY'), + target: LOCK_USDW_ADDRESS, + params: [0], + chain, + }) + ).output) +} + +const getLockUsdwBalance = async () => { + return ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: USDW_TOKEN_ADDRESS, + params: [LOCK_USDW_ADDRESS], + chain, + }) + ).output +} + +const getSusdwApy = async () => { + return ssrToApy(( + await sdk.api.abi.call({ + abi: S_USDW_ABI.find((abi) => abi.name == 'ssr'), + target: S_USDW_ADDRESS, + chain, + }) + ).output) +} + +const getSusdwBalance = async () => { + return ( + await sdk.api.abi.call({ + abi: 'erc20:balanceOf', + target: USDW_TOKEN_ADDRESS, + params: [S_USDW_ADDRESS], + chain, + }) + ).output +} + +const poolsFunction = async () => { + + const prices = await getPrices(chain, [WINK_TOKEN_ADDRESS, USDW_TOKEN_ADDRESS]); + + const usdwData = prices[`${chain}:${USDW_TOKEN_ADDRESS.toLowerCase()}`]; + const winkData = prices[`${chain}:${WINK_TOKEN_ADDRESS.toLowerCase()}`]; + + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + const pastTimestamp = currentBlock.timestamp - REBASE_OBSERVATION_PERIOD; + const [fromBlock] = await utils.getBlocksByTime([pastTimestamp], chain); + + const lockWinkBalance = await getLockWinkBalance() + const lockUsdwBalance = await getLockUsdwBalance() + const susdwBalance = await getSusdwBalance() + + return [{ + pool: LOCK_WINK_ADDRESS, + chain: utils.formatChain(chain), + project: 'wink', + symbol: 'LockWINK', + tvlUsd: new BigNumber(lockWinkBalance).times(winkData?.price).div(1e18).toNumber(), + apyReward: await getLockWinkApy(fromBlock, toBlock, lockWinkBalance), + rewardTokens: [WINK_TOKEN_ADDRESS], + poolMeta: '3 to 24 months lock' + }, { + pool: LOCK_USDW_ADDRESS, + chain: utils.formatChain(chain), + project: 'wink', + symbol: 'LockUSDW', + tvlUsd: new BigNumber(lockUsdwBalance).times(usdwData?.price).div(1e18).toNumber(), + apyReward: await getLockUsdwApy(), + rewardTokens: [USDW_TOKEN_ADDRESS], + poolMeta: '3 to 24 months lock' + }, { + pool: S_USDW_ADDRESS, + chain: utils.formatChain(chain), + project: 'wink', + symbol: 'sUSDW', + tvlUsd: new BigNumber(susdwBalance).times(usdwData?.price).div(1e18).toNumber(), + apyReward: await getSusdwApy(), + rewardTokens: [USDW_TOKEN_ADDRESS], + poolMeta: 'Liquid staking' + }] +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, // Main function, returns pools + url: 'https://wink.finance/', // Link to page with pools (Only required if you do not provide url's for each pool) +}; diff --git a/src/adaptors/wise-lending-v2/abi/AaveHubABI.json b/src/adaptors/wise-lending-v2/abi/AaveHubABI.json new file mode 100644 index 0000000000..49262073af --- /dev/null +++ b/src/adaptors/wise-lending-v2/abi/AaveHubABI.json @@ -0,0 +1,351 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { "internalType": "address", "name": "_aaveAddress", "type": "address" }, + { "internalType": "address", "name": "_lendingAddress", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AlreadySet", "type": "error" }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { "inputs": [], "name": "InvalidAction", "type": "error" }, + { "inputs": [], "name": "InvalidToken", "type": "error" }, + { "inputs": [], "name": "InvalidValue", "type": "error" }, + { "inputs": [], "name": "NoValue", "type": "error" }, + { "inputs": [], "name": "NotMaster", "type": "error" }, + { "inputs": [], "name": "NotProposed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsBorrowAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsDepositAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsPaybackAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsSolelyDepositAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsSolelyWithdrawAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "IsWithdrawAave", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { "indexed": false, "internalType": "address", "name": "aaveToken", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "SetAaveTokenAddress", + "type": "event" + }, + { + "inputs": [], + "name": "AAVE_ADDRESS", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POSITION_NFT", + "outputs": [{ "internalType": "contract IPositionNFTs", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH_ADDRESS", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_LENDING", + "outputs": [{ "internalType": "contract IWiseLending", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_SECURITY", + "outputs": [{ "internalType": "contract IWiseSecurity", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "aaveTokenAddress", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_borrowAmount", "type": "uint256" } + ], + "name": "borrowExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_borrowAmount", "type": "uint256" } + ], + "name": "borrowExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "depositExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositExactAmountETHMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmountMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_underlyingAsset", "type": "address" }], + "name": "getAavePoolAPY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_underlyingAsset", "type": "address" }], + "name": "getLendingRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_paybackAmount", "type": "uint256" } + ], + "name": "paybackExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "paybackExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "paybackExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_proposedOwner", "type": "address" }], + "name": "proposeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedMaster", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sendingProgressAaveHub", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "address", "name": "_aaveToken", "type": "address" } + ], + "name": "setAaveTokenAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address[]", "name": "_underlyingAssets", "type": "address[]" }, + { "internalType": "address[]", "name": "_aaveTokens", "type": "address[]" } + ], + "name": "setAaveTokenAddressBulk", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_securityAddress", "type": "address" }], + "name": "setWiseSecurity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "bool", "name": "_isAave", "type": "bool" } + ], + "name": "skimAave", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "withdrawExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "withdrawExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_underlyingAsset", "type": "address" }, + { "internalType": "uint256", "name": "_shareAmount", "type": "uint256" } + ], + "name": "withdrawExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_shareAmount", "type": "uint256" } + ], + "name": "withdrawExactSharesETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] \ No newline at end of file diff --git a/src/adaptors/wise-lending-v2/abi/wiseLendingABI.json b/src/adaptors/wise-lending-v2/abi/wiseLendingABI.json new file mode 100644 index 0000000000..8c3ea519a4 --- /dev/null +++ b/src/adaptors/wise-lending-v2/abi/wiseLendingABI.json @@ -0,0 +1,1413 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { + "internalType": "address", + "name": "_wiseOracleHubAddress", + "type": "address" + }, + { "internalType": "address", "name": "_nftContract", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "AmountTooSmall", "type": "error" }, + { "inputs": [], "name": "DeadOracle", "type": "error" }, + { "inputs": [], "name": "InvalidAction", "type": "error" }, + { "inputs": [], "name": "InvalidAddress", "type": "error" }, + { "inputs": [], "name": "InvalidCaller", "type": "error" }, + { "inputs": [], "name": "InvalidLiquidator", "type": "error" }, + { "inputs": [], "name": "LiquidatorIsInPowerFarm", "type": "error" }, + { "inputs": [], "name": "NoValue", "type": "error" }, + { "inputs": [], "name": "NotMaster", "type": "error" }, + { "inputs": [], "name": "NotPowerFarm", "type": "error" }, + { "inputs": [], "name": "NotProposed", "type": "error" }, + { "inputs": [], "name": "PositionLocked", "type": "error" }, + { "inputs": [], "name": "SendValueFailed", "type": "error" }, + { "inputs": [], "name": "TokenNotPresent", "type": "error" }, + { "inputs": [], "name": "TooManyTokens", "type": "error" }, + { "inputs": [], "name": "ValueIsZero", "type": "error" }, + { "inputs": [], "name": "ValueNotZero", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsBorrowed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsBorrowedOnBehalf", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalPayment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalPaymentShares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsReturned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsSolelyDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsSolelyWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "nftId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "FundsWithdrawnOnBehalf", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "proposer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "proposedMaster", + "type": "address" + } + ], + "name": "MasterProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousMaster", + "type": "address" + } + ], + "name": "RenouncedOwnership", + "type": "event" + }, + { + "inputs": [], + "name": "POSITION_NFT", + "outputs": [ + { + "internalType": "contract IPositionNFTs", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH_ADDRESS", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_ORACLE", + "outputs": [ + { + "internalType": "contract IWiseOracleHub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_SECURITY", + "outputs": [ + { + "internalType": "contract IWiseSecurity", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "algorithmData", + "outputs": [ + { "internalType": "bool", "name": "increasePole", "type": "bool" }, + { "internalType": "uint256", "name": "bestPole", "type": "uint256" }, + { "internalType": "uint256", "name": "maxValue", "type": "uint256" }, + { "internalType": "uint256", "name": "previousValue", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowOnBehalfExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowPoolData", + "outputs": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { + "internalType": "uint256", + "name": "pseudoTotalBorrowAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBorrowShares", + "type": "uint256" + }, + { "internalType": "uint256", "name": "borrowRate", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowRatesData", + "outputs": [ + { "internalType": "uint256", "name": "pole", "type": "uint256" }, + { "internalType": "uint256", "name": "deltaPole", "type": "uint256" }, + { "internalType": "uint256", "name": "minPole", "type": "uint256" }, + { "internalType": "uint256", "name": "maxPole", "type": "uint256" }, + { + "internalType": "uint256", + "name": "multiplicativeFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "bool", "name": "_maxSharePrice", "type": "bool" } + ], + "name": "calculateBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "bool", "name": "_maxSharePrice", "type": "bool" } + ], + "name": "calculateLendingShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "cashoutAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checkDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checkPositionLocked", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "collateralizeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_nftIdLiquidator", + "type": "uint256" + }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_paybackToken", "type": "address" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_paybackAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shareAmountToPay", + "type": "uint256" + } + ], + "name": "coreLiquidationIsolationPools", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "corePaybackFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { "internalType": "address", "name": "poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "poolMulFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolCollFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDepositAmount", + "type": "uint256" + } + ], + "internalType": "struct PoolManager.CreatePool", + "name": "_params", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "curvePool", + "type": "address" + }, + { + "internalType": "address", + "name": "curveMetaPool", + "type": "address" + }, + { + "internalType": "bytes", + "name": "swapBytesPool", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "swapBytesMeta", + "type": "bytes" + } + ], + "internalType": "struct CurveSwapStructData", + "name": "curveSecuritySwapsData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "curvePoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curvePoolTokenIndexTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexTo", + "type": "uint256" + } + ], + "internalType": "struct CurveSwapStructToken", + "name": "curveSecuritySwapsToken", + "type": "tuple" + } + ], + "internalType": "struct PoolManager.CurvePoolSettings", + "name": "_settings", + "type": "tuple" + } + ], + "name": "createCurvePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { "internalType": "address", "name": "poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "poolMulFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolCollFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxDepositAmount", + "type": "uint256" + } + ], + "internalType": "struct PoolManager.CreatePool", + "name": "_params", + "type": "tuple" + } + ], + "name": "createPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "depositExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositExactAmountETHMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmountMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_index", "type": "uint256" } + ], + "name": "getPositionBorrowTokenByIndex", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "getPositionBorrowTokenLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionLendingShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_index", "type": "uint256" } + ], + "name": "getPositionLendingTokenByIndex", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "getPositionLendingTokenLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPseudoTotalBorrowAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPseudoTotalPool", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPureCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getTimeStamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getTotalBareToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getTotalBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getTotalDepositShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getTotalPool", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "globalPoolData", + "outputs": [ + { "internalType": "uint256", "name": "totalPool", "type": "uint256" }, + { "internalType": "uint256", "name": "utilization", "type": "uint256" }, + { + "internalType": "uint256", + "name": "totalBareToken", + "type": "uint256" + }, + { "internalType": "uint256", "name": "poolFee", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "isUncollateralized", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "lendingPoolData", + "outputs": [ + { + "internalType": "uint256", + "name": "pseudoTotalPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDepositShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralFactor", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_nftIdLiquidator", + "type": "uint256" + }, + { "internalType": "address", "name": "_paybackToken", "type": "address" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_shareAmountToPay", + "type": "uint256" + } + ], + "name": "liquidatePartiallyFromTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDepositValueToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "paybackAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "paybackExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "paybackExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "paybackExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "positionBorrowTokenData", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "positionLendTokenData", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "positionLocked", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_proposedOwner", "type": "address" } + ], + "name": "proposeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedMaster", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "pureCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sendingProgress", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_poolMulFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_upperBoundMaxRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lowerBoundMaxRate", + "type": "uint256" + }, + { "internalType": "bool", "name": "_steppingDirection", "type": "bool" }, + { "internalType": "bool", "name": "_isFinal", "type": "bool" } + ], + "name": "setParamsLASA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setPoolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_collateralFactor", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maximumDeposit", + "type": "uint256" + } + ], + "name": "setPoolParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "bool", "name": "_registerState", "type": "bool" } + ], + "name": "setRegistrationIsolationPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_wiseSecurity", "type": "address" } + ], + "name": "setSecurity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_isolationPool", + "type": "address" + }, + { "internalType": "bool", "name": "_state", "type": "bool" } + ], + "name": "setVerifiedIsolationPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "solelyDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "solelyDepositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "solelyDepositETHMint", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "solelyDepositMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_withdrawAmount", + "type": "uint256" + } + ], + "name": "solelyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_withdrawAmount", + "type": "uint256" + } + ], + "name": "solelyWithdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "syncManually", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "timestampsPoolData", + "outputs": [ + { "internalType": "uint256", "name": "timeStamp", "type": "uint256" }, + { + "internalType": "uint256", + "name": "timeStampScaling", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "initialTimeStamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "unCollateralizeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userLendingData", + "outputs": [ + { "internalType": "bool", "name": "unCollateralized", "type": "bool" }, + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "verifiedIsolationPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_withdrawAmount", + "type": "uint256" + } + ], + "name": "withdrawExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawExactSharesETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "internalType": "uint256", + "name": "_withdrawAmount", + "type": "uint256" + } + ], + "name": "withdrawOnBehalfExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawOnBehalfExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } + ] diff --git a/src/adaptors/wise-lending-v2/abi/wiseSecurityABI.json b/src/adaptors/wise-lending-v2/abi/wiseSecurityABI.json new file mode 100644 index 0000000000..f31f08e21f --- /dev/null +++ b/src/adaptors/wise-lending-v2/abi/wiseSecurityABI.json @@ -0,0 +1,927 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { + "internalType": "address", + "name": "_wiseLendingAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_aaveHubAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "BaseRewardFarmTooHigh", "type": "error" }, + { "inputs": [], "name": "BaseRewardFarmTooLow", "type": "error" }, + { "inputs": [], "name": "BaseRewardTooHigh", "type": "error" }, + { "inputs": [], "name": "BaseRewardTooLow", "type": "error" }, + { "inputs": [], "name": "ChainlinkDead", "type": "error" }, + { "inputs": [], "name": "DepositAmountTooSmall", "type": "error" }, + { "inputs": [], "name": "LiquidationDenied", "type": "error" }, + { "inputs": [], "name": "MaxFeeEthTooHigh", "type": "error" }, + { "inputs": [], "name": "MaxFeeEthTooLow", "type": "error" }, + { "inputs": [], "name": "MaxFeeFarmEthTooHigh", "type": "error" }, + { "inputs": [], "name": "MaxFeeFarmEthTooLow", "type": "error" }, + { "inputs": [], "name": "NoValue", "type": "error" }, + { "inputs": [], "name": "NotAllowedEntity", "type": "error" }, + { "inputs": [], "name": "NotAllowedToBorrow", "type": "error" }, + { "inputs": [], "name": "NotAllowedWiseSecurity", "type": "error" }, + { "inputs": [], "name": "NotMaster", "type": "error" }, + { "inputs": [], "name": "NotOwner", "type": "error" }, + { "inputs": [], "name": "NotProposed", "type": "error" }, + { "inputs": [], "name": "NotWiseLendingSecurity", "type": "error" }, + { "inputs": [], "name": "OpenBorrowPosition", "type": "error" }, + { "inputs": [], "name": "ResultsInBadDebt", "type": "error" }, + { "inputs": [], "name": "SecuritySwapFailed", "type": "error" }, + { "inputs": [], "name": "TokenBlackListed", "type": "error" }, + { "inputs": [], "name": "TooManyShares", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "SecurityShutdown", + "type": "event" + }, + { + "inputs": [], + "name": "AAVE_HUB", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BORROW_PERCENTAGE_CAP", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_MANAGER", + "outputs": [ + { "internalType": "contract IFeeManager", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POSITION_NFTS", + "outputs": [ + { + "internalType": "contract IPositionNFTs", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_LENDING", + "outputs": [ + { "internalType": "contract IWiseLending", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_LIQUIDATION", + "outputs": [ + { + "internalType": "contract IWiseLiquidation", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_ORACLE", + "outputs": [ + { + "internalType": "contract IWiseOracleHub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseRewardLiquidation", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseRewardLiquidationFarm", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { "internalType": "uint256", "name": "_paybackETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_maxFeeETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_baseRewardLiquidation", + "type": "uint256" + } + ], + "name": "calculateWishPercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_borrowETHTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weightedCollateralETH", + "type": "uint256" + } + ], + "name": "canLiquidate", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMinDepositValue", + "type": "uint256" + } + ], + "name": "changeMinDepositValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "checkBadDebtLiquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_borrowETHTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_unweightedCollateral", + "type": "uint256" + } + ], + "name": "checkBadDebtThreshold", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "bool", "name": "_isPowerFarm", "type": "bool" } + ], + "name": "checkHealthState", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checkHeartbeat", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_paybackETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_feeLiquidation", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_maxFeeETH", "type": "uint256" } + ], + "name": "checkMaxFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { + "internalType": "address", + "name": "_tokenToPayback", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_borrowETHTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_unweightedCollateralETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shareAmountToPay", + "type": "uint256" + } + ], + "name": "checkMaxShares", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checkMinDepositValue", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checkOwnerPosition", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "checkPoolCondition", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checkPoolWithMinDeposit", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolAddress", "type": "address" } + ], + "name": "checkTokenAllowed", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checkUncollateralizedDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checksBorrow", + "outputs": [ + { "internalType": "bool", "name": "specialCase", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolAddress", "type": "address" } + ], + "name": "checksCollateralizeDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_nftIdLiquidate", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_tokenToPayback", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_shareAmountToPay", + "type": "uint256" + } + ], + "name": "checksLiquidation", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checksRegister", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checksSolelyWithdraw", + "outputs": [ + { "internalType": "bool", "name": "specialCase", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checksWithdraw", + "outputs": [ + { "internalType": "bool", "name": "specialCase", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "curveSecurityCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "curveSwapInfoData", + "outputs": [ + { "internalType": "address", "name": "curvePool", "type": "address" }, + { "internalType": "address", "name": "curveMetaPool", "type": "address" }, + { "internalType": "bytes", "name": "swapBytesPool", "type": "bytes" }, + { "internalType": "bytes", "name": "swapBytesMeta", "type": "bytes" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "curveSwapInfoToken", + "outputs": [ + { + "internalType": "uint256", + "name": "curvePoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curvePoolTokenIndexTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexTo", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getBorrowRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getETHBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getETHCollateral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getETHCollateralUpdated", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getExpectedLendingAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getExpectedPaybackAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getFullCollateralETH", + "outputs": [ + { "internalType": "uint256", "name": "ethCollateral", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getLendingRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "getLiveDebtRatio", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionBorrowAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionLendingAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFeeETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFeeFarmETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "maximumBorrowToken", + "outputs": [ + { "internalType": "uint256", "name": "tokenAmount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_solelyWithdrawAmount", + "type": "uint256" + } + ], + "name": "maximumWithdrawToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_poolWithdrawAmount", + "type": "uint256" + } + ], + "name": "maximumWithdrawTokenSolely", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minDepositEthValue", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallBorrowAPY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHBorrow", + "outputs": [ + { "internalType": "uint256", "name": "buffer", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHBorrowBare", + "outputs": [ + { "internalType": "uint256", "name": "buffer", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHBorrowHeartbeat", + "outputs": [ + { "internalType": "uint256", "name": "buffer", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHCollateralsBare", + "outputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHCollateralsBoth", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallETHCollateralsWeighted", + "outputs": [ + { "internalType": "uint256", "name": "weightedTotal", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallLendingAPY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "overallNetAPY", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "positionBlackListToken", + "outputs": [ + { "internalType": "bool", "name": "", "type": "bool" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "curvePool", "type": "address" }, + { + "internalType": "address", + "name": "curveMetaPool", + "type": "address" + }, + { "internalType": "bytes", "name": "swapBytesPool", "type": "bytes" }, + { "internalType": "bytes", "name": "swapBytesMeta", "type": "bytes" } + ], + "internalType": "struct CurveSwapStructData", + "name": "_curveSwapStructData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "curvePoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curvePoolTokenIndexTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexTo", + "type": "uint256" + } + ], + "internalType": "struct CurveSwapStructToken", + "name": "_curveSwapStructToken", + "type": "tuple" + } + ], + "name": "prepareCurvePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_proposedOwner", "type": "address" } + ], + "name": "proposeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedMaster", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "revokeShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" } + ], + "name": "safeLimitPosition", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "securityShutdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "securityWorker", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tokenAddress", "type": "address" }, + { "internalType": "bool", "name": "_state", "type": "bool" } + ], + "name": "setBlacklistToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_baseReward", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_baseRewardFarm", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_newMaxFeeETH", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_newMaxFeeFarmETH", + "type": "uint256" + } + ], + "name": "setLiquidationSettings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_entitiy", "type": "address" }, + { "internalType": "bool", "name": "_state", "type": "bool" } + ], + "name": "setSecurityWorker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "wasBlacklisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + } + ] diff --git a/src/adaptors/wise-lending-v2/index.js b/src/adaptors/wise-lending-v2/index.js new file mode 100644 index 0000000000..8f8ba16f46 --- /dev/null +++ b/src/adaptors/wise-lending-v2/index.js @@ -0,0 +1,187 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const wiseLendingABI = require('./abi/wiseLendingABI.json'); +const wiseSecurityABI = require('./abi/wiseSecurityABI.json'); +const AaveHubABI = require('./abi/AaveHubABI.json'); +const superagent = require('superagent'); + +const ChainName = { + ethereum: "Ethereum", + arbitrum: "Arbitrum", +}; + +const contracts = { + wiseLending: { + ethereum: "0x78190e4c7C7B2c2C3b0562F1f155a1FC2F5160CA", + arbitrum: "0x9034a49587bD2c1Af27598E0f04F30Db66C87Ebf" + }, + wiseSecurity: { + ethereum: "0x8EB1B69fB74C6019C16f43ae93F0fAD7CCB9A59d", + arbitrum: "0x67dae107eCF474F0D5B7d8aD45490608a5AdbE2A" + }, + aaveHub: { + ethereum: "0x5b2E35d9dEB2962D05A5C7E91939169656DCd1Cd", + arbitrum: "0x4A56DCd67E66102E6a877dE8BF2E903Df5E18978" + } +}; + +const aavePools = [ + "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8", + "0x724dc807b04555b71ed48a6896b6F41593b8C637", + "0x6ab707Aca953eDAeFBc4fD23bA73294241490620", + "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE", +]; + +const tokenAddresses = { + ethereum: { + WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7", + USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + WBTC: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", + DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F", + wstETH: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", + }, + arbitrum: { + WETH: "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8", + USDC: "0x724dc807b04555b71ed48a6896b6F41593b8C637", + USDT: "0x6ab707Aca953eDAeFBc4fD23bA73294241490620", + DAI: "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE", + wstETH: "0x5979D7b546E38E414F7E9822514be443A4800529", + }, + underlying: { + WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + } +}; + +const projectSlug = 'wise-lending-v2'; + +const getTokenData = async (chain, token, addresses, contract) => { + const address = addresses[chain]; + const isAave = aavePools.includes(address[token]); + const underlyingAddress = isAave ? addresses.underlying[token] : address[token]; + const wiseSecurity = contracts.wiseSecurity[chain]; + const wiseLending = contracts.wiseLending[chain]; + const aaveHub = isAave ? contracts.aaveHub[chain] : wiseSecurity; + + try { + + if (chain === "ethereum") { + sdk.api.config.setProvider( + `${chain}`, + new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/b2ca877d39fa4a1c99e9120a03d53e57`) + ); + } + + const tokenAddress = `${chain}:${address[token]}`; + + const usdPrice = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${tokenAddress}` + ) + ).body.coins[tokenAddress]; + + const lendingData = await sdk.api.abi.call({ + target: aaveHub, + abi: AaveHubABI.find((m) => m.name === 'getLendingRate'), + chain, + params: [underlyingAddress], + }); + + const lendingRate = lendingData.output / 1e16; + + const borrowData = await sdk.api.abi.call({ + target: wiseSecurity, + abi: wiseSecurityABI.find((m) => m.name === 'getBorrowRate'), + chain, + params: [address[token]], + }); + + const borrowRate = borrowData.output / 1e16; + + const totalBorrowData = await sdk.api.abi.call({ + target: wiseLending, + abi: wiseLendingABI.find((m) => m.name === 'getPseudoTotalBorrowAmount'), + chain, + params: [address[token]], + }); + + const totalBorrow = totalBorrowData.output / Math.pow(10, usdPrice.decimals); + + const totalSupplyData = await sdk.api.abi.call({ + target: wiseLending, + abi: wiseLendingABI.find((m) => m.name === 'getPseudoTotalPool'), + chain, + params: [address[token]], + }); + + const totalSupply = totalSupplyData.output / Math.pow(10, usdPrice.decimals); + + const balanceData = await sdk.api.abi.call({ + target: address[token], + abi: 'erc20:balanceOf', + chain, + params: [wiseLending], + }); + + const balance = balanceData.output / Math.pow(10, usdPrice.decimals); + + const tvlUsd = balance * usdPrice.price; + const totalSupplyUsd = totalSupply * usdPrice.price; + const totalBorrowUsd = totalBorrow * usdPrice.price; + + return { + pool: `${address[token]}-${projectSlug}-${chain}`, + chain: ChainName[chain], + project: projectSlug, + symbol: token, + poolMeta: usdPrice.symbol, + tvlUsd, + apyBase: lendingRate, + // apyReward: lendingRate, + url: 'https://wiselending.com/', + apyBaseBorrow: borrowRate, + // apyRewardBorrow: borrowRate, + totalSupplyUsd, + totalBorrowUsd, + }; + } catch (e) { + console.log('error', chain, token, address[token], wiseSecurity, wiseLending, e); + } +}; + +async function apy() { + const chains = Object.keys(ChainName); + const pools = await Promise.all( + chains.map(async (chain) => { + const tokens = Object.keys(tokenAddresses[chain]); + return ( + await Promise.all( + // Lend Pool + [ + Promise.all( + tokens.map(async (token) => { + + return getTokenData( + chain, + token, + tokenAddresses, + contracts + ); + }) + ), + ] + ) + ).flat(); + }), + ); + + return pools.flat(); +} + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/wise-lending/abi/erc20ABI.json b/src/adaptors/wise-lending/abi/erc20ABI.json new file mode 100644 index 0000000000..02214fea56 --- /dev/null +++ b/src/adaptors/wise-lending/abi/erc20ABI.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } + ] \ No newline at end of file diff --git a/src/adaptors/wise-lending/abi/wiseLendingABI.json b/src/adaptors/wise-lending/abi/wiseLendingABI.json new file mode 100644 index 0000000000..ae632022e8 --- /dev/null +++ b/src/adaptors/wise-lending/abi/wiseLendingABI.json @@ -0,0 +1,1081 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { "internalType": "address", "name": "_wiseOracleHubAddress", "type": "address" }, + { "internalType": "address", "name": "_nftContract", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "CollateralTooSmall", "type": "error" }, + { "inputs": [], "name": "DeadOracle", "type": "error" }, + { "inputs": [], "name": "InvalidAction", "type": "error" }, + { "inputs": [], "name": "InvalidCaller", "type": "error" }, + { "inputs": [], "name": "NoValue", "type": "error" }, + { "inputs": [], "name": "NotMaster", "type": "error" }, + { "inputs": [], "name": "NotProposed", "type": "error" }, + { "inputs": [], "name": "PositionLocked", "type": "error" }, + { "inputs": [], "name": "SharePriceDecreased", "type": "error" }, + { "inputs": [], "name": "SharePriceIncreased", "type": "error" }, + { "inputs": [], "name": "ZeroSharesAssigned", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "newMaster", "type": "address" }, + { + "indexed": true, + "internalType": "address", + "name": "previousMaster", + "type": "address" + } + ], + "name": "ClaimedOwnership", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsBorrowed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsBorrowedOnBehalf", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalPayment", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalPaymentShares", + "type": "uint256" + }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsReturned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsSolelyDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsSolelyWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsSolelyWithdrawnOnBehalf", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, + { "indexed": true, "internalType": "uint256", "name": "nftId", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "token", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "shares", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "timestamp", "type": "uint256" } + ], + "name": "FundsWithdrawnOnBehalf", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "proposer", "type": "address" }, + { + "indexed": true, + "internalType": "address", + "name": "proposedMaster", + "type": "address" + } + ], + "name": "MasterProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousMaster", + "type": "address" + } + ], + "name": "RenouncedOwnership", + "type": "event" + }, + { + "inputs": [], + "name": "POSITION_NFT", + "outputs": [{ "internalType": "contract IPositionNFTs", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH_ADDRESS", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_ORACLE", + "outputs": [{ "internalType": "contract IWiseOracleHub", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_SECURITY", + "outputs": [{ "internalType": "contract IWiseSecurity", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "algorithmData", + "outputs": [ + { "internalType": "bool", "name": "increasePole", "type": "bool" }, + { "internalType": "uint256", "name": "bestPole", "type": "uint256" }, + { "internalType": "uint256", "name": "maxValue", "type": "uint256" }, + { "internalType": "uint256", "name": "previousValue", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_spender", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "borrowOnBehalfExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowPoolData", + "outputs": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { "internalType": "uint256", "name": "pseudoTotalBorrowAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "totalBorrowShares", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowRate", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "borrowRatesData", + "outputs": [ + { "internalType": "uint256", "name": "pole", "type": "uint256" }, + { "internalType": "uint256", "name": "deltaPole", "type": "uint256" }, + { "internalType": "uint256", "name": "minPole", "type": "uint256" }, + { "internalType": "uint256", "name": "maxPole", "type": "uint256" }, + { "internalType": "uint256", "name": "multiplicativeFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "bool", "name": "_maxSharePrice", "type": "bool" } + ], + "name": "calculateBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "bool", "name": "_maxSharePrice", "type": "bool" } + ], + "name": "calculateLendingShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "cashoutAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checkDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checkPositionLocked", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "collateralizeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_nftIdLiquidator", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_receiver", "type": "address" }, + { "internalType": "address", "name": "_paybackToken", "type": "address" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { "internalType": "uint256", "name": "_paybackAmount", "type": "uint256" }, + { "internalType": "uint256", "name": "_shareAmountToPay", "type": "uint256" } + ], + "name": "coreLiquidationIsolationPools", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "corePaybackFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { "internalType": "address", "name": "poolToken", "type": "address" }, + { "internalType": "uint256", "name": "poolMulFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "poolCollFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "maxDepositAmount", "type": "uint256" } + ], + "internalType": "struct PoolManager.CreatePool", + "name": "_params", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { "internalType": "address", "name": "curvePool", "type": "address" }, + { + "internalType": "address", + "name": "curveMetaPool", + "type": "address" + }, + { "internalType": "bytes", "name": "swapBytesPool", "type": "bytes" }, + { "internalType": "bytes", "name": "swapBytesMeta", "type": "bytes" } + ], + "internalType": "struct CurveSwapStructData", + "name": "curveSecuritySwapsData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "curvePoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curvePoolTokenIndexTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexTo", + "type": "uint256" + } + ], + "internalType": "struct CurveSwapStructToken", + "name": "curveSecuritySwapsToken", + "type": "tuple" + } + ], + "internalType": "struct PoolManager.CurvePoolSettings", + "name": "_settings", + "type": "tuple" + } + ], + "name": "createCurvePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bool", "name": "allowBorrow", "type": "bool" }, + { "internalType": "address", "name": "poolToken", "type": "address" }, + { "internalType": "uint256", "name": "poolMulFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "poolCollFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "maxDepositAmount", "type": "uint256" } + ], + "internalType": "struct PoolManager.CreatePool", + "name": "_params", + "type": "tuple" + } + ], + "name": "createPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "depositExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositExactAmountETHMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "depositExactAmountMint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_index", "type": "uint256" } + ], + "name": "getPositionBorrowTokenByIndex", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "getPositionBorrowTokenLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionLendingShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_index", "type": "uint256" } + ], + "name": "getPositionLendingTokenByIndex", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "getPositionLendingTokenLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getPseudoTotalBorrowAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getPseudoTotalPool", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPureCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getTimeStamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getTotalBareToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getTotalBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getTotalDepositShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getTotalPool", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "globalPoolData", + "outputs": [ + { "internalType": "uint256", "name": "totalPool", "type": "uint256" }, + { "internalType": "uint256", "name": "utilization", "type": "uint256" }, + { "internalType": "uint256", "name": "totalBareToken", "type": "uint256" }, + { "internalType": "uint256", "name": "poolFee", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "isUncollateralized", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "lendingPoolData", + "outputs": [ + { "internalType": "uint256", "name": "pseudoTotalPool", "type": "uint256" }, + { "internalType": "uint256", "name": "totalDepositShares", "type": "uint256" }, + { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_nftIdLiquidator", "type": "uint256" }, + { "internalType": "address", "name": "_paybackToken", "type": "address" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { "internalType": "uint256", "name": "_shareAmountToPay", "type": "uint256" } + ], + "name": "liquidatePartiallyFromTokens", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "maxDepositValueToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "newBorrowRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "paybackAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "paybackExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "paybackExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "paybackExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "positionBorrowTokenData", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "positionLendTokenData", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "positionLocked", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "preparePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_proposedOwner", "type": "address" }], + "name": "proposeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "pureCollateralAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sendingProgress", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_contract", "type": "address" }, + { "internalType": "bool", "name": "_status", "type": "bool" } + ], + "name": "setOnBehalf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_poolMulFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "_upperBoundMaxRate", "type": "uint256" }, + { "internalType": "uint256", "name": "_lowerBoundMaxRate", "type": "uint256" }, + { "internalType": "bool", "name": "_steppingDirection", "type": "bool" }, + { "internalType": "bool", "name": "_isFinal", "type": "bool" } + ], + "name": "setParamsLASA", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_newFee", "type": "uint256" } + ], + "name": "setPoolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_collateralFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "_maximumDeposit", "type": "uint256" } + ], + "name": "setPoolParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "bool", "name": "_registerState", "type": "bool" } + ], + "name": "setRegistrationIsolationPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_wiseSecurity", "type": "address" }], + "name": "setSecurity", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_isolationPool", "type": "address" }, + { "internalType": "bool", "name": "_state", "type": "bool" } + ], + "name": "setVerifiedIsolationPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "skim", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "solelyDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "solelyDepositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "solelyDepositETHMint", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "solelyDepositMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "solelyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "withdrawAmount", "type": "uint256" } + ], + "name": "solelyWithdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "solelyWithdrawOnBehalf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "syncManually", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "timestampsPoolData", + "outputs": [ + { "internalType": "uint256", "name": "timeStamp", "type": "uint256" }, + { "internalType": "uint256", "name": "timeStampScaling", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "unCollateralizeDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userBorrowShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userLendingData", + "outputs": [ + { "internalType": "bool", "name": "unCollateralized", "type": "bool" }, + { "internalType": "uint256", "name": "shares", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "verifiedIsolationPool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "withdrawExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdrawExactAmountETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawExactSharesETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_withdrawAmount", "type": "uint256" } + ], + "name": "withdrawOnBehalfExactAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_shares", "type": "uint256" } + ], + "name": "withdrawOnBehalfExactShares", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] \ No newline at end of file diff --git a/src/adaptors/wise-lending/abi/wiseSecurityABI.json b/src/adaptors/wise-lending/abi/wiseSecurityABI.json new file mode 100644 index 0000000000..dfaad112e8 --- /dev/null +++ b/src/adaptors/wise-lending/abi/wiseSecurityABI.json @@ -0,0 +1,676 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "_master", "type": "address" }, + { "internalType": "address", "name": "_wiseLendingAddress", "type": "address" }, + { "internalType": "address", "name": "_aaveHubAddress", "type": "address" }, + { "internalType": "uint256", "name": "_borrowPercentageCap", "type": "uint256" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "ChainlinkDead", "type": "error" }, + { "inputs": [], "name": "LiquidationDenied", "type": "error" }, + { "inputs": [], "name": "NoValue", "type": "error" }, + { "inputs": [], "name": "NotAllowedToBorrow", "type": "error" }, + { "inputs": [], "name": "NotAllowedWiseSecurity", "type": "error" }, + { "inputs": [], "name": "NotEnoughCollateral", "type": "error" }, + { "inputs": [], "name": "NotMaster", "type": "error" }, + { "inputs": [], "name": "NotOwner", "type": "error" }, + { "inputs": [], "name": "NotProposed", "type": "error" }, + { "inputs": [], "name": "NotWiseLendingSecurity", "type": "error" }, + { "inputs": [], "name": "OpenBorrowPosition", "type": "error" }, + { "inputs": [], "name": "PositionLockedWiseSecurity", "type": "error" }, + { "inputs": [], "name": "ResultsInBadDebt", "type": "error" }, + { "inputs": [], "name": "SecuritySwapFailed", "type": "error" }, + { "inputs": [], "name": "TokenBlackListed", "type": "error" }, + { "inputs": [], "name": "TooManyShares", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "newMaster", "type": "address" }, + { + "indexed": true, + "internalType": "address", + "name": "previousMaster", + "type": "address" + } + ], + "name": "ClaimedOwnership", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "proposer", "type": "address" }, + { + "indexed": true, + "internalType": "address", + "name": "proposedMaster", + "type": "address" + } + ], + "name": "MasterProposed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousMaster", + "type": "address" + } + ], + "name": "RenouncedOwnership", + "type": "event" + }, + { + "inputs": [], + "name": "AAVE_HUB", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FEE_MANAGER", + "outputs": [{ "internalType": "contract IFeeManager", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POSITION_NFTS", + "outputs": [{ "internalType": "contract IPositionNFTs", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_LENDING", + "outputs": [{ "internalType": "contract IWiseLending", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_LIQUIDATION", + "outputs": [{ "internalType": "contract IWiseLiquidation", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WISE_ORACLE", + "outputs": [{ "internalType": "contract IWiseOracleHub", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseRewardLiquidation", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseRewardLiquidationFarm", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowPercentageCap", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_receiveToken", "type": "address" }, + { "internalType": "uint256", "name": "_paybackETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_maxFeeETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_baseRewardLiquidation", "type": "uint256" } + ], + "name": "calculateWishPercentage", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_borrowETHTotal", "type": "uint256" }, + { "internalType": "uint256", "name": "_weightedCollateralETH", "type": "uint256" } + ], + "name": "canLiquidate", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "checkBadDebt", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_borrowETHTotal", "type": "uint256" }, + { "internalType": "uint256", "name": "_unweightedCollateral", "type": "uint256" } + ], + "name": "checkBadDebtThreshold", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checkBorrowLimit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "checkHeartbeat", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_paybackETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_feeLiquidation", "type": "uint256" }, + { "internalType": "uint256", "name": "_maxFeeETH", "type": "uint256" } + ], + "name": "checkMaxFee", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_tokenToPayback", "type": "address" }, + { "internalType": "uint256", "name": "_borrowETHTotal", "type": "uint256" }, + { "internalType": "uint256", "name": "_unweightedCollateralETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_shareAmountToPay", "type": "uint256" } + ], + "name": "checkMaxShares", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checkOwnerPosition", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolAddress", "type": "address" }], + "name": "checkTokenAllowed", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "checkUncollateralizedDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checksBorrow", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolAddress", "type": "address" } + ], + "name": "checksCollateralizeDeposit", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftIdLiquidate", "type": "uint256" }, + { "internalType": "address", "name": "_tokenToPayback", "type": "address" }, + { "internalType": "uint256", "name": "_shareAmountToPay", "type": "uint256" } + ], + "name": "checksLiquidation", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" } + ], + "name": "checksRegister", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checksSolelyWithdraw", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_caller", "type": "address" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "checksWithdraw", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "curveSecurityCheck", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "curveSwapInfoData", + "outputs": [ + { "internalType": "address", "name": "curvePool", "type": "address" }, + { "internalType": "address", "name": "curveMetaPool", "type": "address" }, + { "internalType": "bytes", "name": "swapBytesPool", "type": "bytes" }, + { "internalType": "bytes", "name": "swapBytesMeta", "type": "bytes" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "curveSwapInfoToken", + "outputs": [ + { "internalType": "uint256", "name": "curvePoolTokenIndexFrom", "type": "uint256" }, + { "internalType": "uint256", "name": "curvePoolTokenIndexTo", "type": "uint256" }, + { "internalType": "uint256", "name": "curveMetaPoolTokenIndexFrom", "type": "uint256" }, + { "internalType": "uint256", "name": "curveMetaPoolTokenIndexTo", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getBorrowRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getETHBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getETHCollateral", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getETHCollateralUpdated", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getExpectedLendingAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "getExpectedPaybackAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getFullCollateralETH", + "outputs": [{ "internalType": "uint256", "name": "ethCollateral", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_poolToken", "type": "address" }], + "name": "getLendingRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "getLiveDebtRatio", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionBorrowAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" } + ], + "name": "getPositionLendingAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFeeETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFeeFarmETH", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" } + ], + "name": "maximumBorrowToken", + "outputs": [{ "internalType": "uint256", "name": "tokenAmount", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" }, + { "internalType": "uint256", "name": "_solelyWithdrawAmount", "type": "uint256" } + ], + "name": "maximumWithdrawToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_nftId", "type": "uint256" }, + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { "internalType": "uint256", "name": "_interval", "type": "uint256" }, + { "internalType": "uint256", "name": "_poolWithdrawAmount", "type": "uint256" } + ], + "name": "maximumWithdrawTokenSolely", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallBorrowAPY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallETHBorrow", + "outputs": [{ "internalType": "uint256", "name": "buffer", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallETHBorrowHeartbeat", + "outputs": [{ "internalType": "uint256", "name": "buffer", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallETHCollateralsBare", + "outputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallETHCollateralsBoth", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallETHCollateralsWeighted", + "outputs": [{ "internalType": "uint256", "name": "weightedTotal", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallLendingAPY", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "overallNetAPY", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "bool", "name": "", "type": "bool" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "positionLocked", + "outputs": [ + { "internalType": "bool", "name": "", "type": "bool" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_poolToken", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "curvePool", "type": "address" }, + { "internalType": "address", "name": "curveMetaPool", "type": "address" }, + { "internalType": "bytes", "name": "swapBytesPool", "type": "bytes" }, + { "internalType": "bytes", "name": "swapBytesMeta", "type": "bytes" } + ], + "internalType": "struct CurveSwapStructData", + "name": "_curveSwapStructData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "curvePoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curvePoolTokenIndexTo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexFrom", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curveMetaPoolTokenIndexTo", + "type": "uint256" + } + ], + "internalType": "struct CurveSwapStructToken", + "name": "_curveSwapStructToken", + "type": "tuple" + } + ], + "name": "prepareCurvePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "_proposedOwner", "type": "address" }], + "name": "proposeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "_nftId", "type": "uint256" }], + "name": "safeLimitPosition", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_tokenAddress", "type": "address" }, + { "internalType": "bool", "name": "_state", "type": "bool" } + ], + "name": "setBlacklistToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_baseReward", "type": "uint256" }, + { "internalType": "uint256", "name": "_baseRewardFarm", "type": "uint256" }, + { "internalType": "uint256", "name": "_newMaxFeeETH", "type": "uint256" }, + { "internalType": "uint256", "name": "_newMaxFeeFarmETH", "type": "uint256" } + ], + "name": "setLiquidationSettings", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "wasBlacklisted", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wise-lending/index.js b/src/adaptors/wise-lending/index.js new file mode 100644 index 0000000000..9a242bb0bf --- /dev/null +++ b/src/adaptors/wise-lending/index.js @@ -0,0 +1,116 @@ +const sdk = require('@defillama/sdk'); +const { ethers } = require('ethers'); +const { Web3 } = require('web3'); +const wiseLendingABI = require('./abi/wiseLendingABI.json'); +const wiseSecurityABI = require('./abi/wiseSecurityABI.json'); +const erc20ABI = require('./abi/erc20ABI.json'); +const { getProvider } = require('@defillama/sdk/build/general'); +const superagent = require('superagent'); + +const WISE_LENDING_CONTRACT = '0x37e49bf3749513A02FA535F0CbC383796E8107E4'; +const WISE_SECURITY_CONTRACT = '0x829c3AE2e82760eCEaD0F384918a650F8a31Ba18'; +const FEE_MANAGER_CONTRACT = '0x0bC24E61DAAd6293A1b3b53a7D01086BfF0Ea6e5'; + +const address = { + WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', +}; + +const ChainName = { + ethereum: 'Ethereum', +}; + +const projectSlug = 'wise-lending'; +const tokens = ['WETH']; + +const web3 = new Web3( + 'https://mainnet.infura.io/v3/b2ca877d39fa4a1c99e9120a03d53e57' +); + +async function apy() { + const pools = await Promise.all( + ['ethereum'].map(async (chain) => { + return ( + await Promise.all( + // Lend Pool + [ + Promise.all( + tokens.map(async (token) => { + const tokenAddress = `${chain}:${address[token]}`; + + const usdPrice = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${tokenAddress}` + ) + ).body.coins[tokenAddress]; + + const wiseSecurityContract = await new web3.eth.Contract( + wiseSecurityABI, + WISE_SECURITY_CONTRACT + ); + + const lendingRate = + (await wiseSecurityContract.methods + .getLendingRate(address[token]) + .call()) / 1e16; + const borrowRate = + (await wiseSecurityContract.methods + .getBorrowRate(address[token]) + .call()) / 1e16; + + const wiseLendingContract = await new web3.eth.Contract( + wiseLendingABI, + WISE_LENDING_CONTRACT + ); + + const totalBorrow = + (await wiseLendingContract.methods + .getPseudoTotalBorrowAmount(address[token]) + .call()) / 1e18; + const totalSupply = + (await wiseLendingContract.methods + .getPseudoTotalPool(address[token]) + .call()) / 1e18; + + const tokenContract = await new web3.eth.Contract( + erc20ABI, + address[token] + ); + + const balance = + (await tokenContract.methods + .balanceOf(WISE_LENDING_CONTRACT) + .call()) / 1e18; + + const tvlUsd = balance * usdPrice.price; + const totalSupplyUsd = totalSupply * usdPrice.price; + const totalBorrowUsd = totalBorrow * usdPrice.price; + + return { + pool: `${address[token]}-wise-lending-${chain}`, + chain: ChainName[chain], + project: projectSlug, + symbol: usdPrice.symbol, + tvlUsd, + apyBase: lendingRate, + // apyReward: lendingRate, + url: 'https://wiselending.com/', + apyBaseBorrow: borrowRate, + // apyRewardBorrow: borrowRate, + totalSupplyUsd, + totalBorrowUsd, + }; + }) + ), + ] + ) + ).flat(); + }) + ); + + return pools.flat(); +} + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/wombat-exchange/config.js b/src/adaptors/wombat-exchange/config.js new file mode 100644 index 0000000000..eb113fb996 --- /dev/null +++ b/src/adaptors/wombat-exchange/config.js @@ -0,0 +1,31 @@ +const sdk = require('@defillama/sdk'); + +module.exports = { + bsc: { + APR_ENDPOINT: sdk.graph.modifyEndpoint( + '3jEHqbiN3BQn7pyMDzkDcBwm5EYFtpMpXaeryRDGPKA7' + ), + BLOCK_ENDPOINT: sdk.graph.modifyEndpoint( + 'aFYiBZ2nkQVbv1HsKTQcPpWBxCAiJY4w4pG8RXaDxge' + ), + WOM_ADDRESS: '0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1', + }, + arbitrum: { + APR_ENDPOINT: sdk.graph.modifyEndpoint( + '5YPaz7z5iYgboKtoShdvZYPohUKtrDLibcLSLzaC424M' + ), + BLOCK_ENDPOINT: sdk.graph.modifyEndpoint( + 'H51Q1HznwXnrEEMQrKoniHJ6VLz3zryYmb9XQ8T8BmqJ' + ), + WOM_ADDRESS: '0x7b5eb3940021ec0e8e463d5dbb4b7b09a89ddf96', + }, + avax: { + APR_ENDPOINT: sdk.graph.modifyEndpoint( + 'CoQESay2omXqeXf2irxDoPnggR9ULC9SeM7jPeSNgEVT' + ), + BLOCK_ENDPOINT: sdk.graph.modifyEndpoint( + 'ESjwguQU6CdSHnBT6jMniNHkj2dfAHRdFLB5eWwDe6jB' + ), + WOM_ADDRESS: '0xa15E4544D141aa98C4581a1EA10Eb9048c3b3382', + }, +}; diff --git a/src/adaptors/wombat-exchange/index.js b/src/adaptors/wombat-exchange/index.js new file mode 100644 index 0000000000..247a1b7d55 --- /dev/null +++ b/src/adaptors/wombat-exchange/index.js @@ -0,0 +1,119 @@ +const { gql, request } = require('graphql-request'); +const config = require('./config.js'); + +const prevBlockQuery = gql` + query Blocks($timestamp_lte: BigInt = "") { + blocks( + first: 1 + orderBy: timestamp + orderDirection: desc + where: { timestamp_lte: $timestamp_lte } + ) { + number + timestamp + } + } +`; + +const volumesQuery = gql` + query Volumes($block: Int = 0) { + assetsNow: assets { + id + symbol + totalSharedFeeUSD + liabilityUSD + } + assets24hAgo: assets(block: { number: $block }) { + id + symbol + totalSharedFeeUSD + liabilityUSD + } + } +`; + +const aprQuery = gql` + query Apr { + assets(where: { id_not: "0x0000000000000000000000000000000000000000" }) { + id + symbol + liabilityUSD + totalSharedFeeUSD + womBaseApr + avgBoostedApr + totalBonusTokenApr + underlyingToken { + id + } + } + } +`; + +const oneDay = 86400; + +const apy = async () => { + apy_export = []; + for (chain in config) { + const timestampPrior = +(new Date() / 1000).toFixed(0) - oneDay; + + const blockPrior = ( + await request(config[chain]['BLOCK_ENDPOINT'], prevBlockQuery, { + timestamp_lte: timestampPrior, + }) + ).blocks[0].number; + + const { assetsNow, assets24hAgo } = await request( + config[chain]['APR_ENDPOINT'], + volumesQuery, + { + block: +blockPrior, + } + ); + + const { assets: aprs } = await request( + config[chain]['APR_ENDPOINT'], + aprQuery + ); + + const assets = aprs.map((pool) => { + const aprData = aprs.find((apr) => apr.id === pool.id) || {}; + const feeNow = assetsNow.find((apr) => apr.id === pool.id) || {}; + const fee24hAgo = assets24hAgo.find((apr) => apr.id === pool.id) || {}; + + // Projected baseApy estimated by feeUSD collected in 24h + let apyBase = + (((Number(feeNow.totalSharedFeeUSD) - + Number(fee24hAgo.totalSharedFeeUSD)) / + 2) * + 365 * + 100) / + Number(pool.liabilityUSD) || 0; + + let apyReward = + (Number(aprData.womBaseApr) + Number(aprData.totalBonusTokenApr)) * 100; + + apy_export.push({ + pool: aprData.id, + project: 'wombat-exchange', + chain: chain, + tvlUsd: Number(pool.liabilityUSD) || 0, + symbol: pool.symbol, + apyReward, + apyBase, + underlyingTokens: [pool.underlyingToken.id], + rewardTokens: [config[chain]['WOM_ADDRESS']], + }); + }); + } + + // remove dupes on lptoken + return apy_export.filter( + (v, i, a) => a.findIndex((v2) => v2.pool === v.pool) === i + ); +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://app.wombat.exchange/pool', +}; diff --git a/src/adaptors/wombex-finance/abis/Asset.json b/src/adaptors/wombex-finance/abis/Asset.json new file mode 100644 index 0000000000..d68fe0b897 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Asset.json @@ -0,0 +1,691 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "underlyingToken_", + "type": "address" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ASSET_OVERFLOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_FORBIDDEN", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "previousMaxSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newMaxSupply", + "type": "uint256" + } + ], + "name": "SetMaxSupply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousPoolAddr", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPoolAddr", + "type": "address" + } + ], + "name": "SetPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addCash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addLiability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cash", + "outputs": [ + { + "internalType": "uint120", + "name": "", + "type": "uint120" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liability", + "outputs": [ + { + "internalType": "uint120", + "name": "", + "type": "uint120" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "removeCash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "removeLiability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxSupply_", + "type": "uint256" + } + ], + "name": "setMaxSupply", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool_", + "type": "address" + } + ], + "name": "setPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferUnderlyingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "underlyingTokenDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/Booster.json b/src/adaptors/wombex-finance/abis/Booster.json new file mode 100644 index 0000000000..59d810a904 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Booster.json @@ -0,0 +1,1766 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_voterProxy", + "type": "address" + }, + { + "internalType": "address", + "name": "_cvx", + "type": "address" + }, + { + "internalType": "address", + "name": "_crv", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minMintRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxMintRatio", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintRatio", + "type": "uint256" + } + ], + "name": "CustomMintRatioUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "poolid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newEarmarkDelegate", + "type": "address" + } + ], + "name": "EarmarkDelegateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EarmarkRewards", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "distro", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "queue", + "type": "bool" + } + ], + "name": "EarmarkRewardsTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newDist", + "type": "address" + } + ], + "name": "ExtraRewardsDistributorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "rewardFactory", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "tokenFactory", + "type": "address" + } + ], + "name": "FactoriesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "FeeInfoChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeDistro", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "lockFees", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + } + ], + "name": "FeeInfoUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newFeeManager", + "type": "address" + } + ], + "name": "FeeManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "lockRewards", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "cvxLocker", + "type": "address" + } + ], + "name": "LockRewardContractsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "pendingRewardTokens", + "type": "address[]" + } + ], + "name": "LpPendingRewardTokensUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "mintRatio", + "type": "uint256" + } + ], + "name": "MintRatioUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newPenalty", + "type": "uint256" + } + ], + "name": "PenaltyShareUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "PoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPoolManager", + "type": "address" + } + ], + "name": "PoolManagerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + } + ], + "name": "PoolShutdown", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "lock", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "penalty", + "type": "uint256" + } + ], + "name": "RewardClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newBooster", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + } + ], + "name": "RewardMigrate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "earmarkOnDeposit", + "type": "bool" + } + ], + "name": "SetEarmarkOnDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "SetPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "voteDelegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "VoteDelegateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "voting", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "valid", + "type": "bool" + } + ], + "name": "VotingMapUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "poolid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PENALTY_SHARE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_crvRewards", + "type": "address" + } + ], + "name": "addCreatedPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "_gauge", + "type": "address" + } + ], + "name": "addPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_distro", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_distributionTokens", + "type": "address[]" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "approveDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "approvePoolsCrvRewardsDistribution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "crv", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crvLockRewards", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "customMintRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvx", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cvxLocker", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_stake", + "type": "bool" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "depositFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_transferTo", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_transferAmount", + "type": "uint256[]" + }, + { + "internalType": "bool[]", + "name": "_callQueue", + "type": "bool[]" + } + ], + "name": "distributeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "earmarkDelegate", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "earmarkOnDeposit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "extraRewardsDist", + "outputs": [ + { + "internalType": "contract IExtraRewardsDistributor", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "forceShutdownPool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newGauge", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "migratePids", + "type": "uint256[]" + } + ], + "name": "gaugeMigrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "_lptoken", + "type": "address" + } + ], + "name": "getLpBalance", + "outputs": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lptoken", + "type": "address" + } + ], + "name": "getPendingRewardTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lptoken", + "type": "address" + } + ], + "name": "getPendingRewards", + "outputs": [ + { + "internalType": "uint256[]", + "name": "result", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isShutdown", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpPendingRewardTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lpPendingRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxMintRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_rewards", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "_newBooster", + "type": "address" + } + ], + "name": "migrateRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minMintRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "penaltyShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "address", + "name": "lptoken", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "gauge", + "type": "address" + }, + { + "internalType": "address", + "name": "crvRewards", + "type": "address" + }, + { + "internalType": "bool", + "name": "shutdown", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_address", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_lock", + "type": "bool" + } + ], + "name": "rewardClaimed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_mintRatios", + "type": "uint256[]" + } + ], + "name": "setCustomMintRatioMultiple", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_earmarkDelegate", + "type": "address" + } + ], + "name": "setEarmarkDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_earmarkOnDeposit", + "type": "bool" + } + ], + "name": "setEarmarkOnDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dist", + "type": "address" + } + ], + "name": "setExtraRewardsDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_rfactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_tfactory", + "type": "address" + } + ], + "name": "setFactories", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeM", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_crvLockRewards", + "type": "address" + }, + { + "internalType": "address", + "name": "_cvxLocker", + "type": "address" + } + ], + "name": "setLockRewardContracts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "address[]", + "name": "_addresses", + "type": "address[]" + } + ], + "name": "setLpPendingRewardTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_mintRatio", + "type": "uint256" + } + ], + "name": "setMintRatio", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_paused", + "type": "bool" + } + ], + "name": "setPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolM", + "type": "address" + } + ], + "name": "setPoolManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_penaltyShare", + "type": "uint256" + } + ], + "name": "setRewardClaimedPenalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_rewardPools", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "bool", + "name": "_paused", + "type": "bool" + } + ], + "name": "setRewardTokenPausedInPools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "valid", + "type": "bool" + } + ], + "name": "setVote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voteDelegate", + "type": "address" + }, + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + } + ], + "name": "setVoteDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voting", + "type": "address" + }, + { + "internalType": "bool", + "name": "_valid", + "type": "bool" + } + ], + "name": "setVotingValid", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "shutdownPool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shutdownSystem", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenFactory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updateLpPendingRewardTokensByGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "voteDelegate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_voting", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "voteExecute", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "voterProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "_pendingTokens", + "type": "address[]" + } + ], + "name": "voterProxyClaimRewards", + "outputs": [ + { + "internalType": "uint256[]", + "name": "pendingRewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "votingMap", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "withdrawTo", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/Bribe.json b/src/adaptors/wombex-finance/abis/Bribe.json new file mode 100644 index 0000000000..2a60dc2a0a --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Bribe.json @@ -0,0 +1,446 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_master", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startTimestamp", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "OnReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRate", + "type": "uint256" + } + ], + "name": "RewardRateUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "name": "addRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "balances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances_", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "emergencyTokenWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_lpAmount", + "type": "uint256" + } + ], + "name": "onReward", + "outputs": [ + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newVote", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "originalTotalVotes", + "type": "uint256" + } + ], + "name": "onVote", + "outputs": [ + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "tokens", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "distributedAmount", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "name": "setRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardDebt", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "unpaidRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/Bribewmx.json b/src/adaptors/wombex-finance/abis/Bribewmx.json new file mode 100644 index 0000000000..ce2989face --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Bribewmx.json @@ -0,0 +1,1525 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "operator_", + "type": "address" + }, + { + "internalType": "address", + "name": "lptoken_", + "type": "address" + }, + { + "internalType": "bool", + "name": "_callOperatorOnGetReward", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Donate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "currentRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRewards", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "SetRewardTokenPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "callOperatorOnGetReward", + "type": "bool" + } + ], + "name": "UpdateBribesConfig", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "UpdateOperatorData", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxRewardRatio", + "type": "uint256" + } + ], + "name": "UpdateRatioConfig", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NEW_REWARD_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allRewardTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boosterRewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "callOperatorOnGetReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableRewards", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "donate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "duration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_lockCvx", + "type": "bool" + } + ], + "name": "getReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_lockCvx", + "type": "bool" + }, + { + "internalType": "address[]", + "name": "_claimTokens", + "type": "address[]" + } + ], + "name": "getReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "newRewardRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "processIdleRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "queueNewRewards", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokensLen", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokensList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "name": "setRewardTokenPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakeAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_for", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stakeFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenRewards", + "outputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "historicalRewards", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_callOperatorOnGetReward", + "type": "bool" + } + ], + "name": "updateBribesConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pid_", + "type": "uint256" + } + ], + "name": "updateOperatorData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newRewardRatio", + "type": "uint256" + } + ], + "name": "updateRatioConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdrawAllAndUnwrap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdrawAndUnwrap", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_claimRecipient", + "type": "address" + } + ], + "name": "withdrawAndUnwrapFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/CLP.json b/src/adaptors/wombex-finance/abis/CLP.json new file mode 100644 index 0000000000..bca8a84144 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/CLP.json @@ -0,0 +1,509 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + }, + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "int256", + "name": "current", + "type": "int256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + } + ], + "name": "AnswerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "roundId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "startedBy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + } + ], + "name": "NewRound", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessController", + "outputs": [ + { + "internalType": "contract AccessControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aggregator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "confirmAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_roundId", + "type": "uint256" + } + ], + "name": "getTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestAnswer", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRound", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "phaseAggregators", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "phaseId", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + } + ], + "name": "proposeAggregator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proposedAggregator", + "outputs": [ + { + "internalType": "contract AggregatorV2V3Interface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "proposedGetRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proposedLatestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_accessController", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/Coin.json b/src/adaptors/wombex-finance/abis/Coin.json new file mode 100644 index 0000000000..77e534cabe --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Coin.json @@ -0,0 +1,612 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCap", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCap", + "type": "uint256" + } + ], + "name": "SupplyCapSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + } + ], + "name": "deny", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainId_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint256", + "name": "supplyCap_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "move", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "pull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "usr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "push", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "guy", + "type": "address" + } + ], + "name": "rely", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "setSupplyCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "supplyCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainId_", + "type": "uint256" + } + ], + "name": "updateDomainSeparator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "wards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/MasterWombat.json b/src/adaptors/wombex-finance/abis/MasterWombat.json new file mode 100644 index 0000000000..b4a2f8544a --- /dev/null +++ b/src/adaptors/wombex-finance/abis/MasterWombat.json @@ -0,0 +1,1056 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + } + ], + "name": "Add", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositFor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "EmergencyWomWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + } + ], + "name": "SetRewarder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "basePartition", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boostedPartition", + "type": "uint256" + } + ], + "name": "UpdateEmissionPartition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "oldVeWOM", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVeWOM", + "type": "address" + } + ], + "name": "UpdateVeWOM", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "oldVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVoter", + "type": "address" + } + ], + "name": "UpdateVoter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "ACC_TOKEN_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IMultiRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "basePartition", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boostedPartition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "calRewardPerUnit", + "outputs": [ + { + "internalType": "uint256", + "name": "accWomPerShare", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accWomPerFactorShare", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "additionalRewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWomWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getAssetPid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_wom", + "type": "address" + }, + { + "internalType": "contract IVeWom", + "name": "_veWom", + "type": "address" + }, + { + "internalType": "address", + "name": "_voter", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_basePartition", + "type": "uint16" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_periodFinish", + "type": "uint256" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + } + ], + "name": "migrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_pids", + "type": "uint256[]" + } + ], + "name": "multiClaim", + "outputs": [ + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256[][]", + "name": "additionalRewards", + "type": "uint256[][]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingRewards", + "type": "uint256" + }, + { + "internalType": "contract IERC20[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "pendingBonusRewards", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "allocPoint", + "type": "uint96" + }, + { + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "sumOfFactors", + "type": "uint256" + }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "poolInfoV3", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint40", + "name": "periodFinish", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "sumOfFactors", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRate", + "type": "uint128" + }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "rewarderBonusTokenInfo", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMasterWombatV3", + "name": "_newMasterWombat", + "type": "address" + } + ], + "name": "setNewMasterWombat", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "contract IMultiRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "setRewarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IVeWom", + "name": "_newVeWom", + "type": "address" + } + ], + "name": "setVeWom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newVoter", + "type": "address" + } + ], + "name": "setVoter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_basePartition", + "type": "uint16" + } + ], + "name": "updateEmissionPartition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_newVeWomBalance", + "type": "uint256" + } + ], + "name": "updateFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "factor", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardDebt", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "pendingWom", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "veWom", + "outputs": [ + { + "internalType": "contract IVeWom", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "additionalRewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wom", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/PancakeRouter.json b/src/adaptors/wombex-finance/abis/PancakeRouter.json new file mode 100644 index 0000000000..c1d05c2c79 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/PancakeRouter.json @@ -0,0 +1,973 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountADesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountTokenDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETHSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapETHForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/wombex-finance/abis/Rewarder.json b/src/adaptors/wombex-finance/abis/Rewarder.json new file mode 100644 index 0000000000..a19e464bc2 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Rewarder.json @@ -0,0 +1,417 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_master", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startTimestamp", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "OnReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRate", + "type": "uint256" + } + ], + "name": "RewardRateUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "name": "addRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "balances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances_", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "emergencyTokenWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "master", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_lpAmount", + "type": "uint256" + } + ], + "name": "onReward", + "outputs": [ + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "rewards", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rewardInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "distributedAmount", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "_tokenPerSec", + "type": "uint96" + } + ], + "name": "setRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userInfo", + "outputs": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardDebt", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "unpaidRewards", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/adaptors/wombex-finance/abis/Router.json b/src/adaptors/wombex-finance/abis/Router.json new file mode 100644 index 0000000000..3d4ca741f8 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/Router.json @@ -0,0 +1,973 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountADesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountTokenDesired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "addLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveOut", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsIn", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + } + ], + "name": "getAmountsOut", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveB", + "type": "uint256" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETH", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "removeLiquidityETHSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountTokenMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountETHMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountETH", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountAMin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountBMin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "approveMax", + "type": "bool" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "removeLiquidityWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "amountA", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountB", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapETHForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactETHForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForETHSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactETH", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/VoterProxy.json b/src/adaptors/wombex-finance/abis/VoterProxy.json new file mode 100644 index 0000000000..5481e193c7 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/VoterProxy.json @@ -0,0 +1,749 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributeReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "baseAllocation", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "votePartition", + "type": "uint256" + } + ], + "name": "UpdateEmissionPartition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "UpdateVote", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IGauge", + "name": "_gaugeManager", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IBribe", + "name": "_bribe", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "baseAllocation", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseIndex", + "outputs": [ + { + "internalType": "uint104", + "name": "", + "type": "uint104" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "_lpTokens", + "type": "address[]" + } + ], + "name": "claimBribes", + "outputs": [ + { + "internalType": "uint256[][]", + "name": "bribeRewards", + "type": "uint256[][]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWomWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "firstEpochStartTime", + "outputs": [ + { + "internalType": "uint40", + "name": "", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "getUserVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "infos", + "outputs": [ + { + "internalType": "uint104", + "name": "supplyBaseIndex", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "supplyVoteIndex", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "nextEpochStartTime", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "claimable", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "whitelist", + "type": "bool" + }, + { + "internalType": "contract IGauge", + "name": "gaugeManager", + "type": "address" + }, + { + "internalType": "contract IBribe", + "name": "bribe", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_wom", + "type": "address" + }, + { + "internalType": "contract IVe", + "name": "_veWom", + "type": "address" + }, + { + "internalType": "uint88", + "name": "_womPerSec", + "type": "uint88" + }, + { + "internalType": "uint40", + "name": "_startTimestamp", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "_firstEpochStartTime", + "type": "uint40" + }, + { + "internalType": "uint16", + "name": "_baseAllocation", + "type": "uint16" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTimestamp", + "outputs": [ + { + "internalType": "uint40", + "name": "", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpTokenLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "lpTokens", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "pauseVoteEmission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "_lpTokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "pendingBribes", + "outputs": [ + { + "internalType": "contract IERC20[][]", + "name": "bribeTokenAddresses", + "type": "address[][]" + }, + { + "internalType": "string[][]", + "name": "bribeTokenSymbols", + "type": "string[][]" + }, + { + "internalType": "uint256[][]", + "name": "bribeRewards", + "type": "uint256[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "pendingWom", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "resumeAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + } + ], + "name": "resumeVoteEmission", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint128", + "name": "_allocPoint", + "type": "uint128" + } + ], + "name": "setAllocPoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_baseAllocation", + "type": "uint16" + } + ], + "name": "setBaseAllocation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IBribe", + "name": "_bribe", + "type": "address" + } + ], + "name": "setBribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IGauge", + "name": "_gaugeManager", + "type": "address" + } + ], + "name": "setGauge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint88", + "name": "_womPerSec", + "type": "uint88" + } + ], + "name": "setWomPerSec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWeight", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "veWom", + "outputs": [ + { + "internalType": "contract IVe", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "_lpVote", + "type": "address[]" + }, + { + "internalType": "int256[]", + "name": "_deltas", + "type": "int256[]" + } + ], + "name": "vote", + "outputs": [ + { + "internalType": "uint256[][]", + "name": "bribeRewards", + "type": "uint256[][]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "voteAllocation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voteIndex", + "outputs": [ + { + "internalType": "uint104", + "name": "", + "type": "uint104" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "votes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "name": "weights", + "outputs": [ + { + "internalType": "uint128", + "name": "allocPoint", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "voteWeight", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wom", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "womPerSec", + "outputs": [ + { + "internalType": "uint88", + "name": "", + "type": "uint88" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/WMXPOOL.json b/src/adaptors/wombex-finance/abis/WMXPOOL.json new file mode 100644 index 0000000000..23858ca091 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/WMXPOOL.json @@ -0,0 +1,363 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_receipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_totalSupply", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/wombex-finance/abis/crvRewards.json b/src/adaptors/wombex-finance/abis/crvRewards.json new file mode 100644 index 0000000000..d03b702db9 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/crvRewards.json @@ -0,0 +1,1383 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "pid_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "stakingToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "operator_", + "type": "address" + }, + { + "internalType": "address", + "name": "lptoken_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Donate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "currentRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRewards", + "type": "uint256" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "name": "RewardPaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "SetRewardTokenPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Staked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + } + ], + "name": "UpdateOperatorData", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NEW_REWARD_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allRewardTokens", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boosterRewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "claimableRewards", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "donate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "earned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_lockCvx", + "type": "bool" + } + ], + "name": "getReward", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "processIdleRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_rewards", + "type": "uint256" + } + ], + "name": "queueNewRewards", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokensLen", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokensList", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token_", + "type": "address" + }, + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "name": "setRewardTokenPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stake", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakeAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_for", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "stakeFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenRewards", + "outputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "periodFinish", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastUpdateTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "rewardPerTokenStored", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "queuedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "historicalRewards", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pid_", + "type": "uint256" + } + ], + "name": "updateOperatorData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userRewardPerTokenPaid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdrawAllAndUnwrap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "claim", + "type": "bool" + } + ], + "name": "withdrawAndUnwrap", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/wmx.json b/src/adaptors/wombex-finance/abis/wmx.json new file mode 100644 index 0000000000..bb32fc7463 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/wmx.json @@ -0,0 +1,489 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_proxy", + "type": "address" + }, + { + "internalType": "string", + "name": "_nameArg", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbolArg", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Initialised", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOperator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOperator", + "type": "address" + } + ], + "name": "OperatorChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "EMISSIONS_MAX_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INIT_MINT_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "getFactAmounMint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "minterMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reductionPerCliff", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalCliffs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vProxy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/abis/wombatPoolABI.json b/src/adaptors/wombex-finance/abis/wombatPoolABI.json new file mode 100644 index 0000000000..fce7a748e8 --- /dev/null +++ b/src/adaptors/wombex-finance/abis/wombatPoolABI.json @@ -0,0 +1,1313 @@ +[ + { + "inputs": [], + "name": "CORE_UNDERFLOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_AMOUNT_TOO_LOW", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_ALREADY_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_ALREADY_PAUSED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_NOT_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ASSET_NOT_PAUSED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_CASH_NOT_ENOUGH", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_COV_RATIO_LIMIT_EXCEEDED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_EXPIRED", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_FORBIDDEN", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_INVALID_VALUE", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_SAME_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_AMOUNT", + "type": "error" + }, + { + "inputs": [], + "name": "WOMBAT_ZERO_LIQUIDITY", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FillPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "PausedAsset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetAmpFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetDev", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lpDividendRatio", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "retentionRatio", + "type": "uint256" + } + ], + "name": "SetFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetFeeTo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetHaircutRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "SetMasterWombat", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SetMintFeeThreshold", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "TransferTipBucket", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "UnpausedAsset", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "addAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "addressOfAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ampFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumLiquidity", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "shouldStake", + "type": "bool" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dev", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "endCovRatio", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "exchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "xr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fillPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalEquilCovRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "equilCovRatio", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "invariantInUint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "haircutRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ampFactor_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircutRate_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lpDividendRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterWombat", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "mintFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintFeeThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "pauseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "int256", + "name": "toAmount", + "type": "int256" + } + ], + "name": "quoteAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "quotePotentialDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reward", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "int256", + "name": "fromAmount", + "type": "int256" + } + ], + "name": "quotePotentialSwap", + "outputs": [ + { + "internalType": "uint256", + "name": "potentialOutcome", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "name": "quotePotentialWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "name": "quotePotentialWithdrawFromOtherAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrewAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "removeAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "retentionRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ampFactor_", + "type": "uint256" + } + ], + "name": "setAmpFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "startCovRatio_", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "endCovRatio_", + "type": "uint128" + } + ], + "name": "setCovRatioFeeParam", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dev_", + "type": "address" + } + ], + "name": "setDev", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lpDividendRatio_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "retentionRatio_", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "feeTo_", + "type": "address" + } + ], + "name": "setFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "haircutRate_", + "type": "uint256" + } + ], + "name": "setHaircutRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "masterWombat_", + "type": "address" + } + ], + "name": "setMasterWombat", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mintFeeThreshold_", + "type": "uint256" + } + ], + "name": "setMintFeeThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startCovRatio", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumToAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "actualToAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "haircut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "tipBucketBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferTipBucket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "unpauseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "withdrawFromOtherAsset", + "outputs": [ + { + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wombex-finance/config.js b/src/adaptors/wombex-finance/config.js new file mode 100644 index 0000000000..f99533350e --- /dev/null +++ b/src/adaptors/wombex-finance/config.js @@ -0,0 +1,76 @@ +module.exports = { + bsc: { + booster: "0x561050ffb188420d2605714f84eda714da58da69", + wmx: "0xa75d9ca2a0a1D547409D82e1B06618EC284A2CeD", + wmxwom: "0x0415023846Ff1C6016c4d9621de12b24B2402979", + wom: "0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1", + pancake: "0x10ED43C718714eb63d5aA57B78B54704E256024E", + busd: "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", + endpoint_pool_map: { + '0x2Ea772346486972E7690219c190dAdDa40Ac5dA4': '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + '0x8df1126de13bcfef999556899F469d64021adBae': '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + '0xB0219A90EF6A24a237bC038f7B7a6eAc5e01edB0': '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + '0x05f727876d7C123B9Bb41507251E2Afd81EAD09A': '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + '0x4dFa92842d05a790252A7f374323b9C86D7b7E12': '0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5', + '0x312Bc7eAAF93f1C60Dc5AfC115FcCDE161055fb0': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + '0x0520451B19AD0bb00eD35ef391086A692CFC74B2': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + '0x48f6A8a0158031BaF8ce3e45344518f1e69f2A14': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + '0x8ad47d7ab304272322513eE63665906b64a49dA2': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + '0x277E777F7687239B092c8845D4d2cd083a33C903': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + + }, //pool->ept map equivalent to lens settings + lens_usd_stables: ['0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + '0x55d398326f99059fF775485246999027B3197955', + '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3', + '0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5', + '0x90C97F71E18723b0Cf0dfa30ee176Ab653E89F40', + '0x14016E85a25aeb13065688cAFB43044C2ef86784', + '0x4268B8F0B87b6Eae5d897996E6b845ddbD99Adf3', + '0xFa4BA88Cf97e282c505BEa095297786c16070129', + '0x0A3BB08b3a15A19b4De82F8AcFc862606FB69A2D', + '0xd17479997F34dd9156Deef8F95A52D81D265be9c'], + lens_misc_ept: ['0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1', '0xa75d9ca2a0a1D547409D82e1B06618EC284A2CeD', + '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'], + bribepools: ['0x4eb829fb1d7c9d14a214d26419bff94776853b91', + '0x24373cf57213874c989444d9712780d4cd7ee0bd', + '0x1623955a87dc65b19482864d7a1f7213f0e3e04a', + '0x5623ebb81b9a10ad599baca9a309f2c409fc498c', + '0xa140a78a0a2c4d7b2478c61c8f76f36e0c774c0f', + '0x20099484b891d3daf50c5bcf7bae885c50778eef', + '0x0161ab396d0e0441851c0b6a66de98e660d2cfcc', + '0x5fc1fcbb9cf1018a3af3b86ab9115e360589d0b7', + '0xaffeba56472e2067069e54343c3afa74a6a2af6e', + '0x6cf9e6662c269fdfe269d0c52ec1a01e8d51f987', + '0x844998cc12e87391c3405d73e4972d6c691f95bb', + '0x32abdf44b89efd0dd68d6688344083bb9be9a332', + '0xa26756a4962953f62f8e44d1aef83c121ae2f133', + '0x0caf10050f0af729416f4d52ab87b8bc43943e23', + '0xb8cd9d6f471ba2ff46dd4d16f63e5cc1c53020a1', + '0xb4df346bdc7180b0808af9238e782f9a3d885203', + '0xb18910a744dd35322f2cde65cd00a5ca716e1601' + ], + manual_eps: { '0xB0B195aEFA3650A6908f15CdaC7D92F8a5791B0B': '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' }, + tvl_corr: 1 //obsolete + }, + arbitrum: { + booster: "0x4181E561b42fDaD14c68b0794c215DeB9Bc80c8F", + wmx: "0x5190f06eacefa2c552dc6bd5e763b81c73293293", + wmxwom: "0xEfF2B1353Cdcaa2C3279C2bfdE72120c7FfB5E24", + wom: '0x7B5EB3940021Ec0e8e463D5dBB4B7B09a89DDF96', + pancake: "0xc873fEcbd354f5A56E00E710B90EF4201db2448d", //actually a camelot swap, but doesn't really matter + busd: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + endpoint_pool_map: { + '0x20D7ee728900848752FA280fAD51aF40c47302f1': '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, //pool->ept map equivalent to lens settings + lens_usd_stables: ['0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', + '0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F', + '0xB0B195aEFA3650A6908f15CdaC7D92F8a5791B0B' + ], + lens_misc_ept: ['0x5190F06EaceFA2C552dc6BD5e763b81C73293293', '0x7B5EB3940021Ec0e8e463D5dBB4B7B09a89DDF96',], + manual_eps: {}, + tvl_corr: '1' //obsolete + }, +}; diff --git a/src/adaptors/wombex-finance/index.js b/src/adaptors/wombex-finance/index.js new file mode 100644 index 0000000000..e5cff5d43b --- /dev/null +++ b/src/adaptors/wombex-finance/index.js @@ -0,0 +1,398 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); +const _ = require("lodash") +const BoosterABI = require('./abis/Booster.json'); +const MWABI = require('./abis/MasterWombat.json'); +const MRPSABI = require('./abis/Rewarder.json'); +const RouterABI = require('./abis/Router.json'); +const crvRewardsABI = require('./abis/crvRewards.json'); +const CoinABI = require('./abis/Coin.json'); +const AssetABI = require('./abis/Asset.json'); +const WMXPOOLABI = require('./abis/WMXPOOL.json'); +const pckswapABI = require('./abis/PancakeRouter.json'); +const voterProxyABI = require('./abis/VoterProxy.json'); +const bribeABI = require('./abis/Bribe.json'); +const wmxABI = require('./abis/wmx.json'); +const wombatPoolABI = require('./abis/wombatPoolABI.json'); +const wmxbribeABI = require('./abis/Bribewmx.json'); +const config = require('./config.js') +const slug = "wombex-finance"; +const one_eth = (BigNumber(10).pow(BigNumber(18))).valueOf() +const zeroAddress = '0x0000000000000000000000000000000000000000' +const secToYear = 365 * 24 * 60 * 60; + + +//version emulating the algorithm in the lens + +function formatEther(value, unit = 18) { + const result = BigNumber(value).div(BigNumber(10).pow(BigNumber(unit))); + return result.toString(); +} + +//get all pools +async function boosterPoolInfos(chain) { + booster = config[chain].booster; + len_pools = await sdk.api.abi.call({ + target: booster, + chain: chain, + abi: BoosterABI.find((n) => n.name === 'poolLength') + }).output; + +} +//estimate token price in USD (BUSD) using pancake/camelot/any uniswap-like router +async function tokenToBUSD(token, amount_in, chain) { + //a departure from the Lens contract, which estimates all stable usd tokens at 1/1 wrt usd + //since I don't want to multiply the amount of addresses to configure in config + //for the same reason (and because Arbi has no bnb), + //all tokens are routed directly to BUSD, with no tokens being routed with + //mediation of BNB, like e.g. ANKR in the BSC Lens. This will engender minor deviations in estimation + //though hopefully not as great as for my own method with hybrid price quoting + usdStables = config[chain].lens_usd_stables; + if (usdStables.includes(token)) { + return amount_in; + } + if (token in config[chain].manual_eps) { path = [token, config[chain].manual_eps[token], config[chain].busd]; } + else { path = [token, config[chain].busd]; } + try { + result = (await sdk.api.abi.call({ + target: config[chain].pancake, + chain: chain, + abi: RouterABI.find((n) => n.name === "getAmountsOut"), + params: [one_eth, path] + })).output.at(-1); + return result; + } + catch (error) { + console.log(error); + console.log(token); + } +} + +async function getLpUsdOut(pool, amt, chain) { + pem = config[chain].endpoint_pool_map; + tokenOut = zeroAddress; + if (pool in pem) { + tokenOut = pem[pool]; ans = await quoteWithdrawtoBUSD(pool, tokenOut, amt, chain); + return ans } + else { + usdStables = config[chain].lens_usd_stables; + miscEpt = config[chain].lens_misc_ept; + tokens = (await sdk.api.abi.call({ + target: pool, + chain: chain, + abi: wombatPoolABI.find((n) => n.name === 'getTokens') + })).output; + tokenOut = tokens.find((t) => usdStables.includes(t)); + if (tokenOut === undefined || tokenOut === zeroAddress) { + tokenOut = tokens.find((t) => miscEpt.includes(t)); + } + if (tokenOut === zeroAddress || tokenOut === undefined) { + console.log(`No endpoint token in pool ${pool}`); + return 0 + } + else { + ans = await quoteWithdrawtoBUSD(pool, tokenOut, amt, chain) + return ans + } + } +} + +async function quoteWithdrawtoBUSD(pool, tokenOut, amt, chain) { + try { + potentialWithdraw = (await sdk.api.abi.call({ + target: pool, + chain: chain, + abi: wombatPoolABI.find((n) => n.name === 'quotePotentialWithdraw'), + params: [tokenOut, amt] + })).output; + decs = (await sdk.api.abi.call({ + target: tokenOut, + chain: chain, + abi: CoinABI.find((n)=>n.name === 'decimals') + })).output; + potentialWithdraw.amount = (BigNumber(potentialWithdraw.amount).multipliedBy(BigNumber(one_eth)).dividedBy((BigNumber(10)).pow(BigNumber(decs)))).valueOf(); + return await tokenToBUSD(tokenOut, potentialWithdraw.amount, chain) + } + catch { return 0} +} + + +async function setApys(crvRewards, wmxUsdPrice, mintRatio, poolValuestvl, poolValues, chain) { + + rewardTokens = (await sdk.api.abi.call({ + target: crvRewards, + chain: chain, + abi: crvRewardsABI.find((n)=>n.name === 'rewardTokensList') + })).output; + + len = rewardTokens.length; + aprs = []; + aprTotal = BigNumber(0); + wmxApr = 0; + + for (let i = 0; i < len; i++) { + token = rewardTokens[i]; + + rewardState = (await sdk.api.abi.call({ + target: crvRewards, + chain: chain, + abi: crvRewardsABI.find((n) => n.name === 'tokenRewards'), + params: [token] + })).output; + decs = (await sdk.api.abi.call({ + target: config[chain].busd, + chain: chain, + abi: CoinABI.find((n) => n.name === 'decimals') + })).output; + if (token === config[chain].wom) { + rpy = (BigNumber(rewardState.rewardRate).multipliedBy(BigNumber(secToYear))) + //tofixed is an unholy hack, but utterly necessary here to avoid BigNumber value problems + factAmountMint = (await sdk.api.abi.call({ + target: config['bsc'].wmx, + chain: 'bsc', + abi: wmxABI.find((n) => n.name === 'getFactAmounMint'), + params: [rpy.toFixed()], + })).output; + //bsc chain is fixed above because on arbi the wmx token is a proxy of wormhole bridge + //and lacks functionaity like getfactamountmint + //wmx is not minted on arbi and is instead transferred there, just like e.g. cvx + wmxRate = factAmountMint; + if (mintRatio > 0) { + wmxRate = BigNumber(factAmountMint).multipliedBy(BigNumber(mintRatio)).dividedBy(BigNumber(10000)); + } + wmxApr = BigNumber(wmxRate).multipliedBy(BigNumber(wmxUsdPrice)).multipliedBy(BigNumber(100)).dividedBy(BigNumber(poolValuestvl)).dividedBy( + BigNumber(10).pow(BigNumber(decs)) + ); + aprTotal = aprTotal.plus(wmxApr); + aprs.push({ + 'token': config[chain].wmx, + 'apr': wmxApr.valueOf() + }) + } + usdPrice = await tokenToBUSD(token, one_eth, chain); + apr = BigNumber(rewardState.rewardRate).multipliedBy(BigNumber(secToYear)).multipliedBy(BigNumber(usdPrice)).multipliedBy(BigNumber(100)).dividedBy(BigNumber(poolValuestvl)).dividedBy( + BigNumber(10).pow(BigNumber(decs)) + ); + aprTotal = aprTotal.plus(apr); + aprs.push({ + 'token': token, + 'apr': apr.valueOf() + }) + } + return {'tokenAprs': aprs, 'totalApr': aprTotal.valueOf(), 'wmxApr': wmxApr.valueOf()} +} + +async function apy_chain(chain) { + //get pool amt + booster = config[chain].booster; + + len_pools = (await sdk.api.abi.call({ + target: booster, + chain: chain, + abi: BoosterABI.find((n) => n.name === 'poolLength') + })).output; + + mintRatio = (await sdk.api.abi.call({ + target: booster, + chain: chain, + abi: BoosterABI.find((n) => n.name === 'mintRatio'), + })).output; + + wmxUsdPrice = await tokenToBUSD(config[chain].wmx, one_eth, chain); + + all_apys = []; + + //iterate over pools + for (let i = 0; i < len_pools; i++) { + //get booster poolinfo + + pool_info = (await sdk.api.abi.call({ + target: booster, + chain: chain, + abi: BoosterABI.find((n) => n.name === 'poolInfo'), + params: i + })).output; + + crvRewards = pool_info.crvRewards; + + pool = (await sdk.api.abi.call({ + target: pool_info.lptoken, + chain: chain, + abi: AssetABI.find((n) => n.name === 'pool'), + })).output; + + poolValues = {}; + poolValues['pid'] = i; + + poolValues['symbol'] = (await sdk.api.abi.call({ + target: pool_info.lptoken, + chain: chain, + abi: AssetABI.find((n) => n.name === 'symbol'), + })).output; + + poolValues['rewardPool'] = crvRewards; + //compute tvl + poolValues['lpTokenPrice'] = await getLpUsdOut(pool, one_eth, chain); + + poolValues['lpTokenBalance'] = (await sdk.api.abi.call({ + target: crvRewards, + chain: chain, + abi: crvRewardsABI.find((n) => n.name === 'totalSupply'), + })).output; + + poolValues['tvl'] = (BigNumber(poolValues.lpTokenBalance).multipliedBy(BigNumber(poolValues.lpTokenPrice)).dividedBy(BigNumber(one_eth)).multipliedBy(BigNumber(config[chain].tvl_corr))).valueOf(); + + //compute apys of lp(!) pools + + if (poolValues.tvl > 10) { + const { tokenAprs, totalApr, wmxApr } = await setApys(crvRewards, wmxUsdPrice, mintRatio, (BigNumber(poolValues.tvl).dividedBy(BigNumber(config[chain].tvl_corr))).valueOf(), poolValues, chain); + poolValues['tokenAprs'] = tokenAprs; + poolValues['totalApr'] = totalApr; + poolValues['wmxApr'] = wmxApr; + } + poolValues['underlyingToken'] = ( + await sdk.api.abi.call({ + target: pool_info.lptoken, + chain: chain, + abi: AssetABI.find((n)=>n.name === 'underlyingToken') + }) + ).output; + all_apys.push(poolValues); + + } + return all_apys +} + + +async function apy_bribe_chain(chain) { + //gauge voting lens is not really usable for getting bribe apys + //since I have no use for current+historical rewards and am more interesting in reward rate + //for this reason, I implement my own algo (get reward rate /year and divide by total votes). Fight me + //note for self: don't forget to get the ratio of vevom balance of voterproxy and total supply of vlwmx + //bribepool rewardrate => bribepool reward per year + //wom votes of bribepool => wmx votes of bribepool => wmx votes of bribepool in usd + //bribepool reward per year in usd / wmx votes of bribepool in usd (by wmx prices) => apy + bribe_apys = []; + if (!('bribepools' in config[chain])) { + return bribe_apys + } + else { + bribepools = config[chain].bribepools; + for (let a of bribepools) { + //wmx bribepool rewardtokens - old config + rts = ( + await sdk.api.abi.call({ + target: a, + chain: chain, + abi: wmxbribeABI.find((n) => n.name === 'rewardTokensList') + }) + ).output; + aprs = []; + totalBribeApr = BigNumber(0); + votes = ( + await sdk.api.abi.call({ + target: a, + chain: chain, + abi: wmxbribeABI.find((n) => n.name === 'totalSupply') + }) + ).output; //totalSupply coincides with vlwmx balance of bribe pool + for (let rt of rts) { + //go over all reward tokens + //get tokenRewards + trwd = ( + await sdk.api.abi.call({ + target: a, + chain: chain, + abi: wmxbribeABI.find((n) => n.name === 'tokenRewards'), + params: [rt] + }) + ).output; + if (trwd.paused === true) { + continue; //ignore paused bribes + } + rrate = trwd.rewardRate; + rrate_usd = await tokenToBUSD(rt, rrate, chain); + aux = await tokenToBUSD(rt, one_eth, chain) + rrate_usd = BigNumber(aux).multipliedBy(BigNumber(rrate)).dividedBy(BigNumber(one_eth)) + rpy = BigNumber(rrate_usd).multipliedBy(BigNumber(secToYear)); + aux = await tokenToBUSD(rt, one_eth, chain) + vlwmxUsdPrice = await tokenToBUSD(config[chain].wmx, one_eth, chain); + votesUsd = BigNumber(vlwmxUsdPrice).multipliedBy(BigNumber(votes)).dividedBy(BigNumber(one_eth)); + apy = rpy.dividedBy(BigNumber(votesUsd)); + aprs.push({ + 'token': rt, + 'apr': apy, + 'rpy': rpy, + }) + totalBribeApr = totalBribeApr.plus(apy); + } + if (Number(formatEther(votesUsd))>0) { + bribe_apys.push({ + 'pool': a, + 'rewardTokens': rts, + 'rewardAprs': aprs, + 'totalApr': totalBribeApr.valueOf(), + 'tvlVotes': formatEther(votesUsd), + 'underlyingTokens': [config[chain].wmx], + 'rpys': aprs.map(a => formatEther(a.rpy)), + 'symbol': (await sdk.api.abi.call({ + target: a, + chain: chain, + abi: wmxbribeABI.find((n)=>n.name === 'symbol') + })).output.slice(3) + }) + } + } + } + return bribe_apys +} + +async function apy() { + apy_export = [] + + for (chain in config) { + a = await apy_chain(chain); + bribes = await apy_bribe_chain(chain); + //got raw apy data, make it conform to defillama specs + a.map(a => { + if (Number(formatEther(a.tvl)) > 0 && Number(a.wmxApr) > 0) { + apy_export.push({ + 'pool': a.rewardPool + `-${chain}`, + 'chain': chain, + 'project': slug, + 'symbol': a.symbol.slice(3), + 'tvlUsd': Number(formatEther(a.tvl)), + 'apyReward': Number(a.totalApr), + 'rewardTokens': a.tokenAprs.map(b => { return b.token }), + 'underlyingTokens': [a.underlyingToken], + 'poolMeta': 'LP Pool', + 'url': 'wombex.finance' + }) + } + }) + bribes.map(bribe => { + apy_export.push({ + 'pool': 'vlWMX-'+bribe.pool + `-${chain}`, + 'chain': chain, + 'project': slug, + 'symbol': bribe.symbol, + 'tvlUsd': Number(bribe.tvlVotes), + 'apyReward': 100*Number(bribe.totalApr), + 'rewardTokens': bribe.rewardAprs.map(b => { return b.token }), + 'underlyingTokens': bribe.underlyingTokens, + 'poolMeta': 'Bribe Pool', + 'url': 'wombex.finance' + }) + }) + + } + //got raw apy data, make it conform to defillama specs + + return apy_export +} + +module.exports = { + timetravel: false, + apy, +}; \ No newline at end of file diff --git a/src/adaptors/wompie/abis/MagpieReader.json b/src/adaptors/wompie/abis/MagpieReader.json new file mode 100644 index 0000000000..92d8dba4e3 --- /dev/null +++ b/src/adaptors/wompie/abis/MagpieReader.json @@ -0,0 +1,1557 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "BUSD", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WBNB", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMasterMagpieReader", + "name": "_masterMagpie", + "type": "address" + }, + { + "internalType": "contract IWombatBribeManagerReader", + "name": "_wombatBribeManager", + "type": "address" + }, + { + "internalType": "contract IPancakeRouter02Reader", + "name": "_pancakeRouter02", + "type": "address" + }, + { + "internalType": "contract IWombatRouterReader", + "name": "_wombatRouter", + "type": "address" + } + ], + "name": "__MagpieReader_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "priceAddress", + "type": "address" + } + ], + "name": "addTokenChainlink", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "paths", + "type": "address[]" + } + ], + "name": "addTokenPancakeRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address[]", + "name": "paths", + "type": "address[]" + }, + { + "internalType": "address[]", + "name": "pools", + "type": "address[]" + } + ], + "name": "addTokenWombatRouter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "poolType", + "type": "string" + } + ], + "name": "addWombatPoolType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllTokenPrice", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.TokenPrice[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBNBPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBUSDPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBribeInfo", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "bribeCallerFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bribeProtocolFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "usedVote", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalVlMgpInVote", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "lpAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "lpSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "string", + "name": "underlyingTokenSymbol", + "type": "string" + }, + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalVoteInVlmgp", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "uint104", + "name": "supplyBaseIndex", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "supplyVoteIndex", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "nextEpochStartTime", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "claimable", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "whitelist", + "type": "bool" + }, + { + "internalType": "contract IWombatGauge", + "name": "gaugeManager", + "type": "address" + }, + { + "internalType": "contract IWombatBribeReader", + "name": "bribe", + "type": "address" + }, + { + "internalType": "uint128", + "name": "allocPoint", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "voteWeight", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "wombatStakingUserVotes", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "contract IERC20", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "distributedAmount", + "type": "uint128" + } + ], + "internalType": "struct MagpieReader.BribePoolReward[]", + "name": "rewardList", + "type": "tuple[]" + } + ], + "internalType": "struct MagpieReader.BribePool[]", + "name": "pools", + "type": "tuple[]" + } + ], + "internalType": "struct MagpieReader.BribeInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getETHPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getMagpieInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "wom", + "type": "address" + }, + { + "internalType": "address", + "name": "mgp", + "type": "address" + }, + { + "internalType": "address", + "name": "vlmgp", + "type": "address" + }, + { + "internalType": "address", + "name": "mWom", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.TokenPrice[]", + "name": "tokenPriceList", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accMGPPerShare", + "type": "uint256" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "helper", + "type": "address" + }, + { + "internalType": "bool", + "name": "helperNeedsHarvest", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "emission", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sizeOfPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPoint", + "type": "uint256" + }, + { + "internalType": "string", + "name": "poolType", + "type": "string" + }, + { + "internalType": "string", + "name": "stakingTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "stakingTokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolTokenPrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isWombatPool", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isMPGRewardPool", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "depositToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lpAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "receiptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "helper", + "type": "address" + }, + { + "internalType": "address", + "name": "depositTarget", + "type": "address" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPoolFeeFree", + "type": "bool" + } + ], + "internalType": "struct MagpieReader.WombatStakingPool", + "name": "wombatStakingPool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint40", + "name": "periodFinish", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "sumOfFactors", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRateToMgp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "boostedEffect", + "type": "uint128" + }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "wombatStakingUserAmount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "wombatStakingUserFactor", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "distributedAmount", + "type": "uint128" + }, + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "rewardTokenDecimals", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.WombatV3PoolReward[]", + "name": "rewardList", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "string", + "name": "poolType", + "type": "string" + }, + { + "internalType": "uint256", + "name": "assetCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetLiability", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.WombatV3Pool", + "name": "wombatV3Pool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isNative", + "type": "bool" + }, + { + "internalType": "address", + "name": "depositToken", + "type": "address" + }, + { + "internalType": "string", + "name": "depositTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "depositTokenDecimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + } + ], + "internalType": "struct MagpieReader.WombatPoolHelperInfo", + "name": "wombatHelperInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "pendingMGP", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "pendingBonusRewards", + "type": "uint256[]" + } + ], + "internalType": "struct MagpieReader.MagpieRewardInfo", + "name": "rewardInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stakingAllowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableAmount", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.MagpieAccountInfo", + "name": "accountInfo", + "type": "tuple" + } + ], + "internalType": "struct MagpieReader.MagpiePool[]", + "name": "pools", + "type": "tuple[]" + } + ], + "internalType": "struct MagpieReader.MagpieInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getMagpiePoolInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accMGPPerShare", + "type": "uint256" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "helper", + "type": "address" + }, + { + "internalType": "bool", + "name": "helperNeedsHarvest", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "emission", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sizeOfPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPoint", + "type": "uint256" + }, + { + "internalType": "string", + "name": "poolType", + "type": "string" + }, + { + "internalType": "string", + "name": "stakingTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "stakingTokenDecimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolTokenPrice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isWombatPool", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isMPGRewardPool", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "depositToken", + "type": "address" + }, + { + "internalType": "address", + "name": "lpAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "receiptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "helper", + "type": "address" + }, + { + "internalType": "address", + "name": "depositTarget", + "type": "address" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPoolFeeFree", + "type": "bool" + } + ], + "internalType": "struct MagpieReader.WombatStakingPool", + "name": "wombatStakingPool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "uint40", + "name": "periodFinish", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "sumOfFactors", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rewardRateToMgp", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "boostedEffect", + "type": "uint128" + }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + }, + { + "internalType": "uint128", + "name": "wombatStakingUserAmount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "wombatStakingUserFactor", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint96", + "name": "tokenPerSec", + "type": "uint96" + }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "distributedAmount", + "type": "uint128" + }, + { + "internalType": "string", + "name": "rewardTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "rewardTokenDecimals", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.WombatV3PoolReward[]", + "name": "rewardList", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "string", + "name": "poolType", + "type": "string" + }, + { + "internalType": "uint256", + "name": "assetCash", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetLiability", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.WombatV3Pool", + "name": "wombatV3Pool", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "isNative", + "type": "bool" + }, + { + "internalType": "address", + "name": "depositToken", + "type": "address" + }, + { + "internalType": "string", + "name": "depositTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "depositTokenDecimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + } + ], + "internalType": "struct MagpieReader.WombatPoolHelperInfo", + "name": "wombatHelperInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "pendingMGP", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "pendingBonusRewards", + "type": "uint256[]" + } + ], + "internalType": "struct MagpieReader.MagpieRewardInfo", + "name": "rewardInfo", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stakingAllowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableAmount", + "type": "uint256" + } + ], + "internalType": "struct MagpieReader.MagpieAccountInfo", + "name": "accountInfo", + "type": "tuple" + } + ], + "internalType": "struct MagpieReader.MagpiePool", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unitPrice", + "type": "uint256" + } + ], + "name": "getTokenPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mWom", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterMagpie", + "outputs": [ + { + "internalType": "contract IMasterMagpieReader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterWombatV3", + "outputs": [ + { + "internalType": "contract IMasterWombatV3Reader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mgp", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pancakeRouter02", + "outputs": [ + { + "internalType": "contract IPancakeRouter02Reader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "reInit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "magpiePoolId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "status", + "type": "uint256" + } + ], + "name": "setMagpieWombatPoolStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tokenList", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenRouterMap", + "outputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chainlink", + "type": "address" + }, + { + "internalType": "uint256", + "name": "routerType", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vlmgp", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "voter", + "outputs": [ + { + "internalType": "contract IWombatVoter", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wom", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wombatBribeManager", + "outputs": [ + { + "internalType": "contract IWombatBribeManagerReader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "wombatPoolStatus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "wombatPoolType", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wombatRouter", + "outputs": [ + { + "internalType": "contract IWombatRouterReader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "wombatStaking", + "outputs": [ + { + "internalType": "contract IWombatStakingReader", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wompie/abis/MasterMagpie.json b/src/adaptors/wompie/abis/MasterMagpie.json new file mode 100644 index 0000000000..1c041cdfc2 --- /dev/null +++ b/src/adaptors/wompie/abis/MasterMagpie.json @@ -0,0 +1,1256 @@ +[ + { + "inputs": [], + "name": "InvalidStakingToken", + "type": "error" + }, + { + "inputs": [], + "name": "MGPsetAlready", + "type": "error" + }, + { + "inputs": [], + "name": "MustBeContract", + "type": "error" + }, + { + "inputs": [], + "name": "MustBeContractOrZero", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyActivePool", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCompounder", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPoolHelper", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPoolManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyVlMgp", + "type": "error" + }, + { + "inputs": [], + "name": "PoolExsisted", + "type": "error" + }, + { + "inputs": [], + "name": "UnlockAmountExceedsLocked", + "type": "error" + }, + { + "inputs": [], + "name": "WithdrawAmountExceedsStaked", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IBaseRewardPool", + "name": "_rewarder", + "type": "address" + } + ], + "name": "Add", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newCompounder", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_oldCompounder", + "type": "address" + } + ], + "name": "CompounderUpated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "DepositNotAvailable", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isLock", + "type": "bool" + } + ], + "name": "HarvestMGP", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_isRewardMGP", + "type": "bool" + } + ], + "name": "LockFreePoolUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_mgp", + "type": "address" + } + ], + "name": "MGPSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_status", + "type": "bool" + } + ], + "name": "PoolManagerStatus", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IBaseRewardPool", + "name": "_rewarder", + "type": "address" + } + ], + "name": "Set", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_oldMgpPerSec", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newMgpPerSec", + "type": "uint256" + } + ], + "name": "UpdateEmissionRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_lastRewardTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_accMGPPerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_newVlmgp", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_oldVlmgp", + "type": "address" + } + ], + "name": "VLMGPUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "MPGRewardPool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "PoolManagers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_mgp", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_mgpPerSec", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_startTimestamp", + "type": "uint256" + } + ], + "name": "__MasterMagpie_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_helper", + "type": "address" + }, + { + "internalType": "bool", + "name": "_helperNeedsHarvest", + "type": "bool" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "allPendingTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingMGP", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "pendingBonusRewards", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "compounder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "mainRewardToken", + "type": "address" + } + ], + "name": "createRewarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_for", + "type": "address" + } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_for", + "type": "address" + } + ], + "name": "depositVlMGPFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + } + ], + "name": "getPoolInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "emission", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocpoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sizeOfPool", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalPoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mgp", + "outputs": [ + { + "internalType": "contract MGP", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mgpPerSec", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_stakingTokens", + "type": "address[]" + } + ], + "name": "multiclaim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_stakingTokens", + "type": "address[]" + }, + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "multiclaimOnBehalf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingMGP", + "type": "uint256" + }, + { + "internalType": "address", + "name": "bonusTokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "bonusTokenSymbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "pendingBonusToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "registeredToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + } + ], + "name": "rewarderBonusTokenInfo", + "outputs": [ + { + "internalType": "address[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_allocPoint", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_helper", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewarder", + "type": "address" + }, + { + "internalType": "bool", + "name": "_helperNeedsHarvest", + "type": "bool" + } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_compounder", + "type": "address" + } + ], + "name": "setCompounder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isLockFree", + "type": "bool" + } + ], + "name": "setMGPRewardPools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_mgp", + "type": "address" + } + ], + "name": "setMgp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "bool", + "name": "_allowedManager", + "type": "bool" + } + ], + "name": "setPoolManagerStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_vlmgp", + "type": "address" + } + ], + "name": "setVlmgp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "stakingInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "availableAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "tokenToPoolInfo", + "outputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accMGPPerShare", + "type": "uint256" + }, + { + "internalType": "address", + "name": "rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "helper", + "type": "address" + }, + { + "internalType": "bool", + "name": "helperNeedsHarvest", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_mgpPerSec", + "type": "uint256" + } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vlmgp", + "outputs": [ + { + "internalType": "contract IVLMGP", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_for", + "type": "address" + } + ], + "name": "withdrawFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_for", + "type": "address" + } + ], + "name": "withdrawVlMGPFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wompie/abis/MasterWombat.json b/src/adaptors/wompie/abis/MasterWombat.json new file mode 100644 index 0000000000..bb204f0457 --- /dev/null +++ b/src/adaptors/wompie/abis/MasterWombat.json @@ -0,0 +1,768 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + } + ], + "name": "Add", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositFor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EmergencyWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "name": "EmergencyWomWithdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "allocPoint", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "overwrite", + "type": "bool" + } + ], + "name": "Set", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "basePartition", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "boostedPartition", + "type": "uint256" + } + ], + "name": "UpdateEmissionPartition", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "womPerSec", + "type": "uint256" + } + ], + "name": "UpdateEmissionRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lastRewardTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lpSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accWomPerShare", + "type": "uint256" + } + ], + "name": "UpdatePool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "oldVeWOM", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newVeWOM", + "type": "address" + } + ], + "name": "UpdateVeWOM", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "pid", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "uint96", "name": "_allocPoint", "type": "uint96" }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "contract IMultiRewarder", + "name": "_rewarder", + "type": "address" + } + ], + "name": "add", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "basePartition", + "outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boostedPartition", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "deposit", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWomWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getAssetPid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "contract IERC20", "name": "_wom", "type": "address" }, + { + "internalType": "contract IVeWom", + "name": "_veWom", + "type": "address" + }, + { "internalType": "uint104", "name": "_womPerSec", "type": "uint104" }, + { "internalType": "uint16", "name": "_basePartition", "type": "uint16" }, + { "internalType": "uint40", "name": "_startTimestamp", "type": "uint40" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "massUpdatePools", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_pids", "type": "uint256[]" } + ], + "name": "migrate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256[]", "name": "_pids", "type": "uint256[]" } + ], + "name": "multiClaim", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, + { "internalType": "uint256[][]", "name": "", "type": "uint256[][]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "pendingTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingRewards", + "type": "uint256" + }, + { + "internalType": "contract IERC20[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + }, + { + "internalType": "uint256[]", + "name": "pendingBonusRewards", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "poolInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "lpToken", + "type": "address" + }, + { "internalType": "uint96", "name": "allocPoint", "type": "uint96" }, + { + "internalType": "contract IMultiRewarder", + "name": "rewarder", + "type": "address" + }, + { "internalType": "uint256", "name": "sumOfFactors", "type": "uint256" }, + { + "internalType": "uint104", + "name": "accWomPerShare", + "type": "uint104" + }, + { + "internalType": "uint104", + "name": "accWomPerFactorShare", + "type": "uint104" + }, + { + "internalType": "uint40", + "name": "lastRewardTimestamp", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "rewarderBonusTokenInfo", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "bonusTokenAddresses", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "bonusTokenSymbols", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint96", "name": "_allocPoint", "type": "uint96" }, + { + "internalType": "contract IMultiRewarder", + "name": "_rewarder", + "type": "address" + }, + { "internalType": "bool", "name": "overwrite", "type": "bool" } + ], + "name": "set", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IMasterWombatV2", + "name": "_newMasterWombat", + "type": "address" + } + ], + "name": "setNewMasterWombat", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IVeWom", + "name": "_newVeWom", + "type": "address" + } + ], + "name": "setVeWom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [{ "internalType": "uint40", "name": "", "type": "uint40" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalAllocPoint", + "outputs": [{ "internalType": "uint96", "name": "", "type": "uint96" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint16", "name": "_basePartition", "type": "uint16" } + ], + "name": "updateEmissionPartition", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint104", "name": "_womPerSec", "type": "uint104" } + ], + "name": "updateEmissionRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { + "internalType": "uint256", + "name": "_newVeWomBalance", + "type": "uint256" + } + ], + "name": "updateFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" } + ], + "name": "updatePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userInfo", + "outputs": [ + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "uint128", "name": "factor", "type": "uint128" }, + { "internalType": "uint128", "name": "rewardDebt", "type": "uint128" }, + { "internalType": "uint128", "name": "pendingWom", "type": "uint128" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "veWom", + "outputs": [ + { "internalType": "contract IVeWom", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_pid", "type": "uint256" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256[]", "name": "", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wom", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "womPerSec", + "outputs": [{ "internalType": "uint104", "name": "", "type": "uint104" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/adaptors/wompie/abis/MultiRewarderPerSec.json b/src/adaptors/wompie/abis/MultiRewarderPerSec.json new file mode 100644 index 0000000000..f25143d2da --- /dev/null +++ b/src/adaptors/wompie/abis/MultiRewarderPerSec.json @@ -0,0 +1,292 @@ +[ + { + "inputs": [ + { + "internalType": "contract IMasterWombat", + "name": "_MP", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_startTimestamp", + "type": "uint256" + }, + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { "internalType": "uint96", "name": "_tokenPerSec", "type": "uint96" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "OnReward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newRate", + "type": "uint256" + } + ], + "name": "RewardRateUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_rewardToken", + "type": "address" + }, + { "internalType": "uint96", "name": "_tokenPerSec", "type": "uint96" } + ], + "name": "addRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "balances", + "outputs": [ + { "internalType": "uint256[]", "name": "balances_", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "emergencyTokenWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "emergencyWithdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTimestamp", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterWombat", + "outputs": [ + { + "internalType": "contract IMasterWombat", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" }, + { "internalType": "uint256", "name": "_lpAmount", "type": "uint256" } + ], + "name": "onReward", + "outputs": [ + { "internalType": "uint256[]", "name": "rewards", "type": "uint256[]" } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "operator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "pendingTokens", + "outputs": [ + { "internalType": "uint256[]", "name": "rewards", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "rewardInfo", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "rewardToken", + "type": "address" + }, + { "internalType": "uint96", "name": "tokenPerSec", "type": "uint96" }, + { + "internalType": "uint128", + "name": "accTokenPerShare", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardLength", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_operator", "type": "address" } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint96", "name": "_tokenPerSec", "type": "uint96" } + ], + "name": "setRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "userInfo", + "outputs": [ + { "internalType": "uint128", "name": "amount", "type": "uint128" }, + { "internalType": "uint128", "name": "rewardDebt", "type": "uint128" }, + { "internalType": "uint256", "name": "unpaidRewards", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } +] diff --git a/src/adaptors/wompie/abis/WombatPoolHelper.json b/src/adaptors/wompie/abis/WombatPoolHelper.json new file mode 100644 index 0000000000..e84bc88f5c --- /dev/null +++ b/src/adaptors/wompie/abis/WombatPoolHelper.json @@ -0,0 +1,346 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_pid", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_lpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_wombatStaking", + "type": "address" + }, + { + "internalType": "address", + "name": "_masterMagpie", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_mWom", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isNative", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "NotNativeToken", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "NewDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "NewLpDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "NewWithdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minimumLiquidity", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lpAmount", + "type": "uint256" + } + ], + "name": "depositLP", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minimumLiquidity", + "type": "uint256" + } + ], + "name": "depositNative", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "harvest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isNative", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mWom", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterMagpie", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingWom", + "outputs": [ + { + "internalType": "uint256", + "name": "pendingTokens", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stakingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_liquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wombatStaking", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/wompie/config.js b/src/adaptors/wompie/config.js new file mode 100644 index 0000000000..27bb0cdb15 --- /dev/null +++ b/src/adaptors/wompie/config.js @@ -0,0 +1,26 @@ +module.exports = [ + { + chain: "bsc", + contract: { + MasterMagpieAddress: "0xa3B615667CBd33cfc69843Bf11Fbb2A1D926BD46", + MagpieReaderAddress: "0x0E7EB5fb8d4e1e9C872ebF7072383cf97434D2e2", + VlMGPAddress: "0x9B69b06272980FA6BAd9D88680a71e3c3BeB32c6", + MWOMSVAddress: "0x0000000000000000000000000000000000000000", + MGPAddress: "0xD06716E1Ff2E492Cc5034c2E81805562dd3b45fa", + WOMAddress: "0xAD6742A35fB341A9Cc6ad674738Dd8da98b94Fb1", + MWOMAddress: "0x027a9d301FB747cd972CFB29A63f3BDA551DFc5c", + }, + }, + { + chain: "arbitrum", + contract: { + MasterMagpieAddress: "0x664cc2BcAe1E057EB1Ec379598c5B743Ad9Db6e7", + MagpieReaderAddress: "0x5833b55498bE2689B1789De53d1b76CDF9ABE0c2", + VlMGPAddress: "0x536599497Ce6a35FC65C7503232Fec71A84786b9", + MWOMSVAddress: "0x21804FB90593458630298f10a85094cb6d3B07Db", + MGPAddress: "0xa61F74247455A40b01b0559ff6274441FAfa22A3", + WOMAddress: "0x7B5EB3940021Ec0e8e463D5dBB4B7B09a89DDF96", + MWOMAddress: "0x509FD25EE2AC7833a017f17Ee8A6Fb4aAf947876", + }, + }, +]; \ No newline at end of file diff --git a/src/adaptors/wompie/index.js b/src/adaptors/wompie/index.js new file mode 100644 index 0000000000..d4f2f2d419 --- /dev/null +++ b/src/adaptors/wompie/index.js @@ -0,0 +1,421 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); +const _ = require('lodash'); + +const MagpieReaderABI = require('./abis/MagpieReader.json'); +const config = require('./config'); + +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + +function formatEther(value, unit = 18) { + const result = BigNumber(value).div(BigNumber(10).pow(BigNumber(unit))); + return result.toString(); +} + +async function getMagpieInfo() { + const infos = []; + for (let conf of config) { + const result = ( + await sdk.api.abi.call({ + target: conf.contract.MagpieReaderAddress, + chain: conf.chain, + abi: MagpieReaderABI.find((n) => n.name === 'getMagpieInfo'), + params: [ZERO_ADDRESS], + }) + ).output; + infos.push({ + chain: conf.chain, + masterMagpie: conf.contract.MasterMagpieAddress, + result: result, + }); + } + + return infos; +} + +async function apy() { + const magpieInfos = await getMagpieInfo(); + const poolAprList = []; + + for (let info of magpieInfos) { + const magpieInfo = info.result; + const mgpAddress = magpieInfo.mgp; + const vlmgpAddress = magpieInfo.vlmgp; + const womAddress = magpieInfo.wom; + + const priceData = {}; + for (let item of magpieInfo.tokenPriceList) { + priceData[item.symbol.toUpperCase()] = Number(formatEther(item.price)); + } + priceData['VLMGP'] = priceData['MGP']; + priceData['MWOM'] = priceData['WOM']; + priceData['MWOMSV'] = priceData['WOM']; + const wombatRewardTokens = []; + wombatRewardTokens.push({ + symbol: 'WOM', + tokenPerSec: 0, + address: womAddress, + }); + + let poolInfos = []; + + for (let i = 0, l = magpieInfo.pools.length; i < l; i++) { + const rawInfo = magpieInfo.pools[i]; + if (rawInfo.isActive === false) { + continue; + } + const pool = { + type: rawInfo.poolType, + poolId: Number(rawInfo.poolId), + isNative: + rawInfo.poolType === 'WOMBAT_POOL' + ? rawInfo.wombatHelperInfo.isNative + : false, + wombatPoolType: + rawInfo.poolType === 'WOMBAT_POOL' && rawInfo.isActive + ? rawInfo.wombatV3Pool.poolType.replace(' ', '_').toUpperCase() + : '', + helper: rawInfo.helper, + isActive: rawInfo.isActive, + helperNeedsHarvest: rawInfo.helperNeedsHarvest, + locker: + rawInfo.poolType === 'MAGPIE_VLMGP_POOL' + ? rawInfo.helper + : ZERO_ADDRESS, + rawStakingToken: rawInfo.stakingToken, + stakingToken: + rawInfo.poolType === 'WOMBAT_POOL' + ? rawInfo.wombatHelperInfo.depositToken + : rawInfo.poolType === 'MAGPIE_VLMGP_POOL' + ? mgpAddress + : rawInfo.stakingToken, + rewarder: rawInfo.rewarder, + isPoolFeeFree: + rawInfo.poolType === 'WOMBAT_POOL' && rawInfo.isActive + ? rawInfo.wombatStakingPool.isPoolFeeFree + : false, + rawStakingTokenInfo: { + name: rawInfo.stakingTokenSymbol, + symbol: rawInfo.stakingTokenSymbol, + }, + stakingTokenInfo: + rawInfo.poolType === 'WOMBAT_POOL' + ? { + name: rawInfo.wombatHelperInfo.depositTokenSymbol, + symbol: rawInfo.wombatHelperInfo.depositTokenSymbol, + showSymbol: rawInfo.wombatHelperInfo.depositTokenSymbol, + decimals: Number(rawInfo.wombatHelperInfo.depositTokenDecimals), + priceId: + rawInfo.wombatHelperInfo.depositTokenSymbol.toUpperCase(), + } + : { + name: rawInfo.stakingTokenSymbol, + symbol: rawInfo.stakingTokenSymbol, + showSymbol: rawInfo.stakingTokenSymbol, + decimals: Number(rawInfo.stakingTokenDecimals), + priceId: rawInfo.stakingTokenSymbol.toUpperCase(), + }, + }; + //console.log("pool", pool) + if (rawInfo.poolType === 'WOMBAT_POOL') { + pool.helperInfo = { + depositToken: rawInfo.wombatHelperInfo.depositToken, + lpToken: rawInfo.wombatHelperInfo.lpToken, + stakingToken: rawInfo.wombatHelperInfo.stakingToken, + }; + } + + pool.tvlInfo = { + totalSupply: rawInfo.sizeOfPool, + formatTotalSupply: formatEther(rawInfo.sizeOfPool), + totalAmount: new BigNumber(formatEther(rawInfo.sizeOfPool)) + .multipliedBy( + priceData[pool.stakingTokenInfo?.showSymbol?.toUpperCase()] + ) + .toNumber(), + }; + if (rawInfo.isActive) { + pool.aprInfo = { + totalApr: 0, + formatTotalApr: '0.0', + items: [], + }; + let rewardAmount = new BigNumber(formatEther(rawInfo.emission)); + rewardAmount = rewardAmount + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(priceData['MGP']); + const mgpApr = rewardAmount.dividedBy( + new BigNumber(pool.tvlInfo.totalAmount) + ); + const mgpAprItem = { + name: rawInfo.isMPGRewardPool ? 'MGP' : 'vlMGP', + symbol: rawInfo.isMPGRewardPool ? 'MGP' : 'vlMGP', + value: mgpApr.toNumber(), + formatValue: mgpApr.gt(new BigNumber(0)) + ? mgpApr.multipliedBy(100).toFixed(2) + : '0.0', + address: rawInfo.isMPGRewardPool ? mgpAddress : vlmgpAddress, + }; + pool.aprInfo.items.push(mgpAprItem); + + if (pool.type === 'WOMBAT_POOL') { + const poolFactor = Number( + formatEther(rawInfo.wombatV3Pool.sumOfFactors) + ); + const userBalance = Number( + formatEther(rawInfo.wombatV3Pool.wombatStakingUserAmount) + ); + const userfactor = Number( + formatEther(rawInfo.wombatV3Pool.wombatStakingUserFactor) + ); + const totalSupply = Number( + formatEther(rawInfo.wombatV3Pool.totalSupply) + ); + const rewardRate = Number( + formatEther(rawInfo.wombatV3Pool.rewardRate) + ); + const normPerSec = (rewardRate * 0.375 * userBalance) / totalSupply; + const boostedPerSec = (rewardRate * 0.625 * userfactor) / poolFactor; + const rewardAmount = new BigNumber(normPerSec + boostedPerSec) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(pool.isPoolFeeFree ? 1 : 0.8) + .multipliedBy(priceData['WOM']); + wombatRewardTokens[0].tokenPerSec = + wombatRewardTokens[0].tokenPerSec + normPerSec + boostedPerSec; + const womApr = rewardAmount.dividedBy( + new BigNumber(pool.tvlInfo.totalAmount) + ); + const womAprItem = { + name: 'WOM', + symbol: 'WOM', + value: womApr.toNumber(), + formatValue: womApr.gt(new BigNumber(0)) + ? womApr.multipliedBy(100).toFixed(2) + : '0.0', + address: womAddress, + }; + pool.aprInfo.items.push(womAprItem); + for ( + let i = 0, l = rawInfo.wombatV3Pool.rewardList.length; + i < l; + i++ + ) { + const rewardInfo = rawInfo.wombatV3Pool.rewardList[i]; + if (Number(rewardInfo.tokenPerSec) === 0) { + continue; + } + const rewardAmount = new BigNumber( + formatEther(rewardInfo.tokenPerSec) + ) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(pool.isPoolFeeFree ? 1 : 0.8) + .multipliedBy( + priceData[rewardInfo.rewardTokenSymbol.toUpperCase()] + ); + const tvlAmount = new BigNumber( + formatEther(rawInfo.wombatV3Pool.totalSupply) + ).multipliedBy( + priceData[ + rawInfo.wombatHelperInfo.depositTokenSymbol.toUpperCase() + ] + ); + const rewardApr = rewardAmount.dividedBy(tvlAmount); + const rewardAprItem = { + name: rewardInfo.rewardTokenSymbol, + symbol: rewardInfo.rewardTokenSymbol, + value: rewardApr.toNumber(), + formatValue: rewardApr.gt(new BigNumber(0)) + ? rewardApr.multipliedBy(100).toFixed(2) + : '0.0', + address: rewardInfo.rewardToken, + }; + wombatRewardTokens.push({ + symbol: rewardInfo.rewardTokenSymbol, + tokenPerSec: rewardInfo.tokenPerSec, + totalSupply: rawInfo.wombatV3Pool.totalSupply, + userBalance: rawInfo.wombatV3Pool.wombatStakingUserAmount, + address: rewardInfo.rewardToken, + }); + pool.aprInfo.items.push(rewardAprItem); + } + } + + let totalApr = new BigNumber(0); + for (let i = 0, l = pool.aprInfo.items.length; i < l; i++) { + totalApr = totalApr.plus(new BigNumber(pool.aprInfo.items[i].value)); + } + pool.aprInfo.totalApr = totalApr.toNumber(); + pool.aprInfo.formatTotalApr = new BigNumber(pool.aprInfo.totalApr).gt( + new BigNumber(0) + ) + ? new BigNumber(pool.aprInfo.totalApr).multipliedBy(100).toFixed(2) + : '0.0'; + } + + poolInfos.push(pool); + } + + const magpieWomPool = _.find(poolInfos, (item) => { + return item.type === 'MAGPIE_WOM_POOL'; + }); + if (magpieWomPool && magpieWomPool.aprInfo) { + for (let i = 0, l = wombatRewardTokens.length; i < l; i++) { + const rewardInfo = wombatRewardTokens[i]; + let apr = new BigNumber(0); + const tvl = new BigNumber(magpieWomPool.tvlInfo?.totalAmount); + + if (rewardInfo.symbol === 'WOM') { + apr = new BigNumber(rewardInfo.tokenPerSec) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(0.12) + .multipliedBy(priceData['WOM']) + .dividedBy(tvl); + } else { + //console.log(poolInfo, rewardInfo, rewardInfos) + let rewardAmount = new BigNumber(formatEther(rewardInfo.tokenPerSec)) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(0.12); + if (rewardInfo.userBalance && rewardInfo.totalSupply) { + rewardAmount = rewardAmount + .multipliedBy(new BigNumber(formatEther(rewardInfo.userBalance))) + .dividedBy(new BigNumber(formatEther(rewardInfo.totalSupply))); + } + rewardAmount = rewardAmount.multipliedBy( + priceData[rewardInfo.symbol.toUpperCase()] + ); + apr = rewardAmount.dividedBy(tvl); + } + + magpieWomPool.aprInfo?.items.push({ + name: rewardInfo.symbol, + symbol: rewardInfo.symbol, + value: apr.toNumber(), + formatValue: apr.gt(new BigNumber(0)) + ? apr.multipliedBy(100).toFixed(2) + : '0.0', + address: rewardInfo.address, + }); + } + let totalApr = new BigNumber(0); + for (let i = 0, l = magpieWomPool.aprInfo.items.length; i < l; i++) { + totalApr = totalApr.plus( + new BigNumber(magpieWomPool.aprInfo?.items[i].value) + ); + } + magpieWomPool.aprInfo.totalApr = totalApr.toNumber(); + magpieWomPool.aprInfo.formatTotalApr = new BigNumber( + magpieWomPool.aprInfo.totalApr + ).gt(new BigNumber(0)) + ? new BigNumber(magpieWomPool.aprInfo.totalApr) + .multipliedBy(100) + .toFixed(2) + : '0.0'; + } + const magpieVlMgpPool = _.find(poolInfos, (item) => { + return item.type === 'MAGPIE_VLMGP_POOL'; + }); + if (magpieVlMgpPool && magpieVlMgpPool.aprInfo) { + for (let i = 0, l = wombatRewardTokens.length; i < l; i++) { + const rewardInfo = wombatRewardTokens[i]; + let apr = new BigNumber(0); + const tvl = new BigNumber(magpieVlMgpPool.tvlInfo?.totalAmount); + if (rewardInfo.symbol === 'WOM') { + apr = new BigNumber(rewardInfo.tokenPerSec) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(0.08) + .multipliedBy(priceData['WOM']) + .dividedBy(tvl); + } else { + //console.log(poolInfo, rewardInfo, rewardInfos) + let rewardAmount = new BigNumber(formatEther(rewardInfo.tokenPerSec)) + .multipliedBy(365) + .multipliedBy(24) + .multipliedBy(60) + .multipliedBy(60) + .multipliedBy(0.08); + if (rewardInfo.userBalance && rewardInfo.totalSupply) { + rewardAmount = rewardAmount + .multipliedBy(new BigNumber(formatEther(rewardInfo.userBalance))) + .dividedBy(new BigNumber(formatEther(rewardInfo.totalSupply))); + } + rewardAmount = rewardAmount.multipliedBy( + priceData[rewardInfo.symbol.toUpperCase()] + ); + apr = rewardAmount.dividedBy(tvl); + } + + magpieVlMgpPool.aprInfo?.items.push({ + name: rewardInfo.symbol === 'WOM' ? 'mWom' : rewardInfo.symbol, + symbol: rewardInfo.symbol === 'WOM' ? 'mWom' : rewardInfo.symbol, + value: apr.toNumber(), + formatValue: apr.gt(new BigNumber(0)) + ? apr.multipliedBy(100).toFixed(2) + : '0.0', + address: rewardInfo.address, + }); + } + let totalApr = new BigNumber(0); + for (let i = 0, l = magpieVlMgpPool.aprInfo.items.length; i < l; i++) { + totalApr = totalApr.plus( + new BigNumber(magpieVlMgpPool.aprInfo?.items[i].value) + ); + } + magpieVlMgpPool.aprInfo.totalApr = totalApr.toNumber(); + magpieVlMgpPool.aprInfo.formatTotalApr = new BigNumber( + magpieVlMgpPool.aprInfo.totalApr + ).gt(new BigNumber(0)) + ? new BigNumber(magpieVlMgpPool.aprInfo.totalApr) + .multipliedBy(100) + .toFixed(2) + : '0.0'; + } + + for (let poolInfo of poolInfos) { + //console.log(poolInfo) + if (poolInfo.tvlInfo.totalAmount == 0) { + continue; + } + poolAprList.push({ + pool: `${info.masterMagpie}-${poolInfo.poolId}`, + project: 'wompie', + chain: utils.formatChain(info.chain), + symbol: poolInfo.stakingTokenInfo.showSymbol, + tvlUsd: poolInfo.tvlInfo.totalAmount, + url: 'https://magpiexyz.io/stake', + underlyingTokens: [poolInfo.stakingToken], + // apy: totalApr.multipliedBy(100).toNumber(), + apyReward: new BigNumber(poolInfo.aprInfo.totalApr) + .multipliedBy(100) + .toNumber(), + rewardTokens: poolInfo.aprInfo.items.map((item) => item.address), + poolMeta: poolInfo.type == 'WOMBAT_POOL' ? 'Wombat' : null, + }); + } + } + + return poolAprList.filter((i) => utils.keepFinite(i)); +} + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/woofi-earn/index.js b/src/adaptors/woofi-earn/index.js new file mode 100644 index 0000000000..54bd7812a6 --- /dev/null +++ b/src/adaptors/woofi-earn/index.js @@ -0,0 +1,112 @@ +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); + +const API_URL = 'https://fi-api.woo.org/yield'; +const STATS_API_URL = 'https://api.woofi.com/token_stat'; + +const API_URLS = { + binance: `${API_URL}?network=bsc`, + avalanche: `${API_URL}?network=avax`, + fantom: `${API_URL}?network=fantom`, + polygon: `${API_URL}?network=polygon`, + arbitrum: `${API_URL}?network=arbitrum`, + optimism: `${API_URL}?network=optimism`, + era: `${API_URL}?network=zksync`, + linea: `${API_URL}?network=linea`, + base: `${API_URL}?network=base`, + mantle: `${API_URL}?network=mantle`, + sonic: `${API_URL}?network=sonic`, + berachain: `${API_URL}?network=berachain`, +}; + +const rewardTokensMapping = { + // binance: '0x4691937a7508860F876c9c0a2a617E7d9E945D4B', // WOO + // avalanche: '0xaBC9547B534519fF73921b1FBA6E672b5f58D083', // WOO + // fantom: '0x6626c47c00F1D87902fc13EECfaC3ed06D5E8D8a', // WOO + // polygon: '0x1B815d120B3eF02039Ee11dC2d33DE7aA4a8C603', // WOO + // arbitrum: '0xcAFcD85D8ca7Ad1e1C6F82F651fA15E33AEfD07b', // WOO + // optimism: '0x871f2F2ff935FD1eD867842FF2a7bfD051A5E527', // WOO + optimism: '0x4200000000000000000000000000000000000042', // OP + // linea: '0xF3df0A31ec5EA438150987805e841F960b9471b6', // WOO + // base: '0xF3df0A31ec5EA438150987805e841F960b9471b6', // WOO + mantle: '0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8', // WMNT + // sonic: '0xF3df0A31ec5EA438150987805e841F960b9471b6', // WOO +}; + +async function getStats() { + const stats = {} + for (const chain of Object.keys(API_URLS)) { + let woofiChain = chain; + if (chain === 'binance') woofiChain = 'bsc'; + if (chain === 'avalanche') woofiChain = 'avax'; + if (chain === 'era') woofiChain = 'zksync'; + + // don't know why woofi api return bsc data key for all chains here + stats[chain] = (await utils.getData(`${STATS_API_URL}?network=${woofiChain}`))['data']['bsc']; + } + return stats; +} + +const main = async () => { + const stats = await getStats() + const datas = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await utils.getData(url))['data']['auto_compounding'], + ]) + ); + + let results = []; + for (const [chain, data] of datas) { + for (const [address, info] of Object.entries(data)) { + let source = info['source']; + if (source.indexOf('woofi_super_charger') === -1) continue; + + let version = 'V1'; + if (source.split('_').length >= 4) { + version = source.split('_')[3].toUpperCase(); + } + + let decimals = info['decimals']; + let apyReward; + let rewardTokens; + if (chain === "optimism" || chain === "mantle") { + apyReward = info['reward_apr']; + rewardTokens = [rewardTokensMapping[chain]]; + } else { + apyReward = 0; + rewardTokens = []; + } + + let volumeUsd1d = 0; + if (stats[chain]) { + for (const token of stats[chain]) { + if (token.symbol === info['symbol']) { + volumeUsd1d = Number(token['24h_volume_usd']) / 1e18; + } + } + } + + results.push({ + pool: `${address}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'woofi-earn', + symbol: utils.formatSymbol(info['symbol']), + poolMeta: `Supercharger${version}`, + tvlUsd: parseFloat(BigNumber(info['tvl']).div(10 ** decimals)), + apyBase: info['weighted_average_apr'], + apyReward: apyReward, + volumeUsd1d: volumeUsd1d, + rewardTokens: rewardTokens, + }); + } + } + + return results; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://fi.woo.org/swap/earn', +}; diff --git a/src/adaptors/xexchange/index.js b/src/adaptors/xexchange/index.js new file mode 100644 index 0000000000..059f53b023 --- /dev/null +++ b/src/adaptors/xexchange/index.js @@ -0,0 +1,38 @@ +const { request } = require('graphql-request'); +const { query } = require('./query.json'); +const utils = require('../utils'); + +const API_URL = 'https://graph.xexchange.com/graphql'; + +const VARIABLES = { days: 7, mexID: 'MEX-455c57', offset: 0, pairsLimit: 500 }; + +const apy = async () => { + let { farms } = await request(API_URL, query, VARIABLES); + farms = farms.filter((p) => p.address); + + const pools = farms.map((farm) => { + const apyReward = Number(farm.baseApr) * 100 || 0; + return { + pool: farm.pair.address, + project: 'xexchange', + chain: 'MultiversX', + symbol: `${farm.pair.firstToken.ticker}-${farm.pair.secondToken.ticker}`, + tvlUsd: Number(farm.totalValueLockedUSD), + apyBase: Number(farm.pair.feesAPR) * 100 || 0, + apyReward, + rewardTokens: apyReward ? ['MEX-455c57'] : [], + underlyingTokens: [ + farm.pair.firstToken?.identifier, + farm.pair.secondToken?.identifier, + ], + }; + }); + + return utils.removeDuplicates(pools); +}; + +module.exports = { + apy, + timetravel: false, + url: 'https://maiar.exchange/farms', +}; diff --git a/src/adaptors/xexchange/query.json b/src/adaptors/xexchange/query.json new file mode 100644 index 0000000000..2321c657e6 --- /dev/null +++ b/src/adaptors/xexchange/query.json @@ -0,0 +1,3 @@ +{ + "query": "query ($days: Int!, $mexID: String!) {\n farms {\n ... on FarmModelV2 {\n address\n farmToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n farmTokenPriceUSD\n farmTokenSupply\n farmingToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n farmingTokenPriceUSD\n farmedToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n farmedTokenPriceUSD\n pair {\n address\n firstToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n firstTokenPriceUSD\n secondToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n secondTokenPriceUSD\n liquidityPoolToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n state\n type\n info {\n reserves0\n reserves1\n totalSupply\n __typename\n }\n feesAPR\n totalFeePercent\n specialFeePercent\n __typename\n }\n state\n version\n penaltyPercent\n perBlockRewards\n totalValueLockedUSD\n minimumFarmingEpochs\n produceRewardsEnabled\n baseApr\n energyFactoryAddress\n boostedYieldsRewardsPercenatage\n __typename\n }\n __typename\n }\n lkmexProxies: proxy {\n address\n wrappedLpToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n wrappedFarmToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n lockedAssetTokens {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n assetToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n intermediatedPairs\n intermediatedFarms\n __typename\n }\n simpleLockProxies: simpleLock {\n address\n lockedToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n lpProxyToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n farmProxyToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n intermediatedPairs\n intermediatedFarms\n __typename\n }\n simpleLockEnergy {\n address\n baseAssetToken {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n lockedToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n legacyLockedToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n pauseState\n lockOptions {\n lockEpochs\n penaltyStartPercentage\n __typename\n }\n __typename\n }\n stakingProxies {\n address\n dualYieldToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n farmToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n lpFarmToken {\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n decimals\n name\n collection\n ticker\n __typename\n }\n lpFarmAddress\n pairAddress\n stakingFarmAddress\n __typename\n }\n totalValueLockedUSD\n totalAggregatedRewards(days: $days)\n mexSupply: totalTokenSupply(tokenID: $mexID)\n tokens(identifiers: [$mexID]) {\n balance\n decimals\n name\n identifier\n ticker\n owner\n assets {\n website\n description\n status\n pngUrl\n svgUrl\n __typename\n }\n price\n type\n __typename\n }\n}\n" +} diff --git a/src/adaptors/xtoken/constants.js b/src/adaptors/xtoken/constants.js new file mode 100644 index 0000000000..77e47fe35d --- /dev/null +++ b/src/adaptors/xtoken/constants.js @@ -0,0 +1,53 @@ +const sdk = require('@defillama/sdk'); +const NETWORKS = { + arbitrum: 'arbitrum', + ethereum: 'ethereum', + optimism: 'optimism', + polygon: 'polygon', +}; + +const SUBGRAPHS = { + ethereum: sdk.graph.modifyEndpoint('AhQcCNvtM3YEoCBPQFYfPzxwY6Rk2nFqydr4276zki2c'), + arbitrum: sdk.graph.modifyEndpoint('HQFMggtEW3AfDLp8GCPYaaZi91K1SgH9BjnGDxUDptt5'), + optimism: sdk.graph.modifyEndpoint('DxV73USPBdBXunZFi1UEkBqL6pNA33rt7JYs5hgGbyEc'), + polygon: sdk.graph.modifyEndpoint('9ckmB5VjYouBNxWFWrDsXpNqsNF9jdDewnba8Yx5a9e2'), +}; + +const USDC_ADDRESSES = { + arbitrum: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + ethereum: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + optimism: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607', + polygon: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', +}; + +const DELISTED_POOLS = { + arbitrum: [], + ethereum: [ + '0x6148a1bd2be586e981115f9c0b16a09bbc271e2c', + '0xc5f0237a2a2bb9dc60da73491ad39a1afc4c8b63', + '0x7fc70abe76605d1ef1f7a5ddc5e2ad35a43a6949', + ], + optimism: ['0x6148a1bd2be586e981115f9c0b16a09bbc271e2c'], + polygon: [], +}; + +const NETWORK_IDS = { + arbitrum: 42161, + ethereum: 1, + optimism: 10, + optimism: 137, +}; + +const BASE_APP_URL = 'https://app.xtokenterminal.io/mining'; + +const COINS_PRICES_URL = 'https://coins.llama.fi/prices/current'; + +module.exports = { + NETWORKS, + SUBGRAPHS, + USDC_ADDRESSES, + NETWORK_IDS, + BASE_APP_URL, + COINS_PRICES_URL, + DELISTED_POOLS, +}; diff --git a/src/adaptors/xtoken/index.js b/src/adaptors/xtoken/index.js new file mode 100644 index 0000000000..68f81d40b3 --- /dev/null +++ b/src/adaptors/xtoken/index.js @@ -0,0 +1,417 @@ +const axios = require('axios'); +const utils = require('../utils'); +const constants = require('./constants'); +const { getPoolsQuery } = require('./query'); +const { + ethers, + utils: { formatEther, formatUnits, getAddress }, + constants: { AddressZero }, +} = require('ethers'); + +const getTimeDurationStr = (secs) => { + if (secs < 60) { + return `${secs} seconds`; + } + + const mins = Math.floor(secs / 60); + if (mins < 60) { + return `${mins} minutes`; + } + + const hours = Math.floor(mins / 60); + if (hours < 24) { + return `${hours} hours`; + } + + const days = Math.floor(hours / 24); + if (days === 1) { + return `${days} day`; + } else if (days < 7) { + return `${days} days`; + } + + const weeks = Math.floor(days / 7); + if (weeks === 1) { + return `${weeks} week`; + } + return `${weeks} weeks`; +}; + +const bn = (amount) => { + return ethers.BigNumber.from(amount); +}; + +const getPriceFromUniswapForToken0 = ( + token1Price, + token0Decimals, + token1Decimals, + poolPrice +) => { + const _token0Decimals = Number(token0Decimals); + const _token1Decimals = Number(token1Decimals); + const decimalDiff = Math.abs(_token0Decimals - _token1Decimals); + + let _poolPrice = bn(poolPrice); + + // Adjust token price for different token decimals + if (_token0Decimals >= _token1Decimals) { + _poolPrice = _poolPrice.mul(1e12).div(bn(10).pow(18 - decimalDiff)); + } else { + _poolPrice = _poolPrice.mul(1e12).div(bn(10).pow(18 + decimalDiff)); + } + + return formatUnits( + _poolPrice.mul((Number(token1Price) * 1e8).toFixed(0)).div(bn(10).pow(8)), + 12 + ); +}; + +const getPriceFromUniswapForToken1 = ( + token0Price, + token0Decimals, + token1Decimals, + poolPrice +) => { + const _token0Decimals = Number(token0Decimals); + const _token1Decimals = Number(token1Decimals); + const decimalDiff = Math.abs(_token0Decimals - _token1Decimals); + + let _poolPrice = bn(poolPrice); + + // Adjust token price for different token decimals + if (_token0Decimals >= _token1Decimals) { + _poolPrice = _poolPrice.mul(1e12).div(bn(10).pow(18 - decimalDiff)); + } else { + _poolPrice = _poolPrice.mul(1e12).div(bn(10).pow(18 + decimalDiff)); + } + + return formatUnits( + bn((Number(token0Price) * 1e8).toFixed(0)) + .mul(bn(10).pow(16)) + .div(_poolPrice), + 12 + ); +}; + +const getTokenPriceFrom1inch = async (tokenAddress, tokenDecimals, network) => { + const networkId = constants.NETWORK_IDS[network.toLowerCase()]; + const usdcAddress = constants.USDC_ADDRESSES[network.toLowerCase()]; + const amount = bn(10).pow(tokenDecimals).toString(); + const path = `https://api.1inch.io/v4.0/${networkId}/quote?fromTokenAddress=${tokenAddress}&toTokenAddress=${usdcAddress}&amount=${amount}`; + + let res; + try { + res = await axios.get(path); + } catch (err) { + return '0'; + } + + const decimals = res.data.toToken.decimals; + const price = res.data.toTokenAmount; + + return formatUnits(bn(price).mul(1e12).div(bn(10).pow(decimals)), 12); +}; + +const getTokenPrice = async (token, network) => { + const tokenKey = `${network.toLowerCase()}:${token.address}`; + let price = (await axios.get(`${constants.COINS_PRICES_URL}/${tokenKey}`)) + .data.coins[tokenKey]?.price; + + if (!!price) { + return price; + } + + // use 1inch price as backup + if (token.address & token.decimals) { + return getTokenPriceFrom1inch(token.address, token.decimals, network); + } +}; + +const getLPTokensDetails = async (token0, token1, poolPrice, network) => { + const token0Details = { + ...token0, + price: await getTokenPrice(token0, network), + }; + const token1Details = { + ...token1, + price: await getTokenPrice(token1, network), + }; + + if (!Number(token0Details.price) && !Number(token1Details.price)) { + token0Details.price = '0'; + token1Details.price = '0'; + return [token0Details, token1Details]; + } + + if (!Number(token0Details.price)) { + let uniswapPrice; + try { + if (token0Details.balance != 0) { + uniswapPrice = getPriceFromUniswapForToken0( + token1Details.price, + token0Details.decimals, + token1Details.decimals, + poolPrice + ); + } else { + uniswapPrice = '0'; + } + } catch (err) { + console.error(`err retrieving uniswap price: ${err.message}`); + uniswapPrice = '0'; + } + token0Details.price = uniswapPrice; + } + + if (!Number(token1Details.price)) { + let uniswapPrice; + try { + if (token1Details.balance != 0) { + uniswapPrice = getPriceFromUniswapForToken1( + token0Details.price, + token0Details.decimals, + token1Details.decimals, + poolPrice + ); + } else { + uniswapPrice = '0'; + } + } catch (err) { + console.error(`err retrieving uniswap price: ${err.message}`); + uniswapPrice = '0'; + } + token1Details.price = uniswapPrice; + } + return [token0Details, token1Details]; +}; + +const parseToken = (token) => { + const isTokenEth = token.id === ethers.constants.AddressZero; + return { + address: token.id, + symbol: isTokenEth ? utils.formatSymbol('ETH') : token.symbol, + decimals: isTokenEth ? 18 : token.decimals, + name: isTokenEth ? 'Ethereum' : token.name, + }; +}; + +const calculateTVL = (token0Price, token1Price, poolBalances) => { + try { + const _token0Price = (Number(token0Price) * 1e8).toFixed(0); + const _token1Price = (Number(token1Price) * 1e8).toFixed(0); + + const t0Value = poolBalances[0].mul(_token0Price).div(1e8); + const t1Value = poolBalances[1].mul(_token1Price).div(1e8); + const tvl = t0Value.add(t1Value); + + const t0Percentage = tvl.isZero() + ? 0 + : t0Value.mul(1e8).div(tvl).toNumber() / 1e6; + const t1Percentage = tvl.isZero() + ? 0 + : t1Value.mul(1e8).div(tvl).toNumber() / 1e6; + + return { + t0Value: t0Value.toString(), + t1Value: t1Value.toString(), + t0Percentage, + t1Percentage, + tvl, + }; + } catch (err) { + console.error(`error calculating TVL: ${err}`); + return { + t0Value: '0', + t1Value: '0', + t0Percentage: 0, + t1Percentage: 0, + tvl: bn(0), + }; + } +}; + +const calculateAPY = ( + rewardAmounts, + rewardProgramDuration, + tvlUsd, + rewardTokens, + periodFinish +) => { + try { + const SECONDS_IN_YEAR = 31536000; + if ( + rewardProgramDuration === '0' || + Number(periodFinish) * 1000 < Date.now() // sale ended + ) { + return 0; + } + + let amountPerYearTotal = bn(0); + for (let i = 0; i < rewardAmounts.length; ++i) { + let price = rewardTokens[i].price || '0'; + price = (Number(price) * 1e8).toFixed(0); + const amount = bn(rewardAmounts[i]); + const value = amount.mul(price).div(1e8); + const amountPerYear = value + .mul(SECONDS_IN_YEAR) + .div(rewardProgramDuration); + amountPerYearTotal = amountPerYearTotal.add(amountPerYear); + } + const amoutPerYearTotalNum = Number( + formatEther(amountPerYearTotal.toString()) + ); + + return tvlUsd === 0 + ? amoutPerYearTotalNum + : (amoutPerYearTotalNum * 100) / tvlUsd; + } catch (err) { + console.error(`error calculating APY: ${err}`); + return 0; + } +}; + +const getCurratedPoolData = async (poolData, network) => { + const pool = poolData; + + const token0Balance = pool.stakedTokenBalance + ? pool.stakedTokenBalance[0] + : 0; + const token1Balance = pool.stakedTokenBalance + ? pool.stakedTokenBalance[1] + : 0; + let token0 = parseToken(pool.token0); + let token1 = parseToken(pool.token1); + + let stakedToken = pool.stakedToken ? parseToken(pool.stakedToken) : undefined; + const uniswapPrice = `${pool.price || 0}`; + token0 = { + ...token0, + balance: token0Balance, + }; + token1 = { + ...token1, + balance: token1Balance, + }; + const tokenDetails = await getLPTokensDetails( + token0, + token1, + uniswapPrice, + network + ); + token0 = tokenDetails[0]; + token1 = tokenDetails[1]; + + if (stakedToken != undefined) { + stakedToken = { + ...stakedToken, + price: await getTokenPrice(stakedToken, network), + }; + } + + const rewardAmounts = pool.rewardAmounts || []; + const rewardTokens = []; + + for (let j = 0; j < pool.rewardTokens.length; ++j) { + let rewardToken = parseToken(pool.rewardTokens[j]); + if (rewardToken.address.toLowerCase() === token0.address.toLowerCase()) { + rewardToken = token0; + } else if ( + rewardToken.address.toLowerCase() === token1.address.toLowerCase() + ) { + rewardToken = token1; + } else { + rewardToken = { + ...rewardToken, + price: await getTokenPrice(rewardToken, network), + }; + } + + rewardTokens.push(rewardToken); + if (!pool.rewardAmounts) { + rewardAmounts.push('0'); + } + } + + let poolBalances = [bn(0), bn(0)]; + if (pool.bufferTokenBalance) { + const poolBalance0 = bn(pool.bufferTokenBalance[0]).add( + bn(pool.stakedTokenBalance[0]).mul( + bn(10).pow(18 - Number(token0.decimals)) + ) + ); + const poolBalance1 = bn(pool.bufferTokenBalance[1]).add( + bn(pool.stakedTokenBalance[1]).mul( + bn(10).pow(18 - Number(token1.decimals)) + ) + ); + poolBalances = [poolBalance0, poolBalance1]; + } + + const { tvl } = calculateTVL(token0.price, token1.price, poolBalances); + const tvlUsd = Number(formatEther(tvl.toString())); + + const apy = calculateAPY( + rewardAmounts, + pool.rewardDuration, + tvlUsd, + rewardTokens, + pool.periodFinish || '0' + ); + + return { + pool: `${getAddress(pool.id)}-${network}`, + chain: utils.formatChain(network), + project: 'xtoken', + symbol: `${utils.formatSymbol(token0.symbol)}-${utils.formatSymbol( + token1.symbol + )}`, + tvlUsd: tvlUsd, + apyReward: apy, + rewardTokens: rewardTokens.map(({ address }) => address), + underlyingTokens: [token0, token1].map(({ address }) => address), + url: `${constants.BASE_APP_URL}/pools/${ + network.toLowerCase() === 'ethereum' ? 'mainnet' : network.toLowerCase() + }/${getAddress(pool.id)}`, + ...(Number(pool.vestingPeriod) === 0 + ? {} + : { poolMeta: `${getTimeDurationStr(pool.vestingPeriod)} vesting` }), + }; +}; + +const getPools = async () => { + const responses = await Promise.all( + Object.values(constants.SUBGRAPHS).map((url) => + axios({ + url, + method: 'post', + headers: { + 'content-type': 'application/json', + }, + data: { query: getPoolsQuery }, + }) + ) + ).catch((err) => console.error('Pools subgraph request failed:', err)); + const poolsInfo = responses.map((res) => res.data.data.pools); + + const pools = []; + for (let networkIdx in poolsInfo) { + const network = Object.keys(constants.SUBGRAPHS)[networkIdx]; + const curatedPools = poolsInfo[networkIdx].filter( + (pool) => + !constants.DELISTED_POOLS[network].includes(pool.id.toLowerCase()) + ); + + for (let poolData of curatedPools) { + const poolCurratedData = await getCurratedPoolData(poolData, network); + pools.push(poolCurratedData); + } + } + + return pools; +}; + +module.exports = { + timetravel: false, + apy: getPools, + url: `${constants.BASE_APP_URL}/discover`, +}; diff --git a/src/adaptors/xtoken/query.js b/src/adaptors/xtoken/query.js new file mode 100644 index 0000000000..a83080ffe8 --- /dev/null +++ b/src/adaptors/xtoken/query.js @@ -0,0 +1,36 @@ +const getPoolsQuery = ` + query { + pools(first: 1000, orderBy: createdAt, orderDirection: desc) { + id + token0 { + id + symbol + name + decimals + } + token1 { + id + symbol + name + decimals + } + rewardTokens { + id + symbol + name + decimals + } + price + vestingPeriod + rewardAmounts + rewardDuration + periodFinish + bufferTokenBalance + stakedTokenBalance + } + } +`; + +module.exports = { + getPoolsQuery, +}; diff --git a/src/adaptors/xy-finance/abi.js b/src/adaptors/xy-finance/abi.js new file mode 100644 index 0000000000..c4e61296bd --- /dev/null +++ b/src/adaptors/xy-finance/abi.js @@ -0,0 +1,18 @@ +exports.ContractABIs = { + miniERC20ABI: [ + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', type: 'uint256' }], + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + type: 'function', + }, + ], +}; \ No newline at end of file diff --git a/src/adaptors/xy-finance/config.js b/src/adaptors/xy-finance/config.js new file mode 100644 index 0000000000..69a82f29ba --- /dev/null +++ b/src/adaptors/xy-finance/config.js @@ -0,0 +1,263 @@ +const ETHEREUM_REF_POOL_UNDERLYINGS = { + USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + ETH: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', +}; + +const SUPPORTED_CHAIN_NAMES = { + 1: 'Ethereum', + 56: 'Binance', + 137: 'Polygon', + 250: 'Fantom', + 25: 'Cronos', + 108: 'ThunderCore', + 43114: 'Avalanche', + 321: 'Kucoin', + 42161: 'Arbitrum', + 10: 'Optimism', + 592: 'Astar', + 1285: 'Moonriver', + 8217: 'Klaytn', + // 1111: 'Wemix', + 324: 'zkSync Era', + 1101: 'Polygon zkEVM', +}; + +const YPOOL_INFOS = { + USDC: { + 1: { + ypool: '0xdD8B0995Cc92c7377c7bce2A097EC70f45A192D5', + ypoolToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + decimals: 6, + }, + 56: { + ypool: '0x27C12BCb4538b12fdf29AcB968B71dF7867b3F64', + ypoolToken: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + decimals: 18, + }, + 137: { + ypool: '0xf4137e5D07b476e5A30f907C3e31F9FAAB00716b', + ypoolToken: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + decimals: 6, + }, + 25: { + ypool: '0x44a54941E572C526a599B0ebe27A14A5BF159333', + ypoolToken: '0xc21223249CA28397B4B6541dfFaEcC539BfF0c59', + decimals: 6, + }, + 250: { + ypool: '0x3A459695D49cD6B9637bC85B7ebbb04c5c3038c0', + ypoolToken: '0x04068DA6C83AFCFA0e13ba15A6696662335D5B75', + decimals: 6, + }, + 321: { + ypool: '0xa274931559Fb054bF60e0C44355D3558bB8bC2E6', + ypoolToken: '0x980a5AfEf3D17aD98635F6C5aebCBAedEd3c3430', + decimals: 18, + }, + 42161: { + ypool: '0x680ab543ACd0e52035E9d409014dd57861FA1eDf', + ypoolToken: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + decimals: 6, + }, + 43114: { + ypool: '0x21ae3E63E06D80c69b09d967d88eD9a98c07b4e4', + ypoolToken: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', + decimals: 6, + }, + 10: { + ypool: '0x1e4992E1Be86c9d8ed7dcBFcF3665FE568dE98Ab', + ypoolToken: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607', + decimals: 6, + }, + 1285: { + ypool: '0x680ab543ACd0e52035E9d409014dd57861FA1eDf', + ypoolToken: '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', + decimals: 6, + }, + 8217: { + ypool: '0xB238d4339a44f93aBCF4071A9bB0f55D2403Fd84', + ypoolToken: '0x754288077D0fF82AF7a5317C7CB8c444D421d103', + decimals: 6, + }, + 324: { + ypool: '0x75167284361c8D61Be7E4402f4953e2b112233cb', + ypoolToken: '0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4', + decimals: 6, + }, + 1101: { + ypool: '0x1acCfC3a45313f8F862BE7fbe9aB25f20A93d598', + ypoolToken: '0xA8CE8aee21bC2A48a5EF670afCc9274C7bbbC035', + decimals: 6, + }, + 592: { + ypool: '0xD236639F5B00BC6711aC799bac5AceaF788b2Aa3', + ypoolToken: '0x6a2d262D56735DbA19Dd70682B39F6bE9a931D98', + decimals: 6, + }, + 108: { + ypool: '0x2641911948e0780e615A9465188D975Fa4A72f2c', + ypoolToken: '0x22e89898A04eaf43379BeB70bf4E38b1faf8A31e', + decimals: 6, + }, + // wemix + }, + USDT: { + 1: { + ypool: '0x8e921191a9dc6832C1c360C7c7B019eFB7c29B2d', + ypoolToken: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + decimals: 6, + }, + 56: { + ypool: '0xD195070107d853e55Dad9A2e6e7E970c400E67b8', + ypoolToken: '0x55d398326f99059fF775485246999027B3197955', + decimals: 18, + }, + 137: { + ypool: '0x3243278E0F93cD6F88FC918E0714baF7169AFaB8', + ypoolToken: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + decimals: 6, + }, + 25: { + ypool: '0x74A0EEA77e342323aA463098e959612d3Fe6E686', + ypoolToken: '0x66e428c3f67a68878562e79A0234c1F83c208770', + decimals: 6, + }, + 250: { + ypool: '0xC255563d3Bc3Ed7dBbb8EaE076690497bfBf7Ef8', + ypoolToken: '0x049d68029688eAbF473097a2fC38ef61633A3C7A', + decimals: 6, + }, + 321: { + ypool: '0xF526EFc174b512e66243Cb52524C1BE720144e8d', + ypoolToken: '0x0039f574eE5cC39bdD162E9A88e3EB1f111bAF48', + decimals: 18, + }, + 42161: { + ypool: '0x7a483730AD5a845ED2962c49DE38Be1661D47341', + ypoolToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', + decimals: 6, + }, + 43114: { + ypool: '0x3D2d1ce29B8bC997733D318170B68E63150C6586', + ypoolToken: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7', + decimals: 6, + }, + 10: { + ypool: '0xF526EFc174b512e66243Cb52524C1BE720144e8d', + ypoolToken: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', + decimals: 6, + }, + 1285: { + ypool: '0xF526EFc174b512e66243Cb52524C1BE720144e8d', + ypoolToken: '0xB44a9B6905aF7c801311e8F4E76932ee959c663C', + decimals: 6, + }, + 8217: { + ypool: '0xF526EFc174b512e66243Cb52524C1BE720144e8d', + ypoolToken: '0xceE8FAF64bB97a73bb51E115Aa89C17FfA8dD167', + decimals: 6, + }, + 108: { + ypool: '0x74A0EEA77e342323aA463098e959612d3Fe6E686', + ypoolToken: '0x4f3C8E20942461e2c3Bdd8311AC57B0c222f2b82', + decimals: 6, + }, + 592: { + ypool: '0xF526EFc174b512e66243Cb52524C1BE720144e8d', + ypoolToken: '0x3795C36e7D12A8c252A20C5a7B455f7c57b60283', + decimals: 6, + }, + // wemix + }, + ETH: { + 1: { + ypool: '0x57eA46759fed1B47C200a9859e576239A941df76', + ypoolToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + decimals: 18, + }, + 56: { + ypool: '0xa0ffc7eDB9DAa9C0831Cdf35b658e767ace33939', + ypoolToken: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + decimals: 18, + }, + 137: { + ypool: '0x29d91854B1eE21604119ddc02e4e3690b9100017', + ypoolToken: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + decimals: 18, + }, + 250: { + ypool: '0x5146ba1f786D41ba1E876b5Fd3aA56bD516Ed273', + ypoolToken: '0x74b23882a30290451A17c44f4F05243b6b58C76d', + decimals: 18, + }, + 25: { + ypool: '0x8266B0c8eF1d70cC4b04F8E8F7508256c0E1200f', + ypoolToken: '0xe44Fd7fCb2b1581822D0c862B68222998a0c299a', + decimals: 18, + }, + 42161: { + ypool: '0xd1ae4594E47C153ae98F09E0C9267FB74447FEa3', + ypoolToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + decimals: 18, + }, + 43114: { + ypool: '0xEFaaf68a9a8b7D93bb15D29c8B77FCe87Fcc91b8', + ypoolToken: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB', + decimals: 18, + }, + 10: { + ypool: '0x91474Fe836BBBe63EF72De2846244928860Bce1B', + ypoolToken: '0x4200000000000000000000000000000000000006', + decimals: 18, + }, + 324: { + ypool: '0x935283A00FBF8E40fd2f8C432A488F6ADDC8dB67', + ypoolToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + decimals: 18, + }, + 1101: { + ypool: '0x9fE77412aA5c6Ba67fF3095bBc534884F9a61a38', + ypoolToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + decimals: 18, + }, + }, +}; + +const RPC_ENDPOINTS = { + 1: 'https://rpc.ankr.com/eth', + 56: 'https://rpc.ankr.com/bsc', + 137: 'https://rpc.ankr.com/polygon', + 250: 'https://rpc.ankr.com/fantom', + 25: 'https://rpc.vvs.finance', + 42161: 'https://endpoints.omniatech.io/v1/arbitrum/one/public', + 10: 'https://optimism.api.onfinality.io/public', + 108: 'https://mainnet-rpc.thundercore.com', + 43114: 'https://rpc.ankr.com/avalanche', + 321: 'https://rpc-mainnet.kcc.network', + 592: 'https://evm.astar.network', + 1285: 'https://rpc.api.moonriver.moonbeam.network', + 8217: 'https://rpc.ankr.com/klaytn', + // 1111: 'Wemix', + 324: 'https://mainnet.era.zksync.io', + 1101: 'https://zkevm-rpc.com', +}; + +exports.chainSupported = (chainId) => { + return chainId in SUPPORTED_CHAIN_NAMES; +}; +exports.ethereumRefUnderlyingTokenAddress = (symbol) => { + return ETHEREUM_REF_POOL_UNDERLYINGS[symbol]; +}; + +exports.supportedChainName = (chainId) => { + return SUPPORTED_CHAIN_NAMES[chainId]; +}; + +exports.YPoolInfo = (symbol, chainId) => { + return YPOOL_INFOS[symbol][chainId]; +}; + +exports.RPCEndpoint = (chainId) => { + return RPC_ENDPOINTS[chainId]; +}; diff --git a/src/adaptors/xy-finance/index.js b/src/adaptors/xy-finance/index.js new file mode 100644 index 0000000000..fb3deff835 --- /dev/null +++ b/src/adaptors/xy-finance/index.js @@ -0,0 +1,91 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const superagent = require('superagent'); +const { + chainSupported, + ethereumRefUnderlyingTokenAddress, + supportedChainName, + YPoolInfo, + RPCEndpoint, +} = require('./config'); +const { ContractABIs } = require('./abi'); + +const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; + +const getTokenBalance = (provider, tokenAddress, ownerAddress, decimals) => { + const tokenContract = new ethers.Contract( + tokenAddress, + ContractABIs.miniERC20ABI, + provider + ); + return tokenContract.balanceOf(ownerAddress).then((balance) => { + return balance / Math.pow(10, decimals); + }); +}; + +const main = async () => { + const { data: resp } = await axios.get( + 'https://api.xy.finance/ypool/stats/eachVault' + ); + if (!resp.isSuccess) { + throw new Error('Failed to fetch data from XY Finance'); + } + + var pools = []; + for (const [symbol, vaultInfo] of Object.entries(resp.eachYpoolVault)) { + const refAddr = ethereumRefUnderlyingTokenAddress(symbol); + const key = `ethereum:${refAddr}`; + const priceRes = await superagent.get( + `https://coins.llama.fi/prices/current/${key}` + ); + const tokenPrice = priceRes.body.coins[key].price; + for (const chainId of vaultInfo.supportedChains) { + if (!chainSupported(chainId)) { + continue; + } + + try { + const ypoolInfo = YPoolInfo(symbol, chainId); + console.log(chainId, ypoolInfo); + + let ypoolLocked = 0; + let provider = new ethers.providers.JsonRpcProvider( + RPCEndpoint(chainId) + ); + if (ypoolInfo.ypoolToken === NATIVE_TOKEN_ADDRESS) { + await provider.getBalance(ypoolInfo.ypool).then((balance) => { + ypoolLocked = ethers.utils.formatEther(balance); + }); + } else { + ypoolLocked = await getTokenBalance( + provider, + ypoolInfo.ypoolToken, + ypoolInfo.ypool, + ypoolInfo.decimals + ); + } + + const chainName = supportedChainName(chainId); + pools.push({ + pool: `ypool-${ypoolInfo.ypool}-${chainName}`.toLowerCase(), + chain: chainName, + project: 'xy-finance', + symbol: symbol, + apyBase: Number(vaultInfo.dayAPY), + apyBase7d: Number(vaultInfo.weekAPY), + underlyingTokens: [ypoolInfo.ypoolToken], + tvlUsd: Number(ypoolLocked) * tokenPrice, + }); + } catch (err) { + console.log(err); + } + } + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.xy.finance/pools', +}; diff --git a/src/adaptors/y2k-v1/abi.js b/src/adaptors/y2k-v1/abi.js new file mode 100644 index 0000000000..92b6a36464 --- /dev/null +++ b/src/adaptors/y2k-v1/abi.js @@ -0,0 +1,3045 @@ +exports.ContractABIs = { + vaultABI: [ + { + "inputs": [ + { + "internalType": "address", + "name": "_assetAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "int256", + "name": "_strikePrice", + "type": "int256" + }, + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotController", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotFactory", + "type": "error" + }, + { + "inputs": [], + "name": "AddressZero", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyStarted", + "type": "error" + }, + { + "inputs": [], + "name": "EpochEndMustBeAfterBegin", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotFinished", + "type": "error" + }, + { + "inputs": [], + "name": "FeeCannotBe0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "FeeMoreThan150", + "type": "error" + }, + { + "inputs": [], + "name": "MarketEpochDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "MarketEpochExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "OwnerDidNotAuthorize", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_epoch", + "type": "uint256" + } + ], + "name": "calculateWithdrawalFeeValue", + "outputs": [ + { + "internalType": "uint256", + "name": "feeValue", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "changeController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "changeTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "epochBegin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEnd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_withdrawalFee", + "type": "uint256" + } + ], + "name": "createAssets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "endEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochNull", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epochsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idClaimTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idEpochBegin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idEpochEnded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idFinalTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_counterparty", + "type": "address" + } + ], + "name": "sendTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimTVL", + "type": "uint256" + } + ], + "name": "setClaimTVL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "setEpochNull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strikePrice", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenInsured", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + carouselABI: [ + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "isWETH", + "type": "bool" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenURI", + "type": "string" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strike", + "type": "uint256" + }, + { + "internalType": "address", + "name": "controller", + "type": "address" + }, + { + "internalType": "address", + "name": "emissionsToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "relayerFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minQueueDeposit", + "type": "uint256" + } + ], + "internalType": "struct Carousel.ConstructorArgs", + "name": "_data", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotController", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotFactory", + "type": "error" + }, + { + "inputs": [], + "name": "AddressZero", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyRollingOver", + "type": "error" + }, + { + "inputs": [], + "name": "AmountExceedsTVL", + "type": "error" + }, + { + "inputs": [], + "name": "BPSToHigh", + "type": "error" + }, + { + "inputs": [], + "name": "CanNotDepositETH", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_counterparty", + "type": "address" + } + ], + "name": "DestinationNotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyEnded", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyStarted", + "type": "error" + }, + { + "inputs": [], + "name": "EpochDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "EpochEndMustBeAfterBegin", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotResolved", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotStarted", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEpoch", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEpochId", + "type": "error" + }, + { + "inputs": [], + "name": "MinDeposit", + "type": "error" + }, + { + "inputs": [], + "name": "NoRolloverQueued", + "type": "error" + }, + { + "inputs": [], + "name": "OverflowQueue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "OwnerDidNotAuthorize", + "type": "error" + }, + { + "inputs": [], + "name": "RelayerFeeToLow", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "DepositInQueue", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "operations", + "type": "uint256" + } + ], + "name": "RelayerMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "name": "RolloverQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + } + ], + "name": "WithdrawWithEmissions", + "type": "event" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "minX", + "type": "int256" + }, + { + "internalType": "int256", + "name": "maxX", + "type": "int256" + } + ], + "name": "calculateFeePercent", + "outputs": [ + { + "internalType": "uint256", + "name": "_y", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "changeController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_depositFee", + "type": "uint256" + } + ], + "name": "changeDepositFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_relayerFee", + "type": "uint256" + } + ], + "name": "changeRelayerFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_addressesToDelist", + "type": "address[]" + } + ], + "name": "cleanUpRolloverQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "counterPartyVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "delistInRollover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "depositQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "emissions", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emissionsToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "enlistInRollover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochAccounting", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochConfig", + "outputs": [ + { + "internalType": "uint40", + "name": "epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochEnd", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochCreation", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochNull", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochResolved", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "finalTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllEpochs", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDepositQueueLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDepositQueueTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getEpochConfig", + "outputs": [ + { + "internalType": "uint40", + "name": "epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochEnd", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochCreation", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "getEpochDepositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetsAfterFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEpochsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "getRolloverIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "getRolloverPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getRolloverQueueItem", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRolloverQueueLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRolloverTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + } + ], + "name": "getRolloverTVLByEpochId", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "isEnlistedInRolloverQueue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isWETH", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minQueueDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_operations", + "type": "uint256" + } + ], + "name": "mintDepositInQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_operations", + "type": "uint256" + } + ], + "name": "mintRollovers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "ownerToRollOverQueueIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "previewAmountInShares", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledShareAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "previewEmissionsWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "resolveEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rolloverAccounting", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rolloverQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "sendTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_claimTVL", + "type": "uint256" + } + ], + "name": "setClaimTVL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_counterPartyVault", + "type": "address" + } + ], + "name": "setCounterPartyVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_emissionAmount", + "type": "uint256" + } + ], + "name": "setEmissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint40", + "name": "_epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "_epochEnd", + "type": "uint40" + }, + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + } + ], + "name": "setEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "setEpochNull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strike", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_wAddress", + "type": "address" + } + ], + "name": "whiteListAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedAddresses", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + miniERC20ABI: [ + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', type: 'uint256' }], + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + type: 'function', + }, + ] +}; \ No newline at end of file diff --git a/src/adaptors/y2k-v1/index.js b/src/adaptors/y2k-v1/index.js new file mode 100644 index 0000000000..c720014e97 --- /dev/null +++ b/src/adaptors/y2k-v1/index.js @@ -0,0 +1,251 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { ContractABIs } = require('./abi'); + +const chain = 'arbitrum'; +const rpcEndpoint = 'https://endpoints.omniatech.io/v1/arbitrum/one/public'; +const vault_factory = '0x984e0eb8fb687afa53fc8b33e12e04967560e092'; + +const ONE_YEAR_HOURS = 365 * 24; +const ONE_EPOCH_HOURS = 24 * 7; + +const abis = { + getVaults: { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'getVaults', + outputs: [ + { + internalType: 'address[]', + name: 'vaults', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + marketIndex: { + inputs: [], + name: 'marketIndex', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, +}; + +const getTokenBalance = (provider, tokenAddress, ownerAddress, decimals) => { + const tokenContract = new ethers.Contract( + tokenAddress, + ContractABIs.miniERC20ABI, + provider + ); + return tokenContract.balanceOf(ownerAddress).then((balance) => { + return balance / Math.pow(10, decimals); + }); +}; + +const getApy = async () => { + const provider = new ethers.providers.JsonRpcProvider(rpcEndpoint); + + const poolLength = ( + await sdk.api.abi.call({ + target: vault_factory, + chain, + abi: abis.marketIndex, + }) + ).output; + + const vaultRes = await sdk.api.abi.multiCall({ + abi: abis.getVaults, + calls: Array.from(Array(Number(poolLength)).keys()).map((i) => ({ + target: vault_factory, + params: i, + })), + chain, + }); + + const vaults = vaultRes.output + .map(({ output }) => output) + .flat() + .map((e) => e.toLowerCase()); + + const nameRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'name'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const names = nameRes.output.map(({ output }) => output); + + const assetRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'asset'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const assets = assetRes.output.map(({ output }) => output); + + const symbolsRes = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: assets.map((t, i) => ({ + target: t, + })), + chain, + }); + const symbols = symbolsRes.output.map((o) => o.output); + + const epochLengthRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'epochsLength'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const epochsLengths = epochLengthRes.output.map(({ output }) => output); + + const allEpochsRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'epochs'), + calls: epochsLengths + .map((epochLength, index) => { + return [...Array(Number(epochLength)).keys()].map((i) => ({ + target: vaults[index], + params: i, + })); + }) + .flat(), + chain, + }); + const allEpochs = {}; + allEpochsRes.output.forEach(({ input, output }) => { + if (!allEpochs[input.target]) { + allEpochs[input.target] = []; + } + allEpochs[input.target].push(output); + }); + + const claimTVLRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'idClaimTVL'), + calls: vaults + .map((vault, index) => { + return allEpochs[vault].map((epochId) => ({ + target: vault, + params: epochId, + })); + }) + .flat(), + chain, + }); + const claimTVLs = {}; + claimTVLRes.output.forEach(({ input, output }) => { + if (!claimTVLs[input.target]) { + claimTVLs[input.target] = []; + } + claimTVLs[input.target].push(output); + }); + + const finalTVLRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.vaultABI.find(({ name }) => name === 'idFinalTVL'), + calls: vaults + .map((vault, index) => { + return allEpochs[vault].map((epochId) => ({ + target: vault, + params: epochId, + })); + }) + .flat(), + chain, + }); + const finalTVLs = {}; + finalTVLRes.output.forEach(({ input, output }) => { + if (!finalTVLs[input.target]) { + finalTVLs[input.target] = []; + } + finalTVLs[input.target].push(output); + }); + + const underlyings = [...new Set(assets)]; + const prices = ( + await utils.getPrices( + underlyings.map((underlying) => `${chain}:${underlying}`) + ) + ).pricesByAddress; + + const tokenBalances = {}; + for (let i = 0; i < underlyings.length; i += 1) { + const vaultsForThisAsset = assets + .map((asset, index) => ({ + asset, + index, + })) + .filter((e) => e.asset === underlyings[i]) + .map((e) => vaults[e.index]); + + const balanceRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.miniERC20ABI.find(({ name }) => name === 'balanceOf'), + calls: vaultsForThisAsset.map((vault) => ({ + target: underlyings[i], + params: vault, + })), + chain, + }); + const balances = balanceRes.output.map(({ output }) => output); + balances.forEach((value, index) => { + tokenBalances[vaultsForThisAsset[index]] = value; + }); + } + + var pools = []; + for (let i = 0; i < vaults.length; i += 1) { + let lastRoi = 0; + for (let j = claimTVLs[vaults[i]].length - 1; j >= 0; j -= 1) { + const finalTVL = Number(finalTVLs[vaults[i]][j]); + const claimTVL = Number(claimTVLs[vaults[i]][j]); + if (finalTVL == 0) { + continue; + } + lastRoi = (claimTVL / finalTVL - 1) * 100; + break; + } + const apy = + 100 * ((1 + lastRoi / 100) ** (ONE_YEAR_HOURS / ONE_EPOCH_HOURS) - 1); + + const tokenLocked = Number(tokenBalances[vaults[i]]) / Math.pow(10, 18); + const tokenPrice = prices[assets[i].toLowerCase()]; + const tvlUsd = tokenLocked * tokenPrice; + + pools.push({ + pool: vaults[i], + poolMeta: names[i], + chain, + project: 'y2k-v1', + symbol: symbols[i], + apyBase: apy, + apyBase7d: apy, + underlyingTokens: [assets[i]], + tvlUsd, + url: 'https://app.y2k.finance/market', + }); + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/y2k-v2/abi.js b/src/adaptors/y2k-v2/abi.js new file mode 100644 index 0000000000..92b6a36464 --- /dev/null +++ b/src/adaptors/y2k-v2/abi.js @@ -0,0 +1,3045 @@ +exports.ContractABIs = { + vaultABI: [ + { + "inputs": [ + { + "internalType": "address", + "name": "_assetAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "int256", + "name": "_strikePrice", + "type": "int256" + }, + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotController", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotFactory", + "type": "error" + }, + { + "inputs": [], + "name": "AddressZero", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyStarted", + "type": "error" + }, + { + "inputs": [], + "name": "EpochEndMustBeAfterBegin", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotFinished", + "type": "error" + }, + { + "inputs": [], + "name": "FeeCannotBe0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "FeeMoreThan150", + "type": "error" + }, + { + "inputs": [], + "name": "MarketEpochDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "MarketEpochExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "OwnerDidNotAuthorize", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract ERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_epoch", + "type": "uint256" + } + ], + "name": "calculateWithdrawalFeeValue", + "outputs": [ + { + "internalType": "uint256", + "name": "feeValue", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "changeController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "changeTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "epochBegin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochEnd", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_withdrawalFee", + "type": "uint256" + } + ], + "name": "createAssets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "endEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochNull", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "epochsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idClaimTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idEpochBegin", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idEpochEnded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "idFinalTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_counterparty", + "type": "address" + } + ], + "name": "sendTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimTVL", + "type": "uint256" + } + ], + "name": "setClaimTVL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "setEpochNull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strikePrice", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenInsured", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + carouselABI: [ + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "isWETH", + "type": "bool" + }, + { + "internalType": "address", + "name": "assetAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenURI", + "type": "string" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "strike", + "type": "uint256" + }, + { + "internalType": "address", + "name": "controller", + "type": "address" + }, + { + "internalType": "address", + "name": "emissionsToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "relayerFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minQueueDeposit", + "type": "uint256" + } + ], + "internalType": "struct Carousel.ConstructorArgs", + "name": "_data", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotController", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "AddressNotFactory", + "type": "error" + }, + { + "inputs": [], + "name": "AddressZero", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyRollingOver", + "type": "error" + }, + { + "inputs": [], + "name": "AmountExceedsTVL", + "type": "error" + }, + { + "inputs": [], + "name": "BPSToHigh", + "type": "error" + }, + { + "inputs": [], + "name": "CanNotDepositETH", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_counterparty", + "type": "address" + } + ], + "name": "DestinationNotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyEnded", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "EpochAlreadyStarted", + "type": "error" + }, + { + "inputs": [], + "name": "EpochDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "EpochEndMustBeAfterBegin", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotResolved", + "type": "error" + }, + { + "inputs": [], + "name": "EpochNotStarted", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEpoch", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEpochId", + "type": "error" + }, + { + "inputs": [], + "name": "MinDeposit", + "type": "error" + }, + { + "inputs": [], + "name": "NoRolloverQueued", + "type": "error" + }, + { + "inputs": [], + "name": "OverflowQueue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "OwnerDidNotAuthorize", + "type": "error" + }, + { + "inputs": [], + "name": "RelayerFeeToLow", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "DepositInQueue", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "operations", + "type": "uint256" + } + ], + "name": "RelayerMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "name": "RolloverQueued", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "emissions", + "type": "uint256" + } + ], + "name": "WithdrawWithEmissions", + "type": "event" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "minX", + "type": "int256" + }, + { + "internalType": "int256", + "name": "maxX", + "type": "int256" + } + ], + "name": "calculateFeePercent", + "outputs": [ + { + "internalType": "uint256", + "name": "_y", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "changeController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_depositFee", + "type": "uint256" + } + ], + "name": "changeDepositFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_relayerFee", + "type": "uint256" + } + ], + "name": "changeRelayerFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "claimTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_addressesToDelist", + "type": "address[]" + } + ], + "name": "cleanUpRolloverQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "counterPartyVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "delistInRollover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "depositQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "emissions", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "emissionsToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "enlistInRollover", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochAccounting", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochConfig", + "outputs": [ + { + "internalType": "uint40", + "name": "epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochEnd", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochCreation", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochNull", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochResolved", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "epochs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "finalTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllEpochs", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDepositQueueLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDepositQueueTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "getEpochConfig", + "outputs": [ + { + "internalType": "uint40", + "name": "epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochEnd", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "epochCreation", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "getEpochDepositFee", + "outputs": [ + { + "internalType": "uint256", + "name": "feeAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "assetsAfterFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEpochsLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "getRolloverIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "getRolloverPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "getRolloverQueueItem", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRolloverQueueLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRolloverTVL", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + } + ], + "name": "getRolloverTVLByEpochId", + "outputs": [ + { + "internalType": "uint256", + "name": "tvl", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "isEnlistedInRolloverQueue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isWETH", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minQueueDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_operations", + "type": "uint256" + } + ], + "name": "mintDepositInQueue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_operations", + "type": "uint256" + } + ], + "name": "mintRollovers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "ownerToRollOverQueueIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "previewAmountInShares", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledShareAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_assets", + "type": "uint256" + } + ], + "name": "previewEmissionsWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "entitledAssets", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "relayerFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "resolveEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rolloverAccounting", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "rolloverQueue", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "epochId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "sendTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_claimTVL", + "type": "uint256" + } + ], + "name": "setClaimTVL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_counterPartyVault", + "type": "address" + } + ], + "name": "setCounterPartyVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_emissionAmount", + "type": "uint256" + } + ], + "name": "setEmissions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint40", + "name": "_epochBegin", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "_epochEnd", + "type": "uint40" + }, + { + "internalType": "uint256", + "name": "_epochId", + "type": "uint256" + } + ], + "name": "setEpoch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "setEpochNull", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "strike", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_wAddress", + "type": "address" + } + ], + "name": "whiteListAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedAddresses", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + miniERC20ABI: [ + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', type: 'uint256' }], + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + type: 'function', + }, + ] +}; \ No newline at end of file diff --git a/src/adaptors/y2k-v2/index.js b/src/adaptors/y2k-v2/index.js new file mode 100644 index 0000000000..ca6650c39d --- /dev/null +++ b/src/adaptors/y2k-v2/index.js @@ -0,0 +1,202 @@ +const axios = require('axios'); +const ethers = require('ethers'); +const superagent = require('superagent'); +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { ContractABIs } = require('./abi'); + +const chain = 'arbitrum'; +const rpcEndpoint = 'https://endpoints.omniatech.io/v1/arbitrum/one/public'; + +const factory = '0xC3179AC01b7D68aeD4f27a19510ffe2bfb78Ab3e'; +const topic0_market_create = + '0xe8066e93c2c1e100c0c76002a546075b7c6b53025db53708875180c81afda250'; +const event_market_create = + 'event MarketCreated (uint256 indexed marketId, address premium, address collateral, address underlyingAsset, address token, string name, uint256 strike, address controller)'; + +const contract_interface = new ethers.utils.Interface([event_market_create]); + +const ONE_YEAR_HOURS = 365 * 24; +const ONE_EPOCH_HOURS = 166; + +const getTokenBalance = (provider, tokenAddress, ownerAddress, decimals) => { + const tokenContract = new ethers.Contract( + tokenAddress, + ContractABIs.miniERC20ABI, + provider + ); + return tokenContract.balanceOf(ownerAddress).then((balance) => { + return balance / Math.pow(10, decimals); + }); +}; + +const getApy = async () => { + const provider = new ethers.providers.JsonRpcProvider(rpcEndpoint); + const toBlock = (await sdk.api.util.getLatestBlock(chain)).number; + + const logs_market_create = ( + await sdk.api.util.getLogs({ + target: factory, + topic: '', + fromBlock: 96059531, + toBlock: toBlock, + topics: [topic0_market_create], + keys: [], + chain, + }) + ).output; + + const market_create = logs_market_create.map( + (e) => contract_interface.parseLog(e).args + ); + + const premiumVaults = market_create.map((e) => e.premium); + const collateralVaults = market_create.map((e) => e.collateral); + const vaults = [...premiumVaults, ...collateralVaults]; + + const nameRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.carouselABI.find(({ name }) => name === 'name'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const names = nameRes.output.map(({ output }) => output); + + const assetRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.carouselABI.find(({ name }) => name === 'asset'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const assets = assetRes.output.map(({ output }) => output); + + const symbolsRes = await sdk.api.abi.multiCall({ + abi: 'erc20:symbol', + calls: assets.map((t, i) => ({ + target: t, + })), + chain, + }); + const symbols = symbolsRes.output.map((o) => o.output); + + const getAllEpochsRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.carouselABI.find(({ name }) => name === 'getAllEpochs'), + calls: vaults.map((vault) => ({ + target: vault, + })), + chain, + }); + const allEpochs = getAllEpochsRes.output.map(({ output }) => output); + + const claimTVLRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.carouselABI.find(({ name }) => name === 'claimTVL'), + calls: vaults + .map((vault, index) => { + return allEpochs[index].map((epochId) => ({ + target: vault, + params: epochId, + })); + }) + .flat(), + chain, + }); + const claimTVLs = {}; + claimTVLRes.output.forEach(({ input, output }) => { + if (!claimTVLs[input.target]) { + claimTVLs[input.target] = []; + } + claimTVLs[input.target].push(output); + }); + + const finalTVLRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.carouselABI.find(({ name }) => name === 'finalTVL'), + calls: vaults + .map((vault, index) => { + return allEpochs[index].map((epochId) => ({ + target: vault, + params: epochId, + })); + }) + .flat(), + chain, + }); + const finalTVLs = {}; + finalTVLRes.output.forEach(({ input, output }) => { + if (!finalTVLs[input.target]) { + finalTVLs[input.target] = []; + } + finalTVLs[input.target].push(output); + }); + + const underlyings = [...new Set(assets)]; + const prices = ( + await utils.getPrices( + underlyings.map((underlying) => `${chain}:${underlying}`) + ) + ).pricesByAddress; + + const tokenBalances = {}; + for (let i = 0; i < underlyings.length; i += 1) { + const vaultsForThisAsset = assets + .map((asset, index) => ({ + asset, + index, + })) + .filter((e) => e.asset === underlyings[i]) + .map((e) => vaults[e.index]); + + const balanceRes = await sdk.api.abi.multiCall({ + abi: ContractABIs.miniERC20ABI.find(({ name }) => name === 'balanceOf'), + calls: vaultsForThisAsset.map((vault) => ({ + target: underlyings[i], + params: vault, + })), + chain, + }); + const balances = balanceRes.output.map(({ output }) => output); + balances.forEach((value, index) => { + tokenBalances[vaultsForThisAsset[index]] = value; + }); + } + + var pools = []; + for (let i = 0; i < vaults.length; i += 1) { + let lastRoi = 0; + for (let j = claimTVLs[vaults[i]].length - 1; j >= 0; j -= 1) { + const finalTVL = Number(finalTVLs[vaults[i]][j]); + const claimTVL = Number(claimTVLs[vaults[i]][j]); + if (finalTVL == 0) { + continue; + } + lastRoi = (claimTVL / finalTVL - 1) * 100; + break; + } + const apy = + 100 * ((1 + lastRoi / 100) ** (ONE_YEAR_HOURS / ONE_EPOCH_HOURS) - 1); + + const tokenLocked = Number(tokenBalances[vaults[i]]) / Math.pow(10, 18); + const tokenPrice = prices[assets[i].toLowerCase()]; + const tvlUsd = tokenLocked * tokenPrice; + + pools.push({ + pool: vaults[i], + poolMeta: names[i], + chain, + project: 'y2k-v2', + symbol: symbols[i], + apyBase: apy, + apyBase7d: apy, + underlyingTokens: [assets[i]], + tvlUsd, + url: 'https://app.y2k.finance/market', + }); + } + return pools; +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/yama-finance/abiLockup.js b/src/adaptors/yama-finance/abiLockup.js new file mode 100644 index 0000000000..c55ff52a75 --- /dev/null +++ b/src/adaptors/yama-finance/abiLockup.js @@ -0,0 +1,502 @@ +module.exports = [ + { + "inputs": [ + { + "internalType": "contract YSS", + "name": "_stablecoin", + "type": "address" + }, + { + "internalType": "contract PegStabilityModule", + "name": "_psm", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_psmToken", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "prod1", + "type": "uint256" + } + ], + "name": "PRBMath__MulDivFixedPointOverflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "prod1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "denominator", + "type": "uint256" + } + ], + "name": "PRBMath__MulDivOverflow", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "extStableAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "yamaAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockupAmount", + "type": "uint256" + } + ], + "name": "Lockup", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "yamaAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockupAmount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bsh", + "outputs": [ + { + "internalType": "contract SimpleBSH", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "extStableAmount", + "type": "uint256" + } + ], + "name": "lockup", + "outputs": [ + { + "internalType": "uint256", + "name": "lockupAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "psm", + "outputs": [ + { + "internalType": "contract PegStabilityModule", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "psmToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract SimpleBSH", + "name": "_bsh", + "type": "address" + } + ], + "name": "setBSH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stablecoin", + "outputs": [ + { + "internalType": "contract YSS", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "uint256", + "name": "value_", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lockupAmount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "yamaAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/adaptors/yama-finance/index.js b/src/adaptors/yama-finance/index.js new file mode 100644 index 0000000000..d34bcd043e --- /dev/null +++ b/src/adaptors/yama-finance/index.js @@ -0,0 +1,99 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const abiLockup = require('./abiLockup'); + +const calcYield = async (chain, lockupAddress, extStableAddress) => { + const latestBlock = await sdk.api.util.getLatestBlock(chain); + + const SECONDS_IN_DAY = 86400; + const DAYS_IN_YEAR = 365; + + const oldBlock = await sdk.api.util.lookupBlock( + latestBlock.timestamp - SECONDS_IN_DAY, + { chain: chain } + ); + const oldBlock7d = await sdk.api.util.lookupBlock( + latestBlock.timestamp - SECONDS_IN_DAY * 7, + { chain: chain } + ); + + const valueOld = + ( + await sdk.api.abi.call({ + target: lockupAddress, + abi: abiLockup.find((m) => m.name === 'value'), + chain: chain, + block: oldBlock.block, + }) + ).output / + 10 ** 18; + + const valueOld7d = + ( + await sdk.api.abi.call({ + target: lockupAddress, + abi: abiLockup.find((m) => m.name === 'value'), + chain: chain, + block: oldBlock7d.block, + }) + ).output / + 10 ** 18; + + const totalSupply = + ( + await sdk.api.abi.call({ + target: lockupAddress, + abi: abiLockup.find((m) => m.name === 'totalSupply'), + chain: chain, + block: latestBlock.number, + }) + ).output / + 10 ** 18; + + const value = + ( + await sdk.api.abi.call({ + target: lockupAddress, + abi: abiLockup.find((m) => m.name === 'value'), + chain: chain, + block: latestBlock.number, + }) + ).output / + 10 ** 18; + + const apy = ((value / valueOld) ** DAYS_IN_YEAR - 1) * 100; + const apy7d = ((value / valueOld7d) ** (DAYS_IN_YEAR / 7) - 1) * 100; + + return { + pool: lockupAddress + '-' + chain, + chain: utils.formatChain(chain), + project: 'yama-finance', + symbol: utils.formatSymbol('USDT'), + tvlUsd: totalSupply * value, + apyBase: apy, + apyBase7d: apy7d, + underlyingTokens: [extStableAddress], + poolMeta: 'USDT PSM LP', + }; +}; + +const main = async () => { + return [ + await calcYield( + 'arbitrum', + '0x3296EE4Fa62D0D78B1999617886E969a22653383', + '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9' + ), + await calcYield( + 'polygon_zkevm', + '0xd34296f80676A9F3AF103c3acE6BCCFF8E26a92c', + '0x1E4a5963aBFD975d8c9021ce480b42188849D41d' + ), + ]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://yama.finance/app/lend', +}; diff --git a/src/adaptors/yearn-finance/index.js b/src/adaptors/yearn-finance/index.js index ee20bd4eeb..baa5048f22 100755 --- a/src/adaptors/yearn-finance/index.js +++ b/src/adaptors/yearn-finance/index.js @@ -1,49 +1,62 @@ const utils = require('../utils'); -const baseUrl = 'https://api.yearn.finance/v1/chains'; - -const urls = { - ethereum: `${baseUrl}/1/vaults/all`, - fantom: `${baseUrl}/250/vaults/all`, - arbitrum: `${baseUrl}/42161/vaults/all`, -}; - -const buildPool = (entry, chainString) => { - const newObj = { - pool: entry.address, - chain: utils.formatChain(chainString), - project: 'yearn-finance', - symbol: utils.formatSymbol(entry.symbol), - tvlUsd: entry.tvl.tvl, - apy: entry.apy.net_apy * 100, - }; - return newObj; +const chains = { + ethereum: 1, + fantom: 250, + arbitrum: 42161, + optimism: 10, + base: 8453, + katana: 747474, }; -const topLvl = async (chainString) => { - // pull data - let data = await utils.getData(urls[chainString]); - - // filter to v2 only - data = data.filter((el) => el.type === 'v2'); - - // build pool objects - data = data.map((el) => buildPool(el, chainString)); - - return data; -}; - -const main = async () => { - const data = await Promise.all([ - topLvl('ethereum'), - topLvl('fantom'), - topLvl('arbitrum'), - ]); - - return data.flat(); +const getApy = async () => { + const data = await Promise.all( + Object.entries(chains).map(async (chain) => { + const data = await utils.getData( + `https://ydaemon.yearn.fi/${chain[1]}/vaults/all` + ); + + return data.map((p) => { + if (p.details.isRetired || p.details.isHidden) return {}; + + const underlying = p.token.underlyingTokensAddresses; + + // OP incentives via yvToken staking + const apyReward = p.apr?.extra?.stakingRewardsAPR * 100 ?? 0; + + const forwardAPR = p.apr.forwardAPR?.netAPR; + const apyBase = (forwardAPR ?? p.apr.netAPR) * 100; + + return { + pool: p.address, + chain: utils.formatChain(chain[0]), + project: 'yearn-finance', + symbol: utils.formatSymbol(p.token.display_symbol), + tvlUsd: p.tvl.tvl, + apyBase, + apyReward, + rewardTokens: + apyReward > 0 ? ['0x4200000000000000000000000000000000000042'] : [], + url: `https://yearn.fi/${ + p.version.substring(0, 1) == '3' ? 'v3' : 'vaults' + }/${chains[chain[0]]}/${p.address}`, + underlyingTokens: + underlying.length === 0 ? [p.token.address] : underlying, + }; + }); + }) + ); + + return ( + data + .flat() + .filter((p) => utils.keepFinite(p)) + // old usdc vault + .filter((p) => p.pool !== '0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9') + ); }; module.exports = { timetravel: false, - apy: main, + apy: getApy, }; diff --git a/src/adaptors/yel-finance/abis/erc20.abi.json b/src/adaptors/yel-finance/abis/erc20.abi.json new file mode 100644 index 0000000000..d094cbc5ea --- /dev/null +++ b/src/adaptors/yel-finance/abis/erc20.abi.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } + ] \ No newline at end of file diff --git a/src/adaptors/yel-finance/abis/potion.abi.json b/src/adaptors/yel-finance/abis/potion.abi.json new file mode 100644 index 0000000000..baec3eb1db --- /dev/null +++ b/src/adaptors/yel-finance/abis/potion.abi.json @@ -0,0 +1,792 @@ +[ + { + "inputs": [ + { "internalType": "string", "name": "_name", "type": "string" }, + { "internalType": "string", "name": "_symbol", "type": "string" }, + { + "components": [ + { "internalType": "uint256", "name": "burn", "type": "uint256" }, + { "internalType": "uint256", "name": "bond", "type": "uint256" }, + { "internalType": "uint256", "name": "debond", "type": "uint256" }, + { "internalType": "uint256", "name": "buy", "type": "uint256" }, + { "internalType": "uint256", "name": "sell", "type": "uint256" }, + { "internalType": "uint256", "name": "partner", "type": "uint256" } + ], + "internalType": "struct IDecentralizedIndex.Fees", + "name": "_fees", + "type": "tuple" + }, + { "internalType": "address[]", "name": "_tokens", "type": "address[]" }, + { "internalType": "uint256[]", "name": "_weights", "type": "uint256[]" }, + { "internalType": "address", "name": "_partner", "type": "address" }, + { + "internalType": "address", + "name": "_pairedLpToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_lpRewardsToken", + "type": "address" + }, + { "internalType": "address", "name": "_v2Router", "type": "address" }, + { "internalType": "bool", "name": "_stakeRestriction", "type": "bool" }, + { "internalType": "address", "name": "ownerAddress", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "InvalidShortString", "type": "error" }, + { + "inputs": [{ "internalType": "string", "name": "str", "type": "string" }], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountDAI", + "type": "uint256" + } + ], + "name": "AddLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountTokensBonded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountTokensMinted", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "feesBond", + "type": "uint256" + } + ], + "name": "Bond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "buyFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Buy", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newIdx", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + } + ], + "name": "Create", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountDebonded", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "feesDebond", + "type": "uint256" + } + ], + "name": "Debond", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FlashLoan", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "wallet", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountLiquidity", + "type": "uint256" + } + ], + "name": "RemoveLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "sellFee", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Sell", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BOND_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DAI", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEBOND_FEE", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAIRED_LP_TOKEN", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_idxLPTokens", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_pairedLPTokens", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_slippage", "type": "uint256" }, + { "internalType": "uint256", "name": "_deadline", "type": "uint256" } + ], + "name": "addLiquidityV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "uint256", "name": "_amountMintMin", "type": "uint256" } + ], + "name": "bond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "created", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_amount", "type": "uint256" }, + { "internalType": "address[]", "name": "", "type": "address[]" }, + { "internalType": "uint8[]", "name": "", "type": "uint8[]" } + ], + "name": "debond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "version", "type": "string" }, + { "internalType": "uint256", "name": "chainId", "type": "uint256" }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, + { "internalType": "uint256[]", "name": "extensions", "type": "uint256[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fees", + "outputs": [ + { "internalType": "uint256", "name": "burn", "type": "uint256" }, + { "internalType": "uint256", "name": "bond", "type": "uint256" }, + { "internalType": "uint256", "name": "debond", "type": "uint256" }, + { "internalType": "uint256", "name": "buy", "type": "uint256" }, + { "internalType": "uint256", "name": "sell", "type": "uint256" }, + { "internalType": "uint256", "name": "partner", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllAssets", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "weighting", "type": "uint256" }, + { + "internalType": "uint256", + "name": "basePriceUSDX96", + "type": "uint256" + }, + { "internalType": "address", "name": "c1", "type": "address" }, + { "internalType": "uint256", "name": "q1", "type": "uint256" } + ], + "internalType": "struct IDecentralizedIndex.IndexAssetInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getIdxPriceUSDX96", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_sourceToken", "type": "address" }, + { "internalType": "uint256", "name": "_sourceAmount", "type": "uint256" }, + { "internalType": "address", "name": "_targetToken", "type": "address" } + ], + "name": "getInitialAmount", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "getTokenPriceUSDX96", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "indexTokens", + "outputs": [ + { "internalType": "address", "name": "token", "type": "address" }, + { "internalType": "uint256", "name": "weighting", "type": "uint256" }, + { + "internalType": "uint256", + "name": "basePriceUSDX96", + "type": "uint256" + }, + { "internalType": "address", "name": "c1", "type": "address" }, + { "internalType": "uint256", "name": "q1", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "indexType", + "outputs": [ + { + "internalType": "enum IDecentralizedIndex.IndexType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "isAsset", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpRewardsToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lpStakingPool", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "nonces", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "partner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint8", "name": "v", "type": "uint8" }, + { "internalType": "bytes32", "name": "r", "type": "bytes32" }, + { "internalType": "bytes32", "name": "s", "type": "bytes32" } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "processPreSwapFeesAndSwap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_lpTokens", "type": "uint256" }, + { "internalType": "uint256", "name": "_minIdxTokens", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_minPairedLpToken", + "type": "uint256" + }, + { "internalType": "uint256", "name": "_deadline", "type": "uint256" } + ], + "name": "removeLiquidityV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" } + ], + "name": "rescueERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rescueETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "burn", "type": "uint256" }, + { "internalType": "uint256", "name": "bond", "type": "uint256" }, + { "internalType": "uint256", "name": "debond", "type": "uint256" }, + { "internalType": "uint256", "name": "buy", "type": "uint256" }, + { "internalType": "uint256", "name": "sell", "type": "uint256" }, + { "internalType": "uint256", "name": "partner", "type": "uint256" } + ], + "internalType": "struct IDecentralizedIndex.Fees", + "name": "_fees", + "type": "tuple" + } + ], + "name": "setFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_partner", "type": "address" } + ], + "name": "setPartner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/adaptors/yel-finance/index.js b/src/adaptors/yel-finance/index.js new file mode 100644 index 0000000000..07f8b9add0 --- /dev/null +++ b/src/adaptors/yel-finance/index.js @@ -0,0 +1,159 @@ +const axios = require('axios'); +const sdk = require('@defillama/sdk'); + +const erc20Abi = require('./abis/erc20.abi.json'); +const potionAbi = require('./abis/potion.abi.json'); + +const BASE_URL = 'https://coins.llama.fi/prices/current/'; +const POTIONS_URL = 'https://yel.finance/potions'; + +const CHAINS = { + 81457: 'Blast', + 8453: 'Base', + 250 : 'Fantom', + 146 : 'Sonic' +}; + +const PROJECT_NAME = 'yel-finance'; + +const POTION_SINGLE_STAKING_LIST = { + 81457: { + // Potion Potion Base token + '0x795a85CD543D0E2d29F7e11e33a20a38A4b5121e': '0x4300000000000000000000000000000000000004', // lWETH / WETH + '0x07BF0Bc908Ef4badF8ec0fB1f77A8dBFe33c33c0': '0xb1a5700fA2358173Fe465e6eA4Ff52E36e88E2ad', // lBLAST / Blast + '0x7d2f5881F0C4B840fcFA2c49F4052d1A004eAf0d': '0x949185D3BE66775Ea648F4a306740EA9eFF9C567', // lYEL / YEL + '0xC107e89b842403D3f3Be56D3b611a74388FF69dA': '0xe36072dd051ce26261bf50cd966311cab62c596e' // lTHRUST / THRUST + }, + 8453 : { + // Potion Potion Base token + '0x56a827776511689d6502c5213425c4BFBE3915d1' : '0x4200000000000000000000000000000000000006', // lWETH / WETH + '0x8ca29479CECa6eE24539508B90A02ec1939B88c6' : '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // lUSDC / USDC + '0x1DC50dA045Ad23812c22148e03D62C9691958B47' : '0x949185D3BE66775Ea648F4a306740EA9eFF9C567', // lYEL / YEL + '0x2c21bFc177E297A83EAa87793c29E592fe81CeAC': '0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C' // lANON / ANON + }, + 250 : { + // Potion Potion Base token + '0x97bB72E43Dc056621cBeC637e558C654A5cDe7d2' : '0x949185D3BE66775Ea648F4a306740EA9eFF9C567', // lYEL / YEL + '0x5FF262D0c0Ecd0923DE3d9C0be6308D86F1229B4' : '0x1B6382DBDEa11d97f24495C9A90b7c88469134a4', // laxlUSDC / axlUSDC + '0x9F7908Fc313f7A276c8366C5892839a26e66B5Bc' : '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83' // lWFTM / lWFTM + }, + + 146 : { + '0x7Ba0abb5f6bDCbf6409BB2803CdF801215424490': '0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38', // LSONIC / SONIC + '0x995171196618b7FE0F0C6D606D79583DD1c8ff60': '0x29219dd400f2Bf60E5a23d13Be72B486D4038894', // lUSDC / USDC + '0x92Dd17b19F74E696502Ee9eD478901F24c5d9a9A': '0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C', // lANON / ANON + '0xecf1b589F47511D23b026eF53D16FEbB89Aa5f3A': '0x0e0Ce4D450c705F8a0B6Dd9d5123e3df2787D16B', // lWAGMI / WAGMI + '0x6E074300A7Bf53af6e20f1f07dDDfeedAE5598A8': '0x949185D3BE66775Ea648F4a306740EA9eFF9C567', // lYEL / YEL - + '0xdE31054Fb0ee7c6C39641db2e677011E276644aC': '0x9fDbC3f8Abc05Fa8f3Ad3C17D2F806c1230c4564', // lGOGLZ / GOGLZ + '0x555733fBa1CA24ec45e7027E00C4B6c5065BaC96': '0xE5DA20F15420aD15DE0fa650600aFc998bbE3955', // lstS / stS + '0x85262a5121B8aD219C521665787A6F21eCbBf679': '0x7A0C53F7eb34C5BC8B01691723669adA9D6CB384', // lBOO / BOO - + '0x30Fb515Cf3e0C7fF94Aa923788B466F44768cAA4': '0x59524D5667B299c0813Ba3c99a11C038a3908fBC', // lYOKO / YOKO + '0x2C7A01DE0c419421EB590F9ECd98cBbca4B9eC2A': '0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE', // lscUSD / scUSD + '0x8a3B47d5e13fCeD000dC4cDcbE28EAA2A5Cc24e1': '0x3bcE5CB273F0F148010BbEa2470e7b5df84C7812', // lscETH / scETH + '0xde1F938A7EfE5203E66B4D0efA667f116cBC7C45': '0xb1e25689D55734FD3ffFc939c4C3Eb52DFf8A794', // lOS / OS + '0x828CAd5913CDbdf53A7a538647c8a27CB04a7112': '0x0e899dA2aD0817ed850ce68f7f489688E4D42D9D', // lGhog / GHOG + '0x75a65a8920Da26eBcCb79001ddE5F51AF0160006': '0x3333111A391cC08fa51353E9195526A70b333333', // lx33 / x33 + '0x24B77F92692496a374d67e277e6991DE5Ad73a48': '0x50c42dEAcD8Fc9773493ED674b675bE577f2634b', // lWETH / WETH + '0xBf7D0b0A5F520C7a4E45cf907502072846488d70': '0xddddd1b4a383dcB89938bC8b8964Cad3C632Fad0', // lMyrd / MYRD + } +}; + +const formatNumber = (n, decimals) => { + return n / 10 ** decimals; +}; + +const getAPY = async () => { + const promises = Object.keys(POTION_SINGLE_STAKING_LIST).map((chainId) => { + return Object.keys(POTION_SINGLE_STAKING_LIST[chainId]).map((address) => { + return getData({ + chainId: Number(chainId), + address, + }); + }); + }); + + return await Promise.all(promises.flat()); +}; + +const getData = async ({ chainId, address }) => { + const chain = CHAINS[chainId].toLowerCase(); + + const baseAsset = await sdk.api.abi.call({ + target: address, + abi: potionAbi.find(({ name }) => name === 'getAllAssets'), + chain, + }); + + const decimalsPotion = await sdk.api.abi.call({ + target: address, + abi: potionAbi.find(({ name }) => name === 'decimals'), + chain, + }); + + const totalSupplyPotion = await sdk.api.abi.call({ + target: address, + abi: potionAbi.find(({ name }) => name === 'totalSupply'), + chain, + }); + + const createdPotion = await sdk.api.abi.call({ + target: address, + abi: potionAbi.find(({ name }) => name === 'created'), + chain, + }); + + const symbol = await sdk.api.abi.call({ + target: baseAsset.output[0].token, + abi: erc20Abi.find(({ name }) => name === 'symbol'), + chain, + }); + + const baseAssetOnPotion = await sdk.api.abi.call({ + target: baseAsset.output[0].token, + abi: erc20Abi.find(({ name }) => name === 'balanceOf'), + params: [address], + chain, + }); + + const baseAssetDecimals = await sdk.api.abi.call({ + target: baseAsset.output[0].token, + abi: erc20Abi.find(({ name }) => name === 'decimals'), + chain, + }); + + const adjustedBaseAssetOnPotion = formatNumber(baseAssetOnPotion.output, baseAssetDecimals.output) + const adjustedTotalSupplyPotion = formatNumber(totalSupplyPotion.output, decimalsPotion.output) + + const backingRatio = adjustedBaseAssetOnPotion / adjustedTotalSupplyPotion - 1; //1 is basic constant + const currentTimestamp = Math.floor(Date.now() / 1000); + const timePassedSinceDeployment = currentTimestamp - createdPotion.output; + + const rewardsPerSec = backingRatio / timePassedSinceDeployment; + const apr = rewardsPerSec * 60 * 60 * 24 * 365 * 100; // mul 100 == convert to percent + const { data } = await axios.get( + `${BASE_URL}${CHAINS[chainId]}:${baseAsset.output[0].token}` + ); + + const baseTokenPrice = + data.coins[`${CHAINS[chainId]}:${baseAsset.output[0].token}`]?.price || 0; + + const baseAssetAmountFormated = formatNumber( + baseAssetOnPotion.output, + baseAssetDecimals.output + ); + const tvl = baseAssetAmountFormated * baseTokenPrice; + + return { + chain: CHAINS[chainId], + project: PROJECT_NAME, + pool: `${chainId}-${address}`, + symbol: symbol.output.replace('i', ''), + apyBase: Number(apr), + tvlUsd: Number(tvl), + }; +}; + +module.exports = { + apy: getAPY, + url: POTIONS_URL, +}; diff --git a/src/adaptors/yeti-finance/index.js b/src/adaptors/yeti-finance/index.js new file mode 100644 index 0000000000..d70345e39e --- /dev/null +++ b/src/adaptors/yeti-finance/index.js @@ -0,0 +1,82 @@ +const axios = require("axios"); +const utils = require('../utils'); + +function getSymbol(name) { + if (name === "WETHWAVAXJLP") { + return "WETH-WAVAX" + } else if (name === "AVAXUSDCJLP") { + return "AVAX-USDC" + } + + return name +} + +async function apr() { + const [ + { data: vaults }, + { data: tvls }, + { data: prices }, + { data: aprs }, + { data: vaultToName }, + { data: underlyingTokens}, + { data: yusdData } + ] = await Promise.all([ + axios.get(`https://api.yeti.finance/v1/yeticontroller/vaults`), + axios.get(`https://api.yeti.finance/v1/yeticontroller/tvls`), + axios.get(`https://api.yeti.finance/v1/yeticontroller/prices`), + axios.get(`https://api.yeti.finance/v1/collaterals`), + axios.get(`https://api.yeti.finance/v1/yeticontroller/vaultToName`), + axios.get(`https://api.yeti.finance/v1/yeticontroller/underlyingTokens`), + axios.get(`https://api.yeti.finance/v1/yusd/avax`) + ]); + + const vaultsLength = vaults.length; + + underlying = {} + + for (var i = 0; i < vaultsLength; i++) { + underlying[vaults[i]] = underlyingTokens[i] + } + + const vaultsToExclude = ["WAVAX", "USDC", "WETH", "WBTC", "av3CRV"] + + let vaultAPRs = [ + ...vaults.filter(v => v !== "0x0000000000000000000000000000000000000000" && !vaultsToExclude.includes(vaultToName[v])) + ].map( v => ( + { + pool: `Yeti-${vaultToName[v]}-Vault`, + chain: 'Avalanche', + project: 'yeti-finance', + symbol: getSymbol(vaultToName[v]), + tvlUsd: Number( + tvls[v] + ) / 10 ** 18 * Number(prices[v]) / 10 ** 18, + apy: Number(aprs[vaultToName[v]]?.APY?.value) * 100, + underlyingTokens: [underlying[v]] + })).filter(p => p.apy); + + const stabilityPool = [{ + pool: `Yeti-YUSD-StabilityPool`, + chain: 'Avalanche', + project: 'yeti-finance', + symbol: 'YUSD', + tvlUsd: Number( + yusdData.stabilityPoolDeposits.value) * Number(yusdData.YUSDPrice.value), + apy: Number(yusdData.stabilityPoolAPR.value) * 100, + underlyingTokens: ["0x111111111111ed1D73f860F57b2798b683f2d325"] + }] + + vaultAPRs = vaultAPRs.concat(stabilityPool) + + return vaultAPRs +}; + +const main = async () => { + return await apr(); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.yeti.finance/' +}; \ No newline at end of file diff --git a/src/adaptors/yield-protocol/index.js b/src/adaptors/yield-protocol/index.js new file mode 100644 index 0000000000..ab682e01a2 --- /dev/null +++ b/src/adaptors/yield-protocol/index.js @@ -0,0 +1,226 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { formatChain, formatSymbol } = require('../utils'); +const superagent = require('superagent'); +const { format } = require('date-fns'); +const { compact } = require('lodash'); + +const SUBGRAPHS = { + ethereum: sdk.graph.modifyEndpoint( + '7wjb6tjwaKtZagvNJ8eK18bHkEigLDePhvcryNbGbJEL' + ), + arbitrum: sdk.graph.modifyEndpoint( + '4pW9NfmTa6AwHV9KG3JU6RynQMaNR9dzchxBYF3vy4Q9' + ), +}; + +// in certain pools, the underlying is deposited to earn interest; therefore, as a liquidity provider, a portion of the provided liquidity earns interest +// currently only mainnet pools are depositing base (underlying) into euler markets to accumulate interest +const getBlendedSharesTokenAPY = async ( + sharesTokenAddr, + chain, + poolBaseValue, + sharesReserves, + currentSharePrice +) => { + if (chain !== 'ethereum') return 0; + + const EULER_SUPGRAPH_ENDPOINT = sdk.graph.modifyEndpoint( + 'EQBXhrF4ppZy9cBYnhPdrMCRaVas6seNpqviih5VRGmU' + ); + + const query = ` + query ($address: Bytes!) { + eulerMarketStore(id: "euler-market-store") { + markets(where:{eTokenAddress:$address}) { + supplyAPY + } + } + } +`; + + try { + const { + eulerMarketStore: { markets }, + } = await request(EULER_SUPGRAPH_ENDPOINT, query, { + address: sharesTokenAddr, + }); + const sharesAPY = (+markets[0].supplyAPY * 100) / 1e27; + + // convert shares to base + const sharesValRatio = (sharesReserves * currentSharePrice) / poolBaseValue; + return sharesAPY * sharesValRatio; + } catch (e) { + return 0; + } +}; + +const formatMaturity = (maturity) => { + return format(new Date(maturity * 1000), 'dd MMM yyyy'); +}; + +// get the total base borrowed for a specific seriesEntity +const getTotalBorrow = async (seriesEntityId, chain) => { + const url = SUBGRAPHS[chain]; + const query = gql` + { + vaults(where: { series: "${seriesEntityId}", debtAmount_gt: "0" }) { + debtAmount + } + } + `; + + const { vaults: subgraphVaults } = await request(url, query); + + const totalBorrow = subgraphVaults.reduce((acc, vault) => { + return acc + +vault.debtAmount; + }, 0); + + return totalBorrow; +}; + +const getPools = async (chain) => { + const url = SUBGRAPHS[chain]; + const query = gql` + { + seriesEntities(where: { matured: false }) { + id + fyToken { + id + pools { + borrowAPR + lendAPR + feeAPR + fyTokenInterestAPR + id + currentFYTokenPriceInBase + tvlInBase + sharesToken + baseReserves + currentSharePrice + } + totalSupply + symbol + } + maturity + baseAsset { + id + symbol + } + } + } + `; + const { seriesEntities } = await request(url, query); + // double check is not matured + const NOW = Math.floor(Date.now() / 1000); + const filteredSeriesEntities = seriesEntities.filter((s) => NOW < s.maturity); + + const pools = await Promise.all( + filteredSeriesEntities.map(async (seriesEntity) => { + const { + id: seriesEntityId, + fyToken: { + id: fyTokenAddr, + pools, + totalSupply: fyTokenTotalSupply, + symbol: fyTokenSymbol, + }, + maturity, + baseAsset: { id: baseAddr, symbol: baseSymbol }, + } = seriesEntity; + + const pool = pools[0]; // grab the first pool since there should be only one pool per seriesEntity + + const { + id: poolAddr, + currentFYTokenPriceInBase, + tvlInBase, + borrowAPR, + lendAPR, + fyTokenInterestAPR, + feeAPR, + sharesToken, + baseReserves, + currentSharePrice, + } = pool; + + // price of base token in USD terms + const key = `${chain}:${baseAddr}`; + const priceRes = await superagent.get( + `https://coins.llama.fi/prices/current/${key}` + ); + const price = priceRes.body.coins[key]; + const priceBaseUsd = price ? price.price : 0; + + // total base value in pool plus total fyToken value (in base) in pool, converted to USD + const tvlUsd = tvlInBase * priceBaseUsd; + // total fyTokens in circulation converted to base, then to USD + const totalSupplyUsd = + currentFYTokenPriceInBase * fyTokenTotalSupply * priceBaseUsd; + // total borrowed in USD for this specific pool/series + const totalBorrowUsd = + (await getTotalBorrow(seriesEntityId, chain)) * priceBaseUsd; + + // apy estimate when providing liquidity + // pool apy = sharesTokenAPY + fyTokenInterestAPR + feeAPR + // only calc if the pool uses shares token + const sharesTokenAPY = + baseAddr === sharesToken + ? 0 + : await getBlendedSharesTokenAPY( + sharesToken, + chain, + tvlInBase, + baseReserves, // when pool is tv, this is actually shares + currentSharePrice + ); + const poolAPY = sharesTokenAPY + +fyTokenInterestAPR + +feeAPR; + const poolRewardsAPY = 0; + + // split the yield protocol pool into a liquidity providing object, and a lending/borrowing object for ease of data representation + return [ + { + pool: `${poolAddr}-lp-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'yield-protocol', + symbol: baseSymbol, + underlyingTokens: [baseAddr, fyTokenAddr], + apyReward: poolRewardsAPY, // TODO: pool/strategy reward apy estimate + apyBase: poolAPY, // variable apy estimate for providing liquidity + tvlUsd, + url: `https://app.yieldprotocol.com/`, + poolMeta: `variable rate ${formatMaturity(maturity)}`, + }, + { + pool: `${poolAddr}-lendborrow-${chain}`.toLowerCase(), + chain: formatChain(chain), + project: 'yield-protocol', + symbol: baseSymbol, + underlyingTokens: [baseAddr, fyTokenAddr], + apyBase: +lendAPR, // fixed rate lend apr estimate when using one unit to the decimals of base + apyBaseBorrow: +borrowAPR, // fixed rate borrow apr estimate when using one unit to the decimals of base + tvlUsd, + totalSupplyUsd, + totalBorrowUsd, + url: `https://app.yieldprotocol.com/`, + poolMeta: `fixed rate ${formatMaturity(maturity)}`, + ltv: 0.7, // using 70% ltv, which is close to an eth/stable borrow, but the ltv differs between each collateral/base pair (there are many collateral assets available for each base) + }, + ]; + }) + ); + + return compact(pools).flat(); +}; + +const main = async () => { + return Object.keys(SUBGRAPHS).reduce(async (acc, chain) => { + return [...(await acc), ...(await getPools(chain))]; + }, Promise.resolve([])); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://app.yieldprotocol.com/', +}; diff --git a/src/adaptors/yield-yak-aggregator/index.js b/src/adaptors/yield-yak-aggregator/index.js new file mode 100644 index 0000000000..18402ee464 --- /dev/null +++ b/src/adaptors/yield-yak-aggregator/index.js @@ -0,0 +1,331 @@ +const axios = require('axios'); +const superagent = require('superagent'); +const { get } = require('lodash'); +const sdk = require('@defillama/sdk'); + +// Helper for chain ids +const CHAIN_CONFIG = { + '43114': { chain: 'avax', chainName: 'Avalanche' }, + '42161': { chain: 'arbitrum', chainName: 'Arbitrum' }, + '5000': { chain: 'mantle', chainName: 'Mantle' }, +} + +// Yield Yak vaults configuration +const VAULT_ACCOUNTANT_ABI = 'function getRate() external view returns (uint256)' +const VAULTS = [ + { + chainId: '43114', + address: '0xDf788AD40181894dA035B827cDF55C523bf52F67', + accountant: '0xA8d0c29cF475dD91Fe043D376bEFDDeEC2d2e24A', + symbol: 'rsAVAX', + underlyingToken: '0x2b2C81e08f1Af8835a78Bb2A90AE924ACE0eA4bE', + rateDecimals: 18, + }, + { + chainId: '43114', + address: '0x9D15A28fCB96AF5e26dd0EF546D6a777C0ec34cd', + accountant: '0x46520834D24FBF4e556576a8BB29eB8500378561', + symbol: 'rstAVAX', + underlyingToken: '0xA25EaF2906FA1a3a13EdAc9B9657108Af7B703e3', + rateDecimals: 18, + }, + { + chainId: '43114', + address: '0xe684F692bdf5B3B0DB7E8e31a276DE8A2E9F0025', + accountant: '0x57392E941a72cA47097135b9567C2c9Da8B2E0Fc', + symbol: 'rBTC.b', + underlyingToken: '0x152b9d0FdC40C096757F570A51E494bd4b943E50', + rateDecimals: 8, + }, + { + chainId: '43114', + address: '0xa845Cbe370B99AdDaB67AfE442F2cF5784d4dC29', + accountant: '0x6870599e4ffB6b9aB7facA3420875A1D2e188906', + symbol: 'aiAVAX', + underlyingToken: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', + rateDecimals: 18, + }, + { + chainId: '43114', + address: '0xdC038cFf8E55416a5189e37F382879c19217a4CB', + accountant: '0x5A26Fb0b0b008FB372E5F830b474ABF374FA11f8', + symbol: 'aiUSD', + underlyingToken: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', + rateDecimals: 6, + }, + { + chainId: '43114', + address: '0x0FB51627a4D9E01B24C427BB62Ed8d5C9018f8F6', + accountant: '0x00da610F7b9bc42fa2EF2D4BA312f8cD95131fA2', + symbol: 'aiBTC', + underlyingToken: '0x152b9d0FdC40C096757F570A51E494bd4b943E50', + rateDecimals: 6, + }, + { + chainId: '43114', + address: '0x72Ab674eC8FB2b2626Cf48131Fe34fC95075D9b5', + accountant: '0x5554A2b4dB48a5B923F7C74798F679F8458e3BE6', + symbol: 'sSUZ', + underlyingToken: '0x451532F1C9eb7E4Dc2d493dB52b682C0Acf6F5EF', + rateDecimals: 18, + } +]; + +/** + * Get prices for a list of addresses on a single chain + * @param {string} chain in slug format + * @param {string[]} addresses in format address + */ +const getPrices = async (chain, addresses) => { + if (!addresses || addresses.length === 0) { + return { pricesByAddress: {}, pricesBySymbol: {} }; + } + + const priceKeys = addresses.map((address) => `${chain}:${address}`).join(','); + const response = await superagent.get( + `https://coins.llama.fi/prices/current/${priceKeys.toLowerCase()}` + ); + + const prices = response.body.coins || {}; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +/** + * Get vault data for a single vault + * @param {Object} vaultConfig + * @param {string} vaultConfig.chainId + * @param {string} vaultConfig.address + * @param {string} vaultConfig.accountant + * @param {string} vaultConfig.symbol + * @param {string} vaultConfig.underlyingToken + * @param {number} vaultConfig.rateDecimals + */ +const getVaultData = async (vaultConfig) => { + const now = Math.floor(Date.now() / 1000); + const timestamp1dayAgo = now - 86400; + const timestamp7dayAgo = now - 86400 * 7; + + // Get block numbers for historical data + const chain = CHAIN_CONFIG[vaultConfig.chainId].chain; + const [block1dayAgo, block7dayAgo] = await Promise.all([ + axios.get(`https://coins.llama.fi/block/${chain}/${timestamp1dayAgo}`), + axios.get(`https://coins.llama.fi/block/${chain}/${timestamp7dayAgo}`) + ]); + + // Get exchange rates from accountant + const [ + currentRate, + rate1dayAgo, + rate7dayAgo, + currentSupplyWei + ] = await Promise.all([ + sdk.api.abi.call({ + target: vaultConfig.accountant, + abi: VAULT_ACCOUNTANT_ABI, + chain: chain + }), + sdk.api.abi.call({ + target: vaultConfig.accountant, + abi: VAULT_ACCOUNTANT_ABI, + chain: chain, + block: block1dayAgo.data.height + }), + sdk.api.abi.call({ + target: vaultConfig.accountant, + abi: VAULT_ACCOUNTANT_ABI, + chain: chain, + block: block7dayAgo.data.height + }), + sdk.api.abi.call({ + target: vaultConfig.address, + abi: 'erc20:totalSupply', + chain: chain + }) + ]); + + const totalSupply = currentSupplyWei.output / 1e18; + + // Get underlying token price + const priceKey = `${chain}:${vaultConfig.underlyingToken}`; + const underlyingPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + if (!underlyingPrice) { + console.log(`Underlying token price not found, skipping ${vaultConfig.symbol} vault`); + return null; + } + + // Calculate APY and TVL + const rateDenominator = 10 ** vaultConfig.rateDecimals; + const currentRateNormalized = currentRate.output / rateDenominator; + const rate1dayAgoNormalized = rate1dayAgo.output / rateDenominator; + const rate7dayAgoNormalized = rate7dayAgo.output / rateDenominator; + + // Calculate APY based on percentage change in exchange rate + const dailyRate = rate1dayAgoNormalized > 0 ? (currentRateNormalized - rate1dayAgoNormalized) / rate1dayAgoNormalized : 0; + const apr1d = dailyRate * 365 * 100; + const apy1d = (Math.pow(1 + dailyRate, 365) - 1) * 100; + + const weeklyRate = rate7dayAgoNormalized > 0 ? (currentRateNormalized - rate7dayAgoNormalized) / rate7dayAgoNormalized / 7 : 0; + const apr7d = weeklyRate * 365 * 100; + const apy7d = (Math.pow(1 + weeklyRate, 365) - 1) * 100; + const tvlUsd = totalSupply * currentRateNormalized * underlyingPrice; + + const chainName = CHAIN_CONFIG[vaultConfig.chainId].chainName; + + return { + pool: vaultConfig.address, + chain: chainName, + project: 'yield-yak-aggregator', + symbol: vaultConfig.symbol, + poolMeta: 'Milk Vault', + apyBase: apy1d, + apyBase7d: apy7d, + underlyingTokens: [vaultConfig.underlyingToken], + tvlUsd: tvlUsd, + }; +}; + +/** + * Get all vault data + * @returns {Object[]} Array of vault data objects + */ +const getAllVaultData = async () => { + const vaultPromises = VAULTS.map(vaultConfig => getVaultData(vaultConfig)); + const vaultResults = await Promise.all(vaultPromises); + return vaultResults.filter(result => result !== null); +}; + +/** + * Get farm data for a single chain + * @param {string} chainId + * @returns {Object[]} Array of farm data objects + */ +const getFarms = async (chainId) => { + const chain = CHAIN_CONFIG[chainId].chain; + const [{ data: farms }, { data: apys }] = await Promise.all([ + axios.get(`https://staging-api.yieldyak.com/${chainId}/farms`), + axios.get(`https://staging-api.yieldyak.com/${chainId}/apys`), + ]); + + const farmsWithApys = farms.filter((farm) => apys.hasOwnProperty(farm.address)); + const tokens = [ + ...new Set( + farmsWithApys + .map(({ depositToken }) => + (depositToken.underlying || []).map((token) => token.toLowerCase()) + ) + .flat() + ), + ]; + + const { pricesByAddress, pricesBySymbol } = await getPrices(chain, tokens); + + const farmResults = farmsWithApys + .map((farm) => { + let tvlUsd = 0; + + const isLp = !!farm.lpToken; + if (isLp) { + const token0Symbol = get(farm, 'token0.symbol', '').toLowerCase(); + const token1Symbol = get(farm, 'token1.symbol', '').toLowerCase(); + const token0Reserves = Number(get(farm, 'token0.reserves', 0)); + const token1Reserves = Number(get(farm, 'token1.reserves', 0)); + const token0Price = pricesBySymbol[token0Symbol]; + const token1Price = pricesBySymbol[token1Symbol]; + + if (token0Price && token1Price && token0Price > 0 && token1Price > 0) { + const token0Usd = token0Price * token0Reserves; + const token1Usd = token1Price * token1Reserves; + tvlUsd = + (token0Usd > token1Usd ? token1Usd : token0Usd) * + 2 * + (farm.totalDeposits / farm.lpToken.supply); + } else { + // Try to calculate TVL with available price data + if (token0Price && token0Price > 0 && token0Reserves > 0) { + tvlUsd = token0Price * token0Reserves * 2 * (farm.totalDeposits / farm.lpToken.supply); + } else if (token1Price && token1Price > 0 && token1Reserves > 0) { + tvlUsd = token1Price * token1Reserves * 2 * (farm.totalDeposits / farm.lpToken.supply); + } + } + } else { + let tokenPrice = 0; + + if (farm.platform == 'wombat') { + const tokenSymbol = farm.depositToken.underlying[0].toLowerCase(); + tokenPrice = pricesByAddress[tokenSymbol]; + } else { + const tokenSymbol = farm.depositToken.address.toLowerCase(); + const tokenName = farm.name.toLowerCase(); + tokenPrice = + pricesByAddress[tokenSymbol] || pricesBySymbol[tokenName]; + } + + if (farm.depositToken.stablecoin) { + tvlUsd = Number(farm.totalDeposits); + } else if (tokenPrice && tokenPrice > 0) { + tvlUsd = tokenPrice * Number(farm.totalDeposits); + } + } + + // Ensure tvlUsd is a valid number + if (!Number.isFinite(tvlUsd) || tvlUsd < 0) { + tvlUsd = 0; + } + + const chainName = CHAIN_CONFIG[chainId].chainName; + + return { + pool: farm.address, + chain: chainName, + project: 'yield-yak-aggregator', + symbol: farm.name, + poolMeta: farm.platform, + apyBase: apys[farm.address].apy, + underlyingTokens: farm.depositToken.underlying, + tvlUsd: tvlUsd, + }; + }); + + return farmResults; +} + +const getAllFarmData = async () => { + const farmPromises = Object.keys(CHAIN_CONFIG).map(chainId => getFarms(chainId)); + const farmResults = await Promise.all(farmPromises); + return farmResults.flat(); +} + +const main = async () => { + const [farmData, vaultData] = await Promise.all([ + getAllFarmData(), + getAllVaultData(), + ]); + + return [...farmData, ...vaultData]; +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://yieldyak.com/', +}; diff --git a/src/adaptors/yieldfi/index.js b/src/adaptors/yieldfi/index.js new file mode 100644 index 0000000000..00d94dfe3f --- /dev/null +++ b/src/adaptors/yieldfi/index.js @@ -0,0 +1,238 @@ +const utils = require('../utils'); +const { ethers } = require("ethers"); +const sdk = require('@defillama/sdk'); + +// Constants +const DECIMALS = { + yUSD: 18, + vyUSD: 18, + yETH: 18, + vyETH: 18, + yBTC: 18, + vyBTC: 18, +}; + +// Contract addresses - Multi-chain configuration +const YUSD_CONTRACTS = { + ethereum: "0x19Ebd191f7A24ECE672ba13A302212b5eF7F35cb", + optimism: '0x4772D2e014F9fC3a820C444e3313968e9a5C8121', + arbitrum: '0x4772D2e014F9fC3a820C444e3313968e9a5C8121', + base: '0x4772D2e014F9fC3a820C444e3313968e9a5C8121', + sonic: '0x4772D2e014F9fC3a820C444e3313968e9a5C8121', + plume_mainnet: '0x4772D2e014F9fC3a820C444e3313968e9a5C8121', + katana: "0x4772D2e014F9fC3a820C444e3313968e9a5C8121", + bsc: "0x4772D2e014F9fC3a820C444e3313968e9a5C8121", + avax: "0x4772D2e014F9fC3a820C444e3313968e9a5C8121", + tac: "0x4772D2e014F9fC3a820C444e3313968e9a5C8121", + linea: "0x4e559dBCCbe87De66c6a9F3f25231096F24c2e28", + plasma: "0x4772D2e014F9fC3a820C444e3313968e9a5C8121", + saga: "0x839e7e610108Cf3DCc9b40329db33b6E6bc9baCE", +}; + +const VYUSD_CONTRACTS = { + ethereum: "0x2e3C5e514EEf46727DE1FE44618027A9b70D92FC", + optimism: '0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de', + arbitrum: '0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de', + base: '0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de', + sonic: '0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de', + plume_mainnet: '0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de', + katana: "0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de", + bsc: "0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de", + avax: "0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de", + tac: "0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de", + linea: "0x168BC4DB5dcbecA279983324d3082c47e47569E7", + plasma: "0xF4F447E6AFa04c9D11Ef0e2fC0d7f19C24Ee55de", + saga: "0x704a58f888f18506C9Fc199e53AE220B5fdCaEd8", +}; + +const YETH_CONTRACTS = { + ethereum: "0x8464F6eCAe1EA58EC816C13f964030eAb8Ec123A", + arbitrum: "0x1F52Edf2815BfA625890B61d6bf43dDC24671Fe8", + base: "0x1F52Edf2815BfA625890B61d6bf43dDC24671Fe8", + saga: "0xA6F89de43315B444114258f6E6700765D08bcd56", +}; + +const VYETH_CONTRACTS = { + ethereum: "0x3073112c2c4800b89764973d5790ccc7fba5c9f9", + arbitrum: "0x8c93a6752Bfe29FDA26EbA8df4390c642e6A7f90", + base: "0x8c93a6752Bfe29FDA26EbA8df4390c642e6A7f90" +}; + +const YBTC_CONTRACTS = { + ethereum: "0xa01200b2e74DE6489cF56864E3d76BBc06fc6C43", +}; + +const VYBTC_CONTRACTS = { + ethereum: "0x1e2a5622178f93EFd4349E2eB3DbDF2761749e1B", +}; +// Supported chains +const SUPPORTED_CHAINS = Object.keys(YUSD_CONTRACTS); + +// API endpoints +const API_ENDPOINTS = { + yUSD: 'https://ctrl.yield.fi/t/apy/yusd/apyHistory', + vyUSD: 'https://ctrl.yield.fi/t/apy/vyusd/apyHistory', + yETH: 'https://ctrl.yield.fi/t/apy/yeth/apyHistory', + vyETH: 'https://ctrl.yield.fi/t/apy/vyeth/apyHistory', + yBTC: 'https://ctrl.yield.fi/t/apy/ybtc/apyHistory', + vyBTC: 'https://ctrl.yield.fi/t/apy/vybtc/apyHistory', +}; + +// ABIs +const ABIS = { + totalSupply: 'function totalSupply() view returns (uint256)' +}; + +/** + * Fetch latest APY data from the API + * @param {string} tokenSymbol - Token symbol (yUSD or vyUSD) + * @returns {Promise} Latest APY + */ +const fetchLatestAPY = async (tokenSymbol) => { + try { + const endpoint = API_ENDPOINTS[tokenSymbol]; + if (!endpoint) { + console.error(`No API endpoint found for ${tokenSymbol}`); + return 0; + } + + const response = await fetch(endpoint); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + const apyHistory = data.apy_history; + + if (!apyHistory || !Array.isArray(apyHistory) || apyHistory.length === 0) { + console.error(`No APY history data found for ${tokenSymbol}`); + return 0; + } + + // Get the latest APY (first entry in the array is the most recent) + const latestAPY = apyHistory[0].apy; + + console.log(`${tokenSymbol} latest APY: ${latestAPY.toFixed(2)}%`); + return parseFloat(latestAPY.toFixed(2)); + } catch (error) { + console.error(`Error fetching APY for ${tokenSymbol}:`, error); + return 0; + } +}; + +/** + * Get TVL for a specific token on a specific chain + * @param {string} tokenAddress - Token contract address + * @param {string} chain - Blockchain name + * @param {number} decimals - Token decimals + * @returns {Promise} TVL value in USD + */ +const getTVL = async (tokenAddress, chain, decimals = DECIMALS.yUSD) => { + try { + // Get total supply and token price in parallel + const [supplyResponse, priceData] = await Promise.all([ + sdk.api.abi.call({ + chain: chain, + abi: ABIS.totalSupply, + target: tokenAddress + }), + utils.getPrices([tokenAddress], chain) + ]); + + const totalSupply = supplyResponse.output / (10 ** decimals); + const tokenPrice = priceData.pricesByAddress[tokenAddress.toLowerCase()] || 0; + const tvlUsd = totalSupply * tokenPrice; + return parseFloat(tvlUsd.toFixed(2)); + } catch (error) { + console.error(`Error getting TVL for ${tokenAddress} on ${chain}:`, error); + return 0; + } +}; + +/** + * Create pool object for a token + * @param {string} tokenAddress - Token contract address + * @param {string} symbol - Token symbol + * @param {string} chain - Blockchain name + * @param {number} tvl - Total Value Locked + * @param {number} apy - Annual Percentage Yield + * @returns {Object} Pool object + */ +const createPool = (tokenAddress, symbol, chain, tvl, apy) => ({ + pool: `${tokenAddress}-${chain}`, + chain: chain, + project: 'yieldfi', + symbol: utils.formatSymbol(symbol), + tvlUsd: tvl, + apyBase: apy, +}); + +/** + * Process token data for a specific chain + * @param {string} tokenAddress - Token contract address + * @param {string} symbol - Token symbol + * @param {string} chain - Blockchain name + * @returns {Promise} Pool object or null if error + */ +const processToken = async (tokenAddress, symbol, chain) => { + try { + const [tvl, apy] = await Promise.all([ + getTVL(tokenAddress, chain), + fetchLatestAPY(symbol) + ]); + + if (apy === 0) { + console.log(`No APY data available for ${symbol} on ${chain}`); + return null; + } + + return createPool(tokenAddress, symbol, chain, tvl, apy); + } catch (error) { + console.error(`Error processing ${symbol} on ${chain}:`, error); + return null; + } +}; + +/** + * Main function to get pool data for all chains + * @returns {Promise} Array of pool objects + */ +const poolsFunction = async () => { + const allPools = []; + + // Process all chains in parallel + const chainPromises = SUPPORTED_CHAINS.map(async (chain) => { + const tokenPromises = [ + processToken(YUSD_CONTRACTS[chain], 'yUSD', chain), + processToken(VYUSD_CONTRACTS[chain], 'vyUSD', chain) + ]; + + // Only process yETH, vyETH, yBTC, vyBTC on Ethereum + if (chain === 'ethereum') { + tokenPromises.push( + processToken(YETH_CONTRACTS[chain], 'yETH', chain), + processToken(VYETH_CONTRACTS[chain], 'vyETH', chain), + processToken(YBTC_CONTRACTS[chain], 'yBTC', chain), + processToken(VYBTC_CONTRACTS[chain], 'vyBTC', chain) + ); + } + + const pools = await Promise.all(tokenPromises); + return pools.filter(Boolean); + }); + + const chainResults = await Promise.all(chainPromises); + + // Flatten the results + chainResults.forEach(pools => { + allPools.push(...pools); + }); + + return allPools; +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://yield.fi/mint', +}; diff --git a/src/adaptors/yieldlend/index.js b/src/adaptors/yieldlend/index.js new file mode 100644 index 0000000000..823cfcc867 --- /dev/null +++ b/src/adaptors/yieldlend/index.js @@ -0,0 +1,261 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const SECONDS_PER_YEAR = 31536000; + +const chainUrlParam = { + base: 'proto_base_v3', +}; + +const oraclePriceABI = { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getAssetPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getPrices = async (addresses) => { + const yieldAddr = '0x3f7a11bb98959966260347233bfe6559a1067dbf'; + const aaveOracleAddr = '0x0B9252d63cb44eFa7f18911Ee2259cB40d0c2965'; + + const _prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const oraclePrice = ( + await sdk.api.abi.call({ + target: aaveOracleAddr, + abi: oraclePriceABI, + chain: 'base', + params: [yieldAddr], + }) + ).output; + + const _yield = { + [`base:${yieldAddr}`]: { + decimals: 18, + symbol: 'YIELD', + price: Number(oraclePrice) / 1e8, + timestamp: Date.now(), + confidence: 0.99, + }, + }; + + const prices = { ..._prices, ..._yield }; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const API_URLS = { + base: 'https://api.studio.thegraph.com/query/60668/yieldlend/version/latest', +}; + +const query = gql` + query ReservesQuery { + reserves(where: { name_not: "" }) { + name + borrowingEnabled + aToken { + id + rewards(where: { distributionEnd_gt: 0 }) { + id + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + underlyingAssetAddress + underlyingAssetDecimals + } + vToken { + rewards(where: { distributionEnd_gt: 0 }) { + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + } + symbol + liquidityRate + variableBorrowRate + baseLTVasCollateral + isFrozen + } + } +`; + +const apy = async () => { + let data = await Promise.all( + Object.entries(API_URLS).map(async ([chain, url]) => [ + chain, + (await request(url, query)).reserves, + ]) + ); + + data = data.map(([chain, reserves]) => [ + chain, + reserves.filter((p) => !p.isFrozen), + ]); + + const totalSupply = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: reserves.map((reserve) => ({ + target: reserve.aToken.id, + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingBalances = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: reserves.map((reserve, i) => ({ + target: reserve.aToken.underlyingAssetAddress, + params: [reserve.aToken.id], + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingTokens = data.map(([chain, reserves]) => + reserves.map((pool) => `${chain}:${pool.aToken.underlyingAssetAddress}`) + ); + + const rewardTokens = data.map(([chain, reserves]) => + reserves.map((pool) => + pool.aToken.rewards.map((rew) => `${chain}:${rew.rewardToken}`) + ) + ); + + const { pricesByAddress, pricesBySymbol } = await getPrices( + underlyingTokens.flat().concat(rewardTokens.flat(Infinity)) + ); + + const pools = data.map(([chain, markets], i) => { + const chainPools = markets.map((pool, idx) => { + const supply = totalSupply[i][idx]; + const currentSupply = underlyingBalances[i][idx]; + const totalSupplyUsd = + (supply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const tvlUsd = + (currentSupply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const { rewards } = pool.aToken; + + const rewardPerYear = rewards.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol], + 0 + ); + + const { rewards: rewardsBorrow } = pool.vToken; + const rewardPerYearBorrow = rewardsBorrow.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol], + 0 + ); + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + totalBorrowUsd = totalBorrowUsd < 0 ? 0 : totalBorrowUsd; + + const supplyRewardEnd = pool.aToken.rewards[0]?.distributionEnd; + const borrowRewardEnd = pool.vToken.rewards[0]?.distributionEnd; + + return { + pool: `${pool.aToken.id}-${chain}`.toLowerCase(), + chain: utils.formatChain('base'), + project: 'yieldlend', + symbol: pool.symbol, + tvlUsd, + apyBase: (pool.liquidityRate / 10 ** 27) * 100, + apyReward: + supplyRewardEnd * 1000 > new Date() + ? (rewardPerYear / totalSupplyUsd) * 100 + : null, + rewardTokens: + supplyRewardEnd * 1000 > new Date() + ? rewards.map((rew) => rew.rewardToken) + : null, + underlyingTokens: [pool.aToken.underlyingAssetAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.variableBorrowRate) / 1e25, + apyRewardBorrow: + borrowRewardEnd * 1000 > new Date() + ? (rewardPerYearBorrow / totalBorrowUsd) * 100 + : null, + ltv: Number(pool.baseLTVasCollateral) / 10000, + url: `https://use.yieldlend.xyz/reserve-overview/?underlyingAsset=${pool.aToken.underlyingAssetAddress}&marketName=${chainUrlParam[chain]}&utm_source=defillama&utm_medium=listing&utm_campaign=external`, + borrowable: pool.borrowingEnabled, + }; + }); + + return chainPools; + }); + + return pools.flat().filter((p) => !!p.tvlUsd); +}; + +module.exports = { + timetravel: false, + apy, +}; diff --git a/src/adaptors/yieldnest/index.js b/src/adaptors/yieldnest/index.js new file mode 100755 index 0000000000..d257ee6ec0 --- /dev/null +++ b/src/adaptors/yieldnest/index.js @@ -0,0 +1,80 @@ +const { request, gql } = require('graphql-request'); + +const yieldnestGatewayUrl = 'https://gateway.yieldnest.finance/api/v1/graphql'; +const yieldnestRestakePoolBaseUrl = 'https://app.yieldnest.finance/restake/'; +const chainIdToName = { + 1: 'Ethereum', + 56: 'Binance', +}; +const yieldnestSummaryQuery = gql` +{ + getLRTsData(networkType: mainnet) { + tokens { + token + blockchains { + chainId + apr { + apr7d + restaking7dApr + } + contract_details { + tokenAddress + } + tvl { + value_usd + } + } + } + } +}` + +const yieldnestUnderlyingAssetsQuery = gql` +query lrt($chainId: Int!, $token: TOKENS!) { + getAPRLRT(chainId: $chainId, token: $token) { + underlyingAssets { + address + } + } +}` + +const getUnderlyingAssets = async (chainId, token) => { + try { + const data = await request(yieldnestGatewayUrl, yieldnestUnderlyingAssetsQuery, { chainId, token }); + + return data.getAPRLRT.underlyingAssets.map((asset) => asset.address); + } catch (error) { + return []; + } +} + +const apy = async () => { + const data = await request(yieldnestGatewayUrl, yieldnestSummaryQuery); + const tokens = data.getLRTsData.tokens; + + const pools = await Promise.all(tokens.map(async (token) => { + const blockchainData = token.blockchains[0]; + if (!blockchainData) return; + const chain = chainIdToName[blockchainData.chainId]; + if (!chain) return; + const address = blockchainData.contract_details.tokenAddress; + const symbol = token.token; + const decimals = 18; + const apy = blockchainData.apr.apr7d + blockchainData.apr.restaking7dApr; + const tvl = blockchainData.tvl.value_usd; + const underlyingAssets = await getUnderlyingAssets(blockchainData.chainId, token.token); + return { + pool: `${address}-${chain}`.toLowerCase(), + chain: chain, + project: 'yieldnest', + symbol: symbol, + tvlUsd: tvl, + apy: apy, + underlyingTokens: underlyingAssets, + url: `${yieldnestRestakePoolBaseUrl}${symbol}`, + }; + })); + + return pools; +}; + +module.exports = { timetravel: false, apy }; diff --git a/src/adaptors/yieldoor/adaptiveCurveIrmLib.js b/src/adaptors/yieldoor/adaptiveCurveIrmLib.js new file mode 100644 index 0000000000..0b2b62ff5e --- /dev/null +++ b/src/adaptors/yieldoor/adaptiveCurveIrmLib.js @@ -0,0 +1,197 @@ +const MathLib = require('./mathLib'); + +/** + * JS implementation of {@link https://github.com/morpho-org/morpho-blue-irm/blob/main/src/libraries/adaptive-curve/ExpLib.sol ExpLib} used by the Adaptive Curve IRM. + */ + +/** + * The scale of the oracle price. Hardcoded to 1e36. + */ +const ORACLE_PRICE_SCALE = 1_000000000000000000000000000000000000n; +const SECONDS_PER_YEAR = 31536000n; + +const CURVE_STEEPNESS = 4_000000000000000000n; +const TARGET_UTILIZATION = 90_0000000000000000n; +const INITIAL_RATE_AT_TARGET = 4_0000000000000000n / SECONDS_PER_YEAR; +const ADJUSTMENT_SPEED = 50_000000000000000000n / SECONDS_PER_YEAR; +const MIN_RATE_AT_TARGET = 10_00000000000000n / SECONDS_PER_YEAR; +const MAX_RATE_AT_TARGET = 2_000000000000000000n / SECONDS_PER_YEAR; + +/** + * ln(2), scaled by WAD. + */ +const LN_2_INT = 693147180559945309n; + +/** + * ln(1e-18), scaled by WAD. + */ +const LN_WEI_INT = -41_446531673892822312n; + +/** + * Above this bound, `wExp` is clipped to avoid overflowing when multiplied with 1 ether. + * This upper bound corresponds to: ln(type(int256).max / 1e36) (scaled by WAD, floored). + */ +const WEXP_UPPER_BOUND = 93_859467695000404319n; + +/** + * The value of wExp(`WEXP_UPPER_BOUND`). + */ +const WEXP_UPPER_VALUE = +57716089161558943949701069502944508345128_422502756744429568n; + +/** + * Returns an approximation of exp(x) used by the Adaptive Curve IRM. + * @param x + */ +const wExp = (x) => { +x = BigInt(x); + +// If x < ln(1e-18) then exp(x) < 1e-18 so it is rounded to zero. +if (x < LN_WEI_INT) return 0n; +// `wExp` is clipped to avoid overflowing when multiplied with 1 ether. +if (x >= WEXP_UPPER_BOUND) return WEXP_UPPER_VALUE; + +// Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 <= r <= ln(2)/2. +// q = x / ln(2) rounded half toward zero. +const roundingAdjustment = x < 0n ? -(LN_2_INT / 2n) : LN_2_INT / 2n; +const q = (x + roundingAdjustment) / LN_2_INT; +const r = x - q * LN_2_INT; + +// Compute e^r with a 2nd-order Taylor polynomial. +const expR = MathLib.WAD + r + (r * r) / MathLib.WAD / 2n; + +// Return e^x = 2^q * e^r. +if (q >= 0n) return expR << q; +return expR >> -q; +} + +const getBorrowRate = ( +startUtilization, +startRateAtTarget, +elapsed, +) => { +startUtilization = BigInt(startUtilization); +startRateAtTarget = BigInt(startRateAtTarget); +elapsed = BigInt(elapsed); + +const errNormFactor = + startUtilization > TARGET_UTILIZATION + ? MathLib.WAD - TARGET_UTILIZATION + : TARGET_UTILIZATION; +const err = MathLib.wDivDown( + startUtilization - TARGET_UTILIZATION, + errNormFactor, +); + +let avgRateAtTarget; +let endRateAtTarget; + +if (startRateAtTarget === 0n) { + // First interaction. + avgRateAtTarget = INITIAL_RATE_AT_TARGET; + endRateAtTarget = INITIAL_RATE_AT_TARGET; +} else { + // The speed is assumed constant between two updates, but it is in fact not constant because of interest. + // So the rate is always underestimated. + const speed = MathLib.wMulDown(ADJUSTMENT_SPEED, err); + const linearAdaptation = speed * elapsed; + + if (linearAdaptation === 0n) { + // If linearAdaptation == 0, avgRateAtTarget = endRateAtTarget = startRateAtTarget; + avgRateAtTarget = startRateAtTarget; + endRateAtTarget = startRateAtTarget; + } else { + // Non negative because MIN_RATE_AT_TARGET > 0. + const _newRateAtTarget = (linearAdaptation) => + MathLib.min( + MathLib.max( + MathLib.wMulDown(startRateAtTarget, wExp(linearAdaptation)), + MIN_RATE_AT_TARGET, + ), + MAX_RATE_AT_TARGET, + ); + + // Formula of the average rate that should be returned to Morpho Blue: + // avg = 1/T * ∫_0^T curve(startRateAtTarget*exp(speed*x), err) dx + // The integral is approximated with the trapezoidal rule: + // avg ~= 1/T * Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / 2 * T/N + // Where f(x) = startRateAtTarget*exp(speed*x) + // avg ~= Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / (2 * N) + // As curve is linear in its first argument: + // avg ~= curve([Σ_i=1^N [f((i-1) * T/N) + f(i * T/N)] / (2 * N), err) + // avg ~= curve([(f(0) + f(T))/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err) + // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err) + // With N = 2: + // avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + startRateAtTarget*exp(speed*T/2)] / 2, err) + // avg ~= curve([startRateAtTarget + endRateAtTarget + 2*startRateAtTarget*exp(speed*T/2)] / 4, err) + endRateAtTarget = _newRateAtTarget(linearAdaptation); + avgRateAtTarget = + (startRateAtTarget + + endRateAtTarget + + 2n * _newRateAtTarget(linearAdaptation / 2n)) / + 4n; + } +} + +// Non negative because 1 - 1/C >= 0, C - 1 >= 0. +const coeff = + err < 0 + ? MathLib.WAD - MathLib.wDivDown(MathLib.WAD, CURVE_STEEPNESS) + : CURVE_STEEPNESS - MathLib.WAD; + +const _curve = (rateAtTarget) => + MathLib.wMulDown( + MathLib.wMulDown(coeff, err) + MathLib.WAD, + rateAtTarget, + ); + +// Non negative if avgRateAtTarget >= 0 because if err < 0, coeff <= 1. +return { + avgBorrowRate: _curve(avgRateAtTarget), + endBorrowRate: _curve(endRateAtTarget), + endRateAtTarget, +}; +} + +const getUtilizationAtBorrowRate = ( +borrowRate, +rateAtTarget, +) => { +borrowRate = BigInt(borrowRate); +rateAtTarget = BigInt(rateAtTarget); + +if (borrowRate >= rateAtTarget) { + const maxBorrowRate = MathLib.wMulDown(rateAtTarget, CURVE_STEEPNESS); + + const diffToMaxBorrowRate = maxBorrowRate - rateAtTarget; + if (diffToMaxBorrowRate === 0n) return MathLib.WAD; + + return MathLib.min( + MathLib.WAD, + TARGET_UTILIZATION + + MathLib.mulDivDown( + MathLib.WAD - TARGET_UTILIZATION, + borrowRate - rateAtTarget, + diffToMaxBorrowRate, + ), + ); +} + +const minBorrowRate = MathLib.wDivDown(rateAtTarget, CURVE_STEEPNESS); + +return MathLib.max( + 0n, + MathLib.mulDivDown( + TARGET_UTILIZATION, + borrowRate - minBorrowRate, + rateAtTarget - minBorrowRate, + ), +); +} + +module.exports = { + getBorrowRate, + getUtilizationAtBorrowRate, + SECONDS_PER_YEAR, + ORACLE_PRICE_SCALE +}; diff --git a/src/adaptors/yieldoor/index.js b/src/adaptors/yieldoor/index.js new file mode 100644 index 0000000000..0d67071ff0 --- /dev/null +++ b/src/adaptors/yieldoor/index.js @@ -0,0 +1,862 @@ +const { request, gql } = require('graphql-request'); +const superagent = require('superagent'); +const { formatChain, getPrices, getERC4626Info } = require('../utils'); +const BigNumber = require('bignumber.js'); +const { formatCollectsQuery } = require('./queries'); +const sdk = require('@defillama/sdk'); +const { blueAbi, adaptiveCurveIrmAbi, blueOracleAbi } = require('./morphoBlueAbi'); +const { morphoMarketAbi, code } = require('./morphoMarketAbi'); +const { getUtilization, getAccruedInterest, getAccrualBorrowRate, getBorrowApy, toBorrowAssets, getLtv } = require('./morphoSdk'); +const { getFormattedActiveMarkets } = require('./pendleMarkets'); +const { + utils: { formatEther, formatUnits }, +} = require('ethers'); + +const PROJECT_NAME = 'yieldoor'; +const BASE_URL = 'https://app.yieldoor.com'; +const TEN = new BigNumber(10); +const CHAINS = { + ethereum: 1, + base: 8453, + sonic: 146 +} + +const MORPHO_GRAPH_URL = 'https://blue-api.morpho.org/graphql'; + +const CONFIG = { + ethereum: { + subgraph: 'https://subgraph.satsuma-prod.com/ebe562dbf792/yieldoor--594520/yieldoor-leverager-base/version/v0.0.2/api', + blockTime: 12, + morpho: { + morpho: '0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb', + adaptiveCurveIrm: '0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC', + }, + lendingPool: '', + lp: [], + looped: [{ + address: '0x67d0bde18945999ff517a04fa156189a07ba6543', + name: 'ethereum-looped-usdc' + }] + }, + base: { + subgraph: 'https://subgraph.satsuma-prod.com/ebe562dbf792/yieldoor--594520/yieldoor-leverager-base/version/v0.0.2/api', + uniswapSubgraph: sdk.graph.modifyEndpoint('HMuAwufqZ1YCRmzL2SfHTVkzZovC9VL2UAKhjvRqKiR1'), + blockTime: 2, + lendingPool: '0xa35b16cec42094f3ba4fd838b13641ec77d23f98', + lp: { + "0x8e16c184df379196782e943f4d5a2682a8720cc4": { + "name": "uniswap-base-weth-usdc-0.05", + "address": "0x8e16c184df379196782e943f4d5a2682a8720cc4", + }, + "0x92ed462970e63b4fe955937cb1741ef5218b8e40": { + "name": "uniswap-base-cbbtc-usdc-0.05", + "address": "0x92ed462970e63b4fe955937cb1741ef5218b8e40", + }, + "0x90d8da2839570901f13124ab1a83e92764c7e08f": { + "name": "uniswap-base-weth-cbbtc-0.3", + "address": "0x90d8da2839570901f13124ab1a83e92764c7e08f", + }, + "0xc01403a2466aa7a52a7826a15e5e3bc6b0cd0664": { + "name": "uniswap-base-weth-morpho-0.3", + "address": "0xc01403a2466aa7a52a7826a15e5e3bc6b0cd0664", + } + }, + looped: [] + }, + sonic: { + subgraph: 'https://subgraph.satsuma-prod.com/ebe562dbf792/yieldoor--594520/yieldoor-leverager-sonic/version/v0.0.2/api', + uniswapSubgraph: sdk.graph.modifyEndpoint('9memxmbdvEaCBGvbtLh3MMGcLiMEHN6ooUSBiFU93g5T'), + blockTime: 0.5, + lendingPool: '0x2300ddbc84ee0c375920d706882b62d1babe1dcb', + lp: { + "0x6120de6a13e4496d6c8220bb2a0727ec6350a37f": { + "name": "uniswap-sonic-ws-susdce-0.3", + "address": "0x6120de6a13e4496d6c8220bb2a0727ec6350a37f", + }, + "0xbce4fdcc570855d1f8f7aa2b29a483bdab6cc2df": { + "name": "uniswap-sonic-ws-weth-0.3", + "address": "0xbce4fdcc570855d1f8f7aa2b29a483bdab6cc2df", + }, + "0x2d4d9ec91b60b2bf29ed1ec5028847dd8237cc17": { + "name": "uniswap-sonic-usdc-weth-0.05", + "address": "0x2d4d9ec91b60b2bf29ed1ec5028847dd8237cc17", + } + }, + shadowLp: { + "0x55a9a1444dc5ffeff94090c1e31e1a0c2d5da963": { + "name": "shadow-sonic-ws-susdce-50", + "address": "0x55a9a1444dc5ffeff94090c1e31e1a0c2d5da963", + }, + "0xea2dcb8f95d2582f3dfcf8fb9c13488e8dfbbfa3": { + "name": "shadow-sonic-ws-weth-50", + "address": "0xea2dcb8f95d2582f3dfcf8fb9c13488e8dfbbfa3", + }, + "0xdc8bf0e7ff1742898f8e72143f0b8ab4139272e5": { + "name": "shadow-sonic-usdc-weth-100", + "address": "0xdc8bf0e7ff1742898f8e72143f0b8ab4139272e5", + }, + "0x520e0c1a9071227279b1bec01e2fc93a25c5094e": { + "name": "shadow-sonic-usdc-eurc-5", + "address": "0x520e0c1a9071227279b1bec01e2fc93a25c5094e", + } + }, + looped: [] + } +} + +const abis = { + getAsset: "function asset() view returns (address asset)", + getPrice: "function getPrice(address asset) view returns (uint256)", + balances: "function balances() view returns (uint256, uint256)", + positions: "function positions(uint256) view returns (address denomination, uint256 borrowedAmount, uint256 borrowedIndex, uint256 initCollateralValue, uint256 initCollateralUsd, uint256 initBorrowedUsd, uint256 shares, address vault, address token0, address token1)", + reservesList: "function reservesList(uint256) view returns (address)", + reserves: "function reserves(address) view returns (uint256 borrowingIndex, uint256 currentBorrowingRate, uint256 totalBorrows, address yTokenAddress, address stakingAddress, uint256 reserveCapacity, (uint256 utilizationA, uint256 borrowingRateA, uint256 utilizationB, uint256 borrowingRateB, uint256 maxBorrowingRate) borrowingRateConfig, (uint256 maxIndividualBorrow, uint256 LTV, uint256 LLTV) leverageParams, uint256 underlyingBalance, uint128 lastUpdateTimestamp, (bool isActive, bool frozen, bool borrowingEnabled) flags)", + getVestingAmounts: "function getVestingAmounts() view returns (uint256, uint256)", + getMaxNumberMarkets: "function MAX_NUMBER_MARKETS() view returns (uint8)", + getIdleBalance: "function idleBalance() view returns (uint256)", + getPricefeed: "function pricefeed() view returns (address)", + getCollateralAToken: "function collateralAToken() view returns (address)", + getDebtVToken: "function debtVToken() view returns (address)", + getAave: "function aave() view returns (address)", + getMorphoPositions: "function morphoPositions(uint256) view returns (address, address, address, address, uint256)", + getId: { + type: "function", + name: "getId", + inputs: [ + { + name: "marketParams", + type: "tuple", + internalType: "struct MarketParams", + components: [ + { name: "loanToken", type: "address", internalType: "address" }, + { name: "collateralToken", type: "address", internalType: "address" }, + { name: "oracle", type: "address", internalType: "address" }, + { name: "irm", type: "address", internalType: "address" }, + { name: "lltv", type: "uint256", internalType: "uint256" }, + ], + }, + ], + outputs: [{ name: "id", type: "bytes32", internalType: "Id" }], + stateMutability: "pure", + }, + getReserveData: "function getReserveData(address asset) view returns (uint256 unbacked, uint256 accruedToTreasuryScaled, uint256 totalAToken, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp)", + getUnderlyingAssetAddress: "function UNDERLYING_ASSET_ADDRESS() view returns (address)", +} + +const getDailyFees = async (graphUrl, vault, pool, strategy, block, prices, vaultsData) => { + let feeDataToken0 = new BigNumber(0); + let feeDataToken1 = new BigNumber(0); + let data; + try { + data = await request(graphUrl, formatCollectsQuery(pool.toLowerCase(), strategy.toLowerCase(), block)); + } catch (e) { + console.error(e); + return; + } + + if (!data.pool || !data.pool.collects) { + return; + } + + const collects = data.pool.collects.filter(collect => { + return !collect.transaction.burns.some(burn => burn.amount0 !== '0' || burn.amount1 !== '0') + }); + + collects.forEach(collect => { + feeDataToken0 = new BigNumber(collect.amount0).plus(feeDataToken0); + feeDataToken1 = new BigNumber(collect.amount1).plus(feeDataToken1); + }); + + const token0Usd = feeDataToken0.multipliedBy(prices.pricesByAddress[vaultsData[vault].token0.toLowerCase()]); + const token1Usd = feeDataToken1.multipliedBy(prices.pricesByAddress[vaultsData[vault].token1.toLowerCase()]); + + const totalFees = token0Usd.plus(token1Usd).toNumber(); + vaultsData[vault].dailyFees = totalFees; +}; + + +const getVaultData = async (chain, vaultsData, prices) => { + if (Object.keys(vaultsData).length === 0) return; + + const vaultsAddresses = Object.keys(vaultsData); + + const [balances, strategies] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: vaultsAddresses.map(addr => ({ target: addr })), + abi: abis.balances, + chain + }), + sdk.api.abi.multiCall({ + calls: vaultsAddresses.map(addr => ({ target: addr })), + abi: 'address:strategy', + chain + }) + ]) + + Object.keys(vaultsData).forEach((vault, i) => { + const { token0, token1 } = vaultsData[vault]; + const [b0, b1] = balances.output[i].output; + const token0Usd = new BigNumber(b0).dividedBy(TEN.pow(vaultsData[vault].token0Decimals)).multipliedBy(prices.pricesByAddress[token0.toLowerCase()]); + const token1Usd = new BigNumber(b1).dividedBy(TEN.pow(vaultsData[vault].token1Decimals)).multipliedBy(prices.pricesByAddress[token1.toLowerCase()]); + const totalBalance = token0Usd.plus(token1Usd).toNumber(); + vaultsData[vault].totalBalanceUsd = totalBalance; + vaultsData[vault].strategy = strategies.output[i].output; + }); + + const strategyAddresses = Object.keys(vaultsData).map(vault => vaultsData[vault].strategy); + const [protocolFees, pools] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: strategyAddresses.map(addr => ({ target: addr })), + abi: 'uint256:protocolFee', + chain + }), + sdk.api.abi.multiCall({ + calls: strategyAddresses.map(addr => ({ target: addr })), + abi: 'address:pool', + chain + }) + ]); + + Object.keys(vaultsData).forEach((vault, i) => { + vaultsData[vault].protocolFee = protocolFees.output[i].output; + vaultsData[vault].pool = pools.output[i].output; + }); +} + +const getShadowVaultData = async (chain, vaultsData, prices) => { + const vaults = Object.keys(vaultsData); + const [vestingAmounts] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: vaults.map(vault => ({ target: vaultsData[vault].strategy })), + abi: abis.getVestingAmounts, + chain + }) + ]); + + vaults.forEach((vault, i) => { + const [vestingAmount0, vestingAmount1] = vestingAmounts.output[i].output; + const token0Usd = new BigNumber(vestingAmount0).dividedBy(TEN.pow(vaultsData[vault].token0Decimals)).times(prices.pricesByAddress[vaultsData[vault].token0.toLowerCase()]); + const token1Usd = new BigNumber(vestingAmount1).dividedBy(TEN.pow(vaultsData[vault].token1Decimals)).times(prices.pricesByAddress[vaultsData[vault].token1.toLowerCase()]); + const dailyRewards = token0Usd.plus(token1Usd).toNumber(); + vaultsData[vault].dailyRewards = dailyRewards; + vaultsData[vault].apy = dailyRewards * 365 / vaultsData[vault].totalBalanceUsd; + }); +} + +const getBlockDayAgo = async (chain) => { + const block = await sdk.api.util.getLatestBlock(chain); + const blockTime = CONFIG[chain].blockTime; + const blocksPerDay = 86400 / blockTime; + const blockDayAgo = block.number - blocksPerDay; + return blockDayAgo; +} + +const getUniqueTokensPrices = async (lps, chain) => { + + const vaults = Object.keys(lps); + const [token0s, token1s] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: vaults.map(addr => ({ target: addr })), + abi: 'address:token0', + chain + }), + sdk.api.abi.multiCall({ + calls: vaults.map(addr => ({ target: addr })), + abi: 'address:token1', + chain + }) + ]); + + const vaultsData = {}; + vaults.forEach((vault, i) => { + vaultsData[vault] = { + token0: token0s.output[i].output, + token1: token1s.output[i].output + } + }); + + const [decimals0, symbols0, decimals1, symbols1] = await Promise.all([ + sdk.api.abi.multiCall({ + calls: vaults.map(vault => ({ target: vaultsData[vault].token0 })), + abi: 'uint256:decimals', + chain + }), + sdk.api.abi.multiCall({ + calls: vaults.map(vault => ({ target: vaultsData[vault].token0 })), + abi: 'string:symbol', + chain + }), + sdk.api.abi.multiCall({ + calls: vaults.map(vault => ({ target: vaultsData[vault].token1 })), + abi: 'uint256:decimals', + chain + }), + sdk.api.abi.multiCall({ + calls: vaults.map(vault => ({ target: vaultsData[vault].token1 })), + abi: 'string:symbol', + chain + }) + ]); + + vaults.forEach((vault, i) => { + vaultsData[vault].token0Decimals = decimals0.output[i].output; + vaultsData[vault].token1Decimals = decimals1.output[i].output; + vaultsData[vault].token0Symbol = symbols0.output[i].output; + vaultsData[vault].token1Symbol = symbols1.output[i].output; + }); + + const uniqueTokens = [...new Set([...token0s.output.map(t => t.output), ...token1s.output.map(t => t.output)])]; + const prices = await getPrices(uniqueTokens, chain); + + return [prices, vaultsData]; +} + +const calculatePoolsApy = (vaultsData) => { + Object.keys(vaultsData).map(vault => { + let yearlyFees = vaultsData[vault].dailyFees * 365; + if (vaultsData[vault].protocolFee) { + const protocolFeePercent = new BigNumber(vaultsData[vault].protocolFee.toString()).dividedBy(10000); // Assuming fee is in basis points (10000 = 100%) + yearlyFees = (new BigNumber(1).minus(protocolFeePercent)).times(yearlyFees); + } + vaultsData[vault].apy = yearlyFees.dividedBy(vaultsData[vault].totalBalanceUsd).toNumber(); + }); +} + +const getLpData = async (chain) => { + const { lp, looped, lendingPool, uniswapSubgraph } = CONFIG[chain]; + + const [prices, vaultsData] = await getUniqueTokensPrices(lp, chain); + + await getVaultData(chain, vaultsData, prices); + + const blockDayAgo = await getBlockDayAgo(chain); + + await Promise.all( + Object.keys(vaultsData).map(async (vault) => { + await getDailyFees(uniswapSubgraph, vault, vaultsData[vault].pool, vaultsData[vault].strategy, blockDayAgo, prices, vaultsData); + })); + + calculatePoolsApy(vaultsData); + + return Object.keys(vaultsData).map(vault => { + return { + pool: vault, + chain: formatChain(chain), + project: PROJECT_NAME, + underlyingTokens: [vaultsData[vault].token0, vaultsData[vault].token1], + symbol: `yldr-${vaultsData[vault].token0Symbol}-${vaultsData[vault].token1Symbol}`, + tvlUsd: vaultsData[vault].totalBalanceUsd || 0, + apyBase: 100 * vaultsData[vault].apy || 0, + url: `${BASE_URL}/vaults/${lp[vault].name}` + } + }); +} + +const getShadowLpData = async (chain) => { + const { shadowLp, lendingPool, subgraph } = CONFIG[chain]; + + if (!shadowLp || Object.keys(shadowLp).length === 0) { + return []; + } + + const [prices, vaultsData] = await getUniqueTokensPrices(shadowLp, chain); + + await getVaultData(chain, vaultsData, prices); + + await getShadowVaultData(chain, vaultsData, prices); + + return Object.keys(vaultsData).map(vault => { + return { + pool: vault, + chain: formatChain(chain), + project: PROJECT_NAME, + underlyingTokens: [vaultsData[vault].token0, vaultsData[vault].token1], + symbol: `${vaultsData[vault].token0Symbol}-${vaultsData[vault].token1Symbol}`, + tvlUsd: vaultsData[vault].totalBalanceUsd || 0, + apyBase: 100 * vaultsData[vault].apy || 0, + url: `${BASE_URL}/vaults/${shadowLp[vault].name}` + } + }); +} + +const getUniqueTokensFromMorphoPositions = async (morphoPositionsParams, chain) => { + // Extract unique tokens from morpho positions + const uniqueTokens = morphoPositionsParams.reduce((acc, params) => { + if (!params) return acc; + const [loanToken, collateralToken] = params; + acc.add(loanToken); + acc.add(collateralToken); + return acc; + }, new Set()); + + const uniqueTokensArray = Array.from(uniqueTokens); + + if (uniqueTokensArray.length === 0) { + return {}; + } + + // Create multicall parameters for symbol and decimals + const symbolCalls = uniqueTokensArray.map((token) => { + return sdk.api.abi.call({ + target: token, + abi: "erc20:symbol", + chain + }); + }); + + const decimalsCalls = uniqueTokensArray.map((token)=> { + return sdk.api.abi.call({ + target: token, + abi: "erc20:decimals", + chain + }); + }); + + // Execute all calls in parallel + const [symbolResults, decimalsResults] = await Promise.all([ + Promise.all(symbolCalls), + Promise.all(decimalsCalls) + ]); + + // Build token data object + const tokenData = uniqueTokensArray.reduce((acc, token, index) => { + acc[token] = { + symbol: symbolResults[index].output ?? "", + decimals: Number(decimalsResults[index].output ?? 18), + }; + return acc; + }, {}); + + return tokenData; +}; + +const accrueInterest = async (position, timestamp) => { + timestamp = BigInt(timestamp); + + const { elapsed, avgBorrowRate, endRateAtTarget } = + getAccrualBorrowRate(position, position.marketId, timestamp); + + const { interest, feeShares } = getAccruedInterest( + avgBorrowRate, + position, + elapsed, + ); + + return { + ...position, + totalSupplyAssets: position.totalSupplyAssets + interest, + totalBorrowAssets: position.totalBorrowAssets + interest, + totalSupplyShares: position.totalSupplyShares + feeShares, + lastUpdate: timestamp, + rateAtTarget: endRateAtTarget, + }; +} + +const fetchAccrualPosition = async (chain, user, marketId, parameters = {}) => { + const { morpho, adaptiveCurveIrm } = CONFIG[chain].morpho; + + // morpho, adaptiveCurveIrm addresses + // then fetch position and market + // then for each position, accrue interest + // position.accrueInterest(BigInt(Math.floor(Date.now() / 1000))); + + + // fetch position + + // function position + const result = await sdk.api.abi.call({ + target: morpho, + abi: blueAbi[2], + params: [marketId, user], + chain + }); + + const position = { + user, + marketId, + supplyShares: result.output.supplyShares, + borrowShares: result.output.borrowShares, + collateral: result.output.collateral, + }; + + //fetch market + + const marketParams = await sdk.api.abi.call({ + target: morpho, + abi: blueAbi[0], + params: [marketId], + chain + }); + + const [loanToken, collateralToken, oracle, irm, lltv] = marketParams.output; + + const [marketResult, priceResult, rateAtTargetResult] = await Promise.all([ + sdk.api.abi.call({ + target: morpho, + abi: blueAbi[1], + params: [marketId], + chain + }), + sdk.api.abi.call({ + target: oracle, + abi: blueOracleAbi[0], + params: [], + chain + }), + sdk.api.abi.call({ + target: adaptiveCurveIrm, + abi: adaptiveCurveIrmAbi[0], + params: [marketId], + chain + }) + ]); + + const [totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee, hasPrice] = marketResult.output; + const price = priceResult.output; + const rateAtTarget = rateAtTargetResult.output; + + + const market = { + params: { + loanToken, + collateralToken, + oracle, + irm, + lltv + }, + totalSupplyAssets, + totalBorrowAssets, + totalSupplyShares, + totalBorrowShares, + lastUpdate, + fee, + price, + rateAtTarget, + utilization: getUtilization(totalSupplyAssets, totalBorrowAssets), + }; + + const res = { + ...position, + borrowAssets: toBorrowAssets(position.borrowShares, market), + ltv: getLtv(position, market), + market: market + } + + return res; +} + +const getLoopedData = async (chain) => { + const chainId = CHAINS[chain]; + + const pendleMarketDetails = await getFormattedActiveMarkets(chainId); + + const loopedVaults = CONFIG[chain].looped; + + const calls = loopedVaults.map((vault) => { + return new Promise(async (resolve, reject) => { + try { + + const testMaxNumberOfMarkets = await sdk.api.abi.call({ + target: vault.address, + abi: abis.getMaxNumberMarkets, + chain + }); + + const [maxNumberOfMarkets, idleBalance, assetDecimals, pricefeed, collateralAToken, debtVToken, aave, asset] = await Promise.all([ + sdk.api.abi.call({ + target: vault.address, + abi: abis.getMaxNumberMarkets, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getIdleBalance, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: "erc20:decimals", + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getPricefeed, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getCollateralAToken, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getDebtVToken, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getAave, + chain + }), + sdk.api.abi.call({ + target: vault.address, + abi: abis.getAsset, + chain + }) + ]); + + const [assetSymbol, debtUnderlyingAssetAddress, collateralUnderlyingAssetAddress, debtBalance, collateralBalance] = await Promise.all([ + sdk.api.abi.call({ + target: asset.output, + abi: "erc20:symbol", + chain + }), + sdk.api.abi.call({ + target: debtVToken.output, + abi: abis.getUnderlyingAssetAddress, + chain + }), + sdk.api.abi.call({ + target: collateralAToken.output, + abi: abis.getUnderlyingAssetAddress, + chain + }), + sdk.api.abi.call({ + target: debtVToken.output, + abi: "erc20:balanceOf", + params: [vault.address], + chain + }), + sdk.api.abi.call({ + target: collateralAToken.output, + abi: "erc20:balanceOf", + params: [vault.address], + chain + }) + ]); + + const [debtDecimals, collateralDecimals, reserveData, debtPrice, collateralPrice] = await Promise.all([ + sdk.api.abi.call({ + target: debtUnderlyingAssetAddress.output, + abi: "erc20:decimals", + chain + }), + sdk.api.abi.call({ + target: collateralUnderlyingAssetAddress.output, + abi: "erc20:decimals", + chain + }), + sdk.api.abi.call({ + target: aave.output, + abi: abis.getReserveData, + params: [debtUnderlyingAssetAddress.output], + chain + }), + sdk.api.abi.call({ + target: pricefeed.output, + abi: abis.getPrice, + params: [debtUnderlyingAssetAddress.output], + chain + }), + sdk.api.abi.call({ + target: pricefeed.output, + abi: abis.getPrice, + params: [collateralUnderlyingAssetAddress.output], + chain + }) + ]); + + const variableBorrowRate = +formatUnits(reserveData.output[4], 27); + + const debtTokenPrice = +formatEther(debtPrice.output); + const collateralTokenPrice = +formatEther(collateralPrice.output); + + const debtSize = +formatUnits(debtBalance.output, debtDecimals.output); + const collateralSize = +formatUnits(collateralBalance.output, collateralDecimals.output); + const debtTokenUsd = debtSize * debtTokenPrice; + const collateralTokenUsd = collateralSize * collateralTokenPrice; + + const ltv = debtTokenUsd / collateralTokenUsd; + const ltvPercentage = ltv * 100; + + const ptApy = + pendleMarketDetails[collateralUnderlyingAssetAddress.output]?.impliedApy ?? 0; + + // APY = LTV / (100 - LTV) * (PT APY - Borrow APY) + PT APY + + const aavePositionApy = ltvPercentage / (100 - ltvPercentage) * (ptApy - variableBorrowRate) + ptApy; + + const aavePosition = { + marketApy: aavePositionApy, + positionSize: collateralTokenUsd - debtTokenUsd, + }; + + + const formattedIdleBalance = +formatUnits(idleBalance.output, assetDecimals.output); + + const _morphoPositionsParams = await Promise.all( + Array.from({ length: maxNumberOfMarkets.output }).map(async (_, i) => { + try { + return await sdk.api.abi.call({ + target: vault.address, + abi: abis.getMorphoPositions, + params: [i], + chain + }); + } catch { + return null; + } + }) + ); + + const morphoPositionsParams = _morphoPositionsParams.reduce( + (acc, curr) => { + if (curr) { + acc.push(curr.output); + } + return acc; + }, + [] + ); + + const tokenData = await getUniqueTokensFromMorphoPositions(morphoPositionsParams, chain); + + const loanTokenPrices = await Promise.all( + morphoPositionsParams.map((params) => { + const [loanToken] = params; + return sdk.api.abi.call({ + target: pricefeed.output, + abi: abis.getPrice, + params: [loanToken], + chain + }); + }) + ); + + const collateralTokenPrices = await Promise.all( + morphoPositionsParams.map((params) => { + const [, collateralToken] = params; + return sdk.api.abi.call({ + target: pricefeed.output, + abi: abis.getPrice, + params: [collateralToken], + chain + }); + }) + ); + + const morphoIds = await Promise.all( + morphoPositionsParams.map((params) => { + const [loanToken, collateralToken, oracle, irm, lltv] = params; + + return sdk.api.abi.call({ + target: vault.address, + abi: abis.getId, + params: [{loanToken, collateralToken, oracle, irm, lltv}], + chain + }); + }) + ); + + const morphoPositions = await Promise.all( + morphoIds.map((id) => + fetchAccrualPosition(chain, vault.address, id.output) + ) + ); + + let { total, apyMult, positions } = morphoPositions.reduce( + (acc, position, index) => { + // Accrue interest to get the latest position data + accrueInterest(position, BigInt(Math.floor(Date.now() / 1000))); + + const { + borrowAssets, + ltv: _ltv, + market, + collateral, // quoted in borrowToken + } = position; + + const collateralToken = market.params.collateralToken; + const loanToken = market.params.loanToken; + const ltv = +formatEther(_ltv ?? BigInt(0)); + const borrowApy = +formatEther(getBorrowApy(market, BigInt(Math.floor(Date.now() / 1000)))); + const ptApy = + pendleMarketDetails[market.params.collateralToken] + .impliedApy; + + const marketApy = ((ptApy - borrowApy) * ltv) / (1 - ltv) + ptApy; + + const collateralSize = +formatUnits(collateral, tokenData[collateralToken].decimals); + const borrowSize = +formatUnits(borrowAssets ?? BigInt(0), tokenData[loanToken].decimals); + + const collateralUsd = + collateralSize * + +formatEther(collateralTokenPrices[index].output); + + const borrowUsd = + borrowSize * + +formatEther(loanTokenPrices[index].output); + + const positionSize = collateralUsd - borrowUsd; + + acc.apyMult += positionSize * marketApy; + acc.total += positionSize; + return acc; + }, + { + total: 0, + apyMult: 0 + } + ); + + let tvl = formattedIdleBalance + total; + + if (Object.keys(aavePosition).length > 0) { + tvl += aavePosition.positionSize; + apyMult += aavePosition.positionSize * aavePosition.marketApy; + } + + const vaultApy = apyMult / tvl; + + resolve({ vaultApy: vaultApy, tvl: tvl, asset: asset.output, name: vault.name, address: vault.address, symbol: assetSymbol.output }); + } catch (error) { + console.error("Error fetching looped vault data:"); + console.error(error); + reject(error); + } + }); + }); + + const res = await Promise.all(calls); + + return res.map(vault => { + return { + pool: vault.address, + chain: formatChain(chain), + project: PROJECT_NAME, + underlyingTokens: [vault.asset], + symbol: `Looped${vault.symbol}`, + tvlUsd: vault.tvl || 0, + apyBase: 100 * vault.vaultApy || 0, + url: `${BASE_URL}/vaults/${vault.name}` + } + }); +}; + +const apy = async () => { + const lp = Object.keys(CONFIG).map(async chain => getLpData(chain)); + const shadowLp = [getShadowLpData("sonic")]; + const looped = [getLoopedData("ethereum")]; + + const [lpResults, shadowLpResults, loopedResults] = await Promise.all([ + Promise.all(lp), + Promise.all(shadowLp), + Promise.all(looped) + ]); + + const pools = [...lpResults.flat(), ...shadowLpResults.flat(), ...loopedResults.flat()]; + + return pools; +}; + +module.exports = { apy }; diff --git a/src/adaptors/yieldoor/mathLib.js b/src/adaptors/yieldoor/mathLib.js new file mode 100644 index 0000000000..538f6841bf --- /dev/null +++ b/src/adaptors/yieldoor/mathLib.js @@ -0,0 +1,225 @@ +/** + * Library to manage fixed-point arithmetic. + * https://github.com/morpho-org/morpho-blue/blob/main/src/libraries/MathLib.sol + */ + +const WAD = 1_000000000000000000n; +const RAY = 1_000000000000000000000000000n; + +const maxUint = (nBits) => { + if (nBits % 4 !== 0) throw new Error(`Invalid number of bits: ${nBits}`); + + return BigInt(`0x${"f".repeat(nBits / 4)}`); + } + +const MAX_UINT_256 = maxUint(256); +const MAX_UINT_160 = maxUint(160); +const MAX_UINT_128 = maxUint(128); +const MAX_UINT_48 = maxUint(48); + +/** + * Returns the absolute value of a number + * @param a The number + */ +const abs = (a) => { +a = BigInt(a); + +return a >= 0 ? a : -a; +} + +/** + * Returns the smallest number given as param + * @param x The first number + * @param y The second number + */ +const min = (...xs) => { +return xs.map(BigInt).reduce((x, y) => (x <= y ? x : y)); +} + +/** + * Returns the greatest number given as param + * @param x The first number + * @param y The second number + */ +const max = (...xs) => { +return xs.map(BigInt).reduce((x, y) => (x <= y ? y : x)); +} + +/** + * Returns the subtraction of b from a, floored to zero if negative + * @param x The first number + * @param y The second number + */ +const zeroFloorSub = (x, y) => { +x = BigInt(x); +y = BigInt(y); + +return x <= y ? 0n : x - y; +} + +/** + * Perform the WAD-based multiplication of 2 numbers, rounded down + * @param x The first number + * @param y The second number + */ +const wMulDown = (x, y) => { +return wMul(x, y, "Down"); +} + +/** + * Perform the WAD-based multiplication of 2 numbers, rounded up + * @param x The first number + * @param y The second number + */ +const wMulUp = (x, y) => { +return wMul(x, y, "Up"); +} + +/** + * Perform the WAD-based multiplication of 2 numbers with a provided rounding direction + * @param x The first number + * @param y The second number + */ +const wMul = ( +x, +y, +rounding, +) => { +return mulDiv(x, y, WAD, rounding); +} + +/** + * Perform the WAD-based division of 2 numbers, rounded down + * @param x The first number + * @param y The second number + */ +const wDivDown = (x, y) => { +return wDiv(x, y, "Down"); +} + +/** + * Perform the WAD-based multiplication of 2 numbers, rounded up + * @param x The first number + * @param y The second number + */ +const wDivUp = (x, y) => { +return wDiv(x, y, "Up"); +} + +/** + * Perform the WAD-based multiplication of 2 numbers with a provided rounding direction + * @param x The first number + * @param y The second number + */ +const wDiv = ( +x, +y, +rounding, +) => { +return mulDiv(x, WAD, y, rounding); +} + +/** + * Multiply two numbers and divide by a denominator, rounding down the result + * @param x The first number + * @param y The second number + * @param denominator The denominator + */ +const mulDivDown = ( +x, +y, +denominator, +) => { +x = BigInt(x); +y = BigInt(y); +denominator = BigInt(denominator); +if (denominator === 0n) throw Error("MathLib: DIVISION_BY_ZERO"); + +return (x * y) / denominator; +} + +/** + * Multiply two numbers and divide by a denominator, rounding up the result + * @param x The first number + * @param y The second number + * @param denominator The denominator + */ +const mulDivUp = (x, y, denominator) => { +x = BigInt(x); +y = BigInt(y); +denominator = BigInt(denominator); +if (denominator === 0n) throw Error("MathLib: DIVISION_BY_ZERO"); + +const roundup = (x * y) % denominator > 0 ? 1n : 0n; + +return (x * y) / denominator + roundup; +} + +const mulDiv = ( +x, +y, +denominator, +rounding, +) => { + if (rounding === "Down") { + return mulDivDown(x, y, denominator); + } else if (rounding === "Up") { + return mulDivUp(x, y, denominator); + } else { + throw new Error(`Invalid rounding: ${rounding}`); + } +} + +/** + * The sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, + * to approximate a continuously compounded interest rate. + * + * @param x The base of the exponent + * @param n The exponent + */ +const wTaylorCompounded = (x, n) => { +const firstTerm = BigInt(x) * BigInt(n); +const secondTerm = mulDivDown( + firstTerm, + firstTerm, + 2n * WAD, +); +const thirdTerm = mulDivDown( + secondTerm, + firstTerm, + 3n * WAD, +); + +return firstTerm + secondTerm + thirdTerm; +} + +/** + * Converts a WAD-based quantity to a RAY-based quantity. + * @param x The WAD-based quantity. + */ +const wToRay = (x) => { + return BigInt(x) * 1_000000000n; +} + +module.exports = { + abs, + min, + max, + zeroFloorSub, + wMulDown, + wMulUp, + wMul, + wDivDown, + wDivUp, + wDiv, + mulDivDown, + mulDivUp, + mulDiv, + wTaylorCompounded, + MAX_UINT_256, + MAX_UINT_160, + MAX_UINT_128, + MAX_UINT_48, + WAD, + RAY, +}; diff --git a/src/adaptors/yieldoor/morphoBlueAbi.js b/src/adaptors/yieldoor/morphoBlueAbi.js new file mode 100644 index 0000000000..70836a58d8 --- /dev/null +++ b/src/adaptors/yieldoor/morphoBlueAbi.js @@ -0,0 +1,158 @@ +const blueAbi = [ + { + type: "function", + name: "idToMarketParams", + inputs: [ + { + name: "", + type: "bytes32", + internalType: "Id", + } + ], + outputs: [ + { + name: "loanToken", + type: "address", + internalType: "address", + }, + { + name: "collateralToken", + type: "address", + internalType: "address", + }, + { + name: "oracle", + type: "address", + internalType: "address", + }, + { + name: "irm", + type: "address", + internalType: "address", + }, + { + name: "lltv", + type: "uint256", + internalType: "uint256", + } + ], + stateMutability: "view", + }, + { + type: "function", + name: "market", + inputs: [ + { + name: "", + type: "bytes32", + internalType: "Id", + } + ], + outputs: [ + { + name: "totalSupplyAssets", + type: "uint128", + internalType: "uint128", + }, + { + name: "totalSupplyShares", + type: "uint128", + internalType: "uint128", + }, + { + name: "totalBorrowAssets", + type: "uint128", + internalType: "uint128", + }, + { + name: "totalBorrowShares", + type: "uint128", + internalType: "uint128", + }, + { + name: "lastUpdate", + type: "uint128", + internalType: "uint128", + }, + { + name: "fee", + type: "uint128", + internalType: "uint128", + } + ], + stateMutability: "view", + }, + { + type: "function", + name: "position", + inputs: [ + { + name: "", + type: "bytes32", + internalType: "Id", + }, + { + name: "", + type: "address", + internalType: "address", + } + ], + outputs: [ + { + name: "supplyShares", + type: "uint256", + internalType: "uint256", + }, + { + name: "borrowShares", + type: "uint128", + internalType: "uint128", + }, + { + name: "collateral", + type: "uint128", + internalType: "uint128", + } + ], + stateMutability: "view", + } +]; + +const adaptiveCurveIrmAbi = [ + { + inputs: [ + { + internalType: "Id", + name: "", + type: "bytes32", + } + ], + stateMutability: "view", + type: "function", + name: "rateAtTarget", + outputs: [ + { + internalType: "int256", + name: "", + type: "int256", + } + ], +}]; + +const blueOracleAbi = [ + { + type: "function", + name: "price", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + } + ], + stateMutability: "view", + } +]; + +module.exports = { blueAbi, adaptiveCurveIrmAbi, blueOracleAbi }; \ No newline at end of file diff --git a/src/adaptors/yieldoor/morphoMarketAbi.js b/src/adaptors/yieldoor/morphoMarketAbi.js new file mode 100644 index 0000000000..0c641d1d59 --- /dev/null +++ b/src/adaptors/yieldoor/morphoMarketAbi.js @@ -0,0 +1,121 @@ +const morphoMarketAbi = [ + { + inputs: [ + { + internalType: "contract IMorpho", + name: "morpho", + type: "address", + }, + { + internalType: "Id", + name: "id", + type: "bytes32", + }, + { + internalType: "contract IAdaptiveCurveIrm", + name: "adaptiveCurveIrm", + type: "address", + } + ], + name: "query", + outputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "loanToken", + type: "address", + }, + { + internalType: "address", + name: "collateralToken", + type: "address", + }, + { + internalType: "address", + name: "oracle", + type: "address", + }, + { + internalType: "address", + name: "irm", + type: "address", + }, + { + internalType: "uint256", + name: "lltv", + type: "uint256", + } + ], + internalType: "struct MarketParams", + name: "marketParams", + type: "tuple", + }, + { + components: [ + { + internalType: "uint128", + name: "totalSupplyAssets", + type: "uint128", + }, + { + internalType: "uint128", + name: "totalSupplyShares", + type: "uint128", + }, + { + internalType: "uint128", + name: "totalBorrowAssets", + type: "uint128", + }, + { + internalType: "uint128", + name: "totalBorrowShares", + type: "uint128", + }, + { + internalType: "uint128", + name: "lastUpdate", + type: "uint128", + }, + { + internalType: "uint128", + name: "fee", + type: "uint128", + } + ], + internalType: "struct Market", + name: "market", + type: "tuple", + }, + { + internalType: "bool", + name: "hasPrice", + type: "bool", + }, + { + internalType: "uint256", + name: "price", + type: "uint256", + }, + { + internalType: "uint256", + name: "rateAtTarget", + type: "uint256", + } + ], + internalType: "struct MarketResponse", + name: "res", + type: "tuple", + } + ], + stateMutability: "view", + type: "function", + } +]; + +const code = "0x608080604052346015576104f8908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63d8f172c414610025575f80fd5b34610285576060366003190112610285576004356001600160a01b0381169190829003610285576044356001600160a01b0381169290602435908490036102855761006f8361042c565b60405161007b8161042c565b5f81525f60208201525f60408201525f60608201525f60808201528352602083016040516100a88161045c565b5f81525f60208201525f60408201525f60608201525f60808201525f60a0820152815260408401905f825260608501925f845260808601945f8652604051632c3c915760e01b815282600482015260a081602481855afa908115610291575f9161039f575b5060249160c091895260405192838092632e3071cd60e11b82528660048301525afa908115610291575f91610302575b5082528551604001516001600160a01b03168061029c575b508551606001516001600160a01b0316871461021e575b5060408051955180516001600160a01b0390811688526020808301518216818a015282840151821689850152606080840151909216828a015260809283015189840152935180516001600160801b0390811660a08b81019190915295820151811660c08b015293810151841660e08a0152908101518316610100890152908101518216610120880152909101511661014085015251151561016084015251610180830152516101a08201526101c09150f35b6020906024604051809981936301977b5760e01b835260048301525afa958615610291575f96610258575b509483526101c09460a061016c565b95506020863d602011610289575b8161027360209383610478565b810103126102855794519460a0610249565b5f80fd5b3d9150610266565b6040513d5f823e3d90fd5b60206004916040519283809263501ad8ff60e11b82525afa5f91816102ce575b5015610155576001845284525f610155565b9091506020813d6020116102fa575b816102ea60209383610478565b810103126102855751905f6102bc565b3d91506102dd565b905060c0813d60c011610397575b8161031d60c09383610478565b810103126102855761038c60a0604051926103378461045c565b610340816104ae565b845261034e602082016104ae565b602085015261035f604082016104ae565b6040850152610370606082016104ae565b6060850152610381608082016104ae565b6080850152016104ae565b60a08201525f61013d565b3d9150610310565b905060a0813d60a011610424575b816103ba60a09383610478565b810103126102855760249160c0916080604051916103d78361042c565b6103e08161049a565b83526103ee6020820161049a565b60208401526103ff6040820161049a565b60408401526104106060820161049a565b60608401520151608082015291509161010d565b3d91506103ad565b60a0810190811067ffffffffffffffff82111761044857604052565b634e487b7160e01b5f52604160045260245ffd5b60c0810190811067ffffffffffffffff82111761044857604052565b90601f8019910116810190811067ffffffffffffffff82111761044857604052565b51906001600160a01b038216820361028557565b51906001600160801b03821682036102855756fea2646970667358221220acbd98f027aaca3ed2f90675c4eece5d7bd1a9fbbbb62956dae5a7491ebc745564736f6c634300081b0033"; + +module.exports = { morphoMarketAbi, code }; \ No newline at end of file diff --git a/src/adaptors/yieldoor/morphoSdk.js b/src/adaptors/yieldoor/morphoSdk.js new file mode 100644 index 0000000000..f2446dd8e7 --- /dev/null +++ b/src/adaptors/yieldoor/morphoSdk.js @@ -0,0 +1,182 @@ +const AdaptiveCurveIrmLib = require('./adaptiveCurveIrmLib'); +const MathLib = require('./mathLib'); +const SharesMath = require('./sharesMath'); + +const getUtilization = ( + totalSupplyAssets, + totalBorrowAssets, +) => { + totalSupplyAssets = BigInt(totalSupplyAssets); + totalBorrowAssets = BigInt(totalBorrowAssets); + + if (totalSupplyAssets === 0n) { + if (totalBorrowAssets > 0n) return MathLib.MAX_UINT_256; + + return 0n; + } + + return MathLib.wDivDown(totalBorrowAssets, totalSupplyAssets); +} + +const toBorrowAssets = ( + shares, + market, + rounding = "Up", +) => { + return SharesMath.toAssets( + shares, + market.totalBorrowAssets, + market.totalBorrowShares, + rounding, + ); +} + +/** + * Returns the value of a given amount of collateral quoted in loan assets. + * Return `undefined` iff the market's price is undefined. + */ +const getCollateralValue = ( + collateral, + { price } +) => { + if (price == null) return; + + return MathLib.mulDivDown(collateral, price, AdaptiveCurveIrmLib.ORACLE_PRICE_SCALE); +} + +/** + * Returns the loan-to-value ratio of a given borrow position (scaled by WAD). + * Returns `undefined` iff the market's price is undefined. + * Returns null if the position is not a borrow. + */ +const getLtv = ( + { + collateral, + borrowShares, + }, + market, +) => { + borrowShares = BigInt(borrowShares); + market.totalBorrowShares = BigInt(market.totalBorrowShares); + if (borrowShares === 0n || market.totalBorrowShares === 0n) return null; + + const collateralValue = getCollateralValue(collateral, market); + if (collateralValue == null) return; + if (collateralValue === 0n) return MathLib.MAX_UINT_256; + + return MathLib.wDivUp( + toBorrowAssets(borrowShares, market), + collateralValue, + ); +} + +const getBorrowApy = (market, timestamp) => { + const borrowRate = getBorrowRate(market, timestamp); + + return MathLib.wTaylorCompounded(borrowRate, AdaptiveCurveIrmLib.SECONDS_PER_YEAR); +} + +const getBorrowRate = (market, timestamp) => { + if (market.rateAtTarget == null) return 0n; + + timestamp = BigInt(timestamp); + + const elapsed = timestamp - BigInt(market.lastUpdate); + + if (elapsed < 0n) + throw new Error(`Invalid interest accrual: ${market.id}, ${timestamp}, ${market.lastUpdate}`); + + const { endBorrowRate } = AdaptiveCurveIrmLib.getBorrowRate( + market.utilization, + market.rateAtTarget, + elapsed, + ); + + return endBorrowRate; +} + +const getAccrualBorrowRate = (position, marketId, timestamp, lastUpdate) => { + timestamp = BigInt(timestamp); + + const elapsed = timestamp - lastUpdate; + if (elapsed < 0n) + throw new Error(`Invalid interest accrual: ${marketId}, ${timestamp}, ${lastUpdate}`); + + if (position.rateAtTarget == null) + return { + elapsed, + avgBorrowRate: 0n, + endBorrowRate: 0n, + }; + + return { + elapsed, + ...AdaptiveCurveIrmLib.getBorrowRate( + position.utilization, + position.rateAtTarget, + elapsed, + ), + }; +} + + +/** + * Returns the interest accrued on both sides of the given market + * as well as the supply shares minted to the fee recipient. + * @param borrowRate The average borrow rate since the last market update (scaled by WAD). + * @param market The market state. + * @param elapsed The time elapsed since the last market update (in seconds). + */ +const getAccruedInterest = ( + borrowRate, + { + totalSupplyAssets, + totalBorrowAssets, + totalSupplyShares, + fee, + }, + elapsed = 0n, + ) => { + const interest = MathLib.wMulDown( + totalBorrowAssets, + MathLib.wTaylorCompounded(borrowRate, elapsed), + ); + + const feeAmount = MathLib.wMulDown(interest, fee); + const feeShares = toSupplyShares( + feeAmount, + { + totalSupplyAssets: BigInt(totalSupplyAssets) - feeAmount, + totalSupplyShares, + }, + "Down", + ); + + return { interest, feeShares }; +} + + +const toSupplyShares = ( + assets, + market, + rounding = "Up", +) => { + return SharesMath.toShares( + assets, + market.totalSupplyAssets, + market.totalSupplyShares, + rounding, + ); +} + +module.exports = { + getUtilization, + getAccrualBorrowRate, + getAccruedInterest, + toSupplyShares, + getBorrowApy, + getBorrowRate, + getCollateralValue, + getLtv, + toBorrowAssets, +}; \ No newline at end of file diff --git a/src/adaptors/yieldoor/pendleMarkets.js b/src/adaptors/yieldoor/pendleMarkets.js new file mode 100644 index 0000000000..5767b35941 --- /dev/null +++ b/src/adaptors/yieldoor/pendleMarkets.js @@ -0,0 +1,42 @@ +const axios = require("axios"); +const { utils: { getAddress } } = require("ethers"); + +const HOSTED_SDK_URL = "https://api-v2.pendle.finance/core/v1/"; + +async function callPendleSDK( + path, + params = {} +) { + const response = await axios.get(HOSTED_SDK_URL + path, { + params, + }); + + return response.data; +} + +async function getFormattedActiveMarkets(chainId) { + try { + const data = await callPendleSDK(`${chainId}/markets/active`); + + if (!data) { + throw new Error("Error fetching active markets:"); + } + return data.markets?.reduce( + (acc, currentValue) => { + const pt = getAddress(currentValue.pt.split("-")[1]); + + acc[pt] = currentValue.details; + + return acc; + }, + {} + ); + } catch (error) { + console.error("Error fetching vault data:", error); + throw error; + } +} + +module.exports = { + getFormattedActiveMarkets, +}; \ No newline at end of file diff --git a/src/adaptors/yieldoor/queries.js b/src/adaptors/yieldoor/queries.js new file mode 100644 index 0000000000..ae6476ec6e --- /dev/null +++ b/src/adaptors/yieldoor/queries.js @@ -0,0 +1,28 @@ +const { gql } = require('graphql-request'); + +const formatCollectsQuery = (pool, strategy, block) => { + const queryString = gql` + query data { + pool(id: "${pool}") { + collects( + where: {owner: "${strategy}", _change_block: {number_gte: ${block}}} + ) { + id + amount0 + amount1 + amountUSD + transaction { + burns { + amount + amount0 + amount1 + } + } + } + } + } +`; + return queryString; +} + +module.exports = { formatCollectsQuery }; \ No newline at end of file diff --git a/src/adaptors/yieldoor/sharesMath.js b/src/adaptors/yieldoor/sharesMath.js new file mode 100644 index 0000000000..571a75031a --- /dev/null +++ b/src/adaptors/yieldoor/sharesMath.js @@ -0,0 +1,42 @@ +const MathLib = require('./mathLib'); + +/** + * JS implementation of {@link https://github.com/morpho-org/morpho-blue/blob/main/src/libraries/SharesMathLib.sol SharesMathLib} used by Morpho Blue + * & MetaMorpho (via {@link https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol ERC4626}). + */ + +const VIRTUAL_SHARES = 1000000n; +const VIRTUAL_ASSETS = 1n; + +const toAssets = ( + shares, + totalAssets, + totalShares, + rounding, +) => { + return MathLib.mulDiv( + shares, + BigInt(totalAssets) + VIRTUAL_ASSETS, + BigInt(totalShares) + VIRTUAL_SHARES, + rounding, + ); +} + +const toShares = ( + assets, + totalAssets, + totalShares, + rounding, +) => { + return MathLib.mulDiv( + assets, + BigInt(totalShares) + VIRTUAL_SHARES, + BigInt(totalAssets) + VIRTUAL_ASSETS, + rounding, + ); +} + +module.exports = { + toAssets, + toShares, +}; \ No newline at end of file diff --git a/src/adaptors/yieldwolf/index.js b/src/adaptors/yieldwolf/index.js new file mode 100644 index 0000000000..0dbd85f1c8 --- /dev/null +++ b/src/adaptors/yieldwolf/index.js @@ -0,0 +1,73 @@ +const utils = require('../utils'); +const { request, gql } = require('graphql-request'); +const graphs_url = 'https://yw-api-2-55s94.ondigitalocean.app/graphql'; + +const query = gql` + query Pools($chainId: Int, $first: Int, $filter: PoolFilter, $afterCursor: String, $poolSortBy: PoolSortFilter, $querySearch: String) {\n pools(\n chainId: $chainId\n first: $first\n filter: $filter\n afterCursor: $afterCursor\n poolSortBy: $poolSortBy\n querySearch: $querySearch\n ) {\n nodes {\n ...PoolFragment\n __typename\n }\n cursor\n hasNextPage\n totalCount\n __typename\n }\n}\n\nfragment PoolFragment on Pool {\n type\n chainId\n address\n pid\n baseStakingAddresses\n masterChefAddress\n masterChefPid\n stakingAddress\n liquidityRouterAddress\n swapRouterAddress\n tvl\n totalStakeTokens\n totalEarnTokens\n state\n apy\n dailyReturn\n poolApr\n depositFeeBP\n withdrawFeeBP\n bondPrice\n name\n createdAt\n farm {\n ...FarmFragment\n __typename\n }\n stakeToken {\n ...TokenFragment\n __typename\n }\n earnToken {\n ...TokenFragment\n __typename\n }\n token0 {\n ...TokenFragment\n __typename\n }\n token1 {\n ...TokenFragment\n __typename\n }\n extraEarnTokens {\n ...TokenFragment\n __typename\n }\n __typename\n}\n\nfragment TokenFragment on Token {\n address\n decimals\n symbol\n name\n amountPerUsd\n lpApy\n lpApr\n isStablecoin\n circulatingSupply\n factoryAddress\n __typename\n}\n\nfragment FarmFragment on Farm {\n chainId\n stakingType\n key\n name\n farmType\n stakingType\n listed\n reviewed\n createdAt\n startTime\n masterChefSettings {\n pendingKey\n __typename\n }\n routers\n __typename\n}\n +`; + +const networkMapping = { + 10: { + name: 'optimism', + }, + 43114: { + name: 'avalanche', + }, + 1666600000: { + name: 'harmony', + }, + 42220: { + name: 'celo', + }, + 42161: { + name: 'arbitrum', + }, + 250: { + name: 'fantom', + }, + 137: { + name: 'polygon', + }, + 56: { + name: 'binance', + }, + 25: { + name: 'cronos', + }, +}; + +const apy = async () => { + const poolsResult = await Promise.all(Object.keys(networkMapping).map(id => { + const value = {chainId: Number(id), first: 100, filter: {state: {eq: 'listed'}}}; + return request(graphs_url, query, value); + })); + const res = Object.keys(networkMapping).map((chainId, index) => { + const { pools } = poolsResult[index]; + return pools.nodes + .filter(e => e.token0 !== null) + .filter(e => e.tvl !== 0).map(pool => { + const {token0, token1, tvl, apy, address, poolApr, stakeToken, earnToken} = pool; + const { lpApy } = stakeToken; + const apyBase = lpApy; + const apyReward = poolApr; + return { + pool: address + '-' + networkMapping[chainId].name, + chain: utils.formatChain(networkMapping[chainId].name), + project: 'yieldwolf', + symbol: `${token0?.symbol}${token1?.symbol ? '-' + token1?.symbol : ''}`, + tvlUsd: tvl, + apyBase, + apyReward, + rewardTokens: [earnToken?.address], + underlyingTokens: [token0?.address, token1?.address].filter(e => e) + } + }); + }); + return res.flat(); +}; + +module.exports = { + timetravel: false, + apy: apy, + url: 'https://yieldwolf.finance/', +}; diff --git a/src/adaptors/yldr/abi.js b/src/adaptors/yldr/abi.js new file mode 100644 index 0000000000..c50eb6e1ce --- /dev/null +++ b/src/adaptors/yldr/abi.js @@ -0,0 +1,215 @@ +const abi = { + "inputs": [ + { + "internalType": "contract IPoolAddressesProvider", + "name": "provider", + "type": "address" + } + ], + "name": "getReservesData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "underlyingAsset", + "type": "address" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint256", + "name": "decimals", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseLTVasCollateral", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationThreshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveLiquidationBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "reserveFactor", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "usageAsCollateralEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "borrowingEnabled", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isFrozen", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPaused", + "type": "bool" + }, + { + "internalType": "uint128", + "name": "liquidityIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowIndex", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "liquidityRate", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "variableBorrowRate", + "type": "uint128" + }, + { + "internalType": "uint40", + "name": "lastUpdateTimestamp", + "type": "uint40" + }, + { + "internalType": "address", + "name": "yTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "variableDebtTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "interestRateStrategyAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "availableLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalScaledVariableDebt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInMarketReferenceCurrency", + "type": "uint256" + }, + { + "internalType": "address", + "name": "priceOracle", + "type": "address" + }, + { + "internalType": "uint256", + "name": "variableRateSlope1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "variableRateSlope2", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "baseVariableBorrowRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "optimalUsageRatio", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "accruedToTreasury", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "flashLoanEnabled", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "borrowCap", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supplyCap", + "type": "uint256" + } + ], + "internalType": "struct IUIPoolDataProvider.AggregatedReserveData[]", + "name": "reservesData", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "marketReferenceCurrencyUnit", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "marketReferenceCurrencyPriceInUsd", + "type": "int256" + }, + { + "internalType": "int256", + "name": "networkBaseTokenPriceInUsd", + "type": "int256" + }, + { + "internalType": "uint8", + "name": "networkBaseTokenPriceDecimals", + "type": "uint8" + } + ], + "internalType": "struct IUIPoolDataProvider.BaseCurrencyInfo", + "name": "baseCurrencyInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" +}; + +module.exports = { abi }; \ No newline at end of file diff --git a/src/adaptors/yldr/index.js b/src/adaptors/yldr/index.js new file mode 100644 index 0000000000..2f72e77faa --- /dev/null +++ b/src/adaptors/yldr/index.js @@ -0,0 +1,61 @@ +const { abi } = require('./abi'); +const sdk = require('@defillama/sdk'); +const { calculateAPY } = require('./utils'); +const BigNumber = require('bignumber.js'); +const utils = require('../utils'); + +const chains = ['ethereum', 'arbitrum', 'polygon', 'base']; +const UI_POOL_DATA_PROVIDERS = { "ethereum": '0x6Ab39f4e9F494733893Ca90212558e55C7196012', "arbitrum": '0x775f2616557824bbcf2ea619cA2BacaBd930F2BD', 'polygon': '0x2464dA5c26651cdceD9f6afa9afdc79B5f6413AD', 'base': '0xb9d350537A63B7e5cb02B44e230e093C0abB2707'}; +const ADDRESSES_PROVIDERS = { "ethereum": '0x16085E000eAC286aa503326cBcEe4564268a7F8f', "arbitrum": '0x66d2eaD9cbE6754985a9Be7B829502228Ef8b49B', 'polygon': '0x488402D92f32eEdA5cf61521ADf7f8e8f1DcaC20', 'base': '0x5C6C6ab99afDa79865e57a12c025B0Ad355276aC'}; + +async function apy() { + const pools = await Promise.all( + chains.map(async (chain) => { + const uiPoolDataProviderAddress = UI_POOL_DATA_PROVIDERS[chain]; + const addressesProviderAddress = ADDRESSES_PROVIDERS[chain]; + const reservesData = (await sdk.api.abi.call({ + target: uiPoolDataProviderAddress, + abi: abi, + params: addressesProviderAddress, + chain, + })).output[0]; + const pools = reservesData + .map((reserve, index) => { + const tvlUsd = new BigNumber(reserve.availableLiquidity) + .multipliedBy(reserve.priceInMarketReferenceCurrency) + .shiftedBy(-(Number(reserve.decimals) + 8)) + .toNumber(); + const totalBorrowUsd = new BigNumber(reserve.totalScaledVariableDebt) + .multipliedBy(reserve.variableBorrowIndex) + .multipliedBy(reserve.priceInMarketReferenceCurrency) + .shiftedBy(-(27 + Number(reserve.decimals) + 8)) + .toNumber(); + const totalSupplyUsd = tvlUsd + totalBorrowUsd; + return { + pool: `${reserve.yTokenAddress}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'yldr', + symbol: reserve.symbol, + tvlUsd, + apyBase: calculateAPY(reserve.liquidityRate).toNumber() * 100, + underlyingTokens: [reserve.underlyingAsset], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: + calculateAPY(reserve.variableBorrowRate).toNumber() * 100, + ltv: reserve.baseLTVasCollateral / 10000, + url: `https://yldr.com/lending`, + borrowable: reserve.borrowingEnabled, + }; + }); + + return pools; + }) + ); + return pools.flat(); +} + +module.exports = { + timetravel: true, + apy: apy, +}; diff --git a/src/adaptors/yldr/utils.js b/src/adaptors/yldr/utils.js new file mode 100644 index 0000000000..de76908efa --- /dev/null +++ b/src/adaptors/yldr/utils.js @@ -0,0 +1,47 @@ +const BigNumber = require('bignumber.js'); + +const valueToZDBigNumber = (amount) => { + const BigNumberZeroDecimal = BigNumber.clone({ + DECIMAL_PLACES: 0, + ROUNDING_MODE: BigNumber.ROUND_DOWN, + }); + return new BigNumberZeroDecimal(amount); +}; + +const calculateAPY = (rate) => { + const SECONDS_PER_YEAR = new BigNumber('31536000'); + const RAY = valueToZDBigNumber(10).pow(27); + const RAY_DECIMALS = 27; + const HALF_RAY = RAY.dividedBy(2); + + const rayPow = (a, p) => { + let x = valueToZDBigNumber(a); + let n = valueToZDBigNumber(p); + let z = n.modulo(2).eq(0) ? valueToZDBigNumber(RAY) : x; + + for (n = n.div(2); !n.eq(0); n = n.div(2)) { + x = rayMul(x, x); + + if (!n.modulo(2).eq(0)) { + z = rayMul(z, x); + } + } + + return z; + }; + + const rayMul = (a, b) => { + return HALF_RAY.plus(valueToZDBigNumber(a).multipliedBy(b)).div(RAY); + }; + + return rayPow( + valueToZDBigNumber(rate).dividedBy(SECONDS_PER_YEAR).plus(RAY), + SECONDS_PER_YEAR + ) + .minus(RAY) + .shiftedBy(-RAY_DECIMALS); +}; + +module.exports = { + calculateAPY, +}; diff --git a/src/adaptors/yo-protocol/index.js b/src/adaptors/yo-protocol/index.js new file mode 100644 index 0000000000..ac870adca1 --- /dev/null +++ b/src/adaptors/yo-protocol/index.js @@ -0,0 +1,83 @@ +const superagent = require('superagent'); +const { formatChain, getPrices, getERC4626Info } = require('../utils'); +const { getVaultReward } = require('./services'); + +const PROJECT_NAME = 'yo-protocol'; +const API_URL = 'https://api.yo.xyz/api/v1/vault/stats'; +const MERKL_API_URL = + 'https://api.merkl.xyz/v4/opportunities/?creatorAddress=0xd7A77013933A97A2c08dad7d59937119E76C879a&status=LIVE&chainName=Base'; +const symboToNameMap = { + yoETH: 'Yield Optimizer ETH', + yoBTC: 'Yield Optimizer BTC', + yoUSD: 'Yield Optimizer USD', + yoEUR: 'Yield Optimizer EUR', + yoGOLD: 'Yield Optimizer GOLD', +}; + +const apy = async () => { + const response = await superagent.get(API_URL); + const vaults = response.body.data; + + const priceQuery = vaults + .map((vault) => `${vault.chain.name}:${vault.asset.address}`) + .join(',') + .toLowerCase(); + + const prices = await getPrices( + vaults.map((vault) => `${vault.chain.name}:${vault.asset.address}`) + ); + + const tvls = await Promise.all( + vaults.map((vault) => + getERC4626Info( + vault.contracts.vaultAddress.toLowerCase(), + vault.chain.name + ) + ) + ); + + const tvlByAddress = tvls.reduce((acc, tvl) => { + acc[tvl.pool.toLowerCase()] = tvl.tvl; + return acc; + }, {}); + + // Fetch vault rewards + const vaultRewardMap = await getVaultReward(MERKL_API_URL); + + const result = []; + for (const vault of vaults) { + const normalizedTvl = + tvlByAddress[vault.contracts.vaultAddress.toLowerCase()] / + 10 ** vault.asset.decimals; + + const tvlUsd = + normalizedTvl * + Number(prices.pricesByAddress[vault.asset.address.toLowerCase()]); + + const vaultReward = vaultRewardMap.get( + vault.contracts.vaultAddress.toLowerCase() + ); + + const pool = { + pool: vault.contracts.vaultAddress, + chain: formatChain(vault.chain.name), + poolMeta: vault.name, + project: PROJECT_NAME, + symbol: vault.asset.symbol, + tvlUsd: tvlUsd, + apyBase: Number(vault.yield['1d']), + underlyingTokens: [vault.asset.address], + url: `https://app.yo.xyz/vault/${vault.chain.name}/${vault.contracts.vaultAddress}`, + ...(vaultReward && { + apyReward: Number(vaultReward.apr), + rewardTokens: [vault.asset.address], + }), + }; + + result.push(pool); + } + + return result; +}; + +module.exports = { apy }; diff --git a/src/adaptors/yo-protocol/services.js b/src/adaptors/yo-protocol/services.js new file mode 100644 index 0000000000..eabeaa541b --- /dev/null +++ b/src/adaptors/yo-protocol/services.js @@ -0,0 +1,24 @@ +const superagent = require('superagent'); + +exports.getVaultReward = async (url) => { + const response = (await superagent.get(url)).body; + + // Check if data exists and is an array + if (!response || !Array.isArray(response)) { + return new Map(); + } + + // Filter only live opportunities with valid APR and create a Map + const vaultRewardMap = new Map(); + + response + .filter( + (opportunity) => + opportunity.status === 'LIVE' && typeof opportunity.apr === 'number' + ) + .forEach((opportunity) => { + vaultRewardMap.set(opportunity.identifier.toLowerCase(), opportunity); + }); + + return vaultRewardMap; +}; diff --git a/src/adaptors/yodeswap/abis/lp.json b/src/adaptors/yodeswap/abis/lp.json new file mode 100644 index 0000000000..09dc5dc08a --- /dev/null +++ b/src/adaptors/yodeswap/abis/lp.json @@ -0,0 +1,713 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1In", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "indexed": false, + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + } + ], + "name": "Sync", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MINIMUM_LIQUIDITY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "_reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "_reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "_blockTimestampLast", + "type": "uint32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_token0", + "type": "address" + }, + { + "internalType": "address", + "name": "_token1", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "liquidity", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price0CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "price1CumulativeLast", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "skim", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Out", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Out", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "sync", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/src/adaptors/yodeswap/abis/masterchef.json b/src/adaptors/yodeswap/abis/masterchef.json new file mode 100644 index 0000000000..8fbff36d6d --- /dev/null +++ b/src/adaptors/yodeswap/abis/masterchef.json @@ -0,0 +1,910 @@ +[ + { + "type": "constructor", + "stateMutability": "nonpayable", + "inputs": [ + { + "type": "address", + "name": "_yode", + "internalType": "contract IBoringERC20" + }, + { + "type": "uint256", + "name": "_yodePerBlock", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_marketingAddress", + "internalType": "address" + }, + { + "type": "uint256", + "name": "_marketingPercent", + "internalType": "uint256" + } + ] + }, + { + "type": "event", + "name": "AllocPointsUpdated", + "inputs": [ + { + "type": "address", + "name": "caller", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "previousAmount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "newAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Deposit", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyWithdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmissionRateUpdated", + "inputs": [ + { + "type": "address", + "name": "caller", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "previousAmount", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "newAmount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MetaTxnsDisabled", + "inputs": [ + { + "type": "address", + "name": "caller", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MetaTxnsEnabled", + "inputs": [ + { + "type": "address", + "name": "caller", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OperatorTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOperator", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOperator", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "type": "address", + "name": "previousOwner", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newOwner", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RewardLockedUp", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amountLockedUp", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetmarketingAddress", + "inputs": [ + { + "type": "address", + "name": "oldAddress", + "internalType": "address", + "indexed": true + }, + { + "type": "address", + "name": "newAddress", + "internalType": "address", + "indexed": true + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetmarketingPercent", + "inputs": [ + { + "type": "uint256", + "name": "oldPercent", + "internalType": "uint256", + "indexed": false + }, + { + "type": "uint256", + "name": "newPercent", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Withdraw", + "inputs": [ + { + "type": "address", + "name": "user", + "internalType": "address", + "indexed": true + }, + { + "type": "uint256", + "name": "pid", + "internalType": "uint256", + "indexed": true + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256", + "indexed": false + } + ], + "anonymous": false + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint16", + "name": "", + "internalType": "uint16" + } + ], + "name": "MAXIMUM_DEPOSIT_FEE_RATE", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "MAXIMUM_HARVEST_INTERVAL", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "add", + "inputs": [ + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + }, + { + "type": "uint256", + "name": "_harvestInterval", + "internalType": "uint256" + }, + { + "type": "bool", + "name": "_withUpdate", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "bool", + "name": "", + "internalType": "bool" + } + ], + "name": "canHarvest", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_user", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "deposit", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "depositWithPermit", + "inputs": [ + { + "type": "uint256", + "name": "pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "amount", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "deadline", + "internalType": "uint256" + }, + { + "type": "uint8", + "name": "v", + "internalType": "uint8" + }, + { + "type": "bytes32", + "name": "r", + "internalType": "bytes32" + }, + { + "type": "bytes32", + "name": "s", + "internalType": "bytes32" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "emergencyWithdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "pure", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "getMultiplier", + "inputs": [ + { + "type": "uint256", + "name": "_from", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_to", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "harvestMany", + "inputs": [ + { + "type": "uint256[]", + "name": "_pids", + "internalType": "uint256[]" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "marketingAddress", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "marketingPercent", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "massUpdatePools", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "bool", + "name": "", + "internalType": "bool" + } + ], + "name": "metaTxnsEnabled", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "operator", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "address" + } + ], + "name": "owner", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "pendingYode", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "address", + "name": "_user", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "lpToken", + "internalType": "contract IERC20" + }, + { + "type": "uint256", + "name": "allocPoint", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "lastRewardBlock", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "accYodePerShare", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "depositFeeBP", + "internalType": "uint16" + }, + { + "type": "uint256", + "name": "harvestInterval", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "totalLp", + "internalType": "uint256" + } + ], + "name": "poolInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "poolLength", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "renounceOwnership", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "set", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "uint16", + "name": "_depositFeeBP", + "internalType": "uint16" + }, + { + "type": "uint256", + "name": "_harvestInterval", + "internalType": "uint256" + }, + { + "type": "bool", + "name": "_withUpdate", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setmarketingAddress", + "inputs": [ + { + "type": "address", + "name": "_marketingAddress", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "setmarketingPercent", + "inputs": [ + { + "type": "uint256", + "name": "_newmarketingPercent", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "startBlock", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "startFarming", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "totalAllocPoint", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "totalLockedUpRewards", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "totalYodeInPools", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOperator", + "inputs": [ + { + "type": "address", + "name": "newOperator", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "transferOwnership", + "inputs": [ + { + "type": "address", + "name": "newOwner", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateAllocPoint", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_allocPoint", + "internalType": "uint256" + }, + { + "type": "bool", + "name": "_withUpdate", + "internalType": "bool" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updateEmissionRate", + "inputs": [ + { + "type": "uint256", + "name": "_yodePerBlock", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "updatePool", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "amount", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "rewardDebt", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "rewardLockedUp", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "nextHarvestUntil", + "internalType": "uint256" + } + ], + "name": "userInfo", + "inputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + }, + { + "type": "address", + "name": "", + "internalType": "address" + } + ] + }, + { + "type": "function", + "stateMutability": "nonpayable", + "outputs": [], + "name": "withdraw", + "inputs": [ + { + "type": "uint256", + "name": "_pid", + "internalType": "uint256" + }, + { + "type": "uint256", + "name": "_amount", + "internalType": "uint256" + } + ] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "address", + "name": "", + "internalType": "contract IBoringERC20" + } + ], + "name": "yode", + "inputs": [] + }, + { + "type": "function", + "stateMutability": "view", + "outputs": [ + { + "type": "uint256", + "name": "", + "internalType": "uint256" + } + ], + "name": "yodePerBlock", + "inputs": [] + } +] \ No newline at end of file diff --git a/src/adaptors/yodeswap/index.js b/src/adaptors/yodeswap/index.js new file mode 100644 index 0000000000..1751a7c309 --- /dev/null +++ b/src/adaptors/yodeswap/index.js @@ -0,0 +1,319 @@ +const utils = require('../utils'); +const sdk = require('@defillama/sdk'); +const { default: BigNumber } = require('bignumber.js'); +const superagent = require('superagent'); +const masterChefABI = require('./abis/masterchef.json'); +const lpABI = require('./abis/lp.json'); +const { chunk } = require('lodash'); +const { request, gql, batchRequests } = require('graphql-request'); + +const YODE_TOKEN = '0x6FC4563460d5f45932C473334d5c1C5B4aEA0E01'; +const MASTERCHEF_ADDRESS = '0xf7b1150cb31488bde3eB3201e0FDF1Bd54799712'; +const BLOCK_TIME = 2; +const BLOCKS_PER_YEAR = Math.floor((60 / BLOCK_TIME) * 60 * 24 * 365); +const FEE_RATE = 0.001; +const WEEKS_PER_YEAR = 52; + +const mapTokenDogeChaintoBSC = { + '0x765277EebeCA2e31912C9946eAe1021199B39C61': + '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // USDC + '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101': + '0xba2ae424d960c26247dd6c32edc70b295c744c43', // WWDOGE + '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D': + '0x55d398326f99059fF775485246999027B3197955', // usdt, + '0x332730a4F6E03D9C55829435f10360E13cfA41Ff': + '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', // busd, + '0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F': + '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', // bnb +}; + +const mapTokenBSCtoDogeChain = { + '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d': + '0x765277EebeCA2e31912C9946eAe1021199B39C61', + '0xba2ae424d960c26247dd6c32edc70b295c744c43': + '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101', + '0x55d398326f99059ff775485246999027b3197955': + '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', + '0xe9e7cea3dedca5984780bafc599bd69add087d56': + '0x332730a4F6E03D9C55829435f10360E13cfA41Ff', + '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c': + '0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F', +}; + +const API_URL = 'https://graph.yodeswap.dog/subgraphs/name/yodeswap'; +const pairQuery = gql` + query pairQuery($id_in: [ID!]) { + pairs(where: { id_in: $id_in }) { + id + token0 { + symbol + decimals + id + } + token1 { + symbol + decimals + id + } + } + } +`; + +const getPriceByReserves = (reserves) => { + return reserves[1] / reserves[0]; +}; + +const getPairInfo = async (pairs) => { + const pairInfo = await Promise.all( + chunk(pairs, 7).map((tokens) => + request(API_URL, pairQuery, { + id_in: tokens.map((pair) => pair.toLowerCase()), + }) + ) + ); + + return pairInfo + .map(({ pairs }) => pairs) + .flat() + .reduce((acc, pair) => ({ ...acc, [pair.id.toLowerCase()]: pair }), {}); +}; + +const getPrices = async (addresses) => { + const prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .map((address) => `bsc:${mapTokenDogeChaintoBSC[address]}`) + + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [mapTokenBSCtoDogeChain[address.split(':')[1]].toLowerCase()]: + price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + couponPerSecond, + couponPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint.output; + const couponPerYear = BigNumber(couponPerSecond) + .times(BLOCKS_PER_YEAR) + .times(poolWeight); + const apy = couponPerYear.times(couponPrice).div(reserveUSD).times(100); + return apy.toNumber(); +}; + +const calculateReservesUSD = ( + reserves, + reservesRatio, + token0, + token1, + tokenPrices +) => { + const { decimals: token0Decimals, id: token0Address } = token0; + const { decimals: token1Decimals, id: token1Address } = token1; + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0Decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1Decimals)); + + if (token0Price) return reserve0.times(token0Price).times(2); + if (token1Price) return reserve1.times(token1Price).times(2); +}; + +const getApy = async () => { + const poolLength = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'poolLength'), + }); + const totalAllocPoint = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'totalAllocPoint'), + }); + const couponPerBlock = await sdk.api.abi.call({ + target: MASTERCHEF_ADDRESS, + chain: 'dogechain', + abi: masterChefABI.find((e) => e.name === 'yodePerBlock'), + }); + const normalizedcouponPerBlock = couponPerBlock.output / 1e18; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolLength.output)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain: 'dogechain', + requery: true, + }); + + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter((e) => e.allocPoint !== '0') + .filter((e) => e.lpToken !== '0xB7ddC6414bf4F5515b52D8BdD69973Ae205ff101'); + + const lpTokens = pools.map(({ lpToken }) => lpToken); + const [reservesRes, supplyRes, masterChefBalancesRes] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain: 'dogechain', + requery: true, + }) + ) + ); + + const [underlyingToken0, underlyingToken1] = await Promise.all( + ['token0', 'token1'].map((method) => + sdk.api.abi.multiCall({ + abi: lpABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + })), + chain: 'dogechain', + requery: true, + }) + ) + ); + + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res, i) => res.output + ); + const tokens0 = underlyingToken0.output.map((res) => res.output); + const tokens1 = underlyingToken1.output.map((res) => res.output); + const tokensPrices = await getPrices([...tokens0, ...tokens1]); + const yodeId = 'coingecko:yodeswap'; + const yodePrice = ( + await superagent.get(`https://coins.llama.fi/prices/current/${yodeId}`) + ).body.coins[yodeId].price; + tokensPrices[YODE_TOKEN.toLowerCase()] = yodePrice; + const pairsInfo = await getPairInfo(lpTokens); + const lpChunks = chunk(lpTokens, 10); + + const pairVolumes = await Promise.all( + lpChunks.map((lpsChunk) => + request( + API_URL, + gql` + query volumesQuery { + ${lpsChunk + .slice(0, 10) + .map( + (token, i) => `token_${token.toLowerCase()}:pairDayDatas( + orderBy: date + orderDirection: desc + first: 7 + where: { pairAddress: "${token.toLowerCase()}" } + ) { + dailyVolumeUSD + }` + ) + .join('\n')} + + } + ` + ) + ) + ); + + const volumesMap = pairVolumes.flat().reduce( + (acc, curChunk) => ({ + ...acc, + ...Object.entries(curChunk).reduce((innerAcc, [key, val]) => ({ + ...innerAcc, + [key.split('_')[1]]: val, + })), + }), + {} + ); + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairsInfo[pool.lpToken.toLowerCase()]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const masterChefReservesUsd = calculateReservesUSD( + reserves, + masterChefBalance / supply, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const lpReservesUsd = calculateReservesUSD( + reserves, + 1, + pairInfo.token0, + pairInfo.token1, + tokensPrices + ) + .div(1e18) + .toString(); + + const lpFees7D = + (volumesMap[pool.lpToken.toLowerCase()] || []).reduce( + (acc, { dailyVolumeUSD }) => acc + Number(dailyVolumeUSD), + 0 + ) * FEE_RATE; + const apyBase = ((lpFees7D * WEEKS_PER_YEAR) / lpReservesUsd) * 100; + + const apyReward = calculateApy( + poolInfo, + totalAllocPoint, + normalizedcouponPerBlock, + tokensPrices[YODE_TOKEN.toLowerCase()], + masterChefReservesUsd + ); + + return { + pool: pool.lpToken, + chain: utils.formatChain('dogechain'), + project: 'yodeswap', + symbol: `${pairInfo.token0.symbol}-${pairInfo.token1.symbol}`, + tvlUsd: Number(masterChefReservesUsd), + apyBase, + apyReward, + underlyingTokens: [tokens0[i], tokens1[i]], + rewardTokens: [YODE_TOKEN], + }; + }); + + return res; +}; + +module.exports = { + timetravel: false, + apy: getApy, + url: 'https://yodeswap.dog', +}; diff --git a/src/adaptors/yuzu-finance/index.ts b/src/adaptors/yuzu-finance/index.ts new file mode 100644 index 0000000000..8c3ef6d979 --- /dev/null +++ b/src/adaptors/yuzu-finance/index.ts @@ -0,0 +1,83 @@ +const utils = require('../utils'); + +const YUZU_API_URL_BASE = 'https://mainnet-api.yuzu.finance/v1'; + +async function getPools() { + const pageSize = 100; + let currentPage = 1; + let allPools = []; + + while (true) { + const response = await utils.getData( + `${YUZU_API_URL_BASE}/pools?page=${currentPage}&pageSize=${pageSize}` + ); + + if (!response?.data || response.data.length === 0) { + break; + } + + allPools = allPools.concat(response.data); + + // If we've fetched all pools, break + if (allPools.length >= response.total) { + break; + } + + currentPage++; + } + + return allPools; +} + +async function getTokens() { + const response = await utils.getData( + `${YUZU_API_URL_BASE}/tokens?pageSize=100` + ); + + if (!response?.data) { + return []; + } + + return response.data; +} + +async function main() { + // We're not using on-chain RPC requests here due to the rate limiting and instability of both official and third party RPCs and using our own load-balanced API. + const pools = await getPools(); + const tokens = await getTokens(); + + const defiLlamaPools = pools + .map((pool) => { + const token0 = tokens.find((token) => token.metadata === pool.token0); + const token1 = tokens.find((token) => token.metadata === pool.token1); + const symbol = + token0 && token1 ? `${token0.symbol}-${token1.symbol}` : 'unknown'; + + return { + pool: pool.poolAddr + '-move', + chain: utils.formatChain('move'), + project: 'yuzu-finance', + symbol, + tvlUsd: parseFloat(pool.tvl), + apyBase: pool.feeApr * 100, + apyReward: pool.rewardApr * 100, + // Ensure unique reward tokens since the frontend allows adding the same token multiple times + // This prevents duplicate rewards from appearing in the DefiLlama dashboard + rewardTokens: Array.from( + new Set(pool.rewardInfos?.map((reward) => reward.tokenMetadata) || []) + ), + underlyingTokens: [pool.token0, pool.token1], + volumeUsd1d: +pool.volume24h, + volumeUsd7d: +pool.volume7d, + }; + }) + .filter(Boolean); // Remove null entries + + return defiLlamaPools; +} + +module.exports = { + timetravel: false, + apy: main, + url: `${YUZU_API_URL_BASE}/pools`, +}; diff --git a/src/adaptors/yuzu-money/index.js b/src/adaptors/yuzu-money/index.js new file mode 100644 index 0000000000..cc4042cc74 --- /dev/null +++ b/src/adaptors/yuzu-money/index.js @@ -0,0 +1,118 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const axios = require('axios'); + +const chain = 'plasma'; + +const yzUSD = '0x6695c0f8706c5ace3bdf8995073179cca47926dc'; +const syzUSD = '0xc8a8df9b210243c55d31c73090f06787ad0a1bf6'; + +const yzUSD_unit = 1e18; +const syzUSD_unit = 1e18; + +const YEAR_IN_DAYS = 365; +const DAY_IN_SECONDS = 24 * 60 * 60; + +const APY_REFERENCE_PERIOD_IN_DAYS = 7; + +const getUsdPrice = async () => { + try { + const priceKey = `${chain}:${syzUSD}`; + const { data } = await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`); + return data.coins[priceKey].price; + } catch (error) { + console.error('Error fetching USD price:', error); + throw error; + } +}; + +const getTotalSupply = async () => { + try { + const { output } = await sdk.api.abi.call({ + target: syzUSD, + abi: 'erc20:totalSupply', + chain, + }); + return output / syzUSD_unit; + } catch (error) { + console.error('Error fetching total supply:', error); + throw error; + } +}; + +const getRedemptionPrice = async (blockNumber) => { + try { + const { output } = await sdk.api.abi.call({ + target: syzUSD, + abi: 'function previewRedeem(uint256 shares) external view returns (uint256)', + params: [BigInt(syzUSD_unit)], + chain, + block: blockNumber, + }); + return output / yzUSD_unit; + } catch (error) { + console.error('Error fetching redemption price:', error); + throw error; + } +}; + +const calculateUsdTvl = async () => { + try { + const totalSupply = await getTotalSupply(); + const tokenPrice = await getUsdPrice(); + return totalSupply * tokenPrice; + } catch (error) { + console.error('Error calculating USD TVL:', error); + throw error; + } +}; + +const calculateApy = async () => { + try { + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const startTimestamp = currentBlock.timestamp - APY_REFERENCE_PERIOD_IN_DAYS * DAY_IN_SECONDS; + const [startBlock] = await utils.getBlocksByTime([startTimestamp], chain); + + const [startPrice, currentPrice] = await Promise.all([getRedemptionPrice(startBlock), getRedemptionPrice(currentBlock.block)]); + + const appreciationRatio = currentPrice / startPrice; + const apy = (Math.pow(appreciationRatio, YEAR_IN_DAYS / APY_REFERENCE_PERIOD_IN_DAYS) - 1) * 100; + + return apy; + } catch (error) { + console.error('Error calculating APY:', error); + throw error; + } +}; + +const syzUSDPool = async () => { + try { + const [tvlUsd, apyBase] = await Promise.all([calculateUsdTvl(), calculateApy()]); + return { + tvlUsd, + apyBase, + pool: (`${syzUSD}-${chain}`).toLowerCase(), + chain: 'Plasma', + project: 'yuzu-money', + symbol: 'yzUSD', + underlyingTokens: [yzUSD], + url: 'https://app.yuzu.money/syzusd', + }; + } catch (error) { + console.error('Error fetching pool data:', error); + throw error; + } +}; + +const apy = async () => { + try { + return [await syzUSDPool()]; + } catch (error) { + console.error('Error fetching pools:', error); + throw error; + } +}; + +module.exports = { + apy, +}; diff --git a/src/adaptors/zealousswap/index.js b/src/adaptors/zealousswap/index.js new file mode 100644 index 0000000000..32dfcb6ba6 --- /dev/null +++ b/src/adaptors/zealousswap/index.js @@ -0,0 +1,186 @@ +// Zealous Swap (Kasplex) — Pools adapter for DefiLlama yield-server +// Fetches pool data from our API and reserves on-chain, calculating TVL using DefiLlama's price feeds. +// +// Endpoint used: https://kasplex.zealousswap.com/v1/pools +// Notes: +// - Reserves are fetched on-chain via getReserves(), with API fallback if call fails +// - TVL is calculated from token reserves using DefiLlama's price API +// - Falls back to API's TVL value if DefiLlama prices are unavailable +// - We use `apr` from our API as `apyBase` (already annualized %) +// - If `apr` is missing, we fall back to fee APR from volume * feeRate +// - We include `apyReward` only if our API reports a positive `farmApr` + +const axios = require("axios"); +const sdk = require("@defillama/sdk"); +const BigNumber = require("bignumber.js"); + +const CHAIN = "kasplex"; +const API = "https://kasplex.zealousswap.com/v1/pools"; + +function toNumber(x) { + if (x === null || x === undefined) return 0; + const n = Number(x); + return Number.isFinite(n) ? n : 0; +} + +function poolSymbol(p) { + const s0 = p.token0?.symbol || "T0"; + const s1 = p.token1?.symbol || "T1"; + return `${s0}-${s1}`; +} + +function calcFeeAPR(volumeUSD, tvlUsd, feeRate) { + const vol = toNumber(volumeUSD); + const tvl = toNumber(tvlUsd); + const fee = toNumber(feeRate); + if (tvl <= 0 || vol <= 0 || fee <= 0) return 0; + return (vol * fee / tvl) * 365 * 100; +} + +const getPrices = async (addresses, chain) => { + const prices = ( + await axios.get( + `https://coins.llama.fi/prices/current/${addresses + .map((address) => `${chain}:${address}`) + .join(',') + .toLowerCase()}` + ) + ).data.coins; + + const pricesObj = Object.entries(prices).reduce( + (acc, [address, price]) => ({ + ...acc, + [address.split(':')[1].toLowerCase()]: price.price, + }), + {} + ); + + return pricesObj; +}; + +const calculateReservesUSD = ( + reserve0, + reserve1, + token0Address, + token1Address, + decimals0, + decimals1, + tokenPrices +) => { + const token0Price = tokenPrices[token0Address.toLowerCase()]; + const token1Price = tokenPrices[token1Address.toLowerCase()]; + + const reserve0Adjusted = new BigNumber(reserve0).div(10 ** decimals0); + const reserve1Adjusted = new BigNumber(reserve1).div(10 ** decimals1); + + if (token0Price) return reserve0Adjusted.times(token0Price).times(2); + if (token1Price) return reserve1Adjusted.times(token1Price).times(2); + + return null; +}; + +async function apy() { + const { data } = await axios.get(API); + const poolsObj = data?.pools || {}; + + const poolAddresses = Object.keys(poolsObj); + if (poolAddresses.length === 0) return []; + + const reservesResults = await sdk.api.abi.multiCall({ + abi: { + inputs: [], + name: "getReserves", + outputs: [ + { internalType: "uint112", name: "_reserve0", type: "uint112" }, + { internalType: "uint112", name: "_reserve1", type: "uint112" }, + { internalType: "uint32", name: "_blockTimestampLast", type: "uint32" } + ], + stateMutability: "view", + type: "function" + }, + calls: poolAddresses.map((address) => ({ + target: address, + })), + chain: CHAIN, + permitFailure: true, + }); + + const tokenAddresses = new Set(); + for (const p of Object.values(poolsObj)) { + if (p.token0?.address) tokenAddresses.add(p.token0.address.toLowerCase()); + if (p.token1?.address) tokenAddresses.add(p.token1.address.toLowerCase()); + } + + const tokenPrices = await getPrices(Array.from(tokenAddresses), CHAIN); + + const results = []; + + for (let i = 0; i < poolAddresses.length; i++) { + const address = poolAddresses[i]; + const p = poolsObj[address]; + + if (!p.token0?.address || !p.token1?.address) continue; + + const reserveData = reservesResults.output[i]; + let reserve0, reserve1; + + if (reserveData && reserveData.success && reserveData.output) { + reserve0 = reserveData.output._reserve0 || reserveData.output[0]; + reserve1 = reserveData.output._reserve1 || reserveData.output[1]; + } else { + reserve0 = p.token0Reserves; + reserve1 = p.token1Reserves; + } + + if (!reserve0 || !reserve1) continue; + + const tvlFromReserves = calculateReservesUSD( + reserve0, + reserve1, + p.token0.address, + p.token1.address, + p.token0.decimals, + p.token1.decimals, + tokenPrices + ); + + const tvlUsd = tvlFromReserves + ? Number(tvlFromReserves.toString()) + : toNumber(p.tvl); + + if (!(tvlUsd > 0)) continue; + + let apyBase = toNumber(p.apr); + + if (!(apyBase > 0)) { + const feeRate = p.regularFeeRate ?? p.discountedFeeRate ?? 0.003; + apyBase = calcFeeAPR(p.volumeUSD, tvlUsd, feeRate); + } + + const apyReward = toNumber(p.farmApr) > 0 ? toNumber(p.farmApr) : null; + + results.push({ + pool: `${address}-${CHAIN}`, + chain: CHAIN, + project: "zealousswap", + symbol: poolSymbol(p), + tvlUsd, + apyBase, + apyReward, + rewardTokens: p.hasActiveFarm + ? ["0xb7a95035618354D9ADFC49Eca49F38586B624040"] + : [], + underlyingTokens: [p.token0.address, p.token1.address], + url: "https://app.zealousswap.com/liquidity", + volumeUsd1d: toNumber(p.volumeUSD), + }); + } + + return results.filter(x => Number.isFinite(x.tvlUsd) && x.tvlUsd > 0); +} + +module.exports = { + timetravel: false, + apy, + url: API, +}; \ No newline at end of file diff --git a/src/adaptors/zeebu/index.js b/src/adaptors/zeebu/index.js new file mode 100644 index 0000000000..2e3b62321c --- /dev/null +++ b/src/adaptors/zeebu/index.js @@ -0,0 +1,174 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const utils = require('../utils'); + +// Reward tokens per chain (1st = stablecoin, 2nd = ZBU) +const REWARD_TOKENS = { + ethereum: ['0xdAC17F958D2ee523a2206206994597C13D831ec7', '0xe77f6aCD24185e149e329C1C0F479201b9Ec2f4B'], + base: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', '0x2C8C89C442436CC6C0A77943E09C8DAF49DA3161'], + bsc: ['0x55d398326f99059ff775485246999027b3197955', '0x4D3dc895a9EDb234DfA3e303A196c009dC918f84'], +}; + +// ZBU token addresses per chain +const ZBU = { + ethereum: '0xe77f6aCD24185e149e329C1C0F479201b9Ec2f4B', + base: '0x2C8C89C442436CC6C0A77943E09C8DAF49DA3161', + bsc: '0x4D3dc895a9EDb234DfA3e303A196c009dC918f84', +}; + +// Reward Distributor contracts +const REWARD_DISTRIBUTORS = { + ethereum: '0xE843115fF0Dc2b20f5b07b6E7Ba5fED064468AC6', + base: '0x24a4f5afc6a87005f00770e7e66d4a3d134f9923', + bsc: '0x8ae3D193a7Dfeb4c8e36211d21E729feCcfa738A', +}; + +// Voting Escrow contracts +const VOTING_ESCROW_ADDRESSES = { + ethereum: '0x8e76Cdf3b14c540aB54aFa7f8492AC1d16Ecfb35', + base: '0xcf08D1EC5d8e566D95299399307F75f98D6AEa03', + bsc: '0xd3e8cD2eDbf252860E02ffb245fD654b1ab30f30', +}; + +// Chain-specific block numbers (for fetching logs) +const FROM_BLOCKS = { + ethereum: 21324707, + base: 23235100, + bsc: 44561619, +}; + +// Decimals for stablecoins & ZBU +const DECIMALS = { + ethereum: [6, 18], // USDT (6), ZBU (18) + base: [6, 18], // USDC (6), ZBU (18) + bsc: [18, 18], // BSC-USD (18), ZBU (18) +}; + +// Event topic for AddedRewardDistribution +const ADDED_REWARD_DISTRIBUTION_TOPIC = '0xf00943d3f835d7ca6986bc0202fbb734d3be564db0bad44bafccb5d41149302e'; + +const apy = async () => { + console.log("Starting APY calculation..."); + const results = []; + + for (const chain of Object.keys(REWARD_DISTRIBUTORS)) { + console.log(`Processing ${chain}...`); + + // Fetch total staked ZBU + const totalStakedZBU = ( + await sdk.api.abi.call({ + target: ZBU[chain], + abi: 'erc20:balanceOf', + params: [VOTING_ESCROW_ADDRESSES[chain]], + chain, + }) + ).output / 1e18; // ZBU has 18 decimals + console.log(`Total Staked ZBU on ${chain}: `, totalStakedZBU, ` ZBU`); + + // Fetch prices for both reward tokens (stablecoin + ZBU) + const tokenPrices = {}; + for (const token of REWARD_TOKENS[chain]) { + const priceKey = `${chain}:${token}`; + tokenPrices[token] = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + } + console.log(`Token Prices for ${chain}: `, tokenPrices); + + // Calculate TVL in USD (using stablecoin price) + const tvlUsd = totalStakedZBU * tokenPrices[REWARD_TOKENS[chain][1]]; + console.log(`TVL (USD) for ${chain}: $ `, tvlUsd); + const currentBlock = await sdk.api.util.getLatestBlock(chain); + const toBlock = currentBlock.number; + // Fetch logs from RewardDistributor contract + const logs = ( + await sdk.api.util.getLogs({ + target: REWARD_DISTRIBUTORS[chain], + topic: '', + toBlock, + fromBlock: FROM_BLOCKS[chain], + keys: [], + topics: [ADDED_REWARD_DISTRIBUTION_TOPIC], + chain, + }) + ).output.sort((a, b) => b.blockNumber - a.blockNumber); + // console.log(`Fetched Logs for ${chain}: `, logs); + + if (logs.length === 0) { + console.log(`No reward distribution events found for ${chain}.`); + continue; + } + + // Decode and sum up rewards + let totalRewardsUsd = 0; + + for (const log of logs) { + const dataHex = log.data; + const amountHex = dataHex.slice(0, 66); // First 32 bytes -> Amount + const timestampHex = dataHex.slice(66, 130); // Second 32 bytes -> Reward Timestamp + + const tokenAddress = `0x${log.topics[2].slice(-40)}`; // Extract token address + console.log("Token Address: ", tokenAddress); + const decimals = REWARD_TOKENS[chain][0].toLowerCase() === tokenAddress.toLowerCase() + ? DECIMALS[chain][0] // First token (Stablecoin) + : DECIMALS[chain][1]; // Second token (ZBU) + + const amount = Number(BigInt(amountHex).toString()) / 10 ** decimals; + const rewardTimestamp = parseInt(timestampHex, 16); + + // Fetch token price + let tokenPrice; + if (REWARD_TOKENS[chain][0].toLowerCase() === tokenAddress.toLowerCase()) { + // If it's a usd-pegged stablecoin, use $1 + tokenPrice = 1; + } else { + // If it's ZBU, use its actual price + tokenPrice = tokenPrices[Object.keys(tokenPrices).find( + key => key.toLowerCase() === tokenAddress.toLowerCase() + )]; + } + + const rewardValueUsd = Number(amount) * tokenPrice; + totalRewardsUsd += rewardValueUsd; + + console.log(`Token: ${tokenAddress} - Amount: ${amount} - Reward Value (in USD): ${rewardValueUsd} - Timestamp: ${rewardTimestamp}`); + } + + console.log(`Total Rewards in USD for ${chain}: `, totalRewardsUsd); + + // APY Calculation + const now = Math.floor(Date.now() / 1000); + const firstLogTimestamp = parseInt(logs[logs.length - 1].data.slice(66, 130), 16); + const daysSinceStart = (now - firstLogTimestamp) / 86400; + + if (daysSinceStart <= 0) { + console.log(`Invalid daysSinceStart for ${chain}. Skipping APY calculation.`); + continue; + } + + const aprReward = (totalRewardsUsd * 365) / (tvlUsd * daysSinceStart) * 100; + const apyReward = utils.aprToApy(aprReward, 52); + + console.log(`APR (Reward) for ${chain}: `, aprReward); + console.log(`APY (Reward) for ${chain}: `, apyReward); + + results.push({ + pool: VOTING_ESCROW_ADDRESSES[chain], + chain: chain.charAt(0).toUpperCase() + chain.slice(1), + project: 'zeebu', + symbol: 'ZBU', + tvlUsd, + apyReward, + rewardTokens: REWARD_TOKENS[chain], + underlyingTokens: [ZBU[chain]], + poolMeta: 'Zeebu Staking Rewards', + url: 'https://zeebu.fi/', + }); + } + + return results; +}; + +module.exports = { + apy +}; diff --git a/src/adaptors/zerolend/index.js b/src/adaptors/zerolend/index.js new file mode 100755 index 0000000000..77e6d6537f --- /dev/null +++ b/src/adaptors/zerolend/index.js @@ -0,0 +1,319 @@ +const superagent = require('superagent'); +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); + +const utils = require('../utils'); +const { aTokenAbi } = require('../aave-v3/abi'); +const poolAbi = require('../aave-v3/poolAbi'); + +const SECONDS_PER_YEAR = 31536000; + +const chainUrlParam = { + linea: ['proto_linea_v3'], + ethereum: [ + 'proto_mainnet_lrt_v3', + 'proto_mainnet_btc_v3', + 'proto_mainnet_rwa_v3', + ], + era: ['proto_zksync_era_v3'], + blast: ['proto_blast_v3'], + manta: ['proto_manta_v3'], + xlayer: ['proto_layerx_v3'], + base: ['proto_base_v3'], +}; + +const mainnnet_pools = { + '0x3bc3d34c32cc98bf098d832364df8a222bbab4c0': 'proto_mainnet_lrt_v3', + '0xcd2b31071119d7ea449a9d211ac8ebf7ee97f987': 'proto_mainnet_btc_v3', + '0xd3a4da66ec15a001466f324fa08037f3272bdbe8': 'proto_mainnet_rwa_v3', +}; +const oraclePriceABI = { + inputs: [ + { + internalType: 'address', + name: 'asset', + type: 'address', + }, + ], + name: 'getAssetPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', +}; + +const getPrices = async (addresses) => { + const _prices = ( + await superagent.get( + `https://coins.llama.fi/prices/current/${addresses + .join(',') + .toLowerCase()}` + ) + ).body.coins; + + const zeroPrice = ( + await sdk.api.abi.call({ + target: '0x1cc993f2C8b6FbC43a9bafd2A44398E739733385', + abi: oraclePriceABI, + params: ['0x3db28e471fa398bf2527135a1c559665941ee7a3'], + chain: 'ethereum', + }) + ).output; + + const earlyZero = { + 'era:0x9793eac2fecef55248efa039bec78e82ac01cb2f': { + decimals: 18, + symbol: 'earlyZERO', + price: Number(zeroPrice) / 1e8, + timestamp: Date.now(), + confidence: 0.99, + }, + 'linea:0x40a59a3f3b16d9e74c811d24d8b7969664cfe180': { + decimals: 18, + symbol: 'earlyZERO', + price: Number(zeroPrice) / 1e8, + timestamp: Date.now(), + confidence: 0.99, + }, + 'ethereum:0x3db28e471fa398bf2527135a1c559665941ee7a3': { + decimals: 18, + symbol: 'earlyZERO', + price: Number(zeroPrice) / 1e8, + timestamp: Date.now(), + confidence: 0.99, + }, + }; + + const prices = { ..._prices, ...earlyZero }; + + const pricesBySymbol = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [price.symbol.toLowerCase()]: price.price, + }), + {} + ); + + const pricesByAddress = Object.entries(prices).reduce( + (acc, [name, price]) => ({ + ...acc, + [name.split(':')[1]]: price.price, + }), + {} + ); + + return { pricesByAddress, pricesBySymbol }; +}; + +const baseUrl = + 'https://api.goldsky.com/api/public/project_clsk1wzatdsls01wchl2e4n0y/subgraphs/'; +const API_URLS = { + ethereum: [ + baseUrl + 'zerolend-mainnet-lrt/1.0.0/gn', + baseUrl + 'zerolend-mainnet-btc/1.0.0/gn', + baseUrl + 'zerolend-mainnet-rwa/1.0.1/gn', + ], + linea: [baseUrl + 'zerolend-linea/1.0.0/gn'], + era: [baseUrl + 'zerolend-zksync/1.0.0/gn'], + manta: [baseUrl + 'zerolend-m/1.0.0/gn'], + blast: [baseUrl + 'zerolend-blast/1.0.1/gn'], + xlayer: [baseUrl + 'zerolend-xlayer/1.0.0/gn'], + base: [baseUrl + 'zerolend-base-mainnet/1.0.0/gn'], +}; + +const query = gql` + query ReservesQuery { + reserves(where: { name_not: "" }) { + name + borrowingEnabled + pool { + pool + } + aToken { + id + rewards { + id + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + underlyingAssetAddress + underlyingAssetDecimals + } + vToken { + rewards { + emissionsPerSecond + rewardToken + rewardTokenDecimals + rewardTokenSymbol + distributionEnd + } + } + symbol + liquidityRate + variableBorrowRate + baseLTVasCollateral + isFrozen + } + } +`; + +const apy = async () => { + let data = await Promise.all( + Object.entries(API_URLS).flatMap(([chain, urls]) => { + return urls.map(async (url) => [ + chain, + (await request(url, query)).reserves, + ]); + }) + ); + + data = data.map(([chain, reserves]) => [ + chain, + reserves.filter((p) => !p.isFrozen), + ]); + + const totalSupply = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'totalSupply'), + calls: reserves.map((reserve) => ({ + target: reserve.aToken.id, + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingBalances = await Promise.all( + data.map(async ([chain, reserves]) => + ( + await sdk.api.abi.multiCall({ + chain: chain, + abi: aTokenAbi.find(({ name }) => name === 'balanceOf'), + calls: reserves.map((reserve, i) => ({ + target: reserve.aToken.underlyingAssetAddress, + params: [reserve.aToken.id], + })), + }) + ).output.map(({ output }) => output) + ) + ); + + const underlyingTokens = data.map(([chain, reserves]) => + reserves.map((pool) => `${chain}:${pool.aToken.underlyingAssetAddress}`) + ); + + const rewardTokens = data.map(([chain, reserves]) => + reserves.map((pool) => + pool.aToken.rewards.map((rew) => `${chain}:${rew.rewardToken}`) + ) + ); + + const allTokens = underlyingTokens.flat().concat(rewardTokens.flat(Infinity)); + const pricesByAddress = {}; + const pricesBySymbol = {}; + + for (let i = 0; i < allTokens.length; i += 50) { + const chunk = allTokens.slice(i, i + 50); + const { + pricesByAddress: chunkPricesByAddress, + pricesBySymbol: chunkPricesBySymbol, + } = await getPrices(chunk); + Object.assign(pricesByAddress, chunkPricesByAddress); + Object.assign(pricesBySymbol, chunkPricesBySymbol); + } + + const pools = data.map(([chain, markets], i) => { + const chainPools = markets.map((pool, idx) => { + const supply = totalSupply[i][idx]; + const currentSupply = underlyingBalances[i][idx]; + const totalSupplyUsd = + (supply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const tvlUsd = + (currentSupply / 10 ** pool.aToken.underlyingAssetDecimals) * + (pricesByAddress[pool.aToken.underlyingAssetAddress] || + pricesBySymbol[pool.symbol]); + const { rewards } = pool.aToken; + + const rewardPerYear = rewards.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol] || + 0), + 0 + ); + + const { rewards: rewardsBorrow } = pool.vToken; + const rewardPerYearBorrow = rewardsBorrow.reduce( + (acc, rew) => + acc + + (rew.emissionsPerSecond / 10 ** rew.rewardTokenDecimals) * + SECONDS_PER_YEAR * + (pricesByAddress[rew.rewardToken] || + pricesBySymbol[rew.rewardTokenSymbol] || + 0), + 0 + ); + let totalBorrowUsd = totalSupplyUsd - tvlUsd; + totalBorrowUsd = totalBorrowUsd < 0 ? 0 : totalBorrowUsd; + + const supplyRewardEnd = pool.aToken.rewards[0]?.distributionEnd; + const borrowRewardEnd = pool.vToken.rewards[0]?.distributionEnd; + + return { + pool: `${pool.aToken.id}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'zerolend', + symbol: pool.symbol, + tvlUsd, + apyBase: (pool.liquidityRate / 10 ** 27) * 100, + apyReward: + supplyRewardEnd * 1000 > new Date() + ? (rewardPerYear / totalSupplyUsd) * 100 + : null, + rewardTokens: + supplyRewardEnd * 1000 > new Date() + ? rewards.map((rew) => rew.rewardToken) + : null, + underlyingTokens: [pool.aToken.underlyingAssetAddress], + totalSupplyUsd, + totalBorrowUsd, + apyBaseBorrow: Number(pool.variableBorrowRate) / 1e25, + apyRewardBorrow: + borrowRewardEnd * 1000 > new Date() + ? (rewardPerYearBorrow / totalBorrowUsd) * 100 + : null, + ltv: Number(pool.baseLTVasCollateral) / 10000, + url: `https://app.zerolend.xyz/reserve-overview/?underlyingAsset=${ + pool.aToken.underlyingAssetAddress + }&marketName=${ + chain === 'ethereum' + ? mainnnet_pools[pool.pool.pool] + : chainUrlParam[chain][0] + }&utm_source=defillama&utm_medium=listing&utm_campaign=external`, + borrowable: pool.borrowingEnabled, + }; + }); + + return chainPools; + }); + + return pools.flat().filter((p) => !!p.tvlUsd); +}; + +module.exports = { timetravel: false, apy }; diff --git a/src/adaptors/zeroliquid/index.js b/src/adaptors/zeroliquid/index.js new file mode 100644 index 0000000000..603a04377c --- /dev/null +++ b/src/adaptors/zeroliquid/index.js @@ -0,0 +1,84 @@ +const sdk = require('@defillama/sdk'); +const utils = require('../utils'); +const { ethers } = require('ethers'); +const fetch = require('node-fetch'); + +const liquidity_endpoint = sdk.graph.modifyEndpoint('BgVpYLQVGwb2RRPcW66aLBtmv48w9NwGxhypBMRNDi34'); +const pricing_endpoint = sdk.graph.modifyEndpoint('39DkzkpLtF3xJTWgpZwnSKPqqnHbErYhHTVh7RCZ6SMN'); +const zETH = '0x776280f68ad33c4d49e6846507b7dbaf7811c89f'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; + +const query_liquidity = `{ + zeroLiquids { + amountETH + amountZETH + amountETHPOL + amountZETHPOL + currentMiningReward + } + }`; + +const query_price = `{ + zethPrice : token(id: "${zETH}") { + drivedUSD + name + } + wethPrice : token(id: "${WETH}") { + drivedUSD + name + } +}`; + +const poolsFunction = async () => { + const data_liquidity = await fetch(liquidity_endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify({ query: query_liquidity }), + }) + .then((r) => r.json()) + .then((data) => { + return data.data.zeroLiquids[0]; + }); + + const data_pricing = await fetch(pricing_endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify({ query: query_price }), + }) + .then((r) => r.json()) + .then((data) => { + return data.data; + }); + + console.log(data_pricing, 'data_lllll'); + + const zethPool = { + pool: '0xb2C57D651dB0FcCc96cABda11191DF25E05B88b6', + chain: utils.formatChain('Ethereum'), + project: 'zeroliquid', + symbol: utils.formatSymbol('zETH-WETH'), + tvlUsd: + (data_pricing.zethPrice.drivedUSD * data_liquidity.amountZETH) / 1e18 + + (data_pricing.wethPrice.drivedUSD * data_liquidity.amountETH) / 1e18, + apy: + ((data_liquidity.currentMiningReward * 12) / + (data_liquidity.amountETH - + data_liquidity.amountETHPOL + + (data_liquidity.amountZETH - data_liquidity.amountZETHPOL))) * + 100, + }; + + return [zethPool]; // Anchor only has a single pool with APY +}; + +module.exports = { + timetravel: false, + apy: poolsFunction, + url: 'https://app.zeroliquid.xyz/earn', +}; diff --git a/src/adaptors/zest-protocol/abis.js b/src/adaptors/zest-protocol/abis.js new file mode 100644 index 0000000000..86c3a83882 --- /dev/null +++ b/src/adaptors/zest-protocol/abis.js @@ -0,0 +1,1801 @@ +module.exports = { + masterChefABI: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_controller', + type: 'address', + }, + ], + name: 'EmissionControllerSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Harvest', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + ], + name: 'LogPoolAddition', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'rewardPerSecond', + type: 'uint256', + }, + ], + name: 'LogRewardPerSecond', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IRewarder', + name: 'rewarder', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'overwrite', + type: 'bool', + }, + ], + name: 'LogSetPool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + ], + name: 'LogUpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'pid', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { + internalType: 'contract IERC20', + name: '_lpToken', + type: 'address', + }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: '_update', type: 'bool' }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emissionController', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'harvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'harvestAllRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'lpToken', + outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingReward', + outputs: [{ internalType: 'uint256', name: 'pending', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + { internalType: 'uint256', name: 'lastRewardTime', type: 'uint256' }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: 'pools', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'rewardMinter', + outputs: [ + { internalType: 'contract IZestStaking', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardPerSecond', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewarder', + outputs: [ + { internalType: 'contract IRewarder', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IRewarder', + name: '_rewarder', + type: 'address', + }, + { internalType: 'bool', name: '_overwrite', type: 'bool' }, + { internalType: 'bool', name: '_update', type: 'bool' }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_controller', type: 'address' }, + ], + name: 'setEmissionController', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardMinter', type: 'address' }, + ], + name: 'setRewardMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_rewardPerSecond', + type: 'uint256', + }, + { internalType: 'bool', name: '_update', type: 'bool' }, + ], + name: 'setRewardPerSecond', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'updatePool', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'accRewardPerShare', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'lastRewardTime', + type: 'uint256', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + ], + internalType: 'struct ZestChef.PoolInfo', + name: 'pool', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: 'pids', type: 'uint256[]' }], + name: 'updatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'int256', name: 'rewardDebt', type: 'int256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'withdrawAndHarvest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + lpTokenABI: [ + { + inputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Burn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1', + type: 'uint256', + }, + ], + name: 'Mint', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1In', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount0Out', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount1Out', + type: 'uint256', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint112', + name: 'reserve0', + type: 'uint112', + }, + { + indexed: false, + internalType: 'uint112', + name: 'reserve1', + type: 'uint112', + }, + ], + name: 'Sync', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + constant: true, + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'MINIMUM_LIQUIDITY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'PERMIT_TYPEHASH', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'allowance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'balanceOf', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'burn', + outputs: [ + { internalType: 'uint256', name: 'amount0', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'factory', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { internalType: 'uint112', name: '_reserve0', type: 'uint112' }, + { internalType: 'uint112', name: '_reserve1', type: 'uint112' }, + { internalType: 'uint32', name: '_blockTimestampLast', type: 'uint32' }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: '_token0', type: 'address' }, + { internalType: 'address', name: '_token1', type: 'address' }, + ], + name: 'initialize', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'kLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'mint', + outputs: [ + { internalType: 'uint256', name: 'liquidity', type: 'uint256' }, + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'name', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'nonces', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'owner', type: 'address' }, + { internalType: 'address', name: 'spender', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price0CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'price1CumulativeLast', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'skim', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'uint256', name: 'amount0Out', type: 'uint256' }, + { internalType: 'uint256', name: 'amount1Out', type: 'uint256' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'swap', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'symbol', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [], + name: 'sync', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token0', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'token1', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + payable: false, + stateMutability: 'view', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + { + constant: false, + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'uint256', name: 'value', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + payable: false, + stateMutability: 'nonpayable', + type: 'function', + }, + ], + stakeABI: [ + { + inputs: [ + { internalType: 'address', name: '_stakingToken', type: 'address' }, + { + internalType: 'address', + name: '_stakingTokenReserve', + type: 'address', + }, + { internalType: 'address', name: '_veZest', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + ], + name: 'MinterAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'minter', + type: 'address', + }, + ], + name: 'MinterRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Recovered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'rewardAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'distributor', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'approved', + type: 'bool', + }, + ], + name: 'RewardDistributorApproved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'rewardsToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'reward', + type: 'uint256', + }, + ], + name: 'RewardPaid', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'rewardTokenAddress', + type: 'address', + }, + ], + name: 'RewardTokenAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { indexed: false, internalType: 'bool', name: 'lock', type: 'bool' }, + ], + name: 'Staked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdrawn', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'user', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'unlockTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'veZestMinted', + type: 'event', + }, + { + inputs: [], + name: 'PRECISION', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'ZSP', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_newMinter', type: 'address' }, + ], + name: 'addMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'address', name: '_distributor', type: 'address' }, + ], + name: 'addReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'airdrop', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'address', name: '_distributor', type: 'address' }, + { internalType: 'bool', name: '_approved', type: 'bool' }, + ], + name: 'approveRewardDistributor', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'claimableRewards', + outputs: [ + { + components: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + internalType: 'struct ZestStaking.RewardData[]', + name: '_rewards', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'index', type: 'uint256' }], + name: 'currentMinters', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardToken', type: 'address' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'currentRewardDistributors', + outputs: [ + { internalType: 'address', name: '_distributor', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'earnedBalances', + outputs: [ + { internalType: 'uint256', name: 'total', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'unlockTime', type: 'uint256' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + internalType: 'struct ZestStaking.LockedBalance[]', + name: 'earningsData', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'emergencyWithdrawWithoutRewards', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'getLockedZestBalanceFromNFT', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getReward', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + ], + name: 'getRewardForDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + ], + name: 'lastTimeRewardApplicable', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lockDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'lockedBalances', + outputs: [ + { internalType: 'uint256', name: 'total', type: 'uint256' }, + { internalType: 'uint256', name: 'unlockable', type: 'uint256' }, + { internalType: 'uint256', name: 'locked', type: 'uint256' }, + { + components: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'unlockTime', type: 'uint256' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + internalType: 'struct ZestStaking.LockedBalance[]', + name: 'lockData', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'lockedSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'maximumLockDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'user', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'minters', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'mintersArray', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'users', type: 'address[]' }, + { internalType: 'uint256', name: '_amountPerUser', type: 'uint256' }, + { internalType: 'uint256', name: '_duration', type: 'uint256' }, + ], + name: 'notifyAirdrop', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + { internalType: 'uint256', name: 'reward', type: 'uint256' }, + ], + name: 'notifyRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_from', type: 'address' }, + { internalType: 'address', name: '_to', type: 'address' }, + { internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'notifyTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenAddress', type: 'address' }, + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + name: 'recoverERC20', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_minter', type: 'address' }], + name: 'removeMinter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'rewardData', + outputs: [ + { internalType: 'uint256', name: 'periodFinish', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardRate', type: 'uint256' }, + { internalType: 'uint256', name: 'lastUpdateTime', type: 'uint256' }, + { + internalType: 'uint256', + name: 'rewardPerTokenStored', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewardDistributors', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'rewardDistributorsArray', + outputs: [ + { internalType: 'address', name: 'rewardToken', type: 'address' }, + { internalType: 'address', name: 'distributor', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_rewardsToken', type: 'address' }, + ], + name: 'rewardPerToken', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'rewardTokens', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'rewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'rewardsDuration', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_contract', type: 'address' }], + name: 'setAirdrop', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'bool', name: 'lock', type: 'bool' }, + { + internalType: 'uint256', + name: 'userDefinedLockDuration', + type: 'uint256', + }, + ], + name: 'stake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'stakingToken', + outputs: [ + { internalType: 'contract IYToken', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'stakingTokenReserve', + outputs: [ + { + internalType: 'contract IYTokenReserve', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'totalBalance', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'unlockedBalance', + outputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userRewardPerTokenPaid', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 've', + outputs: [{ internalType: 'contract IVe', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'veZest', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawExpiredLocks', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'user', type: 'address' }], + name: 'withdrawableBalance', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'penaltyAmount', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, + ], + oracleAbi: [ + { + inputs: [ + { internalType: 'address', name: '_xToken', type: 'address' }, + { internalType: 'address', name: '_yToken', type: 'address' }, + { internalType: 'address', name: '_oracleXToken', type: 'address' }, + { internalType: 'address', name: '_oracleYToken', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + inputs: [], + name: 'getXTokenPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getXTokenTWAP', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getYTokenPrice', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getYTokenTWAP', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracleXToken', + outputs: [ + { internalType: 'contract IPairOracle', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'oracleYToken', + outputs: [ + { internalType: 'contract IPairOracle', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'xToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'yToken', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], +}; diff --git a/src/adaptors/zest-protocol/index.js b/src/adaptors/zest-protocol/index.js new file mode 100644 index 0000000000..078dc0a96b --- /dev/null +++ b/src/adaptors/zest-protocol/index.js @@ -0,0 +1,258 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); + +const { masterChefABI, lpTokenABI, stakeABI, oracleAbi } = require('./abis'); +const utils = require('../utils'); +const { fetchURL } = require('../../helper/utils'); + +const RPC_URL = 'https://rpc.ftm.tools/'; +const API_URL = 'https://api.fura.org/subgraphs/name/spookyswap'; + +const MASTERCHEF_ADDRESS = '0xFdAa392FCF8946e8e658B9f36ffbE6659cB40edf'; +const STAKING_ADDRESS = '0x1b6deD5c603d66800B0DDf566Ec316a344C7BcaD'; +const ZSP_ADDRESS = '0x2C26617034C840C9412CD67aE0Fc68A6755D00BF'; +const WFTM_ADDRESS = '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83'; +const ORACLE_ADDRESS = '0xb9Eebcd999130Ec2037DcAC98bd36185bB22D797'; +const WETH_ADDRESS = '0x74b23882a30290451A17c44f4F05243b6b58C76d'; + +const BLOCKS_PER_DAY = 86400; + +const web3 = new Web3(RPC_URL); + +const pairQuery = gql` + query pairQuery($id: ID!) { + pair(id: $id) { + name + id + token0 { + decimals + } + token1 { + decimals + } + } + } +`; + +const getPairInfo = (pair) => { + const pairInfo = request(API_URL, pairQuery, { id: pair.toLowerCase() }); + + return pairInfo; +}; + +const calculateApy = ( + poolInfo, + totalAllocPoint, + zspPerBlock, + zspPrice, + reserveUSD +) => { + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + + return ( + ((poolWeight * BLOCKS_PER_DAY * zspPerBlock * zspPrice) / reserveUSD) * + 100 * + 365 + ); +}; + +const calculateReservesUSD = ( + pairName, + reserves, + reservesRatio, + ftmPrice, + zspPrice, + ethPrice, + token0decimals, + token1decimals +) => { + const [token0, token1] = pairName.split('-'); + const reserve0 = new BigNumber(reserves._reserve0) + .times(reservesRatio) + .times(10 ** (18 - token0decimals)); + const reserve1 = new BigNumber(reserves._reserve1) + .times(reservesRatio) + .times(10 ** (18 - token1decimals)); + + if (token0.includes('USDC')) return reserve0.times(2); + if (token0.includes('FTM')) return reserve0.times(ftmPrice).times(2); + if (token0.includes('ZSP')) return reserve0.times(zspPrice).times(2); + if (token0.includes('ETH')) return reserve0.times(ethPrice).times(2); + if (token1.includes('USDC')) return reserve1.times(2); + if (token1.includes('FTM')) return reserve1.times(ftmPrice).times(2); + if (token1.includes('ZSP')) return reserve1.times(zspPrice).times(2); + if (token1.includes('ETH')) return reserve1.times(ethPrice).times(2); +}; + +const getBaseTokensPrice = async () => { + const prices = await utils.getData( + 'https://api.coingecko.com/api/v3/simple/price?ids=zest-synthetic-protocol%2Cfantom%2Cethereum&vs_currencies=usd' + ); + + const zspPrice = prices['zest-synthetic-protocol'].usd; + const ethPrice = prices.ethereum.usd; + const ftmPrice = prices.fantom.usd; + + return { zspPrice, ethPrice, ftmPrice }; +}; + +const main = async () => { + const { ethPrice, ftmPrice } = await getBaseTokensPrice(); + const masterChef = new web3.eth.Contract(masterChefABI, MASTERCHEF_ADDRESS); + const staking = new web3.eth.Contract(stakeABI, STAKING_ADDRESS); + //Farms + const poolsCount = await masterChef.methods.poolLength().call(); + const totalAllocPoint = await masterChef.methods.totalAllocPoint().call(); + const rewardRate = await masterChef.methods.rewardPerSecond().call(); + const normalizedRewardPerBlock = rewardRate / 1e18; + //ZSP Price from Oracle + const oracle = new web3.eth.Contract(oracleAbi, ORACLE_ADDRESS); + const zspFtmPrice = await oracle.methods.getYTokenPrice().call(); + const zspPrice = (zspFtmPrice / 1e18) * ftmPrice; + const zspPriceFtm = zspFtmPrice / 1e18; + //Staking + const rewardRateFtm = await staking.methods.rewardData(WFTM_ADDRESS).call(); + const normalisedRewardRateFtm = rewardRateFtm.rewardRate / 1e18; + const rewardRateZsp = await staking.methods.rewardData(ZSP_ADDRESS).call(); + const normalisedRewardRateZsp = rewardRateZsp.rewardRate / 1e18; + const rewardRateEth = await staking.methods.rewardData(WETH_ADDRESS).call(); + const normalisedRewardRateEth = rewardRateEth.rewardRate / 1e18; + const totalLocked = await staking.methods.lockedSupply().call(); + const normalisedTotalLocked = totalLocked / 1e18; + const totalSupply = await staking.methods.totalSupply().call(); + const normalisedTotalSupply = totalSupply / 1e18; + const stakedSupply = normalisedTotalSupply - normalisedTotalLocked; + + const stakeRewardPerYear = normalisedRewardRateFtm * BLOCKS_PER_DAY * 365; + const stakeRewardsEthPerYear = normalisedRewardRateEth * BLOCKS_PER_DAY * 365; + const stakeRewardsFtm = stakeRewardPerYear / normalisedTotalSupply; + const stakeRewardsEth = stakeRewardsEthPerYear / normalisedTotalSupply; + + const stakeAPR = ((stakeRewardsFtm + stakeRewardsEth) / zspPriceFtm) * 100; + const stakeTVL = stakedSupply * zspPrice; + + const lockRewardsPerYear = normalisedRewardRateZsp * BLOCKS_PER_DAY * 365; + const lockRewards = lockRewardsPerYear / normalisedTotalLocked; + const lockAPR = lockRewards * 100 + stakeAPR; + const lockTVL = normalisedTotalLocked * zspPrice; + + const chain = 'fantom'; + + const [poolsRes, lpTokensRes] = await Promise.all( + ['poolInfo', 'lpToken'].map((method) => + sdk.api.abi.multiCall({ + abi: masterChefABI.filter(({ name }) => name === method)[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: MASTERCHEF_ADDRESS, + params: i, + })), + chain, + }) + ) + ); + const poolsInfo = poolsRes.output.map((res) => res.output); + const lpTokens = lpTokensRes.output.map((res) => res.output); + + const [ + reservesRes, + supplyRes, + masterChefBalancesRes, + underlyingToken0, + underlyingToken1, + ] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf', 'token0', 'token1'].map( + (method) => + sdk.api.abi.multiCall({ + abi: lpTokenABI.filter(({ name }) => name === method)[0], + calls: lpTokens.map((address) => ({ + target: address, + params: method === 'balanceOf' ? [MASTERCHEF_ADDRESS] : null, + })), + chain, + }) + ) + ); + const underlyingToken0Data = underlyingToken0.output.map((res) => res.output); + const underlyingToken1Data = underlyingToken1.output.map((res) => res.output); + const reservesData = reservesRes.output.map((res) => res.output); + const supplyData = supplyRes.output.map((res) => res.output); + const masterChefBalData = masterChefBalancesRes.output.map( + (res) => res.output + ); + + let pools = await Promise.all( + poolsInfo.map((pool, i) => + getPairInfo(lpTokens[i]).then(({ pair: pairInfo }) => { + const poolInfo = poolsInfo[i]; + const reserves = reservesData[i]; + const underlying0 = underlyingToken0Data[i]; + const underlying1 = underlyingToken1Data[i]; + + const supply = supplyData[i]; + const masterChefBalance = masterChefBalData[i]; + + const reserveUSD = calculateReservesUSD( + pairInfo.name, + reserves, + masterChefBalance / supply, + ftmPrice, + zspPrice, + ethPrice, + pairInfo.token0.decimals, + pairInfo.token1.decimals + ) + .div(1e18) + .toString(); + const pool = { + pool: `${pairInfo.id}-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'zest-protocol', + symbol: pairInfo.name.replace(/(WFTM)+/g, 'FTM'), + tvlUsd: Number(reserveUSD), + apyReward: calculateApy( + poolInfo, + totalAllocPoint, + normalizedRewardPerBlock, + zspPrice, + reserveUSD + ), + rewardTokens: ['0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83'], + underlyingTokens: [underlying0, underlying1], + }; + return pool; + }) + ) + ); + + const stakeZsp = { + pool: `${ZSP_ADDRESS}-staking-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'zest-protocol', + symbol: 'ZSP Staked', + tvlUsd: Number(stakeTVL), + apyReward: Number(stakeAPR), + rewardTokens: [WFTM_ADDRESS], + }; + + const lockZsp = { + pool: `${ZSP_ADDRESS}-locking-${chain}`.toLowerCase(), + chain: utils.formatChain(chain), + project: 'zest-protocol', + symbol: 'ZSP Locked', + tvlUsd: Number(lockTVL), + apyReward: Number(lockAPR), + rewardTokens: [WFTM_ADDRESS, ZSP_ADDRESS], + }; + + pools = [...pools, stakeZsp, lockZsp]; + + return pools.filter(Boolean); +}; + +module.exports = { + timetravel: false, + apy: main, + url: 'https://zestprotocol.fi/dashboard', +}; diff --git a/src/adaptors/zest/index.js b/src/adaptors/zest/index.js new file mode 100644 index 0000000000..6cfbf0e812 --- /dev/null +++ b/src/adaptors/zest/index.js @@ -0,0 +1,161 @@ +const { callReadOnlyFunction, contractPrincipalCV } = require("@stacks/transactions"); +const { StacksMainnet } = require("@stacks/network"); + +const AssetConfig = { + stSTX: { + assetAddress: 'SP4SZE494VC2YC5JYG7AYFQ44F5Q4PYV7DVMDPBG', + contractName: 'ststx-token', + oracleContractName: 'ststx-oracle-v1-4', + decimals: 6, + }, + aeUSDC: { + assetAddress: 'SP3Y2ZSH8P7D50B0VBTSX11S7XSG24M1VB9YFQA4K', + contractName: 'token-aeusdc', + oracleContractName: 'aeusdc-oracle-v1-0', + decimals: 6, + }, + STX: { + assetAddress: 'SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N', + contractName: 'wstx', + oracleContractName: 'stx-oracle-v1-3', + decimals: 6, + }, + DIKO: { + assetAddress: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR', + contractName: 'arkadiko-token', + oracleContractName: 'diko-oracle-v1-1', + decimals: 6, + }, +} + +async function getAddressBalances() { + try { + const response = await fetch( + "https://api.hiro.so/extended/v1/address/SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N.pool-vault/balances", + { + method: "GET", + headers: { + 'Content-Type': 'application/json' + } + } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + + // Process the balances + const processedBalances = { + STX: Number(data.stx.balance) / Math.pow(10, 6) // STX has 6 decimals + }; + + // Process fungible tokens + Object.entries(data.fungible_tokens).forEach(([fullTokenId, tokenData]) => { + const [addressAndContract] = fullTokenId.split('::'); + const [address, contractName] = addressAndContract.split('.'); + + const matchingAsset = Object.entries(AssetConfig).find(([_, config]) => + config.assetAddress === address && config.contractName === contractName + ); + + if (matchingAsset) { + const [assetKey, config] = matchingAsset; + processedBalances[assetKey] = Number(tokenData.balance) / Math.pow(10, config.decimals); + } + }); + + return processedBalances; + } catch (error) { + console.error('Error fetching address balances:', error); + } +} + +async function getZestPools() { + try { + const contractAddress = 'SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N'; + const network = new StacksMainnet(); + + const chain = 'Stacks'; + + const pools = []; + + const balances = await getAddressBalances(); + // Reserve data + for (const [assetKey, asset] of Object.entries(AssetConfig)) { + const {assetAddress, contractName, oracleContractName} = asset; + + let supplyApy = 0.0; + let tvlUsd = 0.0; + let price = 0.0; + + // Fetch yields + try { + const reserveData = await callReadOnlyFunction({ + contractAddress, + contractName: 'pool-read-v1-3-2', + functionName: 'get-reserve-data', + network, + functionArgs: [ + contractPrincipalCV(assetAddress, contractName), + ], + senderAddress: contractAddress, + }); + + if (reserveData.data) { + supplyApy = Number(reserveData.data['current-liquidity-rate'].value) / 1000000; + borrowApy = Number(reserveData.data['current-variable-borrow-rate'].value) / 1000000; + ltv = Number(reserveData.data['base-ltv-as-collateral'].value) / 100000000; + } + + } catch (error) { + console.log(`Error fetching yields: ${error}`); + } + + try { + const result = await callReadOnlyFunction({ + contractAddress, + contractName: oracleContractName, + functionName: 'get-price', + network, + functionArgs: [], + senderAddress: contractAddress, + }); + + // Get price and calculate TVL using the balance + price = Number(result.value) / 100000000; + const assetBalance = balances[assetKey] || 0; + tvlUsd = price * assetBalance; + + } catch (error) { + console.log(`Error fetching TVL: ${error}`); + } + + pools.push({ + pool: `${assetAddress}.${contractName}-${chain}`.toLowerCase(), + chain: chain, + project: 'zest', + symbol: assetKey, + tvlUsd: tvlUsd, + apyBase: supplyApy, + underlyingTokens: [`${assetAddress}.${contractName}`], + }); + } + return pools; + } catch (e) { + if (e instanceof Error) { + if (!e.message.includes('UnwrapFailure')) { + console.log(e); + } + } + return []; + } + +} + +module.exports = { + timetravel: false, + apy: getZestPools, + url: 'https://app.zestprotocol.com/assets', +}; \ No newline at end of file diff --git a/src/adaptors/zipswap/index.js b/src/adaptors/zipswap/index.js new file mode 100644 index 0000000000..79752159f0 --- /dev/null +++ b/src/adaptors/zipswap/index.js @@ -0,0 +1,66 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const utils = require('../utils'); + +const subgraphURL = sdk.graph.modifyEndpoint('5tAUjmnM9iE4aADZwKhk3fobY8fMFbb1VMsrSKvo4kFr'); + +const getCurrentDate = gql` + { + uniswapDayDatas(orderBy: date, orderDirection: desc, first: 1) { + date + } + } +`; +const getDate = async () => { + let data = await request(subgraphURL, getCurrentDate); + let date = data.uniswapDayDatas[0].date; + return date + ''; +}; + +var query = gql` +{ + pairDayDatas(first: 10, + orderDirection: desc, + orderBy: dailyVolumeUSD,where:{ + date: , + }) + { + id + pairAddress + reserveUSD + dailyVolumeUSD + token0 { + symbol + } + token1 { + symbol + } + } +} +`; + +const acquireData = async () => { + let obj = []; + let date = await getDate(); + query = query.replace('', date); + let results = await request(subgraphURL, query); + results.pairDayDatas.forEach((pairs) => { + newObj = { + pool: pairs.pairAddress, + chain: utils.formatChain('optimism'), + project: 'zipswap', + symbol: `${pairs.token0['symbol']}-${pairs.token1['symbol']}`, + tvlUsd: parseFloat(pairs.reserveUSD), + apyBase: + parseFloat(pairs.dailyVolumeUSD / pairs.reserveUSD) * 365 * 0.003 * 100, + }; + obj.push(newObj); + }); + return obj; +}; + +module.exports = { + timetravel: false, + apy: acquireData, + url: 'https://zipswap.fi/#/farm', +}; diff --git a/src/adaptors/zircon-gamma/constants.js b/src/adaptors/zircon-gamma/constants.js new file mode 100644 index 0000000000..ca4f6041a6 --- /dev/null +++ b/src/adaptors/zircon-gamma/constants.js @@ -0,0 +1,87 @@ +const sdk = require("@defillama/sdk"); +module.exports = Object.freeze({ + MASTER_CONTRACT_ADDRESS: "0x97b2aE105DAFb7DC8a73c93e5f56d3f095D0DCF3", + PT_FACT_CONTRACT_ADDRESS: "0x2D4ddeB8b183413e9D88A98Fa3Dd844e34D41c54", + CONTRACT_ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EmergencyWithdraw\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"poolLimitPerUser\",\"type\":\"uint256\"}],\"name\":\"NewPoolLimit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endBlock\",\"type\":\"uint256\"}],\"name\":\"NewStartAndEndBlocks\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"RewardsStop\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenRecovery\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"PRECISION_FACTOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PSIONIC_FACTORY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accTokenPerShare\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bonusEndBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"closingFarm\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emergencyWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasUserLimit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Metadata\",\"name\":\"_stakedToken\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Metadata\",\"name\":\"_psionicVault\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_bonusEndBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_poolLimitPerUser\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberBlocksForUserLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRewardBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"numberBlocksForUserLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"pendingReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolLimitPerUser\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"psionicVault\",\"outputs\":[{\"internalType\":\"contract IERC20Metadata\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"recoverToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"routerDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakedToken\",\"outputs\":[{\"internalType\":\"contract IERC20Metadata\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stopReward\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_userLimit\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"_poolLimitPerUser\",\"type\":\"uint256\"}],\"name\":\"updatePoolLimitPerUser\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_startBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_bonusEndBlock\",\"type\":\"uint256\"}],\"name\":\"updateStartAndEndBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"userInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rewardDebt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"userLimit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]\n", + VAULT_CONTRACT_ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"PSIONIC_FACTORY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"add\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"shouldMint\",\"type\":\"bool\"}],\"name\":\"adjust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_liquidity\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"farm\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_rewardTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"_initialSupply\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_farm\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"modifyRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"remove\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewardTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]\n", + PAIR_CONTRACT_ABI: "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0In\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1In\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0Out\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1Out\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"Swap\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint112\",\"name\":\"reserve0\",\"type\":\"uint112\"},{\"indexed\":false,\"internalType\":\"uint112\",\"name\":\"reserve1\",\"type\":\"uint112\"}],\"name\":\"Sync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"MINIMUM_LIQUIDITY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isReserve0\",\"type\":\"bool\"}],\"name\":\"burnOneSide\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_revAddress\",\"type\":\"address\"}],\"name\":\"changeEnergyRevAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"energyRevenueAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getReserves\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"_reserve0\",\"type\":\"uint112\"},{\"internalType\":\"uint112\",\"name\":\"_reserve1\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"_blockTimestampLast\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token1\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_energy\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"kLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isReserve0\",\"type\":\"bool\"}],\"name\":\"mintOneSide\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"price0CumulativeLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"price1CumulativeLast\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"publicMintFee\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0Out\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1Out\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"swap\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"sync\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"token0\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"token1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"tryLock\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]\n", + PT_CONTRACT_ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pylonFactory\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pylon\",\"type\":\"address\"}],\"name\":\"changePylonAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_pair\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_pylon\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isAnchor\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isAnchor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pair\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pylon\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pylonFactory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]\n", + PYLON_CONTRACT_ABI: "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isAnchor\",\"type\":\"bool\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn1\",\"type\":\"uint256\"}],\"name\":\"BurnAsync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn1\",\"type\":\"uint256\"}],\"name\":\"MintAsync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"aIn0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isAnchor\",\"type\":\"bool\"}],\"name\":\"MintSync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vab\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vfb\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_gamma\",\"type\":\"uint256\"}],\"name\":\"PylonSync\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_reserve0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_reserve1\",\"type\":\"uint256\"}],\"name\":\"PylonUpdate\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[],\"name\":\"EMABlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"anchorKFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isAnchor\",\"type\":\"bool\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_isAnchor\",\"type\":\"bool\"}],\"name\":\"burnAsync\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_energyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_energyRevAddress\",\"type\":\"address\"}],\"name\":\"changeEnergyAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"formulaSwitch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gammaEMA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"gammaMulDecimals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getSyncReserves\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"_reserve0\",\"type\":\"uint112\"},{\"internalType\":\"uint112\",\"name\":\"_reserve1\",\"type\":\"uint112\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_gamma\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_vab\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_anchorKFactor\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_formulaSwitch\",\"type\":\"bool\"}],\"name\":\"initMigratedPylon\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"initPylon\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"floatLiquidity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"anchorLiquidity\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_floatPoolTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anchorPoolTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_floatToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_anchorToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_pairAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_pairFactoryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_energy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_energyRev\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"initialized\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isFloatReserve0\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"lastRootKTranslated\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPylon\",\"type\":\"address\"}],\"name\":\"migrateLiquidity\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"shouldMintAnchor\",\"type\":\"bool\"}],\"name\":\"mintAsync\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isAnchor\",\"type\":\"bool\"}],\"name\":\"mintPoolTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"liquidity\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"muMulDecimals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"strikeBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"thisBlockEMA\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"virtualAnchorBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]\n", + PT_FACTORY_ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"migrator_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeToSetter_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"oldPylon\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenB\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newPylon\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pylonFactory\",\"type\":\"address\"}],\"name\":\"changePylonAddress\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pylonAddress\",\"type\":\"address\"}],\"name\":\"createPTAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"poolToken\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"feeToSetter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pylonFactory\",\"type\":\"address\"}],\"name\":\"getCreationBytecode\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_pylonFactory\",\"type\":\"address\"}],\"name\":\"getInitHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"getPoolToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"migrator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_feeToSetter\",\"type\":\"address\"}],\"name\":\"setFeeToSetter\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_migrator\",\"type\":\"address\"}],\"name\":\"setMigrator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]\n", + ERC20_ABI: [ + // Read-Only Functions + "function balanceOf(address owner) view returns (uint256)", + "function decimals() view returns (uint8)", + "function symbol() view returns (string)", + + // Authenticated Functions + "function transfer(address to, uint amount) returns (bool)", + + // Events + "event Transfer(address indexed from, address indexed to, uint amount)" + ], + OWNER_REPO: "Zircon-Finance", + REPO: "zircon-interface", + COMMIT_MESSAGE: "Updating LP APR", + PATH_REPO: "src/constants/lpAprs.json", + NETWORK:{ + "1285":{ + chainId: 1285, + name: 'moonriver' + }, + "1287":{ + chainId: 1287, + name: 'moonbase' + }, + "56":{ + chainId:56, + name:"BSC" + }}, + PROVIDER_URL: { + "1285":"https://moonriver.public.blastapi.io", + "1287":'https://rpc.api.moonbase.moonbeam.network', + "56":"https://rpc.ankr.com/bsc" + }, + BRANCH: 'dev', + SUBGRAPH_URI: { + "1285": sdk.graph.modifyEndpoint('2uB6zSi8gN1kCmijML2Qm2ZCRcNq3n1qLnTXMo5Jm2tk'), + "1287": "https://api.thegraph.com/subgraphs/name/vittoridavide/psionic-farm-moonbase", + "56": sdk.graph.modifyEndpoint('GEoMDCQEb8ShDFjn8UvrVdfABEfKzWCuurdpbPi6Dyfx') + }, + GAMMA_SUBGRAPH_URI: { + "1285": sdk.graph.modifyEndpoint('8weH8Sp54JoeKtmQ9mYMhBzyXd1FdFoKvzgQmugRffwi'), + "56": sdk.graph.modifyEndpoint('9Ep2SL39VA42EAuPVvb7hAp683bUHwkmm4J4WPELKuah'), + "1287": "https://api.thegraph.com/subgraphs/name/reshyresh/zircon-finance2" + }, + ZRG_ADDRESS: { + "1285": "0x4545E94974AdACb82FC56BCf136B07943e152055", + "1287": "0x9AF666c9058a964759C902947DB701afAd956F8f", + "56": "0x808A3F2639a5CD54D64eD768192369BCd729100e" + }, + WMOVR_ADDRESS: { + "1285": "0x98878B06940aE243284CA214f92Bb71a2b032B8A", + "1287": "0xD909178CC99d318e4D46e7E66a972955859670E1", + "56": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" + }, + NTV_ZRG_PAIR_ADDRESS: { + "1285": "0x89BB1bd89c764e1C2d4AA6469062590732B26323", + "1287": "0x0171dC396961896cf86E091795a9eE155f448828", + "56": "0xE1FCCc2E790AcBfC9a88E23765a8E5f63Ab94455" + + }, + NTV_USDC_PAIR_ADDRESS: { + "1285": "0xcc2a7ceF44CAa59847699104629E034eA7D89F6a", + "1287": "0x486AD090866ca2C4827E3cfB07EB67F0B839c62B", + "56": "0x59f8C4a5c154AC6370c9d607051921250566aFE5" + }, + DAILY_BLOCK: { + "1285": 6500, + "1287": 5760, + "56": 28800 + }, + CHAIN_NAME: { + 1285: "moonriver", + 1287: "moonbase", + 56: "bsc" + } +}) diff --git a/src/adaptors/zircon-gamma/index.js b/src/adaptors/zircon-gamma/index.js new file mode 100644 index 0000000000..fd8d37b5d9 --- /dev/null +++ b/src/adaptors/zircon-gamma/index.js @@ -0,0 +1,444 @@ +const { Web3 } = require('web3'); +let _ = require('lodash'); +const { + CONTRACT_ABI, + PROVIDER_URL, + SUBGRAPH_URI, + VAULT_CONTRACT_ABI, + ZRG_ADDRESS, + WMOVR_ADDRESS, + PAIR_CONTRACT_ABI, + MOVR_ZRG_PAIR_ADDRESS, + MOVR_USDC_PAIR_ADDRESS, + PT_CONTRACT_ABI, + PYLON_CONTRACT_ABI, + GAMMA_SUBGRAPH_URI, + NTV_ZRG_PAIR_ADDRESS, + NTV_USDC_PAIR_ADDRESS, + DAILY_BLOCK, + CHAIN_NAME, +} = require('./constants'); +const axios = require('axios'); +const { BigNumber } = require('bignumber.js'); +const utils = require('../utils'); + +let getPoolsSubgraph = async function (chainId, web3) { + let blockNumber = await web3.eth.getBlockNumber(); + + const QUERY = `{ + psionicFarms(where:{endBlock_gt: ${blockNumber}}) { + endBlock + id + startBlock + timestamp + stakeToken { + id + } + } + } + `; + let query = await axios.post( + SUBGRAPH_URI[chainId], + JSON.stringify({ query: QUERY, variables: null, operationName: undefined }) + ); + return query.data.data.psionicFarms; +}; + +const getTokenPrice = async (tokenAddress, chain = 'moonriver') => { + let key = `${chain}:${tokenAddress}`; + const data = await utils.getData( + `https://coins.llama.fi/prices/current/${key}` + ); + console.log(data); + return data.coins[key]; +}; + +let gettingDailyVolume = async function (pairAddress, chainId) { + let date = new Date(); + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - 1); + let unix = +date / 1000; + + let QUERY = `{ + pairDayDatas(where: {pairAddress: "${pairAddress.toString()}", date: ${unix}}) { + dailyVolumeUSD + } + }`; + let query = await axios.post( + GAMMA_SUBGRAPH_URI[chainId], + JSON.stringify({ query: QUERY, variables: null, operationName: undefined }) + ); + if (query.data.data.pairDayDatas.length > 0) { + return query.data.data.pairDayDatas[0].dailyVolumeUSD; + } +}; + +let calculatePrices = async function (chainId, web3) { + // Calculating ZRG Price and MOVR Price + const zrgNtvContract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + NTV_ZRG_PAIR_ADDRESS[chainId] + ); + const usdcMovrContract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + NTV_USDC_PAIR_ADDRESS[chainId] + ); + const zrgNtvReserves = await zrgNtvContract.methods.getReserves().call(); + let tk0 = await zrgNtvContract.methods.token0().call(); + let token0 = new web3.eth.Contract(JSON.parse(PAIR_CONTRACT_ABI), tk0); + let symbol0 = await token0.methods.symbol().call(); + let zrgNtvPrice; + if (symbol0 === 'ZRG') { + zrgNtvPrice = new BigNumber(zrgNtvReserves[1].toString()).dividedBy( + zrgNtvReserves[0].toString() + ); + } else { + zrgNtvPrice = new BigNumber(zrgNtvReserves[0].toString()).dividedBy( + zrgNtvReserves[1].toString() + ); + } + + let tk0U = await usdcMovrContract.methods.token0().call(); + let tk1 = await usdcMovrContract.methods.token1().call(); + let token0USDC = new web3.eth.Contract(JSON.parse(PAIR_CONTRACT_ABI), tk0U); + let token1USDC = new web3.eth.Contract(JSON.parse(PAIR_CONTRACT_ABI), tk1); + let symbol0USDC = await token0USDC.methods.symbol().call(); + let decimals0USDC = await token0USDC.methods.decimals().call(); + let decimals1USDC = await token1USDC.methods.decimals().call(); + let usdcMovrReserves = await usdcMovrContract.methods.getReserves().call(); + let ntvUsdPrice; + if (symbol0USDC.startsWith('USD')) { + ntvUsdPrice = new BigNumber(usdcMovrReserves[0].toString()) + .multipliedBy(new BigNumber('1e' + (decimals1USDC - decimals0USDC))) + .dividedBy(usdcMovrReserves[1].toString()); + } else { + ntvUsdPrice = new BigNumber(usdcMovrReserves[1].toString()) + .multipliedBy(new BigNumber('1e' + (decimals0USDC - decimals1USDC))) + .dividedBy(usdcMovrReserves[0].toString()); + } + // Hardcoded to 1e12 because USDC is 6 decimals and MOVR is 18 decimals + return { + zrg: zrgNtvPrice.multipliedBy(ntvUsdPrice), + movr: ntvUsdPrice, + ntv: ntvUsdPrice, + }; +}; + +let getPools = async function (chainId) { + // Getting Moonbase Provider + // Getting Farming Contract + // Getting Pools And Allocation Points + const web3 = new Web3(PROVIDER_URL[chainId]); + + const pools = await getPoolsSubgraph(chainId, web3); + + // Getting ZRG/MOVR ERC20 Contracts + const zrgContract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + ZRG_ADDRESS[chainId] + ); + const wmovrContract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + WMOVR_ADDRESS[chainId] + ); + + // Getting ZRG USD Price + const prices = await calculatePrices(chainId, web3); + + // Creating the result to convert in JSON + let result = []; + if (!_.isEmpty(pools)) { + for (const pool of pools) { + try { + // Pool Contract + const contract = new web3.eth.Contract( + JSON.parse(CONTRACT_ABI), + pool.id + ); + const stakedToken = pool.stakeToken.id; // Staked PT Address + + // Getting Vault Contract + const vaultAddress = await contract.methods.psionicVault().call(); + const vaultContract = new web3.eth.Contract( + JSON.parse(VAULT_CONTRACT_ABI), + vaultAddress.toString() + ); + + // Balances from Vault + let ZRGBalance = await zrgContract.methods + .balanceOf(vaultAddress.toString()) + .call(); + let WMOVRBalance = await wmovrContract.methods + .balanceOf(vaultAddress.toString()) + .call(); + if (ZRGBalance <= 0) { + // In case the pool was initialized but it doesn't have any rewards yet we skip it + continue; + } + + // Adding Reward Tokens to the list + + let rewardTokens = []; + if (ZRGBalance > 0) { + rewardTokens.push(ZRG_ADDRESS[chainId]); + } + if (WMOVRBalance > 0) { + rewardTokens.push(WMOVR_ADDRESS[chainId]); + } + + // Getting PT & Pylon Contracts for each pool + const ptStakedContract = new web3.eth.Contract( + JSON.parse(PT_CONTRACT_ABI), + stakedToken + ); + const pylon = await ptStakedContract.methods.pylon().call(); + const pylonContract = new web3.eth.Contract( + JSON.parse(PYLON_CONTRACT_ABI), + pylon + ); + const pair = await ptStakedContract.methods.pair().call(); + const pairContract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + pair + ); + const token0 = await pairContract.methods.token0().call(); + const token1 = await pairContract.methods.token1().call(); + const reserves = await pairContract.methods.getReserves().call(); + const isAnchor = await ptStakedContract.methods.isAnchor().call(); + + const isFloatRes0 = await pylonContract.methods + .isFloatReserve0() + .call(); + + // Getting Info from Tokens + const token0Contract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + isFloatRes0 ? token0 : token1 + ); + const token1Contract = new web3.eth.Contract( + JSON.parse(PAIR_CONTRACT_ABI), + !isFloatRes0 ? token0 : token1 + ); + const token0Symbol = await token0Contract.methods.symbol().call(); + const token0Decimals = await token0Contract.methods.decimals().call(); + const token1Decimals = await token1Contract.methods.decimals().call(); + const token1Symbol = await token1Contract.methods.symbol().call(); + + // Retrieving Price From Binance + let symbol = token1Symbol === 'WMOVR' ? 'MOVR' : token1Symbol; + symbol = token1Symbol === 'WBNB' ? 'BNB' : symbol; + symbol = symbol.replace('xc', ''); // For cross chain tokens + symbol = `${symbol}BUSD`; + symbol = symbol === 'USDTBUSD' ? 'BUSDUSDT' : symbol; + const stablePrice = await getTokenPrice( + !isFloatRes0 ? token0 : token1, + CHAIN_NAME[chainId] + ); + + //await axios.get(`https://api.binance.com/api/v3/ticker/price?symbol=${symbol}`) + + // Getting Staked Ratio of PT in farm + const totalStaked = await ptStakedContract.methods + .balanceOf(pool.id) + .call(); + const totalSupply = await ptStakedContract.methods.totalSupply().call(); + const stakedRatio = new BigNumber(totalStaked.toString()).dividedBy( + totalSupply.toString() + ); + + // LP Total Supply And Pylon Balance + const lpTotalSupply = await pairContract.methods.totalSupply().call(); + const pylonBalance = await pairContract.methods + .balanceOf(pylon.toString()) + .call(); + const pylonRatio = new BigNumber(pylonBalance.toString()).dividedBy( + lpTotalSupply.toString() + ); + + // Getting muu for daily fees + const muu = await pylonContract.methods.muMulDecimals().call(); + // Getting Daily Volume + let dailyVolume = await gettingDailyVolume(pair, chainId); + let dailyFees = new BigNumber(dailyVolume).multipliedBy(0.0015); + + // Getting TVL of the pool + const pylonReserves = await pylonContract.methods + .getSyncReserves() + .call(); + const r0 = new BigNumber(reserves[0].toString()).dividedBy( + new BigNumber(10).pow(token0Decimals.toString()) + ); + const r1 = new BigNumber(reserves[1].toString()).dividedBy( + new BigNumber(10).pow(token1Decimals.toString()) + ); + const pairRes0 = isFloatRes0 ? r0 : r1; + const pairRes1 = isFloatRes0 ? r1 : r0; + const ratio = pairRes1.dividedBy(pairRes0); + + const tvlPair = new BigNumber(pairRes1) + .multipliedBy(2) + .multipliedBy(stablePrice.price); + const r0Pylon = new BigNumber(pylonReserves[0].toString()).dividedBy( + new BigNumber(10).pow(token0Decimals.toString()) + ); + const r1Pylon = new BigNumber(pylonReserves[1].toString()).dividedBy( + new BigNumber(10).pow(token1Decimals.toString()) + ); + + const r0PylonTVL = r0Pylon + .multipliedBy(ratio) + .multipliedBy(stablePrice.price); + const r1PylonTVL = r1Pylon.dividedBy( + new BigNumber(10).pow(token1Decimals.toString()) + ); + + const tvlPylon = r0PylonTVL.plus(r1PylonTVL); + const tvl = tvlPair.plus(tvlPylon); + // Calculating VAB or VFB in USD + let tokenReserveUSD = 0; + let feesAPR = 0; + let staked = 0; + const vab = await pylonContract.methods.virtualAnchorBalance().call(); + const gamma = await pylonContract.methods.gammaMulDecimals().call(); + + if (isAnchor) { + const vabDecimals = new BigNumber(vab.toString()).dividedBy( + new BigNumber(10).pow(token1Decimals.toString()) + ); + const vabFarm = vabDecimals.multipliedBy(stakedRatio); + tokenReserveUSD = new BigNumber(vabFarm).multipliedBy( + parseFloat(stablePrice.price) + ); + staked = vabDecimals; + // Calculating Stable fees APR + // daylyFees*365*muu/vab + let muuDivided = new BigNumber(muu.toString()).dividedBy(1e18); + feesAPR = new BigNumber(dailyFees.toString()) + .multipliedBy(muuDivided) + .multipliedBy(365) + .dividedBy(vabDecimals.multipliedBy(stablePrice.price)) + .multipliedBy(100); + } else { + const gammaDivided = new BigNumber(gamma.toString()).dividedBy( + new BigNumber(10).pow(18) + ); + const reserveTR = new BigNumber(pairRes1) + .multipliedBy(2) + .multipliedBy(gammaDivided) + .multipliedBy(pylonRatio.toString()); + const vfb = new BigNumber(pylonReserves[0].toString()) + .multipliedBy(ratio) + .dividedBy(new BigNumber(10).pow(token0Decimals.toString())) + .plus(reserveTR); + tokenReserveUSD = new BigNumber(vfb) + .multipliedBy(stablePrice.price) + .multipliedBy(stakedRatio); + staked = vfb; + + // Calculating Float fees APR + // daylyFees*365*(1-muu)/vfb + let muuDivided = new BigNumber(1e18) + .minus(muu.toString()) + .dividedBy(1e18); + feesAPR = new BigNumber(dailyFees.toString()) + .multipliedBy(muuDivided) + .multipliedBy(365) + .dividedBy(vfb.multipliedBy(stablePrice.price)) + .multipliedBy(100); + } + + // Calculating Total Pending Rewards to subtract from block balance + const psiTS = await vaultContract.methods.totalSupply().call(); + const blocksRemaining = + pool.endBlock - (await web3.eth.getBlockNumber()); + let psiRemaining = await vaultContract.methods + .balanceOf(pool.id) + .call(); + let remaining = new BigNumber(psiRemaining.toString()).minus( + new BigNumber(blocksRemaining).multipliedBy(1e18) + ); + + // Calculating earnings per year + let ZRGBalanceCorrected = new BigNumber(ZRGBalance.toString()).minus( + remaining + .multipliedBy(ZRGBalance.toString()) + .dividedBy(psiTS.toString()) + ); + let MOVRBalanceCorrected = new BigNumber(WMOVRBalance.toString()).minus( + remaining + .multipliedBy(WMOVRBalance.toString()) + .dividedBy(psiTS.toString()) + ); + + // Current earnings per block + let movrEarningsPerBlock = new BigNumber(MOVRBalanceCorrected) + .multipliedBy(prices.movr.toString()) + .dividedBy(1e18) + .dividedBy(blocksRemaining.toString()); + let zrgEarningsPerBlock = new BigNumber(ZRGBalanceCorrected) + .multipliedBy(prices.zrg.toString()) + .dividedBy(1e18) + .dividedBy(blocksRemaining.toString()); + + let earningPerYear = new BigNumber(zrgEarningsPerBlock) + .plus(movrEarningsPerBlock) + .multipliedBy(DAILY_BLOCK[chainId] * 365); + const apr = earningPerYear.dividedBy(tokenReserveUSD).multipliedBy(100); + + result.push({ + pairId: pair, + apr: apr.toString(), + feesAPR: feesAPR.toString(), + tokenSymbol: isAnchor ? token1Symbol : token0Symbol, + tokenAddress: isAnchor ? token1 : token0, + tvl: tvl.toString(), + isAnchor, + rewardTokens, + underlyingTokens: [token0, token1], + underlyingTokensSymbol: [token0Symbol, token1Symbol], + stakedToken, + movrEarningsPerBlock, + zrgEarningsPerBlock, + psiTS, + ZRGBalance, + WMOVRBalance, + }); + } catch (e) { + console.error(e); + } + } + } + + return result; +}; + +async function apy(chain) { + let response = await getPools(chain); + let chainName = chain === 56 ? 'bsc' : 'moonriver'; + const pools = response.map((p) => ({ + pool: `${p.stakedToken}-${chainName}`.toLowerCase(), + chain: `${chainName}`, + project: 'zircon-gamma', + symbol: `${p.tokenSymbol}`, + tvlUsd: Number(p.tvl), + apyBase: Number(p.feesAPR), + apyReward: Number(p.apr), + rewardTokens: p.rewardTokens, + underlyingTokens: p.underlyingTokens, + poolMeta: `${ + p.isAnchor ? 'Stable' : 'Float' + } ${p.underlyingTokensSymbol.join('-')}`, + })); + + return [...pools]; +} + +const main = async () => { + const [movr, bsc] = await Promise.all([apy(1285), apy(56)]); + return [...movr, ...bsc]; +}; +module.exports = { + timetravel: false, + apy: main, + url: 'https://www.app.zircon.finance/#/farm', +}; diff --git a/src/adaptors/zklend/abi.js b/src/adaptors/zklend/abi.js new file mode 100644 index 0000000000..8a5cd689f8 --- /dev/null +++ b/src/adaptors/zklend/abi.js @@ -0,0 +1,177 @@ +const market = [ + { + name: 'get_total_debt_for_token', + type: 'function', + inputs: [ + { + name: 'token', + type: 'felt', + }, + ], + outputs: [ + { + name: 'debt', + type: 'felt', + }, + ], + stateMutability: 'view', + customInput: 'address', + }, + { + type: 'struct', + name: 'MarketReserveData', + members: [ + { + name: 'enabled', + type: 'bool', + }, + { + name: 'decimals', + type: 'felt', + }, + { + name: 'z_token_address', + type: 'address', + }, + { + name: 'interest_rate_model', + type: 'address', + }, + { + name: 'collateral_factor', + type: 'felt', + }, + { + name: 'borrow_factor', + type: 'felt', + }, + { + name: 'reserve_factor', + type: 'felt', + }, + { + name: 'last_update_timestamp', + type: 'felt', + }, + { + name: 'lending_accumulator', + type: 'felt', + }, + { + name: 'debt_accumulator', + type: 'felt', + }, + { + name: 'current_lending_rate', + type: 'felt', + }, + { + name: 'current_borrowing_rate', + type: 'felt', + }, + { + name: 'raw_total_debt', + type: 'felt', + }, + { + name: 'flash_loan_fee', + type: 'felt', + }, + { + name: 'liquidation_bonus', + type: 'felt', + }, + { + name: 'debt_limit', + type: 'felt', + }, + ], + }, + { + type: 'function', + name: 'get_reserve_data', + inputs: [ + { + name: 'token', + type: 'address', + }, + ], + outputs: [ + { + type: 'MarketReserveData', + }, + ], + state_mutability: 'view', + }, +]; +const marketAbi = {}; +market.forEach((i) => (marketAbi[i.name] = i)); + +const erc20 = [ + { + name: 'balanceOf', + type: 'function', + inputs: [ + { + name: 'account', + type: 'felt', + }, + ], + outputs: [ + { + name: 'balance', + type: 'Uint256', + }, + ], + stateMutability: 'view', + customInput: 'address', + }, +]; +const erc20Abi = {}; +erc20.forEach((i) => (erc20Abi[i.name] = i)); + +const irm = [ + { + type: 'struct', + name: 'ModelRates', + members: [ + { + name: 'lending_rate', + type: 'felt', + }, + { + name: 'borrowing_rate', + type: 'felt', + }, + ], + }, + { + type: 'function', + name: 'get_interest_rates', + inputs: [ + { + name: 'reserve_balance', + type: 'felt', + }, + { + name: 'total_debt', + type: 'felt', + }, + ], + outputs: [ + { + name: 'rates', + type: 'ModelRates', + }, + ], + state_mutability: 'view', + }, +]; +const irmAbi = {}; +irm.forEach((i) => (irmAbi[i.name] = i)); + +module.exports = { + marketAbi, + erc20Abi, + irmAbi, +}; diff --git a/src/adaptors/zklend/index.js b/src/adaptors/zklend/index.js new file mode 100644 index 0000000000..61a1b4049d --- /dev/null +++ b/src/adaptors/zklend/index.js @@ -0,0 +1,201 @@ +const { multiCall, call } = require('../../helper/starknet'); +const { marketAbi, erc20Abi, irmAbi, zTokenAbi } = require('./abi'); +const axios = require('axios'); +const BN = require('bn.js'); +const { default: BigNumber } = require('bignumber.js'); + +const SCALE = BigNumber('1000000000000000000000000000'); +const e = 2.7182818284590452353602874713527; +const market = + '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05'; +const REWARD_API = `https://app.zklend.com/api/pools`; +const STRK = `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d`; +const ZEND = `0x00585c32b625999e6e5e78645ff8df7a9001cf5cf3eb6b80ccdd16cb64bd3a34`; + +const assets = [ + { + name: 'DAIv0', + address: + '0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3', + decimals: 18, + }, + { + name: 'DAI', + address: + '0x05574eb6b8789a91466f902c380d978e472db68170ff82a5b650b95a58ddf4ad', + decimals: 18, + }, + { + name: 'USDC', + address: + '0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8', + decimals: 6, + }, + { + name: 'USDT', + address: + '0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8', + decimals: 6, + }, + { + name: 'WBTC', + address: + '0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac', + decimals: 8, + }, + { + name: 'ETH', + address: + '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + decimals: 18, + }, + { + name: 'wstETH', + address: + '0x042b8f0484674ca266ac5d08e4ac6a3fe65bd3129795def2dca5c34ecc5f96d2', + decimals: 18, + }, + { + name: 'STRK', + address: + '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', + decimals: 18, + }, +]; + +const getTokenPrice = async (token) => { + const networkTokenPair = `starknet:${token}`; + return ( + await axios.get(`https://coins.llama.fi/prices/current/${networkTokenPair}`) + ).data.coins[networkTokenPair].price; +}; + +const getRewardApys = async () => { + const { data } = await axios.get(REWARD_API); + const tokenSymbolToRewardApyPercent = {}; + + if (!data) { + return {}; + } + + if (!Array.isArray(data)) { + return {}; + } + + for (pool of data) { + // (0 < reward_apy < 1) + const reward_apy = pool.lending_apy.reward_apy; + const symbol = pool.token.symbol; + + if (reward_apy === null || reward_apy === undefined) { + continue; + } + + if (symbol === null || symbol === undefined) { + continue; + } + + if (typeof reward_apy !== 'number') { + continue; + } + + if (typeof symbol !== 'string') { + continue; + } + + const upperSymbol = symbol.toUpperCase(); + + // Convert to percent + tokenSymbolToRewardApyPercent[upperSymbol] = reward_apy * 100; + } + + return tokenSymbolToRewardApyPercent; +}; + +const apy = async () => { + const tokenSymbolToRewardApyPercent = await getRewardApys(); + + const promises = assets.map(async ({ name, address, decimals }) => { + const [priceUsd, marketTokenBalanceBn, totalDebtBn, reserveData] = + await Promise.all([ + getTokenPrice(address), + call({ + abi: erc20Abi.balanceOf, + target: address, + params: [market], + }), + call({ + abi: marketAbi.get_total_debt_for_token, + target: market, + params: [address], + }), + call({ + abi: marketAbi.get_reserve_data, + target: market, + params: [address], + allAbi: [marketAbi.MarketReserveData], + }), + ]); + + const interestRates = await call({ + abi: irmAbi.get_interest_rates, + target: `0x${reserveData.interest_rate_model.toString(16)}`, + params: [marketTokenBalanceBn, totalDebtBn], + allAbi: [irmAbi.ModelRates], + }); + + const reserveFactor = BigNumber(reserveData.reserve_factor.toString()); + const lendingApr = BigNumber(interestRates.lending_rate.toString()) + .multipliedBy(SCALE.minus(reserveFactor)) + .div(SCALE) + .div(SCALE); + const borrowApr = BigNumber(interestRates.borrowing_rate.toString()).div( + SCALE, + ); + + // In percent + const lendingApy = (Math.pow(e, lendingApr.toNumber()) - 1) * 100; + const borrowApy = (Math.pow(e, borrowApr.toNumber()) - 1) * 100; + + const totalDebt = BigNumber(totalDebtBn.toString()).div( + BigNumber(`1e${decimals}`), + ); + const totalDebtUsd = totalDebt.times(priceUsd); + const marketTokenBalance = BigNumber(marketTokenBalanceBn.toString()).div( + BigNumber(`1e${decimals}`), + ); + const marketTokenBalanceUsd = marketTokenBalance.times(priceUsd); + + const zTokenAddress = `0x${reserveData.z_token_address.toString(16)}`; + + let rewardInfo = {}; + if (name.toUpperCase() in tokenSymbolToRewardApyPercent) { + rewardInfo = { + apyReward: tokenSymbolToRewardApyPercent[name.toUpperCase()], + }; + rewardInfo.rewardTokens = [STRK]; + } + + return { + pool: `${zTokenAddress}-starknet`.toLowerCase(), + chain: 'Starknet', + project: `zklend`, + symbol: name, + tvlUsd: marketTokenBalanceUsd.toNumber(), + apyBase: lendingApy, + apyBaseBorrow: borrowApy, + underlyingTokens: [address], + totalSupplyUsd: marketTokenBalanceUsd.plus(totalDebtUsd).toNumber(), + totalBorrowUsd: totalDebtUsd.toNumber(), + url: `https://app.zklend.com/asset/${name}`, + ...rewardInfo, + }; + }); + + return Promise.all(promises); +}; + +module.exports = { + apy, + url: 'https://app.zklend.com/markets', +}; diff --git a/src/adaptors/zkp2p/index.js b/src/adaptors/zkp2p/index.js new file mode 100644 index 0000000000..82221f7ea0 --- /dev/null +++ b/src/adaptors/zkp2p/index.js @@ -0,0 +1,62 @@ +const axios = require('axios'); + +const getApy = async () => { + // time-based scheduling: only run once a day at hour 0 (midnight) + const currentHour = new Date().getHours(); + if (currentHour !== 0) { + console.log( + `zkp2p: Skipping execution at hour ${currentHour} (runs once daily at midnight)` + ); + return []; + } + + try { + // Fetch data from Dune API with your API key + const response = await axios.get( + 'https://api.dune.com/api/v1/query/5416872/results', + { + headers: { + 'X-Dune-API-Key': process.env.DUNE_API_KEY + }, + timeout: 10000 + } + ); + + const duneData = response.data; + const rows = duneData.result.rows; + + if (!rows || rows.length === 0) { + console.error('No data found in Dune query'); + return []; + } + + // Find the most recent data by date + const latestData = rows.reduce((latest, current) => { + const currentDate = new Date(current.day); + const latestDate = new Date(latest.day); + return currentDate > latestDate ? current : latest; + }); + + const pool = { + pool: 'zkp2p-main-pool-base', + chain: 'Base', + project: 'zkp2p', + symbol: 'ZKP2P', + tvlUsd: Number(latestData.tvl), + apy: Number(latestData.protocol_apr_pct), + url: 'https://zkp2p.xyz', + poolMeta: 'APR is a TVL-weighted median across payment rail pools (e.g., Venmo, Zelle). Details: https://docs.zkp2p.xyz/user-guides/for-sellers/calculating-apr', + }; + + console.log('ZKP2P: Fetched fresh data from Dune'); + return [pool]; + } catch (error) { + console.error('Error fetching zkp2p yield data:', error.message); + return []; + } +}; + +module.exports = { + timetravel: false, + apy: getApy, +}; diff --git a/src/adaptors/zkswap-v2/abis.js b/src/adaptors/zkswap-v2/abis.js new file mode 100644 index 0000000000..2c7a6c6a4e --- /dev/null +++ b/src/adaptors/zkswap-v2/abis.js @@ -0,0 +1,2254 @@ +module.exports = { + zfFarmABI: [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Deposit", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "EmergencyWithdraw", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "caller", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "previousAmount", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "newAmount", + type: "uint256" + } + ], + name: "EmissionRateUpdated", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address" + } + ], + name: "OwnershipTransferred", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "user", + type: "address" + }, + { + indexed: true, + internalType: "uint256", + name: "pid", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "Withdraw", + type: "event" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_allocPoint", + type: "uint256" + }, + { + internalType: "contract IERC20", + name: "_lpToken", + type: "address" + }, + { + internalType: "bool", + name: "_withUpdate", + type: "bool" + } + ], + name: "add", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "currentTimestamp", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256" + } + ], + name: "deposit", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + } + ], + name: "emergencyWithdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_from", + type: "uint256" + }, + { + internalType: "uint256", + name: "_to", + type: "uint256" + } + ], + name: "getMultiplier", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "pure", + type: "function" + }, + { + inputs: [], + name: "massUpdatePools", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + }, + { + internalType: "address", + name: "_user", + type: "address" + } + ], + name: "pendingZF", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + name: "poolInfo", + outputs: [ + { + internalType: "contract IERC20", + name: "lpToken", + type: "address" + }, + { + internalType: "uint256", + name: "allocPoint", + type: "uint256" + }, + { + internalType: "uint256", + name: "lastRewardTime", + type: "uint256" + }, + { + internalType: "uint256", + name: "accZFPerShare", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "poolLength", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "_allocPoint", + type: "uint256" + }, + { + internalType: "bool", + name: "_withUpdate", + type: "bool" + } + ], + name: "set", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "startTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "totalAllocPoint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address" + } + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_zfPerSecond", + type: "uint256" + } + ], + name: "updateEmissionRate", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + } + ], + name: "updatePool", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_startTime", + type: "uint256" + } + ], + name: "updateStartTime", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + }, + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "userInfo", + outputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256" + }, + { + internalType: "uint256", + name: "rewardDebt", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "_pid", + type: "uint256" + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256" + } + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "zf", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "zfPerSecond", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + } + ], + zfTokenABI: [ + { + inputs: [ + { + internalType: "address", + name: "_token0", + type: "address" + }, + { + internalType: "address", + name: "_token1", + type: "address" + } + ], + stateMutability: "nonpayable", + type: "constructor" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256" + } + ], + name: "Approval", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount0", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount1", + type: "uint256" + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address" + } + ], + name: "Burn", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount0", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount1", + type: "uint256" + } + ], + name: "Mint", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "amount0In", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount1In", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount0Out", + type: "uint256" + }, + { + indexed: false, + internalType: "uint256", + name: "amount1Out", + type: "uint256" + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address" + } + ], + name: "Swap", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint112", + name: "reserve0", + type: "uint112" + }, + { + indexed: false, + internalType: "uint112", + name: "reserve1", + type: "uint112" + } + ], + name: "Sync", + type: "event" + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address" + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address" + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256" + } + ], + name: "Transfer", + type: "event" + }, + { + inputs: [], + name: "DOMAIN_SEPARATOR", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "PERMIT_TYPEHASH", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address" + }, + { + internalType: "address", + name: "spender", + type: "address" + } + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address" + } + ], + name: "burn", + outputs: [ + { + internalType: "uint256", + name: "amount0", + type: "uint256" + }, + { + internalType: "uint256", + name: "amount1", + type: "uint256" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8" + } + ], + stateMutability: "pure", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address" + }, + { + internalType: "uint256", + name: "subtractedValue", + type: "uint256" + } + ], + name: "decreaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "factory", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address" + } + ], + name: "getPrincipal", + outputs: [ + { + internalType: "uint112", + name: "principal0", + type: "uint112" + }, + { + internalType: "uint112", + name: "principal1", + type: "uint112" + }, + { + internalType: "uint32", + name: "timeLastUpdate", + type: "uint32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getReserves", + outputs: [ + { + internalType: "uint112", + name: "_reserve0", + type: "uint112" + }, + { + internalType: "uint112", + name: "_reserve1", + type: "uint112" + }, + { + internalType: "uint32", + name: "_blockTimestampLast", + type: "uint32" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getReservesAndParameters", + outputs: [ + { + internalType: "uint112", + name: "_reserve0", + type: "uint112" + }, + { + internalType: "uint112", + name: "_reserve1", + type: "uint112" + }, + { + internalType: "uint16", + name: "_swapFee", + type: "uint16" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getReservesSimple", + outputs: [ + { + internalType: "uint112", + name: "", + type: "uint112" + }, + { + internalType: "uint112", + name: "", + type: "uint112" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "getSwapFee", + outputs: [ + { + internalType: "uint16", + name: "", + type: "uint16" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address" + }, + { + internalType: "uint256", + name: "addedValue", + type: "uint256" + } + ], + name: "increaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "kLast", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address" + } + ], + name: "mint", + outputs: [ + { + internalType: "uint256", + name: "liquidity", + type: "uint256" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + name: "nonces", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address" + }, + { + internalType: "address", + name: "spender", + type: "address" + }, + { + internalType: "uint256", + name: "value", + type: "uint256" + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256" + }, + { + internalType: "uint8", + name: "v", + type: "uint8" + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32" + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32" + } + ], + name: "permit", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "price0CumulativeLast", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "price1CumulativeLast", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint16", + name: "_swapFeeOverride", + type: "uint16" + } + ], + name: "setSwapFeeOverride", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address" + } + ], + name: "skim", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount0Out", + type: "uint256" + }, + { + internalType: "uint256", + name: "amount1Out", + type: "uint256" + }, + { + internalType: "address", + name: "to", + type: "address" + }, + { + internalType: "bytes", + name: "data", + type: "bytes" + } + ], + name: "swap", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "swapFeeOverride", + outputs: [ + { + internalType: "uint16", + name: "", + type: "uint16" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount0Out", + type: "uint256" + }, + { + internalType: "address", + name: "to", + type: "address" + } + ], + name: "swapFor0", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount1Out", + type: "uint256" + }, + { + internalType: "address", + name: "to", + type: "address" + } + ], + name: "swapFor1", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "sync", + outputs: [], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [], + name: "token0", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "token1", + outputs: [ + { + internalType: "address", + name: "", + type: "address" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "nonpayable", + type: "function" + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address" + }, + { + internalType: "address", + name: "to", + type: "address" + }, + { + internalType: "uint256", + name: "amount", + type: "uint256" + } + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool" + } + ], + stateMutability: "nonpayable", + type: "function" + } + ], + erc20ABI: [ + { + constant: true, + inputs: [{ name: '_owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: 'balance', type: 'uint256' }], + type: 'function', + }, + { + constant: true, + inputs: [], + name: 'decimals', + outputs: [{ name: '', type: 'uint8' }], + type: 'function', + }, + ], + zfFactory: [ + { + inputs: [], + name: "protocolFeeFactor", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8" + } + ], + stateMutability: "view", + type: "function" + }, + { + inputs: [], + name: "swapFee", + outputs: [ + { + internalType: "uint16", + name: "", + type: "uint16" + } + ], + stateMutability: "view", + type: "function" + } + ], + zfGOVAbi: [ + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "DELEGATION_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rawAmount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint96", + "name": "votes", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "endTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getCurrentVotes", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCurrentZF", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPriorVotes", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getYZFPricePerFullShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getZFPricePerFullShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRewardTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingZF", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rawAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_endTime", + "type": "uint256" + } + ], + "name": "setEndTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_zfPerSecond", + "type": "uint256" + } + ], + "name": "setRewardRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_startTime", + "type": "uint256" + } + ], + "name": "setStartTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "_factor", + "type": "uint8" + } + ], + "name": "setWithdrawFeeFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "startTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rawAmount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rawAmount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_shares", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFeeFactor", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFeeFactorMax", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "zfPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + zfLpABI: [ + { + inputs: [], + name: "getSwapFee", + outputs: [ + { + internalType: "uint16", + name: "", + type: "uint16" + } + ], + stateMutability: "view", + type: "function" + }, + ] + +} diff --git a/src/adaptors/zkswap-v2/index.js b/src/adaptors/zkswap-v2/index.js new file mode 100644 index 0000000000..bafc0e1f95 --- /dev/null +++ b/src/adaptors/zkswap-v2/index.js @@ -0,0 +1,346 @@ +const { Web3 } = require('web3'); +const { default: BigNumber } = require('bignumber.js'); +const sdk = require('@defillama/sdk'); +const { request, gql, batchRequests } = require('graphql-request'); +const superagent = require('superagent'); +const { chunk } = require('lodash'); + +const { + zfFarmABI, + zfTokenABI, + erc20ABI, + zfFactory, + zfGOVAbi, + zfLpABI, +} = require('./abis'); +const utils = require('../utils'); +const { SECONDS_PER_YEAR } = require('../across/constants'); + +const ZFFarm = '0x9f9d043fb77a194b4216784eb5985c471b979d67'; +const ZFToken = '0x31c2c031fdc9d33e974f327ab0d9883eae06ca4a'; +const ZFFactory = '0x3a76e377ed58c8731f9df3a36155942438744ce3'; +const ZF_GOV = '0x4ca2ac3513739cebf053b66a1d59c88d925f1987'; +const DAO_START_TIME = 1697716800; + +const RPC_URL = 'https://mainnet.era.zksync.io'; +const API_URL = 'https://api.studio.thegraph.com/query/49271/zkswap/0.0.9'; +const DAO_API_URL = + 'https://api.studio.thegraph.com/query/49271/zfgovernancestaking/0.1.2'; + +const SECOND_PER_DAY = 60 * 60 * 24; +const DAY_PER_YEAR = 365; +const SECOND_PER_YEAR = SECOND_PER_DAY * DAY_PER_YEAR; +const WEEKS_PER_YEAR = 52; +const CHAIN = 'era'; + +const web3 = new Web3(RPC_URL); + +const apy = async () => { + const nonLpPools = [0]; + const zfFarm = new web3.eth.Contract(zfFarmABI, ZFFarm); + + const zfGOV = new web3.eth.Contract(zfGOVAbi, ZF_GOV); + + const poolsCount = await zfFarm.methods.poolLength().call(); + const totalAllocPoint = Number(await zfFarm.methods.totalAllocPoint().call()); + const zfPerSecond = Number(await zfFarm.methods.zfPerSecond().call()) / 1e18; + + const protocolFeeRes = await sdk.api.abi.call({ + abi: zfFactory.find((abi) => abi.name === 'protocolFeeFactor'), + target: ZFFactory, + chain: CHAIN, + }); + + const protocolFee = protocolFeeRes.output; + + const poolsRes = await sdk.api.abi.multiCall({ + abi: zfFarmABI.filter(({ name }) => name === 'poolInfo')[0], + calls: [...Array(Number(poolsCount)).keys()].map((i) => ({ + target: ZFFarm, + params: i, + })), + chain: CHAIN, + requery: true, + }); + const pools = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter(({ i }) => !nonLpPools.includes(i)); + + const lpTokens = pools.map(({ lpToken }) => lpToken); + + const lpTokensSwapFeeCall = await sdk.api.abi.multiCall({ + abi: zfLpABI.filter(({ name }) => name === 'getSwapFee')[0], + calls: lpTokens.map((lpAddress) => ({ + target: lpAddress, + })), + chain: CHAIN, + requery: true, + permitFailure: true, + }); + + const lpTokensSwapFee = lpTokensSwapFeeCall.output.reduce( + (lpSwapFeeObj, item, index, arr) => { + lpSwapFeeObj[lpTokens[index]?.toLowerCase()] = item?.output; + return lpSwapFeeObj; + }, + {} + ); + + const nonLpPoolList = poolsRes.output + .map(({ output }, i) => ({ ...output, i })) + .filter(({ i }) => nonLpPools.includes(i)); + + const nonLpToken = nonLpPoolList.map(({ lpToken }) => lpToken); + + const [reservesData, supplyData, zfFarmBalData] = await Promise.all( + ['getReserves', 'totalSupply', 'balanceOf'].map((method) => + makeMulticall( + zfTokenABI.filter(({ name }) => name === method)[0], + lpTokens, + CHAIN, + method === 'balanceOf' ? [ZFFarm] : null + ) + ) + ); + const [tokens0, tokens1] = await Promise.all( + ['token0', 'token1'].map((method) => + makeMulticall( + zfTokenABI.filter(({ name }) => name === method)[0], + lpTokens, + CHAIN + ) + ) + ); + + const { pricesByAddress: tokensPrices } = await utils.getPrices( + [...new Set([...tokens0, ...tokens1])], + CHAIN + ); + + const pairsInfo = await utils.uniswap.getPairsInfo(lpTokens, API_URL); + const lpChunks = chunk(lpTokens, 10); + + const currentTime = Math.round(new Date().getTime() / 1000); + + const daoQuery = gql` + query daoQuery { + transfers( + where: {blockTimestamp_gt: ${ + currentTime - SECOND_PER_DAY * 3 + }, blockTimestamp_lte: ${currentTime}} + first: 1000 + ) { + value + }} + `; + + const { transfers } = await request(DAO_API_URL, daoQuery); + + const unstakedZFReward = + transfers.reduce((volume, transf) => { + return volume + Number(transf.value) / 1e18; + }, 0) / 90; + + const pairVolumes = await Promise.all( + lpChunks.map((lpsChunk) => + request( + API_URL, + gql` + query volumesQuery { + ${lpsChunk + .slice(0, 10) + .map( + (token, i) => + `token_${token.toLowerCase()}:pairHourDatas( + orderBy: hourStartUnix + orderDirection: desc + first: 24 + where: {pair_: {id: "${token.toLowerCase()}"}}) + { + hourlyVolumeUSD + }` + ) + .join('\n')}}` + ) + ) + ); + + const volumesMap = pairVolumes.flat().reduce( + (acc, curChunk) => ({ + ...acc, + ...Object.entries(curChunk).reduce( + (innerAcc, [key, val]) => ({ + ...innerAcc, + [key.split('_')[1]]: val, + }), + {} + ), + }), + {} + ); + + const [tvl] = await makeMulticall( + zfTokenABI.filter(({ name }) => name === 'balanceOf')[0], + nonLpToken, + CHAIN, + [ZFFarm] + ); + const nonLpTvl = tvl / 1e18; + const nonLpRes = nonLpPoolList + .map((pool, i) => { + const poolInfo = pool; + const poolWeight = poolInfo.allocPoint / totalAllocPoint; + const totalRewardPricePerYear = + tokensPrices[ZFToken] * poolWeight * zfPerSecond * SECOND_PER_YEAR; + const totalStakingTokenInPool = tokensPrices[ZFToken] * nonLpTvl; + const apyReward = + (totalRewardPricePerYear / totalStakingTokenInPool) * 100; + return { + pool: poolInfo.lpToken, + chain: CHAIN, + project: 'zkswap-v2', + symbol: 'ZF', + tvlUsd: totalStakingTokenInPool, + apyBase: 0, + apyReward, + underlyingTokens: [poolInfo.lpToken.toLowerCase()], + rewardTokens: [ZFToken], + url: 'https://zkswap.finance/earn', + }; + }) + .filter((pool) => pool.apyReward > 0); + + const unstakedZFReward3Day = + (unstakedZFReward / 3) * DAY_PER_YEAR * tokensPrices[ZFToken]; + + const { output: zfDAOPerSecondRes } = await sdk.api.abi.call({ + abi: zfGOVAbi.filter(({ name }) => name === 'zfPerSecond')[0], + target: ZF_GOV, + chain: CHAIN, + }); + const zfDAOPerSecond = Number(zfDAOPerSecondRes) / 1e18; + + const { output: pendingZfRes } = await sdk.api.abi.call({ + abi: zfGOVAbi.filter(({ name }) => name === 'pendingZF')[0], + target: ZF_GOV, + chain: CHAIN, + }); + const pendingZf = Number(pendingZfRes) / 1e18; + + const { output: currentGovTvlRes } = await sdk.api.abi.call({ + abi: zfGOVAbi.filter(({ name }) => name === 'balance')[0], + target: ZF_GOV, + chain: CHAIN, + }); + const currentGovTvl = Number(currentGovTvlRes) / 1e18; + + const zfRewardDAOUntilNow = (currentTime - DAO_START_TIME) * zfDAOPerSecond; + const govTvl = + (currentGovTvl + pendingZf - zfRewardDAOUntilNow) * tokensPrices[ZFToken]; + const unstakedAPY = (unstakedZFReward3Day / govTvl) * 100; + const govFarmAPY = + ((zfDAOPerSecond * SECONDS_PER_YEAR * tokensPrices[ZFToken]) / govTvl) * + 100; + + const govPool = { + pool: ZF_GOV, + chain: CHAIN, + project: 'zkswap-v2', + symbol: 'ZF', + tvlUsd: govTvl, + apyBase: unstakedAPY, + apyReward: govFarmAPY, + underlyingTokens: [ZFToken], + rewardTokens: [ZFToken], + url: 'https://zkswap.finance/earn', + }; + + const res = pools.map((pool, i) => { + const poolInfo = pool; + const reserves = reservesData[i]; + const pairInfo = pairsInfo[pool.lpToken.toLowerCase()]; + + if (!pairInfo) return {}; + + const supply = supplyData[i]; + const zfFarmBalance = zfFarmBalData[i]; + + const zfFarmReservesUsd = utils.uniswap + .calculateReservesUSD( + reserves, + zfFarmBalance / supply, + pairInfo?.token0, + pairInfo?.token1, + tokensPrices + ) + .toString(); + + const lpReservesUsd = utils.uniswap + .calculateReservesUSD( + reserves, + 1, + pairInfo?.token0, + pairInfo?.token1, + tokensPrices + ) + .toString(); + + const fee = lpTokensSwapFee[pool.lpToken.toLowerCase()]; + const feeRate = (fee * (1 - 1 / protocolFee)) / 10000; + + const lpFees24h = + (volumesMap[pool.lpToken.toLowerCase()] || []).reduce( + (acc, { hourlyVolumeUSD }) => acc + Number(hourlyVolumeUSD), + 0 + ) * feeRate; + + const apyBase = ((lpFees24h * DAY_PER_YEAR) / lpReservesUsd) * 100; + + const apyReward = utils.uniswap.calculateApy( + poolInfo, + totalAllocPoint, + zfPerSecond, + tokensPrices[ZFToken], + zfFarmReservesUsd, + SECOND_PER_YEAR + ); + + return { + pool: pool.lpToken, + chain: CHAIN, + project: 'zkswap-v2', + symbol: pairInfo.name, + tvlUsd: Number(zfFarmReservesUsd), + apyBase, + apyReward, + underlyingTokens: + tokens0[i] && tokens1[i] + ? [tokens0[i], tokens1[i]] + : [poolInfo.address.toLowerCase()], + rewardTokens: [ZFToken], + url: 'https://zkswap.finance/earn', + }; + }); + return [...nonLpRes, ...res, govPool].filter((i) => utils.keepFinite(i)); +}; + +const makeMulticall = async (abi, addresses, chain, params = null) => { + const data = await sdk.api.abi.multiCall({ + abi, + calls: addresses.map((address) => ({ + target: address, + params, + })), + chain, + permitFailure: true, + }); + + const res = data.output.map(({ output }) => output); + + return res; +}; + +module.exports = { + timetravel: false, + apy: apy, +}; diff --git a/src/adaptors/zunami-protocol/index.js b/src/adaptors/zunami-protocol/index.js new file mode 100644 index 0000000000..900d7f9a08 --- /dev/null +++ b/src/adaptors/zunami-protocol/index.js @@ -0,0 +1,91 @@ +const utils = require('../utils'); + +const zunETHAddr = "0xc2e660C62F72c2ad35AcE6DB78a616215E2F2222"; +const zunETHApsAddr = "0x5Ab3aa11a40eB34f1d2733f08596532871bd28e2"; +const zunETHApsStakingAddr = "0x61b31cF4039D39F2F2909B8cb82cdb8eB5927Cd8"; + +const zunUSDAddr = "0x8C0D76C9B18779665475F3E212D9Ca1Ed6A1A0e6"; +const zunUSDApsAddr = "0x28e487bbF6b64867C29e61DccbCD17aB64082889"; +const zunUSDApsStakingAddr = "0x280d48e85f712e067a16d6b25e7ffe261c0810bd"; + +const zunStakingAddr = "0x45af4F12B46682B3958B297bAcebde2cE2E795c3"; + +const collectPools = async () => { + const data = await utils.getData('https://api.zunami.io/api/pool/aggregated-info'); + const info = data['info']; + + const zunUSD = info['zunUSD']; + const zunUSDAps = info['zunUSDAps']; + const zunUSDApsStaking = info['zunUSDApsStaking']; + + const zunETH = info['zunETH']; + const zunETHAps = info['zunETHAps']; + const zunETHApsStaking = info['zunETHApsStaking']; + + const zunStaking = info['staking']; + + return [ + { + pool: zunUSDAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'DAI-USDC-USDT-crvUSD', + tvlUsd: zunUSD['tvlUsd'], + apy: zunUSD['apr'], + }, + { + pool: zunUSDApsAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'zunUSD', + tvlUsd: zunUSDAps['tvlUsd'], + apy: zunUSDAps['apy'], + }, + { + pool: zunUSDApsStakingAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'apsZunUSD', + tvlUsd: zunUSDApsStaking['tvlUsd'], + apy: zunUSDApsStaking['apr'], + }, + { + pool: zunETHAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'ETH-wETH-sfrxETH-stETH', + tvlUsd: zunETH['tvlUsd'], + apy: zunETH['apr'], + }, + { + pool: zunETHApsAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'zunETH', + tvlUsd: zunETHAps['tvlUsd'], + apy: zunETHAps['apy'], + }, + { + pool: zunETHApsStakingAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'apsZunETH', + tvlUsd: zunETHApsStaking['tvlUsd'], + apy: zunETHApsStaking['apr'], + }, + { + pool: zunStakingAddr, + chain: utils.formatChain('ethereum'), + project: 'zunami-protocol', + symbol: 'ZUN', + tvlUsd: zunStaking['tvlUsd'], + apy: zunStaking['apr'], + }, + ]; +}; + +module.exports = { + timetravel: false, + apy: collectPools, + url: 'https://app.zunami.io/', +}; diff --git a/src/adaptors/zyberswap-amm/index.js b/src/adaptors/zyberswap-amm/index.js new file mode 100644 index 0000000000..d0195a7101 --- /dev/null +++ b/src/adaptors/zyberswap-amm/index.js @@ -0,0 +1,153 @@ +const { request, gql } = require('graphql-request'); +const sdk = require('@defillama/sdk'); +const masterchefAbi = require('./masterchef'); +const axios = require('axios'); + +const masterchef = '0x9BA666165867E916Ee7Ed3a3aE6C19415C2fBDDD'; +const ZYB = '0x3B475F6f2f41853706afc9Fa6a6b8C5dF1a2724c'; + +const utils = require('../utils'); + +const url = sdk.graph.modifyEndpoint('3g83GYhbyHtjy581vpTmN1AP9cB9MjWMh5TiuNpvTU4R'); + +const query = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + reserve0 + reserve1 + token0 { + id + symbol + } + token1 { + id + symbol + } + } + } +`; + +const queryPrior = gql` + { + pairs(first: 1000 orderBy: trackedReserveETH orderDirection: desc block: {number: }) { + id + volumeUSD + } + } +`; + +const topLvl = async (chainString, timestamp, url) => { + // rewards + const poolLength = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'poolLength'), + chain: chainString, + }) + ).output; + + const poolInfo = ( + await sdk.api.abi.multiCall({ + calls: [...Array(Number(poolLength)).keys()].map((i) => ({ + target: masterchef, + params: [i], + })), + abi: masterchefAbi.find((m) => m.name === 'poolInfo'), + chain: chainString, + }) + ).output.map((o) => o.output); + + const totalAllocPoint = ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'totalAllocPoint'), + chain: chainString, + }) + ).output; + + const zyberPerSec = + ( + await sdk.api.abi.call({ + target: masterchef, + abi: masterchefAbi.find((m) => m.name === 'zyberPerSec'), + chain: chainString, + }) + ).output / 1e18; + + const priceKey = `arbitrum:${ZYB}`; + const zyberPrice = ( + await axios.get(`https://coins.llama.fi/prices/current/${priceKey}`) + ).data.coins[priceKey]?.price; + + const zyberPerYearUsd = zyberPerSec * 86400 * 365 * zyberPrice; + + const [block, blockPrior] = await utils.getBlocks(chainString, timestamp, [ + url, + ]); + + const [_, blockPrior7d] = await utils.getBlocks( + chainString, + timestamp, + [url], + 604800 + ); + + let data = (await request(url, query.replace('', block))).pairs; + + // pull 24h offset data to calculate fees from swap volume + const dataPrior = ( + await request(url, queryPrior.replace('', blockPrior)) + ).pairs; + + // 7d offset + const dataPrior7d = ( + await request(url, queryPrior.replace('', blockPrior7d)) + ).pairs; + + // calculate tvl + data = await utils.tvl(data, chainString); + + // calculate apy + data = data.map((el) => utils.apy(el, dataPrior, dataPrior7d, 'zyberswap')); + + // build pool objects + data = data.map((p) => { + const x = poolInfo.find( + (pi) => pi.lpToken.toLowerCase() === p.id.toLowerCase() + )?.allocPoint; + + const apyReward = + (((x / totalAllocPoint) * zyberPerYearUsd) / p.totalValueLockedUSD) * 100; + + const symbol = utils.formatSymbol(`${p.token0.symbol}-${p.token1.symbol}`); + return { + pool: p.id, + chain: utils.formatChain(chainString), + project: 'zyberswap-amm', + symbol, + tvlUsd: p.totalValueLockedUSD, + apyBase: p.apy1d, + apyBase7d: p.apy7d, + apyReward, + underlyingTokens: [p.token0.id, p.token1.id], + rewardTokens: apyReward > 0 ? [ZYB] : [], + volumeUsd1d: p.volumeUSD1d, + volumeUsd7d: p.volumeUSD7d, + }; + }); + + return data; +}; + +const main = async (timestamp = null) => { + const data = await Promise.all([topLvl('arbitrum', timestamp, url)]); + return data.flat().filter((p) => utils.keepFinite(p)); +}; + +module.exports = { + timetravel: true, + apy: main, + url: 'https://app.zyberswap.io/exchange/pool', +}; diff --git a/src/adaptors/zyberswap-amm/masterchef.js b/src/adaptors/zyberswap-amm/masterchef.js new file mode 100644 index 0000000000..49ec873acb --- /dev/null +++ b/src/adaptors/zyberswap-amm/masterchef.js @@ -0,0 +1,746 @@ +module.exports = [ + { + inputs: [ + { + internalType: 'contract IBoringERC20', + name: '_zyber', + type: 'address', + }, + { internalType: 'uint256', name: '_zyberPerSec', type: 'uint256' }, + { internalType: 'address', name: '_marketingAddress', type: 'address' }, + { internalType: 'uint256', name: '_marketingPercent', type: 'uint256' }, + { internalType: 'address', name: '_teamAddress', type: 'address' }, + { internalType: 'uint256', name: '_teamPercent', type: 'uint256' }, + { internalType: 'address', name: '_feeAddress', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IMultipleRewards[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Add', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newAmount', + type: 'uint256', + }, + ], + name: 'AllocPointsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Deposit', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'EmergencyWithdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'caller', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'previousValue', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newValue', + type: 'uint256', + }, + ], + name: 'EmissionRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amountLockedUp', + type: 'uint256', + }, + ], + name: 'RewardLockedUp', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'allocPoint', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint16', + name: 'depositFeeBP', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint256', + name: 'harvestInterval', + type: 'uint256', + }, + { + indexed: true, + internalType: 'contract IMultipleRewards[]', + name: 'rewarders', + type: 'address[]', + }, + ], + name: 'Set', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetFeeAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetInvestorAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetTeamAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetTeamPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'oldAddress', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newAddress', + type: 'address', + }, + ], + name: 'SetmarketingAddress', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldPercent', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newPercent', + type: 'uint256', + }, + ], + name: 'SetmarketingPercent', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'lastRewardTimestamp', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'lpSupply', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'accZyberPerShare', + type: 'uint256', + }, + ], + name: 'UpdatePool', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'user', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'pid', type: 'uint256' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [], + name: 'MAXIMUM_DEPOSIT_FEE_RATE', + outputs: [{ internalType: 'uint16', name: '', type: 'uint16' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAXIMUM_HARVEST_INTERVAL', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { + internalType: 'contract IBoringERC20', + name: '_lpToken', + type: 'address', + }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IMultipleRewards[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'add', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'canHarvest', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'pid', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'emergencyWithdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'feeAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getZyberPerSec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256[]', name: '_pids', type: 'uint256[]' }], + name: 'harvestMany', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'marketingAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'marketingPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'massUpdatePools', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingTokens', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'poolInfo', + outputs: [ + { + internalType: 'contract IBoringERC20', + name: 'lpToken', + type: 'address', + }, + { internalType: 'uint256', name: 'allocPoint', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardTimestamp', type: 'uint256' }, + { internalType: 'uint256', name: 'accZyberPerShare', type: 'uint256' }, + { internalType: 'uint16', name: 'depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: 'harvestInterval', type: 'uint256' }, + { internalType: 'uint256', name: 'totalLp', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'poolLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewarders', + outputs: [ + { internalType: 'address[]', name: 'rewarders', type: 'address[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'poolRewardsPerSec', + outputs: [ + { internalType: 'address[]', name: 'addresses', type: 'address[]' }, + { internalType: 'string[]', name: 'symbols', type: 'string[]' }, + { internalType: 'uint256[]', name: 'decimals', type: 'uint256[]' }, + { internalType: 'uint256[]', name: 'rewardsPerSec', type: 'uint256[]' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'pid', type: 'uint256' }], + name: 'poolTotalLp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + { internalType: 'uint16', name: '_depositFeeBP', type: 'uint16' }, + { internalType: 'uint256', name: '_harvestInterval', type: 'uint256' }, + { + internalType: 'contract IMultipleRewards[]', + name: '_rewarders', + type: 'address[]', + }, + ], + name: 'set', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '_feeAddress', type: 'address' }], + name: 'setFeeAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_marketingAddress', type: 'address' }, + ], + name: 'setMarketingAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_newmarketingPercent', + type: 'uint256', + }, + ], + name: 'setMarketingPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: '_teamAddress', type: 'address' }, + ], + name: 'setTeamAddress', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_newTeamPercent', type: 'uint256' }, + ], + name: 'setTeamPercent', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startFarming', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'startTimestamp', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamAddress', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'teamPercent', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalAllocPoint', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalLockedUpRewards', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalZyberInPools', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_allocPoint', type: 'uint256' }, + ], + name: 'updateAllocPoint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_zyberPerSec', type: 'uint256' }, + ], + name: 'updateEmissionRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: '_pid', type: 'uint256' }], + name: 'updatePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', + outputs: [ + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardLockedUp', type: 'uint256' }, + { internalType: 'uint256', name: 'nextHarvestUntil', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: '_pid', type: 'uint256' }, + { internalType: 'uint256', name: '_amount', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'zyber', + outputs: [ + { internalType: 'contract IBoringERC20', name: '', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'zyberPerSec', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/src/api/app.js b/src/api/app.js new file mode 100644 index 0000000000..3d83c4f4b3 --- /dev/null +++ b/src/api/app.js @@ -0,0 +1,62 @@ +const express = require('express'); +const helmet = require('helmet'); +const { Redis } = require("ioredis"); + +const redis = new Redis(process.env.REDIS_URL); + +const yieldRoutes = require('./routes/yield'); +const config = require('./routes/config'); +const median = require('./routes/median'); +const perp = require('./routes/perp'); +const enriched = require('./routes/enriched'); +const lsd = require('./routes/lsd'); +const { getCacheDates } = require('../utils/headers'); +const risk = require('./routes/risk'); + +const app = express(); +app.use(require('morgan')('dev')); +app.use(helmet()); +app.use(express.json()); + +async function redisCache (req, res, next) { + const lastCacheUpdate = await redis.get("lastUpdate#"+req.url) + const {headers, nextCacheDate} = getCacheDates() + if(lastCacheUpdate !== null && Number(lastCacheUpdate) > (nextCacheDate.getTime() - 3600e3)){ + const cacheObject = await redis.get("data#"+req.url) + res.set(headers) + .status(200) + .send(cacheObject); + } else { + res._apicache = { + url: req.url, + end: res.end + } + res.end = function(content, encoding) { + if(res.statusCode === 200){ + redis.set("data#" + res._apicache.url, content.toString()) + redis.set("lastUpdate#" + res._apicache.url, Date.now()) + res.set(headers) + } + return res._apicache.end.apply(this, arguments) + } + next() + } +} +app.use(redisCache) + +app.use('/', [yieldRoutes, config, median, perp, enriched, lsd, risk]); + +function errorHandler (err, req, res, next) { + console.log(err) + res.status(500) + res.render('error', { error: err }) +} + +app.use(errorHandler) + +process.on('uncaughtException', (err) => { + console.error('uncaughtException:', err.message); + process.exit(1); +}); + +module.exports = app; diff --git a/src/api/controllers/config.js b/src/api/controllers/config.js new file mode 100644 index 0000000000..5117643fdb --- /dev/null +++ b/src/api/controllers/config.js @@ -0,0 +1,105 @@ +const validator = require('validator'); + +const AppError = require('../../utils/appError'); +const { conn } = require('../db'); + +// get pool urls +const getUrl = async (req, res) => { + const query = ` + SELECT + config_id, + url + FROM + config + `; + + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + const out = {}; + for (const e of response) { + out[e.config_id] = e.url; + } + res.status(200).json(out); +}; + +// get unique pool values +// (used during adapter testing to check if a pool field is already in the DB) +const getDistinctID = async (req, res) => { + const query = ` + SELECT + DISTINCT(pool), + config_id, + project + FROM + config + `; + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json(response); +}; + +// get config data of pool +const getConfigPool = async (req, res) => { + const configID = req.params.configID; + const ids = configID.split(','); + const valid = + ids.map((id) => validator.isUUID(id)).reduce((a, b) => a + b, 0) === + ids.length; + if (!valid) return { status: 'invalid uuid parameter' }; + + const query = ` + SELECT + * + FROM + config + WHERE + config_id IN ($) + `; + const response = await conn.query(query, { configIDs: ids }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +// for calc liq on main protocol dashboard +const getAllPools = async (req, res) => { + const query = ` + SELECT + config_id, + symbol, + project, + chain, + "underlyingTokens" + FROM + config + `; + + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json(response); +}; + +module.exports = { + getUrl, + getDistinctID, + getConfigPool, + getAllPools, +}; diff --git a/src/api/controllers/enriched.js b/src/api/controllers/enriched.js new file mode 100644 index 0000000000..5c93e17f77 --- /dev/null +++ b/src/api/controllers/enriched.js @@ -0,0 +1,121 @@ +const AWS = require('aws-sdk'); +AWS.config.update({ + accessKeyId: process.env.aws_access_key_id, + secretAccessKey: process.env.aws_secret_access_key, + region: process.env.region, +}); +const S3 = require('aws-sdk/clients/s3'); +const validator = require('validator'); + +const AppError = require('../../utils/appError'); +const poolsEnrichedColumns = require('../../utils/enrichedColumns'); +const { readFromS3 } = require('../../utils/s3'); + +let poolsEnriched = { + lastUpdate: Date.now(), + data: null +} + +async function getPoolsEnrichedData(){ + if(poolsEnriched.lastUpdate < (Date.now() - 10*60*1e3) || poolsEnriched.data === null){ + // this leads to race conditions but thats fine + const data = await readFromS3( + 'llama-apy-prod-data', + 'enriched/dataEnriched.json' + ); + poolsEnriched = { + lastUpdate: Date.now(), + data + } + } + return poolsEnriched.data +} + +const getPoolEnriched = async (req, res) => { + // querystring (though we only use it for pool values on /pool pages) + // note: change to route param later -> /pools/:pool + const configID = req.query.pool; + if (!configID || !validator.isUUID(configID)) + return res.status(400).json('invalid configID!'); + + const queryString = req.query; + + let columns = poolsEnrichedColumns; + columns = queryString !== undefined ? [...columns, 'url'] : columns; + + const data = await getPoolsEnrichedData() + res + .status(200) + .json({ + status: 'success', + data: data.filter((t) => t.pool == configID), + }); +}; + +const getPoolsEnrichedPro = async (req, res) => { + const queryString = req.query; + + // add pool_old (the pool field from the adpaters == address) + let columns = [...poolsEnrichedColumns, 'pool_old']; + + let data = await getPoolsEnrichedData() + if (Object.keys(queryString).length > 0) { + data = data.filter((pool) => { + const key = Object.keys(queryString)[0]; + const val = queryString[key]; + return pool[key] === val; + }); + } + + res.status(200).json({ + status: 'success', + data, + }); +}; + +const getPoolsBorrow = async (req, res) => { + const data = await Promise.all( + ['pools', 'lendBorrow'].map((p) => + readFromS3('defillama-datasets', `yield-api/${p}`) + ) + ); + + if (!data) { + return new AppError("Couldn't retrieve data", 404); + } + + // pools == supply side apy values + const pools = data[0].data; + // lendBorrow == borrow side apy values + const lendBorrow = data[1]; + + // join supply side fields (all enriched fields) onto borrow object + const poolsBorrow = lendBorrow + .map((p) => { + const poolSupplySide = pools.find((i) => i.pool === p.pool); + if (poolSupplySide === undefined) return null; + + return { + ...poolSupplySide, + apyBaseBorrow: p.apyBaseBorrow, + apyRewardBorrow: p.apyRewardBorrow, + totalSupplyUsd: p.totalSupplyUsd, + totalBorrowUsd: p.totalBorrowUsd, + debtCeilingUsd: p.debtCeilingUsd, + ltv: p.ltv, + borrowable: p.borrowable, + mintedCoin: p.mintedCoin, + borrowFactor: p.borrowFactor, + rewardTokens: p.rewardTokens, + }; + }) + .filter(Boolean) + .sort((a, b) => b.totalSupplyUsd - a.totalSupplyUsd); + + res.status(200).json({ + status: 'success', + data: poolsBorrow, + }); +}; + +module.exports = { getPoolEnriched, getPoolsEnrichedPro, getPoolsBorrow }; diff --git a/src/api/controllers/lsd.js b/src/api/controllers/lsd.js new file mode 100644 index 0000000000..9a3366e71b --- /dev/null +++ b/src/api/controllers/lsd.js @@ -0,0 +1,34 @@ +const validator = require('validator'); +const minify = require('pg-minify'); + +const AppError = require('../../utils/appError'); +const { conn } = require('../db'); + +const getLsd = async (req, res) => { + const query = ` + SELECT + DISTINCT ON (address) + name, + symbol, + address, + type, + "expectedRate", + "marketRate", + "ethPeg", + fee + FROM + lsd + ORDER BY + address, + timestamp DESC + `; + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json(response); +}; + +module.exports = { getLsd }; diff --git a/src/api/controllers/median.js b/src/api/controllers/median.js new file mode 100644 index 0000000000..36eade8662 --- /dev/null +++ b/src/api/controllers/median.js @@ -0,0 +1,51 @@ +const AppError = require('../../utils/appError'); +const { conn } = require('../db'); + +const getMedian = async (req, res) => { + const query = ` + SELECT + timestamp, + "uniquePools", + "medianAPY" + FROM + median + ORDER BY + timestamp ASC + `; + + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json(response); +}; + +const getMedianProject = async (req, res) => { + const project = req.params.project; + const query = ` + SELECT + timestamp, + "medianAPY", + "uniquePools" + FROM + median_project + WHERE + project = $ + ORDER BY + timestamp ASC + `; + const response = await conn.query(query, { project }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +module.exports = { getMedian, getMedianProject }; diff --git a/src/api/controllers/perp.js b/src/api/controllers/perp.js new file mode 100644 index 0000000000..a6855137a3 --- /dev/null +++ b/src/api/controllers/perp.js @@ -0,0 +1,115 @@ +const validator = require('validator'); + +const AppError = require('../../utils/appError'); +const { conn } = require('../db'); + +// get latest data for each unique perp +const getPerp = async (req, res) => { + const query = ` + SELECT + perp_id, + "timestamp", + main.marketplace, + main.market, + "baseAsset", + "fundingRate", + "fundingRatePrevious", + "fundingTimePrevious", + "openInterest", + "indexPrice", + "fundingRate7dAverage", + "fundingRate7dSum", + "fundingRate30dAverage", + "fundingRate30dSum" + FROM + ( + SELECT + DISTINCT ON (marketplace, market) * + FROM + perpetual + WHERE + timestamp >= NOW() - INTERVAL '$ HOUR' + ORDER BY + marketplace, + market, + timestamp DESC + ) AS main + JOIN ( + SELECT + weeklyStats.marketplace, + weeklyStats.market, + "fundingRate7dAverage", + "fundingRate7dSum", + "fundingRate30dAverage", + "fundingRate30dSum" + FROM + ( + SELECT + marketplace, + market, + round(avg("fundingRatePrevious"), 10) AS "fundingRate7dAverage", + round(sum("fundingRatePrevious"), 10) AS "fundingRate7dSum" + FROM + ( + SELECT + DISTINCT ON (marketplace, market, "fundingTimePrevious") * + FROM + perpetual + WHERE + "fundingTimePrevious" IS NOT NULL + AND timestamp >= NOW() - INTERVAL '$ DAY' + ORDER BY + marketplace, + market, + "fundingTimePrevious" DESC + ) AS main + GROUP BY + marketplace, + market + ) AS weeklyStats + JOIN ( + SELECT + marketplace, + market, + round(avg("fundingRatePrevious"), 10) AS "fundingRate30dAverage", + round(sum("fundingRatePrevious"), 10) AS "fundingRate30dSum" + FROM + ( + SELECT + DISTINCT ON (marketplace, market, "fundingTimePrevious") * + FROM + perpetual + WHERE + "fundingTimePrevious" IS NOT NULL + AND timestamp >= NOW() - INTERVAL '$ DAY' + ORDER BY + marketplace, + market, + "fundingTimePrevious" DESC + ) AS main + GROUP BY + marketplace, + market + ) AS monthlyStats ON weeklyStats.marketplace = monthlyStats.marketplace + AND weeklyStats.market = monthlyStats.market + ) AS stats ON stats.marketplace = main.marketplace + AND stats.market = main.market + `; + + const response = await conn.query(query, { + age: 3, // last 3 hours + ageWeeklyStats: 7, + ageMonthlyStats: 30, + }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +module.exports = { getPerp }; diff --git a/src/api/controllers/risk.js b/src/api/controllers/risk.js new file mode 100644 index 0000000000..f8d47456a5 --- /dev/null +++ b/src/api/controllers/risk.js @@ -0,0 +1,70 @@ +const fetch = require('node-fetch'); + +const YIELD_RISK_API_EXPONENTIAL = + 'https://api.exponential.fi/api/pool-risk/search'; + +const getRiskRating = async (req, res) => { + try { + const poolData = req.query; + + // pool_old + at least one of the other fields are requried + if (!poolData.pool_old) { + return res.status(400).json({ + status: 'error', + message: 'pool_old is required', + }); + } + + const otherFields = ['chain', 'project', 'tvlUsd', 'underlyingTokens']; + const hasOtherField = otherFields.some((field) => poolData[field]); + + if (!hasOtherField) { + return res.status(400).json({ + status: 'error', + message: `At least one of ${otherFields.join(',')} must be provided`, + }); + } + + const response = await fetch(YIELD_RISK_API_EXPONENTIAL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-API-KEY': process.env.EXPONENTIAL_API_KEY, + }, + body: JSON.stringify({ + token_address: cleanPool(poolData.pool_old), + blockchain: poolData.chain?.toLowerCase(), + protocol: poolData.project, + tvl: poolData.tvlUsd, + assets: poolData.underlyingTokens, + }), + }); + const data = await response.json(); + res.status(200).json({ + status: 'success', + data, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + status: 'error', + message: error.message, + }); + } +}; + +function cleanPool(pool) { + // some pool fields contain chain (or other) info as prefix/suffix + // need to remove these parts from api call, otherwise we won't receive the total risk score + + // for 0x addresses + // match 0x followed by at least 40 hexadecimal characters balancer pool ids have length 64) + const pattern = /0x[a-fA-F0-9]{40,}/; + + const match = pool.match(pattern); + + // for non 0x addresses return pool as is + return match ? match[0] : pool; +} + +module.exports = { getRiskRating }; diff --git a/src/api/controllers/yield.js b/src/api/controllers/yield.js new file mode 100644 index 0000000000..6108178ee2 --- /dev/null +++ b/src/api/controllers/yield.js @@ -0,0 +1,172 @@ +const validator = require('validator'); + +const AppError = require('../../utils/appError'); +const { conn } = require('../db'); + +const getYieldHistory = async (req, res) => { + const configID = req.params.pool; + if (!validator.isUUID(configID)) + return res.status(400).json('invalid configID!'); + + const query = ` + SELECT + timestamp, + "tvlUsd", + apy, + "apyBase", + "apyReward", + "il7d", + "apyBase7d" + FROM + yield + WHERE + timestamp IN ( + SELECT + max(timestamp) + FROM + yield + WHERE + "configID" = $ + GROUP BY + (timestamp :: date) + ) + AND "configID" = $ + ORDER BY + timestamp ASC + `; + + const response = await conn.query(query, { configIDValue: configID }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +const getYieldHistoryHourly = async (req, res) => { + const configID = req.params.pool; + if (!validator.isUUID(configID)) + return res.status(400).json('invalid configID!'); + + const query = ` + SELECT + timestamp, + "tvlUsd", + apy, + "apyBase", + "apyReward", + "il7d", + "apyBase7d" + FROM + yield + WHERE + "configID" = $ + ORDER BY + timestamp ASC + `; + const response = await conn.query(query, { configIDValue: configID }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +const getYieldLendBorrowHistory = async (req, res) => { + const configID = req.params.pool; + if (!validator.isUUID(configID)) + return res.status(400).json('invalid configID!'); + + const query = ` + SELECT + timestamp, + "totalSupplyUsd", + "totalBorrowUsd", + "debtCeilingUsd", + "apyBase", + "apyReward", + "apyBaseBorrow", + "apyRewardBorrow" + FROM + yield + WHERE + timestamp IN ( + SELECT + max(timestamp) + FROM + yield + WHERE + "configID" = $ + GROUP BY + (timestamp :: date) + ) + AND "configID" = $ + ORDER BY + timestamp ASC + `; + const response = await conn.query(query, { configIDValue: configID }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +const getVolumeHistory = async (req, res) => { + const configID = req.params.pool; + if (!validator.isUUID(configID)) + return res.status(400).json('invalid configID!'); + + const query = ` + SELECT + timestamp, + "volumeUsd1d" + FROM + yield + WHERE + timestamp IN ( + SELECT + max(timestamp) + FROM + yield + WHERE + "configID" = $ + GROUP BY + (timestamp :: date) + ) + AND "configID" = $ + AND "volumeUsd1d" IS NOT NULL + ORDER BY + timestamp ASC + `; + + const response = await conn.query(query, { configIDValue: configID }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + res.status(200).json({ + status: 'success', + data: response, + }); +}; + +module.exports = { + getYieldHistory, + getYieldHistoryHourly, + getYieldLendBorrowHistory, + getVolumeHistory, +}; diff --git a/src/api/db.js b/src/api/db.js new file mode 100644 index 0000000000..7c15ffafc6 --- /dev/null +++ b/src/api/db.js @@ -0,0 +1,16 @@ +const pgp = require('pg-promise')({ + capSQL: true, +}); +const path = require('path'); +require('dotenv').config({ path: path.resolve(__dirname, '../../config.env') }); + +pgp.pg.types.setTypeParser(20, parseInt); +pgp.pg.types.setTypeParser(1700, parseFloat); + +const conn = pgp({ + connectionString: process.env.DATABASE_URL, + max: 5, + idleTimeoutMillis: 3000, +}); + +module.exports = { pgp, conn }; diff --git a/src/api/dbConnection.js b/src/api/dbConnection.js deleted file mode 100755 index d91c0cbb9e..0000000000 --- a/src/api/dbConnection.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require('mongoose'); -const SSM = require('aws-sdk/clients/ssm'); - -// on first connect, cache db connection for reuse so we don't -// need to connect on new requests -let conn = null; - -// https://mongoosejs.com/docs/lambda.html -// Because conn is in the global scope, Lambda may retain it between -// function calls thanks to `callbackWaitsForEmptyEventLoop`. -// This means your Lambda function doesn't have to go through the -// potentially expensive process of connecting to MongoDB every time. -exports.connect = async () => { - if (conn === null) { - console.log('using new db connection'); - - // 1) retrieve db connection secrets from SSM - const ssm = new SSM(); - const options = { - Name: `${process.env.SSM_PATH}/dbconnection`, - WithDecryption: true, - }; - let params = await ssm.getParameter(options).promise(); - params = JSON.parse(params.Parameter.Value); - - const DB = params.database.replace('', params.database_password); - // set conection - conn = mongoose - .connect(DB, { - useNewUrlParser: true, - useCreateIndex: true, - useFindAndModify: false, - useUnifiedTopology: true, - // and tell the MongoDB driver to not wait more than 5 seconds - // before erroring out if it isn't connected - serverSelectionTimeoutMS: 5000, - }) - .then(() => mongoose); - - // awaiting connection after assigning to the `conn` variable - // to avoid multiple function calls creating new connections - await conn; - } - - return conn; -}; diff --git a/src/api/routes/config.js b/src/api/routes/config.js new file mode 100644 index 0000000000..b2f2fa73e0 --- /dev/null +++ b/src/api/routes/config.js @@ -0,0 +1,10 @@ +const express = require('express'); +const router = express.Router(); +const config = require('../controllers/config'); + +router.route('/url').get(config.getUrl); +router.route('/distinctID').get(config.getDistinctID); +router.route('/configPool/:configID').get(config.getConfigPool); +router.route('/allPools').get(config.getAllPools); + +module.exports = router; diff --git a/src/api/routes/enriched.js b/src/api/routes/enriched.js new file mode 100644 index 0000000000..6e6d964edc --- /dev/null +++ b/src/api/routes/enriched.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const enriched = require('../controllers/enriched'); + +router.route('/poolsEnriched').get(enriched.getPoolEnriched); + +// PRO API routes +router.route('/poolsPro').get(enriched.getPoolsEnrichedPro); +router.route('/poolsOld').get((req, res, next) => { + res.set('Link', '; rel="successor-version"'); + res.set('X-Preferred-Route', '/poolsPro'); + res.set('X-Notice', 'Prefer /poolsPro; this alias remains available.'); + next(); +}, enriched.getPoolsEnrichedPro); // alias; prefer /poolsPro +router.route('/poolsBorrow').get(enriched.getPoolsBorrow); + +module.exports = router; diff --git a/src/api/routes/lsd.js b/src/api/routes/lsd.js new file mode 100644 index 0000000000..3e8253fcd6 --- /dev/null +++ b/src/api/routes/lsd.js @@ -0,0 +1,7 @@ +const express = require('express'); +const router = express.Router(); +const lsd = require('../controllers/lsd'); + +router.route('/lsdRates').get(lsd.getLsd); + +module.exports = router; diff --git a/src/api/routes/median.js b/src/api/routes/median.js new file mode 100644 index 0000000000..c2ce1e7be5 --- /dev/null +++ b/src/api/routes/median.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); +const median = require('../controllers/median'); + +router.route('/median').get(median.getMedian); +router.route('/medianProject/:project').get(median.getMedianProject); + +module.exports = router; diff --git a/src/api/routes/perp.js b/src/api/routes/perp.js new file mode 100644 index 0000000000..2ec078a4a1 --- /dev/null +++ b/src/api/routes/perp.js @@ -0,0 +1,7 @@ +const express = require('express'); +const router = express.Router(); +const perp = require('../controllers/perp'); + +router.route('/perps').get(perp.getPerp); + +module.exports = router; diff --git a/src/api/routes/risk.js b/src/api/routes/risk.js new file mode 100644 index 0000000000..735fba8665 --- /dev/null +++ b/src/api/routes/risk.js @@ -0,0 +1,7 @@ +const express = require('express'); +const router = express.Router(); +const risk = require('../controllers/risk'); + +router.route('/risk').get(risk.getRiskRating); + +module.exports = router; diff --git a/src/api/routes/yield.js b/src/api/routes/yield.js new file mode 100644 index 0000000000..e95c87adc2 --- /dev/null +++ b/src/api/routes/yield.js @@ -0,0 +1,10 @@ +const express = require('express'); +const router = express.Router(); +const yieldControllers = require('../controllers/yield'); + +router.route('/chart/:pool').get(yieldControllers.getYieldHistory); +router.route('/chartHourly/:pool').get(yieldControllers.getYieldHistoryHourly); +router.route('/chartLendBorrow/:pool').get(yieldControllers.getYieldLendBorrowHistory); +router.route('/volume/:pool').get(yieldControllers.getVolumeHistory); + +module.exports = router; diff --git a/src/api/server.js b/src/api/server.js new file mode 100644 index 0000000000..c5c4743c5c --- /dev/null +++ b/src/api/server.js @@ -0,0 +1,5 @@ +const app = require('./app'); +const port = process.env.PORT || 3000; +app.listen(port, () => { + console.log(`Server listening on port ${port}`); +}); diff --git a/src/handlers/deletePools.js b/src/handlers/deletePools.js deleted file mode 100644 index 92eae8438d..0000000000 --- a/src/handlers/deletePools.js +++ /dev/null @@ -1,33 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const poolModel = require('../models/pool'); -const AppError = require('../utils/appError'); - -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - const conn = await dbConnection.connect(); - const M = conn.model(poolModel.modelName); - - const timestamp = Number(event.pathParameters.timestamp); - const lb = new Date(timestamp * 1000); - const ub = new Date((timestamp + 86400) * 1000); - - // we filter to a project and the current timestamp from midnight up to the next day midnight - // eg timestamp 1649116800 == 2022-04-05T00:00:00.000Z - // lb == 2022-04-05T00:00:00.000Z; ub == 2022-04-06T00:00:00.000Z - // we remove everything >= lb up to < ub - const filter = { - project: event.pathParameters.project, - timestamp: { $gte: lb, $lt: ub }, - }; - - const response = await M.deleteMany(filter); - - if (!response) { - return new AppError("Couldn't delete data", 404); - } - - return { - status: 'success', - response, - }; -}; diff --git a/src/handlers/getChart.js b/src/handlers/getChart.js deleted file mode 100644 index 1a190546b4..0000000000 --- a/src/handlers/getChart.js +++ /dev/null @@ -1,70 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const poolModel = require('../models/pool'); -const AppError = require('../utils/appError'); - -// retrieve chart data of latest daily tvl and apy values of requested pool -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - - const conn = await dbConnection.connect(); - const M = conn.model(poolModel.modelName); - - const pool = event.pathParameters.pool; - - const aggQuery = [ - { - $match: { - pool: pool, - }, - }, - { - $sort: { - timestamp: -1, - }, - }, - { - $group: { - _id: { - $toDate: { - $subtract: [ - { $toLong: '$timestamp' }, - { $mod: [{ $toLong: '$timestamp' }, 86400000] }, - ], - }, - }, - apy: { - $first: '$apy', - }, - tvlUsd: { - $first: '$tvlUsd', - }, - timestamp: { - $first: '$timestamp', - }, - }, - }, - // remove the grouping key - { - $project: { - _id: 0, - }, - }, - { - $sort: { - timestamp: 1, - }, - }, - ]; - - const query = M.aggregate(aggQuery); - const response = await query; - - if (!response) { - return new AppError("Couldn't retrieve data", 404); - } - - return { - status: 'sucess', - data: response, - }; -}; diff --git a/src/handlers/getOffsets.js b/src/handlers/getOffsets.js deleted file mode 100644 index 95b5af554d..0000000000 --- a/src/handlers/getOffsets.js +++ /dev/null @@ -1,88 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const poolModel = require('../models/pool'); -const AppError = require('../utils/appError'); - -// retrieve the historical offset data for a project and a given offset day (1d/7d/30d) -// to calculate pct changes. allow some buffer (+/- 3hs) in case of missing data -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - const conn = await dbConnection.connect(); - const M = conn.model(poolModel.modelName); - - const daysMilliSeconds = - Number(event.pathParameters.days) * 60 * 60 * 24 * 1000; - const tOffset = Date.now() - daysMilliSeconds; - - // 3 hour window - const h = 3; - const tWindow = 60 * 60 * h * 1000; - // mongoose query requires Date - const recent = new Date(tOffset + tWindow); - const oldest = new Date(tOffset - tWindow); - - // pull only data >= 10k usd in tvl (we won't show smaller pools on the frontend) - const tvlUsdLB = 1e4; - - const aggQuery = [ - // filter - { - $match: { - project: event.pathParameters.project, - timestamp: { - $gte: oldest, - $lte: recent, - }, - tvlUsd: { $gte: tvlUsdLB }, - }, - }, - // calc time distances from exact offset - { - $addFields: { - time_dist: { - $abs: [{ $subtract: ['$timestamp', new Date(tOffset)] }], - }, - }, - }, - // sort ascending (the smallest distance are the closest data points to the exact offset) - { - $sort: { time_dist: 1 }, - }, - // group by id, and return the first sample of apy - { - $group: { - _id: '$pool', - apy: { - $first: '$apy', - }, - }, - }, - // adding "back" the pool field, the grouping key is only available as _id - { - $addFields: { - pool: '$_id', - }, - }, - // remove the grouping key - { - $project: { - _id: 0, - }, - }, - ]; - const query = M.aggregate(aggQuery); - - // run query on db server - const response = await query; - - if (!response) { - return new AppError("Couldn't retrieve data", 404); - } - - return { - status: 'sucess', - data: { - timestampExact: tOffset, - offsets: response, - }, - }; -}; diff --git a/src/handlers/getPools.js b/src/handlers/getPools.js deleted file mode 100644 index b2f4cfe48b..0000000000 --- a/src/handlers/getPools.js +++ /dev/null @@ -1,87 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const poolModel = require('../models/pool'); -const AppError = require('../utils/appError'); - -// get latest object of each unique pool -module.exports.handler = async (event, context, callback) => { - // Make sure to add this so you can re-use `conn` between function calls. - // See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas - context.callbackWaitsForEmptyEventLoop = false; - - // create/use existing connection - const conn = await dbConnection.connect(); - - const M = conn.model(poolModel.modelName); - - // pull only data >= 10k usd in tvl (we won't show smaller pools on the frontend) - const tvlUsdLB = 1e4; - - // query consists of stages: - // 1. match tvlUSd >= $10k - // 2. sort entries by timestamp in descending order - // 3. group by the pool returned the first objects fields - // 4. sort again on tvl desc - const aggQuery = [ - { - $sort: { - pool: 1, - timestamp: -1, - }, - }, - { - $group: { - _id: '$pool', - chain: { - $first: '$chain', - }, - project: { - $first: '$project', - }, - symbol: { - $first: '$symbol', - }, - tvlUsd: { - $first: '$tvlUsd', - }, - apy: { - $first: '$apy', - }, - timestamp: { - $first: '$timestamp', - }, - }, - }, - // sort on tvl desc - { - $sort: { - tvlUsd: -1, - }, - }, - // adding "back" the pool field, the grouping key is only available as _id - { - $addFields: { - pool: '$_id', - }, - }, - // remove the _id field - { - $project: { - _id: 0, - }, - }, - // finally, remove pools below the tvl threshold - { $match: { tvlUsd: { $gte: tvlUsdLB } } }, - ]; - - const query = M.aggregate(aggQuery); - const response = await query; - - if (!response) { - return new AppError("Couldn't retrieve data", 404); - } - - return { - status: 'sucess', - data: response, - }; -}; diff --git a/src/handlers/getPoolsEnriched.js b/src/handlers/getPoolsEnriched.js deleted file mode 100644 index 1a4a40675a..0000000000 --- a/src/handlers/getPoolsEnriched.js +++ /dev/null @@ -1,131 +0,0 @@ -const S3 = require('aws-sdk/clients/s3'); - -const AppError = require('../utils/appError'); - -// returns enriched pool data -module.exports.handler = async (event, context, callback) => { - const response = await main(event.queryStringParameters); - - if (!response) { - return new AppError("Couldn't retrieve data", 404); - } - - return { - status: 'success', - data: response, - }; -}; - -const main = async (queryString) => { - const columns = [ - 'chain', - 'project', - 'symbol', - 'tvlUsd', - 'apy', - 'pool', - 'apyPct1D', - 'apyPct7D', - 'apyPct30D', - 'projectName', - 'stablecoin', - 'ilRisk', - 'exposure', - 'predictions', - 'audits', - 'audit_links', - 'url', - 'twitter', - 'category', - 'market', - ] - .map((el) => `t."${el}"`) - .join(', '); - - let query = `SELECT ${columns} FROM s3object[*][*] t`; - - if (queryString !== undefined) { - query = `${query} where t.${Object.keys(queryString)[0]}='${ - Object.values(queryString)[0] - }'`; - } - - const params = { - Bucket: 'llama-apy-prod-data', - Key: 'enriched/dataEnriched.json', - ExpressionType: 'SQL', - Expression: query, - InputSerialization: { - JSON: { - Type: 'DOCUMENT', - }, - }, - OutputSerialization: { - JSON: { - RecordDelimiter: ',', - }, - }, - }; - - let data = await getDataUsingS3Select(params); - // rook requires an adaptor change, we going to remove it from the enriched - // dataset for now - data = data.filter((el) => el.project !== 'rook'); - - return data; -}; - -const getDataUsingS3Select = async (params) => { - const s3 = new S3(); - - return new Promise((resolve, reject) => { - s3.selectObjectContent(params, (err, data) => { - if (err) { - reject(err); - } - - if (!data) { - reject('Empty data object'); - } - - // This will be an array of bytes of data, to be converted - // to a buffer - const records = []; - - // This is a stream of events - data.Payload.on('data', (event) => { - // There are multiple events in the eventStream, but all we - // care about are Records events. If the event is a Records - // event, there is data inside it - if (event.Records) { - records.push(event.Records.Payload); - } - }) - .on('error', (err) => { - reject(err); - }) - .on('end', () => { - // Convert the array of bytes into a buffer, and then - // convert that to a string - let X = Buffer.concat(records).toString('utf8'); - - // remove any trailing commas - X = X.replace(/\,$/, ''); - - // Add into JSON 'array' - X = `[${X}]`; - - try { - const out = JSON.parse(X); - resolve(out); - } catch (e) { - reject( - new Error( - `Unable to convert S3 data to JSON object. S3 Select Query: ${params.Expression}` - ) - ); - } - }); - }); - }); -}; diff --git a/src/handlers/getStds.js b/src/handlers/getStds.js deleted file mode 100644 index 6a1b992791..0000000000 --- a/src/handlers/getStds.js +++ /dev/null @@ -1,21 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const stdModel = require('../models/std'); -const AppError = require('../utils/appError'); - -// get expanding standard deviation data -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - const conn = await dbConnection.connect(); - const M = conn.model(stdModel.modelName); - - const response = await M.find({}, { _id: 0, createdAt: 0, updatedAt: 0 }); - - if (!response) { - return new AppError("Couldn't get std data", 404); - } - - return { - status: 'success', - data: response, - }; -}; diff --git a/src/handlers/storePools.js b/src/handlers/storePools.js deleted file mode 100644 index 73f58d6db0..0000000000 --- a/src/handlers/storePools.js +++ /dev/null @@ -1,23 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const poolModel = require('../models/pool'); -const AppError = require('../utils/appError'); - -// insert pools -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - const conn = await dbConnection.connect(); - const M = conn.model(poolModel.modelName); - - const payload = JSON.parse(event.body); - - const response = await M.insertMany(payload); - - if (!response) { - return new AppError("Couldn't update data", 404); - } - - return { - status: 'success', - response: `Inserted ${payload.length} samples`, - }; -}; diff --git a/src/handlers/storeStds.js b/src/handlers/storeStds.js deleted file mode 100644 index 27c113b0d3..0000000000 --- a/src/handlers/storeStds.js +++ /dev/null @@ -1,34 +0,0 @@ -const dbConnection = require('../api/dbConnection.js'); -const stdModel = require('../models/std'); -const AppError = require('../utils/appError'); - -// get standard deviation -module.exports.handler = async (event, context, callback) => { - context.callbackWaitsForEmptyEventLoop = false; - const conn = await dbConnection.connect(); - const M = conn.model(stdModel.modelName); - - const payload = JSON.parse(event.body); - - // updating via bulkwrite with array of updateOne operations - const bulkOperations = []; - for (const el of payload) { - bulkOperations.push({ - updateOne: { - filter: { pool: el.pool }, - update: { $set: { count: el.count, mean: el.mean, mean2: el.mean2 } }, - upsert: true, - }, - }); - } - const response = await M.bulkWrite(bulkOperations); - - if (!response) { - return new AppError("Couldn't update data", 404); - } - - return { - status: 'success', - response, - }; -}; diff --git a/src/handlers/triggerAdaptor.js b/src/handlers/triggerAdaptor.js index ca6b1dd273..827137607e 100644 --- a/src/handlers/triggerAdaptor.js +++ b/src/handlers/triggerAdaptor.js @@ -1,13 +1,25 @@ +const crypto = require('crypto'); + const superagent = require('superagent'); -const SSM = require('aws-sdk/clients/ssm'); -const utils = require('../utils/s3'); +const utils = require('../adaptors/utils'); +const AppError = require('../utils/appError'); +const exclude = require('../utils/exclude'); +const { sendMessage } = require('../utils/discordWebhook'); +const { connect } = require('../utils/dbConnection'); +const { getYieldProject, buildInsertYieldQuery } = require('../queries/yield'); +const { + getConfigProject, + buildInsertConfigQuery, + getDistinctProjects, +} = require('../queries/config'); -module.exports.handler = async (event) => { +module.exports.handler = async (event, context) => { + context.callbackWaitsForEmptyEventLoop = false; console.log(event); // We return failed msg ids, - // so that only failed messages will be retried by SQS in case of min of 1 error in batch + // so that only failed messages will be retried by SQS in case of min of 1 error init batch // https://www.serverless.com/blog/improved-sqs-batch-error-handling-with-aws-lambda const failedMessageIds = []; @@ -29,48 +41,469 @@ module.exports.handler = async (event) => { }; }; -// func for running adaptor, storing result to db (filtered) and s3 (unfiltered) +// func for running adaptor, storing result to db const main = async (body) => { - // run adaptor + // ---------- run adaptor console.log(body.adaptor); - const project = require(`../adaptors/${body.adaptor}/index.js`); + const project = require(`../adaptors/${body.adaptor}`); let data = await project.apy(); + console.log(data[0]); + + const protocolConfig = ( + await superagent.get('https://api.llama.fi/config/yields?a=1') + ).body.protocols; + + // ---------- prepare prior insert + // remove potential null/undefined objects in array + data = data.filter((p) => p); + + // cast dtypes + // even though we have tests for datatypes, will need to guard against sudden changes + // from api responses in terms of data types (eg have seen this on lido stETH) which went from + // number to string. so in order for the below filters to work proplerly we need to guarantee that the + // datatypes are correct (on db insert, mongoose checks field types against the schema and the bulk insert + // will fail if a pools field types doesnt match) + const strToNum = (val) => (typeof val === 'string' ? Number(val) : val); + data = data.map((p) => ({ + ...p, + apy: strToNum(p.apy), + apyBase: strToNum(p.apyBase), + apyReward: strToNum(p.apyReward), + apyBaseBorrow: strToNum(p.apyBaseBorrow), + apyRewardBorrow: strToNum(p.apyRewardBorrow), + apyBase7d: strToNum(p.apyBase7d), + apyRewardFake: strToNum(p.apyRewardFake), + apyRewardBorrowFake: strToNum(p.apyRewardBorrowFake), + apyBaseInception: strToNum(p.apyBaseInception), + })); - // add the timestamp field - // will be rounded to the nearest hour - // eg 2022-04-06T10:00:00.000Z - const timestamp = new Date( - Math.floor(Date.now() / 1000 / 60 / 60) * 60 * 60 * 1000 + // filter tvl to be btw lb-ub (except GHO borrow pool on aave-v3 (has a constant tvlUsd of 0 cause can't be used as collateral)) + data = data.filter( + (p) => + (p.tvlUsd >= exclude.boundaries.tvlUsdDB.lb && + p.tvlUsd <= exclude.boundaries.tvlUsdDB.ub) || + (p.project === 'aave-v3' && p.symbol === 'GHO') ); - for (const d of data) { - d['timestamp'] = timestamp; + + // nullify NaN, undefined or Infinity apy values + data = data.map((p) => ({ + ...p, + apy: Number.isFinite(p.apy) ? p.apy : null, + apyBase: Number.isFinite(p.apyBase) ? p.apyBase : null, + apyReward: Number.isFinite(p.apyReward) ? p.apyReward : null, + apyBaseBorrow: Number.isFinite(p.apyBaseBorrow) ? p.apyBaseBorrow : null, + apyRewardBorrow: Number.isFinite(p.apyRewardBorrow) + ? p.apyRewardBorrow + : null, + apyBase7d: Number.isFinite(p.apyBase7d) ? p.apyBase7d : null, + apyRewardFake: Number.isFinite(p.apyRewardFake) ? p.apyRewardFake : null, + apyRewardBorrowFake: Number.isFinite(p.apyRewardBorrowFake) + ? p.apyRewardBorrowFake + : null, + apyBaseInception: Number.isFinite(p.apyBaseInception) + ? p.apyBaseInception + : null, + })); + + // remove pools where all 3 apy related fields are null + data = data.filter( + (p) => !(p.apy === null && p.apyBase === null && p.apyReward === null) + ); + + // in case of negative apy values (cause of bug, or else we set those to 0) + // note: for options apyBase can be negative + data = data.map((p) => ({ + ...p, + apy: p.apy < 0 ? 0 : p.apy, + apyBase: + protocolConfig[body.adaptor]?.category === 'Options' || + ['mellow-protocol', 'sommelier', 'abracadabra', 'resolv'].includes( + body.adaptor + ) + ? p.apyBase + : p.apyBase < 0 + ? 0 + : p.apyBase, + apyReward: p.apyReward < 0 ? 0 : p.apyReward, + apyBaseBorrow: p.apyBaseBorrow < 0 ? 0 : p.apyBaseBorrow, + apyRewardBorrow: p.apyRewardBorrow < 0 ? 0 : p.apyRewardBorrow, + apyBase7d: p.apyBase7d < 0 ? 0 : p.apyBase7d, + apyRewardFake: p.apyRewardFake < 0 ? 0 : p.apyRewardFake, + apyRewardBorrowFake: p.apyRewardBorrowFake < 0 ? 0 : p.apyRewardBorrowFake, + })); + + // derive final total apy field + data = data.map((p) => ({ + ...p, + apy: + // in case all three fields are given (which is redundant cause we calc the sum here), + // we recalculate the total apy. reason: this takes into account any of the above 0 clips + // which will result in a different sum than the adaptors output + // (only applicable if all 3 fields are provided in the adapter + // and if apBase and or apyReward < 0) + p.apy !== null && p.apyBase !== null && p.apyReward !== null + ? p.apyBase + p.apyReward + : // all other cases for which we compute the sum only if apy is null/undefined + p.apy ?? p.apyBase + p.apyReward, + })); + + // remove pools based on apy boundaries + data = data.filter( + (p) => + p.apy !== null && + p.apy >= exclude.boundaries.apy.lb && + p.apy <= exclude.boundaries.apy.ub + ); + + // remove exclusion pools + data = data.filter((p) => !exclude.excludePools.includes(p.pool)); + + // format chain symbol + data = data.map((p) => ({ ...p, chain: utils.formatChain(p.chain) })); + // change chain `Binance` -> `BSC` + data = data.map((p) => ({ + ...p, + chain: + p.chain === 'Binance' + ? 'BSC' + : p.chain === 'Avax' + ? 'Avalanche' + : p.chain, + })); + console.log(data.length); + + // ---- add IL (only for dexes + pools with underlyingTokens array) + // need the protocol response to check if adapter.body === 'Dexes' category + + // required conditions to calculate IL field + const isUniV3Fork = data.filter((i) => + i.poolMeta?.includes('stablePool=') + ).length; + + if ( + data[0]?.underlyingTokens?.length && + protocolConfig[body.adaptor]?.category === 'Dexes' && + !['balancer-v2', 'curve-dex', 'clipper', 'astroport', 'cetus-amm'].includes( + body.adaptor + ) && + !['elrond', 'near', 'hedera', 'carbon'].includes( + data[0].chain.toLowerCase() + ) + ) { + // extract all unique underlyingTokens + const uniqueToken = [ + ...new Set( + data + .map((p) => p.underlyingTokens?.map((t) => `${p.chain}:${t}`)) + .flat() + ), + ].filter(Boolean); + + // prices now + const priceUrl = 'https://coins.llama.fi/prices'; + const prices = ( + await utils.getData(priceUrl, { + coins: uniqueToken, + }) + ).coins; + + const timestamp7daysAgo = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60; + // price endpoint seems to break with too many tokens, splitting it to max 150 per request + const maxSize = 100; + const pages = Math.ceil(uniqueToken.length / maxSize); + let prices7d_ = []; + let x = ''; + for (const p of [...Array(pages).keys()]) { + x = uniqueToken.slice(p * maxSize, maxSize * (p + 1)).join(','); + prices7d_ = [ + ...prices7d_, + ( + await superagent.get( + `https://coins.llama.fi/prices/historical/${timestamp7daysAgo}/${x}` + ) + ).body.coins, + ]; + } + // flatten + let prices7d = {}; + for (const p of prices7d_.flat()) { + prices7d = { ...prices7d, ...p }; + } + prices7d = Object.fromEntries( + Object.entries(prices7d).map(([k, v]) => [k.toLowerCase(), v]) + ); + + // calc IL + data = data.map((p) => { + if (p?.underlyingTokens === null || p?.underlyingTokens === undefined) + return { ...p }; + // extract prices + const token0 = `${p.chain}:${p.underlyingTokens[0]}`.toLowerCase(); + const token1 = `${p.chain}:${p.underlyingTokens[1]}`.toLowerCase(); + + // now + const price0 = prices[token0]?.price; + const price1 = prices[token1]?.price; + + // 7 days ago + const price0_7d = prices7d[token0]?.price; + const price1_7d = prices7d[token1]?.price; + + // relative price changes + const pctChangeX = (price0 - price0_7d) / price0_7d; + const pctChangeY = (price1 - price1_7d) / price1_7d; + + // return in case of missing/weird prices + if (!Number.isFinite(pctChangeX) || !Number.isFinite(pctChangeY)) + return { ...p }; + + // d paramter (P1 / P0) + const d = (1 + pctChangeX) / (1 + pctChangeY); + + // IL(d) + let il7d = ((2 * Math.sqrt(d)) / (1 + d) - 1) * 100; + + // for uni v3 + if (isUniV3Fork) { + const P = price1 / price0; + + // for stablecoin pools, we assume a +/- 0.1% range around current price + // for non-stablecoin pools -> +/- 30% + const pct = 0.3; + const pctStablePool = 0.001; + const delta = p.poolMeta.includes('stablePool=true') + ? pctStablePool + : pct; + + const [p_lb, p_ub] = [P * (1 - delta), P * (1 + delta)]; + + // https://medium.com/auditless/impermanent-loss-in-uniswap-v3-6c7161d3b445 + // ilv3 = ilv2 * factor + const factor = + 1 / (1 - (Math.sqrt(p_lb / P) + d * Math.sqrt(P / p_ub)) / (1 + d)); + + // scale IL by factor + il7d *= factor; + // if the factor is too large, it may result in IL values >100% which don't make sense + // -> clip to max -100% IL + il7d = il7d < 0 ? Math.max(il7d, -100) : il7d; + } + + return { + ...p, + il7d, + }; + }); + } + + // for PK, FK, read data from config table + const config = await getConfigProject(body.adaptor); + const mapping = {}; + for (const c of config) { + // the pool fields are used to map to the config_id values from the config table + mapping[c.pool] = c.config_id; } - // filter to $1k usd tvl - const tvlMinThr = 1e3; - dataDB = data.filter((el) => el.tvlUsd >= tvlMinThr); - console.log('saving data to DB'); + // we round numerical fields to 5 decimals after the comma + const precision = 5; + const timestamp = new Date(Date.now()); + data = data.map((p) => { + // if pool not in mapping -> its a new pool -> create a new uuid, else keep existing one + const id = mapping[p.pool] ?? crypto.randomUUID(); + return { + ...p, + config_id: id, // config PK field + configID: id, // yield FK field referencing config_id in config + symbol: ['usdc+', 'eth+', 'usdex+', 'usd0++', 'arb++'].some((i) => + p.symbol.toLowerCase().includes(i) + ) + ? p.symbol + : utils.formatSymbol(p.symbol), + tvlUsd: Math.round(p.tvlUsd), // round tvlUsd to integer and apy fields to n-dec + apy: +p.apy.toFixed(precision), // round apy fields + apyBase: p.apyBase !== null ? +p.apyBase.toFixed(precision) : p.apyBase, + apyReward: + p.apyReward !== null ? +p.apyReward.toFixed(precision) : p.apyReward, + url: p.url ?? project.url, + timestamp, + apyBaseBorrow: + p.apyBaseBorrow !== null + ? +p.apyBaseBorrow.toFixed(precision) + : p.apyBaseBorrow, + apyRewardBorrow: + p.apyRewardBorrow !== null + ? +p.apyRewardBorrow.toFixed(precision) + : p.apyRewardBorrow, + totalSupplyUsd: + p.totalSupplyUsd === undefined || p.totalSupplyUsd === null + ? null + : Math.round(p.totalSupplyUsd), + totalBorrowUsd: + p.totalBorrowUsd === undefined || p.totalBorrowUsd === null + ? null + : Math.round(p.totalBorrowUsd), + debtCeilingUsd: + p.debtCeilingUsd === undefined || p.debtCeilingUsd === null + ? null + : Math.round(p.debtCeilingUsd), + mintedCoin: p.mintedCoin ? utils.formatSymbol(p.mintedCoin) : null, + poolMeta: + p.poolMeta === undefined + ? null + : p.poolMeta?.includes('stablePool=') + ? p.poolMeta?.split(',')[0] + : p.poolMeta, + il7d: p.il7d ? +p.il7d.toFixed(precision) : null, + apyBase7d: + p.apyBase7d !== null ? +p.apyBase7d.toFixed(precision) : p.apyBase7d, + apyRewardFake: + p.apyRewardFake !== null + ? +p.apyRewardFake.toFixed(precision) + : p.apyRewardFake, + apyRewardBorrowFake: + p.apyRewardBorrowFake !== null + ? +p.apyRewardBorrowFake.toFixed(precision) + : p.apyRewardBorrowFake, + volumeUsd1d: + p.volumeUsd1d >= 0 + ? +parseFloat(p.volumeUsd1d).toFixed(precision) + : null, + volumeUsd7d: + p.volumeUsd7d >= 0 + ? +parseFloat(p.volumeUsd7d).toFixed(precision) + : null, + apyBaseInception: p.apyBaseInception + ? +p.apyBaseInception.toFixed(precision) + : null, + }; + }); - // get cached access token - const ssm = new SSM(); - const options = { - Name: `${process.env.SSM_PATH}/bearertoken`, - WithDecryption: true, - }; - const token = await ssm.getParameter(options).promise(); - // save to db - const response = await superagent - .post(`${process.env.APIG_URL}/pools`) - .send(dataDB) - .set({ Authorization: `Bearer ${token.Parameter.Value}` }); - console.log(response.body); - - // save unfiltered backup to s3 - console.log('saving data to S3'); - const d = new Date(); - const dd = d.toISOString().split('T'); - const bucket = process.env.BUCKET_DATA; - const key = `base/${dd[0]}/${d.getHours()}/${dd[1]}_${body.adaptor}.json`; - - await utils.writeToS3(bucket, key, data); + // ---------- tvl spike check + // prior insert, we run a tvl check to make sure + // that there haven't been any sudden spikes in tvl compared to the previous insert; + // insert only if tvl conditions are ok: + // if tvl + // - has increased >10x since the last hourly update + // - and has been updated in the last 5 hours + // -> block update + + // load last entries for each pool for this sepcific adapter + const dataInitial = await getYieldProject(body.adaptor); + + const dataDB = []; + const nHours = 5; + const tvlDeltaMultiplier = 5; + const apyDeltaMultiplier = tvlDeltaMultiplier; + const timedeltaLimit = 60 * 60 * nHours * 1000; + const droppedPools = []; + for (const p of data) { + const x = dataInitial.find((e) => e.configID === p.configID); + if (x === undefined) { + dataDB.push(p); + continue; + } + // if existing pool, check conditions + const timedelta = timestamp - x.timestamp; + // skip the update if tvl or apy at t is ntimes larger than tvl at t-1 && timedelta condition is met + if ( + (p.tvlUsd > x.tvlUsd * tvlDeltaMultiplier || + p.apy > x.apy * apyDeltaMultiplier) && + timedelta < timedeltaLimit + ) { + console.log(`removing pool ${p.pool}`); + droppedPools.push({ + configID: p.configID, + symbol: p.symbol, + project: p.project, + tvlUsd: p.tvlUsd, + tvlUsdDB: x.tvlUsd, + tvlMultiplier: p.tvlUsd / x.tvlUsd, + apy: p.apy, + apyDB: x.apy, + apyMultiplier: p.apy / x.apy, + }); + continue; + } + dataDB.push(p); + } + // return if dataDB is empty; + if (!dataDB.length) return; + + // send msg to discord if tvl spikes + const delta = data.length - dataDB.length; + if (delta > 0) { + console.log(`removed ${delta} sample(s) prior to insert`); + // send discord message + // we limit sending msg only if the pool's last tvlUsd value is >= $50k + const filteredPools = droppedPools.filter( + (p) => p.tvlUsdDB >= 5e4 && p.apyDB >= 10 + ); + if (filteredPools.length) { + const message = filteredPools + .map((p) => + p.apyMultiplier >= apyDeltaMultiplier + ? `APY spike for configID: ${ + p.configID + } from ${p.apyDB.toFixed()} to ${p.apy.toFixed()} (${p.apyMultiplier.toFixed( + 2 + )}x increase) [tvlUsd: ${p.tvlUsd.toFixed()}] + ` + : `TVL spike for configID: ${ + p.configID + } from ${p.tvlUsdDB.toFixed()} to ${p.tvlUsd.toFixed()} (${p.tvlMultiplier.toFixed( + 2 + )}x increase) + ` + ) + .join('\n'); + await sendMessage(message, process.env.TVL_SPIKE_WEBHOOK); + } + } + + // ---------- discord bot for newly added projects + const distinctProjects = await getDistinctProjects(); + if ( + !distinctProjects.includes(body.adaptor) && + dataDB.filter(({ tvlUsd }) => tvlUsd > exclude.boundaries.tvlUsdUI.lb) + .length + ) { + const message = `Project ${body.adaptor} yields have been added`; + await sendMessage(message, process.env.NEW_YIELDS_WEBHOOK); + } + + // ---------- DB INSERT + const response = await insertConfigYieldTransaction(dataDB); + console.log(response); +}; + +// --------- transaction query +const insertConfigYieldTransaction = async (payload) => { + const conn = await connect(); + + // build queries + const configQ = buildInsertConfigQuery(payload); + const yieldQ = buildInsertYieldQuery(payload); + + return conn + .tx(async (t) => { + // sequence of queries: + // 1. config: insert/update + const q1 = await t.result(configQ); + // 2. yield: insert + const q2 = await t.result(yieldQ); + + return [q1, q2]; + }) + .then((response) => { + // success, COMMIT was executed + return { + status: 'success', + data: response, + }; + }) + .catch((err) => { + // failure, ROLLBACK was executed + console.log(err); + return new AppError('ConfigYield Transaction failed, rolling back', 404); + }); }; diff --git a/src/handlers/triggerAuthenticate.js b/src/handlers/triggerAuthenticate.js deleted file mode 100644 index b61ab42c33..0000000000 --- a/src/handlers/triggerAuthenticate.js +++ /dev/null @@ -1,42 +0,0 @@ -const superagent = require('superagent'); -const SSM = require('aws-sdk/clients/ssm'); - -module.exports.handler = async (event) => { - await updateBearerToken(); -}; - -// updating auth0 bearer token and storing to SSM -const updateBearerToken = async () => { - console.log(`UPDATE BEARER TOKEN at ${new Date()}`); - const baseString = process.env.SSM_PATH; - - const ssm = new SSM(); - - // read the parameters which are required for auth0 token generation - let params = await ssm - .getParameter({ - Name: `${baseString}/auth0parameters`, - WithDecryption: true, - }) - .promise(); - params = JSON.parse(params.Parameter.Value); - - // make a post request to the auth0 provider - const data = { - client_id: params.client_id, - client_secret: params.client_secret, - audience: params.audience, - grant_type: params.grant_type, - }; - const token = await superagent.post(params.auth0_post_request_url).send(data); - - // update new bearer token to SSM - await ssm - .putParameter({ - Name: `${baseString}/bearertoken`, - Type: 'SecureString', // encrypt - Value: token.body.access_token, - Overwrite: true, - }) - .promise(); -}; diff --git a/src/handlers/triggerCsv.js b/src/handlers/triggerCsv.js new file mode 100644 index 0000000000..c67e2fa449 --- /dev/null +++ b/src/handlers/triggerCsv.js @@ -0,0 +1,46 @@ +const AWS = require('aws-sdk'); +const createCsvStringifier = require('csv-writer').createObjectCsvStringifier; + +const utils = require('../utils/s3'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + let poolsEnriched = ( + await utils.readFromS3('defillama-datasets', 'yield-api/pools') + ).data; + + // parse nested prediction field into separate fields + poolsEnriched = poolsEnriched.map((p) => ({ + ...p, + predictedClass: p['predictions']['predictedClass'], + predictedConfidence: p['predictions']['predictedProbability'], + binnedConfidence: p['predictions']['binnedConfidence'], + })); + + // remove predictions field + poolsEnriched = poolsEnriched.map(({ predictions, ...item }) => item); + + const csvStringifier = createCsvStringifier({ + header: Object.keys(poolsEnriched[0]).map((c) => ({ id: c, title: c })), + }); + + const headerString = csvStringifier.getHeaderString(); + const body = csvStringifier.stringifyRecords(poolsEnriched); + const csv = headerString + body; + + const params = { + Bucket: 'defillama-datasets', + Key: 'yields/yield_rankings.csv', + ACL: 'public-read', + Body: csv, + ContentType: 'text/csv', + }; + + const s3 = new AWS.S3(); + const resp = await s3.upload(params).promise(); + const msg = `saved to ${resp.Location}`; + console.log(msg); +}; diff --git a/src/handlers/triggerEnrichment.js b/src/handlers/triggerEnrichment.js index 56256d20cc..d97f28409b 100644 --- a/src/handlers/triggerEnrichment.js +++ b/src/handlers/triggerEnrichment.js @@ -1,51 +1,79 @@ const superagent = require('superagent'); -const SSM = require('aws-sdk/clients/ssm'); const ss = require('simple-statistics'); const utils = require('../utils/s3'); -const { el } = require('date-fns/locale'); - -module.exports.handler = async (event) => { +const { + getYieldFiltered, + getLatestYieldForPool, + getYieldOffset, + getYieldAvg30d, + getYieldLendBorrow, +} = require('../queries/yield'); +const { getStat } = require('../queries/stat'); +const { welfordUpdate } = require('../utils/welford'); +const poolsResponseColumns = require('../utils/enrichedColumns'); +const { getExcludedAdaptors } = require('../utils/exclude'); + +module.exports.handler = async (event, context) => { await main(); }; -// loading latest "base" data from db for each pool -// enriching the data with 1/7/30 day pct-changes of apy -// store single enriched data file as json to s3 const main = async () => { - console.log(`START DATA ENRICHMENT at ${new Date()}`); - - ////// 1) load latest data - const urlBase = process.env.APIG_URL; - console.log('\n1. pulling base data...'); - let data = await superagent.get(`${urlBase}/pools`); - data = data.body.data; - - ////// 2 add pct-change columns - // for each project we get 3 offsets (1D, 7D, 30D) and calculate the apy pct-change - // which we append to data - console.log('\n2. adding pct-change fields...'); + console.log('START DATA ENRICHMENT'); + + // ---------- get lastet unique pool + console.log('\ngetting pools'); + let data = await getYieldFiltered(); + const aaveGHO = await getLatestYieldForPool( + '1e00ac2b-0c3c-4b1f-95be-9378f98d2b40' + ); + data = [...data, ...aaveGHO]; + + const excludedProjects = await getExcludedAdaptors(); + data = data.filter((p) => !excludedProjects.has(p.project)); + + // remove aave v2 frozen assets from dataEnriched (we keep ingesting into db, but don't + // want to display frozen pools on the UI) + data = data.filter( + (p) => !(p.project === 'aave-v2' && p.poolMeta === 'frozen') + ); + + // remove expired pendle pools (expiration is in poolMeta) + data = data.filter((p) => { + if (p.project !== 'pendle') return true; + + const match = p.poolMeta?.match(/(\d{2}[A-Z]{3}\d{4})/); + if (!Array.isArray(match) || match.length < 2) return true; // keep if no valid match + + const date = new Date(match[1]); + return !isNaN(date) && date > new Date(); // keep if valid future date + }); + + // remove past Merkl pools + data = data.filter((p) => !(p.project === 'merkl' && p.poolMeta === 'past')); + + // ---------- add additional fields + // for each project we get 3 offsets (1D, 7D, 30D) and calculate absolute apy pct-change + console.log('\nadding pct-change fields'); const days = ['1', '7', '30']; let dataEnriched = []; const failed = []; - for (const adaptor of JSON.parse(process.env.ADAPTORS)) { - console.log(adaptor); - + for (const adaptor of [...new Set(data.map((p) => p.project))]) { // filter data to project const dataProject = data.filter((el) => el.project === adaptor); // api calls const promises = []; for (let i = 0; i < days.length; i++) { - promises.push(superagent.get(`${urlBase}/offsets/${adaptor}/${days[i]}`)); + promises.push(getYieldOffset(adaptor, days[i])); } try { const offsets = await Promise.all(promises); // calculate pct change for each pool dataEnriched = [ ...dataEnriched, - ...dataProject.map((pool) => enrich(pool, days, offsets)), + ...dataProject.map((p) => enrich(p, days, offsets)), ]; } catch (err) { console.log(err); @@ -59,150 +87,103 @@ const main = async () => { } } - console.log('Nb of pools: ', dataEnriched.length); - console.log( - `Nb of failed adaptor offset calculations: ${failed.length}, List of failed adaptors: ${failed}` - ); - - ////// 3) remove outliers - // remove pools which have extreme values of TVL and/or APY - // note(!) this could be more sophisticated via learned quantiles - // but keeping it simple here and applying some basic thrs - console.log('\n3. checking for apy null values and outliers'); - const UBApy = 1e6; - const UBTvl = 2e10; - outliers = dataEnriched.filter((el) => el.apy > UBApy && el.tvlUsd > UBTvl); - console.log(`Found and removing ${outliers.length} pools from dataEnriched`); - dataEnriched = dataEnriched.filter( - (el) => el.apy !== null && el.apy <= UBApy && el.tvlUsd <= UBTvl - ); - - ////// 4) add defillama fields for frontend referencing - console.log('\n4. adding defillama protocol fields'); - let protocols = await superagent.get('https://api.llama.fi/protocols'); - protocols = protocols.body; - for (const pool of dataEnriched) { - const x = protocols.find((el) => el.slug === pool.project); - pool['projectName'] = x?.name; - pool['projectId'] = x?.id; - pool['audits'] = x?.audits; - pool['audit_links'] = x?.audit_links; - pool['url'] = x?.url; - pool['twitter'] = x?.twitter; - pool['category'] = x?.category; - } + // add 30d avg apy + const avgApy30d = await getYieldAvg30d(); + dataEnriched = dataEnriched.map((p) => ({ + ...p, + apyMean30d: avgApy30d[p.configID] ?? null, + })); - ////// 5) add exposure, ilRisk and stablecoin fields - console.log('\n5. adding additional pool info fields'); - dataEnriched = dataEnriched.map((el) => addPoolInfo(el)); + // add info about stablecoin, exposure etc. + console.log('\nadding additional pool info fields'); + const stablecoins = ( + await superagent.get( + 'https://stablecoins.llama.fi/stablecoins?includePrices=true' + ) + ).body.peggedAssets + // removing any stable which a price 30% from 1usd + .filter((s) => s.price >= 0.7) + .map((s) => s.symbol.toLowerCase()) + .filter((s) => !['r', 'm'].includes(s)); + if (!stablecoins.includes('eur')) stablecoins.push('eur'); + if (!stablecoins.includes('3crv')) stablecoins.push('3crv'); + if (!stablecoins.includes('fraxbp')) stablecoins.push('fraxbp'); + if (!stablecoins.includes('usdr')) stablecoins.push('usdr'); + if (!stablecoins.includes('more')) stablecoins.push('more'); + if (!stablecoins.includes('ustb')) stablecoins.push('ustb'); + if (!stablecoins.includes('usdn')) stablecoins.push('usdn'); + if (!stablecoins.includes('aiusd')) stablecoins.push('aiusd'); + + // get catgory data (we hardcode IL to true for options protocols) + const config = ( + await superagent.get('https://api.llama.fi/config/yields?a=1') + ).body.protocols; + dataEnriched = dataEnriched.map((el) => addPoolInfo(el, stablecoins, config)); + + // add ML and overview plot fields + // expanding mean, expanding standard deviation, + // geometric mean and standard deviation (of daily returns) + console.log('\nadding stats columns'); + const T = 365; + dataEnriched = dataEnriched.map((p) => ({ + ...p, + return: (1 + p.apy / 100) ** (1 / T) - 1, + })); - // complifi has single token exposure only, but IL can still occur if a trader makes a big one, in which - // case the protocol will pay traders via deposited amounts... - // so hardcoding this here as IL + const dataStat = await getStat(); + const statColumns = welfordUpdate(dataEnriched, dataStat); + // add columns to dataEnriched for (const p of dataEnriched) { - if (p.project === 'complifi') { - p.ilRisk = 'yes'; - } + const x = statColumns.find((i) => i.configID === p.configID); + // create columns + // a) ML section + p['count'] = x.count; + p['apyMeanExpanding'] = x.meanAPY; + p['apyStdExpanding'] = + x.count < 2 ? null : Math.sqrt(x.mean2APY / (x.count - 1)); + // b) scatterchart section + p['mu'] = (x.productDR ** (T / x.count) - 1) * 100; + p['sigma'] = + x.count < 2 ? 0 : Math.sqrt((x.mean2DR / (x.count - 1)) * T) * 100; } - - ////// 6) add ml features - console.log('\n6. adding ml features'); - let dataStd = await superagent.get(`${urlBase}/stds`); - - // calculating both backward looking std and mean aking into account the current apy value - const dataStdUpdated = []; - for (const el of dataEnriched) { - d = dataStd.body.data.find((i) => i.pool === el.pool); - - if (d !== undefined) { - // calc std using welford's algorithm - // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance - // For a new value newValue, compute the new count, new mean, the new M2. - // mean accumulates the mean of the entire dataset - // M2 aggregates the squared distance from the mean - // count aggregates the number of samples seen so far - count = d.count; - mean = d.mean; - mean2 = d.mean2; - - count += 1; - delta = el.apy - mean; - mean += delta / count; - delta2 = el.apy - mean; - mean2 += delta * delta2; - } else { - // in case of a new pool, we won't have an entry yet in db and d will be undefined - // need to store count, mean and mean2 into table - count = 1; - mean = el.apy; - mean2 = 0; - } - // add the backward looking stats - // adding count as well, will use this to nullify predictions for objects which have less than 7 samples - el['count'] = count; - el['apyStdExpanding'] = - d === undefined || count < 2 ? null : Math.sqrt(mean2 / (count - 1)); - // for both undefined or not, the apy will be the (if undefined, mean === the current apy) - el['apyMeanExpanding'] = mean; - - // update std table only for pools which match the last hour of current day - const currentDay = new Date().toISOString().split('T')[0]; - if (el.timestamp === [currentDay, '23:00:00.000Z'].join('T')) { - console.log('updating std table'); - dataStdUpdated.push({ - pool: el.pool, - count, - mean, - mean2, - }); - } + // mark pools as outliers if outside boundary (let user filter via toggle on frontend) + const columns = ['mu', 'sigma']; + const outlierBoundaries = {}; + for (const col of columns) { + // for quantile thr calculation we keep only finite values (discarding null, undefined, NaN, Infinity) + const x = dataEnriched.map((p) => p[col]).filter((p) => Number.isFinite(p)); + const x_iqr = ss.quantile(x, 0.75) - ss.quantile(x, 0.25); + const x_median = ss.median(x); + const distance = 1.5; + const x_lb = x_median - distance * x_iqr; + const x_ub = x_median + distance * x_iqr; + outlierBoundaries[col] = { lb: Math.max(0, x_lb), ub: x_ub }; } - - if (dataStdUpdated.length > 0) { - const ssm = new SSM(); - const options = { - Name: `${process.env.SSM_PATH}/bearertoken`, - WithDecryption: true, - }; - const token = await ssm.getParameter(options).promise(); - const response = await superagent - .post(`${urlBase}/stds`) - .send(dataStdUpdated) - .set({ Authorization: `Bearer ${token.Parameter.Value}` }); - console.log('/stds response: \n', response.body); - } - - // bin std into stability metric - const stds = dataEnriched - .map((el) => el.apyStdExpanding) - .filter((el) => el !== null); - const quantiles = { - q25: ss.quantile(stds, 0.25), - q50: ss.quantile(stds, 0.5), - q75: ss.quantile(stds, 0.75), - }; - - dataEnriched = dataEnriched.map((el) => ({ - ...el, - Stability: - el.apyStdExpanding <= quantiles.q25 - ? 'A' - : el.apyStdExpanding <= quantiles.q50 - ? 'B' - : el.apyStdExpanding <= quantiles.q75 - ? 'C' - : 'D', + // before adding the new outlier field, + // i'm setting sigma to 0 instead of keeping it to null + // so the label on the scatterchart makes more sense + dataEnriched = dataEnriched.map((p) => ({ + ...p, + mu: Number.isFinite(p.mu) ? p.mu : 0, + sigma: Number.isFinite(p.sigma) ? p.sigma : 0, })); - ////// 7) add the algorithms predictions - console.log('\n7. adding apy runway prediction'); + dataEnriched = dataEnriched.map((p) => ({ + ...p, + outlier: + p['mu'] < outlierBoundaries['mu']['lb'] || + p['mu'] > outlierBoundaries['mu']['ub'] || + p['sigma'] < outlierBoundaries['sigma']['lb'] || + p['sigma'] > outlierBoundaries['sigma']['ub'], + })); + // add ML predictions + console.log('\nadding apy runway prediction'); // load categorical feature mappings const modelMappings = await utils.readFromS3( 'llama-apy-prediction-prod', 'mlmodelartefacts/categorical_feature_mapping_2022_05_20.json' ); - console.log(modelMappings); for (const el of dataEnriched) { project_fact = modelMappings.project_factorized[el.project]; chain_fact = modelMappings.chain_factorized[el.chain]; @@ -213,36 +194,30 @@ const main = async () => { el.chain_factorized = chain_fact === undefined ? -1 : chain_fact; } - // just for sanity, remove any potential objects with which have null value - // for apy and mean (there shouldn't be any, as we filter above) - // (should only be on apyStdExpanding because if d was undefined or count < 2) - dataEnriched = dataEnriched.filter( - (el) => el.apy !== null && el.apyMeanExpanding !== null - ); - // impute null values on apyStdExpanding (this will be null whenever we have pools with less than 2 // samples, eg. whenever a new pool project is listed or an existing project adds new pools - for (const el of dataEnriched) { - el.apyStdExpanding = el.apyStdExpanding === null ? 0 : el.apyStdExpanding; - } - - let y_pred = await superagent - .post( - 'https://yet9i1xlhf.execute-api.eu-central-1.amazonaws.com/predictions' - ) - // filter to required features only - .send( - dataEnriched.map((el) => ({ - apy: el.apy, - tvlUsd: el.tvlUsd, - apyMeanExpanding: el.apyMeanExpanding, - apyStdExpanding: el.apyStdExpanding, - chain_factorized: el.chain_factorized, - project_factorized: el.project_factorized, - })) - ); + dataEnriched = dataEnriched.map((p) => ({ + ...p, + apyStdExpanding: p.apyStdExpanding ?? 0, + })); - y_pred = y_pred.body.predictions; + const y_pred = ( + await superagent + .post( + 'https://yet9i1xlhf.execute-api.eu-central-1.amazonaws.com/predictions' + ) + // filter to required features only + .send( + dataEnriched.map((el) => ({ + apy: el.apy, + tvlUsd: el.tvlUsd, + apyMeanExpanding: el.apyMeanExpanding, + apyStdExpanding: el.apyStdExpanding, + chain_factorized: el.chain_factorized, + project_factorized: el.project_factorized, + })) + ) + ).body.predictions; // add predictions to dataEnriched if (dataEnriched.length !== y_pred.length) { throw new Error( @@ -253,8 +228,7 @@ const main = async () => { for (const [i, el] of dataEnriched.entries()) { // for certain conditions we don't want to show predictions on the frontend // 1. apy === 0 - // 2. project === 'anchor' ("stable" apy, prediction would be confusing) - // 3. less than 7 datapoints per pool + // 2. less than 7 datapoints per pool // (low confidence in the model predictions backward looking features (mean and std) // are undeveloped and might skew prediction results) @@ -264,8 +238,7 @@ const main = async () => { 1: 'Stable/Up', }; - const nullifyPredictionsCond = - el.apy <= 0 || el.count < 7 || el.project === 'anchor'; + const nullifyPredictionsCond = el.apy <= 0 || el.count < 7; const cond = y_pred[i][0] >= y_pred[i][1]; // (we add label + probabalilty of the class with the larger probability) const predictedClass = nullifyPredictionsCond @@ -285,6 +258,15 @@ const main = async () => { }; } + // hardcode notional's fixed rate pools to stable + high confidence + dataEnriched = dataEnriched.map((p) => ({ + ...p, + predictions: + p.project === 'notional' && p.poolMeta?.toLowerCase().includes('maturing') + ? { predictedClass: 'Stable/Up', predictedProbability: 100 } + : p.predictions, + })); + // based on discussion here: https://github.com/DefiLlama/yield-ml/issues/2 // the output of a random forest predict_proba are smoothed relative frequencies of // of class distributions and do not represent calibrated probabilities @@ -311,85 +293,139 @@ const main = async () => { : 3; } - // removing 0xf4bfe9b4ef01f27920e490cea87fe2642a8da18d (saitama-weth sushiswap on ethereum) - // had insane pump in price from coingecko, likely wrong - dataEnriched = dataEnriched.filter( - (p) => p.pool !== '0xf4bfe9b4ef01f27920e490cea87fe2642a8da18d' + // round numbers + const precision = 5; + dataEnriched = dataEnriched.map((p) => + Object.fromEntries( + Object.entries(p).map(([k, v]) => [ + k, + typeof v === 'number' ? +v.toFixed(precision) : v, + ]) + ) ); - ////// 8) save enriched data to s3 + // before saving, we set pool = configID for the api response of /pools & /poolsEnriched + // so we can have the same usage pattern on /chart without breaking changes + dataEnriched = dataEnriched + .map((p) => ({ ...p, pool_old: p.pool, pool: p.configID })) + .map(({ configID, ...p }) => p); + + // overwrite triggerAdapter apy calc for abracadabra (some of their vaults apply interest on collateral + // instead of borrowed mim) -> negative apyBase -> negative apy (we don't store negative apy values in db though + // nor do we use neg values on feature calc cause might break some things) + // hence the updated calc here to have correct nbs on UI + dataEnriched = dataEnriched.map((p) => ({ + ...p, + apy: p.project === 'abracadabra' ? p.apyBase + p.apyReward : p.apy, + })); + + // ---------- save output to S3 console.log('\nsaving data to S3'); + console.log('nb of pools', dataEnriched.length); const bucket = process.env.BUCKET_DATA; const key = 'enriched/dataEnriched.json'; dataEnriched = dataEnriched.sort((a, b) => b.tvlUsd - a.tvlUsd); await utils.writeToS3(bucket, key, dataEnriched); - // also save to other "folder" where we keep track of hourly predictions (this will be used - // for ML dashboard performance monitoring) - const timestamp = new Date( - Math.floor(Date.now() / 1000 / 60 / 60) * 60 * 60 * 1000 - ).toISOString(); - const keyPredictions = `predictions-hourly/dataEnriched_${timestamp}.json`; - await utils.writeToS3(bucket, keyPredictions, dataEnriched); + // store ML predictions so we can keep track of model performance + const f = 1000 * 60 * 60; + const timestamp = new Date(Math.floor(Date.now() / f) * f).toISOString(); + + if (timestamp.split('T')[1] === '23:00:00.000Z') { + const keyPredictions = `predictions-hourly/dataEnriched_${timestamp}.json`; + await utils.writeToS3(bucket, keyPredictions, dataEnriched); + } + + // we cp dataEnriched (but remove unecessary columns) to our public s3 bucket + // which is used as source for /pools + const pools = dataEnriched.map((p) => { + const newPool = {}; + poolsResponseColumns.forEach((col) => (newPool[col] = p[col])); + return newPool; + }); + + await utils.storeAPIResponse('defillama-datasets', 'yield-api/pools', { + status: 'success', + data: pools, + }); + + // query db for lendBorrow and store to s3 as origin for cloudfront + await utils.storeAPIResponse( + 'defillama-datasets', + 'yield-api/lendBorrow', + await getYieldLendBorrow() + ); }; ////// helper functions -// calculate pct change +// calculate absolute change btw current apy and offset value const enrich = (pool, days, offsets) => { const poolC = { ...pool }; for (let d = 0; d < days.length; d++) { - let X = offsets[d].body.data.offsets; - const apyOffset = X.find((x) => x.pool === poolC.pool)?.apy; - poolC[`apyPct${days[d]}D`] = ((poolC['apy'] - apyOffset) / apyOffset) * 100; + let X = offsets[d]; + const apyOffset = X.find((x) => x.configID === poolC.configID)?.apy; + poolC[`apyPct${days[d]}D`] = poolC['apy'] - apyOffset; } return poolC; }; -const checkStablecoin = (el) => { - stablecoins = [ - 'usdt', - 'usdc', - 'busd', - // 'ust', // excluding cause of depeg - 'dai', - 'mim', - 'frax', - 'tusd', - 'usdp', - 'fei', - 'lusd', - 'alusd', - 'husd', - 'gusd', - 'susd', - 'musd', - 'cusd', - 'eur', - 'usdn', - 'dusd', - 'usd+', - ]; - +const checkStablecoin = (el, stablecoins) => { let tokens = el.symbol.split('-').map((el) => el.toLowerCase()); + const symbolLC = el.symbol.toLowerCase(); let stable; - // specific case for aave amm positions - if (el.project === 'aave' && el.symbol.toLowerCase().includes('amm')) { + if ( + el.project === 'curve' && + symbolLC.includes('3crv') && + !symbolLC.includes('btc') + ) { + stable = true; + } else if (el.project === 'curve-dex' && symbolLC.includes('xstable')) { + stable = true; + } else if (el.project === 'convex-finance' && symbolLC.includes('3crv')) { + stable = true; + } else if (el.project === 'aave-v2' && symbolLC.includes('amm')) { tok = tokens[0].split('weth'); stable = tok[0].includes('wbtc') ? false : tok.length > 1 ? false : true; + } else if (tokens[0].includes('torn')) { + stable = false; + } else if (el.project === 'hermes-protocol' && symbolLC.includes('maia')) { + stable = false; + } else if (el.project === 'sideshift' && symbolLC.includes('xai')) { + stable = false; + } else if (el.project === 'archimedes-finance' && symbolLC.includes('usd')) { + stable = true; + } else if ( + el.project === 'aura' && + [ + '0xa13a9247ea42d743238089903570127dda72fe44', + '0x99c88ad7dc566616548adde8ed3effa730eb6c34', + '0xf3aeb3abba741f0eece8a1b1d2f11b85899951cb', + ].includes(el.pool) + ) { + stable = true; + } else if ( + tokens.some((t) => t.includes('sushi')) || + tokens.some((t) => t.includes('dusk')) || + tokens.some((t) => t.includes('fpis')) || + tokens.some((t) => t.includes('emaid')) || + tokens.some((t) => t.includes('grail')) || + tokens.some((t) => t.includes('oxai')) || + tokens.some((t) => t.includes('crv') && !t.includes('crvusd')) || + tokens.some((t) => t.includes('wbai')) || + tokens.some((t) => t.includes('move')) + ) { + stable = false; } else if (tokens.length === 1) { - stable = stablecoins.some((x) => tokens[0].includes(x)); + stable = stablecoins.some((x) => + tokens[0].replace(/\s*\(.*?\)\s*/g, '').includes(x) + ); } else if (tokens.length > 1) { let x = 0; for (const t of tokens) { x += stablecoins.some((x) => t.includes(x)); } stable = x === tokens.length ? true : false; - - // this case is for Bancor only - if (tokens.includes('bnt') && x > 0) { - stable = true; - } } return stable; @@ -400,7 +436,7 @@ const checkStablecoin = (el) => { // 2: - 1 asset // 3: - more than 1 asset but same underlying assets const checkIlRisk = (el) => { - const l1Token = ['btc', 'eth', 'avax', 'matic', 'eur']; + const l1Token = ['btc', 'eth', 'avax', 'matic', 'eur', 'link', 'sushi']; const symbol = el.symbol.toLowerCase(); const tokens = symbol.split('-'); @@ -410,14 +446,12 @@ const checkIlRisk = (el) => { symbol.includes('ammuni') || symbol.includes('ammbpt') || symbol.includes('tricrypto') || - symbol.includes('3crypto') + symbol.includes('3crypto') || + (symbol.includes('crvusd') && symbol.includes('eth')) ) { ilRisk = 'yes'; } else if (tokens.length === 1) { ilRisk = 'no'; - // for bancor - } else if (tokens.length === 2 && tokens.includes('bnt')) { - ilRisk = 'no'; } else { const elements = []; for (const t of tokens) { @@ -446,6 +480,10 @@ const checkExposure = (el) => { // generic let exposure = el.symbol.includes('-') ? 'multi' : 'single'; + // generic 3crv check + if (exposure === 'single' && el.symbol.toLowerCase().includes('3crv')) + return 'multi'; + // project specific if (el.project === 'aave') { exposure = @@ -453,19 +491,44 @@ const checkExposure = (el) => { el.symbol.toLowerCase().includes('ammbpt') ? 'multi' : exposure; - } else if (el.project === 'bancor') { - exposure = 'single'; } else if (el.project === 'badger-dao') { exposure = el.symbol.toLowerCase().includes('crv') ? 'multi' : exposure; + } else if (el.project === 'dot-dot-finance') { + exposure = 'multi'; + } else if (el.project === 'synapse') { + exposure = 'multi'; } return exposure; }; -const addPoolInfo = (el) => { - el['stablecoin'] = checkStablecoin(el); +const addPoolInfo = (el, stablecoins, config) => { + el['stablecoin'] = checkStablecoin(el, stablecoins); + + // complifi has single token exposure only cause the protocol + // will pay traders via deposited amounts el['ilRisk'] = - el.stablecoin && el.symbol.toLowerCase().includes('eur') + el.pool === '0x13C6Bed5Aa16823Aba5bBA691CAeC63788b19D9d' // jones-dao jusdc pool + ? 'no' + : config[el.project]?.category === 'Options' + ? 'yes' + : [ + 'complifi', + 'optyfi', + 'arbor-finance', + 'opyn-squeeth', + 'gmd-protocol', + 'y2k-v1', + 'y2k-v2', + 'o3-swap', + 'solv-funds', + ].includes(el.project) + ? 'yes' + : ['mycelium-perpetual-swaps', 'gmx', 'rage-trade'].includes( + el.project + ) && ['mlp', 'glp'].includes(el.symbol.toLowerCase()) + ? 'yes' + : el.stablecoin && el.symbol.toLowerCase().includes('eur') ? checkIlRisk(el) : el.stablecoin ? 'no' @@ -474,3 +537,5 @@ const addPoolInfo = (el) => { return el; }; + +module.exports.checkStablecoin = checkStablecoin; diff --git a/src/handlers/triggerEntrypoint.js b/src/handlers/triggerEntrypoint.js index d1c2c13611..cb0ffc1b8b 100644 --- a/src/handlers/triggerEntrypoint.js +++ b/src/handlers/triggerEntrypoint.js @@ -1,6 +1,9 @@ const SQS = require('aws-sdk/clients/sqs'); -module.exports.handler = async (event) => { +const { getExcludedAdaptors } = require('../utils/exclude'); +const adaptorList = require('../adaptors/list'); + +module.exports.handler = async () => { await main(); }; @@ -8,11 +11,14 @@ module.exports.handler = async (event) => { // sends 1 msg for each adaptor to adaptorqueue // from which the adaptor lambda polls of messages const main = async () => { - console.log(`START ADAPTER-PIPELINE at ${new Date()}`); + console.log(`START ADAPTER-PIPELINE`); try { const sqs = new SQS(); - for (const adaptor of JSON.parse(process.env.ADAPTORS)) { + const excludedAdaptors = await getExcludedAdaptors(); + const adaptors = adaptorList.filter((a) => !excludedAdaptors.has(a)); + + for (const adaptor of adaptors) { await sqs .sendMessage({ QueueUrl: process.env.ADAPTER_QUEUE_URL, diff --git a/src/handlers/triggerLSDRates.js b/src/handlers/triggerLSDRates.js new file mode 100644 index 0000000000..635c7737e6 --- /dev/null +++ b/src/handlers/triggerLSDRates.js @@ -0,0 +1,654 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); + +const { insertLsd } = require('../queries/lsd'); + +module.exports.handler = async (event, context) => { + context.callbackWaitsForEmptyEventLoop = false; + const payload = await getRates(); + const response = await insertLsd(payload); + console.log(response); +}; + +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +const r = 'rebase'; +const a = 'accruing'; + +// name field must match `name` in our protocols endpoint +const lsdTokens = [ + { + name: 'Lido', + symbol: 'stETH', + address: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84', + type: r, + fee: 0.1, + }, + { + name: 'Coinbase Wrapped Staked ETH', + symbol: 'cbETH', + address: '0xbe9895146f7af43049ca1c1ae358b0541ea49704', + type: a, + fee: 0.25, + }, + { + name: 'Rocket Pool', + symbol: 'rETH', + address: '0xae78736cd615f374d3085123a210448e74fc6393', + type: a, + fee: 0.14, + }, + { + name: 'StakeWise', + symbol: 'osETH', + address: '0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38', + type: a, + fee: 0.05, + }, + { + name: 'Ankr', + symbol: 'ANKRETH', + address: '0xe95a203b1a91a908f9b9ce46459d101078c2c3cb', + type: a, + fee: 0.1, + }, + { + name: 'Frax Ether', + symbol: 'sfrxETH', + address: '0xac3e018457b222d93114458476f3e3416abbe38f', + type: a, + fee: 0.1, + }, + { + name: 'SharedStake', + symbol: 'vETH2', + address: '0x898bad2774eb97cf6b94605677f43b41871410b1', + fee: 0.06, + }, + { + name: 'Stafi', + symbol: 'rETH', + address: '0x9559aaa82d9649c7a7b220e7c461d2e74c9a3593', + type: a, + fee: 0.1, + }, + { + name: 'StakeHound', + symbol: 'stETH', + address: '0xdfe66b14d37c77f4e9b180ceb433d1b164f0281d', + }, + { + name: 'Bifrost Liquid Staking', + symbol: 'vETH', + address: '0x4Bc3263Eb5bb2Ef7Ad9aB6FB68be80E43b43801F', // vETH + addressExchangeRate: '0x74bAA141B18D5D1eeF1591abf37167FbeCE23B72', // Staking Liquidity Protocol Contract + type: a, + }, + { + name: 'GETH', + symbol: 'GETH', + address: '0x3802c218221390025bceabbad5d8c59f40eb74b8', + type: r, + fee: 0.1, + }, + { + name: 'Hord', + symbol: 'hETH', + address: '0x5bBe36152d3CD3eB7183A82470b39b29EedF068B', + type: a, + fee: 0.1, + }, + { + name: 'Swell Liquid Staking', + symbol: 'swETH', + address: '0xf951E335afb289353dc249e82926178EaC7DEd78', + type: a, + fee: 0.1, + }, + { + name: 'Binance staked ETH', + symbol: 'wBETH', + address: '0xa2E3356610840701BDf5611a53974510Ae27E2e1', + type: a, + fee: 0.1, + }, + { + name: 'Tranchess Ether', + symbol: 'qETH', + address: '0x93ef1Ea305D11A9b2a3EbB9bB4FCc34695292E7d', // qETH + addressExchangeRate: '0xA6aeD7922366611953546014A3f9e93f058756a2', // QueenRateProvider + type: a, + // fee: 0.1, + }, + { + name: 'Stakehouse', + symbol: 'dETH', + address: '0x3d1e5cf16077f349e999d6b21a4f646e83cd90c5', + type: a, + fee: 0, + }, + { + name: 'Stader', + symbol: 'ETHx', + address: '0xA35b1B31Ce002FBF2058D22F30f95D405200A15b', + addressExchangeRate: '0xcf5EA1b38380f6aF39068375516Daf40Ed70D299', + type: a, + fee: 0.1, + }, + { + name: 'NodeDAO', + symbol: 'nETH', + address: '0xC6572019548dfeBA782bA5a2093C836626C7789A', + addressExchangeRate: '0x8103151E2377e78C04a3d2564e20542680ed3096', + type: a, + fee: 0.1, + }, + { + name: 'Bedrock uniETH', + symbol: 'uniETH', + address: '0xF1376bceF0f78459C0Ed0ba5ddce976F1ddF51F4', + addressExchangeRate: '0x4beFa2aA9c305238AA3E0b5D17eB20C045269E9d', + type: a, + fee: 0.1, + }, + { + name: 'mETH Protocol', + symbol: 'mETH', + address: '0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa', + addressExchangeRate: '0xe3cBd06D7dadB3F4e6557bAb7EdD924CD1489E8f', + type: a, + fee: 0.1, + }, + { + name: 'Dinero (pxETH)', + symbol: 'APXETH', + address: '0x04c154b66cb340f3ae24111cc767e0184ed00cc6', + addressExchangeRate: '0x9ba021b0a9b958b5e75ce9f6dff97c7ee52cb3e6', + type: a, + fee: 0.1, + }, + { + name: 'Liquid Collective', + symbol: 'lsETH', + address: '0x8c1bed5b9a0928467c9b1341da1d7bd5e10b6549', + type: a, + fee: 0.1, + }, + { + name: 'MEV Protocol', + symbol: 'mevETH', + address: '0x24Ae2dA0f361AA4BE46b48EB19C91e02c5e4f27E', + type: a, + fee: 0.1, + }, + { + name: 'Meta Pool ETH', + symbol: 'mpETH', + address: '0x48AFbBd342F64EF8a9Ab1C143719b63C2AD81710', + type: a, + fee: 0.1, + }, + { + name: 'Crypto.com Staked ETH', + symbol: 'CDCETH', + address: '0x7a7c9db510aB29A2FC362a4c34260BEcB5cE3446', + type: a, + fee: 0.1, + }, +]; + +const priceUrl = 'https://aggregator-api.kyberswap.com/ethereum/api/v1/routes'; +const cbETHRateUrl = + 'https://api-public.sandbox.pro.coinbase.com/wrapped-assets/CBETH/conversion-rate'; + +const getRates = async () => { + const marketRates = await getMarketRates(); + const expectedRates = await getExpectedRates(); + + const timestamp = new Date(); + const payload = expectedRates.map((p) => { + const marketRate = + marketRates.find( + (mr) => mr.sellTokenAddress.toLowerCase() === p.address.toLowerCase() + )?.buyAmount / 1e18; + const ethPeg = (marketRate / p.expectedRate - 1) * 100; + + return { + ...p, + marketRate: Number.isFinite(marketRate) ? marketRate : null, + ethPeg: Number.isFinite(ethPeg) ? ethPeg : null, + timestamp, + }; + }); + + return payload; +}; + +const getMarketRates = async () => { + const amount = 1e18; + const urls = lsdTokens + .filter((i) => i.name !== 'StakeHound') // useless data + .map( + (lsd) => + `${priceUrl}?tokenIn=${lsd.address}&tokenOut=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&amountIn=${amount}` + ); + + const marketRates = []; + for (const url of urls) { + try { + marketRates.push((await axios.get(url)).data.data.routeSummary); + await sleep(500); + } catch (err) { + console.log(url, err.response.data); + } + } + + return marketRates.map((m) => ({ + buyTokenAddress: m.tokenOut, + sellTokenAddress: m.tokenIn, + buyAmount: m.amountOut, + sellAmount: m.amountIn, + })); +}; + +const getExpectedRates = async () => { + // same for rETHStafi + const rETHAbi = { + inputs: [], + name: 'getExchangeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const ankrETHAbi = { + inputs: [], + name: 'ratio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const sfrxETHAbi = { + inputs: [], + name: 'pricePerShare', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const swETHAbi = { + inputs: [], + name: 'getRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const wBETHAbi = { + inputs: [], + name: 'exchangeRate', + outputs: [ + { internalType: 'uint256', name: '_exchangeRate', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }; + + const hETHAbi = [ + { + inputs: [], + name: 'lastExecLayerRewardsForFeeCalc', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'amountETH', type: 'uint256' }, + { internalType: 'bool', name: 'isContractCall', type: 'bool' }, + { + internalType: 'uint256', + name: 'diffExecLayerRewardsForFeelCalc', + type: 'uint256', + }, + ], + name: 'getAmountOfHETHforETH', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ]; + + const qETHAbi = { + inputs: [], + name: 'getRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const vETHAbi = { + inputs: [ + { internalType: 'uint256', name: 'vTokenAmount', type: 'uint256' }, + ], + name: 'calculateTokenAmount', + outputs: [ + { internalType: 'uint256', name: 'tokenAmount', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }; + + const ETHxAbi = { + inputs: [], + name: 'getExchangeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const nETHAbi = { + inputs: [], + name: 'getExchangeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const uniETHAbi = { + inputs: [], + name: 'exchangeRatio', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const mETHAbi = { + inputs: [{ internalType: 'uint256', name: 'mETHAmount', type: 'uint256' }], + name: 'mETHToETH', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const lsETHAbi = { + inputs: [ + { + internalType: 'uint256', + name: '_underlyingAssetAmount', + type: 'uint256', + }, + ], + name: 'sharesFromUnderlyingBalance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const mevETHAbi = { + inputs: [], + name: 'fraction', + outputs: [ + { internalType: 'uint128', name: 'elastic', type: 'uint128' }, + { internalType: 'uint128', name: 'base', type: 'uint128' }, + ], + stateMutability: 'view', + type: 'function', + }; + + const mpETHAbi = { + inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }], + name: 'convertToAssets', + outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }; + + const CDCETHAbi = { + inputs: [], + name: 'exchangeRate', + outputs: [ + { internalType: 'uint256', name: '_exchangeRate', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }; + + // --- cbETH + const cbETHRate = Number((await axios.get(cbETHRateUrl)).data.amount); + + // --- rETH (rocket pool) + const rETHRate = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Rocket Pool').address, + chain: 'ethereum', + abi: rETHAbi, + }) + ).output / 1e18; + + // --- rETH (stafi) + const rETHStafiRate = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Stafi').address, + chain: 'ethereum', + abi: rETHAbi, + }) + ).output / 1e18; + + // --- ankrETH + const ankrETHRate = + 1 / + (( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Ankr').address, + chain: 'ethereum', + abi: ankrETHAbi, + }) + ).output / + 1e18); + + // --- sfrxETH + const sfrxETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Frax Ether').address, + chain: 'ethereum', + abi: sfrxETHAbi, + }) + ).output / 1e18; + + // --- swETH + const swETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Swell Liquid Staking') + .address, + chain: 'ethereum', + abi: swETHAbi, + }) + ).output / 1e18; + + const wBETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Binance staked ETH') + .address, + chain: 'ethereum', + abi: wBETHAbi, + }) + ).output / 1e18; + + const hETHlastExecLayerRewardsForFeeCalc = ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Hord').address, + chain: 'ethereum', + abi: hETHAbi[0], + }) + ).output; + + const hETH = + 1 / + (( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Hord').address, + chain: 'ethereum', + abi: hETHAbi[1], + params: [ + BigInt(1e18), + false, + BigInt(hETHlastExecLayerRewardsForFeeCalc), + ], + }) + ).output / + 1e18); + + const qETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Tranchess Ether') + .addressExchangeRate, + chain: 'ethereum', + abi: qETHAbi, + }) + ).output / 1e18; + + const vETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Bifrost Liquid Staking') + .addressExchangeRate, + chain: 'ethereum', + abi: vETHAbi, + params: [BigInt(1e18)], + }) + ).output / 1e18; + + const ETHx = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Stader') + .addressExchangeRate, + chain: 'ethereum', + abi: ETHxAbi, + }) + ).output / 1e18; + + const nETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'NodeDAO') + .addressExchangeRate, + chain: 'ethereum', + abi: nETHAbi, + }) + ).output / 1e18; + + const uniETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Bedrock uniETH') + .addressExchangeRate, + chain: 'ethereum', + abi: uniETHAbi, + }) + ).output / 1e18; + + const mETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'mETH Protocol') + .addressExchangeRate, + chain: 'ethereum', + abi: mETHAbi, + params: [1000000000000000000n], + }) + ).output / 1e18; + + const lsETH = + 10000 / + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Liquid Collective') + .address, + chain: 'ethereum', + abi: lsETHAbi, + params: [10000], + }) + ).output; + + const mevETHRes = ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'MEV Protocol').address, + chain: 'ethereum', + abi: mevETHAbi, + }) + ).output; + const mevETH = mevETHRes[0] / mevETHRes[1]; + + const mpETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Meta Pool ETH').address, + chain: 'ethereum', + params: [1000000000000000000n], + abi: mpETHAbi, + }) + ).output / 1e18; + + const CDCETH = + ( + await sdk.api.abi.call({ + target: lsdTokens.find((lsd) => lsd.name === 'Crypto.com Staked ETH') + .address, + chain: 'cronos', + abi: CDCETHAbi, + }) + ).output / 1e18; + + return lsdTokens.map((lsd) => ({ + ...lsd, + expectedRate: + lsd.name === 'Coinbase Wrapped Staked ETH' + ? cbETHRate + : lsd.name === 'Rocket Pool' + ? rETHRate + : lsd.name === 'Stafi' + ? rETHStafiRate + : lsd.name === 'Ankr' + ? ankrETHRate + : lsd.name === 'Frax Ether' + ? sfrxETH + : lsd.name === 'Swell Liquid Staking' + ? swETH + : lsd.name === 'Binance staked ETH' + ? wBETH + : lsd.name === 'Hord' + ? hETH + : lsd.name === 'Tranchess Ether' + ? qETH + : lsd.name === 'Bifrost Liquid Staking' + ? vETH + : lsd.name === 'Stader' + ? ETHx + : lsd.name === 'NodeDAO' + ? nETH + : lsd.name === 'Bedrock uniETH' + ? uniETH + : lsd.name === 'mETH Protocol' + ? mETH + : lsd.name === 'Liquid Collective' + ? lsETH + : lsd.name === 'MEV Protocol' + ? mevETH + : lsd.name === 'Meta Pool ETH' + ? mpETH + : lsd.name === 'Crypto.com Staked ETH' + ? CDCETH + : 1, + })); +}; diff --git a/src/handlers/triggerMedian.js b/src/handlers/triggerMedian.js new file mode 100644 index 0000000000..6f3206106e --- /dev/null +++ b/src/handlers/triggerMedian.js @@ -0,0 +1,34 @@ +const ss = require('simple-statistics'); + +const { insertMedian } = require('../queries/median'); +const utils = require('../utils/s3'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + let pools = ( + await utils.readFromS3('llama-apy-prod-data', 'enriched/dataEnriched.json') + ).map((i) => ({ ...i, timestamp: new Date(i.timestamp) })); + + // include only pools which we have updated on that day, + // otherwise median calc for that day would include values from yst up to 7days ago + console.log('removing stale pools...'); + console.log('prior filter', pools.length); + const maxTimestamp = Math.max(...pools.map((p) => p.timestamp)); + const n = 1000 * 60 * 60 * 24; + const latestDay = new Date(Math.floor(maxTimestamp / n) * n); + pools = pools.filter((p) => p.timestamp >= latestDay); + console.log('after filter', pools.length); + + const payload = [ + { + timestamp: new Date(), + medianAPY: +ss.median(pools.map((p) => p.apy)).toFixed(5), + uniquePools: new Set(pools.map((p) => p.pool)).size, + }, + ]; + const response = await insertMedian(payload); + console.log(response); +}; diff --git a/src/handlers/triggerMedianProject.js b/src/handlers/triggerMedianProject.js new file mode 100644 index 0000000000..7967857435 --- /dev/null +++ b/src/handlers/triggerMedianProject.js @@ -0,0 +1,55 @@ +const { pgp, connect } = require('../utils/dbConnection'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + const conn = await connect(); + + const query = ` +INSERT INTO + median_project (timestamp, project, "medianAPY", "uniquePools") +WITH today AS ( + SELECT + "configID", + apy + FROM + yield + WHERE + timestamp >= CURRENT_DATE + AND apy > 0 + AND "tvlUsd" > 10000 + ), + combined AS ( + SELECT + t."configID" as "configID", + t.apy AS apy, + c.project AS project + FROM + today t + JOIN config c ON t."configID" = c.config_id + ) +SELECT + CURRENT_DATE AS timestamp, + project, + PERCENTILE_CONT(0.5) WITHIN GROUP ( + ORDER BY + apy + ) AS "medianAPY", + count(distinct "configID") AS "uniquePools" +FROM + combined +GROUP BY + project + + `; + + const response = await conn.query(query); + + if (!response) { + return new AppError(`Couldn't insert into median_project data`, 404); + } + + return response; +}; diff --git a/src/handlers/triggerMonitor.js b/src/handlers/triggerMonitor.js new file mode 100644 index 0000000000..ca57df234f --- /dev/null +++ b/src/handlers/triggerMonitor.js @@ -0,0 +1,22 @@ +const { getStaleProjects } = require('../queries/monitor'); +const { sendMessage } = require('../utils/discordWebhook'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + const stale = await getStaleProjects(); + + if (stale.length) { + const message = stale + .map( + (p) => + `${p.project}: ${p.stale_since.days ?? 0} day(s) ${ + p.stale_since.hours + }:${p.stale_since.minutes}:00 ago (${p.nb_effected_pools} pool(s))` + ) + .join('\n'); + await sendMessage(message, process.env.STALE_PROJECTS_WEBHOOK); + } +}; diff --git a/src/handlers/triggerPerpetuals.js b/src/handlers/triggerPerpetuals.js new file mode 100644 index 0000000000..ea50b40b25 --- /dev/null +++ b/src/handlers/triggerPerpetuals.js @@ -0,0 +1,42 @@ +const binance = require('../perpetuals/binance'); +const bybit = require('../perpetuals/bybit'); +const dydx = require('../perpetuals/dydx'); +const okx = require('../perpetuals/okx'); +const synthetix = require('../perpetuals/synthetix'); + +const { insertPerp } = require('../queries/perp'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + const perps = ( + await Promise.allSettled([ + binance.getPerpData(), + bybit.getPerpData(), + dydx.getPerpData(), + okx.getPerpData(), + synthetix.getPerpData(), + ]) + ) + .filter((c) => c.status === 'fulfilled') + .map((i) => i.value) + .flat() + .filter((m) => m.indexPrice !== null) + .map((m) => ({ + ...m, + timestamp: new Date(Date.now()), + market: m.market.toUpperCase(), + baseAsset: m.baseAsset.toUpperCase(), + fundingRate: +m.fundingRate.toFixed(10), + fundingRatePrevious: +m.fundingRatePrevious.toFixed(10), + fundingTimePrevious: Number(m.fundingTimePrevious), + indexPrice: +m.indexPrice.toFixed(5), + openInterest: Math.round(m.openInterest), + })) + .filter((m) => m.indexPrice >= 0); + + const r = await insertPerp(perps); + console.log(r); +}; diff --git a/src/handlers/triggerProtocolNameChange.js b/src/handlers/triggerProtocolNameChange.js new file mode 100644 index 0000000000..019f52326e --- /dev/null +++ b/src/handlers/triggerProtocolNameChange.js @@ -0,0 +1,28 @@ +const axios = require('axios'); +const { sendMessage } = require('../utils/discordWebhook'); + +module.exports.handler = async () => { + await main(); +}; + +const main = async () => { + const protocols = (await axios('https://api.llama.fi/config/yields')).data + .protocols; + + const pools = (await axios.get('https://yields.llama.fi/pools')).data.data; + const uniqueProjects = [...new Set(pools.map((p) => p.project))]; + + const noMatch = []; + for (const project of uniqueProjects) { + if (!protocols[project]) { + noMatch.push(project); + } + } + + if (noMatch.length) { + await sendMessage( + `Check /protocols slug for ${noMatch}`, + process.env.STALE_PROJECTS_WEBHOOK + ); + } +}; diff --git a/src/handlers/triggerStat.js b/src/handlers/triggerStat.js new file mode 100644 index 0000000000..065c9395ca --- /dev/null +++ b/src/handlers/triggerStat.js @@ -0,0 +1,28 @@ +const { welfordUpdate } = require('../utils/welford'); +const { getStat, insertStat } = require('../queries/stat'); +const utils = require('../utils/s3'); + +module.exports.handler = async (event, context) => { + await main(); +}; + +// we trigger this once per day at midnight, reason: the stat table was boostrapped on +// daily values, and the ML relying on those features was trained on daily values too. +// so i want to keep things consistent (even though it shouldnt be a big difference, at least +// for the majority of pools) +const main = async () => { + let data = ( + await utils.readFromS3('llama-apy-prod-data', 'enriched/dataEnriched.json') + ).map((i) => ({ ...i, configID: i.pool, timestamp: new Date(i.timestamp) })); + const T = 365; + // transform raw apy to return field (required for geometric mean) + data = data.map((p) => ({ + ...p, + return: (1 + p.apy / 100) ** (1 / T) - 1, + })); + + const dataStat = await getStat(); + const payload = welfordUpdate(data, dataStat); + const response = await insertStat(payload); + console.log(response); +}; diff --git a/src/helper/requery.js b/src/helper/requery.js new file mode 100644 index 0000000000..8b2cad980a --- /dev/null +++ b/src/helper/requery.js @@ -0,0 +1,22 @@ +const sdk = require('@defillama/sdk'); + +async function requery(resultsRaw, chain, block, abi) { + const results = resultsRaw.output; + if (results.some(r => !r.success)) { + const failed = results.map((r, i) => [r, i]).filter(r => !r[0].success) + const newResults = await sdk.api.abi + .multiCall({ + abi, + chain, + calls: failed.map((f) => f[0].input), + block, + }).then(({ output }) => output); + failed.forEach((f, i) => { + results[f[1]] = newResults[i] + }) + } +} + +module.exports = { + requery +} \ No newline at end of file diff --git a/src/helper/starknet.js b/src/helper/starknet.js new file mode 100644 index 0000000000..e3c4032c1e --- /dev/null +++ b/src/helper/starknet.js @@ -0,0 +1,112 @@ +// https://www.starknetjs.com/docs/API/contract +const { Contract, validateAndParseAddress, number, hash, uint256, } = require('starknet') +const axios = require('axios') +const plimit = require('p-limit') +const { sliceIntoChunks, sleep } = require('./utils') + +const _rateLimited = plimit(1) +const rateLimited = fn => (...args) => _rateLimited(() => fn(...args)) + +const STARKNET_RPC = process.env.STARKNET_RPC + +function formCallBody({ abi, target, params = [], allAbi = [] }, id = 0) { + if ((params || params === 0) && !Array.isArray(params)) + params = [params] + const contract = new Contract([abi, ...allAbi,], target, null) + const requestData = contract.populate(abi.name, params) + requestData.entry_point_selector = hash.getSelectorFromName(requestData.entrypoint) + requestData.contract_address = requestData.contractAddress + requestData.calldata = params + delete requestData.contractAddress + delete requestData.entrypoint + if (abi.customInput === 'address') requestData.calldata = params.map(i => i.slice(2)) + return getCallBody(requestData, id) + + function getCallBody(i) { + return { jsonrpc: "2.0", id, method: "starknet_call", params: [i, "latest"] } + } +} + +function parseOutput(result, abi, allAbi) { + const contract = new Contract([abi,...allAbi], null, null) + let response = contract.parseResponse(abi.name, result) + if (abi.outputs.length === 1) { + response = response[0] + if (abi.outputs[0].type === 'Uint256') return response + switch (abi.customType) { + case 'address': return validateAndParseAddress(response) + case 'Uint256': return response + } + } + return response +} + +async function call({ abi, target, params = [], allAbi = [] } = {}, ...rest) { + const { data: { result } } = await axios.post(STARKNET_RPC, formCallBody({ abi, target, params, allAbi })) + return parseOutput(result, abi, allAbi) +} + +async function multiCall({ abi: rootAbi, target: rootTarget, calls = [], allAbi = [] }) { + if (!calls.length) return [] + calls = calls.map((callArgs) => { + if (typeof callArgs !== 'object') { + if (!rootTarget) return { target: callArgs, abi: rootAbi, allAbi, } + return { target: rootTarget, params: callArgs, abi: rootAbi, allAbi, } + } + const { target, params, abi } = callArgs + return { target: target || rootTarget, params, abi: abi || rootAbi } + }) + const callBodies = calls.map(formCallBody) + const allData = [] + const chunks = sliceIntoChunks(callBodies, 25) + for (const chunk of chunks) { + await sleep(2000) + const { data } = await axios.post(STARKNET_RPC, chunk) + allData.push(...data) + } + + const response = [] + allData.forEach((i) => { + const { result, id } = i + const abi = calls[id].abi ?? rootAbi + response[id] = parseOutput(result, abi, allAbi) + }) + return response +} + +const balanceOfABI = { + "name": "balanceOf", + "type": "function", + "inputs": [ + { + "name": "account", + "type": "felt" + } + ], + "outputs": [ + { + "name": "balance", + "type": "Uint256" + } + ], + "stateMutability": "view", + "customInput": 'address', +} + +const api = { + chain: 'starknet', +} + +const defaultAbis = { + balanceOf: balanceOfABI, +} + +module.exports = { + call: rateLimited(call), + multiCall: rateLimited(multiCall), + parseAddress: validateAndParseAddress, + number, +} + +api.call = module.exports.call +api.multiCall = module.exports.multiCall diff --git a/src/helper/unwrapLPs.js b/src/helper/unwrapLPs.js new file mode 100644 index 0000000000..0e72486577 --- /dev/null +++ b/src/helper/unwrapLPs.js @@ -0,0 +1,189 @@ +const sdk = require('@defillama/sdk'); +const BigNumber = require("bignumber.js"); +const { requery } = require('./requery'); + +const lpReservesAbi = { "constant": true, "inputs": [], "name": "getReserves", "outputs": [{ "internalType": "uint112", "name": "_reserve0", "type": "uint112" }, { "internalType": "uint112", "name": "_reserve1", "type": "uint112" }, { "internalType": "uint32", "name": "_blockTimestampLast", "type": "uint32" }], "payable": false, "stateMutability": "view", "type": "function" } +const lpSuppliesAbi = { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" } +const token0Abi = { "constant": true, "inputs": [], "name": "token0", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" } +const token1Abi = { "constant": true, "inputs": [], "name": "token1", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" } + +/* lpPositions:{ + balance, + token +}[] +*/ +async function unwrapUniswapLPs(balances, lpPositions, block, chain = 'ethereum', transformAddress = (addr) => addr, excludeTokensRaw = [], retry = false, uni_type = 'standard',) { + const excludeTokens = excludeTokensRaw.map(addr => addr.toLowerCase()) + const lpTokenCalls = lpPositions.map(lpPosition => ({ + target: lpPosition.token + })) + const lpReserves = sdk.api.abi.multiCall({ + block, + abi: lpReservesAbi, + calls: lpTokenCalls, + chain + }) + const lpSupplies = sdk.api.abi.multiCall({ + block, + abi: lpSuppliesAbi, + calls: lpTokenCalls, + chain + }) + const tokens0 = sdk.api.abi.multiCall({ + block, + abi: token0Abi, + calls: lpTokenCalls, + chain + }) + const tokens1 = sdk.api.abi.multiCall({ + block, + abi: token1Abi, + calls: lpTokenCalls, + chain + }) + if (retry) { + await Promise.all([ + [lpReserves, lpReservesAbi], + [lpSupplies, lpSuppliesAbi], + [tokens0, token0Abi], + [tokens1, token1Abi] + ].map(async call => { + await requery(await call[0], chain, block, call[1]) + })) + } + await Promise.all(lpPositions.map(async lpPosition => { + try { + let token0, token1, supply + const lpToken = lpPosition.token + const token0_ = (await tokens0).output.find(call => call.input.target === lpToken) + const token1_ = (await tokens1).output.find(call => call.input.target === lpToken) + const supply_ = (await lpSupplies).output.find(call => call.input.target === lpToken) + + token0 = token0_.output.toLowerCase() + token1 = token1_.output.toLowerCase() + supply = supply_.output + // console.log(token0_, supply_, token1_, lpToken) + + if (supply === "0") { + return + } + + let _reserve0, _reserve1 + if (uni_type === 'standard') { + ({ _reserve0, _reserve1 } = (await lpReserves).output.find(call => call.input.target === lpToken).output) + } + else if (uni_type === 'gelato') { + const gelatoPools = sdk.api.abi.multiCall({ + block, + abi: gelatoPoolsAbi, + calls: lpTokenCalls, + chain + }); + const gelatoPool = (await gelatoPools).output.find(call => call.input.target === lpToken).output + const [{ output: _reserve0_ }, { output: _reserve1_ }] = (await Promise.all([ + sdk.api.erc20.balanceOf({ + target: token0, + owner: gelatoPool, + block, + chain + }) + , sdk.api.erc20.balanceOf({ + target: token1, + owner: gelatoPool, + block, + chain + }) + ])) + _reserve0 = _reserve0_ + _reserve1 = _reserve1_ + } + + if (!excludeTokens.includes(token0)) { + const token0Balance = BigNumber(lpPosition.balance).times(BigNumber(_reserve0)).div(BigNumber(supply)) + sdk.util.sumSingleBalance(balances, await transformAddress(token0), token0Balance.toFixed(0)) + } + if (!excludeTokens.includes(token1)) { + const token1Balance = BigNumber(lpPosition.balance).times(BigNumber(_reserve1)).div(BigNumber(supply)) + sdk.util.sumSingleBalance(balances, await transformAddress(token1), token1Balance.toFixed(0)) + } + } catch (e) { + console.log(`Failed to get data for LP token at ${lpPosition.token} on chain ${chain}`) + throw e + } + })) +} +const crv_abi = { + "crvLP_coins": { "stateMutability": "view", "type": "function", "name": "coins", "inputs": [{ "name": "arg0", "type": "uint256" }], "outputs": [{ "name": "", "type": "address" }], "gas": 3123 } +} +async function genericUnwrapCrv(balances, crvToken, lpBalance, block, chain) { + const { output: resolvedCrvTotalSupply } = await sdk.api.erc20.totalSupply({ + target: crvToken, + chain, block + }) + + // Get Curve LP token balances + // A while-loop would need a try-catch because sending error when idx > tokens_count + const { output: crv_symbol } = await sdk.api.abi.call({ + abi: 'erc20:symbol', + target: crvToken, + chain, + block + }) + + const LP_tokens_count = ['3Crv'].includes(crv_symbol) ? 3 : 2 + const coins_indices = Array.from(Array(LP_tokens_count).keys()) + const coins = (await sdk.api.abi.multiCall({ + abi: crv_abi['crvLP_coins'], + calls: coins_indices.map(i => ({ params: [i] })), + target: crvToken, + chain, + block + })).output.map(c => c.output) + const crvLP_token_balances = await sdk.api.abi.multiCall({ + abi: 'erc20:balanceOf', + calls: coins.map(c => ({ + target: c, + params: crvToken, + })), + chain, + block + }) + + // Edit the balances to weigh with respect to the wallet holdings of the crv LP token + crvLP_token_balances.output.forEach(call => + call.output = BigNumber(call.output).times(lpBalance).div(resolvedCrvTotalSupply).toFixed(0) + ) + sdk.util.sumMultiBalanceOf(balances, crvLP_token_balances); +} + +async function sumTokensAndLPs(balances, tokens, block, chain = "ethereum", transformAddress = id => id) { + const balanceOfTokens = await sdk.api.abi.multiCall({ + calls: tokens.map(t => ({ + target: t[0], + params: t[1] + })), + abi: 'erc20:balanceOf', + block, + chain + }) + const lpBalances = [] + balanceOfTokens.output.forEach((result, idx) => { + const token = result.input.target + const balance = result.output + if (tokens[idx][2]) { + lpBalances.push({ + token, + balance + }) + } else { + sdk.util.sumSingleBalance(balances, transformAddress(token), balance); + } + }) + await unwrapUniswapLPs(balances, lpBalances, block, chain, transformAddress) +} + +module.exports = { + unwrapUniswapLPs, + genericUnwrapCrv, + sumTokensAndLPs +} \ No newline at end of file diff --git a/src/helper/utils.js b/src/helper/utils.js new file mode 100644 index 0000000000..3414857bb9 --- /dev/null +++ b/src/helper/utils.js @@ -0,0 +1,38 @@ +const retry = require('async-retry'); +const axios = require('axios'); +const MAX_PROMISE_RETRY = 3; + +async function fetchURL(url) { + return await retry(async (bail) => await axios.get(url), { + retries: 3, + }); +} + +async function tryUntilSucceed(promiseFn, maxTries = MAX_PROMISE_RETRY) { + try { + return await promiseFn(); + } catch (e) { + if (maxTries > 0) { + return tryUntilSucceed(promiseFn, maxTries - 1); + } + throw e; + } +} + +function sliceIntoChunks(arr, chunkSize = 100) { + const res = []; + for (let i = 0; i < arr.length; i += chunkSize) { + const chunk = arr.slice(i, i + chunkSize); + res.push(chunk); + } + return res; +} + +async function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +module.exports = { + fetchURL, + tryUntilSucceed, +}; diff --git a/src/models/enriched.js b/src/models/enriched.js deleted file mode 100644 index b2f853a765..0000000000 --- a/src/models/enriched.js +++ /dev/null @@ -1,123 +0,0 @@ -const mongoose = require('mongoose'); - -const msg = 'A pool must have a <> field'; - -const predictionSchema = new mongoose.Schema( - { - predictedClass: { - type: Number, - }, - predictedProbability: { - type: Number, - }, - confidence: { - type: String, - trim: true, - }, - }, - { versionKey: false, _id: false } -); - -const enrichedSchema = new mongoose.Schema( - { - pool: { - type: String, - required: [true, msg.replace('<>', 'pool')], - trim: true, - unique: true, // === mongoose sets it to unique index - }, - chain: { - type: String, - required: [true, msg.replace('<>', 'chain')], - trim: true, - }, - project: { - type: String, - required: [true, msg.replace('<>', 'project')], - trim: true, - }, - market: { - type: String, - trim: true, - }, - symbol: { - type: String, - required: [true, msg.replace('<>', 'symbol')], - trim: true, - }, - tvlUsd: { - type: Number, - required: [true, msg.replace('<>', 'tvlUsd')], - }, - apy: { - type: Number, - default: null, - }, - timestamp: { - type: Date, - required: [true, msg.replace('<>', 'timestamp')], - }, - projectName: { - type: String, - trim: true, - required: [true, msg.replace('<>', 'projectName')], - }, - apyPct1D: { - type: Number, - default: null, - }, - apyPct7D: { - type: Number, - default: null, - }, - apyPct30D: { - type: Number, - default: null, - }, - stablecoin: { - type: Boolean, - required: [true, msg.replace('<>', 'stablecoin')], - }, - ilRisk: { - type: String, - trim: true, - required: [true, msg.replace('<>', 'ilRisk')], - }, - exposure: { - type: String, - trim: true, - required: [true, msg.replace('<>', 'exposure')], - }, - apyStdExpanding: { - type: Number, - default: null, - }, - apyMeanExpanding: { - type: Number, - default: null, - }, - Stability: { - type: String, - trim: true, - }, - project_factorized: { - type: Number, - }, - chain_factorized: { - type: Number, - }, - predictions: { - type: predictionSchema, - }, - }, - { versionKey: false, timestamps: true } -); - -enrichedSchema.index({ project: 1 }); -enrichedSchema.index({ chain: 1 }); - -const nameModel = 'Enriched'; -const nameCollection = nameModel.toLowerCase(); -const enrichedModel = mongoose.model(nameModel, enrichedSchema, nameCollection); - -module.exports = enrichedModel; diff --git a/src/models/pool.js b/src/models/pool.js deleted file mode 100644 index 314fb020e4..0000000000 --- a/src/models/pool.js +++ /dev/null @@ -1,63 +0,0 @@ -const mongoose = require('mongoose'); - -const poolSchema = new mongoose.Schema( - { - pool: { - type: String, - required: [true, 'A pool must have an pool field'], - trim: true, - }, - chain: { - type: String, - required: [true, 'A pool must have a chain field'], - trim: true, - }, - project: { - type: String, - required: [true, 'A pool must have a project field'], - trim: true, - }, - // for uniswap (v2 vs v3) - market: { - type: String, - trim: true, - }, - symbol: { - type: String, - required: [true, 'A pool must have a symbol field'], - trim: true, - }, - tvlUsd: { - type: Number, - required: [true, 'A pool must have a tvlUsd field'], - }, - apy: { - type: Number, - // either i set it to default null here or I'll need to replace - // NaN and null values from the adaptors with 0? but that would imply a zero apy, which is just - // misleading, so I rather remove the required in here - default: null, - }, - // for historical stuff in db, inserted that field via: - // db.pools.updateMany({}, [{$set: {"timestamp": {$dateTrunc: {date: "$createdAt", unit: "hour"}}}}]) - timestamp: { - type: Date, - required: [true, 'A pool must have a timestamp field'], - }, - }, - // i remove __v versionkey created by mongoose - { versionKey: false } -); - -// compound indices speed up queries significantly -// /latest -> ~50ms -// /chart/pool -> ~1ms -// /offsets/project/day -> ~1ms -poolSchema.index({ pool: 1, timestamp: -1 }); -poolSchema.index({ project: 1, timestamp: -1 }); - -const nameModel = 'Pools'; -const nameCollection = nameModel.toLowerCase(); -const poolModel = mongoose.model(nameModel, poolSchema, nameCollection); - -module.exports = poolModel; diff --git a/src/models/std.js b/src/models/std.js deleted file mode 100644 index 8ed9c0db0c..0000000000 --- a/src/models/std.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose'); - -const stdSchema = new mongoose.Schema( - { - pool: { - type: String, - required: [true, 'A pool must have an pool field'], - trim: true, - }, - count: { - type: Number, - default: null, - }, - mean: { - type: Number, - default: null, - }, - mean2: { - type: Number, - default: null, - }, - }, - { timestamps: true } -); - -stdSchema.index({ pool: 1 }); - -const nameModel = 'Stds'; -const nameCollection = nameModel.toLowerCase(); -const stdModel = mongoose.model(nameModel, stdSchema, nameCollection); - -module.exports = stdModel; diff --git a/src/perpetuals/binance.js b/src/perpetuals/binance.js new file mode 100644 index 0000000000..836cb2a2f9 --- /dev/null +++ b/src/perpetuals/binance.js @@ -0,0 +1,33 @@ +const axios = require('axios'); + +const api = 'https://fapi.binance.com/fapi/v1'; + +exports.getPerpData = async () => { + let fr = (await axios.get(`${api}/premiumIndex`)).data; + // remove futures + fr = fr?.filter((m) => !m.symbol.includes('_')); + + const oiUrls = fr?.map((p) => `${api}/openInterest?symbol=${p.symbol}`); + const oi = (await Promise.allSettled(oiUrls.map((u) => axios.get(u)))) + .filter((m) => m.status === 'fulfilled') + .map((m) => m.value.data); + + const previousFR = (await axios.get(`${api}/fundingRate?limit=${fr.length}`)) + .data; + + return oi.map((m) => { + const frM = fr.find((i) => i.symbol === m.symbol); + const frP = previousFR.find((i) => i.symbol === m.symbol); + + return { + marketplace: 'Binance', + market: m.symbol, + baseAsset: m.symbol.replace(/USDT|BUSD/g, ''), + fundingRate: Number(frM?.lastFundingRate) ?? null, + fundingRatePrevious: Number(frP?.fundingRate), + fundingTimePrevious: frP?.fundingTime, + openInterest: Number(m.openInterest), + indexPrice: Number(frM?.indexPrice), + }; + }); +}; diff --git a/src/perpetuals/bybit.js b/src/perpetuals/bybit.js new file mode 100644 index 0000000000..baf0fe499f --- /dev/null +++ b/src/perpetuals/bybit.js @@ -0,0 +1,36 @@ +const axios = require('axios'); + +const api = 'https://api.bybit.com'; + +exports.getPerpData = async () => { + const bybit = ( + await axios.get(`${api}/v2/public/tickers`) + ).data.result.filter((p) => !p.symbol.includes('23')); + + const previousFRs = ( + await Promise.all( + bybit.map((p) => + axios.get( + `${api}/derivatives/v3/public/funding/history-funding-rate?symbol=${p.symbol}&limit=1` + ) + ) + ) + ) + .map((p) => p.data.result.list) + .flat(); + + return bybit.map((p) => { + const frP = previousFRs.find((i) => i.symbol === p.symbol); + + return { + marketplace: 'Bybit', + market: p.symbol, + baseAsset: p.symbol.replace(/USDT/g, ''), + fundingRate: Number(p.funding_rate), + fundingRatePrevious: Number(frP?.fundingRate), + fundingTimePrevious: Number(frP?.fundingRateTimestamp), + openInterest: Number(p.open_interest), + indexPrice: Number(p.index_price), + }; + }); +}; diff --git a/src/perpetuals/dydx.js b/src/perpetuals/dydx.js new file mode 100644 index 0000000000..482b67b63f --- /dev/null +++ b/src/perpetuals/dydx.js @@ -0,0 +1,32 @@ +const axios = require('axios'); + +const api = 'https://api.dydx.exchange/v3'; + +exports.getPerpData = async () => { + const dydx = Object.values((await axios.get(`${api}/markets`)).data.markets); + + const previousFRs = ( + await Promise.all( + dydx.map((p) => + axios.get(`${api}/historical-funding/${p.market}?limit=1`) + ) + ) + ) + .map((p) => p.data.historicalFunding) + .flat(); + + return dydx.map((p) => { + const frP = previousFRs.find((i) => i.market === p.market); + + return { + marketplace: 'dYdX', + market: p.market, + baseAsset: p.baseAsset, + fundingRate: Number(p.nextFundingRate), + fundingRatePrevious: Number(frP?.rate), + fundingTimePrevious: new Date(frP?.effectiveAt).getTime(), + openInterest: Number(p.openInterest), + indexPrice: Number(p.indexPrice), + }; + }); +}; diff --git a/src/perpetuals/gmx.js b/src/perpetuals/gmx.js new file mode 100644 index 0000000000..10261b71ad --- /dev/null +++ b/src/perpetuals/gmx.js @@ -0,0 +1,82 @@ +const sdk = require('@defillama/sdk'); +const axios = require('axios'); +const { request, gql } = require('graphql-request'); + +const api = 'https://api.gmx.io'; + +const chains = { + arbitrum: { + api: 'https://api.gmx.io', + subgraph: sdk.graph.modifyEndpoint('E15amJKR3s5Wsaa4GeVhHcCzoo7jSu1Kk8SNqY4XXH9i'), + }, + avalanche: { + api: 'https://gmx-avax-server.uc.r.appspot.com', + subgraph: + sdk.graph.modifyEndpoint('9VZwoVRkrXVpbcaprAgFRkLnA3q682wx9JbBnFpLFYqy'), + }, +}; + +const q = gql` + query MyQuery($tokens: [String]) { + fundingRates( + orderBy: endTimestamp + orderDirection: desc + where: { token_in: $tokens } + ) { + id + endFundingRate + endTimestamp + startFundingRate + startTimestamp + token + } + } +`; + +exports.getPerpData = async () => { + const data = await Promise.all( + Object.keys(chains).map(async (chain) => { + const prices = (await axios.get(`${chains[chain].api}/prices`)).data; + const tokens = Object.values( + (await axios.get(`${chains[chain].api}/tokens`)).data + ); + + const markets = Object.keys(prices).map((m) => m.toLowerCase()); + + const fundingRates = ( + await request(chains[chain].subgraph, q, { + tokens: markets, + }) + ).fundingRates.filter((p) => !p.id.includes('total')); + + return Object.entries(prices).map((i) => { + const token = tokens.find((t) => t.id === i[0]).data; + const price = Number(i[1]) / 10 ** 30; + + const oiLong = token.guaranteedUsd / 1e30; + const oiShort = (token.globalShortSize / token.liqMaxPrice) * price; + + const fr = fundingRates.filter( + (t) => t.token.toLowerCase() === i[0].toLowerCase() + )[1]; // 0 -> most recent, 1 -> previous + + const timeDelta = (fr.endTimestamp - fr.startTimestamp) / (60 * 60); + + const frPrevious = + (fr.endFundingRate - fr.startFundingRate) / timeDelta; + + return { + marketplace: `GMX-${chain}`, + market: `${token.symbol}-USD`, + baseAsset: token.symbol, + fundingRate: Number(token.fundingRate) / 1e6, + fundingRatePrevious: frPrevious / 1e6, + fundingTimePrevious: fr.endTimestamp, + openInterest: oiLong + oiShort, + indexPrice: price, + }; + }); + }) + ); + return data.flat(); +}; diff --git a/src/perpetuals/okx.js b/src/perpetuals/okx.js new file mode 100644 index 0000000000..91d8dcbbba --- /dev/null +++ b/src/perpetuals/okx.js @@ -0,0 +1,81 @@ +const axios = require('axios'); + +const api = 'https://www.okx.com/api/v5'; + +exports.getPerpData = async () => { + const okxOI = ( + await axios.get(`${api}/public/open-interest?instType=SWAP`) + ).data.data.filter((m) => m.instId.includes('-USDT-')); + + const frUrls = okxOI.map( + (p) => `${api}/public/funding-rate?instId=${p.instId}` + ); + const okxFR = (await Promise.all(frUrls.map((u) => axios.get(u)))) + .map((m) => m.data.data) + .flat(); + + const markets = [...new Set(okxFR.map((m) => m.instId.replace('-SWAP', '')))]; + + function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + // --- rate limited endpoints (indexPrices and historical FRs) + const maxSize = 10; + let indexPrices = []; + console.log('indexPrices...'); + for (const p of [...Array(Math.ceil(markets.length / maxSize)).keys()]) { + console.log(p); + indexPrices.push( + await Promise.all( + markets + .slice(p * maxSize, maxSize * (p + 1)) + .map((m) => axios.get(`${api}/market/index-tickers?instId=${m}`)) + ) + ); + await sleep(1000); + } + indexPrices = indexPrices + .flat() + .map((m) => m.data.data) + .flat(); + + let previusFRs = []; + console.log('FR history...'); + for (const p of [...Array(Math.ceil(okxFR.length / maxSize)).keys()]) { + console.log(p); + previusFRs.push( + await Promise.all( + okxFR + .map((m) => m.instId) + .slice(p * maxSize, maxSize * (p + 1)) + .map((m) => + axios.get(`${api}/public/funding-rate-history?instId=${m}&limit=1`) + ) + ) + ); + await sleep(1000); + } + previusFRs = previusFRs + .flat() + .map((m) => m.data.data) + .flat(); + + return okxFR.map((p) => { + const frP = previusFRs.find((i) => i.instId === p.instId); + + return { + marketplace: 'OKX', + market: p.instId.replace('-SWAP', ''), + baseAsset: p.instId.split('-')[0], + fundingRate: Number(p.fundingRate), + fundingRatePrevious: Number(frP?.fundingRate), + fundingTimePrevious: Number(frP?.fundingTime), + openInterest: Number(okxOI.find((i) => i.instId === p.instId)?.oiCcy), + indexPrice: Number( + indexPrices.find((i) => i.instId === p.instId.replace('-SWAP', '')) + ?.idxPx + ), + }; + }); +}; diff --git a/src/perpetuals/synthetix.js b/src/perpetuals/synthetix.js new file mode 100644 index 0000000000..b3a5a0ea10 --- /dev/null +++ b/src/perpetuals/synthetix.js @@ -0,0 +1,78 @@ +const sdk = require('@defillama/sdk'); +const { request, gql } = require('graphql-request'); +const { getProvider } = require('@defillama/sdk/build/general'); +const { ethers } = require('ethers'); +const abi = [{"inputs":[{"internalType":"contract IAddressResolver","name":"_resolverProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"allMarketSummaries","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"asset","type":"bytes32"},{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"marketSize","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"currentFundingRate","type":"int256"},{"internalType":"int256","name":"currentFundingVelocity","type":"int256"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketSummary[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"allProxiedMarketSummaries","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"asset","type":"bytes32"},{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"marketSize","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"currentFundingRate","type":"int256"},{"internalType":"int256","name":"currentFundingVelocity","type":"int256"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketSummary[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globals","outputs":[{"components":[{"internalType":"uint256","name":"minInitialMargin","type":"uint256"},{"internalType":"uint256","name":"liquidationFeeRatio","type":"uint256"},{"internalType":"uint256","name":"minKeeperFee","type":"uint256"},{"internalType":"uint256","name":"maxKeeperFee","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FuturesGlobals","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IPerpsV2MarketViews","name":"market","type":"address"}],"name":"marketDetails","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"baseAsset","type":"bytes32"},{"internalType":"bytes32","name":"marketKey","type":"bytes32"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"maxMarketValue","type":"uint256"}],"internalType":"struct PerpsV2MarketData.MarketLimits","name":"limits","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxFundingVelocity","type":"uint256"},{"internalType":"uint256","name":"skewScale","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FundingParameters","name":"fundingParameters","type":"tuple"},{"components":[{"internalType":"uint256","name":"marketSize","type":"uint256"},{"components":[{"internalType":"uint256","name":"long","type":"uint256"},{"internalType":"uint256","name":"short","type":"uint256"}],"internalType":"struct PerpsV2MarketData.Sides","name":"sides","type":"tuple"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"}],"internalType":"struct PerpsV2MarketData.MarketSizeDetails","name":"marketSizeDetails","type":"tuple"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"invalid","type":"bool"}],"internalType":"struct PerpsV2MarketData.PriceDetails","name":"priceDetails","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketData","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"marketKey","type":"bytes32"}],"name":"marketDetailsForKey","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"baseAsset","type":"bytes32"},{"internalType":"bytes32","name":"marketKey","type":"bytes32"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"maxMarketValue","type":"uint256"}],"internalType":"struct PerpsV2MarketData.MarketLimits","name":"limits","type":"tuple"},{"components":[{"internalType":"uint256","name":"maxFundingVelocity","type":"uint256"},{"internalType":"uint256","name":"skewScale","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FundingParameters","name":"fundingParameters","type":"tuple"},{"components":[{"internalType":"uint256","name":"marketSize","type":"uint256"},{"components":[{"internalType":"uint256","name":"long","type":"uint256"},{"internalType":"uint256","name":"short","type":"uint256"}],"internalType":"struct PerpsV2MarketData.Sides","name":"sides","type":"tuple"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"}],"internalType":"struct PerpsV2MarketData.MarketSizeDetails","name":"marketSizeDetails","type":"tuple"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"invalid","type":"bool"}],"internalType":"struct PerpsV2MarketData.PriceDetails","name":"priceDetails","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketData","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"markets","type":"address[]"}],"name":"marketSummaries","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"asset","type":"bytes32"},{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"marketSize","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"currentFundingRate","type":"int256"},{"internalType":"int256","name":"currentFundingVelocity","type":"int256"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketSummary[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"marketKeys","type":"bytes32[]"}],"name":"marketSummariesForKeys","outputs":[{"components":[{"internalType":"address","name":"market","type":"address"},{"internalType":"bytes32","name":"asset","type":"bytes32"},{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"marketSize","type":"uint256"},{"internalType":"int256","name":"marketSkew","type":"int256"},{"internalType":"uint256","name":"marketDebt","type":"uint256"},{"internalType":"int256","name":"currentFundingRate","type":"int256"},{"internalType":"int256","name":"currentFundingVelocity","type":"int256"},{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"}],"internalType":"struct PerpsV2MarketData.FeeRates","name":"feeRates","type":"tuple"}],"internalType":"struct PerpsV2MarketData.MarketSummary[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"marketKey","type":"bytes32"}],"name":"parameters","outputs":[{"components":[{"internalType":"uint256","name":"takerFee","type":"uint256"},{"internalType":"uint256","name":"makerFee","type":"uint256"},{"internalType":"uint256","name":"takerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"takerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"makerFeeOffchainDelayedOrder","type":"uint256"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"},{"internalType":"uint256","name":"maxMarketValue","type":"uint256"},{"internalType":"uint256","name":"maxFundingVelocity","type":"uint256"},{"internalType":"uint256","name":"skewScale","type":"uint256"},{"internalType":"uint256","name":"nextPriceConfirmWindow","type":"uint256"},{"internalType":"uint256","name":"delayedOrderConfirmWindow","type":"uint256"},{"internalType":"uint256","name":"minDelayTimeDelta","type":"uint256"},{"internalType":"uint256","name":"maxDelayTimeDelta","type":"uint256"},{"internalType":"uint256","name":"offchainDelayedOrderMinAge","type":"uint256"},{"internalType":"uint256","name":"offchainDelayedOrderMaxAge","type":"uint256"},{"internalType":"bytes32","name":"offchainMarketKey","type":"bytes32"},{"internalType":"uint256","name":"offchainPriceDivergence","type":"uint256"},{"internalType":"uint256","name":"liquidationPremiumMultiplier","type":"uint256"},{"internalType":"uint256","name":"liquidationBufferRatio","type":"uint256"},{"internalType":"uint256","name":"maxLiquidationDelta","type":"uint256"},{"internalType":"uint256","name":"maxPD","type":"uint256"}],"internalType":"struct IPerpsV2MarketSettings.Parameters","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract IPerpsV2MarketViews","name":"market","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"positionDetails","outputs":[{"components":[{"components":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"uint64","name":"lastFundingIndex","type":"uint64"},{"internalType":"uint128","name":"margin","type":"uint128"},{"internalType":"uint128","name":"lastPrice","type":"uint128"},{"internalType":"int128","name":"size","type":"int128"}],"internalType":"struct IPerpsV2MarketBaseTypes.Position","name":"position","type":"tuple"},{"internalType":"int256","name":"notionalValue","type":"int256"},{"internalType":"int256","name":"profitLoss","type":"int256"},{"internalType":"int256","name":"accruedFunding","type":"int256"},{"internalType":"uint256","name":"remainingMargin","type":"uint256"},{"internalType":"uint256","name":"accessibleMargin","type":"uint256"},{"internalType":"uint256","name":"liquidationPrice","type":"uint256"},{"internalType":"bool","name":"canLiquidatePosition","type":"bool"}],"internalType":"struct PerpsV2MarketData.PositionData","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"marketKey","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"positionDetailsForMarketKey","outputs":[{"components":[{"components":[{"internalType":"uint64","name":"id","type":"uint64"},{"internalType":"uint64","name":"lastFundingIndex","type":"uint64"},{"internalType":"uint128","name":"margin","type":"uint128"},{"internalType":"uint128","name":"lastPrice","type":"uint128"},{"internalType":"int128","name":"size","type":"int128"}],"internalType":"struct IPerpsV2MarketBaseTypes.Position","name":"position","type":"tuple"},{"internalType":"int256","name":"notionalValue","type":"int256"},{"internalType":"int256","name":"profitLoss","type":"int256"},{"internalType":"int256","name":"accruedFunding","type":"int256"},{"internalType":"uint256","name":"remainingMargin","type":"uint256"},{"internalType":"uint256","name":"accessibleMargin","type":"uint256"},{"internalType":"uint256","name":"liquidationPrice","type":"uint256"},{"internalType":"bool","name":"canLiquidatePosition","type":"bool"}],"internalType":"struct PerpsV2MarketData.PositionData","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"resolverProxy","outputs":[{"internalType":"contract IAddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]; + +const subgraph = sdk.graph.modifyEndpoint('H7Dah56WoqjycitDeQ414HGRQcoq9FsSLfrrEx3XevXh'); + +const q = gql` + query f($marketId: String){ + fundingRateUpdates( + orderBy: timestamp + orderDirection: desc + first: 2 + where: { + market_: { + id: $marketId + } + } + ) { + id + funding + fundingRate + timestamp + market { + id + } + } + } +` +exports.getPerpData = async () => { + const PerpsV2MarketData = new ethers.Contract( + "0x58e6227510F83d3F45B339F2f7A05a699fDEE6D4", + abi, + getProvider('optimism') + ); + const markets = (await PerpsV2MarketData.allProxiedMarketSummaries()).map( + m => { + return { + address: m.market.toLowerCase(), + asset: ethers.utils.toUtf8String(m.asset).replace(/s|\0/g, ''), + price: ethers.utils.formatEther(m.price), + openInterest: ethers.utils.formatEther(m.marketSize) + } + } + ); + const fundingRates = ( + await Promise.allSettled( + markets.map( + market => request(subgraph, q, { + marketId: market.address + }) + ) + ) + ).filter((m) => m.status === 'fulfilled') + .map((m) => m.value); + const res = []; + fundingRates.forEach((rate) => { + if (!rate.fundingRateUpdates) return {} + let current = rate.fundingRateUpdates[0]; + let previous = rate.fundingRateUpdates[1]; + const token = markets.find((m) => current.market.id === m.address); + res.push( + { + marketplace: `Synthetix`, + market: `${token.asset}-USD`, + baseAsset: token.asset, + fundingRate: Number(current.fundingRate) / 1e18 / 3, + fundingRatePrevious: Number(previous.fundingRate) / 1e18 / 3, + fundingTimePrevious: Number(previous.timestamp), + openInterest: Number(token.openInterest * token.price), + indexPrice: Number(token.price), + } + ) + } + ) + return res; +} \ No newline at end of file diff --git a/src/queries/config.js b/src/queries/config.js new file mode 100644 index 0000000000..6abb3b25b9 --- /dev/null +++ b/src/queries/config.js @@ -0,0 +1,76 @@ +const { pgp, connect } = require('../utils/dbConnection'); + +const tableName = 'config'; + +const getDistinctProjects = async () => { + const conn = await connect(); + + const query = `SELECT distinct project FROM $`; + + const response = await conn.query(query, { table: tableName }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + return response.map((i) => i.project); +}; + +// get config data per project +const getConfigProject = async (project) => { + const conn = await connect(); + + const query = ` + SELECT + config_id, + pool + FROM + $ + WHERE + project = $ + `; + + const response = await conn.query(query, { table: tableName, project }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + return response; +}; + +// multi row insert (update on conflict) query generator +const buildInsertConfigQuery = (payload) => { + const columns = [ + 'config_id', + 'pool', + 'project', + 'chain', + 'symbol', + // pg-promise is not aware of the db-schema -> we need to make sure that + // optional fields are marked and provided with a default value + // otherwise the `result` method will fail + { name: 'poolMeta', def: null }, + { name: 'underlyingTokens', def: null }, + { name: 'rewardTokens', def: null }, + 'url', + { name: 'ltv', def: null }, + { name: 'borrowable', def: null }, + { name: 'mintedCoin', def: null }, + { name: 'borrowFactor', def: null }, + ]; + const cs = new pgp.helpers.ColumnSet(columns, { table: tableName }); + const query = + pgp.helpers.insert(payload, cs) + + ' ON CONFLICT(config_id) DO UPDATE SET ' + + cs.assignColumns({ from: 'EXCLUDED', skip: 'config_id' }); + + return query; +}; + +module.exports = { + getConfigProject, + buildInsertConfigQuery, + getDistinctProjects, + tableName, +}; diff --git a/src/queries/lsd.js b/src/queries/lsd.js new file mode 100644 index 0000000000..49385bee7f --- /dev/null +++ b/src/queries/lsd.js @@ -0,0 +1,32 @@ +const minify = require('pg-minify'); + +const { pgp, connect } = require('../utils/dbConnection'); + +const insertLsd = async (payload) => { + const conn = await connect(); + + const columns = [ + 'timestamp', + 'name', + 'symbol', + 'address', + { name: 'type', def: null }, + { name: 'expectedRate', def: null }, + { name: 'marketRate', def: null }, + { name: 'ethPeg', def: null }, + { name: 'fee', def: null }, + ]; + const cs = new pgp.helpers.ColumnSet(columns, { table: 'lsd' }); + const query = pgp.helpers.insert(payload, cs); + const response = await conn.result(query); + + if (!response) { + return new AppError(`Couldn't insert/update data`, 404); + } + + return response; +}; + +module.exports = { + insertLsd, +}; diff --git a/src/queries/median.js b/src/queries/median.js new file mode 100644 index 0000000000..87572505e6 --- /dev/null +++ b/src/queries/median.js @@ -0,0 +1,25 @@ +const minify = require('pg-minify'); + +const { pgp, connect } = require('../utils/dbConnection'); + +const tableName = 'median'; + +// insert +const insertMedian = async (payload) => { + const conn = await connect(); + + const columns = ['timestamp', 'uniquePools', 'medianAPY']; + const cs = new pgp.helpers.ColumnSet(columns, { table: tableName }); + const query = pgp.helpers.insert(payload, cs); + const response = await conn.result(query); + + if (!response) { + return new AppError(`Couldn't insert ${tableName} data`, 404); + } + + return response; +}; + +module.exports = { + insertMedian, +}; diff --git a/src/queries/monitor.js b/src/queries/monitor.js new file mode 100644 index 0000000000..798dcaa807 --- /dev/null +++ b/src/queries/monitor.js @@ -0,0 +1,50 @@ +const AppError = require('../utils/appError'); +const exclude = require('../utils/exclude'); +const { pgp, connect } = require('../utils/dbConnection'); + +// get list of stale projects which are still active +const getStaleProjects = async () => { + const conn = await connect(); + + const query = ` +WITH base AS ( + SELECT + * + FROM + config + WHERE + pool NOT IN ($) + AND project NOT IN ($) +) +SELECT + project, + date_trunc('second', NOW() - max(updated_at)) AS stale_since, + count(pool) AS nb_effected_pools +FROM + base +GROUP BY + project +HAVING + max(updated_at) >= NOW() - INTERVAL '$ days' + AND max(updated_at) <= NOW() - INTERVAL '$ HOURS' +ORDER BY + max(updated_at) ASC + `; + + const response = await conn.query(query, { + age: exclude.boundaries.age, + excludePools: exclude.excludePools, + excludeProjects: exclude.excludeAdaptors, + // time (here hours) of min staleness + // (i don't want to log right away but only after n-consecutive failures) + minStaleHours: 6, + }); + + if (!response) { + return new AppError(`Couldn't get data`, 404); + } + + return response; +}; + +module.exports = { getStaleProjects }; diff --git a/src/queries/perp.js b/src/queries/perp.js new file mode 100644 index 0000000000..327108eb57 --- /dev/null +++ b/src/queries/perp.js @@ -0,0 +1,37 @@ +const minify = require('pg-minify'); + +const AppError = require('../utils/appError'); +const { pgp, connect } = require('../utils/dbConnection'); + +const tableName = 'perpetual'; + +// multi row +const insertPerp = async (payload) => { + const conn = await connect(); + + const columns = [ + 'timestamp', + 'marketplace', + 'market', + 'baseAsset', + 'fundingRate', + 'fundingRatePrevious', + 'fundingTimePrevious', + 'openInterest', + 'indexPrice', + ]; + const cs = new pgp.helpers.ColumnSet(columns, { table: tableName }); + const query = pgp.helpers.insert(payload, cs); + + const response = await conn.result(query); + + if (!response) { + return new AppError(`Couldn't insert ${tableName} data`, 404); + } + + return response; +}; + +module.exports = { + insertPerp, +}; diff --git a/src/queries/stat.js b/src/queries/stat.js new file mode 100644 index 0000000000..b548826d52 --- /dev/null +++ b/src/queries/stat.js @@ -0,0 +1,69 @@ +const { pgp, connect } = require('../utils/dbConnection'); + +const tableName = 'stat'; + +// get full content from stat table +const getStat = async () => { + const conn = await connect(); + + const query = ` + SELECT + "configID", + count, + "meanAPY", + "mean2APY", + "meanDR", + "mean2DR", + "productDR" + FROM + $ + `; + const response = await conn.query(query, { table: tableName }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + // reformat + const responseObject = {}; + for (const p of response) { + const configID = p.configID; + responseObject[configID] = { configID, ...p }; + } + + return responseObject; +}; + +// multi row insert (update on conflict) +const insertStat = async (payload) => { + const conn = await connect(); + + const columns = [ + 'configID', + 'count', + 'meanAPY', + 'mean2APY', + 'meanDR', + 'mean2DR', + 'productDR', + ]; + const cs = new pgp.helpers.ColumnSet(columns, { table: tableName }); + + const query = + pgp.helpers.insert(payload, cs) + + ' ON CONFLICT("configID") DO UPDATE SET ' + + cs.assignColumns({ from: 'EXCLUDED', skip: 'configID' }); + + const response = await conn.result(query); + + if (!response) { + return new AppError(`Couldn't insert/update ${tableName} data`, 404); + } + + return response; +}; + +module.exports = { + getStat, + insertStat, +}; diff --git a/src/queries/yield.js b/src/queries/yield.js new file mode 100644 index 0000000000..c54b5b52da --- /dev/null +++ b/src/queries/yield.js @@ -0,0 +1,359 @@ +const AppError = require('../utils/appError'); +const exclude = require('../utils/exclude'); +const { pgp, connect } = require('../utils/dbConnection'); +const { tableName: configTableName } = require('./config'); + +const tableName = 'yield'; + +// get last DB entry per unique pool (with exclusion; this is what we use in enrichment handler) +const getYieldFiltered = async () => { + const conn = await connect(); + + // -- get latest yield row per unique configID (a pool) + // -- exclude if tvlUsd is < LB + // -- exclude if pool age > 7days (speeds up query) + // -- join config data + const query = ` + WITH wanted_cfg AS ( + SELECT * + FROM $ + WHERE pool NOT IN ($) + AND project NOT IN ($) + AND symbol NOT LIKE '%RENBTC%' + ) + SELECT + c.config_id AS "configID", + c.pool, + y.timestamp, + c.project, + c.chain, + c.symbol, + c."poolMeta", + c."underlyingTokens", + c."rewardTokens", + y."tvlUsd", + y.apy, + y."apyBase", + y."apyReward", + y."il7d", + y."apyBase7d", + CASE WHEN y."volumeUsd1d" < 0 THEN NULL ELSE y."volumeUsd1d" END AS "volumeUsd1d", + CASE WHEN y."volumeUsd7d" < 0 THEN NULL ELSE y."volumeUsd7d" END AS "volumeUsd7d", + y."apyBaseInception", + c.url + FROM wanted_cfg AS c + CROSS JOIN LATERAL ( + SELECT * + FROM $ + WHERE "configID" = c.config_id + AND "tvlUsd" >= $ + AND timestamp >= NOW() - INTERVAL '$ DAY' + ORDER BY timestamp DESC + LIMIT 1 + ) AS y + `; + + const response = await conn.query(query, { + tvlLB: exclude.boundaries.tvlUsdUI.lb, + age: exclude.boundaries.age, + yieldTable: tableName, + configTable: configTableName, + excludePools: exclude.excludePools, + excludeProjects: exclude.excludeAdaptors, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + return response; +}; + +const getLatestYieldForPool = async (configID) => { + const conn = await connect(); + + const query = ` + SELECT + y."configID" AS "configID", + c.pool, + y.timestamp, + c.project, + c.chain, + c.symbol, + c."poolMeta", + c."underlyingTokens", + c."rewardTokens", + y."tvlUsd", + y.apy, + y."apyBase", + y."apyReward", + y."il7d", + y."apyBase7d", + CASE WHEN y."volumeUsd1d" < 0 THEN NULL ELSE y."volumeUsd1d" END AS "volumeUsd1d", + CASE WHEN y."volumeUsd7d" < 0 THEN NULL ELSE y."volumeUsd7d" END AS "volumeUsd7d", + y."apyBaseInception", + c.url + FROM $ AS c + CROSS JOIN LATERAL ( + SELECT * + FROM $ + WHERE "configID" = $ + AND timestamp >= NOW() - INTERVAL '$ DAY' + ORDER BY timestamp DESC + LIMIT 1 + ) AS y + WHERE c.config_id = $; + `; + + const response = await conn.query(query, { + configID, + age: exclude.boundaries.age, + yieldTable: tableName, + configTable: configTableName, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + return response; +}; + +// get last DB entry per unique pool for a given project (used by adapter handler to check for TVL spikes) +const getYieldProject = async (project) => { + const conn = await connect(); + + // -- get latest yield row per unique configID (a pool) for a specific project + // -- exclude if tvlUsd is < LB + // -- exclude if pool age > 7days + // -- join config data + const query = ` + SELECT + DISTINCT ON ("configID") "configID", + "tvlUsd", + apy, + timestamp + FROM + $ + WHERE + "configID" IN ( + SELECT + DISTINCT (config_id) + FROM + $ + WHERE + "project" = $ + ) + AND "tvlUsd" >= $ + AND timestamp >= NOW() - INTERVAL '$ DAY' + ORDER BY + "configID", + timestamp DESC + `; + + const response = await conn.query(query, { + tvlLB: exclude.boundaries.tvlUsdUI.lb, + age: exclude.boundaries.age, + project, + yieldTable: tableName, + configTable: configTableName, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} project data`, 404); + } + + return response; +}; + +// get apy offset value for project/day combo +const getYieldOffset = async (project, offset) => { + const conn = await connect(); + + const age = Number(offset); + const daysMilliSeconds = age * 60 * 60 * 24 * 1000; + const tOffset = Date.now() - daysMilliSeconds; + + // 3 hour window + const h = 3; + const tWindow = 60 * 60 * h * 1000; + const tsLB = new Date(tOffset - tWindow); + const tsUB = new Date(tOffset + tWindow); + + const tvlLB = exclude.boundaries.tvlUsdUI.lb; + + // -- retrieve the historical offset data for a every unique pool given an offset day (1d/7d/30d) + // -- to calculate pct changes. allow some buffer (+/- 3hs) in case of missing data (via tsLB and tsUB) + const query = ` + SELECT + DISTINCT ON ("configID") "configID", + apy + FROM + ( + SELECT + "configID", + apy, + abs( + extract ( + epoch + FROM + timestamp - (NOW() - INTERVAL '$ DAY') + ) + ) AS abs_delta + FROM + $ AS y + INNER JOIN config AS c ON c.config_id = y."configID" + WHERE + "tvlUsd" >= $ + AND project = $ + AND timestamp >= $ + AND timestamp <= $ + ) AS y + ORDER BY + "configID", + abs_delta ASC + `; + + const response = await conn.query(query, { + project, + age, + tsLB, + tsUB, + tvlLB, + table: tableName, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} offset data`, 404); + } + + return response; +}; + +// get last DB entry per unique pool (lending/borrow fields only) +const getYieldLendBorrow = async () => { + const conn = await connect(); + + const query = ` + WITH wanted_cfg AS ( + SELECT * + FROM $ + WHERE pool NOT IN ($) + AND project NOT IN ($) + AND symbol NOT LIKE '%RENBTC%' + AND ltv BETWEEN 0 AND 1 + ) + SELECT + c.config_id AS pool, + y."apyBaseBorrow", + y."apyRewardBorrow", + y."totalSupplyUsd", + y."totalBorrowUsd", + y."debtCeilingUsd", + c.ltv, + c.borrowable, + c."mintedCoin", + c."rewardTokens", + c."underlyingTokens", + c."borrowFactor" + FROM wanted_cfg AS c + CROSS JOIN LATERAL ( + SELECT * + FROM $ + WHERE "configID" = c.config_id + AND timestamp >= NOW() - INTERVAL '$ DAY' + AND "totalSupplyUsd" >= 0 + ORDER BY timestamp DESC + LIMIT 1 + ) AS y; + `; + + const response = await conn.query(query, { + tvlLB: exclude.boundaries.tvlUsdUI.lb, + age: exclude.boundaries.age, + yieldTable: tableName, + configTable: configTableName, + excludePools: exclude.excludePools, + excludeProjects: exclude.excludeAdaptors, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} data`, 404); + } + + return response; +}; + +// get 30day avg +const getYieldAvg30d = async () => { + const conn = await connect(); + + const query = ` + SELECT + "configID", + round(avg(apy), 5) as "avgApy30d" + FROM + $ + WHERE + timestamp >= NOW() - INTERVAL '$ DAY' + GROUP BY + "configID" + `; + + const response = await conn.query(query, { + age: 30, + table: tableName, + }); + + if (!response) { + return new AppError(`Couldn't get ${tableName} 30day avg data`, 404); + } + + // reformat + const responseObject = {}; + for (const p of response) { + responseObject[p.configID] = p.avgApy30d; + } + + return responseObject; +}; + +// multi row insert query generator +const buildInsertYieldQuery = (payload) => { + // note: even though apyBase and apyReward are optional fields + // they are both added in the adapter handler to derive final apy. + // hence, there is no need to specify optional fields defaults for pg-promise + // (in contrast to some fields in `insertConfig`) + const columns = [ + 'configID', + 'timestamp', + 'tvlUsd', + 'apy', + 'apyBase', + 'apyReward', + 'il7d', + 'apyBase7d', + 'apyRewardFake', + 'apyRewardBorrowFake', + 'volumeUsd1d', + 'volumeUsd7d', + 'apyBaseInception', + { name: 'apyBaseBorrow', def: null }, + { name: 'apyRewardBorrow', def: null }, + { name: 'totalSupplyUsd', def: null }, + { name: 'totalBorrowUsd', def: null }, + { name: 'debtCeilingUsd', def: null }, + ]; + const cs = new pgp.helpers.ColumnSet(columns, { table: tableName }); + return pgp.helpers.insert(payload, cs); +}; + +module.exports = { + getYieldFiltered, + getLatestYieldForPool, + getYieldOffset, + getYieldProject, + getYieldLendBorrow, + buildInsertYieldQuery, + getYieldAvg30d, +}; diff --git a/src/types/Pool.d.ts b/src/types/Pool.d.ts new file mode 100644 index 0000000000..d3fb6d7994 --- /dev/null +++ b/src/types/Pool.d.ts @@ -0,0 +1,19 @@ +export interface Pool { + pool: string; + chain: string; + project: string; + symbol: string; + tvlUsd: number; // for lending protocols: tvlUsd = totalSupplyUsd - totalBorrowUsd + apyBase?: number; + apyReward?: number; + rewardTokens?: Array; + underlyingTokens?: Array; + poolMeta?: string; + url?: string; + // optional lending protocol specific fields: + apyBaseBorrow?: number; + apyRewardBorrow?: number; + totalSupplyUsd?: number; + totalBorrowUsd?: number; + ltv?: number; // btw [0, 1] +} \ No newline at end of file diff --git a/src/utils/dbConnection.js b/src/utils/dbConnection.js new file mode 100755 index 0000000000..50c9d0a2ca --- /dev/null +++ b/src/utils/dbConnection.js @@ -0,0 +1,54 @@ +const path = require('path'); + +require('dotenv').config({ path: path.resolve(__dirname, '../../config.env') }); + +const pgp = require('pg-promise')({ + /* initialization options */ + capSQL: true, // capitalize all generated SQL +}); +// set type options (pg-promise returns integers and numeric types as strings) +// id 20 = INTEGER +// id 1700 = NUMERIC +pgp.pg.types.setTypeParser(20, parseInt); +pgp.pg.types.setTypeParser(1700, parseFloat); + +// on first connect, cache db connection for reuse so we don't +// need to connect on new requests +let conn = null; + +const connect = async () => { + if (conn === null) { + console.log('using new db connection'); + // set connection + conn = pgp({ + connectionString: process.env.DATABASE_URL, + // max milliseconds a client can go unused before it is removed + // from the connection pool and destroyed. + // overriding default of 30sec to 60sec to decrease nb of potential reconnects of 1 lambda + // running multiple adapters + idleTimeoutMillis: 30000, + max: 5, + }); + } + return conn; +}; + +// SIGTERM Handler +// from https://github.com/aws-samples/graceful-shutdown-with-aws-lambda +process.on('SIGTERM', async () => { + console.info('[runtime] SIGTERM received'); + + console.info('[runtime] cleaning up'); + if(conn !== null){ + let realConn = await conn + await realConn.$pool.end() + } + + console.info('[runtime] exiting'); + process.exit(0) +}); + +module.exports = { + pgp, + connect, +}; diff --git a/src/utils/discordWebhook.js b/src/utils/discordWebhook.js new file mode 100644 index 0000000000..7d742d66f0 --- /dev/null +++ b/src/utils/discordWebhook.js @@ -0,0 +1,28 @@ +const fetch = require('node-fetch'); + +// copy pasta from defillama-server +module.exports.sendMessage = async (message, webhookUrl, formatted = true) => { + const formattedMessage = formatted ? '```\n' + message + '\n```' : message; // Put it into a code block to prevent the format from getting messed up + if (formattedMessage.length >= 2000) { + const lines = message.split('\n'); + if (lines.length <= 2) { + throw new Error('Lines are too long, reaching infinite recursivity'); + } + const mid = Math.round(lines.length / 2); + await sendMessage(lines.slice(0, mid).join('\n'), webhookUrl); + await sendMessage(lines.slice(mid).join('\n'), webhookUrl); + return; + } + // Example: https://gist.github.com/dragonwocky/ea61c8d21db17913a43da92efe0de634 + // Docs: https://gist.github.com/dragonwocky/ea61c8d21db17913a43da92efe0de634 + const response = await fetch(`${webhookUrl}?wait=true`, { + method: 'post', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + content: formattedMessage, + }), + }).then((body) => body.json()); + console.log('discord', response); +}; diff --git a/src/utils/enrichedColumns.js b/src/utils/enrichedColumns.js new file mode 100644 index 0000000000..cfa553d2d3 --- /dev/null +++ b/src/utils/enrichedColumns.js @@ -0,0 +1,32 @@ +const poolsResponseColumns = [ + 'chain', + 'project', + 'symbol', + 'tvlUsd', + 'apyBase', + 'apyReward', + 'apy', + 'rewardTokens', + 'pool', + 'apyPct1D', + 'apyPct7D', + 'apyPct30D', + 'stablecoin', + 'ilRisk', + 'exposure', + 'predictions', + 'poolMeta', + 'mu', + 'sigma', + 'count', + 'outlier', + 'underlyingTokens', + 'il7d', + 'apyBase7d', + 'apyMean30d', + 'volumeUsd1d', + 'volumeUsd7d', + 'apyBaseInception', +]; + +module.exports = poolsResponseColumns; diff --git a/src/utils/exclude.js b/src/utils/exclude.js new file mode 100644 index 0000000000..40aa73f15f --- /dev/null +++ b/src/utils/exclude.js @@ -0,0 +1,690 @@ +const axios = require('axios'); + +// adaptors which we don't want to be triggered + +// which we don't want to be included in the enriched dataset +// in case we have old values in db +// note (added cbridge cause their apy values are kinda fake given they move the positions to a different chain) +const excludeAdaptors = [ + 'koyo-finance', + 'pony-finance', + 'optifi', + 'cbridge', + 'friktion', + 'armor', // is now ease.org + 'lachain-yield-market', + 'euler', // adapter is breaking since hack, need to fix, + 'ratio-finance', + '0vix', // pausing cause of hack + 'rehold', // apy values are fake + 'deficurrent', // vaults deprecated + 'dogium-farm', // seems to be dead + 'zest-protocol', // tiny pools + 'hedge', // seems to be dead, ui not working + 'double-club', // seems to be dead + 'yieldwolf', // dead + 'hubble-exchange', // no live pools + 'yodeswap', // v1 deprecated + 'optyfi', // dead + 'rodeo', // exploited + 'fairfi', // seems dead + 'mole', // needs to be reimplement + 'luxsfi', + 'geist-finance', + 'el-dorado-exchange', // hacked + 'sturdy', // hacked + // removing cause a) curve pool is redundant cause we already have that on curve adapter + // and the rebonding strategy is targeting a max apy + 'lusd-chickenbonds', + 'eternal-finance', + 'wild-base', // empty + 'vendor-v1', // empty + 'uncx-network-v2', + 'rocifi-v2', + 'steadefi', // hacked, + 'bank-of-chain', + 'myso-v1', + 'civfund', + 'midas-capital', + 'pearlfi', // tmp + 'foodcourt', + 'yield-protocol', + 'autofarm', + 'complifi', + 'illuminate', + 'klap', + 'polylend', + 'tempus-finance', + 'kolibri', + 'vires-finance', + 'nftx', + 'mahadao-arth', + 'xy-finance', + 'quoll', + 'omnidex-lend', + 'ease.org', + 'kyberswap-elastic', + 'penrose', + 'unknown', + 'mooncake-finance', + 'hydradex-v2', + 'apollodao', + 'liqee', + 'earnmos', + 'magik-farm', + 'swapfish', + 'rage-trade', + 'ottopia', + 'velodrome-v1', + 'brinc-finance', + 'nuls-pocm', + 'unipilot', + 'deri-protocol', + 'frakt', + 'goledo', + 'archly-v1', + 'polytrade', + '3xcalibur', + 'onering-v2', + 'wise-lending', + 'nudes', + 'pickle', + 'mycelium-perpetual-swaps', + 'lyra-v1', + 'reflexer', + 'robo-vault', + 'neutra-finance', + 'insuredao', + 'barnbridge', + 'homora-v2', + 'jelly', + 'mahalend', + 'mixswap-finance', + 'muuu-finance', + 'orbitalswap', + 'securo-finance', + 'sharpe-magnum', + 'stella', + 'teahouse-managed', + 'thegoblins', + 'unlockd', + 'valas-finance', + 'veplus', + 'whaleswap', + 'y2k-v2', + 'zest-protocol', + 'pembrock-finance', + 'yieldlend', + 'iron-bank', + 'swapr-v2', + 'agave', + 'blueshift', + 'gyroscope-protocol', + 'blue-planet', + 'archimedes-finance', + 'koi-finance-amm', + 'kagla-finance', + 'plenty', + 'platypus-finance', + 'biswap-v2', + 'burrow', + 'ref-finance', + 'shoebill-v1', + 'auragi-finance', + 'notional-v2', + 'stablebase', + 'hedgefarm', + 'vendor-v2', + 'beanstalk', + 'tenderize-v1', + 'blastnyan', + 'forge', + 'stakehouse', + 'yeti-finance', + 'lst-optimizer', + 'mellow-yield', + 'glacier-exchange-v2', + 'pinjam-labs', + 'horizondex', + 'equilibre', + 'maia-dao', + 'hermes-protocol', + 'xtoken', + 'arbitrum-exchange-v3', + 'bfx-(blast-futures)', + 'stack', + 'liquid-bolt', + 'avault', + 'metastreet-v2', + 'mero', + 'meteora', // pushed by mistake + 'rhino.fi', + 'icpex', + 'nx-finance', + 'c3-exchange', + 'bagful', + 'conic-finance', + 'cadabra-finance', + 'zeroliquid', + 'corepound', + 'midas-rwa', + 'stream-finance', + 'impermax-v3', + 'gmx-v1-perps', + 'orange-finance', + 'struct-finance', + 'gloop', + 'ribbon', +]; + +const excludePools = [ + '0xf4bfe9b4ef01f27920e490cea87fe2642a8da18d', + 'DWmAv5wMun4AHxigbwuJygfmXBBe9WofXAtrMCRJExfb', // Solend COOL coin pool + // ripae pools (reported by MathieuB as scam project, and definitely not noIL!) + 'ripae-seth-weth-42161', + 'ripae-peth-weth-42161', + '0x3eed430cd45c5e2b45aa1adc609cc77c6728d45b', // mind-wavax on traderjoe, snowtrace shows tiny lp value, but tvl is huge + '0x3c42B0f384D2912661C940d46cfFE1CD10F1c66F-ethereum', // test pool on curve? (CTDL-WBTC) + '0x165ab553871b1a6b3c706e15b6a7bb29a244b2f3', // XSTUSD-WETH on uniswap + '0xf81ebbc00b9bbc3a0b0cb1bc4e87ac157028698f', // nitrodoge on sushiswap, tvl on our side is way to large + '0xEc54859519293B8784bc5Bf28144166f313618aF', // dai-o uniswap + 'BRnJFznuWEuqMZTHGKyWjYijugcj8wtb3oiLMyu2Tj4R', // usdh soldust pool + '0xec54859519293b8784bc5bf28144166f313618af', // dai-o uniswap + '0xE6D31ab5607eb7618a16B5923b67314d16BD350f-miMATIC-fantom', // decomissioned tarot pool + // bunch of aave-v3 pools on fantom, are all frozen (updated adapter to consider frozen state, but need to add here + // otherwise we' gonna see those pools on the UI for the next 7days. (can be removed afterwards)) + '0x191c10aa4af7c30e871e70c95db0e4eb77237530-fantom', + '0x6d80113e533a2c0fe82eabd35f1875dcea89ea97-fantom', + '0x078f358208685046a11c85e8ad32895ded33a249-fantom', + '0xf329e36c7bf6e5e86ce2150875a84ce77f477375-fantom', + '0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8-fantom', + '0x82e64f49ed5ec1bc6e43dad4fc8af9bb3a2312ee-fantom', + '0x6ab707aca953edaefbc4fd23ba73294241490620-fantom', + '0xc45a479877e1e9dfe9fcd4056c699575a1045daa-fantom', + '0x625e7708f30ca75bfd92586e17077590c60eb4cd-fantom', + '0x513c7e3a9c69ca3e22550ef58ac1c0088e918fff-fantom', + '0xf0d17f404343D7Ba66076C818c9DC726650E2435-dot-dot-finance', + '0xa3B615667CBd33cfc69843Bf11Fbb2A1D926BD46-6', // magpie ABNBC pool + '0x1d03D8199f43ea030a5D1c2a5d4675d18581D129', // dino pool form unicrypt, jumped from 1mil to > 800mil in tvl + '0x726e324c29a1e49309672b244bdc4ff62a270407000200000000000000000702', // USDC-XSGD balancer pool on polygon. can't find on UI + '0xf4c0dd9b82da36c07605df83c8a416f11724d88b', // GNO-WETH on aura + '0xa33c1963d74d203df6bffdfda3bff39a1d76e1d0', // sol pool on lyra + '0x7a5011bf1dad77a23ec35ce04dcc2ac7d29963c5', // matic-peco + '0x19D3364A399d251E894aC732651be8B0E4e85001', // ydai + '0x09AA7178049Ba617119425A80faeee12dBe121de', // weth on klap + '0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9', // old usdc vault on yearn + '0x152d62dccc2c7c7930c4483cc2a24fefd23c24c2-fantom', + '0x5427f192137405e6a4143d1c3321359bab2dbd87-fantom', + '0x7a5011bf1dad77a23ec35ce04dcc2ac7d29963c5', + '0x45859D71D4caFb93694eD43a5ecE05776Fc2465d-dot-dot-finance', // until fixed + '0xc3d088842dcf02c13699f936bb83dfbbc6f721ab', // bifrost veth v1 + '0x015908fec4ac33782d7bcd7a6ae88ab0ade405f4', //drop-usdc pool + '0x7578aa78d5c5f622800d9205e942b12d353432b7', + '0x05d3d04f1aeb77d591a0581827b148ea634c0d1c', + '0xc1b228c22ca914069c7164e5489e8d79a9cbb922', + '0xe50341e6f27a2514908f347e743119f3dfd84ad5', + '0xb59A93eAB4059C58d33b0c29fE4Fa3F3433997cc', + '0xB657B895B265C38c53FFF00166cF7F6A3C70587d', + // curve exploit + '0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511-ethereum', + '0xC4C319E2D4d66CcA4464C0c2B32c9Bd23ebe784e-ethereum', + '0xc897b98272AA23714464Ea2A0Bd5180f1B8C0025-ethereum', + '0x9848482da3Ee3076165ce6497eDA906E66bB85C5-ethereum', + '0x4CF4f433e359a343648c480b2f3952FD64616a9a', // peth harvest + '0x7ba1D55606900c5028Fb3BB82Fa0c198e3b0580E', + '0x0DEA7dc835e2dB8E1fF8853577a5B8D5E5F55413', + '0xB3D81Fad8f5092903592249d30cdeBD681057153', + '0x80eF5eF7099C69bC9fcF952217240331F96bdF5F', + + // balancer hack + // https://github.com/BalancerMaxis/multisig-ops/blob/main/BIPs/00notGov/2023-08-mitigation.md + '0x2b4af4bb149cc06f5de580be013e86f81e4d2b30000100000000000000000373', + '0xb0de49429fbb80c635432bbad0b3965b2856017700010000000000000000004e', + '0x585d95df0231fa08aeee35ff0c16b92fd0ecdc3300020000000000000000045f', + '0xb3d658d5b95bf04e2932370dd1ff976fe18dd66a000000000000000000000ace', + '0xf572649606db4743d217a2fa6e8b8eb79742c24a000000000000000000000039', + '0x48e6b98ef6329f8f0a30ebb8c7c960330d64808500000000000000000000075b', + '0xc7e6389e364f4275eb442ef215ed21877028e2af000000000000000000000ac7', + '0x0bc54e914f53f98d16035f4f0d948f3e09c2fac0000200000000000000000bac', + '0x02e139d53ebf4033bf78ab66c6a1e7f1f204487f0002000000000000000009f9', + '0xb973ca96a3f0d61045f53255e319aedb6ed49240000200000000000000000011', + '0x3efb91c4f9b103ee45885695c67794591916f34e000200000000000000000b43', + '0xc2b021133d1b0cf07dba696fd5dd89338428225b000000000000000000000598', + '0xa3ed6f78edc29f69df8a0d16b1d1ccf9871f918c000000000000000000000032', + '0x53bc3cba3832ebecbfa002c12023f8ab1aa3a3a0000000000000000000000411', + '0x5a6a8cffb4347ff7fc484bf5f0f8a2e234d34255000200000000000000000275', + '0x9fb771d530b0ceba5160f7bfe2dd1e8b8aa1340300000000000000000000040e', + '0xe78b25c06db117fdf8f98583cdaaa6c92b79e917000000000000000000000b2b', + '0x302b8b64795b064cadc32f74993a6372498608070001000000000000000003e0', + '0xdfc65c1f15ad3507754ef0fd4ba67060c108db7e000000000000000000000406', + '0x9a020bdc2faff5bd24c6acc2020d01ff9f2c627a000000000000000000000ae2', + '0xa55318e5d8b7584b8c0e5d3636545310bf9eeb8f000000000000000000000337', + '0x970712708a08e8fb152be4d81b2dc586923f5369000200000000000000000479', + '0x559d2ac340216e3a6630741147cda6a2cdbc2be10001000000000000000005de', + '0xb95829adbacd8af89e291dee78bc09e24de51d6b000000000000000000000043', + '0xe94c45de980f914904fdcfa9fbbe7c4a0ffe6ac70000000000000000000000e0', + '0x1379b816b9be611431d693290289c204720ca56d000100000000000000000b6f', + '0x7b50775383d3d6f0215a8f290f2c9e2eebbeceb20000000000000000000000fe', + '0x6abe4e7a497b8293c258389c1b00d177e4f257ed00010000000000000000080d', + '0x2a96254ca32020b20ed3506f8f75318da24709f9000200000000000000000456', + '0x4cbde5c4b4b53ebe4af4adb85404725985406163000000000000000000000595', + '0xee02583596aee94cccb7e8ccd3921d955f17982a00000000000000000000040a', + '0xd3d5d45f4edf82ba0dfaf061d230766032a10e07000200000000000000000413', + '0x8fd39252d683fdb60bddd4df4b53c9380b496d59000200000000000000000b45', + '0x88e2a551655daadd7e4e67d14cf48bfb413d72680001000000000000000005d2', + '0x7d6bff131b359da66d92f215fd4e186003bfaa42000000000000000000000058', + '0x41503c9d499ddbd1dcdf818a1b05e9774203bf46000000000000000000000594', + '0xeb567dde03f3da7fe185bdacd5ab495ab220769d000000000000000000000548', + '0x7fe29a818438ed2759e30f65c2302295711d66fc0000000000000000000000e5', + '0xfedb19ec000d38d92af4b21436870f115db22725000000000000000000000010', + '0xf48f01dcb2cbb3ee1f6aab0e742c2d3941039d56000000000000000000000445', + '0x20b156776114e8a801e9767d90c6ccccc8adf398000000000000000000000499', + '0x8d13d878e44e8005efc0db4a831b95f84cb4b1540000000000000000000003c6', + '0xa13a9247ea42d743238089903570127dda72fe4400000000000000000000035d', + '0x05e7732bf9ae5592e6aa05afe8cd80f7ab0a7bea00020000000000000000005a', + '0xf22a66046b5307842f21b311ecb4c462c24c0635000000000000000000000b15', + '0xd2f3b9e67c69762dd1c88f1d3dadd1649a190761000200000000000000000bf7', + '0x174d2608b1d794e9078ae2a4861684a38d4e7ae200020000000000000000065b', + '0x2645b13fd2c5295296e94a76280b968bdcbbdfed000000000000000000000c11', + '0x66f33ae36dd80327744207a48122f874634b3ada000100000000000000000013', + '0x959216bb492b2efa72b15b7aacea5b5c984c3cca000200000000000000000472', + '0xe8c56405bc405840154d9b572927f4197d110de10000000000000000000005a4', + '0x53dd233c2af0147846579010b7c80bf9440afff4000200000000000000000602', + '0x882c7a84231484b3e9f3fd45ac04b1eb5d35b076000200000000000000000a91', + '0xac2cae8d2f78a4a8f92f20dbe74042cd0a8d5af3000000000000000000000be2', + '0x00c2a4be503869fa751c2dbcb7156cc970b5a8da000000000000000000000477', + '0xed35f28f837e96f81240ebb82e0e3f518c7e8a2f000100000000000000000bb5', + '0xf28f17be00f8ca3c9b7f66a4aad5513757fb3341000200000000000000000b5a', + '0xe0b50b0635b90f7021d2618f76ab9a31b92d009400010000000000000000003a', + '0xbec621c9ab4ceddcc2a157ca9b5c475fab65f6a40000000000000000000000f3', + '0xba1a5b19d09a79dada039b1f974015c5a989d5fd000100000000000000000046', + '0x64dea772866476c9f88fbe95ee83664d6c909c1800000000000000000000022c', + '0xece571847897fd61e764d455dc15cf1cd9de8d6f000000000000000000000014', + '0x89f1146fee52b5d9166e9c83cc388b6d8f69f1380001000000000000000009e7', + '0xe051605a83deae38d26a7346b100ef1ac2ef8a0b0000000000000000000003ce', + '0xe6909c2f18a29d97217a6146f045e1780606991f000100000000000000000bfe', + '0x1e550b7764da9638fdd32c8a701364de31f45ee800000000000000000000047c', + '0x9cf9358300e34bf9373d30129a1e718d8d058b54000200000000000000000913', + '0x62de5ca16a618e22f6dfe5315ebd31acb10c44b6000000000000000000000037', + '0xa718042e5622099e5f0ace4e7122058ab39e1bbe000200000000000000000475', + '0xbe0f30217be1e981add883848d0773a86d2d2cd4000000000000000000000471', + '0x45c4d1376943ab28802b995acffc04903eb5223f000000000000000000000470', + '0x133d241f225750d2c92948e464a5a80111920331000000000000000000000476', + '0xe274c9deb6ed34cfe4130f8d0a8a948dea5bb28600000000000000000000000d', + '0x6c56e72c551b5ac4bf54a620a76077ca768c8fe40002000000000000000004da', + '0xf7705cd188a8ac806d28f85bdb13a38313e985ff0000000000000000000005b7', + '0x23ca0306b21ea71552b148cf3c4db4fc85ae19290000000000000000000000ac', + '0x60683b05e9a39e3509d8fdb9c959f23170f8a0fa000000000000000000000489', + '0x8a2872fd28f42bd9f6559907235e83fbf4167f480001000000000000000000f2', + '0x593acbfb1eaf3b6ec86fa60325d816996fdcbc0d000000000000000000000038', + '0xe4dc3c1998ac693d68f4c77476d7c815694c3e94000200000000000000000416', + '0x077794c30afeccdf5ad2abc0588e8cee7197b71a000000000000000000000352', + '0xc443c15033fcb6cf72cc24f1bda0db070ddd9786000000000000000000000593', + '0x04b54ea92d73de2d62d651db7d9778f0c49157d8000200000000000000000ba2', + '0xba0e9aea8a7fa1daab4edf244191f2387a4e472b000100000000000000000737', + '0xb1c9ac57594e9b1ec0f3787d9f6744ef4cb0a02400000000000000000000006e', + '0x05513ca725b6ce035ca2641075474eb469f05f4c00020000000000000000041f', + '0x8fbd0f8e490735cfc3abf4f29cbddd5c3289b9a7000000000000000000000b5b', + '0x62cf35db540152e94936de63efc90d880d4e241b0000000000000000000000ef', + '0x4ce0bd7debf13434d3ae127430e9bd4291bfb61f00020000000000000000038b', + '0xc46066ff87b3861ffc5c26ad2e9705190c22aa56000000000000000000000727', + '0x519cce718fcd11ac09194cff4517f12d263be067000000000000000000000382', + '0x779d01f939d78a918a3de18cc236ee89221dfd4e0000000000000000000004c7', + '0x054e7b0c73e1ee5aed6864fa511658fc2b54bcaa000000000000000000000015', + '0x1bd2f176a812e312077bca87e37c08432bb09f3e0000000000000000000005a1', + '0x6e6dc948ce85c62125ff7a1e543d761a88f0a4cb000000000000000000000743', + '0x8a6b25e33b12d1bb6929a8793961076bd1f9d3eb0002000000000000000003e8', + '0xb371aa09f5a110ab69b39a84b5469d29f9b22b76000000000000000000000b37', + '0x1e2576344d49779bdbb71b1b76193d27e6f996b700020000000000000000032d', + '0xde45f101250f2ca1c0f8adfc172576d10c12072d00000000000000000000003f', + '0x9b692f571b256140a39a34676bffa30634c586e100000000000000000000059d', + '0xe2d16b0a39f3fbb4389a0e8f1efcbecfb3d1e6e10000000000000000000005a7', + '0x4c8d2e60863e8d7e1033eda2b3d84e92a641802000000000000000000000040f', + '0xfe48fefea11cceb3bdeb328428f1b25446edad700001000000000000000003d2', + '0x31adc46737ebb8e0e4a391ec6c26438badaee8ca000000000000000000000306', + '0x0392ebb4aea38233e5b89acfabf7b418cdea8e4300010000000000000000073f', + '0xcba9ff45cfb9ce238afde32b0148eb82cbe635620000000000000000000003fd', + '0xf42ed61450458ee4620f5ef4f29adb25a6ef0fb6000000000000000000000bf8', + '0xdb455199d96d5513d831f0029bd819597bc9d158000200000000000000000728', + '0x600bd01b6526611079e12e1ff93aba7a3e34226f0000000000000000000009e4', + '0x592fa9f9d58065096f2b7838709c116957d7b5cf00020000000000000000043c', + '0x402cfdb7781fa85d52f425352661128250b79e12000000000000000000000be3', + '0xa5a935833f6a5312715f182733eab088452335d7000100000000000000000bee', + '0x428e1cc3099cf461b87d124957a0d48273f334b100000000000000000000007f', + '0x30c016f5cf1d34c1bce4c8c9c302f66a268847fd0001000000000000000003f6', + '0x1352fd97a1828093bf375f62e088bc196facd1ee000000000000000000000404', + '0xea256adb68dffd067d27e95f4ad14eba12e86079000100000000000000000586', + '0x3f7a7fd7f214be45ec26820fd01ac3be4fc75aa70002000000000000000004c5', + '0xa10285f445bcb521f1d623300dc4998b02f11c8f00000000000000000000043b', + '0xea52e5eb660ba64b9ba10ad9ae55a8156aa4d29a0002000000000000000003a2', + '0x0c06e87c7b88d998f645b91c1f53b51294b12bca000100000000000000000bb9', + '0x150e7b885bdfce974f2abe88a72fdbd692175c6f0002000000000000000009fd', + '0x32be2d0ddeaf3333501b24a28668ce373ba8e763000200000000000000000014', + '0x173063a30e095313eee39411f07e95a8a806014e0002000000000000000003ab', + '0x6da14f5acd58dd5c8e486cfa1dc1c550f5c61c1c0000000000000000000003cf', + '0x435272180a4125f3b47c92826f482fc6cc165958000200000000000000000059', + '0xc6eee8cb7643ec2f05f46d569e9ec8ef8b41b389000000000000000000000475', + '0x10441785a928040b456a179691141c48356eb3a50001000000000000000002fa', + '0xf47f4d59c863c02cbfa3eefe6771b9c9fbe7b97800000000000000000000072b', + '0xfebb0bbf162e64fb9d0dfe186e517d84c395f016000000000000000000000502', + '0x6c8c7fc50247a47038015eb1fd5dc105d05dafba000200000000000000000ba0', + '0x9d7f992c900fbea0ec314bdd71b7cc1becf76a33000200000000000000000573', + '0x4a0b73f0d13ff6d43e304a174697e3d5cfd310a400020000000000000000091c', + '0xec3626fee40ef95e7c0cbb1d495c8b67b34d398300000000000000000000053d', + '0xab269164a10fab22bc87c39946da06c870b172d6000000000000000000000bfc', + '0xbd4e35784c832d0f9049b54cb3609e5907c5b495000100000000000000000b14', + '0xbbf9d705b75f408cfcaee91da32966124d2c6f7d00000000000000000000047e', + '0x64cee2338369aa9b36fc756ea231eb9bc242926f0000000000000000000000df', + '0xcd7b2232b7435595bbc7fd7962f1f352fc2cc61a0000000000000000000000f0', + '0x64b301e21d640f9bef90458b0987d81fb4cf1b9e00020000000000000000022e', + '0x341068a547c3cde3c09e338714010dd01b32f93f000200000000000000000a34', + '0x5470f064a19c65263b3033da3a6124fdf0a9bab80000000000000000000000e6', + '0x9cebf13bb702f253abf1579294694a1edad00eaa000000000000000000000486', + '0x2e0d46d884af4053787e1838793bf98dcb87488e00020000000000000000072c', + '0xe2dc0e0f2c358d6e31836dee69a558ab8d1390e70000000000000000000009fa', + '0xe1c86d3908dc524aa3555e56adf973de7d3acdba000100000000000000000267', + '0x00fcd3d55085e998e291a0005cedecf58ac14c4000020000000000000000047f', + '0xf86785fe1cefd5069e6df1b4b54b72b1992003110000000000000000000005b3', + '0xcf87708ea94916d7ccd13b86ce56006472d806fe000100000000000000000378', + '0xffecea216f0d0d08bfe2cf572e03f217f8a2bf1300020000000000000000041a', + '0xa154009870e9b6431305f19b09f9cfd7284d4e7a000000000000000000000013', + '0xe0fcbf4d98f0ad982db260f86cf28b49845403c5000000000000000000000504', + '0x624601b34e64a48ef91a6bf888e74ef3eceb1bf9000100000000000000000419', + '0xf57c794f42da72b38c8f610ff3b5e8502e48cbde00000000000000000000055c', + '0x56897add6dc6abccf0ada1eb83d936818bc6ca4d0002000000000000000002e8', + '0xb5e3de837f869b0248825e0175da73d4e8c3db6b000200000000000000000474', + '0xd7edb56f63b2a0191742aea32df1f98ca81ed9c600000000000000000000058e', + '0xac6286126044e2ee2589d394a102cb54b7ab15a7000200000000000000000629', + '0x8b8225bfedebaf1708c55743acb4ad43fd4d0f21000200000000000000000918', + '0x31bccf9e28b94e5dacebaa67fe8bc1603cecd904000000000000000000000a01', + '0x4ccb966d8246240afb7a1a24628efb930870b1c40002000000000000000009fc', + '0x4689122d360c4725d244c5cfea22861333d862e6000100000000000000000468', + '0x96a78983932b8739d1117b16d30c15607926b0c500000000000000000000006d', + '0x8d7ca68d9a33148daf3ad1a495ed290f4eee013e0001000000000000000003b9', + '0x50cf90b954958480b8df7958a9e965752f62712400000000000000000000046f', + '0x483006684f422a9448023b2382615c57c5ecf18f000000000000000000000488', + '0x8b6d3aa69c1cf47677281691b1abf3831ba1329d0001000000000000000000d0', + '0x481c5fc05d63a58aa2f0f2aa417c021b5d419cb200000000000000000000056a', + '0x03090a9811181a2afe830a3a0b467698ccf3a8b1000000000000000000000bf5', + '0x639883476960a23b38579acfd7d71561a0f408cf000200000000000000000505', + '0x359ea8618c405023fc4b98dab1b01f373792a12600010000000000000000004f', + '0x5ddb92a5340fd0ead3987d3661afcd6104c3b757000000000000000000000187', + '0x3db543faf7a92052de7860c5c9debabee59ed5bd000000000000000000000a62', + '0x9fb7d6dcac7b6aa20108bad226c35b85a9e31b63000200000000000000000412', + '0xf48f01dcb2cbb3ee1f6aab0e742c2d3941039d56000200000000000000000012', + '0x6f34a44fce1506352a171232163e7716dd073ade000200000000000000000015', + '0xf51776b52dfb5bf9a7f3ed150c20e78d4dff6e640002000000000000000004e9', + '0x3f1a2c4a3a751f6626bd90ef16e104f0772d4d6b00020000000000000000001b', + '0x216690738aac4aa0c4770253ca26a28f0115c595000000000000000000000b2c', + '0x8b58a1e7fff52001c22386c2918d45938a6a9be30001000000000000000008d9', + '0xb841b062ea8ccf5c4cb78032e91de4ae875560420002000000000000000005b7', + '0x4fd4687ec38220f805b6363c3c1e52d0df3b5023000200000000000000000473', + '0x10b040038f87219d9b42e025e3bd9b8095c87dd9000000000000000000000b11', + '0x968024662b9566b42d78af23a0f441bc8723fa83000200000000000000000418', + '0x9321e2250767d79bab5aa06daa8606a2b3b7b4c5000000000000000000000bf4', + '0xcf8b555b7754556cf2ac2165e77ee23ed8517d7900020000000000000000045e', + '0xcb89e89d798a4563d1599ea5508282e13b225b520000000000000000000000e4', + '0xf227486361252907cb768142a2f4caed08a3d7cb0001000000000000000005dd', + '0x949a12b95ec5b80c375b98963a5d6b33b0d0efff0002000000000000000009fe', + '0x904018c54b2382929b15abaae55136a392af4294000100000000000000000729', + '0x567ecfcb22205d279bb8eed3e066989902bf03d5000000000000000000000452', + '0xe15cac1df3621e001f76210ab12a7f1a1691481f000000000000000000000044', + '0x93c7defe51d787010babfdb19504d5a72166e11200020000000000000000041c', + '0xff600724d670727872a1f7483049326c111d993d000100000000000000000448', + '0xb266ac3b7c98d7bcb28731dac0ef42dba1b276be000000000000000000000be4', + '0xd69959fa7910ceb3a2d359ed33cb8297670b69370000000000000000000005b2', + '0xbf2ef8bdc2fc0f3203b3a01778e3ec5009aeef3300000000000000000000058d', + '0xd4accb350f9cf59fe3cf7a5ee6ed9ace6a568ea9000200000000000000000b75', + '0xff8f84e8c87532af96aef5582ee451572233678b000200000000000000000478', + '0x2e52c64fd319e380cdbcfc4577ea1fda558a32e40002000000000000000005ba', + '0x4fd63966879300cafafbb35d157dc5229278ed230000000000000000000000e9', + '0xc83b55bbd005f1f84906545fcdb145dee53523e0000200000000000000000b30', + '0x11839d635e2f0270da37e8ef4324d4d5d54329570002000000000000000004d8', + '0xac976bb42cb0c85635644e8c7c74d0e0286aa61c0000000000000000000003cb', + '0x86aef31951e0a3a54333bd9e72f9a95587d058c5000200000000000000000912', + '0x9001cbbd96f54a658ff4e6e65ab564ded76a543100000000000000000000050a', + '0xb9bd68a77ccf8314c0dfe51bc291c77590c4e9e6000200000000000000000385', + '0x6222ae1d2a9f6894da50aa25cb7b303497f9bebd000000000000000000000046', + '0xa611a551b95b205ccd9490657acf7899daee5db700000000000000000000002e', + '0x02d928e68d8f10c0358566152677db51e1e2dc8c00000000000000000000051e', + '0x198a22e73aadd2d0ea8e2963799d38ae26adee2e000000000000000000000577', + '0xd997f35c9b1281b82c8928039d14cddab5e13c2000000000000000000000019c', + '0xc5dc1316ab670a2eed5716d7f19ced321191f38200000000000000000000056e', + '0x4228290ee9cab692938ff0b4ba303fbcdb68e9f200020000000000000000057d', + '0xb54b2125b711cd183edd3dd09433439d5396165200000000000000000000075e', + '0x3dbb8d974b82e82ce79c20c0f5995f4f1f533ede000000000000000000000470', + '0x216d6db0c28204014618482c369d7fbf0a8f3232000100000000000000000b60', + '0x418de00ae109e6f874d872658767866d680eaa1900000000000000000000047d', + '0x098f32d98d0d64dba199fc1923d3bf4192e787190001000000000000000000d2', + '0x7f4f4942f2a14b6ab7b08b10ada1aacede4ee8d4000200000000000000000b44', + '0xd00f9ca46ce0e4a63067c4657986f0167b0de1e5000000000000000000000b42', + '0x2ba7aa2213fa2c909cd9e46fed5a0059542b36b00000000000000000000003a3', + '0x43da214fab3315aa6c02e0b8f2bfb7ef2e3c60a50000000000000000000000ae', + '0x334c96d792e4b26b841d28f53235281cec1be1f200020000000000000000038a', + '0x981fb05b738e981ac532a99e77170ecb4bc27aef00010000000000000000004b', + '0x479a7d1fcdd71ce0c2ed3184bfbe9d23b92e8337000000000000000000000049', + '0xd0dc20e6342db2de82692b8dc842301ff9121805000200000000000000000454', + '0x2c8dbe8eb86135d9f2f26d196748c088d47f73e7000200000000000000000a29', + '0xb973ca96a3f0d61045f53255e319aedb6ed4924000000000000000000000042f', + '0x70b7d3b3209a59fb0400e17f67f3ee8c37363f4900020000000000000000018f', + '0x3c74c4ed512050eb843d89fb9dcd5ebb4668eb6d0002000000000000000000cc', + '0xa9cb51abfbbf2ca877b290e988b453f8bf4ab630000000000000000000000430', + '0x1f131ec1175f023ee1534b16fa8ab237c00e238100000000000000000000004a', + '0xeb38aa08bc00ba68237543d2daa1476b4dfd37f800000000000000000000073a', + '0xf0211cceebe6fcc45052b4e57ee95d233f5669d2000100000000000000000c01', + '0x362715c164d606682c4ea7e479633e419d9345eb0001000000000000000000e7', + '0x8c63702d4d4a521a6a8ecec8ab8f7ce9d1d6299e000200000000000000000443', + '0xa8af146d79ac0bb981e4e0d8b788ec5711b1d5d000000000000000000000047b', + '0xd6d20527c7b0669989ee082b9d3a1c63af742290000000000000000000000483', + '0xc69771058481551261709d8db44977e9afde645000010000000000000000042a', + '0x99c88ad7dc566616548adde8ed3effa730eb6c3400000000000000000000049a', + '0xa8bf1c584519be0184311c48adbdc4c15cb2e8c1000000000000000000000bf6', + '0x5b3240b6be3e7487d61cd1afdfc7fe4fa1d81e6400000000000000000000037b', + '0xf52fc9d5aa16c782c9ba51be0da10f1ccf05c702000100000000000000000394', + '0xae8535c23afedda9304b03c68a3563b75fc8f92b0000000000000000000005a0', + '0x2c4a83f98d1cdbeeec825fabacd09c46e2dd3c570002000000000000000000de', + '0x4b18597d3f7c9786a133827572e6a318d55c9fd200020000000000000000028b', + '0x9964b1bd3cc530e5c58ba564e45d45290f677be2000000000000000000000036', + '0xefc1bb0b97780cf7c22059aa7c7e7e88a049d21100020000000000000000041b', + '0x7449f09c8f0ed490472d7c14b4eef235620d027000010000000000000000072d', + '0xa1d14d922a575232066520eda11e27760946c991000000000000000000000012', + '0xc0064b291bd3d4ba0e44ccfc81bf8e7f7a579cd200000000000000000000042c', + '0xecc53ac812123d471360ea3d90023318868b56a5000000000000000000000429', + '0x68a69c596b3839023c0e08d09682314f582314e5000200000000000000000011', + '0xde0a77ab6689b980c30306b10f9131a007e1af81000200000000000000000ba1', + '0xd1af4974fcc995cf36ba40b189caa92964a9126d0000000000000000000000f1', + '0xff2753aaba51c9f84689b9bd0a21b3cf380a1cff00000000000000000000072e', + '0x71bd10c2a590b5858f5576550c163976a48af906000000000000000000000b27', + '0xe191504f9127deb015910768c8a6ac71d185bf91000200000000000000000603', + '0x57793d39e8787ee6295f6a27a81b6cca68e85cdf000000000000000000000397', + '0x04248aabca09e9a1a3d5129a7ba05b7f17de768400000000000000000000050e', + '0x4de21b365d6543661d0e105e579a34b963862497000200000000000000000045', + '0xd4500f270880488a481de1b3256a19b3d9c8fd7e000000000000000000000710', + '0xeb480dbbdd921cd6c359e4cc4c65ddea6395e2a1000200000000000000000946', + '0x252ff6a3a6fd7b5e8e999de8e3f5c3b306ed1401000200000000000000000bec', + '0x015f34e47ca0a88675098c4d6601817403f07a32000200000000000000000723', + '0xd90dc295d571adc7575563d892aa96ac3811d21c000200000000000000000402', + '0x4a77ef015ddcd972fd9ba2c7d5d658689d090f1a000000000000000000000b38', + '0xe0042e7ee284ff355622b7660ccb34be114936fa000100000000000000000400', + '0x49a0e3334496442a9706e481617724e7e37eaa080000000000000000000003ff', + '0x25accb7943fd73dda5e23ba6329085a3c24bfb6a000200000000000000000387', + '0x5a7f39435fd9c381e4932fa2047c9a5136a5e3e7000000000000000000000400', + '0x7839210cd48356bdd6fd400e30cfc7140e1e5ad6000100000000000000000449', + '0x59cfc2307e8b218c242ba61407a07cade73bd6d7000100000000000000000585', + '0xe2272cddb2cc408e79e02a73d1db9acc24a843d5000200000000000000000ba7', + '0x7079a25dec33be61bbd81b2fb69b468e80d3e72c0000000000000000000009ff', + '0x26c2b83fc8535deead276f5cc3ad9c1a2192e02700020000000000000000056b', + '0x9e2d87f904862671eb49cb358e74284762cc9f42000200000000000000000013', + '0x91e96deddca930669feb699d16cc3416289ec7aa000100000000000000000748', + '0x547e9ad4b824f09e9cf1c6d163cf308d4cf998120001000000000000000003c9', + '0x980dfa8bd5c4a96e1b762fe8154b8a2045dab2d70002000000000000000003ef', + '0xa5eb9166679a85bdb3eaa2941ed35c8d909484db00020000000000000000052b', + '0x78ab08bf98f90f29a09c9b1d85b3b549369b03a3000100000000000000000354', + '0xcaa052584b462198a5a9356c28bce0634d65f65c0000000000000000000004db', + '0x50fd4d5d60d6df38f5e29721bc241b537e182bf40002000000000000000005f9', + '0x4c81255cc9ed7062180ea99962fe05ac0d57350b0000000000000000000005a3', + '0xa1ea76c42b2938cfa9abea12357881006c52851300000000000000000000048f', + '0xff09914bf3d1f61ff3468cfcc4529665b908afa3000100000000000000000741', + '0x4ae3661afa119892f0cc8c43edaf6a94989ac171000000000000000000000c06', + '0x16b98793f3e6a17d15931a2c9f98fe28d1c845a1000100000000000000000c1f', + '0xa50f89e9f439fde2a6fe05883721a00475da3c4500000000000000000000048b', + '0x4c36a9a52ca3baf1069e3531d57d96c171a66a230002000000000000000001e9', + '0x3035917be42af437cbdd774be26b9ec90a2bd677000200000000000000000543', + '0xc963ef7d977ECb0Ab71d835C4cb1Bf737f28d010', // rdnt-weth sushi pool in radiant v1 adapter, redundant + '0x7007535de9f864f0c15fe6fa288ce3feb842f72c', + '0xbefaba1c380d8b0a53bc604d8b809684775e74f8', + '0x4b4b425586fa9b5cf0d06baf5ba9eb9e9b936e66-avalanche', + '0x295d1119c1183dc64feeb4bdc3f06f652525013d-avalanche', + '0x4c46ea0265efb51f90d405fb27bac92ff1beb274-avalanche', + '0x6b23732232f836d0918b11ebc03c21ad8759cb10-avalanche', + '0x3bf4885237f857b9668d2c44fa9ccd37b9c988e7-avalanche', + '0x0304a6dc4231c963c13df6c8b033ded30597ef4b-avalanche', + '0xe24563774dd4050e28e3c63567b2918495367626-avalanche', + '0x42c02c24caaf42a27dd95c790073a4ea3118ea48', + '0x4aE5CE819e7D678b07E8D0f483d351E2c8e8B8D3', + '0x5b4ef67c63d091083ec4d30cfc4ac685ef051046-xdai', + '0x659110d07923e2c3fcb9d3c9e66b0a1605e7ce71-astar', + '0xf13eb90f923ff0c424c4a7e917cace304b7386a0a6bafe1caa81efdc7973ae89', + '0x6b175474e89094c44da98b954eedeac495271d0f-smartcredit', + 'CuFuHe8bMES93pM2iD9SrFWyR9GkTfrKdHdP9FMbXwtg', + '0x2487ef2b79f4dce0ef7c6f0da6fb805dca050c06', + '0xa6ef6c45ebfdbc13f6d032fbdfec9b389c1603e5', + 'eqc11t8istqlkjgrocw3fer3kpsyzfuedzch943xkudmir7k-ton', + 'morpho-blue-0xade6749e981ae94420956cc22c299054e05ac3564cc196bf62f4c0924c03bfdf', + '0xBe96502c9bAa5Aec7E4C810c13D80F75e2D669E0', + '0xE39120b27e5bfeC953524402C2e261763c76519E', + + // merkl (temp) + '0x9fFCA51D23Ac7F7df82da414865Ef1055E5aFCc3', + '0x389938CF14Be379217570D8e4619E51fBDafaa21', + '0x7fCDC35463E3770c2fB992716Cd070B63540b947', + + // temp: subset aerordrom slipstream pools + '0xf81e1a62cBfA487E807044618661bFD4802B4982', + '0xcf88B8bf7CCCe2D836878E538197eB20fC673BCE', + '0xeBeC4772aBA30d82bC64BBB99187B4Ca29928e2E', + '0x2092f4acbb18BB1649595DF59B9Cb601bBA1EBB7', + '0x0C9A0e17eAB266DCF8dcFB4bc12792a9712FEd1E', + '0x326841EFD63340767e02ec88E583f18a82AF4A48', + '0x74E4c08Bb50619b70550733D32b7e60424E9628e', + '0x9785eF59E2b499fB741674ecf6fAF912Df7b3C1b', + '0x5A1401c002f67ca00557E7179D34C3FE6d753b28', + '0x565aecF84b5d30a6E79a5CEf3f0dA0Fc4280dEBC', + '0x178904D6F5f49074fC3fDb918F0170E0DBB1677e', + '0x75118B598433430DA15FB1340e486461f2A7c07F', + '0x8216144205B2Ac3523BAc7a8dC46d3c970e84876', + '0xa7423f6BEc29a511d365B0c934e8000720128aE3', + '0x3333E1d9174720D6eC2cF815e65B82915a9eaE1e', + '0x9bE60B89d29613da9e5163A9F4Ed9CC3738D59dc', + '0xc8a87167Ca4C19210725eCd71c762891fBB4EdDd', + '0x2b5fD674f93E329d54371DBa980a67F3ff3BC119', + '0x220cD22a10F4B1FA1B8FB42d707fF0b9642c7dd8', + '0x4b1f694A027103F10B625b6D8928181d86D450AF', + '0x87Cd18069B6547a0E88b6155DD657E71779500eA', + '0xF9b787C6E6111442778A9f6f8850F2d446d44a7c', + '0x8d628d22d298b4a6E3DC9171d4b7aa5229e2353c', + '0x6f8e210030f6eE6933b032628a0e148a1CcfF6a6', + '0xFAD14c545E464e04c737d00643296144eb20c7F8', + '0xe782B72A1157b7bEa1A9452835Cce214962aD43B', + '0xc286ecD3910c62dF30fBBFD2C95A3043076d3912', + '0xAA500dbEDa452Cc2807185DA993b6E3779333Aca', + '0x82321f3BEB69f503380D6B233857d5C43562e2D0', + '0xC5cAa75d63379e4FD78b5643aF419A2b8E5d0410', + '0xaFB62448929664Bfccb0aAe22f232520e765bA88', + '0x113138dC05b05AfbE25E8C31ca9DE9b445CAcA48', + '0x4e829F8A5213c42535AB84AA40BD4aDCCE9cBa02', + '0x088c39ee29fC30DF8Adc394e9f7dEa33E3A26507', + '0xfD22D75b2FB405EE185155D57B0277b9DB2F8E29', + '0xA33f162da19C7273BA1205BFD9D4340dA2446E3a', + '0x0a7021C9843c2fB3b98c02Ed7f93354774286109', + '0x86c1e27208C81484CB467A70CE26d7A9AD1d183F', + '0x4D69971CCd4A636c403a3C1B00c85e99bB9B5606', + '0xa01A2513E95263b9BaCe60B573ce874E1e7a5246', + '0xa19acc3B4f11c46c2b1Fc36B5f592AF422Ee338c', + '0xa4eb9849F46e1E9Db3700BCDadB62096a7bc4aAB', + '0xd9932A538e4c7621D9Ab1b45DE31a5D60E672B1c', + '0xB211a9DDff3a10806c8fdb92Dbc4c34596A23F84', + '0x12CCDd646241412F2a5D44a6994Aa29086dEDC61', + '0xBE00fF35AF70E8415D0eB605a286D8A45466A4c1', + '0xb2cc224c1c9feE385f8ad6a55b4d94E92359DC59', + '0xC29dc26B28FFF463e32834Ce6325B5c74fAC7098', + '0xfD7aBC461df4e496A25898CaB0c6EA88cDd94Cf9', + '0xAD04bE2b6613586f83049d5953611bAa23971340', + '0xefb02e6287bB46AC9196DE3e4120E3749e8DE59a', + + '0xC2E840BdD02B4a1d970C87A912D8576a7e61D314', + 'morpho-blue-0x3f35b581cf7292b09fdaca648638ec8b53969e9f54ecb6ca0e6252bda70b1f64-ethereum', + 'morpho-blue-0xEbFA750279dEfa89b8D99bdd145a016F6292757b-ethereum', + + 'morpho-blue-0xbef47159fd478cdd8c34073b71f97ca796aad295a87192fcffc813fad60de9f4-ethereum', + 'morpho-blue-0xdf2654405b27b5cf7a8f5fd78337e0440d37cbc797de38b1421752671f0ed3b6-ethereum', + 'morpho-blue-0x0d55c325847ed87d53506c2aca7de046cb59d8c22928fd55fb2790c4811d20db-ethereum', + 'morpho-blue-0x355c9a4c12f60a10ab3b68507bfab21bd6913182037ffe25d94dabffea45429f-ethereum', + 'FqsCPQ7x4qFcbxVLdmx1ty7iqSFWYcUzxxsxUFq4eyBn', + '0x1f0bc333c535838ca1020c87a6a043d89577c563-usdc-real', + '0xba309e52c154f090c34c6574b78548fd24a7e284c4d52b832aa50ef67b7a6ac4', + '0xbc2539b24bba254b9843e992a3802027275c50c2ecef1b71d52e289781560ace', + '0x1ba3281b6012f0b927d4d122bda293aa3cac487f', + '0x1d60d7e0987aefb69c41c98fe3233d61f8d8315a-arbitrum', + '3AFvR4L5p25KHiKmuvEXg9SxfCf4MpanN3KuK5qASqqc', + '0xde1e437e0be59b596e69ff58e2bda9209a72ce8b', + '0x9552db595b21884ffcc6851e24a7e3cbe0b638b06e472f77e824b58e0bfe9e0f', + '0x219e6623b7bda645b95ea0b46d22c06081e2adb3-base', + '0xc87a900078f04c45b7f14e46c520d4a6f37296b0-ethereum', + '0x5b2384D566D2E4a0b29B8eccB642C63199cd393c', + 'BCH.BCH-thorchain-savers', + 'BTC.BTC-thorchain-savers', + 'ETH.ETH-thorchain-savers', + 'ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7-thorchain-savers', + 'AVAX.AVAX-thorchain-savers', + 'ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48-thorchain-savers', + 'DOGE.DOGE-thorchain-savers', + 'AVAX.USDC-0XB97EF9EF8734C71904D8002F8B6BC66DD9C48A6E-thorchain-savers', + 'GAIA.ATOM-thorchain-savers', + 'LTC.LTC-thorchain-savers', + '0x90a3515619bab33fBCCB43AA86c25a12e41524B7-merkl', + '0x944D4AE892dE4BFd38742Cc8295d6D5164c5593C-merkl', + '0xfb185c6475e0e9e34c81e0bfb14068ffdb26470b700af47db72345618d61331f-arbitrum-uniswap-v4', + '0xc25a3a3b969415c80451098fa907ec722572917f-concentrator', +]; + +const boundaries = { + // we only insert pools into the db with a tvlUsd of minimum $1k + tvlUsdDB: { lb: 1e3, ub: 5e10 }, + // we only get pools for the UI with a tvlUsd of minimum $10k and max ($20 billion) + tvlUsdUI: { lb: 10000, ub: 2e10 }, + // we only get pools for the UI with a maximum apy of 1million % + apy: { lb: 0, ub: 1e6 }, + // reading from database returns only pools which is max 7 days old + age: 7, +}; + +const getProtocolExclusionsFromApi = async () => { + try { + const response = await axios.get('https://api.llama.fi/protocols', { + timeout: 10_000, + }); + return new Set( + (Array.isArray(response.data) ? response.data : []) + .filter((p) => p.rugged || p.deprecated || p.deadFrom) + .map((p) => p.slug) + ); + } catch (err) { + console.log( + 'Failed to fetch protocol exclusions; falling back to hardcoded list', + err?.message || err + ); + return new Set(); + } +}; + +const getExcludedAdaptors = async () => { + const flagged = await getProtocolExclusionsFromApi(); + return new Set([...excludeAdaptors, ...flagged]); +}; + +module.exports = { + excludeAdaptors, + excludePools, + boundaries, + getExcludedAdaptors, +}; diff --git a/src/utils/headers.js b/src/utils/headers.js new file mode 100644 index 0000000000..87825492af --- /dev/null +++ b/src/utils/headers.js @@ -0,0 +1,34 @@ +const customHeader = (cacheTime) => { + return { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Cache-Control': `max-age=${cacheTime}`, + }; +}; + +const getCacheDates = () => { + const date = new Date(); + date.setMinutes(22); + if (date < new Date()) { + // we are past the :22 mark, roll over to next hour + date.setHours(date.getHours() + 1); + } + return { + nextCacheDate: date, + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + Expires: date.toUTCString(), + } + }; +}; + +const customHeaderFixedCache = () => { + return getCacheDates().headers +}; + +module.exports = { + customHeader, + customHeaderFixedCache, + getCacheDates +}; diff --git a/src/utils/s3.js b/src/utils/s3.js index 6019b02e7c..404f5fc22b 100755 --- a/src/utils/s3.js +++ b/src/utils/s3.js @@ -1,6 +1,6 @@ const S3 = require('aws-sdk/clients/s3'); -exports.writeToS3 = async (bucket, key, body) => { +module.exports.writeToS3 = async (bucket, key, body) => { const params = { Bucket: bucket, Key: key, @@ -14,7 +14,7 @@ exports.writeToS3 = async (bucket, key, body) => { return resp; }; -exports.readFromS3 = async (bucket, key) => { +module.exports.readFromS3 = async (bucket, key) => { const params = { Bucket: bucket, Key: key, @@ -23,3 +23,29 @@ exports.readFromS3 = async (bucket, key) => { const resp = await s3.getObject(params).promise(); return JSON.parse(resp.Body); }; + +function next21Minutedate() { + const dt = new Date(); + dt.setHours(dt.getHours() + 1); + dt.setMinutes(22); + return dt; +} +module.exports.next21Minutedate = next21Minutedate; + +module.exports.storeAPIResponse = ( + bucket, + filename, + body, + expires = next21Minutedate() +) => { + return new S3() + .upload({ + Bucket: bucket, + Key: filename, + Body: JSON.stringify(body), + ACL: 'public-read', + Expires: expires, + ContentType: 'application/json', + }) + .promise(); +}; diff --git a/src/utils/welford.js b/src/utils/welford.js new file mode 100644 index 0000000000..041c6f1c35 --- /dev/null +++ b/src/utils/welford.js @@ -0,0 +1,64 @@ +module.exports.welfordUpdate = (pools, stats) => { + // calc std using welford's algorithm + // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance + // For a new value newValue, compute the new count, new mean, the new M2. + // mean accumulates the mean of the entire dataset + // M2 aggregates the squared distance from the mean + // count aggregates the number of samples seen so far + + const payload = []; + const n = 1000 * 60 * 60 * 24; + const currentDay = new Date(Math.floor(new Date() / n) * n); + for (const p of pools) { + d = stats[p.configID]; + + if (d !== undefined) { + // extract + count = d.count; + meanAPY = d.meanAPY; + mean2APY = d.mean2APY; + meanDR = d.meanDR; + mean2DR = d.mean2DR; + productDR = d.productDR; + + // we only update if the last pool value is from that day (otherwise its stale and we don't + // want to increment/update but instead are just going to keep the existing values) + if (p.timestamp >= currentDay) { + // update using welford algo + count += 1; + // a) ML section + deltaAPY = p.apy - meanAPY; + meanAPY += deltaAPY / count; + delta2APY = p.apy - meanAPY; + mean2APY += deltaAPY * delta2APY; + // b) scatterchart section + deltaDR = p.return - meanDR; + meanDR += deltaDR / count; + delta2DR = p.return - meanDR; + mean2DR += deltaDR * delta2DR; + productDR = (1 + p.return) * productDR; + } + } else { + // in case of a new pool -> boostrap db values + count = 1; + // a) ML section + meanAPY = p.apy; + mean2APY = 0; + // b) scatterchart section + meanDR = p.return; + mean2DR = 0; + productDR = 1 + p.return; + } + + payload.push({ + configID: p.configID, + count, + meanAPY, + mean2APY, + meanDR, + mean2DR, + productDR, + }); + } + return payload; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..27464e2a7c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2020", + "strict": false, + "types": ["node", "jest"], + "resolveJsonModule": true, + "moduleResolution": "node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "allowJs": true, + "lib": ["ES2020"], + "moduleDetection": "force" + }, + "include": ["./src/**/*"] +} diff --git a/webpack.config.js b/webpack.config.js index 6c9e751769..d672c18cf0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ const slsw = require('serverless-webpack'); const path = require('path'); +const webpack = require('webpack'); module.exports = { entry: slsw.lib.entries, @@ -8,7 +9,7 @@ module.exports = { module: { rules: [ { - test: /\.js$/, + test: /\.(ts|js)$/, use: { loader: 'babel-loader' }, include: path.resolve(__dirname, 'src'), exclude: /node_modules/, @@ -17,10 +18,14 @@ module.exports = { }, resolve: { mainFields: ['main'], - extensions: ['.js', '.json'], + extensions: ['.js', '.ts', '.json'], alias: { 'bignumber.js$': 'bignumber.js/bignumber.js', 'node-fetch$': 'node-fetch/lib/index.js', }, }, + plugins: [ + // pg optionally requires pg-native; ignore it -> webpack doesn't fail when the native addon isn't installed + new webpack.IgnorePlugin({ resourceRegExp: /^pg-native$/ }), + ], };